[california/wip/725786-edit-recurring] Use new Toolkit.RotatingButtonBox for create/update dialog
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/725786-edit-recurring] Use new Toolkit.RotatingButtonBox for create/update dialog
- Date: Sat, 12 Jul 2014 01:37:38 +0000 (UTC)
commit c3ad6d22dddf24a7b26706de994827ed31f15d17
Author: Jim Nelson <jim yorba org>
Date: Fri Jul 11 15:03:29 2014 -0700
Use new Toolkit.RotatingButtonBox for create/update dialog
Gtk.Revealer trick too difficult to get right. This does it right,
using Gtk.Stack to slide Gtk.ButtonBoxes into place. Can't use
Glade because no Gtk.Stack support there.
src/Makefile.am | 1 +
src/host/host-create-update-event.vala | 65 +++++++++++++++++--
src/rc/create-update-event.ui | 47 +------------
src/toolkit/toolkit-rotating-button-box.vala | 89 ++++++++++++++++++++++++++
4 files changed, 154 insertions(+), 48 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index e304026..c404850 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -127,6 +127,7 @@ california_VALASOURCES = \
toolkit/toolkit-motion-event.vala \
toolkit/toolkit-mutable-widget.vala \
toolkit/toolkit-popup.vala \
+ toolkit/toolkit-rotating-button-box.vala \
toolkit/toolkit-stack-model.vala \
\
util/util.vala \
diff --git a/src/host/host-create-update-event.vala b/src/host/host-create-update-event.vala
index 5989d2b..095e693 100644
--- a/src/host/host-create-update-event.vala
+++ b/src/host/host-create-update-event.vala
@@ -20,6 +20,9 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
private const int END_HOUR = 23;
private const int MIN_DIVISIONS = 15;
+ private const string FAMILY_NORMAL = "normal";
+ private const string FAMILY_RECURRING = "recurring";
+
public string card_id { get { return ID; } }
public string? title { get { return null; } }
@@ -56,7 +59,7 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
private Gtk.ComboBoxText calendar_combo;
[GtkChild]
- private Gtk.Button accept_button;
+ private Gtk.Box rotating_button_box_container;
public Calendar.DateSpan selected_date_span { get; set; }
@@ -69,6 +72,14 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
private Gtk.Button? last_date_button_touched = null;
private bool both_date_buttons_touched = false;
+ private Toolkit.RotatingButtonBox rotating_button_box = new Toolkit.RotatingButtonBox();
+
+ private Gtk.Button accept_button = new Gtk.Button();
+ private Gtk.Button cancel_button = new Gtk.Button.with_mnemonic(_("_Cancel"));
+ private Gtk.Button update_all_button = new Gtk.Button.with_mnemonic(_("Update A_ll Events"));
+ private Gtk.Button update_this_button = new Gtk.Button.with_mnemonic(_("Update _This Event"));
+ private Gtk.Button cancel_recurring_button = new Gtk.Button.with_mnemonic(_("_Cancel"));
+
public CreateUpdateEvent() {
// when selected_date_span updates, update date buttons as well
notify[PROP_SELECTED_DATE_SPAN].connect(() => {
@@ -101,6 +112,31 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
calendar_model.add(calendar_source);
}
+ accept_button.get_style_context().add_class("suggested-action");
+
+ accept_button.clicked.connect(on_accept_button_clicked);
+ cancel_button.clicked.connect(on_cancel_button_clicked);
+ update_all_button.clicked.connect(on_update_all_button_clicked);
+ update_this_button.clicked.connect(on_update_this_button_clicked);
+ cancel_recurring_button.clicked.connect(on_cancel_recurring_button_clicked);
+
+ rotating_button_box.pack_end(FAMILY_NORMAL, cancel_button);
+ rotating_button_box.pack_end(FAMILY_NORMAL, accept_button);
+
+ rotating_button_box.pack_end(FAMILY_RECURRING, cancel_recurring_button);
+ rotating_button_box.pack_end(FAMILY_RECURRING, update_all_button);
+ rotating_button_box.pack_end(FAMILY_RECURRING, update_this_button);
+
+ // The cancel-recurring-update button looks big compared to other buttons, so allow for the
+ // ButtonBox to reduce it in size
+
rotating_button_box.get_family_container(FAMILY_RECURRING).child_set_property(cancel_recurring_button,
+ "non-homogeneous", true);
+
+ rotating_button_box.expand = true;
+ rotating_button_box.halign = Gtk.Align.FILL;
+ rotating_button_box.valign = Gtk.Align.END;
+ rotating_button_box_container.add(rotating_button_box);
+
update_controls();
}
@@ -193,6 +229,10 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
description_textview.buffer.text = event.description ?? "";
accept_button.label = is_update ? _("_Update") : _("C_reate");
+ accept_button.use_underline = true;
+
+ rotating_button_box.family = FAMILY_NORMAL;
+
original_calendar_source = event.calendar_source;
}
@@ -238,11 +278,17 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
jump_to_card_by_name(CreateUpdateRecurring.ID, event);
}
- [GtkCallback]
- private void on_accept_clicked() {
+ private void on_accept_button_clicked() {
if (calendar_model.active == null)
return;
+ // if updating a recurring event, need to ask about update scope
+ if (event.is_recurring_instance && is_update) {
+ rotating_button_box.family = FAMILY_RECURRING;
+
+ return;
+ }
+
event.calendar_source = calendar_model.active;
event.summary = summary_entry.text;
event.location = location_entry.text;
@@ -271,9 +317,18 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
create_event_async.begin(null);
}
- [GtkCallback]
private void on_cancel_button_clicked() {
- jump_home_or_user_closed();
+ notify_user_closed();
+ }
+
+ private void on_update_all_button_clicked() {
+ }
+
+ private void on_update_this_button_clicked() {
+ }
+
+ private void on_cancel_recurring_button_clicked() {
+ rotating_button_box.family = FAMILY_NORMAL;
}
private async void create_event_async(Cancellable? cancellable) {
diff --git a/src/rc/create-update-event.ui b/src/rc/create-update-event.ui
index 885be53..92b2637 100644
--- a/src/rc/create-update-event.ui
+++ b/src/rc/create-update-event.ui
@@ -268,53 +268,14 @@
</packing>
</child>
<child>
- <object class="GtkButtonBox" id="button_box">
+ <object class="GtkBox" id="rotating_button_box_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="valign">end</property>
<property name="margin_top">8</property>
- <property name="vexpand">True</property>
- <property name="spacing">6</property>
- <property name="homogeneous">True</property>
- <property name="layout_style">end</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">False</property>
<child>
- <object class="GtkButton" id="cancel_button">
- <property name="label" translatable="yes">_Cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <property name="image_position">bottom</property>
- <signal name="clicked" handler="on_cancel_button_clicked"
object="CaliforniaHostCreateUpdateEvent" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="accept_button">
- <property name="label" translatable="yes">C_reate</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <property name="image_position">bottom</property>
- <signal name="clicked" handler="on_accept_clicked" object="CaliforniaHostCreateUpdateEvent"
swapped="no"/>
- <style>
- <class name="suggested-action"/>
- </style>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
+ <placeholder/>
</child>
</object>
<packing>
diff --git a/src/toolkit/toolkit-rotating-button-box.vala b/src/toolkit/toolkit-rotating-button-box.vala
new file mode 100644
index 0000000..13778f7
--- /dev/null
+++ b/src/toolkit/toolkit-rotating-button-box.vala
@@ -0,0 +1,89 @@
+/* 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 {
+
+/**
+ * RotatingButtonBox is a specialty widget for displaying groups ("families") of buttons, with each
+ * family silding (rotating) into view when required.
+ *
+ * Each family of Gtk.Buttons are held in Gtk.ButtonBoxes. They are always laid out horizontally
+ * with an END layout style and fixed spacing. This widget is designed specifically for buttons
+ * which populate the bottom edge of a dialog or popover.
+ *
+ * Families are created on-demand. The direction of them sliding into view is determined by the
+ * order they are created, i.e. the first family created is to the "left" of subsequent families.
+ *
+ * Families are described by a string name. Family names are case-sensitive.
+ */
+
+public class RotatingButtonBox : Gtk.Stack {
+ public const string PROP_FAMILY = "family";
+
+ public Gtk.Orientation ORIENTATION = Gtk.Orientation.HORIZONTAL;
+ public Gtk.ButtonBoxStyle LAYOUT_STYLE = Gtk.ButtonBoxStyle.END;
+ public int SPACING = 8;
+
+ /**
+ * The family name currently visible.
+ */
+ public string? family { get; set; }
+
+ private Gee.HashMap<string, Gtk.ButtonBox> button_boxes = new Gee.HashMap<string, Gtk.ButtonBox>();
+
+ public RotatingButtonBox() {
+ homogeneous = true;
+ transition_duration = SLOW_STACK_TRANSITION_DURATION_MSEC;
+ transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
+
+ bind_property("visible-child-name", this, PROP_FAMILY,
+ BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
+ }
+
+ /**
+ * Pack a Gtk.Button at the start of a particular family, creating the family if necessary.
+ *
+ * See Gtk.Box.pack_start().
+ */
+ public void pack_start(string family, Gtk.Button button) {
+ get_family_container(family).pack_start(button);
+ }
+
+ /**
+ * Pack a Gtk.Button at the end of a particular family, creating the family if necessary.
+ *
+ * See Gtk.Box.pack_end().
+ */
+ public void pack_end(string family, Gtk.Button button) {
+ get_family_container(family).pack_end(button);
+ }
+
+ /**
+ * Direct access to the Gtk.ButtonBox holding the named family.
+ *
+ * If the family doesn't exist, it will be created.
+ */
+ public Gtk.ButtonBox get_family_container(string family) {
+ if (button_boxes.has_key(family))
+ return button_boxes.get(family);
+
+ // create new family of buttons
+ Gtk.ButtonBox button_box = new Gtk.ButtonBox(ORIENTATION);
+ button_box.layout_style = LAYOUT_STYLE;
+ button_box.spacing = SPACING;
+
+ // add to internal lookup
+ button_boxes.set(family, button_box);
+
+ // add to Gtk.Stack using the family name
+ add_named(button_box, family);
+
+ return button_box;
+ }
+}
+
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]