merged brush_preview and pattern_preview into one more generic widget

--Sven
This commit is contained in:
Sven Neumann 1999-09-01 00:12:33 +00:00
parent 01e27f730a
commit 9f84f50d1c
24 changed files with 850 additions and 3002 deletions

View file

@ -1,3 +1,18 @@
Wed Sep 1 02:12:09 MEST 1999 Sven Neumann <sven@gimp.org>
* app/gimpbrushpreview.[ch]
* app/gimppatternprewiew.[ch]: removed
* app/gimpcontextpreview.[ch]: new files.
Merged the preview_widgets into one more generic widget. I'm
calling this context_preview since I hope the widgets will
become useful for the context_manager. I'll add a gradient
preview soon.
* app/Makefile.am
* app/devices.c
* app/inidicator_area.c: Use the new gimp_context_preview.
Tue Sep 1 00:19:30 CEST 1999 vidar@prosalg.no (Vidar Madsen)
* plug-ins/common/spheredesigner.c: Various fixes and enhancements.

View file

@ -193,10 +193,10 @@ gimp_SOURCES = \
gimpbrushlistP.h \
gimpbrushpipe.c \
gimpbrushpipe.h \
gimpbrushpreview.c \
gimpbrushpreview.h \
gimpcontext.c \
gimpcontext.h \
gimpcontextpreview.c \
gimpcontextpreview.h \
gimpdnd.c \
gimpdnd.h \
gimphistogram.c \
@ -213,8 +213,6 @@ gimp_SOURCES = \
gimplutP.h \
gimpparasite.c \
gimpparasite.h \
gimppatternpreview.c \
gimppatternpreview.h \
gimpprogress.c \
gimpprogress.h \
gimprc.c \

View file

@ -23,8 +23,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -749,17 +748,17 @@ create_device_status (void)
2, 3, i, i+1,
0, 0, 2, 2);
deviceD->brushes[i] = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
tool_tips);
deviceD->brushes[i] = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->brushes[i],
3, 4, i, i+1,
0, 0, 2, 2);
deviceD->patterns[i] = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
tool_tips);
deviceD->patterns[i] = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->patterns[i],
4, 5, i, i+1,
0, 0, 2, 2);
@ -954,13 +953,13 @@ device_status_update (guint32 deviceid)
if (device_info->brush)
{
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gtk_widget_show (deviceD->brushes[i]);
}
if (device_info->pattern)
{
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->patterns[i]),
device_info->pattern);
gtk_widget_show (deviceD->patterns[i]);
}
@ -973,3 +972,4 @@ device_status_update (guint32 deviceid)
pattern_area_update();
}
}

View file

@ -1,441 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpBrushPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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 "gimpbrushpreview.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "brush_scale.h"
#include "temp_buf.h"
/* the pixmap for the scale_indicator */
#define scale_indicator_width 7
#define scale_indicator_height 7
#define WHT {255,255,255}
#define BLK { 0, 0, 0}
static unsigned char scale_indicator_bits[7][7][3] =
{
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, BLK, BLK, BLK, BLK, BLK, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT }
};
#define BRUSH_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK)
enum {
CLICKED,
LAST_SIGNAL
};
static guint gimp_brush_preview_signals[LAST_SIGNAL] = { 0 };
static GtkPreviewClass *parent_class = NULL;
static gint gimp_brush_preview_button_press_event (GtkWidget *, GdkEventButton *);
static gint gimp_brush_preview_button_release_event (GtkWidget *, GdkEventButton *);
static void gimp_brush_preview_popup_open (GimpBrushPreview *, gint, gint);
static void gimp_brush_preview_popup_close (GimpBrushPreview *);
static void gimp_brush_preview_draw (GimpBrushPreview *);
static void
gimp_brush_preview_destroy (GtkObject *object)
{
GimpBrushPreview *gbp;
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (object));
gbp = GIMP_BRUSH_PREVIEW (object);
if (gbp->popup)
gtk_widget_destroy (gbp->popup);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
static void
gimp_brush_preview_class_init (GimpBrushPreviewClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_preview_get_type ());
gimp_brush_preview_signals[CLICKED] =
gtk_signal_new ("clicked",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpBrushPreviewClass, clicked),
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, gimp_brush_preview_signals,
LAST_SIGNAL);
class->clicked = NULL;
widget_class->button_press_event = gimp_brush_preview_button_press_event;
widget_class->button_release_event = gimp_brush_preview_button_release_event;
object_class->destroy = gimp_brush_preview_destroy;
}
static void
gimp_brush_preview_init (GimpBrushPreview *gbp)
{
gbp->brush = NULL;
gbp->width = 0;
gbp->height = 0;
gbp->tooltips = NULL;
gbp->popup = NULL;
gbp->popup_preview = NULL;
GTK_PREVIEW (gbp)->type = GTK_PREVIEW_COLOR;
GTK_PREVIEW (gbp)->bpp = 3;
GTK_PREVIEW (gbp)->dither = GDK_RGB_DITHER_NORMAL;
gtk_widget_set_events (GTK_WIDGET (gbp), BRUSH_PREVIEW_EVENT_MASK);
}
GtkType
gimp_brush_preview_get_type ()
{
static GtkType gbp_type = 0;
if (!gbp_type)
{
GtkTypeInfo gbp_info =
{
"GimpBrushPreview",
sizeof (GimpBrushPreview),
sizeof (GimpBrushPreviewClass),
(GtkClassInitFunc) gimp_brush_preview_class_init,
(GtkObjectInitFunc) gimp_brush_preview_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gbp_type = gtk_type_unique (gtk_preview_get_type (), &gbp_info);
}
return gbp_type;
}
GtkWidget*
gimp_brush_preview_new (gint width,
gint height)
{
GimpBrushPreview *gbp;
g_return_val_if_fail (width > 0 && height > 0, NULL);
gbp = gtk_type_new (gimp_brush_preview_get_type ());
gbp->width = width;
gbp->height = height;
gtk_preview_size (GTK_PREVIEW (gbp), width, height);
return GTK_WIDGET (gbp);
}
void
gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GIMP_IS_BRUSH (brush));
if (gbp->brush == brush)
return;
gbp->brush = brush;
gtk_signal_connect (GTK_OBJECT (gbp->brush), "destroy",
gtk_widget_destroyed, &gbp->brush);
gimp_brush_preview_draw (gbp);
if (gbp->tooltips)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
void
gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
gbp->tooltips = tooltips;
gtk_signal_connect (GTK_OBJECT (gbp->tooltips), "destroy",
gtk_widget_destroyed, &gbp->tooltips);
if (gbp->brush)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
static gint
gimp_brush_preview_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
{
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
gimp_brush_preview_popup_open (GIMP_BRUSH_PREVIEW (widget),
bevent->x, bevent->y);
}
return TRUE;
}
static gint
gimp_brush_preview_button_release_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
gimp_brush_preview_popup_close (GIMP_BRUSH_PREVIEW (widget));
return TRUE;
}
static void
gimp_brush_preview_popup_open (GimpBrushPreview *gbp,
gint x,
gint y)
{
gint x_org, y_org;
gint scr_w, scr_h;
guchar *mask, *buf, *b;
gint width, height;
guchar bg;
g_return_if_fail (gbp != NULL);
if (!gbp->brush)
return;
width = gbp->brush->mask->width;
height = gbp->brush->mask->height;
if (width <= gbp->width && height <= gbp->height)
return;
/* make sure the popup exists and is not visible */
if (gbp->popup == NULL)
{
GtkWidget *frame;
gbp->popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (gbp->popup), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (gbp->popup), "destroy",
gtk_widget_destroyed, &gbp->popup);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (gbp->popup), frame);
gtk_widget_show (frame);
gbp->popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_signal_connect (GTK_OBJECT (gbp->popup_preview), "destroy",
gtk_widget_destroyed, &gbp->popup_preview);
gtk_container_add (GTK_CONTAINER (frame), gbp->popup_preview);
gtk_widget_show (gbp->popup_preview);
}
else
{
gtk_widget_hide (gbp->popup);
}
/* decide where to put the popup */
gdk_window_get_origin (GTK_WIDGET (gbp)->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (width >> 1);
y = y_org + y - (height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + width > scr_w) ? scr_w - width : x;
y = (y + height > scr_h) ? scr_h - height : y;
gtk_preview_size (GTK_PREVIEW (gbp->popup_preview), width, height);
gtk_widget_popup (gbp->popup, x, y);
/* Draw the brush */
buf = g_new (guchar, 3 * width);
mask = temp_buf_data (gbp->brush->mask);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (gbp->brush)->pixmap_mask);
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
else
{
for (y = 0; y < height; y++)
{
b = buf;
/* Invert the mask for display. */
for (x = 0; x < width; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
g_free(buf);
gtk_widget_queue_draw (gbp->popup_preview);
}
static void
gimp_brush_preview_popup_close (GimpBrushPreview *gbp)
{
if (gbp->popup != NULL)
gtk_widget_hide (gbp->popup);
}
static void
gimp_brush_preview_draw (GimpBrushPreview *gbp)
{
gboolean scale = FALSE;
gint brush_width, brush_height;
gint offset_x, offset_y;
TempBuf *mask_buf, *pixmap_buf = NULL;
guchar *mask, *buf, *b;
guchar bg;
gint x, y;
g_return_if_fail (gbp != NULL && gbp->brush != NULL);
brush_width = gbp->brush->mask->width;
brush_height = gbp->brush->mask->height;
if (brush_width > gbp->width || brush_height > gbp->height)
{
gdouble ratio_x = (gdouble)brush_width / gbp->width;
gdouble ratio_y = (gdouble)brush_height / gbp->height;
brush_width = (gdouble)brush_width / MAX (ratio_x, ratio_y);
brush_height = (gdouble)brush_height / MAX (ratio_x, ratio_y);
mask_buf = brush_scale_mask (gbp->brush->mask, brush_width, brush_height);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
pixmap_buf = brush_scale_pixmap (GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask,
brush_width, brush_height);
}
scale = TRUE;
}
else
{
mask_buf = gbp->brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
pixmap_buf = GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask;
}
offset_x = (gbp->width - brush_width) >> 1;
offset_y = (gbp->height - brush_height) >> 1;
mask = temp_buf_data (mask_buf);
buf = g_new (guchar, 3 * gbp->width);
memset (buf, 255, 3 * gbp->width);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (pixmap_buf);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
else
{
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
if (scale)
{
offset_x = gbp->width - scale_indicator_width - 1;
offset_y = gbp->height - scale_indicator_height - 1;
for (y = 0; y < scale_indicator_height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), scale_indicator_bits[y][0],
offset_x, offset_y + y, scale_indicator_width);
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
temp_buf_free (pixmap_buf);
}
g_free(buf);
gtk_widget_queue_draw (GTK_WIDGET (gbp));
}

View file

@ -1,71 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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_BRUSH_PREVIEW_H__
#define __GIMP_BRUSH_PREVIEW_H_
#include <gtk/gtk.h>
#include "gimpbrush.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIMP_TYPE_BRUSH_PREVIEW (gimp_brush_preview_get_type ())
#define GIMP_BRUSH_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreview))
#define GIMP_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass))
#define GIMP_IS_BRUSH_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_BRUSH_PREVIEW))
#define GIMP_IS_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_PREVIEW))
typedef struct _GimpBrushPreview GimpBrushPreview;
typedef struct _GimpBrushPreviewClass GimpBrushPreviewClass;
struct _GimpBrushPreview
{
GtkPreview preview;
GimpBrush *brush;
gint width;
gint height;
GtkTooltips *tooltips;
GtkWidget *popup;
GtkWidget *popup_preview;
};
struct _GimpBrushPreviewClass
{
GtkPreviewClass parent_class;
void (* clicked) (GimpBrushPreview *gbp);
};
GtkType gimp_brush_preview_get_type (void);
GtkWidget* gimp_brush_preview_new (gint width,
gint height);
void gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush);
void gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMP_BRUSH_PREVIEW_H__ */

