added utility functions to copy and to free a dash pattern.

2005-05-21  Sven Neumann  <sven@gimp.org>

	* app/core/gimpdashpattern.[ch]: added utility functions to copy
	and to free a dash pattern.

	* app/widgets/Makefile.am
	* app/widgets/widgets-types.h
	* app/widgets/gimpcellrendererdashes.[ch]: added a simple cell
	renderer to visualize a dash pattern.

	* app/widgets/gimpstrokeeditor.c: show previews of the dash
	presets in the combo-box.
This commit is contained in:
Sven Neumann 2005-05-21 20:24:42 +00:00 committed by Sven Neumann
parent b6ad77a1bd
commit a8318e18c5
8 changed files with 453 additions and 2 deletions

View File

@ -1,10 +1,23 @@
2005-05-21 Sven Neumann <sven@gimp.org>
* app/core/gimpdashpattern.[ch]: added utility functions to copy
and to free a dash pattern.
* app/widgets/Makefile.am
* app/widgets/widgets-types.h
* app/widgets/gimpcellrendererdashes.[ch]: added a simple cell
renderer to visualize a dash pattern.
* app/widgets/gimpstrokeeditor.c: show previews of the dash
presets in the combo-box.
2005-05-21 Michael Natterer <mitch@gimp.org>
* tools/test-clipboard.c (main): NULL terminate the options array.
2005-05-21 Sven Neumann <sven@gimp.org>
Allow to paste a new image using Ctrl-V (bug 169477):
Allow to paste a new image using Ctrl-V (bug #169477):
* menus/toolbox-menu.xml.in: added an accelerator for "edit-paste".
@ -229,7 +242,6 @@
instruction count correct. This is partially complete as of this
commit.
2005-05-17 Sven Neumann <sven@gimp.org>
* configure.in: bumped version number to 2.3.1.

View File

@ -254,3 +254,29 @@ gimp_dash_pattern_value_set (GArray *pattern,
g_value_set_boxed (value, val_array);
}
}
GArray *
gimp_dash_pattern_copy (GArray *pattern)
{
if (pattern)
{
GArray *copy;
gint i;
copy = g_array_sized_new (FALSE, FALSE, sizeof (gdouble), pattern->len);
for (i = 0; i < pattern->len; i++)
copy = g_array_append_val (copy, g_array_index (pattern, gdouble, i));
return copy;
}
return NULL;
}
void
gimp_dash_pattern_free (GArray *pattern)
{
if (pattern)
g_array_free (pattern, TRUE);
}

View File

@ -37,5 +37,8 @@ GArray * gimp_dash_pattern_from_value (const GValue *value);
void gimp_dash_pattern_value_set (GArray *pattern,
GValue *value);
GArray * gimp_dash_pattern_copy (GArray *pattern);
void gimp_dash_pattern_free (GArray *pattern);
#endif /* __GIMP_DASH_PATTERN_H__ */

View File

@ -38,6 +38,8 @@ libappwidgets_a_sources = \
gimpbufferview.h \
gimpcellrendereraccel.c \
gimpcellrendereraccel.h \
gimpcellrendererdashes.c \
gimpcellrendererdashes.h \
gimpcellrendererviewable.c \
gimpcellrendererviewable.h \
gimpchanneltreeview.c \

View File

