Commit 0a203e30 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

libgimpwidgets/Makefile.am libgimpwidgets/gimpwidgetstypes.h

2007-02-12  Sven Neumann  <sven@gimp.org>

	* libgimpwidgets/Makefile.am
	* libgimpwidgets/gimpwidgetstypes.h
	* libgimpwidgets/gimpwidgets.h
	* libgimpwidgets/gimpstringcombobox.[ch]: added GimpStringComboBox.

	* libgimpwidgets/gimppropwidgets.[ch]: added a prop widget
	constructor that uses the new widget.

	* libgimpwidgets/gimpwidgets.def: updated.

	* app/widgets/gimpcontrollereditor.c: use a GimpStringComboBox if
	the module specifies a tree model with string values.

	* modules/gimpinputdevicestore.c: minor cleanup.

	* modules/controller_linux_input.c: keep a pointer to the input
	device store and unref it in the finalizer.


svn path=/trunk/; revision=21900
parent 4f6e2969
2007-02-12 Sven Neumann <sven@gimp.org>
* libgimpwidgets/Makefile.am
* libgimpwidgets/gimpwidgetstypes.h
* libgimpwidgets/gimpwidgets.h
* libgimpwidgets/gimpstringcombobox.[ch]: added GimpStringComboBox.
* libgimpwidgets/gimppropwidgets.[ch]: added a prop widget
constructor that uses the new widget.
* libgimpwidgets/gimpwidgets.def: updated.
* app/widgets/gimpcontrollereditor.c: use a GimpStringComboBox if
the module specifies a tree model with string values.
* modules/gimpinputdevicestore.c: minor cleanup.
* modules/controller_linux_input.c: keep a pointer to the input
device store and unref it in the finalizer.
2007-02-12 Sven Neumann <sven@gimp.org>
* app/widgets/gimpcontrollerlist.c (gimp_controller_list_edit_clicked):
......@@ -817,7 +817,33 @@ gimp_controller_string_view_new (GimpController *controller,
if (pspec->flags & G_PARAM_WRITABLE)
{
widget = gimp_prop_entry_new (G_OBJECT (controller), pspec->name, -1);
GtkTreeModel *model = NULL;
gchar *model_name = g_strdup_printf ("%s-values", pspec->name);
GParamSpec *model_spec;
model_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (controller),
model_name);
if (G_IS_PARAM_SPEC_OBJECT (model_spec) &&
g_type_is_a (model_spec->value_type, GTK_TYPE_LIST_STORE))
{
g_object_get (controller,
model_name, &model,
NULL);
}
g_free (model_name);
if (model)
{
widget = gimp_prop_string_combo_box_new (G_OBJECT (controller),
pspec->name, model, 0, 1);
g_object_unref (model);
}
else
{
widget = gimp_prop_entry_new (G_OBJECT (controller), pspec->name, -1);
}
}
else
{
......
......@@ -152,6 +152,8 @@ libgimpwidgets_2_0_la_sources = \
gimpsizeentry.h \
gimpstock.c \
gimpstock.h \
gimpstringcombobox.c \
gimpstringcombobox.h \
gimpunitmenu.c \
gimpunitmenu.h \
gimpzoommodel.c \
......@@ -219,6 +221,7 @@ libgimpwidgetsinclude_HEADERS = \
gimpscrolledpreview.h \
gimpsizeentry.h \
gimpstock.h \
gimpstringcombobox.h \
gimpunitmenu.h \
gimpzoommodel.h
......
......@@ -1952,6 +1952,131 @@ gimp_prop_text_buffer_notify (GObject *config,
}
/***********************/
/* string combo box */
/***********************/
static void gimp_prop_string_combo_box_callback (GtkWidget *widget,
GObject *config);
static void gimp_prop_string_combo_box_notify (GObject *config,
GParamSpec *param_spec,
GtkWidget *widget);
/**
* gimp_prop_string_combo_box_new:
* @config: Object to which property is attached.
* @property_name: Name of int property controlled by combo box.
* @store: #GtkTreeStore holding list of values
* @id_column: column in @store that holds string IDs
* @label_column: column in @store that holds labels to use in the combo-box
*
* Creates a #GimpStringComboBox widget to display and set the
* specified property. The contents of the widget are determined by
* @store.
*
* Return value: The newly created #GimpStringComboBox widget, optionally
* wrapped into a #GtkEventBox.
*
* Since GIMP 2.4
*/
GtkWidget *
gimp_prop_string_combo_box_new (GObject *config,
const gchar *property_name,
GtkTreeStore *store,
gint id_column,
gint label_column)
{
GParamSpec *param_spec;
GtkWidget *combo_box;
GtkWidget *widget;
gchar *value;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (property_name != NULL, NULL);
param_spec = check_param_spec_w (config, property_name,
G_TYPE_PARAM_STRING, G_STRFUNC);
if (! param_spec)
return NULL;
g_object_get (config,
property_name, &value,
NULL);
combo_box = gimp_string_combo_box_new (store, id_column, label_column);
gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (combo_box), value);
g_signal_connect (combo_box, "changed",
G_CALLBACK (gimp_prop_string_combo_box_callback),
config);
/* can't set a tooltip on a combo_box */
if (g_param_spec_get_blurb (param_spec))
{
widget = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (widget), combo_box);
gtk_widget_show (combo_box);
}
else
{
widget = combo_box;
}
set_param_spec (G_OBJECT (combo_box), widget, param_spec);
connect_notify (config, property_name,
G_CALLBACK (gimp_prop_string_combo_box_notify),
combo_box);
return widget;
}
static void
gimp_prop_string_combo_box_callback (GtkWidget *widget,
GObject *config)
{
GParamSpec *param_spec;
gchar *value;
param_spec = get_param_spec (G_OBJECT (widget));
if (! param_spec)
return;
value = gimp_string_combo_box_get_active (GIMP_STRING_COMBO_BOX (widget));
g_object_set (config,
param_spec->name, value,
NULL);
g_free (value);
}
static void
gimp_prop_string_combo_box_notify (GObject *config,
GParamSpec *param_spec,
GtkWidget *combo_box)
{
gchar *value;
g_object_get (config,
param_spec->name, &value,
NULL);
g_signal_handlers_block_by_func (combo_box,
gimp_prop_string_combo_box_callback,
config);
gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (combo_box), value);
g_signal_handlers_unblock_by_func (combo_box,
gimp_prop_string_combo_box_callback,
config);
g_free (value);
}
/*************************/
/* file chooser button */
/*************************/
......
......@@ -136,6 +136,11 @@ GtkWidget * gimp_prop_entry_new (GObject *config,
GtkTextBuffer * gimp_prop_text_buffer_new (GObject *config,
const gchar *property_name,
gint max_len);
GtkWidget * gimp_prop_string_combo_box_new (GObject *config,
const gchar *property_name,
GtkTreeStore *store,
gint id_column,
gint label_column);
/* GimpParamPath */
......
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpstringcombobox.c
* Copyright (C) 2007 Sven Neumann <sven@gimp.org>
*
* 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 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "gimpwidgetstypes.h"
#include "gimpstringcombobox.h"
enum
{
PROP_0,
PROP_ID_COLUMN,
PROP_LABEL_COLUMN,
PROP_ELLIPSIZE
};
typedef struct
{
gint id_column;
gint label_column;
GtkCellRenderer *text_renderer;
} GimpStringComboBoxPrivate;
#define GIMP_STRING_COMBO_BOX_GET_PRIVATE(obj) \
((GimpStringComboBoxPrivate *) ((GimpStringComboBox *) (obj))->priv)
static GObject * gimp_string_combo_box_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
static void gimp_string_combo_box_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_string_combo_box_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
G_DEFINE_TYPE (GimpStringComboBox, gimp_string_combo_box, GTK_TYPE_COMBO_BOX)
#define parent_class gimp_string_combo_box_parent_class
static void
gimp_string_combo_box_class_init (GimpStringComboBoxClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructor = gimp_string_combo_box_constructor;
object_class->set_property = gimp_string_combo_box_set_property;
object_class->get_property = gimp_string_combo_box_get_property;
/**
* GimpStringComboBox:id-column:
*
* The column in the associated GtkTreeModel that holds unique
* string IDs.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class,
PROP_ID_COLUMN,
g_param_spec_int ("id-column", NULL, NULL,
0, G_MAXINT,
0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
/**
* GimpStringComboBox:id-column:
*
* The column in the associated GtkTreeModel that holds strings to
* be used as labels in the combo-box.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class,
PROP_LABEL_COLUMN,
g_param_spec_int ("label-column", NULL, NULL,
0, G_MAXINT,
0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
/**
* GimpStringComboBox:ellipsize:
*
* Specifies the preferred place to ellipsize text in the combo-box,
* if the cell renderer does not have enough room to display the
* entire string.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class,
PROP_ELLIPSIZE,
g_param_spec_enum ("ellipsize", NULL, NULL,
PANGO_TYPE_ELLIPSIZE_MODE,
PANGO_ELLIPSIZE_NONE,
GIMP_PARAM_READWRITE));
g_type_class_add_private (object_class, sizeof (GimpStringComboBoxPrivate));
}
static void
gimp_string_combo_box_init (GimpStringComboBox *combo_box)
{
combo_box->priv = G_TYPE_INSTANCE_GET_PRIVATE (combo_box,
GIMP_TYPE_STRING_COMBO_BOX,
GimpStringComboBoxPrivate);
}
static GObject *
gimp_string_combo_box_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
GObject *object;
GimpStringComboBox *combo;
GimpStringComboBoxPrivate *priv;
GtkTreeModel *model;
GtkCellRenderer *cell;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
combo = GIMP_STRING_COMBO_BOX (object);
priv = GIMP_STRING_COMBO_BOX_GET_PRIVATE (combo);
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
if (! g_type_is_a (gtk_tree_model_get_column_type (model, priv->id_column),
G_TYPE_STRING))
{
g_warning ("GimpStringComboBox: ID column must hold string values");
return object;
}
if (! g_type_is_a (gtk_tree_model_get_column_type (model, priv->label_column),
G_TYPE_STRING))
{
g_warning ("GimpStringComboBox: label column must hold string values");
return object;
}
priv->text_renderer = cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
"text", priv->label_column,
NULL);
return object;
}
static void
gimp_string_combo_box_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpStringComboBoxPrivate *priv = GIMP_STRING_COMBO_BOX_GET_PRIVATE (object);
switch (property_id)
{
case PROP_ID_COLUMN:
priv->id_column = g_value_get_int (value);
break;
case PROP_LABEL_COLUMN:
priv->label_column = g_value_get_int (value);
break;
case PROP_ELLIPSIZE:
g_object_set_property (G_OBJECT (priv->text_renderer),
pspec->name, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_string_combo_box_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpStringComboBoxPrivate *priv = GIMP_STRING_COMBO_BOX_GET_PRIVATE (object);
switch (property_id)
{
case PROP_ID_COLUMN:
g_value_set_int (value, priv->id_column);
break;
case PROP_LABEL_COLUMN:
g_value_set_int (value, priv->label_column);
break;
case PROP_ELLIPSIZE:
g_object_get_property (G_OBJECT (priv->text_renderer),
pspec->name, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gboolean
gimp_string_model_lookup (GtkTreeModel *model,
gint column,
const gchar *id,
GtkTreeIter *iter)
{
GValue value = { 0, };
gboolean iter_valid;
/* This lookup could be backed up by a hash table or some other
* data structure instead of doing a list traversal. But since this
* is a GtkComboBox, there shouldn't be many entries anyway...
*/
g_value_init (&value, G_TYPE_STRING);
for (iter_valid = gtk_tree_model_get_iter_first (model, iter);
iter_valid;
iter_valid = gtk_tree_model_iter_next (model, iter))
{
const gchar *str;
gtk_tree_model_get_value (model, iter, column, &value);
str = g_value_get_string (&value);
if (str && strcmp (str, id) == 0)
break;
g_value_reset (&value);
}
g_value_unset (&value);
return iter_valid;
}
/**
* gimp_string_combo_box_new:
* @id_column:
* @label_column:
*
* Return value: a new #GimpStringComboBox.
*
* Since: GIMP 2.4
**/
GtkWidget *
gimp_string_combo_box_new (GtkTreeModel *model,
gint id_column,
gint label_column)
{
g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
g_return_val_if_fail (gtk_tree_model_get_column_type (model,
id_column) == G_TYPE_STRING, NULL);
g_return_val_if_fail (gtk_tree_model_get_column_type (model,
label_column) == G_TYPE_STRING, NULL);
return g_object_new (GIMP_TYPE_STRING_COMBO_BOX,
"model", model,
"id-column", id_column,
"label-column", label_column,
NULL);
}
/**
* gimp_string_combo_box_set_active:
* @combo_box: a #GimpStringComboBox
* @id:
*
* Looks up the item that belongs to the given @id and makes it the
* selected item in the @combo_box.
*
* Return value: %TRUE on success or %FALSE if there was no item for
* this value.
*
* Since: GIMP 2.4
**/
gboolean
gimp_string_combo_box_set_active (GimpStringComboBox *combo_box,
const gchar *id)
{
GtkTreeModel *model;
GtkTreeIter iter;
gint column;
g_return_val_if_fail (GIMP_IS_STRING_COMBO_BOX (combo_box), FALSE);
g_return_val_if_fail (id != NULL, FALSE);
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
column = GIMP_STRING_COMBO_BOX_GET_PRIVATE (combo_box)->id_column;
if (gimp_string_model_lookup (model, column, id, &iter))
{
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter);
return TRUE;
}
return FALSE;
}
/**
* gimp_string_combo_box_get_active:
* @combo_box: a #GimpStringComboBox
*
* Retrieves the value of the selected (active) item in the @combo_box.
*
* Return value: newly allocated ID string or %NULL if nothing was selected
*
* Since: GIMP 2.4
**/
gchar *
gimp_string_combo_box_get_active (GimpStringComboBox *combo_box)
{
GtkTreeIter iter;
g_return_val_if_fail (GIMP_IS_STRING_COMBO_BOX (combo_box), NULL);
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter))
{
GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
gchar *value;
gint column;
column = GIMP_STRING_COMBO_BOX_GET_PRIVATE (combo_box)->id_column;
gtk_tree_model_get (model, &iter,
column, &value,
-1);
return value;
}
return NULL;
}
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpstringcombobox.h
* Copyright (C) 2007 Sven Neumann <sven@gimp.org>
*
* 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 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_STRING_COMBO_BOX_H__