638
app/gimpcontextpreview.c Normal file
View file

@ -0,0 +1,638 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpContextPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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 "brush_scale.h"
#include "gimpbrush.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "gimpcontextpreview.h"
#include "interface.h" /* for tool_tips */
#include "patterns.h"
#include "temp_buf.h"
/* the pixmap for the scale_indicator */
#define scale_indicator_width 7
#define scale_indicator_height 7
#define WHT {255,255,255}
#define BLK { 0, 0, 0}
static unsigned char scale_indicator_bits[7][7][3] =
{
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, BLK, BLK, BLK, BLK, BLK, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT }
};
#define CONTEXT_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK)
static GtkWidget *gcp_popup = NULL;
static GtkWidget *gcp_popup_preview = NULL;
enum {
CLICKED,
LAST_SIGNAL
};
static guint gimp_context_preview_signals[LAST_SIGNAL] = { 0 };
static GtkPreviewClass *parent_class = NULL;
static gint gimp_context_preview_button_press_event (GtkWidget *,
GdkEventButton *);
static gint gimp_context_preview_button_release_event (GtkWidget *,
GdkEventButton *);
static void gimp_context_preview_popup_open (GimpContextPreview *,
gint, gint);
static void gimp_context_preview_popup_close ();
static gboolean gimp_context_preview_data_matches_type (GimpContextPreview *,
gpointer);
static void gimp_context_preview_draw_brush (GimpContextPreview *);
static void gimp_context_preview_draw_brush_popup (GimpContextPreview *);
static void gimp_context_preview_draw_pattern (GimpContextPreview *);
static void gimp_context_preview_draw_pattern_popup (GimpContextPreview *);
static void
gimp_context_preview_destroy (GtkObject *object)
{
g_return_if_fail (GIMP_IS_CONTEXT_PREVIEW (object));
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
static void
gimp_context_preview_class_init (GimpContextPreviewClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_preview_get_type ());
gimp_context_preview_signals[CLICKED] =
gtk_signal_new ("clicked",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpContextPreviewClass, clicked),
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, gimp_context_preview_signals,
LAST_SIGNAL);
class->clicked = NULL;
widget_class->button_press_event = gimp_context_preview_button_press_event;
widget_class->button_release_event = gimp_context_preview_button_release_event;
object_class->destroy = gimp_context_preview_destroy;
}
static void
gimp_context_preview_init (GimpContextPreview *gcp)
{
gcp->data = NULL;
gcp->type = GCP_LAST;
gcp->width = 0;
gcp->height = 0;
gcp->show_tooltips = FALSE;
GTK_PREVIEW (gcp)->type = GTK_PREVIEW_COLOR;
GTK_PREVIEW (gcp)->bpp = 3;
GTK_PREVIEW (gcp)->dither = GDK_RGB_DITHER_NORMAL;
gtk_widget_set_events (GTK_WIDGET (gcp), CONTEXT_PREVIEW_EVENT_MASK);
}
GtkType
gimp_context_preview_get_type ()
{
static GtkType gcp_type = 0;
if (!gcp_type)
{
GtkTypeInfo gcp_info =
{
"GimpContextPreview",
sizeof (GimpContextPreview),
sizeof (GimpContextPreviewClass),
(GtkClassInitFunc) gimp_context_preview_class_init,
(GtkObjectInitFunc) gimp_context_preview_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gcp_type = gtk_type_unique (gtk_preview_get_type (), &gcp_info);
}
return gcp_type;
}
GtkWidget*
gimp_context_preview_new (GimpContextPreviewType type,
gint width,
gint height,
gboolean show_tooltips)
{
GimpContextPreview *gcp;
g_return_val_if_fail (type >= 0 && type < GCP_LAST, NULL);
g_return_val_if_fail (width > 0 && height > 0, NULL);
gcp = gtk_type_new (gimp_context_preview_get_type ());
gcp->type = type;
gcp->width = width;
gcp->height = height;
gcp->show_tooltips = show_tooltips;
gtk_preview_size (GTK_PREVIEW (gcp), width, height);
return GTK_WIDGET (gcp);
}
void
gimp_context_preview_update (GimpContextPreview *gcp,
gpointer data)
{
g_return_if_fail (GIMP_IS_CONTEXT_PREVIEW (gcp));
g_return_if_fail (gimp_context_preview_data_matches_type (gcp, data));
gcp->data = data;
if (GTK_IS_OBJECT (gcp->data))
gtk_signal_connect (GTK_OBJECT (gcp->data), "destroy",
gtk_widget_destroyed, &gcp->data);
switch (gcp->type)
{
case GCP_BRUSH:
gimp_context_preview_draw_brush (gcp);
break;
case GCP_PATTERN:
gimp_context_preview_draw_pattern (gcp);
default:
break;
}
if (gcp->show_tooltips)
{
gchar *name = NULL;
switch (gcp->type)
{
case GCP_BRUSH:
{
GimpBrush *brush = GIMP_BRUSH (gcp->data);
name = brush->name;
}
break;
case GCP_PATTERN:
{
GPattern *pattern = (GPattern *)(gcp->data);
name = pattern->name;
}
break;
default:
break;
}
gtk_tooltips_set_tip (tool_tips, GTK_WIDGET (gcp), name, NULL);
}
}
static gint
gimp_context_preview_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
{
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
gimp_context_preview_popup_open (GIMP_CONTEXT_PREVIEW (widget),
bevent->x, bevent->y);
}
return TRUE;
}
static gint
gimp_context_preview_button_release_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
gimp_context_preview_popup_close ();
return TRUE;
}
static void
gimp_context_preview_popup_open (GimpContextPreview *gcp,
gint x,
gint y)
{
gint x_org, y_org;
gint scr_w, scr_h;
gint width, height;
g_return_if_fail (gcp != NULL);
if (!gcp->data)
return;
switch (gcp->type)
{
case GCP_BRUSH:
{
GimpBrush *brush = GIMP_BRUSH (gcp->data);
width = brush->mask->width;
height = brush->mask->height;
}
break;
case GCP_PATTERN:
{
GPattern *pattern = (GPattern*)gcp->data;
width = pattern->mask->width;
height = pattern->mask->height;
}
break;
default:
return;
}
if (width <= gcp->width && height <= gcp->height)
return;
/* make sure the popup exists and is not visible */
if (gcp_popup == NULL)
{
GtkWidget *frame;
gcp_popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (gcp_popup), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (gcp_popup), "destroy",
gtk_widget_destroyed, &gcp_popup);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (gcp_popup), frame);
gtk_widget_show (frame);
gcp_popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_signal_connect (GTK_OBJECT (gcp_popup_preview), "destroy",
gtk_widget_destroyed, &gcp_popup_preview);
gtk_container_add (GTK_CONTAINER (frame), gcp_popup_preview);
gtk_widget_show (gcp_popup_preview);
}
else
{
gtk_widget_hide (gcp_popup);
}
/* decide where to put the popup */
gdk_window_get_origin (GTK_WIDGET (gcp)->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (width >> 1);
y = y_org + y - (height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + width > scr_w) ? scr_w - width : x;
y = (y + height > scr_h) ? scr_h - height : y;
gtk_preview_size (GTK_PREVIEW (gcp_popup_preview), width, height);
gtk_widget_popup (gcp_popup, x, y);
switch (gcp->type)
{
case GCP_BRUSH:
gimp_context_preview_draw_brush_popup (gcp);
break;
case GCP_PATTERN:
gimp_context_preview_draw_pattern_popup (gcp);
break;
default:
break;
}
gtk_widget_queue_draw (gcp_popup_preview);
}
static void
gimp_context_preview_popup_close ()
{
if (gcp_popup != NULL)
gtk_widget_hide (gcp_popup);
}
static gboolean
gimp_context_preview_data_matches_type (GimpContextPreview *gcp,
gpointer data)
{
gboolean match = FALSE;
g_return_val_if_fail (GIMP_IS_CONTEXT_PREVIEW (gcp), FALSE);
switch (gcp->type)
{
case GCP_BRUSH:
match = GIMP_IS_BRUSH (data);
break;
case GCP_PATTERN:
match = data != NULL; /* would be nice if pattern was a real gtk_object */
break;
default:
break;
}
return (match);
}
/* brush draw functions */
static void
gimp_context_preview_draw_brush_popup (GimpContextPreview *gcp)
{
GimpBrush *brush;
guchar *mask, *buf, *b;
guchar bg;
gint width, height;
gint x, y;
g_return_if_fail (gcp != NULL && GIMP_IS_BRUSH (gcp->data));
brush = GIMP_BRUSH (gcp->data);
width = brush->mask->width;
height = brush->mask->height;
buf = g_new (guchar, 3 * width);
mask = temp_buf_data (brush->mask);
if (GIMP_IS_BRUSH_PIXMAP (brush))
{
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (brush)->pixmap_mask);
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), buf, 0, y, width);
}
}
else
{
for (y = 0; y < height; y++)
{
b = buf;
/* Invert the mask for display. */
for (x = 0; x < width; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), buf, 0, y, width);
}
}
g_free(buf);
}
static void
gimp_context_preview_draw_brush (GimpContextPreview *gcp)
{
GimpBrush *brush;
gboolean scale = FALSE;
gint brush_width, brush_height;
gint offset_x, offset_y;
TempBuf *mask_buf, *pixmap_buf = NULL;
guchar *mask, *buf, *b;
guchar bg;
gint x, y;
g_return_if_fail (gcp != NULL && GIMP_IS_BRUSH (gcp->data));
brush = GIMP_BRUSH (gcp->data);
brush_width = brush->mask->width;
brush_height = brush->mask->height;
if (brush_width > gcp->width || brush_height > gcp->height)
{
gdouble ratio_x = (gdouble)brush_width / gcp->width;
gdouble ratio_y = (gdouble)brush_height / gcp->height;
brush_width = (gdouble)brush_width / MAX (ratio_x, ratio_y);
brush_height = (gdouble)brush_height / MAX (ratio_x, ratio_y);
mask_buf = brush_scale_mask (brush->mask, brush_width, brush_height);
if (GIMP_IS_BRUSH_PIXMAP (brush))
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
pixmap_buf = brush_scale_pixmap (GIMP_BRUSH_PIXMAP(brush)->pixmap_mask,
brush_width, brush_height);
}
scale = TRUE;
}
else
{
mask_buf = brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (brush))
pixmap_buf = GIMP_BRUSH_PIXMAP(brush)->pixmap_mask;
}
offset_x = (gcp->width - brush_width) >> 1;
offset_y = (gcp->height - brush_height) >> 1;
mask = temp_buf_data (mask_buf);
buf = g_new (guchar, 3 * gcp->width);
memset (buf, 255, 3 * gcp->width);
if (GIMP_IS_BRUSH_PIXMAP (brush))
{
guchar *pixmap = temp_buf_data (pixmap_buf);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
}
memset (buf, 255, 3 * gcp->width);
for (y = brush_height + offset_y; y < gcp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
}
else
{
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
}
memset (buf, 255, 3 * gcp->width);
for (y = brush_height + offset_y; y < gcp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
}
if (scale)
{
offset_x = gcp->width - scale_indicator_width - 1;
offset_y = gcp->height - scale_indicator_height - 1;
for (y = 0; y < scale_indicator_height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gcp), scale_indicator_bits[y][0],
offset_x, offset_y + y, scale_indicator_width);
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (brush))
temp_buf_free (pixmap_buf);
}
g_free (buf);
gtk_widget_queue_draw (GTK_WIDGET (gcp));
}
/* pattern draw functions */
static void
gimp_context_preview_draw_pattern_popup (GimpContextPreview *gcp)
{
GPattern *pattern;
guchar *mask;
gint width, height;
gint x, y;
g_return_if_fail (gcp != NULL && gcp->data != NULL);
pattern = (GPattern*)(gcp->data);
width = pattern->mask->width;
height = pattern->mask->height;
mask = temp_buf_data (pattern->mask);
if (pattern->mask->bytes == 1)
{
guchar *buf = g_new (guchar, 3 * width);
guchar *b;
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
memset (b, *mask++, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), buf, 0, y, width);
}
g_free(buf);
}
else
{
for (y = 0; y < height; y++)
{
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), mask, 0, y, width);
mask += 3 * width;
}
}
}
static void
gimp_context_preview_draw_pattern (GimpContextPreview *gcp)
{
GPattern *pattern;
gint pattern_width, pattern_height;
gint width, height;
gint offset_x, offset_y;
guchar *mask, *buf, *b;
gint x, y;
g_return_if_fail (gcp != NULL && gcp->data != NULL);
pattern = (GPattern*)(gcp->data);
pattern_width = pattern->mask->width;
pattern_height = pattern->mask->height;
width = (pattern_width > gcp->width) ? gcp->width : pattern_width;
height = (pattern_height > gcp->height) ? gcp->height : pattern_height;
offset_x = (gcp->width - width) >> 1;
offset_y = (gcp->height - height) >> 1;
mask = temp_buf_data (pattern->mask);
buf = g_new (guchar, 3 * gcp->width);
memset (buf, 255, 3 * gcp->width);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
if (pattern->mask->bytes == 1)
{
for (y = offset_y; y < height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < width ; x++)
{
memset (b, mask[x], 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
mask += pattern_width;
}
}
else
{
for (y = offset_y; y < height + offset_y; y++)
{
b = buf + 3 * offset_x;
memcpy (b, mask, 3 * width);
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
mask += 3 * pattern_width;
}
}
memset (buf, 255, 3 * gcp->width);
for (y = height + offset_y; y < gcp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
g_free(buf);
}

77
app/gimpcontextpreview.h Normal file
View file

@ -0,0 +1,77 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpContextPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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_CONTEXT_PREVIEW_H__
#define __GIMP_CONTEXT_PREVIEW_H_
#include <gtk/gtk.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIMP_TYPE_CONTEXT_PREVIEW (gimp_context_preview_get_type ())
#define GIMP_CONTEXT_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_CONTEXT_PREVIEW, GimpContextPreview))
#define GIMP_CONTEXT_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CONTEXT_PREVIEW, GimpContextPreviewClass))
#define GIMP_IS_CONTEXT_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_CONTEXT_PREVIEW))
#define GIMP_IS_CONTEXT_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CONTEXT_PREVIEW))
typedef struct _GimpContextPreview GimpContextPreview;
typedef struct _GimpContextPreviewClass GimpContextPreviewClass;
typedef enum
{
GCP_BRUSH = 0,
GCP_PATTERN,
GCP_LAST
} GimpContextPreviewType;
struct _GimpContextPreview
{
GtkPreview preview;
gpointer data;
GimpContextPreviewType type;
gint width;
gint height;
gboolean show_tooltips;
};
struct _GimpContextPreviewClass
{
GtkPreviewClass parent_class;
void (* clicked) (GimpContextPreview *gbp);
};
GtkType gimp_context_preview_get_type (void);
GtkWidget* gimp_context_preview_new (GimpContextPreviewType type,
gint width,
gint height,
gboolean show_tooltips);
void gimp_context_preview_update (GimpContextPreview *gcp,
gpointer data);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMP_CONTEXT_PREVIEW_H__ */

View file

@ -1,357 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpPatternPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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 "gimppatternpreview.h"
#define PATTERN_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK)
enum {
CLICKED,
LAST_SIGNAL
};
static guint gimp_pattern_preview_signals[LAST_SIGNAL] = { 0 };
static GtkPreviewClass *parent_class = NULL;
static gint gimp_pattern_preview_button_press_event (GtkWidget *, GdkEventButton *);
static gint gimp_pattern_preview_button_release_event (GtkWidget *, GdkEventButton *);
static void gimp_pattern_preview_popup_open (GimpPatternPreview *, gint, gint);
static void gimp_pattern_preview_popup_close (GimpPatternPreview *);
static void gimp_pattern_preview_draw (GimpPatternPreview *);
static void
gimp_pattern_preview_destroy (GtkObject *object)
{
GimpPatternPreview *gpp;
g_return_if_fail (GIMP_IS_PATTERN_PREVIEW (object));
gpp = GIMP_PATTERN_PREVIEW (object);
if (gpp->popup)
gtk_widget_destroy (gpp->popup);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
static void
gimp_pattern_preview_class_init (GimpPatternPreviewClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_preview_get_type ());
gimp_pattern_preview_signals[CLICKED] =
gtk_signal_new ("clicked",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpPatternPreviewClass, clicked),
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, gimp_pattern_preview_signals,
LAST_SIGNAL);
class->clicked = NULL;
widget_class->button_press_event = gimp_pattern_preview_button_press_event;
widget_class->button_release_event = gimp_pattern_preview_button_release_event;
object_class->destroy = gimp_pattern_preview_destroy;
}
static void
gimp_pattern_preview_init (GimpPatternPreview *gpp)
{
gpp->pattern = NULL;
gpp->width = 0;
gpp->height = 0;
gpp->tooltips = NULL;
gpp->popup = NULL;
gpp->popup_preview = NULL;
GTK_PREVIEW (gpp)->type = GTK_PREVIEW_COLOR;
GTK_PREVIEW (gpp)->bpp = 3;
GTK_PREVIEW (gpp)->dither = GDK_RGB_DITHER_NORMAL;
gtk_widget_set_events (GTK_WIDGET (gpp), PATTERN_PREVIEW_EVENT_MASK);
}
GtkType
gimp_pattern_preview_get_type ()
{
static GtkType gpp_type = 0;
if (!gpp_type)
{
GtkTypeInfo gpp_info =
{
"GimpPatternPreview",
sizeof (GimpPatternPreview),
sizeof (GimpPatternPreviewClass),
(GtkClassInitFunc) gimp_pattern_preview_class_init,
(GtkObjectInitFunc) gimp_pattern_preview_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gpp_type = gtk_type_unique (gtk_preview_get_type (), &gpp_info);
}
return gpp_type;
}
GtkWidget*
gimp_pattern_preview_new (gint width,
gint height)
{
GimpPatternPreview *gpp;
g_return_val_if_fail (width > 0 && height > 0, NULL);
gpp = gtk_type_new (gimp_pattern_preview_get_type ());
gpp->width = width;
gpp->height = height;
gtk_preview_size (GTK_PREVIEW (gpp), width, height);
return GTK_WIDGET (gpp);
}
void
gimp_pattern_preview_update (GimpPatternPreview *gpp,
GPattern *pattern)
{
g_return_if_fail (GIMP_IS_PATTERN_PREVIEW (gpp));
g_return_if_fail (pattern != NULL);
if (gpp->pattern == pattern)
return;
gpp->pattern = pattern;
gimp_pattern_preview_draw (gpp);
if (gpp->tooltips)
gtk_tooltips_set_tip (gpp->tooltips, GTK_WIDGET (gpp), gpp->pattern->name, NULL);
}
void
gimp_pattern_preview_set_tooltips (GimpPatternPreview *gpp,
GtkTooltips *tooltips)
{
g_return_if_fail (GIMP_IS_PATTERN_PREVIEW (gpp));
g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
gpp->tooltips = tooltips;
gtk_signal_connect (GTK_OBJECT (gpp->tooltips), "destroy",
gtk_widget_destroyed, &gpp->tooltips);
if (gpp->pattern)
gtk_tooltips_set_tip (gpp->tooltips, GTK_WIDGET (gpp), gpp->pattern->name, NULL);
}
static gint
gimp_pattern_preview_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
{
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
gimp_pattern_preview_popup_open (GIMP_PATTERN_PREVIEW (widget),
bevent->x, bevent->y);
}
return TRUE;
}
static gint
gimp_pattern_preview_button_release_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
gimp_pattern_preview_popup_close (GIMP_PATTERN_PREVIEW (widget));
return TRUE;
}
static void
gimp_pattern_preview_popup_open (GimpPatternPreview *gpp,
gint x,
gint y)
{
gint x_org, y_org;
gint scr_w, scr_h;
guchar *mask;
gint width, height;
g_return_if_fail (gpp != NULL);
if (!gpp->pattern)
return;
width = gpp->pattern->mask->width;
height = gpp->pattern->mask->height;
if (width <= gpp->width && height <= gpp->height)
return;
/* make sure the popup exists and is not visible */
if (gpp->popup == NULL)
{
GtkWidget *frame;
gpp->popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (gpp->popup), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (gpp->popup), "destroy",
gtk_widget_destroyed, &gpp->popup);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (gpp->popup), frame);
gtk_widget_show (frame);
gpp->popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_signal_connect (GTK_OBJECT (gpp->popup_preview), "destroy",
gtk_widget_destroyed, &gpp->popup_preview);
gtk_container_add (GTK_CONTAINER (frame), gpp->popup_preview);
gtk_widget_show (gpp->popup_preview);
}
else
{
gtk_widget_hide (gpp->popup);
}
/* decide where to put the popup */
gdk_window_get_origin (GTK_WIDGET (gpp)->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (width >> 1);
y = y_org + y - (height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + width > scr_w) ? scr_w - width : x;
y = (y + height > scr_h) ? scr_h - height : y;
gtk_preview_size (GTK_PREVIEW (gpp->popup_preview), width, height);
gtk_widget_popup (gpp->popup, x, y);
/* Draw the pattern */
mask = temp_buf_data (gpp->pattern->mask);
if (gpp->pattern->mask->bytes == 1)
{
guchar *buf = g_new (guchar, 3 * width);
guchar *b;
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
memset (b, *mask++, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gpp->popup_preview), buf, 0, y, width);
}
g_free(buf);
}
else
{
for (y = 0; y < height; y++)
{
gtk_preview_draw_row (GTK_PREVIEW (gpp->popup_preview), mask, 0, y, width);
mask += 3 * width;
}
}
gtk_widget_queue_draw (gpp->popup_preview);
}
static void
gimp_pattern_preview_popup_close (GimpPatternPreview *gpp)
{
if (gpp->popup != NULL)
gtk_widget_hide (gpp->popup);
}
static void
gimp_pattern_preview_draw (GimpPatternPreview *gpp)
{
gint pattern_width, pattern_height;
gint width, height;
gint offset_x, offset_y;
guchar *mask, *buf, *b;
gint x, y;
g_return_if_fail (gpp != NULL && gpp->pattern != NULL);
pattern_width = gpp->pattern->mask->width;
pattern_height = gpp->pattern->mask->height;
width = (pattern_width > gpp->width) ? gpp->width : pattern_width;
height = (pattern_height > gpp->height) ? gpp->height: pattern_height;
offset_x = (gpp->width - width) >> 1;
offset_y = (gpp->height - height) >> 1;
mask = temp_buf_data (gpp->pattern->mask);
buf = g_new (guchar, 3 * gpp->width);
memset (buf, 255, 3 * gpp->width);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
if (gpp->pattern->mask->bytes == 1)
{
for (y = offset_y; y < height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < width ; x++)
{
memset (b, mask[x], 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
mask += pattern_width;
}
}
else
{
for (y = offset_y; y < height + offset_y; y++)
{
b = buf + 3 * offset_x;
memcpy (b, mask, 3 * width);
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
mask += 3 * pattern_width;
}
}
memset (buf, 255, 3 * gpp->width);
for (y = height + offset_y; y < gpp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
g_free(buf);
gtk_widget_queue_draw (GTK_WIDGET (gpp));
}

View file

@ -1,71 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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_PATTERN_PREVIEW_H__
#define __GIMP_PATTERN_PREVIEW_H_
#include <gtk/gtk.h>
#include "patterns.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIMP_TYPE_PATTERN_PREVIEW (gimp_pattern_preview_get_type ())
#define GIMP_PATTERN_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_PATTERN_PREVIEW, GimpPatternPreview))
#define GIMP_PATTERN_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PATTERN_PREVIEW, GimpPatternPreviewClass))
#define GIMP_IS_PATTERN_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_PATTERN_PREVIEW))
#define GIMP_IS_PATTERN_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PATTERN_PREVIEW))
typedef struct _GimpPatternPreview GimpPatternPreview;
typedef struct _GimpPatternPreviewClass GimpPatternPreviewClass;
struct _GimpPatternPreview
{
GtkPreview preview;
GPattern *pattern;
gint width;
gint height;
GtkTooltips *tooltips;
GtkWidget *popup;
GtkWidget *popup_preview;
};
struct _GimpPatternPreviewClass
{
GtkPreviewClass parent_class;
void (* clicked) (GimpPatternPreview *gpp);
};
GtkType gimp_pattern_preview_get_type (void);
GtkWidget* gimp_pattern_preview_new (gint width,
gint height);
void gimp_pattern_preview_update (GimpPatternPreview *gpp,
GPattern *pattern);
void gimp_pattern_preview_set_tooltips (GimpPatternPreview *gpp,
GtkTooltips *tooltips);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMP_PATTERN_PREVIEW_H__ */

View file

@ -23,8 +23,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -749,17 +748,17 @@ create_device_status (void)
2, 3, i, i+1,
0, 0, 2, 2);
deviceD->brushes[i] = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
tool_tips);
deviceD->brushes[i] = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->brushes[i],
3, 4, i, i+1,
0, 0, 2, 2);
deviceD->patterns[i] = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
tool_tips);
deviceD->patterns[i] = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->patterns[i],
4, 5, i, i+1,
0, 0, 2, 2);
@ -954,13 +953,13 @@ device_status_update (guint32 deviceid)
if (device_info->brush)
{
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gtk_widget_show (deviceD->brushes[i]);
}
if (device_info->pattern)
{
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->patterns[i]),
device_info->pattern);
gtk_widget_show (deviceD->patterns[i]);
}
@ -973,3 +972,4 @@ device_status_update (guint32 deviceid)
pattern_area_update();
}
}

