use _gdk_region_get_xrectangles()

2001-03-02  Havoc Pennington  <hp@redhat.com>

	* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
	_gdk_region_get_xrectangles()

	* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function

	* gtk/testgtk.c (create_shapes): add test for shape_combine_region

	* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
	function, contributed by Ron Steinke

	* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
	gdk_net_wm_supports

	* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
	New function, contributed by Ron Steinke

	* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
	used to line up the text in the entry when using the entry for
	editable sheet cell hacks

	* gtk/testgtk.c (create_entry): test the activate_default setting
	on GtkEntry

	* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
	cause the entry to activate the default button for a dialog when
	activated
	(gtk_entry_get_activates_default): new function
This commit is contained in:
Havoc Pennington 2001-03-02 20:02:17 +00:00 committed by Havoc Pennington
parent b0052ec843
commit 8860615d9a
20 changed files with 766 additions and 85 deletions

View File

@ -1,3 +1,33 @@
2001-03-02 Havoc Pennington <hp@redhat.com>
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
_gdk_region_get_xrectangles()
* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function
* gtk/testgtk.c (create_shapes): add test for shape_combine_region
* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
function, contributed by Ron Steinke
* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
gdk_net_wm_supports
* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
New function, contributed by Ron Steinke
* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
used to line up the text in the entry when using the entry for
editable sheet cell hacks
* gtk/testgtk.c (create_entry): test the activate_default setting
on GtkEntry
* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
cause the entry to activate the default button for a dialog when
activated
(gtk_entry_get_activates_default): new function
Wed Feb 28 19:10:43 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclist.c (real_remove_row): Patch from ChiDeok

View File

@ -1,3 +1,33 @@
2001-03-02 Havoc Pennington <hp@redhat.com>
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
_gdk_region_get_xrectangles()
* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function
* gtk/testgtk.c (create_shapes): add test for shape_combine_region
* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
function, contributed by Ron Steinke
* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
gdk_net_wm_supports
* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
New function, contributed by Ron Steinke
* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
used to line up the text in the entry when using the entry for
editable sheet cell hacks
* gtk/testgtk.c (create_entry): test the activate_default setting
on GtkEntry
* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
cause the entry to activate the default button for a dialog when
activated
(gtk_entry_get_activates_default): new function
Wed Feb 28 19:10:43 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclist.c (real_remove_row): Patch from ChiDeok

View File

@ -1,3 +1,33 @@
2001-03-02 Havoc Pennington <hp@redhat.com>
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
_gdk_region_get_xrectangles()
* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function
* gtk/testgtk.c (create_shapes): add test for shape_combine_region
* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
function, contributed by Ron Steinke
* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
gdk_net_wm_supports
* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
New function, contributed by Ron Steinke
* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
used to line up the text in the entry when using the entry for
editable sheet cell hacks
* gtk/testgtk.c (create_entry): test the activate_default setting
on GtkEntry
* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
cause the entry to activate the default button for a dialog when
activated
(gtk_entry_get_activates_default): new function
Wed Feb 28 19:10:43 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclist.c (real_remove_row): Patch from ChiDeok

View File

@ -1,3 +1,33 @@
2001-03-02 Havoc Pennington <hp@redhat.com>
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
_gdk_region_get_xrectangles()
* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function
* gtk/testgtk.c (create_shapes): add test for shape_combine_region
* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
function, contributed by Ron Steinke
* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
gdk_net_wm_supports
* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
New function, contributed by Ron Steinke
* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
used to line up the text in the entry when using the entry for
editable sheet cell hacks
* gtk/testgtk.c (create_entry): test the activate_default setting
on GtkEntry
* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
cause the entry to activate the default button for a dialog when
activated
(gtk_entry_get_activates_default): new function
Wed Feb 28 19:10:43 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclist.c (real_remove_row): Patch from ChiDeok

View File

@ -1,3 +1,33 @@
2001-03-02 Havoc Pennington <hp@redhat.com>
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
_gdk_region_get_xrectangles()
* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function
* gtk/testgtk.c (create_shapes): add test for shape_combine_region
* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
function, contributed by Ron Steinke
* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
gdk_net_wm_supports
* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
New function, contributed by Ron Steinke
* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
used to line up the text in the entry when using the entry for
editable sheet cell hacks
* gtk/testgtk.c (create_entry): test the activate_default setting
on GtkEntry
* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
cause the entry to activate the default button for a dialog when
activated
(gtk_entry_get_activates_default): new function
Wed Feb 28 19:10:43 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclist.c (real_remove_row): Patch from ChiDeok

