gimp r25344 - in trunk: . app/text app/tools
- From: weskaggs svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r25344 - in trunk: . app/text app/tools
- Date: Wed, 2 Apr 2008 22:32:33 +0100 (BST)
Author: weskaggs
Date: Wed Apr 2 22:32:32 2008
New Revision: 25344
URL: http://svn.gnome.org/viewvc/gimp?rev=25344&view=rev
Log:
Bill Skaggs <weskaggs primate ucdavis edu>
* app/text/gimptextlayout.c
* app/tools/gimptexttool.[ch]
* app/tools/gimprectangletool.[ch]
* app/tools/gimptextoptions.c: allow resizing of text
box. This is work in progress, and needs some tweaks
and fixes. See bug #122707.
Modified:
trunk/ChangeLog
trunk/app/text/gimptextlayout.c
trunk/app/tools/gimprectangletool.c
trunk/app/tools/gimprectangletool.h
trunk/app/tools/gimptextoptions.c
trunk/app/tools/gimptexttool.c
trunk/app/tools/gimptexttool.h
Modified: trunk/app/text/gimptextlayout.c
==============================================================================
--- trunk/app/text/gimptextlayout.c (original)
+++ trunk/app/text/gimptextlayout.c Wed Apr 2 22:32:32 2008
@@ -150,9 +150,6 @@
alignment = PANGO_ALIGN_CENTER;
break;
case GIMP_TEXT_JUSTIFY_FILL:
- /* FIXME: This doesn't work since the implementation is missing
- at the Pango level.
- */
alignment = PANGO_ALIGN_LEFT;
pango_layout_set_justify (layout->layout, TRUE);
break;
@@ -206,6 +203,11 @@
case GIMP_TEXT_BOX_DYNAMIC:
break;
case GIMP_TEXT_BOX_FIXED:
+ layout->extents.width =
+ PANGO_PIXELS (gimp_text_layout_pixel_size (image->gimp,
+ text->box_width,
+ text->box_unit,
+ xres));
layout->extents.height =
PANGO_PIXELS (gimp_text_layout_pixel_size (image->gimp,
text->box_height,
Modified: trunk/app/tools/gimprectangletool.c
==============================================================================
--- trunk/app/tools/gimprectangletool.c (original)
+++ trunk/app/tools/gimprectangletool.c Wed Apr 2 22:32:32 2008
@@ -4116,3 +4116,15 @@
break;
}
}
+
+/**
+ * gimp_rectangle_tool_rectangle_is_narrow:
+ *
+ * Returns TRUE if the handles are being shown outside the
+ * rectangle, FALSE if they are inside
+ */
+gboolean
+gimp_rectangle_tool_rectangle_is_narrow (GimpRectangleTool *rect_tool)
+{
+ return GIMP_RECTANGLE_TOOL_GET_PRIVATE (rect_tool)->narrow_mode;
+}
Modified: trunk/app/tools/gimprectangletool.h
==============================================================================
--- trunk/app/tools/gimprectangletool.h (original)
+++ trunk/app/tools/gimprectangletool.h Wed Apr 2 22:32:32 2008
@@ -139,11 +139,11 @@
const gchar *width_property,
const gchar *height_property);
gboolean gimp_rectangle_tool_rectangle_is_new (GimpRectangleTool *rect_tool);
+gboolean gimp_rectangle_tool_rectangle_is_narrow (GimpRectangleTool *rect_tool);
gboolean gimp_rectangle_tool_point_in_rectangle (GimpRectangleTool *rect_tool,
gdouble x,
gdouble y);
-
/* convenience functions */
void gimp_rectangle_tool_install_properties (GObjectClass *klass);
Modified: trunk/app/tools/gimptextoptions.c
==============================================================================
--- trunk/app/tools/gimptextoptions.c (original)
+++ trunk/app/tools/gimptextoptions.c Wed Apr 2 22:32:32 2008
@@ -43,13 +43,14 @@
#include "gimptextoptions.h"
#include "gimptooloptions-gui.h"
+#include "gimprectangleoptions.h"
#include "gimp-intl.h"
enum
{
- PROP_0,
+ PROP_0 = GIMP_RECTANGLE_OPTIONS_PROP_LAST + 1,
PROP_FONT_SIZE,
PROP_UNIT,
PROP_HINTING,
@@ -90,7 +91,9 @@
GimpContext *context);
-G_DEFINE_TYPE (GimpTextOptions, gimp_text_options, GIMP_TYPE_TOOL_OPTIONS)
+G_DEFINE_TYPE_WITH_CODE (GimpTextOptions, gimp_text_options, GIMP_TYPE_TOOL_OPTIONS,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_RECTANGLE_OPTIONS,
+ NULL))
static void
@@ -171,6 +174,8 @@
GIMP_VIEWABLE_MAX_BUTTON_SIZE,
GIMP_VIEW_SIZE_SMALL,
GIMP_PARAM_STATIC_STRINGS);
+
+ gimp_rectangle_options_install_properties (object_class);
}
static void
@@ -233,7 +238,7 @@
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ gimp_rectangle_options_get_property (object, property_id, value, pspec);
break;
}
}
@@ -291,7 +296,7 @@
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ gimp_rectangle_options_set_property (object, property_id, value, pspec);
break;
}
}
Modified: trunk/app/tools/gimptexttool.c
==============================================================================
--- trunk/app/tools/gimptexttool.c (original)
+++ trunk/app/tools/gimptexttool.c Wed Apr 2 22:32:32 2008
@@ -58,6 +58,8 @@
#include "display/gimpdisplay.h"
#include "gimpeditselectiontool.h"
+#include "gimprectangletool.h"
+#include "gimprectangleoptions.h"
#include "gimptextoptions.h"
#include "gimptexttool.h"
#include "gimptoolcontrol.h"
@@ -70,6 +72,8 @@
/* local function prototypes */
+static void gimp_text_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface);
+
static GObject * gimp_text_tool_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
@@ -84,6 +88,12 @@
guint32 time,
GdkModifierType state,
GimpDisplay *display);
+static void gimp_text_tool_button_release (GimpTool *tool,
+ GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpButtonReleaseType release_type,
+ GimpDisplay *display);
static void gimp_text_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
@@ -123,8 +133,14 @@
GimpDrawable *drawable,
gboolean confirm);
-
-G_DEFINE_TYPE (GimpTextTool, gimp_text_tool, GIMP_TYPE_TOOL)
+static gboolean gimp_text_tool_rectangle_changed (GimpRectangleTool *rect_tool);
+void gimp_rectangle_tool_frame_item (GimpRectangleTool *rect_tool,
+ GimpItem *item);
+
+G_DEFINE_TYPE_WITH_CODE (GimpTextTool, gimp_text_tool,
+ GIMP_TYPE_DRAW_TOOL,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_RECTANGLE_TOOL,
+ gimp_text_tool_rectangle_tool_iface_init))
#define parent_class gimp_text_tool_parent_class
@@ -149,17 +165,35 @@
static void
gimp_text_tool_class_init (GimpTextToolClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
+ GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
- object_class->constructor = gimp_text_tool_constructor;
- object_class->dispose = gimp_text_tool_dispose;
- object_class->finalize = gimp_text_tool_finalize;
-
- tool_class->control = gimp_text_tool_control;
- tool_class->button_press = gimp_text_tool_button_press;
- tool_class->key_press = gimp_edit_selection_tool_key_press;
- tool_class->cursor_update = gimp_text_tool_cursor_update;
+ object_class->constructor = gimp_text_tool_constructor;
+ object_class->dispose = gimp_text_tool_dispose;
+ object_class->finalize = gimp_text_tool_finalize;
+ object_class->set_property = gimp_rectangle_tool_set_property;
+ object_class->get_property = gimp_rectangle_tool_get_property;
+
+ gimp_rectangle_tool_install_properties (object_class);
+
+ tool_class->control = gimp_text_tool_control;
+ tool_class->button_press = gimp_text_tool_button_press;
+ tool_class->motion = gimp_rectangle_tool_motion;
+ tool_class->button_release = gimp_text_tool_button_release;
+ tool_class->key_press = gimp_edit_selection_tool_key_press;
+ tool_class->oper_update = gimp_rectangle_tool_oper_update;
+ tool_class->cursor_update = gimp_text_tool_cursor_update;
+
+ draw_tool_class->draw = gimp_rectangle_tool_draw;
+}
+
+static void
+gimp_text_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface)
+{
+ iface->execute = NULL;
+ iface->cancel = NULL;
+ iface->rectangle_changed = gimp_text_tool_rectangle_changed;
}
static void
@@ -180,6 +214,8 @@
GIMP_TOOL_CURSOR_TEXT);
gimp_tool_control_set_action_object_1 (tool->control,
"context/context-font-select-set");
+
+ text_tool->handle_rectangle_changed = TRUE;
}
static GObject *
@@ -193,6 +229,8 @@
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
+ gimp_rectangle_tool_constructor (object);
+
text_tool = GIMP_TEXT_TOOL (object);
options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
@@ -238,6 +276,8 @@
{
GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
+ gimp_rectangle_tool_control (tool, action, display);
+
switch (action)
{
case GIMP_TOOL_ACTION_PAUSE:
@@ -259,16 +299,39 @@
GdkModifierType state,
GimpDisplay *display)
{
- GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
- GimpText *text = text_tool->text;
- GimpDrawable *drawable;
+ GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
+ GimpText *text = text_tool->text;
+ GimpDrawable *drawable;
+ GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
+ GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (tool);
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+
- GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
- display);
+ /* FIXME: this should certainly be done elsewhere */
+ g_object_set (options,
+ "highlight", FALSE,
+ NULL);
text_tool->x1 = coords->x;
text_tool->y1 = coords->y;
+ gimp_rectangle_tool_button_press (tool, coords, time, state, display);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+
+ /* bail out now if the rectangle is narrow and the button
+ press is outside the layer */
+ if (gimp_rectangle_tool_rectangle_is_narrow (rect_tool))
+ {
+ GimpItem *item = GIMP_ITEM (text_tool->layer);
+ gdouble x = coords->x - item->offset_x;
+ gdouble y = coords->y - item->offset_y;
+
+ if (x < 0 || x > item->width || y < 0 || y > item->height)
+ return;
+ }
+
drawable = gimp_image_get_active_drawable (display->image);
gimp_text_tool_set_drawable (text_tool, drawable, FALSE);
@@ -276,12 +339,14 @@
if (GIMP_IS_LAYER (drawable))
{
GimpItem *item = GIMP_ITEM (drawable);
+ gdouble x = coords->x - item->offset_x;
+ gdouble y = coords->y - item->offset_y;
coords->x -= item->offset_x;
coords->y -= item->offset_y;
- if (coords->x > 0 && coords->x < gimp_item_width (item) &&
- coords->y > 0 && coords->y < gimp_item_height (item))
+ if (x > 0 && x < gimp_item_width (item) &&
+ y > 0 && y < gimp_item_height (item))
{
/* did the user click on a text layer? */
if (gimp_text_tool_set_drawable (text_tool, drawable, TRUE))
@@ -296,10 +361,85 @@
}
/* create a new text layer */
+ text_tool->text_box_fixed = FALSE;
gimp_text_tool_connect (text_tool, NULL, NULL);
gimp_text_tool_editor (text_tool);
}
+#define MIN_LAYER_WIDTH 20
+
+/*
+ * Here is what we want to do:
+ * 1) If the user clicked on an existing text layer, and no rectangle
+ * yet exists there, we want to create one with the right shape.
+ * 2) If the user has modified the rectangle for an existing text layer,
+ * we want to change its shape accordingly. We do this by falling
+ * through to code that causes the "rectangle-changed" signal to
+ * be emitted.
+ * 3) If the rectangle that has been swept out is too small, we want to
+ * use dynamic text.
+ * 4) Otherwise, we want to use the new rectangle that the user has
+ * created as our text box. This again is done by causing
+ * "rectangle-changed" to be emitted.
+ */
+static void
+gimp_text_tool_button_release (GimpTool *tool,
+ GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpButtonReleaseType release_type,
+ GimpDisplay *display)
+{
+ GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (tool);
+ GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
+ GimpText *text = text_tool->text;
+ gint x1, y1, x2, y2;
+
+ g_object_get (rect_tool,
+ "x1", &x1,
+ "y1", &y1,
+ "x2", &x2,
+ "y2", &y2,
+ NULL);
+
+ if (text && text_tool->text == text)
+ {
+ if (gimp_rectangle_tool_rectangle_is_new (rect_tool))
+ {
+ /* user has clicked on an existing text layer */
+
+ gimp_tool_control_halt (tool->control);
+ text_tool->handle_rectangle_changed = FALSE;
+ gimp_rectangle_tool_frame_item (rect_tool,
+ GIMP_ITEM (text_tool->layer));
+ text_tool->handle_rectangle_changed = TRUE;
+ return;
+ }
+ else
+ {
+ /* user has modified shape of an existing text layer */
+ }
+ }
+ else if (y2 - y1 < MIN_LAYER_WIDTH)
+ {
+ /* user has clicked in dead space */
+
+ if (GIMP_IS_TEXT (text_tool->proxy))
+ g_object_set (text_tool->proxy,
+ "box-mode", GIMP_TEXT_BOX_DYNAMIC,
+ NULL);
+ text_tool->handle_rectangle_changed = FALSE;
+ }
+ else
+ {
+ /* user has defined box for a new text layer */
+ }
+
+ gimp_rectangle_tool_button_release (tool, coords, time, state,
+ release_type, display);
+ text_tool->handle_rectangle_changed = TRUE;
+}
+
static void
gimp_text_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
@@ -308,6 +448,8 @@
{
/* FIXME: should do something fancy here... */
+ gimp_rectangle_tool_cursor_update (tool, coords, state, display);
+
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
@@ -474,6 +616,20 @@
if (text_tool->editor && strcmp (pspec->name, "text") == 0)
gimp_text_tool_editor_update (text_tool);
+
+ /* we need to redraw the rectangle if it is visible and the shape of
+ the layer has changed, because of an undo for example. */
+ if ((0 == strcmp (pspec->name, "box-width"))
+ || (0 == strcmp (pspec->name, "box-height"))
+ || (text->box_mode == GIMP_TEXT_BOX_DYNAMIC))
+ {
+ GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (text_tool);
+
+ text_tool->handle_rectangle_changed = FALSE;
+ gimp_rectangle_tool_frame_item (rect_tool,
+ GIMP_ITEM (text_tool->layer));
+ text_tool->handle_rectangle_changed = TRUE;
+ }
}
static gboolean
@@ -611,6 +767,16 @@
gimp_image_undo_group_end (image);
}
+ /* if we're doing dynamic text, we want to update the
+ * shape of the rectangle */
+ if (layer->text->box_mode == GIMP_TEXT_BOX_DYNAMIC)
+ {
+ text_tool->handle_rectangle_changed = FALSE;
+ gimp_rectangle_tool_frame_item (GIMP_RECTANGLE_TOOL (text_tool),
+ GIMP_ITEM (layer));
+ text_tool->handle_rectangle_changed = TRUE;
+ }
+
gimp_image_flush (image);
}
@@ -723,6 +889,36 @@
gimp_image_add_layer (image, layer, -1);
+ if (text_tool->text_box_fixed)
+ {
+ GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (text_tool);
+ GimpItem *item = GIMP_ITEM (layer);
+ gint x1, y1, x2, y2;
+
+ g_object_get (rect_tool,
+ "x1", &x1,
+ "y1", &y1,
+ "x2", &x2,
+ "y2", &y2,
+ NULL);
+ g_object_set (text_tool->proxy,
+ "box-mode", GIMP_TEXT_BOX_FIXED,
+ "box-width", (gdouble) (x2 - x1),
+ "box-height", (gdouble) (y2 - y1),
+ NULL);
+ gimp_item_translate (item,
+ x1 - item->offset_x,
+ y1 - item->offset_y,
+ TRUE);
+ }
+ else
+ {
+ text_tool->handle_rectangle_changed = FALSE;
+ gimp_rectangle_tool_frame_item (GIMP_RECTANGLE_TOOL (text_tool),
+ GIMP_ITEM (layer));
+ text_tool->handle_rectangle_changed = TRUE;
+ }
+
gimp_image_undo_group_end (image);
gimp_image_flush (image);
@@ -917,9 +1113,21 @@
gimp_text_tool_layer_changed (GimpImage *image,
GimpTextTool *text_tool)
{
- GimpLayer *layer = gimp_image_get_active_layer (image);
+ GimpLayer *layer = gimp_image_get_active_layer (image);
+ GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (text_tool);
gimp_text_tool_set_drawable (text_tool, GIMP_DRAWABLE (layer), FALSE);
+
+ if (text_tool->layer)
+ {
+ if (! gimp_rectangle_tool_rectangle_is_new (rect_tool))
+ {
+ text_tool->handle_rectangle_changed = FALSE;
+ gimp_rectangle_tool_frame_item (rect_tool,
+ GIMP_ITEM (text_tool->layer));
+ text_tool->handle_rectangle_changed = TRUE;
+ }
+ }
}
static void
@@ -1054,3 +1262,103 @@
}
}
}
+
+static gboolean
+gimp_text_tool_rectangle_changed (GimpRectangleTool *rect_tool)
+{
+ GimpTextTool *text_tool = GIMP_TEXT_TOOL (rect_tool);
+ GimpText *text = text_tool->text;
+ GimpImage *image = text_tool->image;
+ GimpItem *item ;
+ gint x1, y1, x2, y2;
+
+ if (text_tool->handle_rectangle_changed)
+ {
+ g_object_get (rect_tool,
+ "x1", &x1,
+ "y1", &y1,
+ "x2", &x2,
+ "y2", &y2,
+ NULL);
+
+ if (! text)
+ {
+ /*
+ * we can't set properties for the text layer, because
+ * it isn't created until some text has been inserted,
+ * so we need to make a special note that will remind
+ * us what to do when we actually create the layer
+ */
+ text_tool->text_box_fixed = TRUE;
+ return TRUE;
+ }
+
+ g_object_set (text_tool->proxy,
+ "box-mode", GIMP_TEXT_BOX_FIXED,
+ "box-width", (gdouble) (x2 - x1),
+ "box-height", (gdouble) (y2 - y1),
+ NULL);
+
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT,
+ _("Reshape Text Layer"));
+ item = GIMP_ITEM (text_tool->layer);
+ gimp_item_translate (item,
+ x1 - item->offset_x,
+ y1 - item->offset_y,
+ TRUE);
+ gimp_text_tool_apply (text_tool);
+ gimp_image_undo_group_end (image);
+ }
+
+ return TRUE;
+}
+
+/* this doesn't belong here but this is the only place
+ it is used at the moment -- Bill
+*/
+
+/**
+ * gimp_rectangle_tool_frame_item:
+ * @rect_tool: a #GimpRectangleTool interface
+ * @item: a #GimpItem attached to the image on which a
+ * rectangle is being shown.
+ *
+ * Convenience function to set the corners of the rectangle to
+ * match the bounds of the specified item. The rectangle interface
+ * must be active (i.e., showing a rectangle), and the item must be
+ * attached to the image on which the rectangle is active.
+ */
+void
+gimp_rectangle_tool_frame_item (GimpRectangleTool *rect_tool,
+ GimpItem *item)
+{
+ GimpDisplay *display = GIMP_TOOL (rect_tool)->display;
+ gint offset_x;
+ gint offset_y;
+ gint width;
+ gint height;
+
+ g_return_if_fail (GIMP_IS_ITEM (item));
+ g_return_if_fail (gimp_item_is_attached (item));
+ g_return_if_fail (display != NULL);
+ g_return_if_fail ( (display->image == item->image) );
+
+ width = gimp_item_width (item);
+ height = gimp_item_height (item);
+ gimp_item_offsets (item, &offset_x, &offset_y);
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (rect_tool));
+
+ g_object_set (rect_tool,
+ "x1", offset_x,
+ "y1", offset_y,
+ "x2", offset_x + width,
+ "y2", offset_y + height,
+ NULL);
+
+ gimp_rectangle_tool_set_function (rect_tool,
+ GIMP_RECTANGLE_TOOL_MOVING);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (rect_tool));
+}
+
Modified: trunk/app/tools/gimptexttool.h
==============================================================================
--- trunk/app/tools/gimptexttool.h (original)
+++ trunk/app/tools/gimptexttool.h Wed Apr 2 22:32:32 2008
@@ -20,7 +20,7 @@
#define __GIMP_TEXT_TOOL_H__
-#include "gimptool.h"
+#include "gimpdrawtool.h"
#define GIMP_TYPE_TEXT_TOOL (gimp_text_tool_get_type ())
@@ -37,7 +37,7 @@
struct _GimpTextTool
{
- GimpTool parent_instance;
+ GimpDrawTool parent_instance;
GimpText *proxy;
GList *pending;
@@ -52,11 +52,14 @@
GtkWidget *editor;
GtkWidget *confirm_dialog;
+
+ gboolean handle_rectangle_changed;
+ gboolean text_box_fixed;
};
struct _GimpTextToolClass
{
- GimpToolClass parent_class;
+ GimpDrawToolClass parent_class;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]