View file

@ -19,11 +19,11 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "indicator_area.h"
#include "interface.h"
#include "gimpbrushlist.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "indicator_area.h"
#include "interface.h" /* for tool_tips */
#include "libgimp/gimpintl.h"
#define CELL_SIZE 23 /* The size of the previews */
#define CELL_PADDING 2 /* How much between brush and pattern cells */
@ -49,17 +49,17 @@ brush_area_update ()
brush = get_active_brush();
if (!brush)
{
g_warning("No gimp brush found\n");
g_warning ("No gimp brush found\n");
return;
}
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (brush_preview), brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (brush_preview), brush);
}
static gint
brush_preview_clicked (GtkWidget *widget,
gpointer data)
{
create_brush_dialog();
create_brush_dialog ();
return TRUE;
}
@ -74,10 +74,10 @@ pattern_area_update ()
if (!pattern)
{
g_warning("No gimp pattern found\n");
g_warning ("No gimp pattern found\n");
return;
}
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (pattern_preview), pattern);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (pattern_preview), pattern);
}
static gint
@ -94,15 +94,23 @@ indicator_area_create (int width,
{
indicator_table = gtk_table_new (1, 3, FALSE);
brush_preview = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (brush_preview), tool_tips);
brush_preview = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
FALSE);
gtk_tooltips_set_tip (tool_tips, brush_preview,
_("The active brush.\nClick to open the Brushes Dialog."),
NULL);
gtk_signal_connect (GTK_OBJECT (brush_preview), "clicked",
(GtkSignalFunc) brush_preview_clicked, NULL);
gtk_table_attach_defaults (GTK_TABLE(indicator_table), brush_preview,
0, 1, 0, 1);
pattern_preview = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (pattern_preview), tool_tips);
pattern_preview = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
FALSE);
gtk_tooltips_set_tip (tool_tips, pattern_preview,
_("The active pattern.\nClick to open the Patterns Dialog."),
NULL);
gtk_signal_connect (GTK_OBJECT (pattern_preview), "clicked",
(GtkSignalFunc) pattern_preview_clicked, NULL);
gtk_table_attach_defaults (GTK_TABLE(indicator_table), pattern_preview,

View file

@ -23,8 +23,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -749,17 +748,17 @@ create_device_status (void)
2, 3, i, i+1,
0, 0, 2, 2);
deviceD->brushes[i] = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
tool_tips);
deviceD->brushes[i] = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->brushes[i],
3, 4, i, i+1,
0, 0, 2, 2);
deviceD->patterns[i] = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
tool_tips);
deviceD->patterns[i] = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->patterns[i],
4, 5, i, i+1,
0, 0, 2, 2);
@ -954,13 +953,13 @@ device_status_update (guint32 deviceid)
if (device_info->brush)
{
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gtk_widget_show (deviceD->brushes[i]);
}
if (device_info->pattern)
{
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->patterns[i]),
device_info->pattern);
gtk_widget_show (deviceD->patterns[i]);
}
@ -973,3 +972,4 @@ device_status_update (guint32 deviceid)
pattern_area_update();
}
}

