fix to properly queue resizes when the image is set
2001-04-18 Havoc Pennington <hp@redhat.com> * gtk/gtkimage.c: fix to properly queue resizes when the image is set * gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste if the insertion point isn't editable * demos/gtk-demo/images.c: Added a GtkImage demo * demos/gtk-demo/drawingarea.c: drawing area demo * demos/gtk-demo/menus.c (create_menu): cleanups 2001-04-18 Havoc Pennington <hp@redhat.com> * gdk-pixbuf.c (gdk_pixbuf_fill): Function to fill pixbuf with a given color.


14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: fix to properly queue resizes when the image is
|
||||||
|
set
|
||||||
|
|
||||||
|
* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
|
||||||
|
if the insertion point isn't editable
|
||||||
|
|
||||||
|
* demos/gtk-demo/images.c: Added a GtkImage demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/drawingarea.c: drawing area demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/menus.c (create_menu): cleanups
|
||||||
|
|
||||||
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: fix to properly queue resizes when the image is
|
||||||
|
set
|
||||||
|
|
||||||
|
* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
|
||||||
|
if the insertion point isn't editable
|
||||||
|
|
||||||
|
* demos/gtk-demo/images.c: Added a GtkImage demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/drawingarea.c: drawing area demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/menus.c (create_menu): cleanups
|
||||||
|
|
||||||
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: fix to properly queue resizes when the image is
|
||||||
|
set
|
||||||
|
|
||||||
|
* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
|
||||||
|
if the insertion point isn't editable
|
||||||
|
|
||||||
|
* demos/gtk-demo/images.c: Added a GtkImage demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/drawingarea.c: drawing area demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/menus.c (create_menu): cleanups
|
||||||
|
|
||||||
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: fix to properly queue resizes when the image is
|
||||||
|
set
|
||||||
|
|
||||||
|
* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
|
||||||
|
if the insertion point isn't editable
|
||||||
|
|
||||||
|
* demos/gtk-demo/images.c: Added a GtkImage demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/drawingarea.c: drawing area demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/menus.c (create_menu): cleanups
|
||||||
|
|
||||||
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: fix to properly queue resizes when the image is
|
||||||
|
set
|
||||||
|
|
||||||
|
* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
|
||||||
|
if the insertion point isn't editable
|
||||||
|
|
||||||
|
* demos/gtk-demo/images.c: Added a GtkImage demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/drawingarea.c: drawing area demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/menus.c (create_menu): cleanups
|
||||||
|
|
||||||
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: fix to properly queue resizes when the image is
|
||||||
|
set
|
||||||
|
|
||||||
|
* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
|
||||||
|
if the insertion point isn't editable
|
||||||
|
|
||||||
|
* demos/gtk-demo/images.c: Added a GtkImage demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/drawingarea.c: drawing area demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/menus.c (create_menu): cleanups
|
||||||
|
|
||||||
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: fix to properly queue resizes when the image is
|
||||||
|
set
|
||||||
|
|
||||||
|
* gtk/gtktextview.c (gtk_text_view_do_popup): desensitize Paste
|
||||||
|
if the insertion point isn't editable
|
||||||
|
|
||||||
|
* demos/gtk-demo/images.c: Added a GtkImage demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/drawingarea.c: drawing area demo
|
||||||
|
|
||||||
|
* demos/gtk-demo/menus.c (create_menu): cleanups
|
||||||
|
|
||||||
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
Wed Apr 18 12:15:52 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
* gdk/x11/gdkwindow-x11.c gdk/x11/gdkwindow-x11.h
|
||||||
|
@ -2,12 +2,17 @@
|
|||||||
|
|
||||||
democodedir=$(datadir)/gtk-2.0/demo
|
democodedir=$(datadir)/gtk-2.0/demo
|
||||||
|
|
||||||
|
## These should be in the order you want them to appear in the
|
||||||
|
## demo app, which means alphabetized by demo title, not filename
|
||||||
demos = @STRIP_BEGIN@ \
|
demos = @STRIP_BEGIN@ \
|
||||||
button_box.c \
|
button_box.c \
|
||||||
|
dialog.c \
|
||||||
|
drawingarea.c \
|
||||||
|
images.c \
|
||||||
item_factory.c \
|
item_factory.c \
|
||||||
menus.c \
|
menus.c \
|
||||||
panes.c \
|
panes.c \
|
||||||
dialog.c \
|
pixbufs.c \
|
||||||
textview.c \
|
textview.c \
|
||||||
@STRIP_END@
|
@STRIP_END@
|
||||||
|
|
||||||
@ -63,4 +68,17 @@ gtk_demo_SOURCES = \
|
|||||||
gtk_demo_DEPENDENCIES = $(DEPS)
|
gtk_demo_DEPENDENCIES = $(DEPS)
|
||||||
gtk_demo_LDADD = $(LDADDS)
|
gtk_demo_LDADD = $(LDADDS)
|
||||||
|
|
||||||
democode_DATA = $(demos)
|
IMAGEFILES= apple-red.png \
|
||||||
|
background.jpg \
|
||||||
|
gnome-applets.png \
|
||||||
|
gnome-calendar.png \
|
||||||
|
gnome-foot.png \
|
||||||
|
gnome-gimp.png \
|
||||||
|
gnome-gmush.png \
|
||||||
|
gnome-gsame.png \
|
||||||
|
gnu-keys.png \
|
||||||
|
gtk-logo-rgb.gif
|
||||||
|
|
||||||
|
democode_DATA = $(demos) $(IMAGEFILES)
|
||||||
|
|
||||||
|
EXTRA_DIST = $(IMAGEFILES)
|
||||||
|
BIN
demos/gtk-demo/apple-red.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
demos/gtk-demo/background.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
322
demos/gtk-demo/drawingarea.c
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/* Drawing Area
|
||||||
|
*
|
||||||
|
* GtkDrawingArea is a blank area where you can draw custom displays
|
||||||
|
* of various kinds.
|
||||||
|
*
|
||||||
|
* This demo has two drawing areas. The checkerboard area shows
|
||||||
|
* how you can just draw something; all you have to do is write
|
||||||
|
* a signal handler for expose_event, as shown here.
|
||||||
|
*
|
||||||
|
* The "scribble" area is a bit more advanced, and shows how to handle
|
||||||
|
* events such as button presses and mouse motion. Click the mouse
|
||||||
|
* and drag in the scribble area to draw squiggles. Resize the window
|
||||||
|
* to clear the area.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
/* Pixmap for scribble area, to store current scribbles */
|
||||||
|
static GdkPixmap *pixmap = NULL;
|
||||||
|
|
||||||
|
/* Create a new pixmap of the appropriate size to store our scribbles */
|
||||||
|
static gboolean
|
||||||
|
scribble_configure_event (GtkWidget *widget,
|
||||||
|
GdkEventConfigure *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (pixmap)
|
||||||
|
g_object_unref (G_OBJECT (pixmap));
|
||||||
|
|
||||||
|
pixmap = gdk_pixmap_new (widget->window,
|
||||||
|
widget->allocation.width,
|
||||||
|
widget->allocation.height,
|
||||||
|
-1);
|
||||||
|
|
||||||
|
/* Initialize the pixmap to white */
|
||||||
|
gdk_draw_rectangle (pixmap,
|
||||||
|
widget->style->white_gc,
|
||||||
|
TRUE,
|
||||||
|
0, 0,
|
||||||
|
widget->allocation.width,
|
||||||
|
widget->allocation.height);
|
||||||
|
|
||||||
|
/* We've handled the configure event, no need for further processing. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Redraw the screen from the pixmap */
|
||||||
|
static gboolean
|
||||||
|
scribble_expose_event (GtkWidget *widget,
|
||||||
|
GdkEventExpose *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
/* We use the "foreground GC" for the widget since it already exists,
|
||||||
|
* but honestly any GC would work. The only thing to worry about
|
||||||
|
* is whether the GC has an inappropriate clip region set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gdk_draw_drawable (widget->window,
|
||||||
|
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
|
||||||
|
pixmap,
|
||||||
|
/* Only copy the area that was exposed. */
|
||||||
|
event->area.x, event->area.y,
|
||||||
|
event->area.x, event->area.y,
|
||||||
|
event->area.width, event->area.height);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a rectangle on the screen */
|
||||||
|
static void
|
||||||
|
draw_brush (GtkWidget *widget,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y)
|
||||||
|
{
|
||||||
|
GdkRectangle update_rect;
|
||||||
|
|
||||||
|
update_rect.x = x - 3;
|
||||||
|
update_rect.y = y - 3;
|
||||||
|
update_rect.width = 6;
|
||||||
|
update_rect.height = 6;
|
||||||
|
|
||||||
|
/* Paint to the pixmap, where we store our state */
|
||||||
|
gdk_draw_rectangle (pixmap,
|
||||||
|
widget->style->black_gc,
|
||||||
|
TRUE,
|
||||||
|
update_rect.x, update_rect.y,
|
||||||
|
update_rect.width, update_rect.height);
|
||||||
|
|
||||||
|
/* Now invalidate the affected region of the drawing area. */
|
||||||
|
gdk_window_invalidate_rect (widget->window,
|
||||||
|
&update_rect,
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
scribble_button_press_event (GtkWidget *widget,
|
||||||
|
GdkEventButton *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (pixmap == NULL)
|
||||||
|
return FALSE; /* paranoia check, in case we haven't gotten a configure event */
|
||||||
|
|
||||||
|
if (event->button == 1)
|
||||||
|
draw_brush (widget, event->x, event->y);
|
||||||
|
|
||||||
|
/* We've handled the event, stop processing */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
scribble_motion_notify_event (GtkWidget *widget,
|
||||||
|
GdkEventMotion *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
GdkModifierType state;
|
||||||
|
|
||||||
|
if (pixmap == NULL)
|
||||||
|
return FALSE; /* paranoia check, in case we haven't gotten a configure event */
|
||||||
|
|
||||||
|
/* This call is very important; it requests the next motion event.
|
||||||
|
* If you don't call gdk_window_get_pointer() you'll only get
|
||||||
|
* a single motion event. The reason is that we specified
|
||||||
|
* GDK_POINTER_MOTION_HINT_MASK to gtk_widget_set_events().
|
||||||
|
* If we hadn't specified that, we could just use event->x, event->y
|
||||||
|
* as the pointer location. But we'd also get deluged in events.
|
||||||
|
* By requesting the next event as we handle the current one,
|
||||||
|
* we avoid getting a huge number of events faster than we
|
||||||
|
* can cope.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gdk_window_get_pointer (event->window, &x, &y, &state);
|
||||||
|
|
||||||
|
if (state & GDK_BUTTON1_MASK)
|
||||||
|
draw_brush (widget, x, y);
|
||||||
|
|
||||||
|
/* We've handled it, stop processing */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
checkerboard_expose (GtkWidget *da,
|
||||||
|
GdkEventExpose *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
gint i, j, xcount, ycount;
|
||||||
|
GdkGC *gc1, *gc2;
|
||||||
|
GdkColor color;
|
||||||
|
|
||||||
|
#define CHECK_SIZE 10
|
||||||
|
#define SPACING 2
|
||||||
|
|
||||||
|
/* At the start of an expose handler, a clip region of event->area
|
||||||
|
* is set on the window, and event->area has been cleared to the
|
||||||
|
* widget's background color. The docs for
|
||||||
|
* gdk_window_begin_paint_region() give more details on how this
|
||||||
|
* works.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* It would be a bit more efficient to keep these
|
||||||
|
* GC's around instead of recreating on each expose, but
|
||||||
|
* this is the lazy/slow way.
|
||||||
|
*/
|
||||||
|
gc1 = gdk_gc_new (da->window);
|
||||||
|
color.red = 30000;
|
||||||
|
color.green = 0;
|
||||||
|
color.blue = 30000;
|
||||||
|
gdk_gc_set_rgb_fg_color (gc1, &color);
|
||||||
|
|
||||||
|
gc2 = gdk_gc_new (da->window);
|
||||||
|
color.red = 65535;
|
||||||
|
color.green = 65535;
|
||||||
|
color.blue = 65535;
|
||||||
|
gdk_gc_set_rgb_fg_color (gc2, &color);
|
||||||
|
|
||||||
|
xcount = 0;
|
||||||
|
i = SPACING;
|
||||||
|
while (i < da->allocation.width)
|
||||||
|
{
|
||||||
|
j = SPACING;
|
||||||
|
ycount = xcount % 2; /* start with even/odd depending on row */
|
||||||
|
while (j < da->allocation.height)
|
||||||
|
{
|
||||||
|
GdkGC *gc;
|
||||||
|
|
||||||
|
if (ycount % 2)
|
||||||
|
gc = gc1;
|
||||||
|
else
|
||||||
|
gc = gc2;
|
||||||
|
|
||||||
|
/* If we're outside event->area, this will do nothing.
|
||||||
|
* It might be mildly more efficient if we handled
|
||||||
|
* the clipping ourselves, but again we're feeling lazy.
|
||||||
|
*/
|
||||||
|
gdk_draw_rectangle (da->window,
|
||||||
|
gc,
|
||||||
|
TRUE,
|
||||||
|
i, j,
|
||||||
|
CHECK_SIZE,
|
||||||
|
CHECK_SIZE);
|
||||||
|
|
||||||
|
j += CHECK_SIZE + SPACING;
|
||||||
|
++ycount;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += CHECK_SIZE + SPACING;
|
||||||
|
++xcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (gc1));
|
||||||
|
g_object_unref (G_OBJECT (gc2));
|
||||||
|
|
||||||
|
/* return TRUE because we've handled this event, so no
|
||||||
|
* further processing is required.
|
||||||
|
*/
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_drawingarea (void)
|
||||||
|
{
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *da;
|
||||||
|
GtkWidget *label;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Drawing Area");
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
|
||||||
|
|
||||||
|
vbox = gtk_vbox_new (FALSE, 8);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the checkerboard area
|
||||||
|
*/
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Checkerboard pattern</u>");
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
da = gtk_drawing_area_new ();
|
||||||
|
/* set a minimum size */
|
||||||
|
gtk_widget_set_usize (da, 100, 100);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (da),
|
||||||
|
"expose_event",
|
||||||
|
GTK_SIGNAL_FUNC (checkerboard_expose),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the scribble area
|
||||||
|
*/
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Scribble area</u>");
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
da = gtk_drawing_area_new ();
|
||||||
|
/* set a minimum size */
|
||||||
|
gtk_widget_set_usize (da, 100, 100);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||||
|
|
||||||
|
/* Signals used to handle backing pixmap */
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (da), "expose_event",
|
||||||
|
GTK_SIGNAL_FUNC (scribble_expose_event), NULL);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (da),"configure_event",
|
||||||
|
GTK_SIGNAL_FUNC (scribble_configure_event), NULL);
|
||||||
|
|
||||||
|
/* Event signals */
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (da), "motion_notify_event",
|
||||||
|
GTK_SIGNAL_FUNC (scribble_motion_notify_event), NULL);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (da), "button_press_event",
|
||||||
|
GTK_SIGNAL_FUNC (scribble_button_press_event), NULL);
|
||||||
|
|
||||||
|
|
||||||
|
/* Ask to receive events the drawing area doesn't normally
|
||||||
|
* subscribe to
|
||||||
|
*/
|
||||||
|
gtk_widget_set_events (da, gtk_widget_get_events (da)
|
||||||
|
| GDK_LEAVE_NOTIFY_MASK
|
||||||
|
| GDK_BUTTON_PRESS_MASK
|
||||||
|
| GDK_POINTER_MOTION_MASK
|
||||||
|
| GDK_POINTER_MOTION_HINT_MASK);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GTK_WIDGET_VISIBLE (window))
|
||||||
|
{
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
BIN
demos/gtk-demo/gnome-applets.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
demos/gtk-demo/gnome-calendar.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
demos/gtk-demo/gnome-foot.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
demos/gtk-demo/gnome-gimp.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
demos/gtk-demo/gnome-gmush.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
demos/gtk-demo/gnome-gsame.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
demos/gtk-demo/gnu-keys.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
demos/gtk-demo/gtk-logo-rgb.gif
Normal file
After Width: | Height: | Size: 6.3 KiB |
396
demos/gtk-demo/images.c
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
/* Images
|
||||||
|
*
|
||||||
|
* GtkImage is used to display an image; the image can be in a number of formats.
|
||||||
|
* Typically, you load an image into a GdkPixbuf, then display the pixbuf.
|
||||||
|
*
|
||||||
|
* This demo code shows some of the more obscure cases, in the simple
|
||||||
|
* case a call to gtk_image_new_from_file() is all you need.
|
||||||
|
*
|
||||||
|
* If you want to put image data in your program as a C variable,
|
||||||
|
* use the make-inline-pixbuf program that comes with GTK+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
static GdkPixbufLoader *pixbuf_loader = NULL;
|
||||||
|
static guint load_timeout = 0;
|
||||||
|
static FILE* image_stream = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
progressive_prepared_callback (GdkPixbufLoader* loader, gpointer data)
|
||||||
|
{
|
||||||
|
GdkPixbuf* pixbuf;
|
||||||
|
GtkWidget* image;
|
||||||
|
|
||||||
|
image = GTK_WIDGET (data);
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||||
|
|
||||||
|
/* Avoid displaying random memory contents, since the pixbuf
|
||||||
|
* isn't filled in yet.
|
||||||
|
*/
|
||||||
|
gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
|
||||||
|
|
||||||
|
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
progressive_updated_callback (GdkPixbufLoader* loader,
|
||||||
|
guint x, guint y, guint width, guint height,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkWidget* image;
|
||||||
|
|
||||||
|
image = GTK_WIDGET (data);
|
||||||
|
|
||||||
|
/* We know the pixbuf inside the image has changed, but the image
|
||||||
|
* itself doesn't know this; so queue a redraw. If we wanted to be
|
||||||
|
* really efficient, we could use a drawing area or something
|
||||||
|
* instead of a GtkImage, so we could control the exact position of
|
||||||
|
* the pixbuf on the display, then we could queue a draw for only
|
||||||
|
* the updated area of the image.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gtk_widget_queue_draw (image);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
progressive_timeout (gpointer data)
|
||||||
|
{
|
||||||
|
GtkWidget *image;
|
||||||
|
|
||||||
|
image = GTK_WIDGET (data);
|
||||||
|
|
||||||
|
/* This shows off fully-paranoid error handling, so looks scary.
|
||||||
|
* You could factor out the error handling code into a nice separate
|
||||||
|
* function to make things nicer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (image_stream)
|
||||||
|
{
|
||||||
|
size_t bytes_read;
|
||||||
|
guchar buf[256];
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
bytes_read = fread (buf, 1, 256, image_stream);
|
||||||
|
|
||||||
|
if (ferror (image_stream))
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"Failure reading image file 'gtk-logo-rgb.gif': %s",
|
||||||
|
g_strerror (errno));
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_destroy),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
fclose (image_stream);
|
||||||
|
image_stream = NULL;
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
|
||||||
|
load_timeout = 0;
|
||||||
|
|
||||||
|
return FALSE; /* uninstall the timeout */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gdk_pixbuf_loader_write (pixbuf_loader,
|
||||||
|
buf, bytes_read,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"Failed to load image: %s",
|
||||||
|
error->message);
|
||||||
|
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_destroy),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
fclose (image_stream);
|
||||||
|
image_stream = NULL;
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
|
||||||
|
load_timeout = 0;
|
||||||
|
|
||||||
|
return FALSE; /* uninstall the timeout */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feof (image_stream))
|
||||||
|
{
|
||||||
|
fclose (image_stream);
|
||||||
|
image_stream = NULL;
|
||||||
|
|
||||||
|
/* Errors can happen on close, e.g. if the image
|
||||||
|
* file was truncated we'll know on close that
|
||||||
|
* it was incomplete.
|
||||||
|
*/
|
||||||
|
error = NULL;
|
||||||
|
if (!gdk_pixbuf_loader_close (pixbuf_loader,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"Failed to load image: %s",
|
||||||
|
error->message);
|
||||||
|
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_destroy),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (pixbuf_loader));
|
||||||
|
pixbuf_loader = NULL;
|
||||||
|
|
||||||
|
load_timeout = 0;
|
||||||
|
|
||||||
|
return FALSE; /* uninstall the timeout */
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (pixbuf_loader));
|
||||||
|
pixbuf_loader = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const gchar *filename;
|
||||||
|
|
||||||
|
if (g_file_test ("./gtk-logo-rgb.gif", G_FILE_TEST_EXISTS))
|
||||||
|
filename = "./gtk-logo-rgb.gif";
|
||||||
|
else
|
||||||
|
filename = DEMOCODEDIR"/gtk-log-rgb.gif";
|
||||||
|
|
||||||
|
image_stream = fopen (filename, "r");
|
||||||
|
|
||||||
|
if (image_stream == NULL)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"Unable to open image file 'gtk-logo-rgb.gif': %s",
|
||||||
|
g_strerror (errno));
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_destroy),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
|
||||||
|
load_timeout = 0;
|
||||||
|
|
||||||
|
return FALSE; /* uninstall the timeout */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixbuf_loader)
|
||||||
|
{
|
||||||
|
gdk_pixbuf_loader_close (pixbuf_loader, NULL);
|
||||||
|
g_object_unref (G_OBJECT (pixbuf_loader));
|
||||||
|
pixbuf_loader = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixbuf_loader = gdk_pixbuf_loader_new ();
|
||||||
|
|
||||||
|
g_signal_connect_data (G_OBJECT (pixbuf_loader),
|
||||||
|
"area_prepared",
|
||||||
|
G_CALLBACK (progressive_prepared_callback),
|
||||||
|
image,
|
||||||
|
NULL, FALSE, FALSE);
|
||||||
|
|
||||||
|
g_signal_connect_data (G_OBJECT (pixbuf_loader),
|
||||||
|
"area_updated",
|
||||||
|
G_CALLBACK (progressive_updated_callback),
|
||||||
|
image,
|
||||||
|
NULL, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* leave timeout installed */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_progressive_loading (GtkWidget *image)
|
||||||
|
{
|
||||||
|
/* This is obviously totally contrived (we slow down loading
|
||||||
|
* on purpose to show how incremental loading works).
|
||||||
|
* The real purpose of incremental loading is the case where
|
||||||
|
* you are reading data from a slow source such as the network.
|
||||||
|
* The timeout simply simulates a slow data source by inserting
|
||||||
|
* pauses in the reading process.
|
||||||
|
*/
|
||||||
|
load_timeout = g_timeout_add (300,
|
||||||
|
progressive_timeout,
|
||||||
|
image);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup_callback (GtkObject *object,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (load_timeout)
|
||||||
|
{
|
||||||
|
g_source_remove (load_timeout);
|
||||||
|
load_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixbuf_loader)
|
||||||
|
{
|
||||||
|
gdk_pixbuf_loader_close (pixbuf_loader, NULL);
|
||||||
|
g_object_unref (G_OBJECT (pixbuf_loader));
|
||||||
|
pixbuf_loader = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image_stream)
|
||||||
|
fclose (image_stream);
|
||||||
|
image_stream = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_images (void)
|
||||||
|
{
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *image;
|
||||||
|
GtkWidget *label;
|
||||||
|
GtkWidget *align;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Images");
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (cleanup_callback), NULL);
|
||||||
|
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
|
||||||
|
|
||||||
|
vbox = gtk_vbox_new (FALSE, 8);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Image loaded from a file</u>");
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
/* The alignment keeps the frame from growing when users resize
|
||||||
|
* the window
|
||||||
|
*/
|
||||||
|
align = gtk_alignment_new (0.5, 0.5, 0, 0);
|
||||||
|
gtk_container_add (GTK_CONTAINER (align), frame);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
/* We look for the image in the current directory first,
|
||||||
|
* so you can run gtk-demo without installing GTK
|
||||||
|
*/
|
||||||
|
if (g_file_test ("./gtk-logo-rgb.gif", G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
/* This code shows off error handling. You can just use
|
||||||
|
* gtk_image_new_from_file() instead if you don't want to report
|
||||||
|
* errors to the user. If the file doesn't load when using
|
||||||
|
* gtk_image_new_from_file(), a "missing image" icon will
|
||||||
|
* be displayed instead.
|
||||||
|
*/
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_new_from_file ("./gtk-logo-rgb.gif",
|
||||||
|
&error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"Unable to open image file 'gtk-logo-rgb.gif': %s",
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_destroy),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
image = gtk_image_new_from_pixbuf (pixbuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is the simpler code, with no error handling.
|
||||||
|
* Here we're loading the installed gtk-logo-rgb.gif instead
|
||||||
|
* of the one in the current directory.
|
||||||
|
*/
|
||||||
|
image = gtk_image_new_from_file (DEMOCODEDIR"/gtk-logo-rgb.gif");
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Progressive image loading</u>");
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
/* The alignment keeps the frame from growing when users resize
|
||||||
|
* the window
|
||||||
|
*/
|
||||||
|
align = gtk_alignment_new (0.5, 0.5, 0, 0);
|
||||||
|
gtk_container_add (GTK_CONTAINER (align), frame);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
/* Create an empty image for now; the progressive loader
|
||||||
|
* will create the pixbuf and fill it in.
|
||||||
|
*/
|
||||||
|
image = gtk_image_new_from_pixbuf (NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||||
|
|
||||||
|
start_progressive_loading (image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GTK_WIDGET_VISIBLE (window))
|
||||||
|
{
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
@ -299,16 +299,18 @@ button_press_event_cb (GtkTreeView *tree_view,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
void
|
||||||
row_activated_cb (GtkTreeView *tree_view,
|
row_activated_cb (GtkTreeView *tree_view,
|
||||||
GtkTreePath *path,
|
GtkTreePath *path,
|
||||||
GtkTreeViewColumn *column,
|
GtkTreeViewColumn *column)
|
||||||
GtkTreeModel *model)
|
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
gboolean italic;
|
gboolean italic;
|
||||||
GDoDemoFunc func;
|
GDoDemoFunc func;
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
|
||||||
|
model = gtk_tree_view_get_model (tree_view);
|
||||||
|
|
||||||
gtk_tree_model_get_iter (model, &iter, path);
|
gtk_tree_model_get_iter (model, &iter, path);
|
||||||
gtk_tree_model_get (GTK_TREE_MODEL (model),
|
gtk_tree_model_get (GTK_TREE_MODEL (model),
|
||||||
@ -321,6 +323,7 @@ row_activated_cb (GtkTreeView *tree_view,
|
|||||||
ITALIC_COLUMN, !italic,
|
ITALIC_COLUMN, !italic,
|
||||||
-1);
|
-1);
|
||||||
window = (func) ();
|
window = (func) ();
|
||||||
|
|
||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
{
|
{
|
||||||
CallbackData *cbdata;
|
CallbackData *cbdata;
|
||||||
@ -334,10 +337,6 @@ row_activated_cb (GtkTreeView *tree_view,
|
|||||||
window_closed_cb,
|
window_closed_cb,
|
||||||
cbdata);
|
cbdata);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
gtk_tree_path_free (path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -385,9 +384,20 @@ create_text (GtkTextBuffer **buffer,
|
|||||||
font_desc = pango_font_description_from_string ("Courier 10");
|
font_desc = pango_font_description_from_string ("Courier 10");
|
||||||
gtk_widget_modify_font (text_view, font_desc);
|
gtk_widget_modify_font (text_view, font_desc);
|
||||||
pango_font_description_free (font_desc);
|
pango_font_description_free (font_desc);
|
||||||
}
|
|
||||||
|
|
||||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), !is_source);
|
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view),
|
||||||
|
GTK_WRAP_NONE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Make it a bit nicer for text. */
|
||||||
|
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view),
|
||||||
|
GTK_WRAP_WORD);
|
||||||
|
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (text_view),
|
||||||
|
2);
|
||||||
|
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (text_view),
|
||||||
|
2);
|
||||||
|
}
|
||||||
|
|
||||||
return scrolled_window;
|
return scrolled_window;
|
||||||
}
|
}
|
||||||
@ -458,6 +468,7 @@ main (int argc, char **argv)
|
|||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "GTK+ Code Demos");
|
||||||
gtk_signal_connect (GTK_OBJECT (window), "destroy",
|
gtk_signal_connect (GTK_OBJECT (window), "destroy",
|
||||||
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
|
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
|
||||||
|
|
||||||
|
@ -1,10 +1,31 @@
|
|||||||
/* Menus
|
/* Menus
|
||||||
*
|
*
|
||||||
* GTK+ includes a number of widgets for menus of actions.
|
* There are several widgets involved in displaying menus. The
|
||||||
* GtkMenu is a drop-down menu, GtkMenuBar a horizontal menu bar.
|
* GtkMenuBar widget is a horizontal menu bar, which normally appears
|
||||||
* Each of these widgets can hold various types of menuitem.
|
* at the top of an application. The GtkMenu widget is the actual menu
|
||||||
* As well as the base type, GtkMenuItem, there are GtkCheckMenuItem,
|
* that pops up. Both GtkMenuBar and GtkMenu are subclasses of
|
||||||
* GtkRadioMenuItem and GtkTearoffMenuItem.
|
* GtkMenuShell; a GtkMenuShell contains menu items
|
||||||
|
* (GtkMenuItem). Each menu item contains text and/or images and can
|
||||||
|
* be selected by the user.
|
||||||
|
*
|
||||||
|
* There are several kinds of menu item, including plain GtkMenuItem,
|
||||||
|
* GtkCheckMenuItem which can be checked/unchecked, GtkRadioMenuItem
|
||||||
|
* which is a check menu item that's in a mutually exclusive group,
|
||||||
|
* GtkSeparatorMenuItem which is a separator bar, GtkTearoffMenuItem
|
||||||
|
* which allows a GtkMenu to be torn off, and GtkImageMenuItem which
|
||||||
|
* can place a GtkImage or other widget next to the menu text.
|
||||||
|
*
|
||||||
|
* A GtkMenuItem can have a submenu, which is simply a GtkMenu to pop
|
||||||
|
* up when the menu item is selected. Typically, all menu items in a menu bar
|
||||||
|
* have submenus.
|
||||||
|
*
|
||||||
|
* The GtkOptionMenu widget is a button that pops up a GtkMenu when clicked.
|
||||||
|
* It's used inside dialogs and such.
|
||||||
|
*
|
||||||
|
* GtkItemFactory provides a higher-level interface for creating menu bars
|
||||||
|
* and menus; while you can construct menus manually, most people don't
|
||||||
|
* do that. There's a separate demo for GtkItemFactory.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -39,8 +60,7 @@ create_menu (gint depth, gboolean tearoff)
|
|||||||
sprintf (buf, "item %2d - %d", depth, j);
|
sprintf (buf, "item %2d - %d", depth, j);
|
||||||
menuitem = gtk_radio_menu_item_new_with_label (group, buf);
|
menuitem = gtk_radio_menu_item_new_with_label (group, buf);
|
||||||
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
|
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
|
||||||
if (depth % 2)
|
|
||||||
gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
|
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||||
gtk_widget_show (menuitem);
|
gtk_widget_show (menuitem);
|
||||||
if (i == 3)
|
if (i == 3)
|
||||||
|
277
demos/gtk-demo/pixbufs.c
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
/* Pixbufs
|
||||||
|
*
|
||||||
|
* A GdkPixbuf represents an image, normally in RGB or RGBA format.
|
||||||
|
* Pixbufs are normally used to load files from disk and perform
|
||||||
|
* image scaling.
|
||||||
|
*
|
||||||
|
* This demo is not all that educational, but looks cool. It was written
|
||||||
|
* by Extreme Pixbuf Hacker Federico Mena Quintero. It also shows
|
||||||
|
* off how to use GtkDrawingArea to do a simple animation.
|
||||||
|
*
|
||||||
|
* Look at the Image demo for additional pixbuf usage examples.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define FRAME_DELAY 50
|
||||||
|
|
||||||
|
#define RELATIVE_BACKGROUND_NAME "background.jpg"
|
||||||
|
#define INSTALLED_BACKGROUND_NAME DEMOCODEDIR"/background.jpg"
|
||||||
|
|
||||||
|
static const char *relative_image_names[] = {
|
||||||
|
"apple-red.png",
|
||||||
|
"gnome-applets.png",
|
||||||
|
"gnome-calendar.png",
|
||||||
|
"gnome-foot.png",
|
||||||
|
"gnome-gmush.png",
|
||||||
|
"gnome-gimp.png",
|
||||||
|
"gnome-gsame.png",
|
||||||
|
"gnu-keys.png"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *installed_image_names[] = {
|
||||||
|
DEMOCODEDIR"/apple-red.png",
|
||||||
|
DEMOCODEDIR"/gnome-applets.png",
|
||||||
|
DEMOCODEDIR"/gnome-calendar.png",
|
||||||
|
DEMOCODEDIR"/gnome-foot.png",
|
||||||
|
DEMOCODEDIR"/gnome-gmush.png",
|
||||||
|
DEMOCODEDIR"/gnome-gimp.png",
|
||||||
|
DEMOCODEDIR"/gnome-gsame.png",
|
||||||
|
DEMOCODEDIR"/gnu-keys.png"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define N_IMAGES G_N_ELEMENTS (relative_image_names)
|
||||||
|
|
||||||
|
/* demo window */
|
||||||
|
static GtkWindow *window = NULL;
|
||||||
|
|
||||||
|
/* Current frame */
|
||||||
|
static GdkPixbuf *frame;
|
||||||
|
|
||||||
|
/* Background image */
|
||||||
|
static GdkPixbuf *background;
|
||||||
|
static int back_width, back_height;
|
||||||
|
|
||||||
|
/* Images */
|
||||||
|
static GdkPixbuf *images[N_IMAGES];
|
||||||
|
|
||||||
|
/* Widgets */
|
||||||
|
static GtkWidget *da;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Loads the images for the demo and returns whether the operation succeeded */
|
||||||
|
static gboolean
|
||||||
|
load_pixbufs (GError **error)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char **image_names;
|
||||||
|
|
||||||
|
if (background)
|
||||||
|
return TRUE; /* already loaded earlier */
|
||||||
|
|
||||||
|
background = gdk_pixbuf_new_from_file (RELATIVE_BACKGROUND_NAME, NULL);
|
||||||
|
|
||||||
|
if (!background)
|
||||||
|
background = gdk_pixbuf_new_from_file (INSTALLED_BACKGROUND_NAME, error);
|
||||||
|
|
||||||
|
if (!background)
|
||||||
|
return FALSE; /* note that "error" was filled in and returned */
|
||||||
|
|
||||||
|
back_width = gdk_pixbuf_get_width (background);
|
||||||
|
back_height = gdk_pixbuf_get_height (background);
|
||||||
|
|
||||||
|
if (g_file_test (relative_image_names[0], G_FILE_TEST_EXISTS))
|
||||||
|
image_names = relative_image_names;
|
||||||
|
else
|
||||||
|
image_names = installed_image_names;
|
||||||
|
|
||||||
|
for (i = 0; i < N_IMAGES; i++)
|
||||||
|
{
|
||||||
|
images[i] = gdk_pixbuf_new_from_file (image_names[i], error);
|
||||||
|
if (!images[i])
|
||||||
|
return FALSE; /* Note that "error" was filled with a GError */
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expose callback for the drawing area */
|
||||||
|
static gint
|
||||||
|
expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||||
|
{
|
||||||
|
guchar *pixels;
|
||||||
|
int rowstride;
|
||||||
|
|
||||||
|
rowstride = gdk_pixbuf_get_rowstride (frame);
|
||||||
|
|
||||||
|
pixels = gdk_pixbuf_get_pixels (frame) + rowstride * event->area.y + event->area.x * 3;
|
||||||
|
|
||||||
|
gdk_draw_rgb_image_dithalign (widget->window,
|
||||||
|
widget->style->black_gc,
|
||||||
|
event->area.x, event->area.y,
|
||||||
|
event->area.width, event->area.height,
|
||||||
|
GDK_RGB_DITHER_NORMAL,
|
||||||
|
pixels, rowstride,
|
||||||
|
event->area.x, event->area.y);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CYCLE_LEN 60
|
||||||
|
|
||||||
|
static int frame_num;
|
||||||
|
|
||||||
|
/* Timeout handler to regenerate the frame */
|
||||||
|
static gint
|
||||||
|
timeout (gpointer data)
|
||||||
|
{
|
||||||
|
double f;
|
||||||
|
int i;
|
||||||
|
double xmid, ymid;
|
||||||
|
double radius;
|
||||||
|
|
||||||
|
gdk_pixbuf_copy_area (background, 0, 0, back_width, back_height,
|
||||||
|
frame, 0, 0);
|
||||||
|
|
||||||
|
f = (double) (frame_num % CYCLE_LEN) / CYCLE_LEN;
|
||||||
|
|
||||||
|
xmid = back_width / 2.0;
|
||||||
|
ymid = back_height / 2.0;
|
||||||
|
|
||||||
|
radius = MIN (xmid, ymid) / 2.0;
|
||||||
|
|
||||||
|
for (i = 0; i < N_IMAGES; i++)
|
||||||
|
{
|
||||||
|
double ang;
|
||||||
|
int xpos, ypos;
|
||||||
|
int iw, ih;
|
||||||
|
double r;
|
||||||
|
GdkRectangle r1, r2, dest;
|
||||||
|
double k;
|
||||||
|
|
||||||
|
ang = 2.0 * M_PI * (double) i / N_IMAGES - f * 2.0 * M_PI;
|
||||||
|
|
||||||
|
iw = gdk_pixbuf_get_width (images[i]);
|
||||||
|
ih = gdk_pixbuf_get_height (images[i]);
|
||||||
|
|
||||||
|
r = radius + (radius / 3.0) * sin (f * 2.0 * M_PI);
|
||||||
|
|
||||||
|
xpos = floor (xmid + r * cos (ang) - iw / 2.0 + 0.5);
|
||||||
|
ypos = floor (ymid + r * sin (ang) - ih / 2.0 + 0.5);
|
||||||
|
|
||||||
|
k = (i & 1) ? sin (f * 2.0 * M_PI) : cos (f * 2.0 * M_PI);
|
||||||
|
k = 2.0 * k * k;
|
||||||
|
k = MAX (0.25, k);
|
||||||
|
|
||||||
|
r1.x = xpos;
|
||||||
|
r1.y = ypos;
|
||||||
|
r1.width = iw * k;
|
||||||
|
r1.height = ih * k;
|
||||||
|
|
||||||
|
r2.x = 0;
|
||||||
|
r2.y = 0;
|
||||||
|
r2.width = back_width;
|
||||||
|
r2.height = back_height;
|
||||||
|
|
||||||
|
if (gdk_rectangle_intersect (&r1, &r2, &dest))
|
||||||
|
gdk_pixbuf_composite (images[i],
|
||||||
|
frame,
|
||||||
|
dest.x, dest.y,
|
||||||
|
dest.width, dest.height,
|
||||||
|
xpos, ypos,
|
||||||
|
k, k,
|
||||||
|
GDK_INTERP_NEAREST,
|
||||||
|
((i & 1)
|
||||||
|
? MAX (127, fabs (255 * sin (f * 2.0 * M_PI)))
|
||||||
|
: MAX (127, fabs (255 * cos (f * 2.0 * M_PI)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_queue_draw (da);
|
||||||
|
|
||||||
|
frame_num++;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint timeout_id;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup_callback (GtkObject *object,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
g_source_remove (timeout_id);
|
||||||
|
timeout_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_pixbufs (void)
|
||||||
|
{
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Pixbufs");
|
||||||
|
gtk_window_set_resizeable (GTK_WINDOW (window), FALSE);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (cleanup_callback), NULL);
|
||||||
|
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
if (!load_pixbufs (&error))
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"Failed to load an image: %s",
|
||||||
|
error->message);
|
||||||
|
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_destroy),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_set_usize (window, back_width, back_height);
|
||||||
|
|
||||||
|
frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
|
||||||
|
|
||||||
|
da = gtk_drawing_area_new ();
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (da), "expose_event",
|
||||||
|
GTK_SIGNAL_FUNC (expose_cb), NULL);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), da);
|
||||||
|
|
||||||
|
timeout_id = gtk_timeout_add (FRAME_DELAY, timeout, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GTK_WIDGET_VISIBLE (window))
|
||||||
|
{
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
@ -49,13 +49,13 @@ static GdkPixbuf *frame;
|
|||||||
|
|
||||||
/* Background image */
|
/* Background image */
|
||||||
static GdkPixbuf *background;
|
static GdkPixbuf *background;
|
||||||
int back_width, back_height;
|
static int back_width, back_height;
|
||||||
|
|
||||||
/* Images */
|
/* Images */
|
||||||
static GdkPixbuf *images[N_IMAGES];
|
static GdkPixbuf *images[N_IMAGES];
|
||||||
|
|
||||||
/* Widgets */
|
/* Widgets */
|
||||||
GtkWidget *da;
|
static GtkWidget *da;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -723,18 +723,6 @@ produce superscript and subscript.
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### ARG GtkTextView:justify ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### ARG GtkTextView:wrap-mode ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### SIGNAL GtkWidget::activate-mnemonic ##### -->
|
<!-- ##### SIGNAL GtkWidget::activate-mnemonic ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -496,6 +496,7 @@ This can later be composited together with other
|
|||||||
#GtkRcStyle structures to form a #GtkStyle.
|
#GtkRcStyle structures to form a #GtkStyle.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@parent_instance:
|
||||||
@name:
|
@name:
|
||||||
@bg_pixmap_name:
|
@bg_pixmap_name:
|
||||||
@font_desc:
|
@font_desc:
|
||||||
|
@ -660,6 +660,16 @@ types related to the text widget and how they work together.
|
|||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<!-- ##### ARG GtkTextView:wrap-mode ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<!-- ##### ARG GtkTextView:justify ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
<!-- ##### ARG GtkTextView:left-margin ##### -->
|
<!-- ##### ARG GtkTextView:left-margin ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2001-04-18 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gdk-pixbuf.c (gdk_pixbuf_fill): Function to fill pixbuf with a
|
||||||
|
given color.
|
||||||
|
|
||||||
Wed Apr 4 01:41:02 2001 Tim Janik <timj@gtk.org>
|
Wed Apr 4 01:41:02 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* pixops/Makefile.am (noinst_LTLIBRARIES): include $top_srcdir
|
* pixops/Makefile.am (noinst_LTLIBRARIES): include $top_srcdir
|
||||||
|
@ -409,6 +409,64 @@ gdk_pixbuf_error_quark (void)
|
|||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_fill:
|
||||||
|
* @pixbuf: a #GdkPixbuf
|
||||||
|
* @pixel: RGBA pixel to clear to (0xffffff00 is opaque white, 0x000000ff transparent black)
|
||||||
|
*
|
||||||
|
* Clears a pixbuf to the given RGBA value, converting the RGBA value into
|
||||||
|
* the pixbuf's pixel format. The alpha will be ignored if the pixbuf
|
||||||
|
* doesn't have an alpha channel.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gdk_pixbuf_fill (GdkPixbuf *pixbuf,
|
||||||
|
guint32 pixel)
|
||||||
|
{
|
||||||
|
guchar *pixels;
|
||||||
|
gboolean all_the_same = FALSE;
|
||||||
|
guint r, g, b, a;
|
||||||
|
|
||||||
|
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||||
|
|
||||||
|
pixels = pixbuf->pixels;
|
||||||
|
|
||||||
|
r = (pixel & 0xff000000) >> 24;
|
||||||
|
g = (pixel & 0x00ff0000) >> 16;
|
||||||
|
b = (pixel & 0x0000ff00) >> 8;
|
||||||
|
a = (pixel & 0x000000ff);
|
||||||
|
|
||||||
|
if (r == g && g == b) {
|
||||||
|
if (!pixbuf->has_alpha)
|
||||||
|
all_the_same = TRUE;
|
||||||
|
else
|
||||||
|
all_the_same = (r == a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_the_same) {
|
||||||
|
memset (pixels, r,
|
||||||
|
pixbuf->rowstride * pixbuf->height);
|
||||||
|
} else {
|
||||||
|
guchar *p;
|
||||||
|
guchar *end;
|
||||||
|
|
||||||
|
/* feel free to optimize this */
|
||||||
|
|
||||||
|
p = pixels;
|
||||||
|
end = pixels + pixbuf->rowstride * pixbuf->height;
|
||||||
|
end -= (pixbuf->rowstride - pixbuf->width);
|
||||||
|
|
||||||
|
while (p < end) {
|
||||||
|
*p++ = r;
|
||||||
|
*p++ = g;
|
||||||
|
*p++ = b;
|
||||||
|
if (pixbuf->has_alpha)
|
||||||
|
*p++ = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Include the marshallers */
|
/* Include the marshallers */
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include "gdk-pixbuf-marshal.c"
|
#include "gdk-pixbuf-marshal.c"
|
||||||
|
@ -145,6 +145,9 @@ GdkPixbuf *gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf,
|
|||||||
int length,
|
int length,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/* Mutations */
|
||||||
|
void gdk_pixbuf_fill (GdkPixbuf *pixbuf,
|
||||||
|
guint32 pixel);
|
||||||
|
|
||||||
/* Saving */
|
/* Saving */
|
||||||
|
|
||||||
|
@ -935,11 +935,7 @@ gtk_image_reset (GtkImage *image)
|
|||||||
{
|
{
|
||||||
gtk_image_clear (image);
|
gtk_image_clear (image);
|
||||||
|
|
||||||
GTK_WIDGET (image)->requisition.width = 0;
|
gtk_image_update_size (image, 0, 0);
|
||||||
GTK_WIDGET (image)->requisition.height = 0;
|
|
||||||
|
|
||||||
if (GTK_WIDGET_VISIBLE (image))
|
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (image));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -951,6 +947,12 @@ gtk_image_size_request (GtkWidget *widget,
|
|||||||
|
|
||||||
image = GTK_IMAGE (widget);
|
image = GTK_IMAGE (widget);
|
||||||
|
|
||||||
|
/* We update stock/icon set on every size request, because
|
||||||
|
* the theme could have affected the size; for other kinds of
|
||||||
|
* image, we just update the requisition when the image data
|
||||||
|
* is set.
|
||||||
|
*/
|
||||||
|
|
||||||
switch (image->storage_type)
|
switch (image->storage_type)
|
||||||
{
|
{
|
||||||
case GTK_IMAGE_STOCK:
|
case GTK_IMAGE_STOCK:
|
||||||
@ -976,9 +978,9 @@ gtk_image_size_request (GtkWidget *widget,
|
|||||||
|
|
||||||
if (pixbuf)
|
if (pixbuf)
|
||||||
{
|
{
|
||||||
gtk_image_update_size (image,
|
GTK_WIDGET (image)->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
|
||||||
gdk_pixbuf_get_width (pixbuf),
|
GTK_WIDGET (image)->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
|
||||||
gdk_pixbuf_get_height (pixbuf));
|
|
||||||
g_object_unref (G_OBJECT (pixbuf));
|
g_object_unref (G_OBJECT (pixbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,6 +995,9 @@ gtk_image_update_size (GtkImage *image,
|
|||||||
{
|
{
|
||||||
GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
|
GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
|
||||||
GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
|
GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
|
||||||
|
|
||||||
|
if (GTK_WIDGET_VISIBLE (image))
|
||||||
|
gtk_widget_queue_resize (GTK_WIDGET (image));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4970,6 +4970,8 @@ gtk_text_view_do_popup (GtkTextView *text_view,
|
|||||||
GtkWidget *menuitem;
|
GtkWidget *menuitem;
|
||||||
GtkWidget *submenu;
|
GtkWidget *submenu;
|
||||||
gboolean have_selection;
|
gboolean have_selection;
|
||||||
|
gboolean can_insert;
|
||||||
|
GtkTextIter iter;
|
||||||
|
|
||||||
if (text_view->popup_menu)
|
if (text_view->popup_menu)
|
||||||
gtk_widget_destroy (text_view->popup_menu);
|
gtk_widget_destroy (text_view->popup_menu);
|
||||||
@ -4983,12 +4985,19 @@ gtk_text_view_do_popup (GtkTextView *text_view,
|
|||||||
have_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view),
|
have_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view),
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
|
gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
|
||||||
|
&iter,
|
||||||
|
gtk_text_buffer_get_insert (get_buffer (text_view)));
|
||||||
|
|
||||||
|
can_insert = gtk_text_iter_editable (&iter, text_view->editable);
|
||||||
|
|
||||||
append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard",
|
append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard",
|
||||||
have_selection);
|
have_selection);
|
||||||
append_action_signal (text_view, text_view->popup_menu, _("Copy"), "copy_clipboard",
|
append_action_signal (text_view, text_view->popup_menu, _("Copy"), "copy_clipboard",
|
||||||
have_selection);
|
have_selection);
|
||||||
|
|
||||||
append_action_signal (text_view, text_view->popup_menu, _("Paste"), "paste_clipboard",
|
append_action_signal (text_view, text_view->popup_menu, _("Paste"), "paste_clipboard",
|
||||||
TRUE);
|
can_insert);
|
||||||
|
|
||||||
menuitem = gtk_separator_menu_item_new ();
|
menuitem = gtk_separator_menu_item_new ();
|
||||||
gtk_widget_show (menuitem);
|
gtk_widget_show (menuitem);
|
||||||
|