View File

@ -1,3 +1,33 @@
2001-03-02 Havoc Pennington <hp@redhat.com>
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
_gdk_region_get_xrectangles()
* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function
* gtk/testgtk.c (create_shapes): add test for shape_combine_region
* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
function, contributed by Ron Steinke
* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
gdk_net_wm_supports
* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
New function, contributed by Ron Steinke
* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
used to line up the text in the entry when using the entry for
editable sheet cell hacks
* gtk/testgtk.c (create_entry): test the activate_default setting
on GtkEntry
* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
cause the entry to activate the default button for a dialog when
activated
(gtk_entry_get_activates_default): new function
Wed Feb 28 19:10:43 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclist.c (real_remove_row): Patch from ChiDeok

View File

@ -1,3 +1,33 @@
2001-03-02 Havoc Pennington <hp@redhat.com>
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_flush): use
_gdk_region_get_xrectangles()
* gdk/x11/gdkmain-x11.c (_gdk_region_get_xrectangles): new function
* gtk/testgtk.c (create_shapes): add test for shape_combine_region
* gdk/x11/gdkwindow-x11.c (gdk_window_shape_combine_region): new
function, contributed by Ron Steinke
* gdk/x11/gdkevents-x11.c (gdk_wmspec_supported): rename
gdk_net_wm_supports
* gdk/gdkregion-generic.c (gdk_region_get_rectangles):
New function, contributed by Ron Steinke
* gtk/gtkentry.c (gtk_entry_get_layout_offsets): New function,
used to line up the text in the entry when using the entry for
editable sheet cell hacks
* gtk/testgtk.c (create_entry): test the activate_default setting
on GtkEntry
* gtk/gtkentry.c (gtk_entry_set_activates_default): New function to
cause the entry to activate the default button for a dialog when
activated
(gtk_entry_get_activates_default): new function
Wed Feb 28 19:10:43 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclist.c (real_remove_row): Patch from ChiDeok

View File

@ -186,6 +186,42 @@ gdk_region_get_clipbox (GdkRegion *r, GdkRectangle *rect)
rect->height = r->extents.y2 - r->extents.y1;
}
/**
* gdk_region_get_rectangles:
* @region: a #GdkRegion
* @rectangles: return location for an array of rectangles
* @n_rectangles: length of returned array
*
* Obtains the area covered by the region as a list of rectangles.
* The array returned in @rectangles must be freed with g_free().
*
**/
void
gdk_region_get_rectangles (GdkRegion *region,
GdkRectangle **rectangles,
gint *n_rectangles)
{
gint i;
g_return_if_fail (region != NULL);
g_return_if_fail (rectangles != NULL);
g_return_if_fail (n_rectangles != NULL);
*n_rectangles = region->numRects;
*rectangles = g_new (GdkRectangle, region->numRects);
for (i = 0; i < region->numRects; i++)
{
GdkRegionBox rect;
rect = region->rects[i];
(*rectangles)[i].x = rect.x1;
(*rectangles)[i].y = rect.y1;
(*rectangles)[i].width = rect.x2 - rect.x1;
(*rectangles)[i].height = rect.y2 - rect.y1;
}
}
void
gdk_region_union_with_rect (GdkRegion *region,
GdkRectangle *rect)

View File