View file

@ -19,11 +19,11 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "indicator_area.h"
#include "interface.h"
#include "gimpbrushlist.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "indicator_area.h"
#include "interface.h" /* for tool_tips */
#include "libgimp/gimpintl.h"
#define CELL_SIZE 23 /* The size of the previews */
#define CELL_PADDING 2 /* How much between brush and pattern cells */
@ -49,17 +49,17 @@ brush_area_update ()
brush = get_active_brush();
if (!brush)
{
g_warning("No gimp brush found\n");
g_warning ("No gimp brush found\n");
return;
}
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (brush_preview), brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (brush_preview), brush);
}
static gint
brush_preview_clicked (GtkWidget *widget,
gpointer data)
{
create_brush_dialog();
create_brush_dialog ();
return TRUE;
}
@ -74,10 +74,10 @@ pattern_area_update ()
if (!pattern)
{
g_warning("No gimp pattern found\n");
g_warning ("No gimp pattern found\n");
return;
}
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (pattern_preview), pattern);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (pattern_preview), pattern);
}
static gint
@ -94,15 +94,23 @@ indicator_area_create (int width,
{
indicator_table = gtk_table_new (1, 3, FALSE);
brush_preview = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (brush_preview), tool_tips);
brush_preview = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
FALSE);
gtk_tooltips_set_tip (tool_tips, brush_preview,
_("The active brush.\nClick to open the Brushes Dialog."),
NULL);
gtk_signal_connect (GTK_OBJECT (brush_preview), "clicked",
(GtkSignalFunc) brush_preview_clicked, NULL);
gtk_table_attach_defaults (GTK_TABLE(indicator_table), brush_preview,
0, 1, 0, 1);
pattern_preview = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (pattern_preview), tool_tips);
pattern_preview = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
FALSE);
gtk_tooltips_set_tip (tool_tips, pattern_preview,
_("The active pattern.\nClick to open the Patterns Dialog."),
NULL);
gtk_signal_connect (GTK_OBJECT (pattern_preview), "clicked",
(GtkSignalFunc) pattern_preview_clicked, NULL);
gtk_table_attach_defaults (GTK_TABLE(indicator_table), pattern_preview,

View file

@ -1,441 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpBrushPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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 "gimpbrushpreview.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "brush_scale.h"
#include "temp_buf.h"
/* the pixmap for the scale_indicator */
#define scale_indicator_width 7
#define scale_indicator_height 7
#define WHT {255,255,255}
#define BLK { 0, 0, 0}
static unsigned char scale_indicator_bits[7][7][3] =
{
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, BLK, BLK, BLK, BLK, BLK, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT }
};
#define BRUSH_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK)
enum {
CLICKED,
LAST_SIGNAL
};
static guint gimp_brush_preview_signals[LAST_SIGNAL] = { 0 };
static GtkPreviewClass *parent_class = NULL;
static gint gimp_brush_preview_button_press_event (GtkWidget *, GdkEventButton *);
static gint gimp_brush_preview_button_release_event (GtkWidget *, GdkEventButton *);
static void gimp_brush_preview_popup_open (GimpBrushPreview *, gint, gint);
static void gimp_brush_preview_popup_close (GimpBrushPreview *);
static void gimp_brush_preview_draw (GimpBrushPreview *);
static void
gimp_brush_preview_destroy (GtkObject *object)
{
GimpBrushPreview *gbp;
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (object));
gbp = GIMP_BRUSH_PREVIEW (object);
if (gbp->popup)
gtk_widget_destroy (gbp->popup);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
static void
gimp_brush_preview_class_init (GimpBrushPreviewClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_preview_get_type ());
gimp_brush_preview_signals[CLICKED] =
gtk_signal_new ("clicked",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpBrushPreviewClass, clicked),
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, gimp_brush_preview_signals,
LAST_SIGNAL);
class->clicked = NULL;
widget_class->button_press_event = gimp_brush_preview_button_press_event;
widget_class->button_release_event = gimp_brush_preview_button_release_event;
object_class->destroy = gimp_brush_preview_destroy;
}
static void
gimp_brush_preview_init (GimpBrushPreview *gbp)
{
gbp->brush = NULL;
gbp->width = 0;
gbp->height = 0;
gbp->tooltips = NULL;
gbp->popup = NULL;
gbp->popup_preview = NULL;
GTK_PREVIEW (gbp)->type = GTK_PREVIEW_COLOR;
GTK_PREVIEW (gbp)->bpp = 3;
GTK_PREVIEW (gbp)->dither = GDK_RGB_DITHER_NORMAL;
gtk_widget_set_events (GTK_WIDGET (gbp), BRUSH_PREVIEW_EVENT_MASK);
}
GtkType
gimp_brush_preview_get_type ()
{
static GtkType gbp_type = 0;
if (!gbp_type)
{
GtkTypeInfo gbp_info =
{
"GimpBrushPreview",
sizeof (GimpBrushPreview),
sizeof (GimpBrushPreviewClass),
(GtkClassInitFunc) gimp_brush_preview_class_init,
(GtkObjectInitFunc) gimp_brush_preview_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gbp_type = gtk_type_unique (gtk_preview_get_type (), &gbp_info);
}
return gbp_type;
}
GtkWidget*
gimp_brush_preview_new (gint width,
gint height)
{
GimpBrushPreview *gbp;
g_return_val_if_fail (width > 0 && height > 0, NULL);
gbp = gtk_type_new (gimp_brush_preview_get_type ());
gbp->width = width;
gbp->height = height;
gtk_preview_size (GTK_PREVIEW (gbp), width, height);
return GTK_WIDGET (gbp);
}
void
gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GIMP_IS_BRUSH (brush));
if (gbp->brush == brush)
return;
gbp->brush = brush;
gtk_signal_connect (GTK_OBJECT (gbp->brush), "destroy",
gtk_widget_destroyed, &gbp->brush);
gimp_brush_preview_draw (gbp);
if (gbp->tooltips)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
void
gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
gbp->tooltips = tooltips;
gtk_signal_connect (GTK_OBJECT (gbp->tooltips), "destroy",
gtk_widget_destroyed, &gbp->tooltips);
if (gbp->brush)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
static gint
gimp_brush_preview_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
{
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
gimp_brush_preview_popup_open (GIMP_BRUSH_PREVIEW (widget),
bevent->x, bevent->y);
}
return TRUE;
}
static gint
gimp_brush_preview_button_release_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
gimp_brush_preview_popup_close (GIMP_BRUSH_PREVIEW (widget));
return TRUE;
}
static void
gimp_brush_preview_popup_open (GimpBrushPreview *gbp,
gint x,
gint y)
{
gint x_org, y_org;
gint scr_w, scr_h;
guchar *mask, *buf, *b;
gint width, height;
guchar bg;
g_return_if_fail (gbp != NULL);
if (!gbp->brush)
return;
width = gbp->brush->mask->width;
height = gbp->brush->mask->height;
if (width <= gbp->width && height <= gbp->height)
return;
/* make sure the popup exists and is not visible */
if (gbp->popup == NULL)
{
GtkWidget *frame;
gbp->popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (gbp->popup), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (gbp->popup), "destroy",
gtk_widget_destroyed, &gbp->popup);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (gbp->popup), frame);
gtk_widget_show (frame);
gbp->popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_signal_connect (GTK_OBJECT (gbp->popup_preview), "destroy",
gtk_widget_destroyed, &gbp->popup_preview);
gtk_container_add (GTK_CONTAINER (frame), gbp->popup_preview);
gtk_widget_show (gbp->popup_preview);
}
else
{
gtk_widget_hide (gbp->popup);
}
/* decide where to put the popup */
gdk_window_get_origin (GTK_WIDGET (gbp)->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (width >> 1);
y = y_org + y - (height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + width > scr_w) ? scr_w - width : x;
y = (y + height > scr_h) ? scr_h - height : y;
gtk_preview_size (GTK_PREVIEW (gbp->popup_preview), width, height);
gtk_widget_popup (gbp->popup, x, y);
/* Draw the brush */
buf = g_new (guchar, 3 * width);
mask = temp_buf_data (gbp->brush->mask);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (gbp->brush)->pixmap_mask);
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
else
{
for (y = 0; y < height; y++)
{
b = buf;
/* Invert the mask for display. */
for (x = 0; x < width; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
g_free(buf);
gtk_widget_queue_draw (gbp->popup_preview);
}
static void
gimp_brush_preview_popup_close (GimpBrushPreview *gbp)
{
if (gbp->popup != NULL)
gtk_widget_hide (gbp->popup);
}
static void
gimp_brush_preview_draw (GimpBrushPreview *gbp)
{
gboolean scale = FALSE;
gint brush_width, brush_height;
gint offset_x, offset_y;
TempBuf *mask_buf, *pixmap_buf = NULL;
guchar *mask, *buf, *b;
guchar bg;
gint x, y;
g_return_if_fail (gbp != NULL && gbp->brush != NULL);
brush_width = gbp->brush->mask->width;
brush_height = gbp->brush->mask->height;
if (brush_width > gbp->width || brush_height > gbp->height)
{
gdouble ratio_x = (gdouble)brush_width / gbp->width;
gdouble ratio_y = (gdouble)brush_height / gbp->height;
brush_width = (gdouble)brush_width / MAX (ratio_x, ratio_y);
brush_height = (gdouble)brush_height / MAX (ratio_x, ratio_y);
mask_buf = brush_scale_mask (gbp->brush->mask, brush_width, brush_height);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
pixmap_buf = brush_scale_pixmap (GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask,
brush_width, brush_height);
}
scale = TRUE;
}
else
{
mask_buf = gbp->brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
pixmap_buf = GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask;
}
offset_x = (gbp->width - brush_width) >> 1;
offset_y = (gbp->height - brush_height) >> 1;
mask = temp_buf_data (mask_buf);
buf = g_new (guchar, 3 * gbp->width);
memset (buf, 255, 3 * gbp->width);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (pixmap_buf);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
else
{
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
if (scale)
{
offset_x = gbp->width - scale_indicator_width - 1;
offset_y = gbp->height - scale_indicator_height - 1;
for (y = 0; y < scale_indicator_height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), scale_indicator_bits[y][0],
offset_x, offset_y + y, scale_indicator_width);
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
temp_buf_free (pixmap_buf);
}
g_free(buf);
gtk_widget_queue_draw (GTK_WIDGET (gbp));
}

View file

@ -1,71 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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_BRUSH_PREVIEW_H__
#define __GIMP_BRUSH_PREVIEW_H_
#include <gtk/gtk.h>
#include "gimpbrush.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIMP_TYPE_BRUSH_PREVIEW (gimp_brush_preview_get_type ())
#define GIMP_BRUSH_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreview))
#define GIMP_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass))
#define GIMP_IS_BRUSH_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_BRUSH_PREVIEW))
#define GIMP_IS_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_PREVIEW))
typedef struct _GimpBrushPreview GimpBrushPreview;
typedef struct _GimpBrushPreviewClass GimpBrushPreviewClass;
struct _GimpBrushPreview
{
GtkPreview preview;
GimpBrush *brush;
gint width;
gint height;
GtkTooltips *tooltips;
GtkWidget *popup;
GtkWidget *popup_preview;
};
struct _GimpBrushPreviewClass
{
GtkPreviewClass parent_class;
void (* clicked) (GimpBrushPreview *gbp);
};
GtkType gimp_brush_preview_get_type (void);
GtkWidget* gimp_brush_preview_new (gint width,
gint height);
void gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush);
void gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMP_BRUSH_PREVIEW_H__ */

