diff options
author | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2017-06-25 17:12:23 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2017-12-30 13:42:16 -0300 |
commit | 8ad93eebb8caccfd352f87cca92bfad662d01817 (patch) | |
tree | 5864b7fe26c9c059e5565743a6e05ae8a7a53005 /gladeui/glade-adaptor-chooser.c | |
parent | 02afd232db8ef6cf8aaf906bf14796a91679bff1 (diff) | |
download | glade-8ad93eebb8caccfd352f87cca92bfad662d01817.tar.gz |
GladeAdaptorChooser: implemented new class to replace palette
Diffstat (limited to 'gladeui/glade-adaptor-chooser.c')
-rw-r--r-- | gladeui/glade-adaptor-chooser.c | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/gladeui/glade-adaptor-chooser.c b/gladeui/glade-adaptor-chooser.c new file mode 100644 index 00000000..68b47ea8 --- /dev/null +++ b/gladeui/glade-adaptor-chooser.c @@ -0,0 +1,343 @@ +/* + * glade-adaptor-chooser.c + * + * Copyright (C) 2017 Juan Pablo Ugarte + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Authors: + * Juan Pablo Ugarte <juanpablougarte@gmail.com> + */ + +#include "glade-adaptor-chooser-widget.h" +#include "glade-adaptor-chooser.h" +#include "glade-app.h" + +typedef struct +{ + GladeProject *project; + + GtkWidget *gtk_button_box; + GtkWidget *extra_button; + GtkWidget *others_button; + GtkImage *class_image; + GtkLabel *class_label; + GtkWidget *all_button; + + GList *choosers; +} GladeAdaptorChooserPrivate; + +struct _GladeAdaptorChooser +{ + GtkBox parent_instance; +}; + +enum +{ + PROP_0, + PROP_PROJECT, + + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES]; + +G_DEFINE_TYPE_WITH_PRIVATE (GladeAdaptorChooser, + glade_adaptor_chooser, + GTK_TYPE_BOX); + +#define GET_PRIVATE(d) ((GladeAdaptorChooserPrivate *) glade_adaptor_chooser_get_instance_private((GladeAdaptorChooser*)d)) + +static void +glade_adaptor_chooser_init (GladeAdaptorChooser *chooser) +{ + gtk_widget_init_template (GTK_WIDGET (chooser)); +} + +static void +glade_adaptor_chooser_finalize (GObject *object) +{ + GladeAdaptorChooserPrivate *priv = GET_PRIVATE (object); + + g_list_free (priv->choosers); + + G_OBJECT_CLASS (glade_adaptor_chooser_parent_class)->finalize (object); +} + +static void +glade_adaptor_chooser_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER (object)); + + switch (prop_id) + { + case PROP_PROJECT: + glade_adaptor_chooser_set_project (GLADE_ADAPTOR_CHOOSER (object), + g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +glade_adaptor_chooser_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GladeAdaptorChooserPrivate *priv; + + g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER (object)); + priv = GET_PRIVATE (object); + + switch (prop_id) + { + case PROP_PROJECT: + g_value_set_object (value, priv->project); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +on_adaptor_selected (GtkWidget *widget, + GladeWidgetAdaptor *adaptor, + GladeAdaptorChooser *chooser) +{ + GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser); + + /* Auto-create toplevel types */ + if (GWA_IS_TOPLEVEL (adaptor)) + { + glade_command_create (adaptor, NULL, NULL, priv->project); + } + else + { + glade_project_set_add_item (priv->project, adaptor); + glade_project_set_pointer_mode (priv->project, GLADE_POINTER_ADD_WIDGET); + } + + gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_parent (widget))); +} + +static void +glade_adaptor_chooser_button_add_chooser (GtkWidget *button, GtkWidget *chooser) +{ + GtkWidget *popover; + + popover = gtk_popover_new (button); + gtk_container_add (GTK_CONTAINER (popover), chooser); + gtk_widget_show (chooser); + + gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), popover); +} + +static GtkWidget * +glade_adaptor_chooser_add_chooser (GladeAdaptorChooser *chooser) +{ + GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser); + GtkWidget *chooser_widget = _glade_adaptor_chooser_widget_new (0, NULL); + + priv->choosers = g_list_prepend (priv->choosers, chooser_widget); + g_signal_connect (chooser_widget, "adaptor-selected", + G_CALLBACK (on_adaptor_selected), + chooser); + + return chooser_widget; +} + +static void +button_box_populate_from_catalog (GladeAdaptorChooser *chooser, + GladeCatalog *catalog) +{ + GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser); + GtkWidget *extra_chooser = NULL; + GList *groups; + + groups = glade_catalog_get_widget_groups (catalog); + gtk_box_set_homogeneous (GTK_BOX (priv->gtk_button_box), FALSE); + + for (; groups; groups = g_list_next (groups)) + { + GladeWidgetGroup *group = GLADE_WIDGET_GROUP (groups->data); + + if (!glade_widget_group_get_adaptors (group)) + continue; + + if (glade_widget_group_get_expanded (group)) + { + GtkWidget *button, *chooser_widget; + + chooser_widget = glade_adaptor_chooser_add_chooser (chooser); + button = gtk_menu_button_new (); + gtk_button_set_label (GTK_BUTTON (button), glade_widget_group_get_title (group)); + glade_adaptor_chooser_button_add_chooser (button, chooser_widget); + _glade_adaptor_chooser_widget_add_group (GLADE_ADAPTOR_CHOOSER_WIDGET (chooser_widget), group); + gtk_box_pack_start (GTK_BOX (priv->gtk_button_box), button, FALSE, FALSE, 0); + gtk_widget_show (button); + } + else + { + if (!extra_chooser) + { + extra_chooser = glade_adaptor_chooser_add_chooser (chooser); + glade_adaptor_chooser_button_add_chooser (priv->extra_button, extra_chooser); + gtk_widget_show (priv->extra_button); + } + + _glade_adaptor_chooser_widget_add_group (GLADE_ADAPTOR_CHOOSER_WIDGET (extra_chooser), group); + } + } +} + +static void +glade_adaptor_chooser_constructed (GObject *object) +{ + GladeAdaptorChooser *chooser = GLADE_ADAPTOR_CHOOSER (object); + GladeAdaptorChooserPrivate *priv = GET_PRIVATE (object); + GtkWidget *others_chooser, *all_chooser; + GladeCatalog *gtk_catalog; + GList *l; + + /* GTK+ catalog goes first subdivided by group */ + gtk_catalog = glade_app_get_catalog ("gtk+"); + button_box_populate_from_catalog (chooser, gtk_catalog); + + others_chooser = glade_adaptor_chooser_add_chooser (chooser); + all_chooser = glade_adaptor_chooser_add_chooser (chooser); + glade_adaptor_chooser_button_add_chooser (priv->others_button, others_chooser); + glade_adaptor_chooser_button_add_chooser (priv->all_button, all_chooser); + + /* then the rest */ + for (l = glade_app_get_catalogs (); l; l = g_list_next (l)) + { + GladeCatalog *catalog = l->data; + + _glade_adaptor_chooser_widget_add_catalog (GLADE_ADAPTOR_CHOOSER_WIDGET (all_chooser), catalog); + + if (catalog != gtk_catalog) + _glade_adaptor_chooser_widget_add_catalog (GLADE_ADAPTOR_CHOOSER_WIDGET (others_chooser), catalog); + } +} + +static void +glade_adaptor_chooser_class_init (GladeAdaptorChooserClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = glade_adaptor_chooser_finalize; + object_class->constructed = glade_adaptor_chooser_constructed; + object_class->set_property = glade_adaptor_chooser_set_property; + object_class->get_property = glade_adaptor_chooser_get_property; + + /* Properties */ + properties[PROP_PROJECT] = + g_param_spec_object ("project", "Project", + "This adaptor chooser's current project", + GLADE_TYPE_PROJECT, + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/gladeui/glade-adaptor-chooser.ui"); + gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, gtk_button_box); + gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, extra_button); + gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, others_button); + gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, class_image); + gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, class_label); + gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, all_button); +} + +/* Public API */ + +GtkWidget * +glade_adaptor_chooser_new () +{ + return (GtkWidget*) g_object_new (GLADE_TYPE_ADAPTOR_CHOOSER, NULL); +} + +static void +glade_adaptor_chooser_update_adaptor (GladeAdaptorChooser *chooser) +{ + GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser); + GladeWidgetAdaptor *adaptor; + + if (priv->project && (adaptor = glade_project_get_add_item (priv->project))) + { + gtk_image_set_from_icon_name (priv->class_image, + glade_widget_adaptor_get_icon_name (adaptor), + GTK_ICON_SIZE_BUTTON); + gtk_label_set_label (priv->class_label, + glade_widget_adaptor_get_name (adaptor)); + } + else + { + gtk_image_set_from_pixbuf (priv->class_image, NULL); + gtk_label_set_label (priv->class_label, ""); + } +} + +void +glade_adaptor_chooser_set_project (GladeAdaptorChooser *chooser, + GladeProject *project) +{ + GladeAdaptorChooserPrivate *priv; + GList *l; + + g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER (chooser)); + priv = GET_PRIVATE (chooser); + + if (priv->project) + { + g_signal_handlers_disconnect_by_func (G_OBJECT (priv->project), + G_CALLBACK (glade_adaptor_chooser_update_adaptor), + chooser); + g_clear_object (&priv->project); + } + + if (project) + { + priv->project = g_object_ref (project); + g_signal_connect_swapped (G_OBJECT (project), "notify::add-item", + G_CALLBACK (glade_adaptor_chooser_update_adaptor), + chooser); + gtk_widget_set_sensitive (GTK_WIDGET (chooser), TRUE); + } + else + gtk_widget_set_sensitive (GTK_WIDGET (chooser), FALSE); + + /* Set project in chooser for filter to work */ + for (l = priv->choosers; l; l = g_list_next (l)) + _glade_adaptor_chooser_widget_set_project (l->data, project); + + /* Update class image and label */ + glade_adaptor_chooser_update_adaptor (chooser); +} + +GladeProject * +glade_adaptor_chooser_get_project (GladeAdaptorChooser *chooser) +{ + g_return_val_if_fail (GLADE_IS_ADAPTOR_CHOOSER (chooser), NULL); + + return GET_PRIVATE (chooser)->project; +} |