[gnome-boxes/wip/wizard-n-props-in-dialog2: 228/233] Put wizard in a modal dialog



commit ede092a8fbed33f4f576c91958f25296c7e27768
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Thu Aug 28 18:33:27 2014 +0100

    Put wizard in a modal dialog
    
    With some UI transitions removed during the port away from clutter, its
    better to have it in a dialog. This also helps reduce the size of wizard
    to buttons on both sides are not so far away from each other and hence
    easy to reach.
    
    Known issue: Wizard dialog changes size for some reason when arriving to
    review page.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=733367

 data/gnome-boxes.gresource.xml |    1 +
 data/ui/app-window.ui          |    8 --
 data/ui/sidebar.ui             |   26 +-------
 data/ui/wizard-dialog.ui       |  141 ++++++++++++++++++++++++++++++++++++++++
 src/Makefile.am                |    1 +
 src/app-window.vala            |   37 ++++-------
 src/app.vala                   |    8 +-
 src/sidebar.vala               |    6 --
 src/wizard-dialog.vala         |   85 ++++++++++++++++++++++++
 src/wizard.vala                |   38 +++++------
 10 files changed, 264 insertions(+), 87 deletions(-)
---
diff --git a/data/gnome-boxes.gresource.xml b/data/gnome-boxes.gresource.xml
index 87b856e..4d518f5 100644
--- a/data/gnome-boxes.gresource.xml
+++ b/data/gnome-boxes.gresource.xml
@@ -28,6 +28,7 @@
     <file preprocess="xml-stripblanks">ui/wizard-source.ui</file>
     <file preprocess="xml-stripblanks">ui/wizard-summary.ui</file>
     <file preprocess="xml-stripblanks">ui/wizard-toolbar.ui</file>
+    <file preprocess="xml-stripblanks">ui/wizard-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/snapshot-list-row.ui</file>
   </gresource>
 </gresources>
diff --git a/data/ui/app-window.ui b/data/ui/app-window.ui
index ab82ab1..6857c87 100644
--- a/data/ui/app-window.ui
+++ b/data/ui/app-window.ui
@@ -24,8 +24,6 @@
      |     |        |    |
      |     |        |    |-> content_bin = Gtk.Stack ();
      |     |        |        |
-     |     |        |        |-> wizard = new Boxes.Wizard ();
-     |     |        |        |
      |     |        |        |-> properties = new Boxes.Properties ();
      |     |        |
      |     |        |-> empty_boxes = new Boxes.EmptyBoxes ();
@@ -126,12 +124,6 @@
                         <property name="vexpand">True</property>
 
                         <child>
-                          <object class="BoxesWizard" id="wizard">
-                            <property name="visible">True</property>
-                          </object>
-                        </child>
-
-                        <child>
                           <object class="BoxesProperties" id="properties">
                             <property name="visible">True</property>
                           </object>
diff --git a/data/ui/sidebar.ui b/data/ui/sidebar.ui
index d35e6e1..febbacd 100644
--- a/data/ui/sidebar.ui
+++ b/data/ui/sidebar.ui
@@ -11,32 +11,10 @@
     <property name="hexpand">False</property>
     <property name="halign">start</property>
 
+    <!-- Properties -->
     <child>
-      <object class="GtkNotebook" id="notebook">
+      <object class="BoxesPropertiesSidebar" id="props_sidebar">
         <property name="visible">True</property>
-        <property name="show-tabs">False</property>
-        <property name="vexpand">True</property>
-        <property name="hexpand">True</property>
-        <style>
-          <class name="sidebar"/>
-        </style>
-
-        <!-- Separate page for each UI state -->
-
-        <!-- Wizard -->
-        <child>
-          <object class="BoxesWizardSidebar" id="wizard_sidebar">
-            <property name="visible">True</property>
-          </object>
-        </child>
-
-        <!-- Properties -->
-        <child>
-          <object class="BoxesPropertiesSidebar" id="props_sidebar">
-            <property name="visible">True</property>
-          </object>
-        </child>
-
       </object>
     </child>
   </template>
