[california/wip/725763-google] Deck-ify entire activation process.
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/725763-google] Deck-ify entire activation process.
- Date: Fri, 4 Apr 2014 00:08:39 +0000 (UTC)
commit 24b9a36cb72d2a833a0cfdeb8742f4692ecd1014
Author: Jim Nelson <jim yorba org>
Date: Thu Apr 3 16:17:37 2014 -0700
Deck-ify entire activation process.
src/activator/activator-instance-list.vala | 64 ++++++++++-----
src/activator/activator-instance.vala | 11 ++-
src/activator/activator-window.vala | 21 +++---
src/activator/activator.vala | 8 +--
.../activator-google-authenticating-pane.vala | 6 +-
.../activator-google-calendar-list-pane.vala | 4 +-
.../google/activator-google-login-pane.vala | 4 +-
src/activator/google/activator-google.vala | 8 +-
src/activator/webcal/activator-webcal-pane.vala | 15 +++-
src/activator/webcal/activator-webcal.vala | 9 ++-
src/rc/activator-list.ui | 3 +-
src/rc/webcal-subscribe.ui | 1 +
src/util/util-deck.vala | 85 +++++++++++++++++---
src/util/util-listbox-model.vala | 34 ++++++++
14 files changed, 207 insertions(+), 66 deletions(-)
---
diff --git a/src/activator/activator-instance-list.vala b/src/activator/activator-instance-list.vala
index 2c94778..f7c3bcb 100644
--- a/src/activator/activator-instance-list.vala
+++ b/src/activator/activator-instance-list.vala
@@ -7,51 +7,75 @@
namespace California.Activator {
[GtkTemplate (ui = "/org/yorba/california/rc/activator-list.ui")]
-public class InstanceList : Gtk.Grid, Host.Interaction {
- private class Item : Gtk.Label {
- public Activator.Instance activator;
-
- public Item(Activator.Instance activator) {
- this.activator = activator;
-
- label = activator.title;
- xalign = 0.0f;
- margin = 4;
- }
- }
+public class InstanceList : Gtk.Grid, Card {
+ public const string ID = "ActivatorInstanceList";
+
+ public string card_id { get { return ID; } }
+
+ public string? title { get { return null; } }
public Gtk.Widget? default_widget { get { return add_button; } }
+ public Gtk.Widget? initial_focus { get { return listbox; } }
+
[GtkChild]
private Gtk.ListBox listbox;
[GtkChild]
private Gtk.Button add_button;
- public signal void selected(Activator.Instance activator);
+ private ListBoxModel<Instance> model;
public InstanceList() {
- foreach (Activator.Instance activator in activators)
- listbox.add(new Item(activator));
+ model = new ListBoxModel<Instance>(listbox, model_presentation, activator_comparator);
+ model.add_many(activators);
+
+ model.activated.connect(on_item_activated);
+ model.bind_property(ListBoxModel.PROP_SELECTED, add_button, "sensitive", BindingFlags.SYNC_CREATE,
+ selected_to_sensitive);
show_all();
}
- [GtkCallback]
- private void on_listbox_row_activated(Gtk.ListBoxRow? row) {
- if (row != null)
- selected(((Item) row.get_child()).activator);
+ private bool selected_to_sensitive(Binding binding, Value source_value, ref Value target_value) {
+ target_value = (model.selected != null);
+
+ return true;
+ }
+
+ public void jumped_to(Card? from, Value? message) {
+ }
+
+ private void on_item_activated(Instance activator) {
+ start(activator);
}
[GtkCallback]
private void on_add_button_clicked() {
- on_listbox_row_activated(listbox.get_selected_row());
+ if (model.selected != null)
+ start(model.selected);
}
[GtkCallback]
private void on_cancel_button_clicked() {
dismissed(true);
}
+
+ private void start(Instance activator) {
+ jump_to_card_by_name(activator.first_card_id, null);
+ }
+
+ private Gtk.Widget model_presentation(Instance activator) {
+ Gtk.Label label = new Gtk.Label(activator.title);
+ label.xalign = 0.0f;
+ label.margin = 4;
+
+ return label;
+ }
+
+ private int activator_comparator(Instance a, Instance b) {
+ return String.stricmp(a.title, b.title);
+ }
}
}
diff --git a/src/activator/activator-instance.vala b/src/activator/activator-instance.vala
index 01d84e0..ae9393b 100644
--- a/src/activator/activator-instance.vala
+++ b/src/activator/activator-instance.vala
@@ -33,16 +33,23 @@ public abstract class Instance : BaseObject {
*/
public Backing.Store store { get; private set; }
+ /**
+ * The { link Card.card_id} of the first Card returns by { link create_cards}.
+ */
+ public abstract string first_card_id { get; }
+
protected Instance(string title, Backing.Store store) {
this.title = title;
this.store = store;
}
/**
- * Return a { link Host.Interaction} that guides the user through the steps to create a
+ * Return a collection of { link Cards} that guides the user through the steps to create a
* { link Backing.Source}.
+ *
+ * The first Card will be jumped to initially.
*/
- public abstract Host.Interaction create_interaction(Soup.URI? supplied_uri);
+ public abstract Gee.List<Card> create_cards(Soup.URI? supplied_uri);
public override string to_string() {
return title;
diff --git a/src/activator/activator-window.vala b/src/activator/activator-window.vala
index 7385ae6..ed14006 100644
--- a/src/activator/activator-window.vala
+++ b/src/activator/activator-window.vala
@@ -13,22 +13,21 @@ namespace California.Activator {
public class Window : Host.ModalWindow {
private static Activator.Window? instance = null;
+ private Deck deck = new Deck();
+
private Window(Gtk.Window? parent) {
base (parent);
- InstanceList list = new InstanceList();
+ // 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)
+ Gee.List<Card> cards = new Gee.ArrayList<Card>();
+ cards.add(new InstanceList());
+ foreach (Instance activator in activators)
+ cards.add_all(activator.create_cards(null));
- // when an Activator instance is selected from the list, swap out the list for the
- // Activator's own interaction
- list.selected.connect(activator => {
- content_area.remove(list);
-
- Host.Interaction interaction = activator.create_interaction(null);
- interaction.show_all();
- content_area.add(interaction);
- });
+ deck.add_cards(cards);
- content_area.add(list);
+ content_area.add(deck);
}
public static void display(Gtk.Window? parent) {
diff --git a/src/activator/activator.vala b/src/activator/activator.vala
index a709cbe..27bddf7 100644
--- a/src/activator/activator.vala
+++ b/src/activator/activator.vala
@@ -18,7 +18,7 @@ namespace California.Activator {
private int init_count = 0;
-private Gee.TreeSet<Instance> activators;
+private Gee.List<Instance> activators;
public void init() throws Error {
if (!Unit.do_init(ref init_count))
@@ -26,7 +26,7 @@ public void init() throws Error {
Backing.init();
- activators = new Gee.TreeSet<Instance>(activator_comparator);
+ activators = new Gee.ArrayList<Instance>();
// All Instances that work with EDS
Backing.EdsStore? eds_store = Backing.Manager.instance.get_store_of_type<Backing.EdsStore>()
@@ -45,9 +45,5 @@ public void terminate() {
Backing.terminate();
}
-private int activator_comparator(Instance a, Instance b) {
- return String.stricmp(a.title, b.title);
-}
-
}
diff --git a/src/activator/google/activator-google-authenticating-pane.vala
b/src/activator/google/activator-google-authenticating-pane.vala
index caa9afd..e2738b4 100644
--- a/src/activator/google/activator-google-authenticating-pane.vala
+++ b/src/activator/google/activator-google-authenticating-pane.vala
@@ -51,7 +51,7 @@ public class GoogleAuthenticatingPane : Gtk.Grid, Card {
public GoogleAuthenticatingPane() {
}
- public void jumped_to(Card from, Value? message) {
+ public void jumped_to(Card? from, Value? message) {
Message? credentials = message as Message;
assert(credentials != null);
@@ -66,7 +66,7 @@ public class GoogleAuthenticatingPane : Gtk.Grid, Card {
private void on_cancel_button_clicked() {
// spinner's active property doubles as flag if async operation is in progress
if (!spinner.active) {
- dismissed(true);
+ jump_home();
return;
}
@@ -146,7 +146,7 @@ public class GoogleAuthenticatingPane : Gtk.Grid, Card {
private void login_cancelled() {
spinner.active = false;
- dismissed(true);
+ jump_home();
}
}
diff --git a/src/activator/google/activator-google-calendar-list-pane.vala
b/src/activator/google/activator-google-calendar-list-pane.vala
index eceffd0..343bb6e 100644
--- a/src/activator/google/activator-google-calendar-list-pane.vala
+++ b/src/activator/google/activator-google-calendar-list-pane.vala
@@ -64,7 +64,7 @@ public class GoogleCalendarListPane : Gtk.Grid, Card {
return label;
}
- public void jumped_to(Card from, Value? message) {
+ public void jumped_to(Card? from, Value? message) {
Message? feeds = message as Message;
assert(feeds != null);
@@ -92,7 +92,7 @@ public class GoogleCalendarListPane : Gtk.Grid, Card {
[GtkCallback]
private void on_cancel_button_clicked() {
- dismissed(true);
+ jump_home();
}
[GtkCallback]
diff --git a/src/activator/google/activator-google-login-pane.vala
b/src/activator/google/activator-google-login-pane.vala
index 877e8f2..438af3e 100644
--- a/src/activator/google/activator-google-login-pane.vala
+++ b/src/activator/google/activator-google-login-pane.vala
@@ -34,7 +34,7 @@ internal class GoogleLoginPane : Gtk.Grid, Card {
BindingFlags.SYNC_CREATE, on_entry_changed);
}
- public void jumped_to(Card from, Value? msg) {
+ public void jumped_to(Card? from, Value? msg) {
password_entry.text = "";
}
@@ -46,7 +46,7 @@ internal class GoogleLoginPane : Gtk.Grid, Card {
[GtkCallback]
private void on_cancel_button_clicked() {
- dismissed(true);
+ jump_home();
}
[GtkCallback]
diff --git a/src/activator/google/activator-google.vala b/src/activator/google/activator-google.vala
index 503fa53..5c8a3ba 100644
--- a/src/activator/google/activator-google.vala
+++ b/src/activator/google/activator-google.vala
@@ -7,6 +7,8 @@
namespace California.Activator {
internal class GoogleActivator : Instance {
+ public override string first_card_id { get { return GoogleLoginPane.ID; } }
+
private Backing.WebCalSubscribable webcal_store;
public GoogleActivator(string title, Backing.WebCalSubscribable store) {
@@ -15,15 +17,13 @@ internal class GoogleActivator : Instance {
webcal_store = store;
}
- public override Host.Interaction create_interaction(Soup.URI? supplied_uri) {
- Deck deck = new Deck();
+ public override Gee.List<Card> create_cards(Soup.URI? supplied_uri) {
Gee.List<Card> cards = new Gee.ArrayList<Card>();
cards.add(new GoogleLoginPane());
cards.add(new GoogleAuthenticatingPane());
cards.add(new GoogleCalendarListPane(webcal_store));
- deck.add_cards(cards);
- return deck;
+ return cards;
}
}
diff --git a/src/activator/webcal/activator-webcal-pane.vala b/src/activator/webcal/activator-webcal-pane.vala
index 500794c..b2ebc65 100644
--- a/src/activator/webcal/activator-webcal-pane.vala
+++ b/src/activator/webcal/activator-webcal-pane.vala
@@ -7,9 +7,17 @@
namespace California.Activator {
[GtkTemplate (ui = "/org/yorba/california/rc/webcal-subscribe.ui")]
-internal class WebCalActivatorPane : Gtk.Grid, Host.Interaction {
+internal class WebCalActivatorPane : Gtk.Grid, Card {
+ public const string ID = "WebCalActivatorPane";
+
+ public string card_id { get { return ID; } }
+
+ public string? title { get { return null; } }
+
public Gtk.Widget? default_widget { get { return subscribe_button; } }
+ public Gtk.Widget? initial_focus { get { return name_entry; } }
+
[GtkChild]
private Gtk.ColorButton color_button;
@@ -38,6 +46,9 @@ internal class WebCalActivatorPane : Gtk.Grid, Host.Interaction {
BindingFlags.SYNC_CREATE, on_entry_changed);
}
+ public void jumped_to(Card? from, Value? message) {
+ }
+
private bool on_entry_changed(Binding binding, Value source_value, ref Value target_value) {
target_value =
name_entry.text_length > 0
@@ -49,7 +60,7 @@ internal class WebCalActivatorPane : Gtk.Grid, Host.Interaction {
[GtkCallback]
private void on_cancel_button_clicked() {
- dismissed(true);
+ jump_home();
}
[GtkCallback]
diff --git a/src/activator/webcal/activator-webcal.vala b/src/activator/webcal/activator-webcal.vala
index c232adb..9d91dda 100644
--- a/src/activator/webcal/activator-webcal.vala
+++ b/src/activator/webcal/activator-webcal.vala
@@ -7,6 +7,8 @@
namespace California.Activator {
internal class WebCalActivator : Instance {
+ public override string first_card_id { get { return WebCalActivatorPane.ID; } }
+
private Backing.WebCalSubscribable webcal_store;
public WebCalActivator(string title, Backing.WebCalSubscribable store) {
@@ -15,8 +17,11 @@ internal class WebCalActivator : Instance {
webcal_store = store;
}
- public override Host.Interaction create_interaction(Soup.URI? supplied_uri) {
- return new WebCalActivatorPane(webcal_store, supplied_uri);
+ public override Gee.List<Card> create_cards(Soup.URI? supplied_uri) {
+ Gee.List<Card> cards = new Gee.ArrayList<Card>();
+ cards.add(new WebCalActivatorPane(webcal_store, supplied_uri));
+
+ return cards;
}
}
diff --git a/src/rc/activator-list.ui b/src/rc/activator-list.ui
index da0d3bc..37d5cba 100644
--- a/src/rc/activator-list.ui
+++ b/src/rc/activator-list.ui
@@ -21,7 +21,6 @@
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="activate_on_single_click">False</property>
- <signal name="row-activated" handler="on_listbox_row_activated"
object="CaliforniaActivatorInstanceList" swapped="no"/>
</object>
</child>
</object>
@@ -43,7 +42,7 @@
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel_button">
- <property name="label" translatable="yes">_Cancel</property>
+ <property name="label" translatable="yes">_Close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
diff --git a/src/rc/webcal-subscribe.ui b/src/rc/webcal-subscribe.ui
index a20ddd1..df8749a 100644
--- a/src/rc/webcal-subscribe.ui
+++ b/src/rc/webcal-subscribe.ui
@@ -117,6 +117,7 @@
<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">8</property>
<property name="homogeneous">True</property>
<property name="baseline_position">bottom</property>
diff --git a/src/util/util-deck.vala b/src/util/util-deck.vala
index 89e9610..c564152 100644
--- a/src/util/util-deck.vala
+++ b/src/util/util-deck.vala
@@ -46,6 +46,11 @@ public interface Card : Gtk.Widget {
public abstract Gtk.Widget? initial_focus { get; }
/**
+ * Returns the { link Deck} this { link Card} is registered to, if any.
+ */
+ public Deck? deck { get { return parent as Deck; } }
+
+ /**
* Fired when the { link Card} wishes to jump to another Card in the same { link Deck.}
*
* Each Card can accept a message which parameterizes its activation. It's up to Cards
@@ -108,7 +113,7 @@ public interface Card : Gtk.Widget {
* This is called before dealing with { link default_widget} and { link initial_focus}, so
* changes to those properties in this call, if need be.
*/
- public abstract void jumped_to(Card from, Value? message);
+ public abstract void jumped_to(Card? from, Value? message);
}
/**
@@ -124,10 +129,27 @@ public class Deck : Gtk.Stack, Host.Interaction {
*/
public Gtk.Widget? default_widget { get { return null; } }
- public int size { get { return names.size; } }
+ /**
+ * The number of { link Card}s registered to the { link Deck}.
+ */
+ public int size { get { return list.size; } }
- private Card? top = null;
- private Card? home = null;
+ /**
+ * All registered { link Card}s returned as a read-only List.
+ */
+ public Gee.List<Card> cards { owned get { return list.read_only_view; } }
+
+ /**
+ * The home { link Card}.
+ */
+ public Card? home { owned get { return (list.size > 0) ? list[0] : null; } }
+
+ /**
+ * The current displayed { link Card}.
+ */
+ public Card? top { get; private set; default = null; }
+
+ private Gee.List<Card> list = new Gee.LinkedList<Card>();
private Gee.Deque<Card> navigation_stack = new Gee.LinkedList<Card>();
private Gee.HashMap<string, Card> names = new Gee.HashMap<string, Card>();
@@ -207,19 +229,59 @@ public class Deck : Gtk.Stack, Host.Interaction {
// i.e. home)
card.map.connect(on_card_mapped);
- // first Card seen is home card
- if (home == null)
- home = card;
+ // add in order to ensure order is preserved if sparsely removed later
+ list.add(card);
+ }
+
+ if (set_home_visible && home != null) {
+ set_visible_child(home);
+ home.jumped_to(null, null);
+ }
+ }
+
+ /**
+ * Removes { link Card}s from the { link Deck}.
+ *
+ * If the { link top} card is removed, the Deck will return { link home}, clearing the
+ * navigation stack in the process.
+ */
+ public void remove_cards(Gee.Iterable<Card> cards) {
+ bool displaying = top != null;
+
+ foreach (Card card in cards) {
+ if (!names.has_key(card.card_id)) {
+ message("Card %s not found in Deck", card.card_id);
+
+ continue;
+ }
+
+ card.map.disconnect(on_card_mapped);
+
+ remove(card);
+
+ if (top == card)
+ top = null;
+
+ navigation_stack.remove(card);
+ names.unset(card.card_id);
+ list.remove(card);
}
- if (set_home_visible)
+ // if was displaying a Card and now not, jump home
+ if (displaying && top == null && home != null) {
+ navigation_stack.clear();
set_visible_child(home);
+ home.jumped_to(null, null);
+ }
}
private void on_jump_to_card(Card card, Card next, Value? message) {
// do nothing if already visible
- if (get_visible_child() == next)
+ if (get_visible_child() == next) {
+ debug("Already showing card %s", next.card_id);
+
return;
+ }
// do nothing if not registered with this Deck
if (!names.values.contains(next)) {
@@ -250,7 +312,10 @@ public class Deck : Gtk.Stack, Host.Interaction {
// jumping home clears the navigation stack
navigation_stack.clear();
- on_jump_to_card(card, home, null);
+ if (home != null)
+ on_jump_to_card(card, home, null);
+ else
+ message("No home card in Deck");
}
private void on_dismissed(bool user_request) {
diff --git a/src/util/util-listbox-model.vala b/src/util/util-listbox-model.vala
index 090d336..fb8f0d5 100644
--- a/src/util/util-listbox-model.vala
+++ b/src/util/util-listbox-model.vala
@@ -147,6 +147,23 @@ public class ListBoxModel<G> : BaseObject {
}
/**
+ * Add a collection of { link Card}s to the { link Deck}.
+ *
+ * Returns the number of Cards added.
+ *
+ * @see add
+ */
+ public int add_many(Gee.Iterable<G> items) {
+ int count = 0;
+ foreach (G item in items) {
+ if (add(item))
+ count++;
+ }
+
+ return count;
+ }
+
+ /**
* Removes an item from the model, which in turn removes it from the { link listbox}.
*
* Returns true if the model (and therefore the listbox) were altered due to the removal.
@@ -157,6 +174,23 @@ public class ListBoxModel<G> : BaseObject {
return internal_remove(item, true);
}
+ /**
+ * Removes a collection of { link Card}s from the { link Deck}.
+ *
+ * Returns the number of Cards removed.
+ *
+ * @see remove
+ */
+ public int remove_many(Gee.Iterable<G> items) {
+ int count = 0;
+ foreach (G item in items) {
+ if (remove(item))
+ count++;
+ }
+
+ return count;
+ }
+
private bool internal_remove(G item, bool remove_from_listbox) {
Gtk.ListBoxRow row;
if (!items.unset(item, out row))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]