app/gdisplay.[ch] app/disp_callbacks.c Added preliminary support for

2001-02-20  Simon Budig  <simon@gimp.org>

        * app/gdisplay.[ch]
        * app/disp_callbacks.c
        * app/interface.c: Added preliminary support for Preview icons.

        This is not finished: We need a better way to get previews with
        a specific depth and probably a rendered Checkerboard for the
        alpha channel. Also the update function is now bound to a click
        in the top left menu-button and should go in some idle-stuff.
        Please test this on various window managers and give some
        feedback. The last point is the aspect ratio of the generated
        previews...
This commit is contained in:
Simon Budig 2001-02-20 15:15:30 +00:00 committed by Simon Budig
parent 83a9899ce5
commit 9f0abd04c5
13 changed files with 452 additions and 0 deletions

View File

@ -1,3 +1,17 @@
2001-02-20 Simon Budig <simon@gimp.org>
* app/gdisplay.[ch]
* app/disp_callbacks.c
* app/interface.c: Added preliminary support for Preview icons.
This is not finished: We need a better way to get previews with
a specific depth and probably a rendered Checkerboard for the
alpha channel. Also the update function is now bound to a click
in the top left menu-button and should go in some idle-stuff.
Please test this on various window managers and give some
feedback. The last point is the aspect ratio of the generated
previews...
2001-02-20 Nick Lamb <njl195@zepler.org.uk>
* libgimpwidgets/gimpwidgets.c: include string.h

View File

