Commit ed4dbde1 authored by David Odin's avatar David Odin
Browse files

plug-ins/gfig/gfig-rectangle.[ch] news files to implement a rectangle tool

* plug-ins/gfig/gfig-rectangle.[ch]
* plug-ins/gfig/images/stock-rectangle.png: news files to implement a
  rectangle tool to gfig.

* plug-ins/gfig/gfig-stock.c
* plug-ins/gfig/gfig-stock.h
* plug-ins/gfig/Makefile.am: modified accordingly.

* plug-ins/gfig/gfig-circle.c
* plug-ins/gfig/gfig-dialog.c
* plug-ins/gfig/gfig-dobject.c
* plug-ins/gfig/gfig-ellipse.c
* plug-ins/gfig/gfig-poly.c
* plug-ins/gfig/gfig-star.c
* plug-ins/gfig/gfig-types.h
* plug-ins/gfig/gfig.c
* plug-ins/gfig/gfig.h: modified to support the new shape and
  implement two new filling types: vertical and horizontal gradients.
  These gradients are imho much more useful than the shapeburst one.
parent bc9bc065
2004-12-29 DindinX <dindinx@gimp.org>
* plug-ins/gfig/gfig-rectangle.[ch]
* plug-ins/gfig/images/stock-rectangle.png: news files to implement a
rectangle tool to gfig.
* plug-ins/gfig/gfig-stock.c
* plug-ins/gfig/gfig-stock.h
* plug-ins/gfig/Makefile.am: modified accordingly.
* plug-ins/gfig/gfig-circle.c
* plug-ins/gfig/gfig-dialog.c
* plug-ins/gfig/gfig-dobject.c
* plug-ins/gfig/gfig-ellipse.c
* plug-ins/gfig/gfig-poly.c
* plug-ins/gfig/gfig-star.c
* plug-ins/gfig/gfig-types.h
* plug-ins/gfig/gfig.c
* plug-ins/gfig/gfig.h: modified to support the new shape and
implement two new filling types: vertical and horizontal gradients.
These gradients are imho much more useful than the shapeburst one.
2004-12-28 Bill Skaggs <weskaggs@primate.ucdavis.edu>
* plug-ins/common/compose.c: Recompose did not properly
......
......@@ -19,36 +19,38 @@ libexecdir = $(gimpplugindir)/plug-ins
libexec_PROGRAMS = gfig
gfig_SOURCES = \
gfig.c \
gfig.h \
gfig-arc.c \
gfig-arc.h \
gfig-bezier.c \
gfig-bezier.h \
gfig-circle.c \
gfig-circle.h \
gfig-dialog.c \
gfig-dialog.h \
gfig-dobject.c \
gfig-dobject.h \
gfig-ellipse.c \
gfig-ellipse.h \
gfig-grid.c \
gfig-grid.h \
gfig-line.c \
gfig-line.h \
gfig-poly.c \
gfig-poly.h \
gfig-preview.c \
gfig-preview.h \
gfig-spiral.c \
gfig-spiral.h \
gfig-star.c \
gfig-star.h \
gfig-stock.c \
gfig-stock.h \
gfig-style.c \
gfig-style.h \
gfig.c \
gfig.h \
gfig-arc.c \
gfig-arc.h \
gfig-bezier.c \
gfig-bezier.h \
gfig-circle.c \
gfig-circle.h \
gfig-dialog.c \
gfig-dialog.h \
gfig-dobject.c \
gfig-dobject.h \
gfig-ellipse.c \
gfig-ellipse.h \
gfig-grid.c \
gfig-grid.h \
gfig-line.c \
gfig-line.h \
gfig-poly.c \
gfig-poly.h \
gfig-preview.c \
gfig-preview.h \
gfig-rectangle.c \
gfig-rectangle.h \
gfig-spiral.c \
gfig-spiral.h \
gfig-star.c \
gfig-star.h \
gfig-stock.c \
gfig-stock.h \
gfig-style.c \
gfig-style.h \
gfig-types.h
EXTRA_DIST = README
......
......@@ -130,7 +130,10 @@ d_paint_circle (GfigObject *obj)
selopt.feather,
selopt.feather_radius);
paint_layer_fill ();
paint_layer_fill (center_pnt->pnt.x - radius,
center_pnt->pnt.y - radius,
center_pnt->pnt.x + radius,
center_pnt->pnt.y + radius);
if (obj->style.paint_type == PAINT_BRUSH_TYPE)
gimp_edit_stroke (gfig_context->drawable_id);
......
......@@ -57,6 +57,7 @@
#include "gfig-line.h"
#include "gfig-poly.h"
#include "gfig-preview.h"
#include "gfig-rectangle.h"
#include "gfig-spiral.h"
#include "gfig-star.h"
#include "gfig-stock.h"
......@@ -79,15 +80,9 @@
#define GRID_HIGHTLIGHT 1
#define GRID_RESTORE 2
#define PAINT_LAYERS_MENU 1
#define PAINT_BGS_MENU 2
#define PAINT_TYPE_MENU 3
#define SELECT_TYPE_MENU 1
#define SELECT_ARCTYPE_MENU 2
#define SELECT_TYPE_MENU_FILL 3
#define SELECT_TYPE_MENU_WHEN 4
#define OBJ_SELECT_GT 1
#define OBJ_SELECT_LT 2
#define OBJ_SELECT_EQ 4
......@@ -160,8 +155,7 @@ static void gfig_save_action_callback (GtkAction *action,
static void gfig_list_load_all (const gchar *path);
static void gfig_list_free_all (void);
static void create_notebook_pages (GtkWidget *notebook);
static void select_combo_callback (GtkWidget *widget,
gpointer data);
static void select_filltype_callback (GtkWidget *widget);
static void gfig_grid_action_callback (GtkAction *action,
gpointer data);
static void gfig_prefs_action_callback (GtkAction *action,
......@@ -416,15 +410,17 @@ gfig_dialog (void)
/* fill style combo box in Style frame */
gfig_context->fillstyle_combo = combo
= gimp_int_combo_box_new (_("No fill"), FILL_NONE,
_("Color fill"), FILL_COLOR,
_("Pattern fill"), FILL_PATTERN,
_("Gradient fill"), FILL_GRADIENT,
= gimp_int_combo_box_new (_("No fill"), FILL_NONE,
_("Color fill"), FILL_COLOR,
_("Pattern fill"), FILL_PATTERN,
_("Shape Gradient"), FILL_GRADIENT,
_("Vertical Gradient"), FILL_VERTICAL,
_("Horizontal Gradient"), FILL_HORIZONTAL,
NULL);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), 0);
g_signal_connect (combo, "changed",
G_CALLBACK (select_combo_callback),
GINT_TO_POINTER (SELECT_TYPE_MENU_FILL));
G_CALLBACK (select_filltype_callback),
NULL);
gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
gtk_widget_show (combo);
......@@ -810,7 +806,6 @@ gfig_list_load_all (const gchar *path)
gfig_context->current_obj = NULL;
gfig_list_free_all ();
if (! gfig_list)
{
GFigObj *gfig;
......@@ -904,6 +899,9 @@ create_ui_manager (GtkWidget *window)
{ "line", GFIG_STOCK_LINE,
NULL, "L", N_("Create line"), LINE },
{ "rectangle", GFIG_STOCK_RECTANGLE,
NULL, "R", N_("Create rectangle"), RECTANGLE },
{ "circle", GFIG_STOCK_CIRCLE,
NULL, "C", N_("Create circle"), CIRCLE },
......@@ -987,6 +985,7 @@ create_ui_manager (GtkWidget *window)
"<ui>"
" <toolbar name=\"gfig-toolbar\">"
" <toolitem action=\"line\" />"
" <toolitem action=\"rectangle\" />"
" <toolitem action=\"circle\" />"
" <toolitem action=\"ellipse\" />"
" <toolitem action=\"arc\" />"
......@@ -1029,6 +1028,7 @@ static void
create_notebook_pages (GtkWidget *notebook)
{
tool_option_no_option (notebook); /* Line */
tool_option_no_option (notebook); /* Rectangle */
tool_option_no_option (notebook); /* Circle */
tool_option_no_option (notebook); /* Ellipse */
tool_option_no_option (notebook); /* Arc */
......@@ -1160,33 +1160,15 @@ lower_selected_obj (GtkWidget *widget,
static void
select_combo_callback (GtkWidget *widget,
gpointer data)
select_filltype_callback (GtkWidget *widget)
{
gint mtype = GPOINTER_TO_INT (data);
gint value;
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value);
gtk_notebook_set_current_page (GTK_NOTEBOOK (fill_type_notebook), value);
switch (mtype)
{
case SELECT_TYPE_MENU:
selopt.type = (SelectionType) value;
break;
case SELECT_ARCTYPE_MENU:
selopt.as_pie = (ArcType) value;
break;
case SELECT_TYPE_MENU_FILL:
gfig_context_get_current_style ()->fill_type = (FillType) value;
break;
gtk_notebook_set_current_page (GTK_NOTEBOOK (fill_type_notebook),
MIN (value, FILL_GRADIENT));
default:
g_return_if_reached ();
break;
}
gfig_context_get_current_style ()->fill_type = (FillType) value;
gfig_paint_callback ();
}
......@@ -1806,9 +1788,9 @@ load_file_chooser_response (GtkFileChooser *chooser,
}
void
paint_layer_fill (void)
paint_layer_fill (gdouble x1, gdouble y1, gdouble x2, gdouble y2)
{
GimpBucketFillMode fill_mode;
GimpBucketFillMode fill_mode = FILL_NONE;
Style *current_style;
current_style = gfig_context_get_current_style ();
......@@ -1842,7 +1824,37 @@ paint_layer_fill (void)
0.0, 0.0, /* (x1, y1) - ignored */
0.0, 0.0); /* (x2, y2) - ignored */
return;
default:
case FILL_VERTICAL:
gimp_edit_blend (gfig_context->drawable_id,
GIMP_CUSTOM_MODE,
GIMP_NORMAL_MODE,
GIMP_GRADIENT_LINEAR,
100.0,
0.0,
GIMP_REPEAT_NONE,
FALSE,
FALSE,
0,
0.0,
FALSE,
x1, y1,
x1, y2);
return;
case FILL_HORIZONTAL:
gimp_edit_blend (gfig_context->drawable_id,
GIMP_CUSTOM_MODE,
GIMP_NORMAL_MODE,
GIMP_GRADIENT_LINEAR,
100.0,
0.0,
GIMP_REPEAT_NONE,
FALSE,
FALSE,
0,
0.0,
FALSE,
x1, y1,
x2, y1);
return;
}
......@@ -1953,6 +1965,7 @@ toggle_obj_type (GtkRadioAction *action,
switch (selvals.otype)
{
case LINE:
case RECTANGLE:
case CIRCLE:
case ELLIPSE:
case ARC:
......
......@@ -46,6 +46,7 @@
#include "gfig-ellipse.h"
#include "gfig-line.h"
#include "gfig-poly.h"
#include "gfig-rectangle.h"
#include "gfig-spiral.h"
#include "gfig-star.h"
......@@ -204,6 +205,7 @@ gfig_init_object_classes (void)
{
d_arc_object_class_init ();
d_line_object_class_init ();
d_rectangle_object_class_init ();
d_circle_object_class_init ();
d_ellipse_object_class_init ();
d_poly_object_class_init ();
......@@ -492,6 +494,7 @@ object_operation (GdkPoint *to_pnt,
switch (operation_obj->type)
{
case LINE:
case RECTANGLE:
case CIRCLE:
case ELLIPSE:
case POLY:
......@@ -511,6 +514,7 @@ object_operation (GdkPoint *to_pnt,
switch (operation_obj->type)
{
case LINE:
case RECTANGLE:
case CIRCLE:
case ELLIPSE:
case POLY:
......@@ -791,6 +795,10 @@ object_start (GdkPoint *pnt,
draw_sqr (pnt, TRUE);
d_line_start (pnt, shift_down);
break;
case RECTANGLE:
draw_sqr (pnt, TRUE);
d_rectangle_start (pnt, shift_down);
break;
case CIRCLE:
draw_sqr (pnt, TRUE);
d_circle_start (pnt, shift_down);
......@@ -847,6 +855,10 @@ object_end (GdkPoint *pnt,
d_line_end (pnt, shift_down);
draw_sqr (pnt, TRUE);
break;
case RECTANGLE:
d_rectangle_end (pnt, shift_down);
draw_sqr (pnt, TRUE);
break;
case CIRCLE:
draw_sqr (pnt, TRUE);
d_circle_end (pnt, shift_down);
......
......@@ -149,7 +149,7 @@ d_paint_ellipse (GfigObject *obj)
selopt.feather,
selopt.feather_radius);
paint_layer_fill ();
paint_layer_fill (top_x, top_y, top_x + bound_wx, top_y + bound_wy);
if (obj->style.paint_type == PAINT_BRUSH_TYPE)
gimp_edit_stroke (gfig_context->drawable_id);
......
......@@ -161,6 +161,7 @@ d_paint_poly (GfigObject *obj)
gint loop;
GdkPoint first_pnt, last_pnt;
gboolean first = TRUE;
gdouble *min_max;
g_assert (obj != NULL);
......@@ -173,6 +174,7 @@ d_paint_poly (GfigObject *obj)
return; /* no-line */
line_pnts = g_new0 (gdouble, 2 * seg_count + 1);
min_max = g_new (gdouble, 4);
/* Go around all the points drawing a line from one to the next */
......@@ -190,7 +192,7 @@ d_paint_poly (GfigObject *obj)
for (loop = 0 ; loop < obj->type_data ; loop++)
{
gdouble lx, ly;
gdouble lx, ly;
GdkPoint calc_pnt;
ang_loop = (gdouble)loop * ang_grid + offset_angle;
......@@ -218,6 +220,15 @@ d_paint_poly (GfigObject *obj)
{
first_pnt = calc_pnt;
first = FALSE;
min_max[0] = min_max[2] = calc_pnt.x;
min_max[1] = min_max[3] = calc_pnt.y;
}
else
{
min_max[0] = MIN (min_max[0], calc_pnt.x);
min_max[1] = MIN (min_max[1], calc_pnt.y);
min_max[2] = MAX (min_max[2], calc_pnt.x);
min_max[3] = MAX (min_max[3], calc_pnt.y);
}
}
......@@ -226,9 +237,15 @@ d_paint_poly (GfigObject *obj)
/* Scale before drawing */
if (selvals.scaletoimage)
scale_to_original_xy (&line_pnts[0], i/2);
{// FIXME scale xmax and al.
scale_to_original_xy (&line_pnts[0], i/2);
scale_to_original_xy (min_max, 2);
}
else
scale_to_xy (&line_pnts[0], i/2);
{
scale_to_xy (&line_pnts[0], i/2);
scale_to_xy (min_max, 2);
}
gimp_free_select (gfig_context->image_id,
......@@ -238,12 +255,13 @@ d_paint_poly (GfigObject *obj)
selopt.feather,
selopt.feather_radius);
paint_layer_fill ();
paint_layer_fill (min_max[0], min_max[1], min_max[2], min_max[3]);
if (obj->style.paint_type == PAINT_BRUSH_TYPE)
gimp_edit_stroke (gfig_context->drawable_id);
g_free (line_pnts);
g_free (min_max);
}
void
......
/*
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This is a plug-in for the GIMP.
*
* Generates images containing vector type drawings.
*
* Copyright (C) 1997 Andy Thomas alt@picnic.demon.co.uk
*
* 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 <math.h>
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "gfig.h"
#include "gfig-dobject.h"
#include "gfig-rectangle.h"
#include "libgimp/stdplugins-intl.h"
static void d_draw_rectangle (GfigObject *obj);
static void d_paint_rectangle (GfigObject *obj);
static GfigObject *d_copy_rectangle (GfigObject *obj);
static void d_update_rectangle (GdkPoint *pnt);
static gint
gfig_scale_x (gint x)
{
if (!selvals.scaletoimage)
return (gint) (x * (1 / scale_x_factor));
else
return x;
}
static gint
gfig_scale_y (gint y)
{
if (!selvals.scaletoimage)
return (gint) (y * (1 / scale_y_factor));
else
return y;
}
static void
d_draw_rectangle (GfigObject *obj)
{
DobjPoints *first_pnt;
DobjPoints *second_pnt;
gint xmin, ymin;
gint xmax, ymax;
first_pnt = obj->points;
if (!first_pnt)
return; /* End-of-line */
second_pnt = first_pnt->next;
if (!second_pnt)
{
g_warning ("Internal error - rectangle no edge pnt");
}
draw_sqr (&first_pnt->pnt, obj == gfig_context->selected_obj);
draw_sqr (&second_pnt->pnt, obj == gfig_context->selected_obj);
xmin = MIN (gfig_scale_x (first_pnt->pnt.x),
gfig_scale_x (second_pnt->pnt.x));
ymin = MIN (gfig_scale_y (first_pnt->pnt.y),
gfig_scale_y (second_pnt->pnt.y));
xmax = MAX (gfig_scale_x (first_pnt->pnt.x),
gfig_scale_x (second_pnt->pnt.x));
ymax = MAX (gfig_scale_y (first_pnt->pnt.y),
gfig_scale_y (second_pnt->pnt.y));
gdk_draw_rectangle (gfig_context->preview->window,
gfig_gc,
FALSE,
xmin, ymin,
xmax - xmin, ymax - ymin);
}
static void
d_paint_rectangle (GfigObject *obj)
{
DobjPoints *first_pnt;
DobjPoints *second_pnt;
gdouble dpnts[4];
g_assert (obj != NULL);
/* Drawing rectangles is hard .
* 1) select rectangle
* 2) stroke it
*/
first_pnt = obj->points;
if (!first_pnt)
return; /* End-of-line */
second_pnt = first_pnt->next;
if (!second_pnt)
{
g_error ("Internal error - rectangle no second pnt");
}
dpnts[0] = (gdouble) MIN (first_pnt->pnt.x, second_pnt->pnt.x);
dpnts[1] = (gdouble) MIN (first_pnt->pnt.y, second_pnt->pnt.y);
dpnts[2] = (gdouble) MAX (first_pnt->pnt.x, second_pnt->pnt.x);
dpnts[3] = (gdouble) MAX (first_pnt->pnt.y, second_pnt->pnt.y);
/* Scale before drawing */
if (selvals.scaletoimage)
scale_to_original_xy (&dpnts[0], 2);
else
scale_to_xy (&dpnts[0], 2);
gimp_rect_select (gfig_context->image_id,
dpnts[0], dpnts[1],
dpnts[2] - dpnts[0],
dpnts[3] - dpnts[1],
selopt.type,
selopt.feather,
selopt.feather_radius);
paint_layer_fill (dpnts[0], dpnts[1], dpnts[2], dpnts[3]);
if (obj->style.paint_type == PAINT_BRUSH_TYPE)
gimp_edit_stroke (gfig_context->drawable_id);
}
static GfigObject *
d_copy_rectangle (GfigObject * obj)
{
GfigObject *new_rectangle;
g_assert (obj->type == RECTANGLE);
new_rectangle = d_new_object (RECTANGLE,
obj->points->pnt.x, obj->points->pnt.y);
new_rectangle->points->next = d_copy_dobjpoints (obj->points->next);
return new_rectangle;
}
void
d_rectangle_object_class_init (void)
{
GfigObjectClass *class = &dobj_class[RECTANGLE];
class->type = RECTANGLE;
class->name = "RECTANGLE";
class->drawfunc = d_draw_rectangle;
class->paintfunc = d_paint_rectangle;
class->copyfunc = d_copy_rectangle;
class->update = d_update_rectangle;
}
static void
d_update_rectangle (GdkPoint *pnt)
{
DobjPoints *first_pnt;
DobjPoints *second_pnt;
gint xmin, ymin;
gint xmax, ymax;