@ -40,8 +40,11 @@ GdkRegion *gdk_region_copy (GdkRegion *region);
GdkRegion *gdk_region_rectangle (GdkRectangle *rectangle);
void gdk_region_destroy (GdkRegion *region);
void gdk_region_get_clipbox (GdkRegion *region,
GdkRectangle *rectangle);
void gdk_region_get_clipbox (GdkRegion *region,
GdkRectangle *rectangle);
void gdk_region_get_rectangles (GdkRegion *region,
GdkRectangle **rectangles,
gint *n_rectangles);
gboolean gdk_region_empty (GdkRegion *region);
gboolean gdk_region_equal (GdkRegion *region1,

View File

@ -278,10 +278,15 @@ void gdk_window_scroll (GdkWindow *window,
* The shape_mask can be the mask
* from gdk_pixmap_create_from_xpm. Stefan Wille
*/
void gdk_window_shape_combine_mask (GdkWindow *window,
GdkBitmap *shape_mask,
gint offset_x,
gint offset_y);
void gdk_window_shape_combine_mask (GdkWindow *window,
GdkBitmap *shape_mask,
gint offset_x,
gint offset_y);
void gdk_window_shape_combine_region (GdkWindow *window,
GdkRegion *shape_region,
gint offset_x,
gint offset_y);
/*
* This routine allows you to quickly take the shapes of all the child windows
* of a window and use their shapes as the shape mask for this window - useful

View File

@ -1756,7 +1756,7 @@ gdk_x11_get_server_time (GdkWindow *window)
gboolean
gdk_wmspec_supported (GdkAtom property)
gdk_net_wm_supports (GdkAtom property)
{
static GdkAtom wmspec_check_atom = 0;
static GdkAtom wmspec_supported_atom = 0;
@ -1840,7 +1840,7 @@ gdk_wmspec_supported (GdkAtom property)
XFree (xwindow);
/* since wmspec_check_window != None this isn't infinite. ;-) */
return gdk_wmspec_supported (property);
return gdk_net_wm_supports (property);
}

View File

@ -190,21 +190,19 @@ _gdk_x11_gc_flush (GdkGC *gc)
gc->clip_x_origin, gc->clip_y_origin);
else
{
XRectangle *rectangles = g_new (XRectangle, private->clip_region->numRects);
GdkRegionBox *boxes = private->clip_region->rects;
int i;
XRectangle *rectangles;
gint n_rects;
for (i=0; i<private->clip_region->numRects; i++)
{
rectangles[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
rectangles[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
rectangles[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rectangles[i].x;
rectangles[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rectangles[i].y;
}
_gdk_region_get_xrectangles (private->clip_region,
gc->clip_x_origin,
gc->clip_y_origin,
&rectangles,
&n_rects);
XSetClipRectangles(GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc), 0, 0, rectangles,
private->clip_region->numRects, YXBanded);
XSetClipRectangles (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc), 0, 0,
rectangles,
n_rects, YXBanded);
g_free (rectangles);
}
}

View File

@ -53,6 +53,7 @@
#include "gdkprivate-x11.h"
#include "gdkinternals.h"
#include "gdkregion-generic.h"
#include "gdkinputprivate.h"
#include <pango/pangox.h>
@ -737,3 +738,26 @@ gdk_send_xevent (Window window, gboolean propagate, glong event_mask,
return result && !gdk_error_code;
}
void
_gdk_region_get_xrectangles (GdkRegion *region,
gint x_offset,
gint y_offset,
XRectangle **rects,
gint *n_rects)
{
XRectangle *rectangles = g_new (XRectangle, region->numRects);
GdkRegionBox *boxes = region->rects;
gint i;
for (i = 0; i < region->numRects; i++)
{
rectangles[i].x = CLAMP (boxes[i].x1 + x_offset, G_MINSHORT, G_MAXSHORT);
rectangles[i].y = CLAMP (boxes[i].y1 + y_offset, G_MINSHORT, G_MAXSHORT);
rectangles[i].width = CLAMP (boxes[i].x2 + x_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].x;
rectangles[i].height = CLAMP (boxes[i].y2 + y_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].y;
}
*rects = rectangles;
*n_rects = region->numRects;
}

View File

@ -86,6 +86,12 @@ void _gdk_window_process_expose (GdkWindow *window,
void _gdk_selection_window_destroyed (GdkWindow *window);
gboolean _gdk_selection_filter_clear_event (XSelectionClearEvent *event);
void _gdk_region_get_xrectangles (GdkRegion *region,
gint x_offset,
gint y_offset,
XRectangle **rects,
gint *n_rects);
extern GdkDrawableClass _gdk_x11_drawable_class;
extern gboolean gdk_use_xshm;
extern Atom gdk_wm_delete_window;

View File

@ -1066,7 +1066,7 @@ gdk_window_focus (GdkWindow *window,
if (GDK_WINDOW_DESTROYED (window))
return;
if (gdk_wmspec_supported (gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
if (gdk_net_wm_supports (gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
{
XEvent xev;
@ -1831,6 +1831,8 @@ gdk_window_have_shape_ext (void)
return (have_shape == YES);
}
#define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
/*
* This needs the X11 shape extension.
* If not available, shaped windows will look
@ -1842,6 +1844,7 @@ gdk_window_shape_combine_mask (GdkWindow *window,
gint x, gint y)
{
Pixmap pixmap;
gint xoffset, yoffset;
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
@ -1849,6 +1852,14 @@ gdk_window_shape_combine_mask (GdkWindow *window,
#ifdef HAVE_SHAPE_EXT
if (GDK_WINDOW_DESTROYED (window))
return;
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
if (xoffset != 0 || yoffset != 0)
{
WARN_SHAPE_TOO_BIG ();
return;
}
if (gdk_window_have_shape_ext ())
{
@ -1873,6 +1884,58 @@ gdk_window_shape_combine_mask (GdkWindow *window,
#endif /* HAVE_SHAPE_EXT */
}
void
gdk_window_shape_combine_region (GdkWindow *window,
GdkRegion *shape_region,
gint offset_x,
gint offset_y)
{
gint xoffset, yoffset;
g_return_if_fail (GDK_IS_WINDOW (window));
#ifdef HAVE_SHAPE_EXT
if (GDK_WINDOW_DESTROYED (window))
return;
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
if (xoffset != 0 || yoffset != 0)
{
WARN_SHAPE_TOO_BIG ();
return;
}
if (shape_region == NULL)
{
/* Use NULL mask to unset the shape */
gdk_window_shape_combine_mask (window, NULL, 0, 0);
return;
}
if (gdk_window_have_shape_ext ())
{
gint n_rects = 0;
XRectangle *xrects = NULL;
_gdk_region_get_xrectangles (shape_region,
0, 0,
&xrects, &n_rects);
XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
ShapeBounding,
offset_x, offset_y,
xrects, n_rects,
ShapeSet,
YXBanded);
g_free (xrects);
}
#endif /* HAVE_SHAPE_EXT */
}
void
gdk_window_set_override_redirect (GdkWindow *window,
gboolean override_redirect)

View File

@ -186,7 +186,7 @@ gpointer gdk_xid_table_lookup (XID xid);
guint32 gdk_x11_get_server_time (GdkWindow *window);
/* returns TRUE if we support the given WM spec feature */
gboolean gdk_wmspec_supported (GdkAtom property);
gboolean gdk_net_wm_supports (GdkAtom property);
#define gdk_window_lookup(xid) ((GdkWindow*) gdk_xid_table_lookup (xid))
#define gdk_pixmap_lookup(xid) ((GdkPixmap*) gdk_xid_table_lookup (xid))

View File

@ -41,6 +41,7 @@
#include "gtkseparatormenuitem.h"
#include "gtkselection.h"
#include "gtksignal.h"
#include "gtkwindow.h"
#define MIN_ENTRY_WIDTH 150
#define DRAW_TIMEOUT 20
@ -73,7 +74,8 @@ enum {
PROP_EDITABLE,
PROP_MAX_LENGTH,
PROP_VISIBILITY,
PROP_INVISIBLE_CHAR
PROP_INVISIBLE_CHAR,
PROP_ACTIVATES_DEFAULT
};
static guint signals[LAST_SIGNAL] = { 0 };
@ -205,6 +207,7 @@ static void gtk_entry_cut_clipboard (GtkEntry *entry);
static void gtk_entry_copy_clipboard (GtkEntry *entry);
static void gtk_entry_paste_clipboard (GtkEntry *entry);
static void gtk_entry_toggle_overwrite (GtkEntry *entry);
static void gtk_entry_real_activate (GtkEntry *entry);
/* IM Context Callbacks
*/
@ -355,7 +358,8 @@ gtk_entry_class_init (GtkEntryClass *class)
class->copy_clipboard = gtk_entry_copy_clipboard;
class->paste_clipboard = gtk_entry_paste_clipboard;
class->toggle_overwrite = gtk_entry_toggle_overwrite;
class->activate = gtk_entry_real_activate;
g_object_class_install_property (gobject_class,
PROP_TEXT_POSITION,
g_param_spec_int ("text_position",
@ -401,6 +405,14 @@ gtk_entry_class_init (GtkEntryClass *class)
'*',
G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class,
PROP_ACTIVATES_DEFAULT,
g_param_spec_boolean ("activates_default",
_("Activates default"),
_("Whether to activate the default widget (such as the default button in a dialog) when Enter is pressed."),
FALSE,
G_PARAM_READABLE | G_PARAM_WRITABLE));
signals[INSERT_TEXT] =
gtk_signal_new ("insert_text",
GTK_RUN_LAST,
@ -675,6 +687,10 @@ static void gtk_entry_set_property (GObject *object,
gtk_entry_set_invisible_char (entry, g_value_get_int (value));
break;
case PROP_ACTIVATES_DEFAULT:
gtk_entry_set_activates_default (entry, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -708,6 +724,9 @@ static void gtk_entry_get_property (GObject *object,
case PROP_INVISIBLE_CHAR:
g_value_set_int (value, entry->invisible_char);
break;
case PROP_ACTIVATES_DEFAULT:
g_value_set_boolean (value, entry->activates_default);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -922,13 +941,95 @@ gtk_entry_size_request (GtkWidget *widget,
yborder * 2);
}
static void
get_borders (GtkEntry *entry,
gint *xborder,
gint *yborder)
{
GtkWidget *widget;
widget = GTK_WIDGET (entry);
if (entry->has_frame)
{
if (xborder)
*xborder = widget->style->xthickness;
if (yborder)
*yborder = widget->style->ythickness;
}
else
{
/* 1 pixel for focus rect */
if (xborder)
*xborder = 1;
if (yborder)
*yborder = 1;
}
}
static void
get_text_area_size (GtkEntry *entry,
gint *x,
gint *y,
gint *width,
gint *height)
{
gint xborder, yborder;
GtkRequisition requisition;
GtkWidget *widget;
widget = GTK_WIDGET (entry);
gtk_widget_get_child_requisition (widget, &requisition);
get_borders (entry, &xborder, &yborder);
if (x)
*x = xborder;
if (y)
*y = yborder;
if (width)
*width = GTK_WIDGET (entry)->allocation.width - xborder * 2;
if (height)
*height = requisition.height - yborder * 2;
}
static void
get_widget_window_size (GtkEntry *entry,
gint *x,
gint *y,
gint *width,
gint *height)
{
GtkRequisition requisition;
GtkWidget *widget;
widget = GTK_WIDGET (entry);
gtk_widget_get_child_requisition (widget, &requisition);
if (x)
*x = widget->allocation.x;
if (y)
*y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2;
if (width)
*width = widget->allocation.width;
if (height)
*height = requisition.height;
}
static void
gtk_entry_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkEntry *entry;
GtkEditable *editable;
gint xborder, yborder;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ENTRY (widget));
@ -937,18 +1038,6 @@ gtk_entry_size_allocate (GtkWidget *widget,
widget->allocation = *allocation;
entry = GTK_ENTRY (widget);
editable = GTK_EDITABLE (widget);
if (entry->has_frame)
{
xborder = widget->style->xthickness;
yborder = widget->style->ythickness;
}
else
{
/* 1 pixel for focus rect */
xborder = 1;
yborder = 1;
}
if (GTK_WIDGET_REALIZED (widget))
{
@ -956,18 +1045,17 @@ gtk_entry_size_allocate (GtkWidget *widget,
* backwards compatibility reasons) the realization here to
* be affected by the usize of the entry, if set
*/
GtkRequisition requisition;
gtk_widget_get_child_requisition (widget, &requisition);
gint x, y, width, height;
get_widget_window_size (entry, &x, &y, &width, &height);
gdk_window_move_resize (widget->window,
allocation->x,
allocation->y + (allocation->height - requisition.height) / 2,
allocation->width, requisition.height);
x, y, width, height);
get_text_area_size (entry, &x, &y, &width, &height);
gdk_window_move_resize (entry->text_area,
xborder,
yborder,
allocation->width - xborder * 2,
requisition.height - yborder * 2);
x, y, width, height);
gtk_entry_recompute (entry);
}
@ -1777,6 +1865,24 @@ gtk_entry_toggle_overwrite (GtkEntry *entry)
entry->overwrite_mode = !entry->overwrite_mode;
}
static void
gtk_entry_real_activate (GtkEntry *entry)
{
GtkWindow *window;
GtkWidget *widget;
widget = GTK_WIDGET (entry);
if (entry->activates_default)
{
window = (GtkWindow *) gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
if (window &&
window->default_widget != widget)
gtk_window_activate_default (window);
}
}
/* IM Context Callbacks
*/
@ -1986,6 +2092,47 @@ gtk_entry_get_layout (GtkEntry *entry,
return entry->cached_layout;
}
static void
get_layout_position (GtkEntry *entry,
gint *x,
gint *y)
{
PangoLayout *layout;
PangoRectangle logical_rect;
gint area_width, area_height;
gint y_pos;
PangoLayoutLine *line;
layout = gtk_entry_get_layout (entry, TRUE);
get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
area_height = PANGO_SCALE * (area_height - 2 * INNER_BORDER);
line = pango_layout_get_lines (layout)->data;
pango_layout_line_get_extents (line, NULL, &logical_rect);
/* Align primarily for locale's ascent/descent */
y_pos = ((area_height - entry->ascent - entry->descent) / 2 +
entry->ascent + logical_rect.y);
/* Now see if we need to adjust to fit in actual drawn string */
if (logical_rect.height > area_height)
y_pos = (area_height - logical_rect.height) / 2;
else if (y_pos < 0)
y_pos = 0;
else if (y_pos + logical_rect.height > area_height)
y_pos = area_height - logical_rect.height;
y_pos = INNER_BORDER + y_pos / PANGO_SCALE;
if (x)
*x = INNER_BORDER - entry->scroll_offset;
if (y)
*y = y_pos;
}
static void
gtk_entry_draw_text (GtkEntry *entry)
{
@ -2001,59 +2148,46 @@ gtk_entry_draw_text (GtkEntry *entry)
if (GTK_WIDGET_DRAWABLE (entry))
{
PangoLayout *layout = gtk_entry_get_layout (entry, TRUE);
PangoRectangle logical_rect;
gint area_width, area_height;
gint x, y;
gint start_pos, end_pos;
gint y_pos;
gdk_window_get_size (entry->text_area, &area_width, &area_height);
widget = GTK_WIDGET (entry);
get_layout_position (entry, &x, &y);
get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
gtk_paint_flat_box (widget->style, entry->text_area,
GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
NULL, widget, "entry_bg",
0, 0, area_width, area_height);
area_height = PANGO_SCALE * (area_height - 2 * INNER_BORDER);
line = pango_layout_get_lines (layout)->data;
pango_layout_line_get_extents (line, NULL, &logical_rect);
/* Align primarily for locale's ascent/descent */
y_pos = ((area_height - entry->ascent - entry->descent) / 2 +
entry->ascent + logical_rect.y);
/* Now see if we need to adjust to fit in actual drawn string */
if (logical_rect.height > area_height)
y_pos = (area_height - logical_rect.height) / 2;
else if (y_pos < 0)
y_pos = 0;
else if (y_pos + logical_rect.height > area_height)
y_pos = area_height - logical_rect.height;
y_pos = INNER_BORDER + y_pos / PANGO_SCALE;
gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
INNER_BORDER - entry->scroll_offset, y_pos,
gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
x, y,
layout);
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
{
gint *ranges;
gint n_ranges, i;
PangoRectangle logical_rect;
gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
gint end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text;
GdkRegion *clip_region = gdk_region_new ();
line = pango_layout_get_lines (layout)->data;
pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
pango_layout_get_extents (layout, NULL, &logical_rect);
for (i=0; i < n_ranges; i++)
{
GdkRectangle rect;
rect.x = INNER_BORDER - entry->scroll_offset + ranges[2*i] / PANGO_SCALE;
rect.y = y_pos;
rect.y = y;
rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE;
rect.height = logical_rect.height / PANGO_SCALE;
@ -2065,7 +2199,7 @@ gtk_entry_draw_text (GtkEntry *entry)
gdk_gc_set_clip_region (widget->style->fg_gc [GTK_STATE_SELECTED], clip_region);
gdk_draw_layout (entry->text_area, widget->style->fg_gc [GTK_STATE_SELECTED],
INNER_BORDER - entry->scroll_offset, y_pos,
x, y,
layout);
gdk_gc_set_clip_region (widget->style->fg_gc [GTK_STATE_SELECTED], NULL);
@ -2704,6 +2838,51 @@ gtk_entry_set_max_length (GtkEntry *entry,
g_object_notify (G_OBJECT (entry), "max_length");
}
/**
* gtk_entry_set_activates_default:
* @entry: a #GtkEntry
* @setting: %TRUE to activate window's default widget on Enter keypress
*
* If @setting is %TRUE, pressing Enter in the @entry will activate the default
* widget for the window containing the entry. This usually means that
* the dialog box containing the entry will be closed, since the default
* widget is usually one of the dialog buttons.
*
* (For experts: if @setting is %TRUE, the entry calls
* gtk_window_activate_default() on the window containing the entry, in
* the default handler for the "activate" signal.)
*
**/
void
gtk_entry_set_activates_default (GtkEntry *entry,
gboolean setting)
{
g_return_if_fail (GTK_IS_ENTRY (entry));
setting = setting != FALSE;
if (setting != entry->activates_default)
{
entry->activates_default = setting;
g_object_notify (G_OBJECT (entry), "activates_default");
}
}
/**
* gtk_entry_get_activates_default:
* @entry: a #GtkEntry
*
* Retrieves the value set by gtk_entry_set_activates_default().
*
* Return value: %TRUE if the entry will activate the default widget
**/
gboolean
gtk_entry_get_activates_default (GtkEntry *entry)
{
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);
return entry->activates_default;
}
/**
* gtk_entry_set_has_frame:
* @entry: a #GtkEntry
@ -2729,7 +2908,7 @@ gtk_entry_set_has_frame (GtkEntry *entry,
* gtk_entry_get_has_frame:
* @entry: a #GtkEntry
*
*
* Gets the value set by gtk_entry_set_has_frame().
*
* Return value: whether the entry has a beveled frame
**/
@ -2741,6 +2920,40 @@ gtk_entry_get_has_frame (GtkEntry *entry)
return entry->has_frame;
}
/**
* gtk_entry_get_layout_offsets:
* @entry: a #GtkEntry
* @x: location to store X coordinate of layout
* @y: location to store Y coordinate of layout
*
* Obtains the position of the #PangoLayout used to render text
* in the entry, in widget coordinates. Useful if you want to line
* up the text in an entry with some other text, e.g. when using the
* entry to implement editable cells in a sheet widget.
*
**/
void
gtk_entry_get_layout_offsets (GtkEntry *entry,
gint *x,
gint *y)
{
gint text_area_x, text_area_y;
g_return_if_fail (GTK_IS_ENTRY (entry));
/* this gets coords relative to text area */
get_layout_position (entry, x, y);
/* convert to widget coords */
get_text_area_size (entry, &text_area_x, &text_area_y, NULL, NULL);
if (x)
*x += text_area_x;
if (y)
*y += text_area_y;
}
/* Quick hack of a popup menu
*/
static void

View File

@ -77,6 +77,8 @@ struct _GtkEntry
guint need_im_reset : 1;
guint has_frame : 1;
guint activates_default : 1;
guint button;
guint timer;
@ -146,6 +148,9 @@ gboolean gtk_entry_get_has_frame (GtkEntry *entry);
/* text is truncated if needed */
void gtk_entry_set_max_length (GtkEntry *entry,
gint max);
void gtk_entry_set_activates_default (GtkEntry *entry,
gboolean setting);
gboolean gtk_entry_get_activates_default (GtkEntry *entry);
/* Somewhat more convenient than the GtkEditable generic functions
*/

View File

@ -3429,8 +3429,8 @@ static void
entry_toggle_visibility (GtkWidget *checkbutton,
GtkWidget *entry)
{
gtk_entry_set_visibility(GTK_ENTRY(entry),
GTK_TOGGLE_BUTTON(checkbutton)->active);
gtk_entry_set_visibility (GTK_ENTRY (entry),
GTK_TOGGLE_BUTTON (checkbutton)->active);
}
static void
@ -3443,6 +3443,15 @@ entry_toggle_invisible_char (GtkWidget *checkbutton,
gtk_entry_set_invisible_char (GTK_ENTRY (entry), '*');
}
static void
entry_toggle_activate_default (GtkWidget *checkbutton,
GtkWidget *entry)
{
gtk_entry_set_activates_default (GTK_ENTRY (entry),
GTK_TOGGLE_BUTTON (checkbutton)->active);
}
static void
create_entry (void)
{
@ -3452,6 +3461,7 @@ create_entry (void)
GtkWidget *editable_check;
GtkWidget *sensitive_check;
GtkWidget *invisible_char_check;
GtkWidget *activate_check;
GtkWidget *entry, *cb;
GtkWidget *button;
GtkWidget *separator;
@ -3525,6 +3535,13 @@ create_entry (void)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sensitive_check), TRUE);
gtk_widget_show (sensitive_check);
activate_check = gtk_check_button_new_with_label ("Activates default");
gtk_box_pack_start (GTK_BOX (box2), activate_check, FALSE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (activate_check), "toggled",
GTK_SIGNAL_FUNC (entry_toggle_activate_default), entry);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (activate_check), FALSE);
gtk_widget_show (activate_check);
invisible_char_check = gtk_check_button_new_with_label("invisible_char = 0");
gtk_box_pack_start (GTK_BOX (box2), invisible_char_check, FALSE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled",
@ -3542,7 +3559,6 @@ create_entry (void)
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
@ -7538,7 +7554,8 @@ create_shapes (void)
static GtkWidget *modeller = NULL;
static GtkWidget *sheets = NULL;
static GtkWidget *rings = NULL;
static GtkWidget *with_region = NULL;
if (!(file_exists ("Modeller.xpm") &&
file_exists ("FilesQueue.xpm") &&
file_exists ("3DRings.xpm")))
@ -7581,6 +7598,48 @@ create_shapes (void)
}
else
gtk_widget_destroy (rings);
if (!with_region)
{
GdkRegion *region;
gint x, y;
with_region = shape_create_icon ("3DRings.xpm",
460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (with_region), "destroy",
GTK_SIGNAL_FUNC(gtk_widget_destroyed),
&with_region);
/* reset shape from mask to a region */
x = 0;
y = 0;
region = gdk_region_new ();
while (x < 460)
{
while (y < 270)
{
GdkRectangle rect;
rect.x = x;
rect.y = y;
rect.width = 10;
rect.height = 10;
gdk_region_union_with_rect (region, &rect);
y += 20;
}
y = 0;
x += 20;
}
gdk_window_shape_combine_region (with_region->window,
region,
0, 0);
}
else
gtk_widget_destroy (with_region);
}
/*

View File

@ -3429,8 +3429,8 @@ static void
entry_toggle_visibility (GtkWidget *checkbutton,
GtkWidget *entry)
{
gtk_entry_set_visibility(GTK_ENTRY(entry),
GTK_TOGGLE_BUTTON(checkbutton)->active);
gtk_entry_set_visibility (GTK_ENTRY (entry),
GTK_TOGGLE_BUTTON (checkbutton)->active);
}
static void
@ -3443,6 +3443,15 @@ entry_toggle_invisible_char (GtkWidget *checkbutton,
gtk_entry_set_invisible_char (GTK_ENTRY (entry), '*');
}
static void
entry_toggle_activate_default (GtkWidget *checkbutton,
GtkWidget *entry)
{
gtk_entry_set_activates_default (GTK_ENTRY (entry),
GTK_TOGGLE_BUTTON (checkbutton)->active);
}
static void
create_entry (void)
{
@ -3452,6 +3461,7 @@ create_entry (void)
GtkWidget *editable_check;
GtkWidget *sensitive_check;
GtkWidget *invisible_char_check;
GtkWidget *activate_check;
GtkWidget *entry, *cb;
GtkWidget *button;
GtkWidget *separator;
@ -3525,6 +3535,13 @@ create_entry (void)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sensitive_check), TRUE);
gtk_widget_show (sensitive_check);
activate_check = gtk_check_button_new_with_label ("Activates default");
gtk_box_pack_start (GTK_BOX (box2), activate_check, FALSE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (activate_check), "toggled",
GTK_SIGNAL_FUNC (entry_toggle_activate_default), entry);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (activate_check), FALSE);
gtk_widget_show (activate_check);
invisible_char_check = gtk_check_button_new_with_label("invisible_char = 0");
gtk_box_pack_start (GTK_BOX (box2), invisible_char_check, FALSE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled",
@ -3542,7 +3559,6 @@ create_entry (void)
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
@ -7538,7 +7554,8 @@ create_shapes (void)
static GtkWidget *modeller = NULL;
static GtkWidget *sheets = NULL;
static GtkWidget *rings = NULL;
static GtkWidget *with_region = NULL;
if (!(file_exists ("Modeller.xpm") &&
file_exists ("FilesQueue.xpm") &&
file_exists ("3DRings.xpm")))
@ -7581,6 +7598,48 @@ create_shapes (void)
}
else
gtk_widget_destroy (rings);
if (!with_region)
{
GdkRegion *region;
gint x, y;
with_region = shape_create_icon ("3DRings.xpm",
460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (with_region), "destroy",
GTK_SIGNAL_FUNC(gtk_widget_destroyed),
&with_region);
/* reset shape from mask to a region */
x = 0;
y = 0;
region = gdk_region_new ();
while (x < 460)
{
while (y < 270)
{
GdkRectangle rect;
rect.x = x;
rect.y = y;
rect.width = 10;
rect.height = 10;
gdk_region_union_with_rect (region, &rect);
y += 20;
}
y = 0;
x += 20;
}
gdk_window_shape_combine_region (with_region->window,
region,
0, 0);
}
else
gtk_widget_destroy (with_region);
}
/*