View file

@ -23,8 +23,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -749,17 +748,17 @@ create_device_status (void)
2, 3, i, i+1,
0, 0, 2, 2);
deviceD->brushes[i] = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
tool_tips);
deviceD->brushes[i] = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->brushes[i],
3, 4, i, i+1,
0, 0, 2, 2);
deviceD->patterns[i] = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
tool_tips);
deviceD->patterns[i] = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->patterns[i],
4, 5, i, i+1,
0, 0, 2, 2);
@ -954,13 +953,13 @@ device_status_update (guint32 deviceid)
if (device_info->brush)
{
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gtk_widget_show (deviceD->brushes[i]);
}
if (device_info->pattern)
{
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->patterns[i]),
device_info->pattern);
gtk_widget_show (deviceD->patterns[i]);
}
@ -973,3 +972,4 @@ device_status_update (guint32 deviceid)
pattern_area_update();
}
}

View file

@ -23,8 +23,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -749,17 +748,17 @@ create_device_status (void)
2, 3, i, i+1,
0, 0, 2, 2);
deviceD->brushes[i] = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
tool_tips);
deviceD->brushes[i] = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->brushes[i],
3, 4, i, i+1,
0, 0, 2, 2);
deviceD->patterns[i] = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
tool_tips);
deviceD->patterns[i] = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
TRUE);
gtk_table_attach (GTK_TABLE(deviceD->table), deviceD->patterns[i],
4, 5, i, i+1,
0, 0, 2, 2);
@ -954,13 +953,13 @@ device_status_update (guint32 deviceid)
if (device_info->brush)
{
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->brushes[i]),
device_info->brush);
gtk_widget_show (deviceD->brushes[i]);
}
if (device_info->pattern)
{
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (deviceD->patterns[i]),
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (deviceD->patterns[i]),
device_info->pattern);
gtk_widget_show (deviceD->patterns[i]);
}
@ -973,3 +972,4 @@ device_status_update (guint32 deviceid)
pattern_area_update();
}
}

View file

