glade3 r2035 - trunk/plugins/gtk+



Author: tvb
Date: Wed Nov 19 18:58:40 2008
New Revision: 2035
URL: http://svn.gnome.org/viewvc/glade3?rev=2035&view=rev

Log:
oops, missed these in my last commit


Added:
   trunk/plugins/gtk+/glade-cell-renderer-editor.c
   trunk/plugins/gtk+/glade-cell-renderer-editor.h

Added: trunk/plugins/gtk+/glade-cell-renderer-editor.c
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-cell-renderer-editor.c	Wed Nov 19 18:58:40 2008
@@ -0,0 +1,464 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Tristan Van Berkom.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Tristan Van Berkom <tvb gnome org>
+ */
+
+#include <config.h>
+#include <gladeui/glade.h>
+#include <glib/gi18n-lib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "glade-cell-renderer-editor.h"
+
+
+static void glade_cell_renderer_editor_finalize        (GObject              *object);
+
+static void glade_cell_renderer_editor_editable_init   (GladeEditableIface *iface);
+
+static void glade_cell_renderer_editor_grab_focus      (GtkWidget            *widget);
+
+
+typedef struct {
+	GladeCellRendererEditor  *editor;
+
+	GtkWidget                *attributes_check;
+	GladePropertyClass       *pclass;
+	GladePropertyClass       *attr_pclass;
+	GladePropertyClass       *use_attr_pclass;
+} CheckTab;
+
+G_DEFINE_TYPE_WITH_CODE (GladeCellRendererEditor, glade_cell_renderer_editor, GTK_TYPE_VBOX,
+                         G_IMPLEMENT_INTERFACE (GLADE_TYPE_EDITABLE,
+                                                glade_cell_renderer_editor_editable_init));
+
+
+static void
+glade_cell_renderer_editor_class_init (GladeCellRendererEditorClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	object_class->finalize     = glade_cell_renderer_editor_finalize;
+	widget_class->grab_focus   = glade_cell_renderer_editor_grab_focus;
+}
+
+static void
+glade_cell_renderer_editor_init (GladeCellRendererEditor *self)
+{
+}
+
+static void
+project_changed (GladeProject      *project,
+		 GladeCommand      *command,
+		 gboolean           execute,
+		 GladeCellRendererEditor *renderer_editor)
+{
+	if (renderer_editor->modifying ||
+	    !GTK_WIDGET_MAPPED (renderer_editor))
+		return;
+
+	/* Reload on all commands */
+	glade_editable_load (GLADE_EDITABLE (renderer_editor), renderer_editor->loaded_widget);
+}
+
+
+static void
+project_finalized (GladeCellRendererEditor *renderer_editor,
+		   GladeProject       *where_project_was)
+{
+	renderer_editor->loaded_widget = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (renderer_editor), NULL);
+}
+
+static void
+glade_cell_renderer_editor_load (GladeEditable *editable,
+			       GladeWidget   *widget)
+{
+	GladeCellRendererEditor  *renderer_editor = GLADE_CELL_RENDERER_EDITOR (editable);
+	GList                    *l;
+
+	renderer_editor->loading = TRUE;
+
+	/* Since we watch the project*/
+	if (renderer_editor->loaded_widget)
+	{
+		g_signal_handlers_disconnect_by_func (G_OBJECT (renderer_editor->loaded_widget->project),
+						      G_CALLBACK (project_changed), renderer_editor);
+
+		/* The widget could die unexpectedly... */
+		g_object_weak_unref (G_OBJECT (renderer_editor->loaded_widget->project),
+				     (GWeakNotify)project_finalized,
+				     renderer_editor);
+	}
+
+	/* Mark our widget... */
+	renderer_editor->loaded_widget = widget;
+
+	if (renderer_editor->loaded_widget)
+	{
+		/* This fires for undo/redo */
+		g_signal_connect (G_OBJECT (renderer_editor->loaded_widget->project), "changed",
+				  G_CALLBACK (project_changed), renderer_editor);
+
+		/* The widget/project could die unexpectedly... */
+		g_object_weak_ref (G_OBJECT (renderer_editor->loaded_widget->project),
+				   (GWeakNotify)project_finalized,
+				   renderer_editor);
+	}
+
+	/* load the embedded editable... */
+	if (renderer_editor->embed)
+		glade_editable_load (GLADE_EDITABLE (renderer_editor->embed), widget);
+
+	for (l = renderer_editor->properties; l; l = l->next)
+		glade_editor_property_load_by_widget (GLADE_EDITOR_PROPERTY (l->data), widget);
+
+	if (widget)
+	{
+		for (l = renderer_editor->checks; l; l = l->next)
+		{
+			CheckTab *tab = l->data;
+			gboolean use_attr = FALSE;
+
+			glade_widget_property_get (widget, tab->use_attr_pclass->id, &use_attr);
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tab->attributes_check), use_attr);
+		}
+	}
+	renderer_editor->loading = FALSE;
+}
+
+static void
+glade_cell_renderer_editor_set_show_name (GladeEditable *editable,
+					  gboolean       show_name)
+{
+	GladeCellRendererEditor *renderer_editor = GLADE_CELL_RENDERER_EDITOR (editable);
+
+	glade_editable_set_show_name (GLADE_EDITABLE (renderer_editor->embed), show_name);
+}
+
+static void
+glade_cell_renderer_editor_editable_init (GladeEditableIface *iface)
+{
+	iface->load = glade_cell_renderer_editor_load;
+	iface->set_show_name = glade_cell_renderer_editor_set_show_name;
+}
+
+static void
+glade_cell_renderer_editor_finalize (GObject *object)
+{
+	GladeCellRendererEditor *renderer_editor = GLADE_CELL_RENDERER_EDITOR (object);
+
+	g_list_foreach (renderer_editor->checks, (GFunc)g_free, NULL);
+	g_list_free (renderer_editor->checks);
+	g_list_free (renderer_editor->properties);
+
+	renderer_editor->properties  = NULL;
+	renderer_editor->checks      = NULL;
+	renderer_editor->embed       = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (object), NULL);
+
+	G_OBJECT_CLASS (glade_cell_renderer_editor_parent_class)->finalize (object);
+}
+
+static void
+glade_cell_renderer_editor_grab_focus (GtkWidget *widget)
+{
+	GladeCellRendererEditor *renderer_editor = GLADE_CELL_RENDERER_EDITOR (widget);
+
+	gtk_widget_grab_focus (renderer_editor->embed);
+}
+
+
+static void
+table_attach (GtkWidget *table, 
+	      GtkWidget *child, 
+	      gint pos, gint row)
+{
+	gtk_table_attach (GTK_TABLE (table), child,
+			  pos, pos+1, row, row +1,
+			  pos ? GTK_FILL : GTK_EXPAND | GTK_FILL,
+			  GTK_EXPAND | GTK_FILL,
+			  3, 1);
+}
+
+static void
+attributes_toggled (GtkWidget  *widget,
+		    CheckTab   *tab)
+{
+	GladeCellRendererEditor  *renderer_editor = tab->editor;
+	GladeProperty            *property;
+	GValue                    value = { 0, };
+
+	if (renderer_editor->loading || !renderer_editor->loaded_widget)
+		return;
+
+	renderer_editor->modifying = TRUE;
+
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tab->attributes_check)))
+	{
+
+		glade_command_push_group (_("Setting %s to use the %s property as an attribute"), 
+					  renderer_editor->loaded_widget->name, tab->pclass->id);
+		
+
+		property = glade_widget_get_property (renderer_editor->loaded_widget, tab->pclass->id);
+		glade_property_get_default (property, &value);
+		glade_command_set_property_value (property, &value);
+		g_value_unset (&value);
+		
+		property = glade_widget_get_property (renderer_editor->loaded_widget, tab->use_attr_pclass->id);
+		glade_command_set_property (property, TRUE);
+		
+		glade_command_pop_group ();
+		
+
+	}
+	else
+	{
+		glade_command_push_group (_("Setting %s to use the %s property directly"), 
+					  renderer_editor->loaded_widget->name, tab->pclass->id);
+		
+		
+		property = glade_widget_get_property (renderer_editor->loaded_widget, tab->attr_pclass->id);
+		glade_property_get_default (property, &value);
+		glade_command_set_property_value (property, &value);
+		g_value_unset (&value);
+		
+		property = glade_widget_get_property (renderer_editor->loaded_widget, tab->use_attr_pclass->id);
+		glade_command_set_property (property, FALSE);	
+		
+		glade_command_pop_group ();
+	}
+	renderer_editor->modifying = FALSE;
+
+	/* reload buttons and sensitivity and stuff... */
+	glade_editable_load (GLADE_EDITABLE (renderer_editor), 
+			     renderer_editor->loaded_widget);
+}
+
+
+#define EDITOR_COLUMN_SIZE 150
+
+static void
+label_size_request (GtkWidget *widget, GtkRequisition *requisition, 
+		    gpointer user_data)
+{
+	requisition->width = EDITOR_COLUMN_SIZE;
+}
+
+static void
+label_size_allocate_after (GtkWidget *container, GtkAllocation *allocation,
+			   GtkWidget *widget)
+{
+	GtkWidget *check;
+	GtkRequisition req = { -1, -1 };
+	gint width = EDITOR_COLUMN_SIZE;
+	gint check_width;
+
+	/* Here we have to subtract the check button and the 
+	 * remaining padding inside the hbox so that we are
+	 * only dealing with the size of the label.
+	 * (note the '4' here comes from the hbox spacing).
+	 */
+	check = g_object_get_data (G_OBJECT (container), "attributes-check");
+	g_assert (check);
+
+	gtk_widget_size_request (check, &req);
+	check_width = req.width + 4 + 4;
+
+	if (allocation->width > width)
+		width = allocation->width;
+
+	gtk_widget_set_size_request (widget, width - check_width, -1);
+
+	gtk_container_check_resize (GTK_CONTAINER (container));
+
+	/* Sometimes labels aren't drawn correctly after resize without this */
+	gtk_widget_queue_draw (container);
+
+
+}
+
+
+static gint
+property_class_comp (gconstpointer a, gconstpointer b)
+{
+	const GladePropertyClass *ca = a, *cb = b;
+	
+	if (ca->pspec->owner_type == cb->pspec->owner_type)
+	{
+		gdouble result = ca->weight - cb->weight;
+		/* Avoid cast to int */
+		if (result < 0.0) return -1;
+		else if (result > 0.0) return 1;
+		else return 0;
+	}
+	else
+	{
+		if (g_type_is_a (ca->pspec->owner_type, cb->pspec->owner_type))
+			return (ca->common || ca->packing) ? 1 : -1;
+		else
+			return (ca->common || ca->packing) ? -1 : 1;
+	}
+}
+
+static GList *
+get_sorted_properties (GladeWidgetAdaptor   *adaptor,
+		       GladeEditorPageType   type)
+{
+	GList *l, *list = NULL;
+
+	for (l = adaptor->properties; l; l = g_list_next (l))
+	{
+		GladePropertyClass *klass = l->data;
+
+		if (GLADE_PROPERTY_CLASS_IS_TYPE (klass, type) &&
+		    (glade_property_class_is_visible (klass)))
+		{
+			list = g_list_prepend (list, klass);
+		}
+	}
+	return g_list_sort (list, property_class_comp);
+}
+
+
+GtkWidget *
+glade_cell_renderer_editor_new (GladeWidgetAdaptor  *adaptor,
+				GladeEditorPageType  type,
+				GladeEditable       *embed)
+{
+	GladeCellRendererEditor  *renderer_editor;
+	GladeEditorProperty      *eprop;
+	GladePropertyClass       *pclass, *attr_pclass, *use_attr_pclass;
+	GList                    *list, *sorted;
+	GtkWidget                *label, *alignment, *table, *hbox, *separator;
+	GtkSizeGroup             *input_group;
+	gchar                    *str;
+
+	g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
+	g_return_val_if_fail (GLADE_IS_EDITABLE (embed), NULL);
+
+	renderer_editor = g_object_new (GLADE_TYPE_CELL_RENDERER_EDITOR, NULL);
+	renderer_editor->embed = GTK_WIDGET (embed);
+
+	/* Pack the parent on top... */
+	gtk_box_pack_start (GTK_BOX (renderer_editor), GTK_WIDGET (embed), FALSE, FALSE, 0);
+
+	input_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+	sorted = get_sorted_properties (adaptor, type);
+
+	/* For each normal property, if we have an attr- and use-attr- counterpart, load
+	 * a check button property pair into the table...
+	 */
+	for (list = sorted; list; list = list->next)
+	{
+		gchar *attr_name;
+		gchar *use_attr_name;
+		gint   rows = 0;
+
+		pclass = list->data;
+
+		if (pclass->virt)
+			continue;
+
+		attr_name       = g_strdup_printf ("attr-%s", pclass->id);
+		use_attr_name   = g_strdup_printf ("use-attr-%s", pclass->id);
+
+		attr_pclass     = glade_widget_adaptor_get_property_class (adaptor, attr_name);
+		use_attr_pclass = glade_widget_adaptor_get_property_class (adaptor, use_attr_name);
+
+		if (attr_pclass && use_attr_pclass)
+		{
+			CheckTab *tab = g_new0 (CheckTab, 1);
+
+			tab->editor          = renderer_editor;
+			tab->pclass          = pclass;
+			tab->attr_pclass     = attr_pclass;
+			tab->use_attr_pclass = use_attr_pclass;
+
+			/* Spacing */
+			separator = gtk_hbox_new (FALSE, 0);
+			gtk_box_pack_start (GTK_BOX (renderer_editor), separator, FALSE, FALSE, 4);
+
+
+			/* Label appearance... */
+			hbox   = gtk_hbox_new (FALSE, 0);
+			str    = g_strdup_printf (_("Retrieve <b>%s</b> from model (type %s)"), 
+						  pclass->name, g_type_name (pclass->pspec->value_type));
+			label  = gtk_label_new (str);
+			g_free (str);
+
+			gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+			gtk_label_set_line_wrap (GTK_LABEL(label), TRUE);
+			gtk_label_set_line_wrap_mode (GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
+			gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+			tab->attributes_check = gtk_check_button_new ();
+
+			gtk_box_pack_start (GTK_BOX (hbox), tab->attributes_check, FALSE, FALSE, 4);
+			gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 4);
+			gtk_box_pack_start (GTK_BOX (renderer_editor), hbox, FALSE, FALSE, 0);
+
+			/* A Hack so that PANGO_WRAP_WORD_CHAR works nicely */
+			g_object_set_data (G_OBJECT (hbox), "attributes-check", tab->attributes_check);
+			g_signal_connect (G_OBJECT (hbox), "size-request",
+					  G_CALLBACK (label_size_request), NULL);
+			g_signal_connect_after (G_OBJECT (hbox), "size-allocate",
+						G_CALLBACK (label_size_allocate_after), label);
+
+
+			alignment = gtk_alignment_new (1.0F, 1.0F, 1.0F, 1.0F);
+			gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 12, 0);
+ 			gtk_box_pack_start (GTK_BOX (renderer_editor), alignment, FALSE, FALSE, 0);
+
+			table = gtk_table_new (0, 0, FALSE);
+			gtk_container_add (GTK_CONTAINER (alignment), table);
+
+			/* Edit property */
+			eprop           = glade_widget_adaptor_create_eprop (adaptor, pclass, TRUE);
+			table_attach (table, eprop->item_label, 0, rows);
+			table_attach (table, GTK_WIDGET (eprop), 1, rows++);
+			renderer_editor->properties = g_list_prepend (renderer_editor->properties, eprop);
+			gtk_size_group_add_widget (input_group, GTK_WIDGET (eprop));
+
+			/* Edit attribute */
+			eprop = glade_widget_adaptor_create_eprop (adaptor, attr_pclass, TRUE);
+			table_attach (table, eprop->item_label, 0, rows);
+			table_attach (table, GTK_WIDGET (eprop), 1, rows++);
+			renderer_editor->properties = g_list_prepend (renderer_editor->properties, eprop);
+			gtk_size_group_add_widget (input_group, GTK_WIDGET (eprop));
+
+			g_signal_connect (G_OBJECT (tab->attributes_check), "toggled",
+					  G_CALLBACK (attributes_toggled), tab);
+
+			renderer_editor->checks = g_list_prepend (renderer_editor->checks, tab);
+		}
+		g_free (attr_name);
+		g_free (use_attr_name);
+	}
+	g_list_free (sorted);
+
+	gtk_widget_show_all (GTK_WIDGET (renderer_editor));
+
+	return GTK_WIDGET (renderer_editor);
+}