@ -53,8 +53,10 @@
#include "qmask.h"
#include "scale.h"
#include "selection.h"
#include "temp_buf.h"
#include "undo.h"
#include "pixmaps/wilber.xpm"
#ifdef DISPLAY_FILTERS
#include "gdisplay_color.h"
@ -429,6 +431,9 @@ gdisplay_delete (GDisplay *gdisp)
if (gdisp->nav_popup)
nav_popup_free (gdisp->nav_popup);
gdk_pixmap_unref (gdisp->icon);
gdk_pixmap_unref (gdisp->iconmask);
gtk_widget_unref (gdisp->shell);
g_free (gdisp);
@ -775,6 +780,124 @@ gdisplays_finish_draw (void)
}
}
void
gdisplay_update_icon (GDisplay *gdisp)
{
/* Warning: Lots of obscure Gdk-Stuff ahead. */
static GdkPixmap *wilber_pixmap = NULL;
static GdkBitmap *wilber_mask = NULL;
GtkStyle *style;
GdkGC *icongc, *iconmaskgc;
GdkColormap *colormap;
GdkColor black, white;
TempBuf *icondata;
guchar *data;
gdk_rgb_init ();
icongc = gdk_gc_new (gdisp->icon);
iconmaskgc = gdk_gc_new (gdisp->iconmask);
colormap = gdk_colormap_get_system (); /* or gdk_rgb_get_cmap () */
gdk_color_white (colormap, &white);
gdk_color_black (colormap, &black);
if (! gdisp->icon_needs_update)
return;
style = gtk_widget_get_style (gdisp->shell);
if (wilber_pixmap == NULL)
wilber_pixmap =
gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
&wilber_mask,
&style->bg[GTK_STATE_NORMAL],
wilber_xpm);
icondata = gimp_viewable_get_new_preview (GIMP_VIEWABLE (gdisp->gimage),
gdisp->iconsize,
gdisp->iconsize);
data = temp_buf_data (icondata);
/* Set up an icon mask */
gdk_gc_set_foreground (iconmaskgc, &black);
gdk_draw_rectangle (gdisp->iconmask, iconmaskgc, TRUE, 0, 0,
gdisp->iconsize, gdisp->iconsize);
gdk_gc_set_foreground (iconmaskgc, &white);
gdk_draw_rectangle (gdisp->iconmask, iconmaskgc, TRUE,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width, icondata->height);
/* This is an ugly bad hack. There should be a clean way to get
* a preview in a specified depth with a nicely rendered
* checkerboard if no alpha channel is requested.
* We ignore the alpha channel for now. Also the aspect ratio is
* incorrect.
*
* Currently the icons are updated when you press the "menu" button in
* the top left corner of the window. Of course this should go in an
* idle routine.
*/
if (icondata->bytes == 1)
{
gdk_draw_gray_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else if (icondata->bytes == 3)
{
gdk_draw_rgb_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else if (icondata->bytes == 4)
{
gdk_draw_rgb_32_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else
{
g_printerr ("gdisplay: falling back to default\n");
gdk_window_set_icon (gdisp->shell->window,
NULL, wilber_pixmap, wilber_mask);
}
gdisp->icon_needs_update = 0;
gdk_gc_unref (icongc);
gdk_gc_unref (iconmaskgc);
temp_buf_free (icondata);
}
void
gdisplay_draw_guides (GDisplay *gdisp)
{
@ -2421,6 +2544,7 @@ gdisplay_cleandirty_handler (GimpImage *gimage,
GDisplay *gdisp = data;
gdisplay_update_title (gdisp);
gdisp->icon_needs_update = 1;
}
void

View File

@ -121,6 +121,11 @@ struct _GDisplay
GtkAdjustment *hsbdata; /* horizontal data information */
GtkAdjustment *vsbdata; /* vertical data information */
GdkPixmap *icon; /* Pixmap for the icon */
GdkBitmap *iconmask; /* Bitmap for the icon mask */
guint iconsize; /* The size of the icon pixmap */
guint icon_needs_update; /* Do we need to render a new icon? */
GimpImage *gimage; /* pointer to the associated gimage struct */
gint instance; /* the instance # of this gdisplay as */
/* taken from the gimage at creation */
@ -208,6 +213,7 @@ void gdisplay_expose_guide (GDisplay *, Guide *);
void gdisplay_expose_full (GDisplay *);
void gdisplay_flush (GDisplay *);
void gdisplay_flush_now (GDisplay *);
void gdisplay_update_icon (GDisplay *);
void gdisplay_draw_guides (GDisplay *);
void gdisplay_draw_guide (GDisplay *, Guide *, gboolean);
Guide* gdisplay_find_guide (GDisplay *, gdouble, double);

View File

@ -733,6 +733,11 @@ gdisplay_origin_button_press (GtkWidget *widget,
if (!gimp_busy && event->button == 1)
{
gdisp = data;
/* this does not belong here, It should be placed in an idle-loop! */
gdisplay_update_icon (gdisp);
/* gdisplay_update_icon should be placed in an idle-loop!!!! */
gtk_menu_popup (GTK_MENU (gdisp->popup),
NULL, NULL,
gdisplay_origin_menu_position, widget,

View File

@ -733,6 +733,11 @@ gdisplay_origin_button_press (GtkWidget *widget,
if (!gimp_busy && event->button == 1)
{
gdisp = data;
/* this does not belong here, It should be placed in an idle-loop! */
gdisplay_update_icon (gdisp);
/* gdisplay_update_icon should be placed in an idle-loop!!!! */
gtk_menu_popup (GTK_MENU (gdisp->popup),
NULL, NULL,
gdisplay_origin_menu_position, widget,

View File

@ -53,8 +53,10 @@
#include "qmask.h"
#include "scale.h"
#include "selection.h"
#include "temp_buf.h"
#include "undo.h"
#include "pixmaps/wilber.xpm"
#ifdef DISPLAY_FILTERS
#include "gdisplay_color.h"
@ -429,6 +431,9 @@ gdisplay_delete (GDisplay *gdisp)
if (gdisp->nav_popup)
nav_popup_free (gdisp->nav_popup);
gdk_pixmap_unref (gdisp->icon);
gdk_pixmap_unref (gdisp->iconmask);
gtk_widget_unref (gdisp->shell);
g_free (gdisp);
@ -775,6 +780,124 @@ gdisplays_finish_draw (void)
}
}
void
gdisplay_update_icon (GDisplay *gdisp)
{
/* Warning: Lots of obscure Gdk-Stuff ahead. */
static GdkPixmap *wilber_pixmap = NULL;
static GdkBitmap *wilber_mask = NULL;
GtkStyle *style;
GdkGC *icongc, *iconmaskgc;
GdkColormap *colormap;
GdkColor black, white;
TempBuf *icondata;
guchar *data;
gdk_rgb_init ();
icongc = gdk_gc_new (gdisp->icon);
iconmaskgc = gdk_gc_new (gdisp->iconmask);
colormap = gdk_colormap_get_system (); /* or gdk_rgb_get_cmap () */
gdk_color_white (colormap, &white);
gdk_color_black (colormap, &black);
if (! gdisp->icon_needs_update)
return;
style = gtk_widget_get_style (gdisp->shell);
if (wilber_pixmap == NULL)
wilber_pixmap =
gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
&wilber_mask,
&style->bg[GTK_STATE_NORMAL],
wilber_xpm);
icondata = gimp_viewable_get_new_preview (GIMP_VIEWABLE (gdisp->gimage),
gdisp->iconsize,
gdisp->iconsize);
data = temp_buf_data (icondata);
/* Set up an icon mask */
gdk_gc_set_foreground (iconmaskgc, &black);
gdk_draw_rectangle (gdisp->iconmask, iconmaskgc, TRUE, 0, 0,
gdisp->iconsize, gdisp->iconsize);
gdk_gc_set_foreground (iconmaskgc, &white);
gdk_draw_rectangle (gdisp->iconmask, iconmaskgc, TRUE,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width, icondata->height);
/* This is an ugly bad hack. There should be a clean way to get
* a preview in a specified depth with a nicely rendered
* checkerboard if no alpha channel is requested.
* We ignore the alpha channel for now. Also the aspect ratio is
* incorrect.
*
* Currently the icons are updated when you press the "menu" button in
* the top left corner of the window. Of course this should go in an
* idle routine.
*/
if (icondata->bytes == 1)
{
gdk_draw_gray_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else if (icondata->bytes == 3)
{
gdk_draw_rgb_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else if (icondata->bytes == 4)
{
gdk_draw_rgb_32_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else
{
g_printerr ("gdisplay: falling back to default\n");
gdk_window_set_icon (gdisp->shell->window,
NULL, wilber_pixmap, wilber_mask);
}
gdisp->icon_needs_update = 0;
gdk_gc_unref (icongc);
gdk_gc_unref (iconmaskgc);
temp_buf_free (icondata);
}
void
gdisplay_draw_guides (GDisplay *gdisp)
{
@ -2421,6 +2544,7 @@ gdisplay_cleandirty_handler (GimpImage *gimage,
GDisplay *gdisp = data;
gdisplay_update_title (gdisp);
gdisp->icon_needs_update = 1;
}
void

View File

@ -121,6 +121,11 @@ struct _GDisplay
GtkAdjustment *hsbdata; /* horizontal data information */
GtkAdjustment *vsbdata; /* vertical data information */
GdkPixmap *icon; /* Pixmap for the icon */
GdkBitmap *iconmask; /* Bitmap for the icon mask */
guint iconsize; /* The size of the icon pixmap */
guint icon_needs_update; /* Do we need to render a new icon? */
GimpImage *gimage; /* pointer to the associated gimage struct */
gint instance; /* the instance # of this gdisplay as */
/* taken from the gimage at creation */
@ -208,6 +213,7 @@ void gdisplay_expose_guide (GDisplay *, Guide *);
void gdisplay_expose_full (GDisplay *);
void gdisplay_flush (GDisplay *);
void gdisplay_flush_now (GDisplay *);
void gdisplay_update_icon (GDisplay *);
void gdisplay_draw_guides (GDisplay *);
void gdisplay_draw_guide (GDisplay *, Guide *, gboolean);
Guide* gdisplay_find_guide (GDisplay *, gdouble, double);

View File

@ -733,6 +733,11 @@ gdisplay_origin_button_press (GtkWidget *widget,
if (!gimp_busy && event->button == 1)
{
gdisp = data;
/* this does not belong here, It should be placed in an idle-loop! */
gdisplay_update_icon (gdisp);
/* gdisplay_update_icon should be placed in an idle-loop!!!! */
gtk_menu_popup (GTK_MENU (gdisp->popup),
NULL, NULL,
gdisplay_origin_menu_position, widget,

View File

@ -415,6 +415,17 @@ create_display_shell (GDisplay *gdisp,
&navbutton_mask,
&style->bg[GTK_STATE_NORMAL],
navbutton_xpm);
/* Icon stuff */
gdisp->iconsize = 32;
gdisp->icon = gdk_pixmap_new (gdisp->shell->window,
gdisp->iconsize,
gdisp->iconsize,
-1);
gdisp->iconmask = gdk_pixmap_new (NULL,
gdisp->iconsize,
gdisp->iconsize,
1);
gdisp->icon_needs_update = 1;
}
/* create the GtkPixmaps */

View File

@ -415,6 +415,17 @@ create_display_shell (GDisplay *gdisp,
&navbutton_mask,
&style->bg[GTK_STATE_NORMAL],
navbutton_xpm);
/* Icon stuff */
gdisp->iconsize = 32;
gdisp->icon = gdk_pixmap_new (gdisp->shell->window,
gdisp->iconsize,
gdisp->iconsize,
-1);
gdisp->iconmask = gdk_pixmap_new (NULL,
gdisp->iconsize,
gdisp->iconsize,
1);
gdisp->icon_needs_update = 1;
}
/* create the GtkPixmaps */

View File

@ -53,8 +53,10 @@
#include "qmask.h"
#include "scale.h"
#include "selection.h"
#include "temp_buf.h"
#include "undo.h"
#include "pixmaps/wilber.xpm"
#ifdef DISPLAY_FILTERS
#include "gdisplay_color.h"
@ -429,6 +431,9 @@ gdisplay_delete (GDisplay *gdisp)
if (gdisp->nav_popup)
nav_popup_free (gdisp->nav_popup);
gdk_pixmap_unref (gdisp->icon);
gdk_pixmap_unref (gdisp->iconmask);
gtk_widget_unref (gdisp->shell);
g_free (gdisp);
@ -775,6 +780,124 @@ gdisplays_finish_draw (void)
}
}
void
gdisplay_update_icon (GDisplay *gdisp)
{
/* Warning: Lots of obscure Gdk-Stuff ahead. */
static GdkPixmap *wilber_pixmap = NULL;
static GdkBitmap *wilber_mask = NULL;
GtkStyle *style;
GdkGC *icongc, *iconmaskgc;
GdkColormap *colormap;
GdkColor black, white;
TempBuf *icondata;
guchar *data;
gdk_rgb_init ();
icongc = gdk_gc_new (gdisp->icon);
iconmaskgc = gdk_gc_new (gdisp->iconmask);
colormap = gdk_colormap_get_system (); /* or gdk_rgb_get_cmap () */
gdk_color_white (colormap, &white);
gdk_color_black (colormap, &black);
if (! gdisp->icon_needs_update)
return;
style = gtk_widget_get_style (gdisp->shell);
if (wilber_pixmap == NULL)
wilber_pixmap =
gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
&wilber_mask,
&style->bg[GTK_STATE_NORMAL],
wilber_xpm);
icondata = gimp_viewable_get_new_preview (GIMP_VIEWABLE (gdisp->gimage),
gdisp->iconsize,
gdisp->iconsize);
data = temp_buf_data (icondata);
/* Set up an icon mask */
gdk_gc_set_foreground (iconmaskgc, &black);
gdk_draw_rectangle (gdisp->iconmask, iconmaskgc, TRUE, 0, 0,
gdisp->iconsize, gdisp->iconsize);
gdk_gc_set_foreground (iconmaskgc, &white);
gdk_draw_rectangle (gdisp->iconmask, iconmaskgc, TRUE,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width, icondata->height);
/* This is an ugly bad hack. There should be a clean way to get
* a preview in a specified depth with a nicely rendered
* checkerboard if no alpha channel is requested.
* We ignore the alpha channel for now. Also the aspect ratio is
* incorrect.
*
* Currently the icons are updated when you press the "menu" button in
* the top left corner of the window. Of course this should go in an
* idle routine.
*/
if (icondata->bytes == 1)
{
gdk_draw_gray_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else if (icondata->bytes == 3)
{
gdk_draw_rgb_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else if (icondata->bytes == 4)
{
gdk_draw_rgb_32_image (gdisp->icon,
icongc,
(gdisp->iconsize - icondata->height) / 2,
(gdisp->iconsize - icondata->width) / 2,
icondata->width,
icondata->height,
GDK_RGB_DITHER_MAX,
data,
icondata->width * icondata->bytes);
gdk_window_set_icon (gdisp->shell->window,
NULL, gdisp->icon, gdisp->iconmask);
}
else
{
g_printerr ("gdisplay: falling back to default\n");
gdk_window_set_icon (gdisp->shell->window,
NULL, wilber_pixmap, wilber_mask);
}
gdisp->icon_needs_update = 0;
gdk_gc_unref (icongc);
gdk_gc_unref (iconmaskgc);
temp_buf_free (icondata);
}
void
gdisplay_draw_guides (GDisplay *gdisp)
{
@ -2421,6 +2544,7 @@ gdisplay_cleandirty_handler (GimpImage *gimage,
GDisplay *gdisp = data;
gdisplay_update_title (gdisp);
gdisp->icon_needs_update = 1;
}
void

View File

@ -121,6 +121,11 @@ struct _GDisplay
GtkAdjustment *hsbdata; /* horizontal data information */
GtkAdjustment *vsbdata; /* vertical data information */
GdkPixmap *icon; /* Pixmap for the icon */
GdkBitmap *iconmask; /* Bitmap for the icon mask */
guint iconsize; /* The size of the icon pixmap */
guint icon_needs_update; /* Do we need to render a new icon? */
GimpImage *gimage; /* pointer to the associated gimage struct */
gint instance; /* the instance # of this gdisplay as */
/* taken from the gimage at creation */
@ -208,6 +213,7 @@ void gdisplay_expose_guide (GDisplay *, Guide *);
void gdisplay_expose_full (GDisplay *);
void gdisplay_flush (GDisplay *);
void gdisplay_flush_now (GDisplay *);
void gdisplay_update_icon (GDisplay *);
void gdisplay_draw_guides (GDisplay *);
void gdisplay_draw_guide (GDisplay *, Guide *, gboolean);
Guide* gdisplay_find_guide (GDisplay *, gdouble, double);

View File

@ -415,6 +415,17 @@ create_display_shell (GDisplay *gdisp,
&navbutton_mask,
&style->bg[GTK_STATE_NORMAL],
navbutton_xpm);
/* Icon stuff */
gdisp->iconsize = 32;
gdisp->icon = gdk_pixmap_new (gdisp->shell->window,
gdisp->iconsize,
gdisp->iconsize,
-1);
gdisp->iconmask = gdk_pixmap_new (NULL,
gdisp->iconsize,
gdisp->iconsize,
1);
gdisp->icon_needs_update = 1;
}
/* create the GtkPixmaps */