@ -1,357 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpPatternPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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 "gimppatternpreview.h"
#define PATTERN_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK)
enum {
CLICKED,
LAST_SIGNAL
};
static guint gimp_pattern_preview_signals[LAST_SIGNAL] = { 0 };
static GtkPreviewClass *parent_class = NULL;
static gint gimp_pattern_preview_button_press_event (GtkWidget *, GdkEventButton *);
static gint gimp_pattern_preview_button_release_event (GtkWidget *, GdkEventButton *);
static void gimp_pattern_preview_popup_open (GimpPatternPreview *, gint, gint);
static void gimp_pattern_preview_popup_close (GimpPatternPreview *);
static void gimp_pattern_preview_draw (GimpPatternPreview *);
static void
gimp_pattern_preview_destroy (GtkObject *object)
{
GimpPatternPreview *gpp;
g_return_if_fail (GIMP_IS_PATTERN_PREVIEW (object));
gpp = GIMP_PATTERN_PREVIEW (object);
if (gpp->popup)
gtk_widget_destroy (gpp->popup);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
static void
gimp_pattern_preview_class_init (GimpPatternPreviewClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_preview_get_type ());
gimp_pattern_preview_signals[CLICKED] =
gtk_signal_new ("clicked",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpPatternPreviewClass, clicked),
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, gimp_pattern_preview_signals,
LAST_SIGNAL);
class->clicked = NULL;
widget_class->button_press_event = gimp_pattern_preview_button_press_event;
widget_class->button_release_event = gimp_pattern_preview_button_release_event;
object_class->destroy = gimp_pattern_preview_destroy;
}
static void
gimp_pattern_preview_init (GimpPatternPreview *gpp)
{
gpp->pattern = NULL;
gpp->width = 0;
gpp->height = 0;
gpp->tooltips = NULL;
gpp->popup = NULL;
gpp->popup_preview = NULL;
GTK_PREVIEW (gpp)->type = GTK_PREVIEW_COLOR;
GTK_PREVIEW (gpp)->bpp = 3;
GTK_PREVIEW (gpp)->dither = GDK_RGB_DITHER_NORMAL;
gtk_widget_set_events (GTK_WIDGET (gpp), PATTERN_PREVIEW_EVENT_MASK);
}
GtkType
gimp_pattern_preview_get_type ()
{
static GtkType gpp_type = 0;
if (!gpp_type)
{
GtkTypeInfo gpp_info =
{
"GimpPatternPreview",
sizeof (GimpPatternPreview),
sizeof (GimpPatternPreviewClass),
(GtkClassInitFunc) gimp_pattern_preview_class_init,
(GtkObjectInitFunc) gimp_pattern_preview_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gpp_type = gtk_type_unique (gtk_preview_get_type (), &gpp_info);
}
return gpp_type;
}
GtkWidget*
gimp_pattern_preview_new (gint width,
gint height)
{
GimpPatternPreview *gpp;
g_return_val_if_fail (width > 0 && height > 0, NULL);
gpp = gtk_type_new (gimp_pattern_preview_get_type ());
gpp->width = width;
gpp->height = height;
gtk_preview_size (GTK_PREVIEW (gpp), width, height);
return GTK_WIDGET (gpp);
}
void
gimp_pattern_preview_update (GimpPatternPreview *gpp,
GPattern *pattern)
{
g_return_if_fail (GIMP_IS_PATTERN_PREVIEW (gpp));
g_return_if_fail (pattern != NULL);
if (gpp->pattern == pattern)
return;
gpp->pattern = pattern;
gimp_pattern_preview_draw (gpp);
if (gpp->tooltips)
gtk_tooltips_set_tip (gpp->tooltips, GTK_WIDGET (gpp), gpp->pattern->name, NULL);
}
void
gimp_pattern_preview_set_tooltips (GimpPatternPreview *gpp,
GtkTooltips *tooltips)
{
g_return_if_fail (GIMP_IS_PATTERN_PREVIEW (gpp));
g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
gpp->tooltips = tooltips;
gtk_signal_connect (GTK_OBJECT (gpp->tooltips), "destroy",
gtk_widget_destroyed, &gpp->tooltips);
if (gpp->pattern)
gtk_tooltips_set_tip (gpp->tooltips, GTK_WIDGET (gpp), gpp->pattern->name, NULL);
}
static gint
gimp_pattern_preview_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
{
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
gimp_pattern_preview_popup_open (GIMP_PATTERN_PREVIEW (widget),
bevent->x, bevent->y);
}
return TRUE;
}
static gint
gimp_pattern_preview_button_release_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
gimp_pattern_preview_popup_close (GIMP_PATTERN_PREVIEW (widget));
return TRUE;
}
static void
gimp_pattern_preview_popup_open (GimpPatternPreview *gpp,
gint x,
gint y)
{
gint x_org, y_org;
gint scr_w, scr_h;
guchar *mask;
gint width, height;
g_return_if_fail (gpp != NULL);
if (!gpp->pattern)
return;
width = gpp->pattern->mask->width;
height = gpp->pattern->mask->height;
if (width <= gpp->width && height <= gpp->height)
return;
/* make sure the popup exists and is not visible */
if (gpp->popup == NULL)
{
GtkWidget *frame;
gpp->popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (gpp->popup), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (gpp->popup), "destroy",
gtk_widget_destroyed, &gpp->popup);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (gpp->popup), frame);
gtk_widget_show (frame);
gpp->popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_signal_connect (GTK_OBJECT (gpp->popup_preview), "destroy",
gtk_widget_destroyed, &gpp->popup_preview);
gtk_container_add (GTK_CONTAINER (frame), gpp->popup_preview);
gtk_widget_show (gpp->popup_preview);
}
else
{
gtk_widget_hide (gpp->popup);
}
/* decide where to put the popup */
gdk_window_get_origin (GTK_WIDGET (gpp)->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (width >> 1);
y = y_org + y - (height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + width > scr_w) ? scr_w - width : x;
y = (y + height > scr_h) ? scr_h - height : y;
gtk_preview_size (GTK_PREVIEW (gpp->popup_preview), width, height);
gtk_widget_popup (gpp->popup, x, y);
/* Draw the pattern */
mask = temp_buf_data (gpp->pattern->mask);
if (gpp->pattern->mask->bytes == 1)
{
guchar *buf = g_new (guchar, 3 * width);
guchar *b;
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
memset (b, *mask++, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gpp->popup_preview), buf, 0, y, width);
}
g_free(buf);
}
else
{
for (y = 0; y < height; y++)
{
gtk_preview_draw_row (GTK_PREVIEW (gpp->popup_preview), mask, 0, y, width);
mask += 3 * width;
}
}
gtk_widget_queue_draw (gpp->popup_preview);
}
static void
gimp_pattern_preview_popup_close (GimpPatternPreview *gpp)
{
if (gpp->popup != NULL)
gtk_widget_hide (gpp->popup);
}
static void
gimp_pattern_preview_draw (GimpPatternPreview *gpp)
{
gint pattern_width, pattern_height;
gint width, height;
gint offset_x, offset_y;
guchar *mask, *buf, *b;
gint x, y;
g_return_if_fail (gpp != NULL && gpp->pattern != NULL);
pattern_width = gpp->pattern->mask->width;
pattern_height = gpp->pattern->mask->height;
width = (pattern_width > gpp->width) ? gpp->width : pattern_width;
height = (pattern_height > gpp->height) ? gpp->height: pattern_height;
offset_x = (gpp->width - width) >> 1;
offset_y = (gpp->height - height) >> 1;
mask = temp_buf_data (gpp->pattern->mask);
buf = g_new (guchar, 3 * gpp->width);
memset (buf, 255, 3 * gpp->width);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
if (gpp->pattern->mask->bytes == 1)
{
for (y = offset_y; y < height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < width ; x++)
{
memset (b, mask[x], 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
mask += pattern_width;
}
}
else
{
for (y = offset_y; y < height + offset_y; y++)
{
b = buf + 3 * offset_x;
memcpy (b, mask, 3 * width);
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
mask += 3 * pattern_width;
}
}
memset (buf, 255, 3 * gpp->width);
for (y = height + offset_y; y < gpp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gpp), buf, 0, y, gpp->width);
g_free(buf);
gtk_widget_queue_draw (GTK_WIDGET (gpp));
}

View file

@ -1,71 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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_PATTERN_PREVIEW_H__
#define __GIMP_PATTERN_PREVIEW_H_
#include <gtk/gtk.h>
#include "patterns.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIMP_TYPE_PATTERN_PREVIEW (gimp_pattern_preview_get_type ())
#define GIMP_PATTERN_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_PATTERN_PREVIEW, GimpPatternPreview))
#define GIMP_PATTERN_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PATTERN_PREVIEW, GimpPatternPreviewClass))
#define GIMP_IS_PATTERN_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_PATTERN_PREVIEW))
#define GIMP_IS_PATTERN_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PATTERN_PREVIEW))
typedef struct _GimpPatternPreview GimpPatternPreview;
typedef struct _GimpPatternPreviewClass GimpPatternPreviewClass;
struct _GimpPatternPreview
{
GtkPreview preview;
GPattern *pattern;
gint width;
gint height;
GtkTooltips *tooltips;
GtkWidget *popup;
GtkWidget *popup_preview;
};
struct _GimpPatternPreviewClass
{
GtkPreviewClass parent_class;
void (* clicked) (GimpPatternPreview *gpp);
};
GtkType gimp_pattern_preview_get_type (void);
GtkWidget* gimp_pattern_preview_new (gint width,
gint height);
void gimp_pattern_preview_update (GimpPatternPreview *gpp,
GPattern *pattern);
void gimp_pattern_preview_set_tooltips (GimpPatternPreview *gpp,
GtkTooltips *tooltips);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMP_PATTERN_PREVIEW_H__ */

View file

