[california/wip/732029-gtk-312: 7/7] Use DeckPopover for simple windows, DeckWindow for more complicated editing
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/732029-gtk-312: 7/7] Use DeckPopover for simple windows, DeckWindow for more complicated editing
- Date: Wed, 6 Aug 2014 01:48:02 +0000 (UTC)
commit 614d8b74fe0085378b40c815df656990e8fc77a1
Author: Jim Nelson <jim yorba org>
Date: Tue Aug 5 18:47:35 2014 -0700
Use DeckPopover for simple windows, DeckWindow for more complicated editing
src/Makefile.am | 1 +
src/activator/activator-window.vala | 14 ++--
src/application/california-application.vala | 4 +-
src/host/host-main-window.vala | 91 ++++++++++++++++++-----
src/host/host-quick-create-event.vala | 10 +-
src/host/host-show-event.vala | 13 ++--
src/manager/manager-window.vala | 14 ++--
src/toolkit/toolkit-deck-popover.vala | 102 ++++++++++++++++++++++++++
src/toolkit/toolkit-deck-window.vala | 94 +++++++-----------------
src/toolkit/toolkit-rotating-button-box.vala | 28 +++++++
10 files changed, 254 insertions(+), 117 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index eebcc31..f3006d1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -123,6 +123,7 @@ california_VALASOURCES = \
toolkit/toolkit-card.vala \
toolkit/toolkit-combo-box-text-model.vala \
toolkit/toolkit-deck.vala \
+ toolkit/toolkit-deck-popover.vala \
toolkit/toolkit-deck-window.vala \
toolkit/toolkit-editable-label.vala \
toolkit/toolkit-entry-clear-text-connector.vala \
diff --git a/src/activator/activator-window.vala b/src/activator/activator-window.vala
index 95ff428..29fce40 100644
--- a/src/activator/activator-window.vala
+++ b/src/activator/activator-window.vala
@@ -11,8 +11,8 @@ namespace California.Activator {
*/
public class Window : Toolkit.DeckWindow {
- private Window(Gtk.Widget relative_to, Gdk.Point? for_location) {
- base (relative_to, for_location, null);
+ private Window(Gtk.Window? window) {
+ base (window, null);
// The Deck is pre-populated with each of their Cards, with the InstanceList jumping to
// the right set when asked to (and acting as home)
@@ -24,14 +24,12 @@ public class Window : Toolkit.DeckWindow {
deck.add_cards(cards);
}
- public static void display(Gtk.Widget relative_to, Gdk.Point? for_location) {
- Activator.Window instance = new Activator.Window(relative_to, for_location);
-
- instance.dismiss.connect(() => {
- Toolkit.destroy_later(instance);
- });
+ public static void display(Gtk.Window? window) {
+ Activator.Window instance = new Activator.Window(window);
instance.show_all();
+ instance.run();
+ instance.destroy();
}
}
diff --git a/src/application/california-application.vala b/src/application/california-application.vala
index 72a3296..321dae2 100644
--- a/src/application/california-application.vala
+++ b/src/application/california-application.vala
@@ -212,11 +212,11 @@ public class Application : Gtk.Application {
}
private void on_new_calendar() {
- Activator.Window.display(main_window.calendar_button, null);
+ Activator.Window.display(main_window);
}
private void on_calendar_manager() {
- Manager.Window.display(main_window.calendar_button, null);
+ Manager.Window.display(main_window);
}
private void on_process_file(SimpleAction action, Variant? variant) {
diff --git a/src/host/host-main-window.vala b/src/host/host-main-window.vala
index c5bf312..e343cfc 100644
--- a/src/host/host-main-window.vala
+++ b/src/host/host-main-window.vala
@@ -333,14 +333,17 @@ public class MainWindow : Gtk.ApplicationWindow {
}
}
- private void show_deck(Gtk.Widget relative_to, Gdk.Point? for_location, Toolkit.Deck deck) {
- Toolkit.DeckWindow deck_window = new Toolkit.DeckWindow(relative_to, for_location, deck);
+ private void show_deck_window(Toolkit.Deck deck) {
+ Toolkit.DeckWindow deck_window = new Toolkit.DeckWindow(this, deck);
// when the dialog closes, reset View.Controllable state (selection is maintained while
// use is viewing/editing interaction) and destroy widgets
- deck_window.dismiss.connect(() => {
+ deck_window.deck.dismiss.connect(() => {
current_controller.unselect_all();
- Toolkit.destroy_later(deck_window);
+ deck_window.hide();
+ // give the dialog a change to hide before allowing other signals to fire, which may
+ // invoke another dialog (prevents multiple dialogs on screen at same time)
+ Toolkit.spin_event_loop();
});
deck_window.deck.failure.connect((msg) => {
@@ -348,6 +351,25 @@ public class MainWindow : Gtk.ApplicationWindow {
});
deck_window.show_all();
+ deck_window.run();
+ deck_window.destroy();
+ }
+
+ private void show_deck_popover(Gtk.Widget relative_to, Gdk.Point? for_location, Toolkit.Deck deck) {
+ Toolkit.DeckPopover deck_popover = new Toolkit.DeckPopover(relative_to, for_location, deck);
+
+ // when the popover closes, reset View.Controllable state (selection is maintained while
+ // use is viewing/editing interaction) and destroy widgets
+ deck_popover.dismiss.connect(() => {
+ current_controller.unselect_all();
+ Toolkit.destroy_later(deck_popover);
+ });
+
+ deck_popover.deck.failure.connect((msg) => {
+ Application.instance.error_message(msg);
+ });
+
+ deck_popover.show_all();
}
private void on_quick_create_event() {
@@ -420,29 +442,58 @@ public class MainWindow : Gtk.ApplicationWindow {
private void quick_create_event(Component.Event? initial, Gtk.Widget relative_to, Gdk.Point?
for_location) {
QuickCreateEvent quick_create = new QuickCreateEvent();
- CreateUpdateEvent create_update = new CreateUpdateEvent();
- create_update.is_update = false;
-
- CreateUpdateRecurring create_update_recurring = new CreateUpdateRecurring();
-
- EventTimeSettings event_time_settings = new EventTimeSettings();
-
Toolkit.Deck deck = new Toolkit.Deck();
- deck.add_cards(
- iterate<Toolkit.Card>(quick_create, create_update, create_update_recurring, event_time_settings)
- .to_array_list()
- );
+ deck.add_cards(iterate<Toolkit.Card>(quick_create).to_array_list());
- // initialize the Deck with the initial event (if any)
deck.go_home(initial);
- show_deck(relative_to, for_location, deck);
+ deck.dismiss.connect(() => {
+ if (quick_create.edit_required)
+ edit_event(quick_create.event);
+ });
+
+ show_deck_popover(relative_to, for_location, deck);
}
private void on_request_display_event(Component.Event event, Gtk.Widget relative_to,
Gdk.Point? for_location) {
ShowEvent show_event = new ShowEvent();
+ Toolkit.Deck deck = new Toolkit.Deck();
+ deck.add_cards(iterate<Toolkit.Card>(show_event).to_array_list());
+
+ deck.go_home(event);
+
+ deck.dismiss.connect(() => {
+ if (!show_event.edit_requested)
+ return;
+
+ // pass a clone of the existing event for editing
+ Component.Event clone;
+ try {
+ clone = event.clone() as Component.Event;
+ } catch (Error err) {
+ Application.instance.error_message(_("Unable to edit event: %s").printf(err.message));
+
+ return;
+ }
+
+ edit_event(clone);
+ });
+
+ show_deck_popover(relative_to, for_location, deck);
+ }
+
+ private void edit_event(Component.Event event) {
+ // use Idle loop so popovers have a chance to hide before bringing up DeckWindow
+ Idle.add(() => {
+ on_edit_event(event);
+
+ return false;
+ }, Priority.LOW + 100);
+ }
+
+ private void on_edit_event(Component.Event event) {
CreateUpdateEvent create_update = new CreateUpdateEvent();
create_update.is_update = true;
@@ -452,14 +503,14 @@ public class MainWindow : Gtk.ApplicationWindow {
Toolkit.Deck deck = new Toolkit.Deck();
deck.add_cards(
- iterate<Toolkit.Card>(show_event, create_update, create_update_recurring, event_time_settings)
+ iterate<Toolkit.Card>(create_update, create_update_recurring, event_time_settings)
.to_array_list()
);
- // "initialize" the Deck with the requested Event (because ShowEvent is first, it's home)
+ // "initialize" the Deck with the requested Event
deck.go_home(event);
- show_deck(relative_to, for_location, deck);
+ show_deck_window(deck);
}
}
diff --git a/src/host/host-quick-create-event.vala b/src/host/host-quick-create-event.vala
index 5d9c5a9..734a3a1 100644
--- a/src/host/host-quick-create-event.vala
+++ b/src/host/host-quick-create-event.vala
@@ -16,6 +16,8 @@ public class QuickCreateEvent : Gtk.Grid, Toolkit.Card {
public new Component.Event? event { get; private set; default = null; }
+ public bool edit_required { get; private set; default = false; }
+
public Gtk.Widget? default_widget { get { return create_button; } }
public Gtk.Widget? initial_focus { get { return details_entry; } }
@@ -142,11 +144,9 @@ public class QuickCreateEvent : Gtk.Grid, Toolkit.Card {
if (!event.is_valid(false))
event.set_event_date_span(Calendar.System.today.to_date_span());
- // jump to Create/Update dialog and remove this Card from the Deck ... this ensures
- // that if the user presses Cancel in the Create/Update dialog the Deck exits rather
- // than returns here (via jump_home_or_user_closed())
- jump_to_card_by_name(CreateUpdateEvent.ID, event);
- deck.remove_cards(iterate<Toolkit.Card>(this).to_array_list());
+ edit_required = true;
+
+ notify_user_closed();
}
private async void create_event_async(Cancellable? cancellable) {
diff --git a/src/host/host-show-event.vala b/src/host/host-show-event.vala
index 1a6270f..9a47ebc 100644
--- a/src/host/host-show-event.vala
+++ b/src/host/host-show-event.vala
@@ -25,6 +25,8 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
public Gtk.Widget? initial_focus { get { return close_button; } }
+ public bool edit_requested { get; private set; default = false; }
+
[GtkChild]
private Gtk.Label summary_text;
@@ -115,6 +117,8 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
description_text.bind_property("no-show-all", description_text_window, "no-show-all",
BindingFlags.SYNC_CREATE);
+ rotating_button_box.show_hide_family(FAMILY_REMOVING, event.is_generated_instance);
+
build_display();
}
@@ -207,12 +211,9 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
}
private void on_update_button_clicked() {
- // pass a clone of the existing event for editing
- try {
- jump_to_card_by_name(CreateUpdateEvent.ID, event.clone() as Component.Event);
- } catch (Error err) {
- notify_failure(_("Unable to update event: %s").printf(err.message));
- }
+ edit_requested = true;
+
+ notify_user_closed();
}
private void on_close_button_clicked() {
diff --git a/src/manager/manager-window.vala b/src/manager/manager-window.vala
index a798243..65a5d96 100644
--- a/src/manager/manager-window.vala
+++ b/src/manager/manager-window.vala
@@ -13,20 +13,18 @@ namespace California.Manager {
public class Window : Toolkit.DeckWindow {
private CalendarList calendar_list = new CalendarList();
- private Window(Gtk.Widget relative_to, Gdk.Point? for_location) {
- base (relative_to, for_location, null);
+ private Window(Gtk.Window? window) {
+ base (window, null);
deck.add_cards(iterate<Toolkit.Card>(calendar_list).to_array_list());
}
- public static void display(Gtk.Widget relative_to, Gdk.Point? for_location) {
- Manager.Window instance = new Manager.Window(relative_to, for_location);
-
- instance.dismiss.connect(() => {
- Toolkit.destroy_later(instance);
- });
+ public static void display(Gtk.Window? window) {
+ Manager.Window instance = new Manager.Window(window);
instance.show_all();
+ instance.run();
+ instance.destroy();
}
public override bool key_release_event(Gdk.EventKey event) {
diff --git a/src/toolkit/toolkit-deck-popover.vala b/src/toolkit/toolkit-deck-popover.vala
new file mode 100644
index 0000000..8cf0613
--- /dev/null
+++ b/src/toolkit/toolkit-deck-popover.vala
@@ -0,0 +1,102 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+namespace California.Toolkit {
+
+/**
+ * A GtkPopover with special support for { link Deck}s.
+ */
+
+public class DeckPopover : Gtk.Popover {
+ public Deck deck { get; private set; }
+
+ /**
+ * See { link Card.dismiss}
+ */
+ public signal void dismiss(bool user_request, bool final);
+
+ private bool preserve_mode;
+ private bool forcing_mode = false;
+
+ public DeckPopover(Gtk.Widget rel_to, Gdk.Point? for_location, Deck? starter_deck) {
+ Object (relative_to: rel_to);
+
+ preserve_mode = modal;
+
+ // treat "closed" signal as dismissal by user request
+ closed.connect(() => {
+ dismiss(true, true);
+ });
+
+ notify["modal"].connect(on_modal_changed);
+
+ this.deck = starter_deck ?? new Deck();
+
+ if (for_location != null) {
+ Gdk.Rectangle for_location_rect = Gdk.Rectangle() { x = for_location.x, y = for_location.y,
+ width = 1, height = 1 };
+ pointing_to = for_location_rect;
+ }
+
+ // because adding/removing cards can cause deep in Gtk.Widget the Popover to lose focus,
+ // those operations can prematurely close the Popover. Catching these signals allow for
+ // DeckWindow to go modeless during the operation and not close. (RotatingButtonBox has a
+ // similar issue.)
+ //
+ // TODO: This is fixed in GTK+ 3.13.6. When 3.14 is baseline requirement, this code can
+ // be removed.
+ deck.notify["transition-running"].connect(on_transition_running_changed);
+ deck.adding_removing_cards.connect(on_adding_removing_cards);
+ deck.added_removed_cards.connect(on_added_removed_cards);
+ deck.dismiss.connect(on_deck_dismissed);
+
+ // store Deck in box so margin can be applied
+ Gtk.Box box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+ box.margin = 4;
+ box.add(deck);
+
+ add(box);
+ }
+
+ ~DeckWindow() {
+ deck.notify["transition-running"].disconnect(on_transition_running_changed);
+ deck.adding_removing_cards.disconnect(on_adding_removing_cards);
+ deck.added_removed_cards.disconnect(on_added_removed_cards);
+ deck.dismiss.disconnect(on_deck_dismissed);
+ }
+
+ // if the modal value changes, preserve it (unless it's changing because we're forcing it to
+ // go modal/modeless during transitions we're attempting to work around)
+ private void on_modal_changed() {
+ if (!forcing_mode)
+ preserve_mode = modal;
+ }
+
+ private void force_mode(bool modal) {
+ forcing_mode = true;
+ this.modal = modal;
+ forcing_mode = false;
+ }
+
+ private void on_transition_running_changed() {
+ force_mode(deck.transition_running ? false : preserve_mode);
+ }
+
+ private void on_adding_removing_cards() {
+ force_mode(false);
+ }
+
+ private void on_added_removed_cards() {
+ force_mode(preserve_mode);
+ }
+
+ private void on_deck_dismissed(bool user_request, bool final) {
+ dismiss(user_request, final);
+ }
+}
+
+}
+
diff --git a/src/toolkit/toolkit-deck-window.vala b/src/toolkit/toolkit-deck-window.vala
index 60877ce..6c26f60 100644
--- a/src/toolkit/toolkit-deck-window.vala
+++ b/src/toolkit/toolkit-deck-window.vala
@@ -7,96 +7,54 @@
namespace California.Toolkit {
/**
- * A GtkPopover with special support for { link Deck}s.
+ * A GtkDialog with no visible action area that holds { link Deck}s.
*/
-public class DeckWindow : Gtk.Popover {
+public class DeckWindow : Gtk.Dialog {
public Deck deck { get; private set; }
- /**
- * See { link Card.dismiss}
- */
- public signal void dismiss(bool user_request, bool final);
-
- private bool preserve_mode;
- private bool forcing_mode = false;
-
- public DeckWindow(Gtk.Widget rel_to, Gdk.Point? for_location, Deck? starter_deck) {
- Object (relative_to: rel_to);
-
- preserve_mode = modal;
-
- // treat "closed" signal as dismissal by user request
- closed.connect(() => {
- dismiss(true, true);
- });
-
- notify["modal"].connect(on_modal_changed);
-
+ public DeckWindow(Gtk.Window? parent, Deck? starter_deck) {
this.deck = starter_deck ?? new Deck();
- if (for_location != null) {
- Gdk.Rectangle for_location_rect = Gdk.Rectangle() { x = for_location.x, y = for_location.y,
- width = 1, height = 1 };
- pointing_to = for_location_rect;
- }
+ transient_for = parent;
+ modal = true;
+ resizable = false;
- // because adding/removing cards can cause deep in Gtk.Widget the Popover to lose focus,
- // those operations can prematurely close the Popover. Catching these signals allow for
- // DeckWindow to go modeless during the operation and not close. (RotatingButtonBox has a
- // similar issue.)
- //
- // TODO: This is fixed in GTK+ 3.13.6. When 3.14 is baseline requirement, this code can
- // be removed.
- deck.notify["transition-running"].connect(on_transition_running_changed);
- deck.adding_removing_cards.connect(on_adding_removing_cards);
- deck.added_removed_cards.connect(on_added_removed_cards);
deck.dismiss.connect(on_deck_dismissed);
+ deck.success.connect(on_deck_success);
+ deck.failure.connect(on_deck_failure);
- // store Deck in box so margin can be applied
- Gtk.Box box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
- box.margin = 4;
- box.add(deck);
+ Gtk.Box content_area = (Gtk.Box) get_content_area();
+ content_area.margin = 8;
+ content_area.add(deck);
- add(box);
+ get_action_area().visible = false;
+ get_action_area().no_show_all = true;
}
~DeckWindow() {
- deck.notify["transition-running"].disconnect(on_transition_running_changed);
- deck.adding_removing_cards.disconnect(on_adding_removing_cards);
- deck.added_removed_cards.disconnect(on_added_removed_cards);
deck.dismiss.disconnect(on_deck_dismissed);
+ deck.success.disconnect(on_deck_success);
+ deck.failure.disconnect(on_deck_failure);
}
- // if the modal value changes, preserve it (unless it's changing because we're forcing it to
- // go modal/modeless during transitions we're attempting to work around)
- private void on_modal_changed() {
- if (!forcing_mode)
- preserve_mode = modal;
- }
-
- private void force_mode(bool modal) {
- forcing_mode = true;
- this.modal = modal;
- forcing_mode = false;
- }
-
- private void on_transition_running_changed() {
- force_mode(deck.transition_running ? false : preserve_mode);
- }
-
- private void on_adding_removing_cards() {
- force_mode(false);
+ private void on_deck_dismissed(bool user_request, bool final) {
+ if (final)
+ response(Gtk.ResponseType.CLOSE);
}
- private void on_added_removed_cards() {
- force_mode(preserve_mode);
+ private void on_deck_success() {
+ response(Gtk.ResponseType.OK);
}
- private void on_deck_dismissed(bool user_request, bool final) {
- dismiss(user_request, final);
+ private void on_deck_failure(string? user_message) {
+ if (!String.is_empty(user_message))
+ Application.instance.error_message(user_message);
+
+ response(Gtk.ResponseType.CLOSE);
}
}
}
+
diff --git a/src/toolkit/toolkit-rotating-button-box.vala b/src/toolkit/toolkit-rotating-button-box.vala
index 3cf1e9f..bb3dad9 100644
--- a/src/toolkit/toolkit-rotating-button-box.vala
+++ b/src/toolkit/toolkit-rotating-button-box.vala
@@ -109,6 +109,34 @@ public class RotatingButtonBox : Gtk.Stack {
return button_box;
}
+
+ /**
+ * Removes (or adds back) a family from the { link RotatingButtonBox}.
+ *
+ * The family remains under the RotatingButtonBox's control, it's simply removed from the
+ * widget heirarchy. This is useful for sizing purposes.
+ */
+ public void show_hide_family(string family, bool show) {
+ if (!button_boxes.has_key(family))
+ return;
+
+ Gtk.ButtonBox button_box = button_boxes.get(family);
+
+ bool shown = false;
+ foreach (Gtk.Widget widget in get_children()) {
+ if (widget == button_box) {
+ shown = true;
+
+ break;
+ }
+ }
+
+ if (show && !shown) {
+ add_named(button_box, family);
+ } else if (shown) {
+ remove(button_box);
+ }
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]