diff --git a/data/ui/wizard-dialog.ui b/data/ui/wizard-dialog.ui
new file mode 100644
index 0000000..65cd011
--- /dev/null
+++ b/data/ui/wizard-dialog.ui
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.9 -->
+
+  <!-- Widget hierarchy:
+
+     Boxes.WizardDialog : Gtk.Dialog
+        |
+        |-> vbox (internal child)
+        |     |
+        |     |-> hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+        |     |
+        |     |-> sidebar = new Boxes.WizardSidebar ();
+        |     |
+        |     |-> wizard = new Boxes.Wizard ();
+        |
+        |-> cancel_btn (action child) = new Gtk.Button ();
+        |-> create_btn (action child) = new Gtk.Button ();
+        |-> continue_btn (action child) = new Gtk.Button ();
+        |-> back_btn (action child) = new Gtk.Button ();
+  -->
+
+  <template class="BoxesWizardDialog" parent="GtkDialog">
+    <property name="title" translatable="yes">Create a Box</property>
+    <property name="can_focus">False</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <signal name="key-press-event" after="yes" handler="on_key_pressed"/>
+    <signal name="delete-event" handler="on_delete_event"/>
+
+    <child internal-child="vbox">
+      <object class="GtkBox" id="vbox">
+        <property name="visible">True</property>
+        <property name="spacing">10</property>
+
+        <child>
+          <object class="GtkBox" id="hbox">
+            <property name="visible">True</property>
+            <property name="orientation">horizontal</property>
+            <property name="halign">fill</property>
+            <property name="valign">fill</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <property name="spacing">10</property>
+
+            <child>
+              <object class="BoxesWizardSidebar" id="sidebar">
+                <property name="visible">True</property>
+              </object>
+            </child>
+
+            <child>
+              <object class="BoxesWizard" id="wizard">
+                <property name="visible">True</property>
+              </object>
+            </child>
+
+          </object>
+        </child>
+
+      </object>
+    </child>
+
+    <child type="action">
+      <object class="GtkButton" id="cancel_btn">
+        <property name="visible">True</property>
+        <property name="valign">center</property>
+        <property name="use-underline">True</property>
+        <property name="can-default">True</property>
+        <property name="has-default">True</property>
+        <property name="label" translatable="yes">_Cancel</property>
+        <signal name="clicked" handler="on_cancel_btn_clicked"/>
+        <style>
+          <class name="text-button"/>
+        </style>
+      </object>
+    </child>
+
+    <child type="action">
+      <object class="GtkButton" id="create_btn">
+        <property name="visible">False</property>
+        <property name="valign">center</property>
+        <property name="use-underline">True</property>
+        <property name="can-default">True</property>
+        <property name="label" translatable="yes">C_reate</property>
+        <signal name="clicked" handler="on_create_btn_clicked"/>
+        <style>
+          <class name="text-button"/>
+          <class name="boxes-continue"/>
+        </style>
+      </object>
+    </child>
+
+    <child type="action">
+      <object class="GtkButton" id="continue_btn">
+        <property name="visible">True</property>
+        <property name="valign">center</property>
+        <property name="use-underline">True</property>
+        <property name="can-default">True</property>
+        <property name="has-default">True</property>
+        <property name="label" translatable="yes">C_ontinue</property>
+        <signal name="clicked" handler="on_continue_btn_clicked"/>
+        <style>
+          <class name="text-button"/>
+          <class name="boxes-continue"/>
+        </style>
+      </object>
+    </child>
+
+    <child type="action">
+      <object class="GtkButton" id="back_btn">
+        <property name="visible">True</property>
+        <property name="valign">center</property>
+        <property name="use-underline">True</property>
+        <property name="label" translatable="yes">_Back</property>
+        <signal name="clicked" handler="on_back_btn_clicked"/>
+        <style>
+          <class name="text-button"/>
+        </style>
+      </object>
+    </child>
+
+    <action-widgets>
+      <action-widget response="cancel" default="true">cancel_btn</action-widget>
+      <action-widget response="none">back_btn</action-widget>
+      <action-widget response="none">create_btn</action-widget>
+      <action-widget response="none">continue_btn</action-widget>
+    </action-widgets>
+
+  </template>
+
+  <object class="GtkSizeGroup" id="sizegroup">
+    <property name="mode">horizontal</property>
+    <widgets>
+      <widget name="cancel_btn"/>
+      <widget name="back_btn"/>
+      <widget name="continue_btn"/>
+      <widget name="create_btn"/>
+    </widgets>
+  </object>
+</interface>
diff --git a/src/Makefile.am b/src/Makefile.am
index 7578ac0..d33607a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -143,6 +143,7 @@ gnome_boxes_SOURCES =                               \
        libvirt-system-importer.vala            \
        libvirt-system-vm-importer.vala         \
        vnc-display.vala                        \
