[gnome-builder] views: add document selection popover
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] views: add document selection popover
- Date: Tue, 24 Mar 2015 21:37:05 +0000 (UTC)
commit f8cc584bf67d2b9e75e2f6ede8637d8602931ea3
Author: Christian Hergert <christian hergert me>
Date: Tue Mar 24 14:36:59 2015 -0700
views: add document selection popover
I'm not sure about this long term, but this is a stop gap until we figure
out the design further. In particular, it is difficult to select documents
that are not yet in git.
Some alternate approaches are to simply add the files to git immediately.
This was going to be the case once we have templates for things like
GObjects, widgets, resources, icons, etc. However, that doesn't help the
situation for temporary buffers.
Clearly we could choose a better icon.
This needs design review, and some careful planning as we go forward. I
have a couple other ideas on placement, but this is the minimal patch
that solves the problem at hand.
Signed-off-by: Christian Hergert <christian hergert me>
data/ui/gb-view-stack.ui | 42 ++++++++++++
src/views/gb-view-stack-private.h | 2 +
src/views/gb-view-stack.c | 129 ++++++++++++++++++++++++++++++++++++-
3 files changed, 170 insertions(+), 3 deletions(-)
---
diff --git a/data/ui/gb-view-stack.ui b/data/ui/gb-view-stack.ui
index 860dc47..9aaff68 100644
--- a/data/ui/gb-view-stack.ui
+++ b/data/ui/gb-view-stack.ui
@@ -62,6 +62,26 @@
</child>
</object>
</child>
+ <child>
+ <object class="GtkMenuButton" id="views_button">
+ <property name="visible">true</property>
+ <property name="popover">views_popover</property>
+ <style>
+ <class name="dim-label"/>
+ <class name="image-button"/>
+ <class name="flat"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon-name">system-file-manager-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack-type">start</property>
+ </packing>
+ </child>
<child type="center">
<object class="GtkMenuButton" id="document_button">
<property name="hexpand">true</property>
@@ -326,6 +346,28 @@
</object>
</child>
</object>
+ <object class="GtkPopover" id="views_popover">
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GbScrolledWindow">
+ <property name="max-content-height">400</property>
+ <property name="min-content-height">30</property>
+ <property name="min-content-width">100</property>
+ <property name="max-content-width">300</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkListBox" id="views_listbox">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
<object class="GtkSizeGroup">
<property name="mode">horizontal</property>
<widgets>
diff --git a/src/views/gb-view-stack-private.h b/src/views/gb-view-stack-private.h
index b1d2456..4d34a7e 100644
--- a/src/views/gb-view-stack-private.h
+++ b/src/views/gb-view-stack-private.h
@@ -47,6 +47,8 @@ struct _GbViewStack
GtkPopover *popover;
GtkStack *stack;
GtkLabel *title_label;
+ GtkListBox *views_button;
+ GtkListBox *views_listbox;
guint destroyed : 1;
guint focused : 1;
diff --git a/src/views/gb-view-stack.c b/src/views/gb-view-stack.c
index 47d6cd7..d8aade5 100644
--- a/src/views/gb-view-stack.c
+++ b/src/views/gb-view-stack.c
@@ -46,6 +46,90 @@ static GParamSpec *gParamSpecs [LAST_PROP];
static guint gSignals [LAST_SIGNAL];
static void
+gb_view_stack_add_list_row (GbViewStack *self,
+ GbView *child)
+{
+ GtkWidget *row;
+ GtkWidget *label;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (GB_IS_VIEW (child));
+
+ row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
+ "visible", TRUE,
+ NULL);
+ label = g_object_new (GTK_TYPE_LABEL,
+ "margin-bottom", 3,
+ "margin-end", 6,
+ "margin-start", 6,
+ "margin-top", 3,
+ "visible", TRUE,
+ "xalign", 0.0f,
+ NULL);
+ g_object_bind_property (child, "title", label, "label", G_BINDING_SYNC_CREATE);
+ g_object_set_data (G_OBJECT (row), "GB_VIEW", child);
+ gtk_container_add (GTK_CONTAINER (row), label);
+ gtk_container_add (GTK_CONTAINER (self->views_listbox), row);
+}
+
+static void
+gb_view_stack_remove_list_row (GbViewStack *self,
+ GbView *child)
+{
+ GList *children;
+ GList *iter;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (GB_IS_VIEW (child));
+
+ children = gtk_container_get_children (GTK_CONTAINER (self->views_listbox));
+
+ for (iter = children; iter; iter = iter->next)
+ {
+ GbView *view = g_object_get_data (iter->data, "GB_VIEW");
+
+ if (view == child)
+ {
+ gtk_container_remove (GTK_CONTAINER (self->views_listbox), iter->data);
+ break;
+ }
+ }
+
+ g_list_free (children);
+}
+
+static void
+gb_view_stack_move_top_list_row (GbViewStack *self,
+ GbView *view)
+{
+ GList *children;
+ GList *iter;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (GB_IS_VIEW (view));
+
+ children = gtk_container_get_children (GTK_CONTAINER (self->views_listbox));
+
+ for (iter = children; iter; iter = iter->next)
+ {
+ GtkWidget *row = iter->data;
+ GbView *item = g_object_get_data (G_OBJECT (row), "GB_VIEW");
+
+ if (item == view)
+ {
+ g_object_ref (row);
+ gtk_container_remove (GTK_CONTAINER (self->views_listbox), row);
+ gtk_list_box_prepend (self->views_listbox, row);
+ gtk_list_box_select_row (self->views_listbox, GTK_LIST_BOX_ROW (row));
+ g_object_unref (row);
+ break;
+ }
+ }
+
+ g_list_free (children);
+}
+
+static void
gb_view_stack_add (GtkContainer *container,
GtkWidget *child)
{
@@ -59,6 +143,7 @@ gb_view_stack_add (GtkContainer *container,
gtk_widget_set_sensitive (GTK_WIDGET (self->close_button), TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (self->document_button), TRUE);
+ gtk_widget_set_visible (GTK_WIDGET (self->views_button), TRUE);
self->focus_history = g_list_prepend (self->focus_history, child);
controls = gb_view_get_controls (GB_VIEW (child));
@@ -66,6 +151,7 @@ gb_view_stack_add (GtkContainer *container,
gtk_container_add (GTK_CONTAINER (self->controls_stack), controls);
gtk_container_add (GTK_CONTAINER (self->stack), child);
gb_view_set_back_forward_list (GB_VIEW (child), self->back_forward_list);
+ gb_view_stack_add_list_row (self, GB_VIEW (child));
gtk_stack_set_visible_child (self->stack, child);
}
else
@@ -83,6 +169,8 @@ gb_view_stack_remove (GbViewStack *self,
g_assert (GB_IS_VIEW_STACK (self));
g_assert (GB_IS_VIEW (view));
+ gb_view_stack_remove_list_row (self, view);
+
self->focus_history = g_list_remove (self->focus_history, view);
controls = gb_view_get_controls (view);
if (controls)
@@ -162,6 +250,7 @@ gb_view_stack_real_empty (GbViewStack *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->close_button), FALSE);
gtk_widget_set_sensitive (GTK_WIDGET (self->document_button), FALSE);
gtk_widget_set_visible (GTK_WIDGET (self->modified_label), FALSE);
+ gtk_widget_set_visible (GTK_WIDGET (self->views_button), FALSE);
}
}
@@ -268,6 +357,26 @@ gb_view_stack_hierarchy_changed (GtkWidget *widget,
}
static void
+gb_view_stack__views_listbox_row_activated_cb (GbViewStack *self,
+ GtkListBoxRow *row,
+ GtkListBox *list_box)
+{
+ GbView *view;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (GTK_IS_LIST_BOX_ROW (row));
+ g_assert (GTK_IS_LIST_BOX (list_box));
+
+ view = g_object_get_data (G_OBJECT (row), "GB_VIEW");
+
+ if (GB_IS_VIEW (view))
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->views_button), FALSE);
+ gb_view_stack_set_active_view (self, GTK_WIDGET (view));
+ }
+}
+
+static void
gb_view_stack_destroy (GtkWidget *widget)
{
GbViewStack *self = (GbViewStack *)widget;
@@ -284,6 +393,12 @@ gb_view_stack_constructed (GObject *object)
G_OBJECT_CLASS (gb_view_stack_parent_class)->constructed (object);
+ g_signal_connect_object (self->views_listbox,
+ "row-activated",
+ G_CALLBACK (gb_view_stack__views_listbox_row_activated_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
gb_view_stack_actions_init (self);
}
@@ -397,6 +512,8 @@ gb_view_stack_class_init (GbViewStackClass *klass)
GB_WIDGET_CLASS_BIND (klass, GbViewStack, popover);
GB_WIDGET_CLASS_BIND (klass, GbViewStack, stack);
GB_WIDGET_CLASS_BIND (klass, GbViewStack, title_label);
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, views_button);
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, views_listbox);
}
static void
@@ -455,29 +572,35 @@ gb_view_stack_set_active_view (GbViewStack *self,
GBinding *binding;
GActionGroup *group;
+ ide_set_weak_pointer (&self->active_view, active_view);
+ if (active_view != gtk_stack_get_visible_child (self->stack))
+ gtk_stack_set_visible_child (self->stack, active_view);
+
self->focus_history = g_list_remove (self->focus_history, active_view);
self->focus_history = g_list_prepend (self->focus_history, active_view);
- if (active_view != gtk_stack_get_visible_child (self->stack))
- gtk_stack_set_visible_child (self->stack, active_view);
binding = g_object_bind_property (active_view, "title",
self->title_label, "label",
G_BINDING_SYNC_CREATE);
ide_set_weak_pointer (&self->title_binding, binding);
+
binding = g_object_bind_property (active_view, "modified",
self->modified_label, "visible",
G_BINDING_SYNC_CREATE);
ide_set_weak_pointer (&self->modified_binding, binding);
- ide_set_weak_pointer (&self->active_view, active_view);
+
controls = gb_view_get_controls (GB_VIEW (active_view));
if (controls)
{
gtk_stack_set_visible_child (self->controls_stack, controls);
gtk_widget_show (GTK_WIDGET (self->controls_stack));
}
+
group = gtk_widget_get_action_group (active_view, "view");
if (group)
gtk_widget_insert_action_group (GTK_WIDGET (self), "view", group);
+
+ gb_view_stack_move_top_list_row (self, GB_VIEW (active_view));
}
g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_ACTIVE_VIEW]);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]