[gnome-control-center/wip/gbsneto/sidelist-groups: 3/4] panel-list: create a custom class to handle the sidelist
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/gbsneto/sidelist-groups: 3/4] panel-list: create a custom class to handle the sidelist
- Date: Tue, 7 Jun 2016 13:16:39 +0000 (UTC)
commit 351f7bbd12d5638003897b920e7b01065230e368
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Mon Jun 6 14:13:54 2016 -0300
panel-list: create a custom class to handle the sidelist
As the sidelist gets more complex, managing it in CcWindow
would make it very confusing.
This patch introduces the CcPanelList, a widget that manages
the sidelist.
https://bugzilla.gnome.org/show_bug.cgi?id=767301
shell/Makefile.am | 7 +
shell/alt/Makefile.am | 3 +
shell/alt/cc-panel-list.c | 615 ++++++++++++++++++++++++++++++
shell/alt/cc-panel-list.h | 67 ++++
shell/gnome-control-center.gresource.xml | 1 +
shell/panel-list.ui | 160 ++++++++
6 files changed, 853 insertions(+), 0 deletions(-)
---
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 36fb22e..44e48f7 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -60,6 +60,12 @@ gnome_control_center_alt_SOURCES = \
gnome_control_center_LDFLAGS = -export-dynamic
gnome_control_center_alt_LDFLAGS = -export-dynamic
+# Temporarily add the CC_ENABLE_ALT_CATEGORIES compile-time
+# flag to keep the current panels working.
+gnome_control_center_alt_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DCC_ENABLE_ALT_CATEGORIES
+
gnome_control_center_LDADD = \
libshell.la \
$(SHELL_LIBS) \
@@ -149,6 +155,7 @@ EXTRA_DIST = \
$(completion_in_files) \
gnome-control-center.gresource.xml \
help-overlay.ui \
+ panel-list.ui \
window.ui \
$(resource_files) \
list-panel.sh
diff --git a/shell/alt/Makefile.am b/shell/alt/Makefile.am
index 948b019..235d131 100644
--- a/shell/alt/Makefile.am
+++ b/shell/alt/Makefile.am
@@ -1,5 +1,6 @@
AM_CPPFLAGS = \
-DGNOMELOCALEDIR="\"$(datadir)/locale\""\
+ -DCC_ENABLE_ALT_CATEGORIES \
-I$(top_srcdir) \
$(SHELL_CFLAGS) \
$(CHEESE_CFLAGS) \
@@ -11,6 +12,8 @@ AM_CPPFLAGS = \
noinst_LTLIBRARIES = libshell_alt.la
libshell_alt_la_SOURCES = \
+ cc-panel-list.c \
+ cc-panel-list.h \
cc-window.c \
cc-window.h
diff --git a/shell/alt/cc-panel-list.c b/shell/alt/cc-panel-list.c
new file mode 100644
index 0000000..b22a432
--- /dev/null
+++ b/shell/alt/cc-panel-list.c
@@ -0,0 +1,615 @@
+/* cc-panel-list.c
+ *
+ * Copyright (C) 2016 Endless, Inc
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Georges Basile Stavracas Neto <gbsneto gnome org>
+ */
+
+#include "cc-panel.h"
+#include "cc-panel-list.h"
+#include "cc-util.h"
+
+typedef struct
+{
+ GtkWidget *row;
+ GtkWidget *description_label;
+ CcPanelCategory category;
+ gchar *id;
+ gchar *name;
+ gchar *description;
+} RowData;
+
+struct _CcPanelList
+{
+ GtkStack parent;
+
+ GtkWidget *details_listbox;
+ GtkWidget *devices_listbox;
+ GtkWidget *main_listbox;
+ GtkWidget *search_listbox;
+
+ GtkListBoxRow *details_row;
+ GtkListBoxRow *devices_row;
+
+ gchar *search_query;
+
+ CcPanelListView previous_view;
+ CcPanelListView view;
+};
+
+G_DEFINE_TYPE (CcPanelList, cc_panel_list, GTK_TYPE_STACK)
+
+enum
+{
+ PROP_0,
+ PROP_SEARCH_QUERY,
+ PROP_VIEW,
+ N_PROPS
+};
+
+enum
+{
+ SHOW_PANEL,
+ LAST_SIGNAL
+};
+
+static GParamSpec *properties [N_PROPS] = { NULL, };
+static gint signals [LAST_SIGNAL] = { 0, };
+
+/*
+ * RowData functions
+ */
+static void
+row_data_free (RowData *data)
+{
+ g_free (data->description);
+ g_free (data->name);
+ g_free (data);
+}
+
+static RowData*
+row_data_new (CcPanelCategory category,
+ const gchar *id,
+ const gchar *name,
+ const gchar *description,
+ const gchar *icon)
+{
+ GtkWidget *label, *grid, *image;
+ RowData *data;
+
+ data = g_new0 (RowData, 1);
+ data->category = category;
+ data->row = gtk_list_box_row_new ();
+ data->id = g_strdup (id);
+ data->name = g_strdup (name);
+ data->description = g_strdup (description);
+
+ /* Setup the row */
+ grid = g_object_new (GTK_TYPE_GRID,
+ "visible", TRUE,
+ "hexpand", TRUE,
+ "border-width", 12,
+ "column-spacing", 6,
+ NULL);
+
+ /* Icon */
+ image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
+ gtk_grid_attach (GTK_GRID (grid), image, 0, 0, 1, 1);
+
+ gtk_widget_show (image);
+
+ /* Name label */
+ label = g_object_new (GTK_TYPE_LABEL,
+ "label", name,
+ "visible", TRUE,
+ "xalign", 0.0,
+ "hexpand", TRUE,
+ NULL);
+ gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
+
+ /* Description label */
+ label = g_object_new (GTK_TYPE_LABEL,
+ "label", description,
+ "visible", FALSE,
+ "xalign", 0.0,
+ "hexpand", TRUE,
+ NULL);
+ gtk_label_set_max_width_chars (GTK_LABEL (label), 25);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+
+ gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
+ gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
+
+ data->description_label = label;
+
+ gtk_container_add (GTK_CONTAINER (data->row), grid);
+ gtk_widget_show (data->row);
+
+ g_object_set_data_full (G_OBJECT (data->row), "data", data, (GDestroyNotify) row_data_free);
+
+ return data;
+}
+
+/*
+ * GtkListBox functions
+ */
+static gboolean
+filter_func (GtkListBoxRow *row,
+ gpointer user_data)
+{
+ CcPanelList *self;
+ RowData *data;
+ gchar *search_text, *panel_text, *panel_description;
+ gboolean retval;
+
+ self = CC_PANEL_LIST (user_data);
+ data = g_object_get_data (G_OBJECT (row), "data");
+
+ if (!self->search_query)
+ return TRUE;
+
+ panel_text = cc_util_normalize_casefold_and_unaccent (data->name);
+ search_text = cc_util_normalize_casefold_and_unaccent (self->search_query);
+ panel_description = cc_util_normalize_casefold_and_unaccent (data->description);
+
+ g_strstrip (panel_text);
+ g_strstrip (search_text);
+ g_strstrip (panel_description);
+
+ /*
+ * The description label is only visible when the search is
+ * happening.
+ */
+ gtk_widget_set_visible (data->description_label, g_utf8_strlen (search_text, -1) > 0);
+
+ retval = g_strstr_len (panel_text, -1, search_text) != NULL ||
+ g_strstr_len (panel_description, -1, search_text) != NULL;
+
+ g_free (panel_text);
+ g_free (search_text);
+ g_free (panel_description);
+
+ return retval;
+}
+
+static gint
+sort_function (GtkListBoxRow *a,
+ GtkListBoxRow *b,
+ gpointer user_data)
+{
+ CcPanelList *self;
+ RowData *a_data, *b_data;
+
+ self = CC_PANEL_LIST (user_data);
+
+ /* Handle the Devices and the Details rows */
+ if (a == self->details_row && b == self->devices_row)
+ return 1;
+ if (a == self->devices_row && b == self->details_row)
+ return -1;
+ if (a == self->details_row || a == self->devices_row)
+ return 1;
+ if (b == self->details_row || b == self->devices_row)
+ return -1;
+
+ /*
+ * We can only retrieve the data after assuring that none
+ * of the rows are Devices and Details.
+ */
+ a_data = g_object_get_data (G_OBJECT (a), "data");
+ b_data = g_object_get_data (G_OBJECT (b), "data");
+
+ if (a_data->category != b_data->category)
+ return a_data->category - b_data->category;
+
+ return g_strcmp0 (a_data->name, b_data->name);
+}
+
+static void
+header_func (GtkListBoxRow *row,
+ GtkListBoxRow *before,
+ gpointer user_data)
+{
+ CcPanelList *self = CC_PANEL_LIST (user_data);
+
+ if (!before)
+ return;
+
+ /* The Details row always have the separator */
+ if (row == self->details_row)
+ {
+ GtkWidget *separator;
+
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_set_hexpand (separator, TRUE);
+ gtk_widget_show (separator);
+
+ gtk_list_box_row_set_header (row, separator);
+ }
+ else
+ {
+ RowData *row_data, *before_data;
+
+ if (row == self->devices_row ||
+ before == self->details_row ||
+ before == self->devices_row)
+ {
+ return;
+ }
+
+ /*
+ * We can only retrieve the data after assuring that none
+ * of the rows are Devices and Details.
+ */
+ row_data = g_object_get_data (G_OBJECT (row), "data");
+ before_data = g_object_get_data (G_OBJECT (before), "data");
+
+ if (row_data->category != before_data->category)
+ {
+ GtkWidget *separator;
+
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_set_hexpand (separator, TRUE);
+ gtk_widget_show (separator);
+
+ gtk_list_box_row_set_header (row, separator);
+ }
+ }
+}
+
+/*
+ * Callbacks
+ */
+static void
+row_activated_cb (GtkWidget *listbox,
+ GtkListBoxRow *row,
+ CcPanelList *self)
+{
+ RowData *data;
+
+ /* Search */
+ if (listbox == self->search_listbox)
+ {
+ cc_panel_list_set_view (self, self->previous_view);
+ return;
+ }
+
+ /* Details */
+ if (row == self->details_row)
+ {
+ cc_panel_list_set_view (self, CC_PANEL_LIST_DETAILS);
+ return;
+ }
+
+ /* Devices */
+ if (row == self->devices_row)
+ {
+ cc_panel_list_set_view (self, CC_PANEL_LIST_DEVICES);
+ return;
+ }
+
+ /*
+ * When a panel is selected, the previous one should be
+ * unselected, except when it's search.
+ */
+ if (listbox != self->search_listbox)
+ {
+ if (listbox != self->main_listbox)
+ gtk_list_box_unselect_all (GTK_LIST_BOX (self->main_listbox));
+
+ if (listbox != self->details_listbox)
+ gtk_list_box_unselect_all (GTK_LIST_BOX (self->details_listbox));
+
+ if (listbox != self->devices_listbox)
+ gtk_list_box_unselect_all (GTK_LIST_BOX (self->devices_listbox));
+ }
+
+ data = g_object_get_data (G_OBJECT (row), "data");
+
+ g_signal_emit (self, signals[SHOW_PANEL], 0, data->id);
+}
+
+static void
+cc_panel_list_finalize (GObject *object)
+{
+ CcPanelList *self = (CcPanelList *)object;
+
+ g_clear_pointer (&self->search_query, g_free);
+
+ G_OBJECT_CLASS (cc_panel_list_parent_class)->finalize (object);
+}
+
+static void
+cc_panel_list_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CcPanelList *self = CC_PANEL_LIST (object);
+
+ switch (prop_id)
+ {
+ case PROP_SEARCH_QUERY:
+ g_value_set_string (value, self->search_query);
+ break;
+
+ case PROP_VIEW:
+ g_value_set_int (value, self->view);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+cc_panel_list_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CcPanelList *self = CC_PANEL_LIST (object);
+
+ switch (prop_id)
+ {
+ case PROP_SEARCH_QUERY:
+ cc_panel_list_set_search_query (self, g_value_get_string (value));
+ break;
+
+ case PROP_VIEW:
+ cc_panel_list_set_view (self, g_value_get_int (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+cc_panel_list_class_init (CcPanelListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = cc_panel_list_finalize;
+ object_class->get_property = cc_panel_list_get_property;
+ object_class->set_property = cc_panel_list_set_property;
+
+ /**
+ * CcPanelList:show-panel:
+ *
+ * Emited when a panel is selected.
+ */
+ signals[SHOW_PANEL] = g_signal_new ("show-panel",
+ CC_TYPE_PANEL_LIST,
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+
+ /**
+ * CcPanelList:search-query:
+ *
+ * The search that is being applied to sidelist.
+ */
+ properties[PROP_SEARCH_QUERY] = g_param_spec_string ("search-query",
+ "Search query",
+ "The current search query",
+ NULL,
+ G_PARAM_READWRITE);
+
+ /**
+ * CcPanelList:view:
+ *
+ * The current view of the sidelist.
+ */
+ properties[PROP_VIEW] = g_param_spec_int ("view",
+ "View",
+ "The current view of the sidelist",
+ CC_PANEL_LIST_MAIN,
+ CC_PANEL_LIST_SEARCH,
+ CC_PANEL_LIST_MAIN,
+ G_PARAM_READWRITE);
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/ControlCenter/gtk/panel-list.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, CcPanelList, details_listbox);
+ gtk_widget_class_bind_template_child (widget_class, CcPanelList, details_row);
+ gtk_widget_class_bind_template_child (widget_class, CcPanelList, devices_listbox);
+ gtk_widget_class_bind_template_child (widget_class, CcPanelList, devices_row);
+ gtk_widget_class_bind_template_child (widget_class, CcPanelList, main_listbox);
+ gtk_widget_class_bind_template_child (widget_class, CcPanelList, search_listbox);
+
+ gtk_widget_class_bind_template_callback (widget_class, row_activated_cb);
+}
+
+static void
+cc_panel_list_init (CcPanelList *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->view = CC_PANEL_LIST_MAIN;
+
+ gtk_list_box_set_sort_func (GTK_LIST_BOX (self->main_listbox),
+ sort_function,
+ self,
+ NULL);
+
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->main_listbox),
+ header_func,
+ self,
+ NULL);
+
+ gtk_list_box_set_filter_func (GTK_LIST_BOX (self->search_listbox),
+ filter_func,
+ self,
+ NULL);
+}
+
+GtkWidget*
+cc_panel_list_new (void)
+{
+ return g_object_new (CC_TYPE_PANEL_LIST, NULL);
+}
+
+gboolean
+cc_panel_list_activate (CcPanelList *self)
+{
+ GtkListBoxRow *row;
+
+ g_return_val_if_fail (CC_IS_PANEL_LIST (self), FALSE);
+ g_return_val_if_fail (self->view == CC_PANEL_LIST_SEARCH, FALSE);
+
+ row = gtk_list_box_get_row_at_y (GTK_LIST_BOX (self->search_listbox), 0);
+
+ if (row)
+ {
+ gtk_list_box_select_row (GTK_LIST_BOX (self->search_listbox), row);
+ gtk_widget_grab_focus (GTK_WIDGET (row));
+ }
+
+ return row != NULL;
+}
+
+const gchar*
+cc_panel_list_get_search_query (CcPanelList *self)
+{
+ g_return_val_if_fail (CC_IS_PANEL_LIST (self), NULL);
+
+ return self->search_query;
+}
+
+void
+cc_panel_list_set_search_query (CcPanelList *self,
+ const gchar *search)
+{
+ g_return_if_fail (CC_IS_PANEL_LIST (self));
+
+ if (g_strcmp0 (self->search_query, search) != 0)
+ {
+ g_clear_pointer (&self->search_query, g_free);
+ self->search_query = g_strdup (search);
+
+ if (search && g_utf8_strlen (search, -1) > 0)
+ cc_panel_list_set_view (self, CC_PANEL_LIST_SEARCH);
+ else
+ cc_panel_list_set_view (self, self->previous_view);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SEARCH_QUERY]);
+
+ gtk_list_box_invalidate_filter (GTK_LIST_BOX (self->search_listbox));
+ }
+}
+
+CcPanelListView
+cc_panel_list_get_view (CcPanelList *self)
+{
+ g_return_val_if_fail (CC_IS_PANEL_LIST (self), -1);
+
+ return self->view;
+}
+
+void
+cc_panel_list_set_view (CcPanelList *self,
+ CcPanelListView view)
+{
+ g_return_if_fail (CC_IS_PANEL_LIST (self));
+
+ if (self->view != view)
+ {
+ GtkWidget *visible_child;
+ gboolean should_crossfade;
+
+ self->previous_view = self->view;
+ self->view = view;
+
+ /*
+ * When changing to or from the search view, the animation should
+ * be crossfade. Otherwise, it's the previous-forward movement.
+ */
+ should_crossfade = view == CC_PANEL_LIST_SEARCH ||
+ self->previous_view == CC_PANEL_LIST_SEARCH;
+
+ gtk_stack_set_transition_type (GTK_STACK (self),
+ should_crossfade ? GTK_STACK_TRANSITION_TYPE_CROSSFADE :
+ GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT);
+
+ switch (view)
+ {
+ case CC_PANEL_LIST_MAIN:
+ visible_child = self->main_listbox;
+ break;
+
+ case CC_PANEL_LIST_DETAILS:
+ visible_child = self->details_listbox;
+ break;
+
+ case CC_PANEL_LIST_DEVICES:
+ visible_child = self->devices_listbox;
+ break;
+
+ case CC_PANEL_LIST_SEARCH:
+ visible_child = self->search_listbox;
+ break;
+ }
+
+ gtk_stack_set_visible_child (GTK_STACK (self), visible_child);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VIEW]);
+ }
+}
+
+void
+cc_panel_list_add_panel (CcPanelList *self,
+ CcPanelCategory category,
+ const gchar *id,
+ const gchar *title,
+ const gchar *description,
+ const gchar *icon)
+{
+ GtkWidget *listbox;
+ RowData *data, *search_data;
+
+ g_return_if_fail (CC_IS_PANEL_LIST (self));
+
+ /* Add the panel to the proper listbox */
+ data = row_data_new (category, id, title, description, icon);
+
+ switch (category)
+ {
+ case CC_CATEGORY_DEVICES:
+ listbox = self->devices_listbox;
+ break;
+
+ case CC_CATEGORY_DETAILS:
+ listbox = self->details_listbox;
+ break;
+
+ default:
+ listbox = self->main_listbox;
+ break;
+ }
+
+ gtk_container_add (GTK_CONTAINER (listbox), data->row);
+
+ /* And add to the search listbox too */
+ search_data = row_data_new (category, id, title, description, icon);
+ gtk_container_add (GTK_CONTAINER (self->search_listbox), search_data->row);
+}
diff --git a/shell/alt/cc-panel-list.h b/shell/alt/cc-panel-list.h
new file mode 100644
index 0000000..0cd1880
--- /dev/null
+++ b/shell/alt/cc-panel-list.h
@@ -0,0 +1,67 @@
+/* cc-panel-list.c
+ *
+ * Copyright (C) 2016 Endless, Inc
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Georges Basile Stavracas Neto <gbsneto gnome org>
+ */
+
+#ifndef CC_PANEL_LIST_H
+#define CC_PANEL_LIST_H
+
+#include <glib-object.h>
+
+#include "cc-panel.h"
+#include "cc-shell-model.h"
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ CC_PANEL_LIST_MAIN,
+ CC_PANEL_LIST_DETAILS,
+ CC_PANEL_LIST_DEVICES,
+ CC_PANEL_LIST_SEARCH
+} CcPanelListView;
+
+#define CC_TYPE_PANEL_LIST (cc_panel_list_get_type())
+
+G_DECLARE_FINAL_TYPE (CcPanelList, cc_panel_list, CC, PANEL_LIST, GtkStack)
+
+GtkWidget* cc_panel_list_new (void);
+
+gboolean cc_panel_list_activate (CcPanelList *self);
+
+const gchar* cc_panel_list_get_search_query (CcPanelList *self);
+
+void cc_panel_list_set_search_query (CcPanelList *self,
+ const gchar *search);
+
+CcPanelListView cc_panel_list_get_view (CcPanelList *self);
+
+void cc_panel_list_set_view (CcPanelList *self,
+ CcPanelListView view);
+
+void cc_panel_list_add_panel (CcPanelList *self,
+ CcPanelCategory category,
+ const gchar *id,
+ const gchar *title,
+ const gchar *description,
+ const gchar *icon);
+
+G_END_DECLS
+
+#endif /* CC_PANEL_LIST_H */
+
diff --git a/shell/gnome-control-center.gresource.xml b/shell/gnome-control-center.gresource.xml
index d4256cb..2482393 100644
--- a/shell/gnome-control-center.gresource.xml
+++ b/shell/gnome-control-center.gresource.xml
@@ -2,6 +2,7 @@
<gresources>
<gresource prefix="/org/gnome/ControlCenter/gtk">
<file preprocess="xml-stripblanks">help-overlay.ui</file>
+ <file preprocess="xml-stripblanks">panel-list.ui</file>
<file preprocess="xml-stripblanks">window.ui</file>
</gresource>
</gresources>
diff --git a/shell/panel-list.ui b/shell/panel-list.ui
new file mode 100644
index 0000000..314fa7d
--- /dev/null
+++ b/shell/panel-list.ui
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+ <template class="CcPanelList" parent="GtkStack">
+ <property name="width_request">200</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vhomogeneous">False</property>
+ <property name="transition_type">slide-left-right</property>
+ <child>
+ <object class="GtkListBox" id="main_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <signal name="row-activated" handler="row_activated_cb" object="CcPanelList" swapped="no" />
+ <child>
+ <object class="GtkListBoxRow" id="devices_row">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="selectable">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">applications-system-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Devices</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">go-next-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkListBoxRow" id="details_row">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="selectable">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">applications-system-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Details</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">go-next-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="name">main</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkListBox" id="devices_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <signal name="row-activated" handler="row_activated_cb" object="CcPanelList" swapped="no" />
+ </object>
+ <packing>
+ <property name="name">devices</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkListBox" id="details_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <signal name="row-activated" handler="row_activated_cb" object="CcPanelList" swapped="no" />
+ </object>
+ <packing>
+ <property name="name">details</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkListBox" id="search_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <signal name="row-activated" handler="row_activated_cb" object="CcPanelList" swapped="no" />
+ </object>
+ <packing>
+ <property name="name">search</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </template>
+</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]