+       wizard-dialog.vala                      \
        wizard-sidebar.vala                     \
        wizard-source.vala                      \
        wizard-toolbar.vala                     \
diff --git a/src/app-window.vala b/src/app-window.vala
index fcc9263..dfc33ad 100644
--- a/src/app-window.vala
+++ b/src/app-window.vala
@@ -60,15 +60,7 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
         }
     }
 
-    private void on_machine_state_notify () {
-       if (this != App.app.main_window && (current_item as Machine).state != Machine.MachineState.RUNNING)
-           on_delete_event ();
-    }
-
-    private void on_machine_deleted_notify () {
-       if (this != App.app.main_window && (current_item as Machine).deleted)
-           on_delete_event ();
-    }
+    public WizardDialog wizard_dialog;
 
     [GtkChild]
     public Searchbar searchbar;
@@ -81,8 +73,6 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
     [GtkChild]
     public Sidebar sidebar;
     [GtkChild]
-    public Wizard wizard;
-    [GtkChild]
     public Properties properties;
     [GtkChild]
     public DisplayPage display_page;
@@ -140,7 +130,6 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
 
     public void setup_ui () {
         topbar.setup_ui (this);
-        wizard.setup_ui (this);
         display_page.setup_ui (this);
         view.setup_ui (this);
         selectionbar.setup_ui (this);
@@ -149,6 +138,8 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
         properties.setup_ui (this);
         empty_boxes.setup_ui (this);
         notificationbar.searchbar = searchbar;
+
+        wizard_dialog = new WizardDialog (this);
     }
 
     private void save_window_geometry () {
@@ -167,7 +158,7 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
     private void ui_state_changed () {
         // The order is important for some widgets here (e.g properties must change its state before wizard 
so it can
         // flush any deferred changes for wizard to pick-up when going back from properties to wizard 
(review).
-        foreach (var ui in new Boxes.UI[] { sidebar, topbar, view, properties, wizard, empty_boxes }) {
+        foreach (var ui in new Boxes.UI[] { sidebar, topbar, view, properties, wizard_dialog, empty_boxes }) 
{
             ui.set_state (ui_state);
         }
 
@@ -200,18 +191,12 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
 
         case UIState.CREDS:
         case UIState.DISPLAY:
-
-            break;
-
         case UIState.WIZARD:
-            below_bin.visible_child = below_bin_hbox;
-            content_bin.visible_child = wizard;
 
             break;
 
         case UIState.PROPERTIES:
             below_bin.visible_child = below_bin_hbox;
-            content_bin.visible_child = properties;
 
             break;
 
@@ -322,10 +307,6 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
                    (event.state & default_modifiers) == Gdk.ModifierType.MOD1_MASK) {
             topbar.click_back_button ();
             return true;
-        } else if (event.keyval == Gdk.Key.Right && // ALT + Right -> forward
-                   (event.state & default_modifiers) == Gdk.ModifierType.MOD1_MASK) {
-            topbar.click_forward_button ();
-            return true;
         } else if (event.keyval == Gdk.Key.Escape) { // ESC -> cancel
             topbar.click_cancel_button ();
         }
@@ -376,4 +357,14 @@ private class Boxes.AppWindow: Gtk.ApplicationWindow, Boxes.UI {
 
         return App.app.remove_window (this);
     }
+
+    private void on_machine_state_notify () {
+       if (this != App.app.main_window && (current_item as Machine).state != Machine.MachineState.RUNNING)
+           on_delete_event ();
+    }
+
+    private void on_machine_deleted_notify () {
+       if (this != App.app.main_window && (current_item as Machine).deleted)
+           on_delete_event ();
+    }
 }
diff --git a/src/app.vala b/src/app.vala
index 74c6e45..17f54a6 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -234,11 +234,11 @@ private class Boxes.App: Gtk.Application {
 
                 if (file.query_exists ()) {
                     if (is_uri)
-                        main_window.wizard.open_with_uri (arg);
+                        main_window.wizard_dialog.wizard.open_with_uri (arg);
                     else
-                        main_window.wizard.open_with_uri (file.get_uri ());
+                        main_window.wizard_dialog.wizard.open_with_uri (file.get_uri ());
                 } else if (is_uri)
-                    main_window.wizard.open_with_uri (arg);
+                    main_window.wizard_dialog.wizard.open_with_uri (arg);
                 else
                     open_name (arg);
             });