@ -0,0 +1,270 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpcellrendererdashes.c
* Copyright (C) 2005 Sven Neumann <sven@gimp.org>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <gtk/gtk.h>
#include "widgets-types.h"
#include "core/gimpdashpattern.h"
#include "gimpcellrendererdashes.h"
#define DASHES_WIDTH 72
#define DASHES_HEIGHT 6
#define N_SEGMENTS 24
#define BLOCK_WIDTH (DASHES_WIDTH / N_SEGMENTS)
enum
{
PROP_0,
PROP_PATTERN
};
static void gimp_cell_renderer_dashes_class_init (GimpCellRendererDashesClass *klass);
static void gimp_cell_renderer_dashes_init (GimpCellRendererDashes *cell);
static void gimp_cell_renderer_dashes_finalize (GObject *object);
static void gimp_cell_renderer_dashes_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec);
static void gimp_cell_renderer_dashes_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_cell_renderer_dashes_get_size (GtkCellRenderer *cell,
GtkWidget *widget,
GdkRectangle *rectangle,
gint *x_offset,
gint *y_offset,
gint *width,
gint *height);
static void gimp_cell_renderer_dashes_render (GtkCellRenderer *cell,
GdkWindow *window,
GtkWidget *widget,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GdkRectangle *expose_area,
GtkCellRendererState flags);
static GtkCellRendererClass *parent_class = NULL;
GType
gimp_cell_renderer_dashes_get_type (void)
{
static GType cell_type = 0;
if (! cell_type)
{
static const GTypeInfo cell_info =
{
sizeof (GimpCellRendererDashesClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gimp_cell_renderer_dashes_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpCellRendererDashes),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_cell_renderer_dashes_init,
};
cell_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
"GimpCellRendererDashes",
&cell_info, 0);
}
return cell_type;
}
static void
gimp_cell_renderer_dashes_class_init (GimpCellRendererDashesClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_cell_renderer_dashes_finalize;
object_class->get_property = gimp_cell_renderer_dashes_get_property;
object_class->set_property = gimp_cell_renderer_dashes_set_property;
cell_class->get_size = gimp_cell_renderer_dashes_get_size;
cell_class->render = gimp_cell_renderer_dashes_render;
g_object_class_install_property (object_class, PROP_PATTERN,
g_param_spec_pointer ("pattern", NULL, NULL,
G_PARAM_READWRITE));
}
static void
gimp_cell_renderer_dashes_init (GimpCellRendererDashes *dashes)
{
dashes->pattern = NULL;
dashes->segments = g_new0 (gboolean, N_SEGMENTS);
}
static void
gimp_cell_renderer_dashes_finalize (GObject *object)
{
GimpCellRendererDashes *dashes = GIMP_CELL_RENDERER_DASHES (object);
g_free (dashes->segments);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_cell_renderer_dashes_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
{
GimpCellRendererDashes *dashes = GIMP_CELL_RENDERER_DASHES (object);
switch (param_id)
{
case PROP_PATTERN:
g_value_set_pointer (value, dashes->pattern);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
gimp_cell_renderer_dashes_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
GimpCellRendererDashes *dashes = GIMP_CELL_RENDERER_DASHES (object);
switch (param_id)
{
case PROP_PATTERN:
dashes->pattern = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
gimp_cell_renderer_dashes_get_size (GtkCellRenderer *cell,
GtkWidget *widget,
GdkRectangle *cell_area,
gint *x_offset,
gint *y_offset,
gint *width,
gint *height)
{
if (cell_area)
{
if (x_offset)
{
gdouble align;
align = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
1.0 - cell->xalign : cell->xalign);
*x_offset = align * (cell_area->width - DASHES_WIDTH);
*x_offset = MAX (*x_offset, 0) + cell->xpad;
}
if (y_offset)
{
*y_offset = cell->yalign * (cell_area->height - DASHES_HEIGHT);
*y_offset = MAX (*y_offset, 0) + cell->ypad;
}
}
else
{
if (x_offset)
*x_offset = 0;
if (y_offset)
*y_offset = 0;
}
*width = DASHES_WIDTH + 2 * cell->xpad;
*height = DASHES_HEIGHT + 2 * cell->ypad;
}
static void
gimp_cell_renderer_dashes_render (GtkCellRenderer *cell,
GdkWindow *window,
GtkWidget *widget,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GdkRectangle *expose_area,
GtkCellRendererState flags)
{
GimpCellRendererDashes *dashes = GIMP_CELL_RENDERER_DASHES (cell);
GdkRectangle rect;
gint x, y;
gimp_dash_pattern_segments_set (dashes->pattern,
dashes->segments, N_SEGMENTS);
gdk_rectangle_intersect (cell_area, expose_area, &rect);
gdk_draw_rectangle (window,
widget->style->base_gc[GTK_STATE_NORMAL], TRUE,
rect.x, rect.y, rect.width, rect.height);
y = cell_area->y + (cell_area->height - DASHES_HEIGHT) / 2;
for (x = 0; x < cell_area->width + BLOCK_WIDTH; x += BLOCK_WIDTH)
{
guint index = ((guint) x / BLOCK_WIDTH) % N_SEGMENTS;
if (dashes->segments[index])
{
rect.x = cell_area->x + x;
rect.y = y;
rect.width = BLOCK_WIDTH;
rect.height = DASHES_HEIGHT;
gdk_rectangle_intersect (&rect, expose_area, &rect);
gdk_draw_rectangle (widget->window,
widget->style->text_gc[GTK_STATE_NORMAL], TRUE,
rect.x, rect.y, rect.width, rect.height);
}
}
}
GtkCellRenderer *
gimp_cell_renderer_dashes_new (void)
{
return g_object_new (GIMP_TYPE_CELL_RENDERER_DASHES, NULL);
}

View File

@ -0,0 +1,58 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpcellrendererdashes.h
* Copyright (C) 2005 Sven Neumann <sven@gimp.org>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_CELL_RENDERER_DASHES_H__
#define __GIMP_CELL_RENDERER_DASHES_H__
#include <gtk/gtkcellrenderer.h>
#define GIMP_TYPE_CELL_RENDERER_DASHES (gimp_cell_renderer_dashes_get_type ())
#define GIMP_CELL_RENDERER_DASHES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CELL_RENDERER_DASHES, GimpCellRendererDashes))
#define GIMP_CELL_RENDERER_DASHES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CELL_RENDERER_DASHES, GimpCellRendererDashesClass))
#define GIMP_IS_CELL_RENDERER_DASHES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CELL_RENDERER_DASHES))
#define GIMP_IS_CELL_RENDERER_DASHES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CELL_RENDERER_DASHES))
#define GIMP_CELL_RENDERER_DASHES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CELL_RENDERER_DASHES, GimpCellRendererDashesClass))
typedef struct _GimpCellRendererDashesClass GimpCellRendererDashesClass;
struct _GimpCellRendererDashes
{
GtkCellRenderer parent_instance;
GArray *pattern;
gboolean *segments;
};
struct _GimpCellRendererDashesClass
{
GtkCellRendererClass parent_class;
};
GType gimp_cell_renderer_dashes_get_type (void) G_GNUC_CONST;
GtkCellRenderer * gimp_cell_renderer_dashes_new (void);
#endif /* __GIMP_CELL_RENDERER_DASHES_H__ */

View File

@ -25,8 +25,10 @@
#include "widgets-types.h"
#include "core/gimpdashpattern.h"
#include "core/gimpstrokeoptions.h"
#include "gimpcellrendererdashes.h"
#include "gimpdasheditor.h"
#include "gimpstrokeeditor.h"
@ -59,6 +61,8 @@ static gboolean gimp_stroke_editor_paint_button (GtkWidget *widget,
static void gimp_stroke_editor_dash_preset (GtkWidget *widget,
GimpStrokeOptions *options);
static void gimp_stroke_editor_combo_fill (GimpStrokeOptions *options,
GtkComboBox *box);
static GtkVBoxClass *parent_class = NULL;
@ -178,6 +182,7 @@ gimp_stroke_editor_constructor (GType type,
GtkWidget *expander;
GtkWidget *dash_editor;
GtkWidget *button;
GtkCellRenderer *cell;
GObject *object;
gint row = 0;
@ -286,6 +291,13 @@ gimp_stroke_editor_constructor (GType type,
_("Dash preset:"), 0.0, 0.5,
box, 2, FALSE);
cell = gimp_cell_renderer_dashes_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (box), cell, FALSE);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (box), cell,
"pattern", GIMP_INT_STORE_USER_DATA);
gimp_stroke_editor_combo_fill (editor->options, GTK_COMBO_BOX (box));
g_signal_connect (box, "changed",
G_CALLBACK (gimp_stroke_editor_dash_preset),
editor->options);
@ -365,3 +377,70 @@ gimp_stroke_editor_dash_preset (GtkWidget *widget,
gimp_stroke_options_set_dash_pattern (options, value, NULL);
}
}
static void
gimp_stroke_editor_combo_update (GtkTreeModel *model,
GParamSpec *pspec,
GimpStrokeOptions *options)
{
GtkTreeIter iter;
if (gimp_int_store_lookup_by_value (model, GIMP_DASH_CUSTOM, &iter))
{
GArray *pattern;
gtk_tree_model_get (model, &iter,
GIMP_INT_STORE_USER_DATA, &pattern,
-1);
gimp_dash_pattern_free (pattern);
pattern = gimp_dash_pattern_copy (options->dash_info);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
GIMP_INT_STORE_USER_DATA, pattern,
-1);
}
}
static void
gimp_stroke_editor_combo_fill (GimpStrokeOptions *options,
GtkComboBox *box)
{
GtkTreeModel *model = gtk_combo_box_get_model (box);
GtkTreeIter iter;
gboolean iter_valid;
for (iter_valid = gtk_tree_model_get_iter_first (model, &iter);
iter_valid;
iter_valid = gtk_tree_model_iter_next (model, &iter))
{
GArray *pattern;
gint value;
gtk_tree_model_get (model, &iter,
GIMP_INT_STORE_VALUE, &value,
-1);
if (value == GIMP_DASH_CUSTOM)
{
pattern = gimp_dash_pattern_copy (options->dash_info);
g_signal_connect_object (options, "notify::dash-info",
G_CALLBACK (gimp_stroke_editor_combo_update),
model, G_CONNECT_SWAPPED);
}
else
{
pattern = gimp_dash_pattern_from_preset (value);
}
if (pattern)
{
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
GIMP_INT_STORE_USER_DATA, pattern,
-1);
g_object_weak_ref (G_OBJECT (box),
(GWeakNotify) gimp_dash_pattern_free, pattern);
}
}
}

View File

@ -193,6 +193,7 @@ typedef struct _GimpViewRendererVectors GimpViewRendererVectors;
/* cell renderers */
typedef struct _GimpCellRendererAccel GimpCellRendererAccel;
typedef struct _GimpCellRendererDashes GimpCellRendererDashes;
typedef struct _GimpCellRendererViewable GimpCellRendererViewable;