@ -1,441 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpBrushPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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 "gimpbrushpreview.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "brush_scale.h"
#include "temp_buf.h"
/* the pixmap for the scale_indicator */
#define scale_indicator_width 7
#define scale_indicator_height 7
#define WHT {255,255,255}
#define BLK { 0, 0, 0}
static unsigned char scale_indicator_bits[7][7][3] =
{
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, BLK, BLK, BLK, BLK, BLK, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT }
};
#define BRUSH_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK)
enum {
CLICKED,
LAST_SIGNAL
};
static guint gimp_brush_preview_signals[LAST_SIGNAL] = { 0 };
static GtkPreviewClass *parent_class = NULL;
static gint gimp_brush_preview_button_press_event (GtkWidget *, GdkEventButton *);
static gint gimp_brush_preview_button_release_event (GtkWidget *, GdkEventButton *);
static void gimp_brush_preview_popup_open (GimpBrushPreview *, gint, gint);
static void gimp_brush_preview_popup_close (GimpBrushPreview *);
static void gimp_brush_preview_draw (GimpBrushPreview *);
static void
gimp_brush_preview_destroy (GtkObject *object)
{
GimpBrushPreview *gbp;
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (object));
gbp = GIMP_BRUSH_PREVIEW (object);
if (gbp->popup)
gtk_widget_destroy (gbp->popup);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
static void
gimp_brush_preview_class_init (GimpBrushPreviewClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_preview_get_type ());
gimp_brush_preview_signals[CLICKED] =
gtk_signal_new ("clicked",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpBrushPreviewClass, clicked),
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, gimp_brush_preview_signals,
LAST_SIGNAL);
class->clicked = NULL;
widget_class->button_press_event = gimp_brush_preview_button_press_event;
widget_class->button_release_event = gimp_brush_preview_button_release_event;
object_class->destroy = gimp_brush_preview_destroy;
}
static void
gimp_brush_preview_init (GimpBrushPreview *gbp)
{
gbp->brush = NULL;
gbp->width = 0;
gbp->height = 0;
gbp->tooltips = NULL;
gbp->popup = NULL;
gbp->popup_preview = NULL;
GTK_PREVIEW (gbp)->type = GTK_PREVIEW_COLOR;
GTK_PREVIEW (gbp)->bpp = 3;
GTK_PREVIEW (gbp)->dither = GDK_RGB_DITHER_NORMAL;
gtk_widget_set_events (GTK_WIDGET (gbp), BRUSH_PREVIEW_EVENT_MASK);
}
GtkType
gimp_brush_preview_get_type ()
{
static GtkType gbp_type = 0;
if (!gbp_type)
{
GtkTypeInfo gbp_info =
{
"GimpBrushPreview",
sizeof (GimpBrushPreview),
sizeof (GimpBrushPreviewClass),
(GtkClassInitFunc) gimp_brush_preview_class_init,
(GtkObjectInitFunc) gimp_brush_preview_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gbp_type = gtk_type_unique (gtk_preview_get_type (), &gbp_info);
}
return gbp_type;
}
GtkWidget*
gimp_brush_preview_new (gint width,
gint height)
{
GimpBrushPreview *gbp;
g_return_val_if_fail (width > 0 && height > 0, NULL);
gbp = gtk_type_new (gimp_brush_preview_get_type ());
gbp->width = width;
gbp->height = height;
gtk_preview_size (GTK_PREVIEW (gbp), width, height);
return GTK_WIDGET (gbp);
}
void
gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GIMP_IS_BRUSH (brush));
if (gbp->brush == brush)
return;
gbp->brush = brush;
gtk_signal_connect (GTK_OBJECT (gbp->brush), "destroy",
gtk_widget_destroyed, &gbp->brush);
gimp_brush_preview_draw (gbp);
if (gbp->tooltips)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
void
gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
gbp->tooltips = tooltips;
gtk_signal_connect (GTK_OBJECT (gbp->tooltips), "destroy",
gtk_widget_destroyed, &gbp->tooltips);
if (gbp->brush)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
static gint
gimp_brush_preview_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
{
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
gimp_brush_preview_popup_open (GIMP_BRUSH_PREVIEW (widget),
bevent->x, bevent->y);
}
return TRUE;
}
static gint
gimp_brush_preview_button_release_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
gimp_brush_preview_popup_close (GIMP_BRUSH_PREVIEW (widget));
return TRUE;
}
static void
gimp_brush_preview_popup_open (GimpBrushPreview *gbp,
gint x,
gint y)
{
gint x_org, y_org;
gint scr_w, scr_h;
guchar *mask, *buf, *b;
gint width, height;
guchar bg;
g_return_if_fail (gbp != NULL);
if (!gbp->brush)
return;
width = gbp->brush->mask->width;
height = gbp->brush->mask->height;
if (width <= gbp->width && height <= gbp->height)
return;
/* make sure the popup exists and is not visible */
if (gbp->popup == NULL)
{
GtkWidget *frame;
gbp->popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (gbp->popup), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (gbp->popup), "destroy",
gtk_widget_destroyed, &gbp->popup);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (gbp->popup), frame);
gtk_widget_show (frame);
gbp->popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_signal_connect (GTK_OBJECT (gbp->popup_preview), "destroy",
gtk_widget_destroyed, &gbp->popup_preview);
gtk_container_add (GTK_CONTAINER (frame), gbp->popup_preview);
gtk_widget_show (gbp->popup_preview);
}
else
{
gtk_widget_hide (gbp->popup);
}
/* decide where to put the popup */
gdk_window_get_origin (GTK_WIDGET (gbp)->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (width >> 1);
y = y_org + y - (height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + width > scr_w) ? scr_w - width : x;
y = (y + height > scr_h) ? scr_h - height : y;
gtk_preview_size (GTK_PREVIEW (gbp->popup_preview), width, height);
gtk_widget_popup (gbp->popup, x, y);
/* Draw the brush */
buf = g_new (guchar, 3 * width);
mask = temp_buf_data (gbp->brush->mask);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (gbp->brush)->pixmap_mask);
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
else
{
for (y = 0; y < height; y++)
{
b = buf;
/* Invert the mask for display. */
for (x = 0; x < width; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
g_free(buf);
gtk_widget_queue_draw (gbp->popup_preview);
}
static void
gimp_brush_preview_popup_close (GimpBrushPreview *gbp)
{
if (gbp->popup != NULL)
gtk_widget_hide (gbp->popup);
}
static void
gimp_brush_preview_draw (GimpBrushPreview *gbp)
{
gboolean scale = FALSE;
gint brush_width, brush_height;
gint offset_x, offset_y;
TempBuf *mask_buf, *pixmap_buf = NULL;
guchar *mask, *buf, *b;
guchar bg;
gint x, y;
g_return_if_fail (gbp != NULL && gbp->brush != NULL);
brush_width = gbp->brush->mask->width;
brush_height = gbp->brush->mask->height;
if (brush_width > gbp->width || brush_height > gbp->height)
{
gdouble ratio_x = (gdouble)brush_width / gbp->width;
gdouble ratio_y = (gdouble)brush_height / gbp->height;
brush_width = (gdouble)brush_width / MAX (ratio_x, ratio_y);
brush_height = (gdouble)brush_height / MAX (ratio_x, ratio_y);
mask_buf = brush_scale_mask (gbp->brush->mask, brush_width, brush_height);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
pixmap_buf = brush_scale_pixmap (GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask,
brush_width, brush_height);
}
scale = TRUE;
}
else
{
mask_buf = gbp->brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
pixmap_buf = GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask;
}
offset_x = (gbp->width - brush_width) >> 1;
offset_y = (gbp->height - brush_height) >> 1;
mask = temp_buf_data (mask_buf);
buf = g_new (guchar, 3 * gbp->width);
memset (buf, 255, 3 * gbp->width);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (pixmap_buf);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
else
{
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
if (scale)
{
offset_x = gbp->width - scale_indicator_width - 1;
offset_y = gbp->height - scale_indicator_height - 1;
for (y = 0; y < scale_indicator_height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), scale_indicator_bits[y][0],
offset_x, offset_y + y, scale_indicator_width);
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
temp_buf_free (pixmap_buf);
}
g_free(buf);
gtk_widget_queue_draw (GTK_WIDGET (gbp));
}

View file

@ -1,71 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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_BRUSH_PREVIEW_H__
#define __GIMP_BRUSH_PREVIEW_H_
#include <gtk/gtk.h>
#include "gimpbrush.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIMP_TYPE_BRUSH_PREVIEW (gimp_brush_preview_get_type ())
#define GIMP_BRUSH_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreview))
#define GIMP_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass))
#define GIMP_IS_BRUSH_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_BRUSH_PREVIEW))
#define GIMP_IS_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_PREVIEW))
typedef struct _GimpBrushPreview GimpBrushPreview;
typedef struct _GimpBrushPreviewClass GimpBrushPreviewClass;
struct _GimpBrushPreview
{
GtkPreview preview;
GimpBrush *brush;
gint width;
gint height;
GtkTooltips *tooltips;
GtkWidget *popup;
GtkWidget *popup_preview;
};
struct _GimpBrushPreviewClass
{
GtkPreviewClass parent_class;
void (* clicked) (GimpBrushPreview *gbp);
};
GtkType gimp_brush_preview_get_type (void);
GtkWidget* gimp_brush_preview_new (gint width,
gint height);
void gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush);
void gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMP_BRUSH_PREVIEW_H__ */

View file