Added: trunk/plugins/gtk+/glade-cell-renderer-editor.h
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-cell-renderer-editor.h	Wed Nov 19 18:58:40 2008
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Tristan Van Berkom.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Tristan Van Berkom <tvb gnome org>
+ */
+#ifndef _GLADE_CELL_RENDERER_EDITOR_H_
+#define _GLADE_CELL_RENDERER_EDITOR_H_
+
+#include <gladeui/glade-editable.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GLADE_TYPE_CELL_RENDERER_EDITOR	            (glade_cell_renderer_editor_get_type ())
+#define GLADE_CELL_RENDERER_EDITOR(obj)		    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_CELL_RENDERER_EDITOR, GladeCellRendererEditor))
+#define GLADE_CELL_RENDERER_EDITOR_CLASS(klass)	    (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_CELL_RENDERER_EDITOR, GladeCellRendererEditorClass))
+#define GLADE_IS_CELL_RENDERER_EDITOR(obj)	    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_CELL_RENDERER_EDITOR))
+#define GLADE_IS_CELL_RENDERER_EDITOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_CELL_RENDERER_EDITOR))
+#define GLADE_CELL_RENDERER_EDITOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_CELL_RENDERER_EDITOR, GladeCellRendererEditorClass))
+
+typedef struct _GladeCellRendererEditor        GladeCellRendererEditor;
+typedef struct _GladeCellRendererEditorClass   GladeCellRendererEditorClass;
+
+struct _GladeCellRendererEditor
+{
+	GtkVBox  parent;
+
+	GladeWidget *loaded_widget; /* A handy pointer to the loaded widget ... */
+
+	GtkWidget *embed;           /* Embedded parent class editor */
+
+	GList *checks;             /* A list of radio buttons for each property/attribute pair */
+
+	GList *properties;         /* A list of eprops to update at load() time */
+
+	gboolean loading;          /* Loading flag for loading widgets in the editor */
+	gboolean modifying;        /* Flag for monitoring project changes */
+};
+
+struct _GladeCellRendererEditorClass
+{
+	GtkVBoxClass parent;
+};
+
+GType            glade_cell_renderer_editor_get_type (void);
+GtkWidget       *glade_cell_renderer_editor_new      (GladeWidgetAdaptor  *adaptor,
+						      GladeEditorPageType  type,
+						      GladeEditable       *editable);
+
+G_END_DECLS
+
+#endif  /* _GLADE_CELL_RENDERER_EDITOR_H_ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]