@@ -276,7 +276,7 @@ private class Boxes.App: Gtk.Application {
 
         foreach (var window in windows) {
             window.notificationbar.cancel ();
-            window.wizard.cleanup ();
+            window.wizard_dialog.wizard.cleanup ();
         }
         suspend_machines ();
     }
diff --git a/src/sidebar.vala b/src/sidebar.vala
index d9084b9..12e164c 100644
--- a/src/sidebar.vala
+++ b/src/sidebar.vala
@@ -13,11 +13,7 @@ private class Boxes.Sidebar: Gtk.Revealer, Boxes.UI {
     public UIState ui_state { get; protected set; }
 
     [GtkChild]
-    public WizardSidebar wizard_sidebar;
-    [GtkChild]
     public PropertiesSidebar props_sidebar;
-    [GtkChild]
-    private Gtk.Notebook notebook;
 
     private AppWindow window;
 
@@ -32,10 +28,8 @@ private class Boxes.Sidebar: Gtk.Revealer, Boxes.UI {
 
     private void ui_state_changed () {
         switch (ui_state) {
-        case UIState.WIZARD:
         case UIState.PROPERTIES:
             reveal_child = true;
-            notebook.page = ui_state == UIState.WIZARD ? SidebarPage.WIZARD : SidebarPage.PROPERTIES;
             break;
 
         default:
diff --git a/src/wizard-dialog.vala b/src/wizard-dialog.vala
new file mode 100644
index 0000000..95300f6
--- /dev/null
+++ b/src/wizard-dialog.vala
@@ -0,0 +1,85 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+using Gtk;
+
+[GtkTemplate (ui = "/org/gnome/Boxes/ui/wizard-dialog.ui")]
+private class Boxes.WizardDialog : Gtk.Dialog, Boxes.UI {
+    public UIState previous_ui_state { get; protected set; }
+    public UIState ui_state { get; protected set; }
+
+    [GtkChild]
+    public WizardSidebar sidebar;
+    [GtkChild]
+    public Wizard wizard;
+
+    [GtkChild]
+    public Button back_btn;
+    [GtkChild]
+    public Button continue_btn;
+    [GtkChild]
+    public Button create_btn;
+
+    construct {
+        use_header_bar = 1;
+    }
+
+    public WizardDialog (AppWindow app_window) {
+        wizard.setup_ui (app_window, this);
+
+        set_transient_for (app_window);
+
+        notify["ui-state"].connect (ui_state_changed);
+    }
+
+    private void ui_state_changed () {
+        wizard.set_state (ui_state);
+
+        this.visible = (ui_state == UIState.WIZARD);
+    }
+
+    [GtkCallback]
+    public bool on_key_pressed (Widget widget, Gdk.EventKey event) {
+        var default_modifiers = Gtk.accelerator_get_default_mod_mask ();
+
+        if (event.keyval == Gdk.Key.Left && // ALT + Left -> back
+                   (event.state & default_modifiers) == Gdk.ModifierType.MOD1_MASK) {
+            if (back_btn.sensitive)
+                back_btn.clicked ();
+            return true;
+        } else if (event.keyval == Gdk.Key.Right && // ALT + Right -> forward
+                   (event.state & default_modifiers) == Gdk.ModifierType.MOD1_MASK) {
+            if (continue_btn.sensitive)
+                continue_btn.clicked ();
+            return true;
+        }
+
+        return false;
+    }
+
+    [GtkCallback]
+    private bool on_delete_event () {
+        wizard.cancel ();
+
+        return true;
+    }
+
+    [GtkCallback]
+    private void on_cancel_btn_clicked () {
+        wizard.cancel ();
+    }
+
+    [GtkCallback]
+    private void on_back_btn_clicked () {
+        wizard.cancel_prepare ();
+        wizard.page = wizard.page - 1;
+    }
+
+    [GtkCallback]
+    private void on_continue_btn_clicked () {
+        wizard.page = wizard.page + 1;
+    }
+
+    [GtkCallback]
+    private void on_create_btn_clicked () {
+        wizard.page = WizardPage.LAST;
+    }
+}
diff --git a/src/wizard.vala b/src/wizard.vala
index 7b92742..0360c54 100644
--- a/src/wizard.vala
+++ b/src/wizard.vala
@@ -135,7 +135,7 @@ private class Boxes.Wizard: Gtk.Stack, Boxes.UI {
                 return;
 
             _page = value;
-            window.sidebar.wizard_sidebar.set_page (value);
+            window.wizard_dialog.sidebar.set_page (value);
             visible_child_name = page_names[value];
 
             if (value == WizardPage.SOURCE)
@@ -600,29 +600,12 @@ private class Boxes.Wizard: Gtk.Stack, Boxes.UI {
         prepare (progress);
     }
 
-    public void setup_ui (AppWindow window) {
+    public void setup_ui (AppWindow window, WizardDialog dialog) {
         this.window = window;
 
-        cancel_button = window.topbar.wizard_toolbar.cancel_btn;
-        cancel_button.clicked.connect (() => {
-            cleanup ();
-            wizard_source.page = SourcePage.MAIN;
-            window.set_state (UIState.COLLECTION);
-        });
-        back_button = window.topbar.wizard_toolbar.back_btn;
-        back_button.clicked.connect (() => {
-            prepare_cancellable.cancel ();
-
-            page = page - 1;
-        });
-        continue_button = window.topbar.wizard_toolbar.continue_btn;
-        continue_button.clicked.connect (() => {
-            page = page + 1;
-        });
-        create_button = window.topbar.wizard_toolbar.create_btn;
-        create_button.clicked.connect (() => {
-            page = WizardPage.LAST;
-        });
+        back_button = dialog.back_btn;
+        continue_button = dialog.continue_btn;
+        create_button = dialog.create_btn;
 
         wizard_source.setup_ui (window);
     }
@@ -637,6 +620,17 @@ private class Boxes.Wizard: Gtk.Stack, Boxes.UI {
         page = WizardPage.PREPARATION;
     }
 
+    public void cancel () {
+        cleanup ();
+        wizard_source.page = SourcePage.MAIN;
+        window.set_state (UIState.COLLECTION);
+    }
+
+    public void cancel_prepare () {
+        if (prepare_cancellable != null)
+            prepare_cancellable.cancel ();
+    }
+
     private void ui_state_changed () {
         if (ui_state != UIState.WIZARD)
             return;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]