@ -19,11 +19,11 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "indicator_area.h"
#include "interface.h"
#include "gimpbrushlist.h"
#include "gimpbrushpreview.h"
#include "gimppatternpreview.h"
#include "gimpcontextpreview.h"
#include "indicator_area.h"
#include "interface.h" /* for tool_tips */
#include "libgimp/gimpintl.h"
#define CELL_SIZE 23 /* The size of the previews */
#define CELL_PADDING 2 /* How much between brush and pattern cells */
@ -49,17 +49,17 @@ brush_area_update ()
brush = get_active_brush();
if (!brush)
{
g_warning("No gimp brush found\n");
g_warning ("No gimp brush found\n");
return;
}
gimp_brush_preview_update (GIMP_BRUSH_PREVIEW (brush_preview), brush);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (brush_preview), brush);
}
static gint
brush_preview_clicked (GtkWidget *widget,
gpointer data)
{
create_brush_dialog();
create_brush_dialog ();
return TRUE;
}
@ -74,10 +74,10 @@ pattern_area_update ()
if (!pattern)
{
g_warning("No gimp pattern found\n");
g_warning ("No gimp pattern found\n");
return;
}
gimp_pattern_preview_update (GIMP_PATTERN_PREVIEW (pattern_preview), pattern);
gimp_context_preview_update (GIMP_CONTEXT_PREVIEW (pattern_preview), pattern);
}
static gint
@ -94,15 +94,23 @@ indicator_area_create (int width,
{
indicator_table = gtk_table_new (1, 3, FALSE);
brush_preview = gimp_brush_preview_new (CELL_SIZE, CELL_SIZE);
gimp_brush_preview_set_tooltips (GIMP_BRUSH_PREVIEW (brush_preview), tool_tips);
brush_preview = gimp_context_preview_new (GCP_BRUSH,
CELL_SIZE, CELL_SIZE,
FALSE);
gtk_tooltips_set_tip (tool_tips, brush_preview,
_("The active brush.\nClick to open the Brushes Dialog."),
NULL);
gtk_signal_connect (GTK_OBJECT (brush_preview), "clicked",
(GtkSignalFunc) brush_preview_clicked, NULL);
gtk_table_attach_defaults (GTK_TABLE(indicator_table), brush_preview,
0, 1, 0, 1);
pattern_preview = gimp_pattern_preview_new (CELL_SIZE, CELL_SIZE);
gimp_pattern_preview_set_tooltips (GIMP_PATTERN_PREVIEW (pattern_preview), tool_tips);
pattern_preview = gimp_context_preview_new (GCP_PATTERN,
CELL_SIZE, CELL_SIZE,
FALSE);
gtk_tooltips_set_tip (tool_tips, pattern_preview,
_("The active pattern.\nClick to open the Patterns Dialog."),
NULL);
gtk_signal_connect (GTK_OBJECT (pattern_preview), "clicked",
(GtkSignalFunc) pattern_preview_clicked, NULL);
gtk_table_attach_defaults (GTK_TABLE(indicator_table), pattern_preview,

View file

@ -1,441 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpBrushPreview Widget
* Copyright (C) 1999 Sven Neumann
*
* 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 "gimpbrushpreview.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "brush_scale.h"
#include "temp_buf.h"
/* the pixmap for the scale_indicator */
#define scale_indicator_width 7
#define scale_indicator_height 7
#define WHT {255,255,255}
#define BLK { 0, 0, 0}
static unsigned char scale_indicator_bits[7][7][3] =
{
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, BLK, BLK, BLK, BLK, BLK, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT }
};
#define BRUSH_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK)
enum {
CLICKED,
LAST_SIGNAL
};
static guint gimp_brush_preview_signals[LAST_SIGNAL] = { 0 };
static GtkPreviewClass *parent_class = NULL;
static gint gimp_brush_preview_button_press_event (GtkWidget *, GdkEventButton *);
static gint gimp_brush_preview_button_release_event (GtkWidget *, GdkEventButton *);
static void gimp_brush_preview_popup_open (GimpBrushPreview *, gint, gint);
static void gimp_brush_preview_popup_close (GimpBrushPreview *);
static void gimp_brush_preview_draw (GimpBrushPreview *);
static void
gimp_brush_preview_destroy (GtkObject *object)
{
GimpBrushPreview *gbp;
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (object));
gbp = GIMP_BRUSH_PREVIEW (object);
if (gbp->popup)
gtk_widget_destroy (gbp->popup);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
static void
gimp_brush_preview_class_init (GimpBrushPreviewClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_preview_get_type ());
gimp_brush_preview_signals[CLICKED] =
gtk_signal_new ("clicked",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpBrushPreviewClass, clicked),
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, gimp_brush_preview_signals,
LAST_SIGNAL);
class->clicked = NULL;
widget_class->button_press_event = gimp_brush_preview_button_press_event;
widget_class->button_release_event = gimp_brush_preview_button_release_event;
object_class->destroy = gimp_brush_preview_destroy;
}
static void
gimp_brush_preview_init (GimpBrushPreview *gbp)
{
gbp->brush = NULL;
gbp->width = 0;
gbp->height = 0;
gbp->tooltips = NULL;
gbp->popup = NULL;
gbp->popup_preview = NULL;
GTK_PREVIEW (gbp)->type = GTK_PREVIEW_COLOR;
GTK_PREVIEW (gbp)->bpp = 3;
GTK_PREVIEW (gbp)->dither = GDK_RGB_DITHER_NORMAL;
gtk_widget_set_events (GTK_WIDGET (gbp), BRUSH_PREVIEW_EVENT_MASK);
}
GtkType
gimp_brush_preview_get_type ()
{
static GtkType gbp_type = 0;
if (!gbp_type)
{
GtkTypeInfo gbp_info =
{
"GimpBrushPreview",
sizeof (GimpBrushPreview),
sizeof (GimpBrushPreviewClass),
(GtkClassInitFunc) gimp_brush_preview_class_init,
(GtkObjectInitFunc) gimp_brush_preview_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gbp_type = gtk_type_unique (gtk_preview_get_type (), &gbp_info);
}
return gbp_type;
}
GtkWidget*
gimp_brush_preview_new (gint width,
gint height)
{
GimpBrushPreview *gbp;
g_return_val_if_fail (width > 0 && height > 0, NULL);
gbp = gtk_type_new (gimp_brush_preview_get_type ());
gbp->width = width;
gbp->height = height;
gtk_preview_size (GTK_PREVIEW (gbp), width, height);
return GTK_WIDGET (gbp);
}
void
gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GIMP_IS_BRUSH (brush));
if (gbp->brush == brush)
return;
gbp->brush = brush;
gtk_signal_connect (GTK_OBJECT (gbp->brush), "destroy",
gtk_widget_destroyed, &gbp->brush);
gimp_brush_preview_draw (gbp);
if (gbp->tooltips)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
void
gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips)
{
g_return_if_fail (GIMP_IS_BRUSH_PREVIEW (gbp));
g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
gbp->tooltips = tooltips;
gtk_signal_connect (GTK_OBJECT (gbp->tooltips), "destroy",
gtk_widget_destroyed, &gbp->tooltips);
if (gbp->brush)
gtk_tooltips_set_tip (gbp->tooltips, GTK_WIDGET (gbp), gbp->brush->name, NULL);
}
static gint
gimp_brush_preview_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
{
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
gimp_brush_preview_popup_open (GIMP_BRUSH_PREVIEW (widget),
bevent->x, bevent->y);
}
return TRUE;
}
static gint
gimp_brush_preview_button_release_event (GtkWidget *widget,
GdkEventButton *bevent)
{
if (bevent->button == 1)
gimp_brush_preview_popup_close (GIMP_BRUSH_PREVIEW (widget));
return TRUE;
}
static void
gimp_brush_preview_popup_open (GimpBrushPreview *gbp,
gint x,
gint y)
{
gint x_org, y_org;
gint scr_w, scr_h;
guchar *mask, *buf, *b;
gint width, height;
guchar bg;
g_return_if_fail (gbp != NULL);
if (!gbp->brush)
return;
width = gbp->brush->mask->width;
height = gbp->brush->mask->height;
if (width <= gbp->width && height <= gbp->height)
return;
/* make sure the popup exists and is not visible */
if (gbp->popup == NULL)
{
GtkWidget *frame;
gbp->popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (gbp->popup), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (gbp->popup), "destroy",
gtk_widget_destroyed, &gbp->popup);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (gbp->popup), frame);
gtk_widget_show (frame);
gbp->popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_signal_connect (GTK_OBJECT (gbp->popup_preview), "destroy",
gtk_widget_destroyed, &gbp->popup_preview);
gtk_container_add (GTK_CONTAINER (frame), gbp->popup_preview);
gtk_widget_show (gbp->popup_preview);
}
else
{
gtk_widget_hide (gbp->popup);
}
/* decide where to put the popup */
gdk_window_get_origin (GTK_WIDGET (gbp)->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (width >> 1);
y = y_org + y - (height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + width > scr_w) ? scr_w - width : x;
y = (y + height > scr_h) ? scr_h - height : y;
gtk_preview_size (GTK_PREVIEW (gbp->popup_preview), width, height);
gtk_widget_popup (gbp->popup, x, y);
/* Draw the brush */
buf = g_new (guchar, 3 * width);
mask = temp_buf_data (gbp->brush->mask);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (gbp->brush)->pixmap_mask);
for (y = 0; y < height; y++)
{
b = buf;
for (x = 0; x < width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
else
{
for (y = 0; y < height; y++)
{
b = buf;
/* Invert the mask for display. */
for (x = 0; x < width; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp->popup_preview), buf, 0, y, width);
}
}
g_free(buf);
gtk_widget_queue_draw (gbp->popup_preview);
}
static void
gimp_brush_preview_popup_close (GimpBrushPreview *gbp)
{
if (gbp->popup != NULL)
gtk_widget_hide (gbp->popup);
}
static void
gimp_brush_preview_draw (GimpBrushPreview *gbp)
{
gboolean scale = FALSE;
gint brush_width, brush_height;
gint offset_x, offset_y;
TempBuf *mask_buf, *pixmap_buf = NULL;
guchar *mask, *buf, *b;
guchar bg;
gint x, y;
g_return_if_fail (gbp != NULL && gbp->brush != NULL);
brush_width = gbp->brush->mask->width;
brush_height = gbp->brush->mask->height;
if (brush_width > gbp->width || brush_height > gbp->height)
{
gdouble ratio_x = (gdouble)brush_width / gbp->width;
gdouble ratio_y = (gdouble)brush_height / gbp->height;
brush_width = (gdouble)brush_width / MAX (ratio_x, ratio_y);
brush_height = (gdouble)brush_height / MAX (ratio_x, ratio_y);
mask_buf = brush_scale_mask (gbp->brush->mask, brush_width, brush_height);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
pixmap_buf = brush_scale_pixmap (GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask,
brush_width, brush_height);
}
scale = TRUE;
}
else
{
mask_buf = gbp->brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
pixmap_buf = GIMP_BRUSH_PIXMAP(gbp->brush)->pixmap_mask;
}
offset_x = (gbp->width - brush_width) >> 1;
offset_y = (gbp->height - brush_height) >> 1;
mask = temp_buf_data (mask_buf);
buf = g_new (guchar, 3 * gbp->width);
memset (buf, 255, 3 * gbp->width);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
{
guchar *pixmap = temp_buf_data (pixmap_buf);
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = (255 - *mask);
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
*b++ = bg + (*mask * *pixmap++) / 255;
mask++;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
else
{
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
for (y = offset_y; y < brush_height + offset_y; y++)
{
b = buf + 3 * offset_x;
for (x = 0; x < brush_width ; x++)
{
bg = 255 - *mask++;
memset (b, bg, 3);
b += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
memset (buf, 255, 3 * gbp->width);
for (y = brush_height + offset_y; y < gbp->height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), buf, 0, y, gbp->width);
}
if (scale)
{
offset_x = gbp->width - scale_indicator_width - 1;
offset_y = gbp->height - scale_indicator_height - 1;
for (y = 0; y < scale_indicator_height; y++)
gtk_preview_draw_row (GTK_PREVIEW (gbp), scale_indicator_bits[y][0],
offset_x, offset_y + y, scale_indicator_width);
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (gbp->brush))
temp_buf_free (pixmap_buf);
}
g_free(buf);
gtk_widget_queue_draw (GTK_WIDGET (gbp));
}

View file

@ -1,71 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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_BRUSH_PREVIEW_H__
#define __GIMP_BRUSH_PREVIEW_H_
#include <gtk/gtk.h>
#include "gimpbrush.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIMP_TYPE_BRUSH_PREVIEW (gimp_brush_preview_get_type ())
#define GIMP_BRUSH_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreview))
#define GIMP_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass))
#define GIMP_IS_BRUSH_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_BRUSH_PREVIEW))
#define GIMP_IS_BRUSH_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_PREVIEW))
typedef struct _GimpBrushPreview GimpBrushPreview;
typedef struct _GimpBrushPreviewClass GimpBrushPreviewClass;
struct _GimpBrushPreview
{
GtkPreview preview;
GimpBrush *brush;
gint width;
gint height;
GtkTooltips *tooltips;
GtkWidget *popup;
GtkWidget *popup_preview;
};
struct _GimpBrushPreviewClass
{
GtkPreviewClass parent_class;
void (* clicked) (GimpBrushPreview *gbp);
};
GtkType gimp_brush_preview_get_type (void);
GtkWidget* gimp_brush_preview_new (gint width,
gint height);
void gimp_brush_preview_update (GimpBrushPreview *gbp,
GimpBrush *brush);
void gimp_brush_preview_set_tooltips (GimpBrushPreview *gbp,
GtkTooltips *tooltips);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GIMP_BRUSH_PREVIEW_H__ */