[gtk+] GtkWindow: Allow setting size from geometry
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkWindow: Allow setting size from geometry
- Date: Mon, 11 Oct 2010 18:16:28 +0000 (UTC)
commit a4a7a611f2219a4cdcb359ac828ea122906f158e
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Sat Oct 9 22:38:54 2010 -0400
GtkWindow: Allow setting size from geometry
If you set a geometry widget via gtk_window_set_geometry_hints() it
becomes very hard to compute appropriate toplevel sizes in pixels
to make the window a particular size. Synthesizing strings and passing
them to gtk_window_parse_geometry() is possible, but to avoid
avoid such ugliness, add functions:
gtk_window_set_default_geometry()
gtk_window_resize_to_geometry()
That act like gtk_window_set_default_size() and
gtk_window_resize() but are in terms of the resize increments of the
geometry widget.
https://bugzilla.gnome.org/show_bug.cgi?id=631796
gtk/gtkwindow.c | 171 ++++++++++++++++++++++++++++++++++++--------------
gtk/gtkwindow.h | 8 +++
tests/testgeometry.c | 29 +++++++++
3 files changed, 161 insertions(+), 47 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 0c6dbe1..7ef2d5f 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -281,11 +281,15 @@ struct _GtkWindowGeometryInfo
*/
guint position_constraints_changed : 1;
- /* if true, default_width, height come from gtk_window_parse_geometry,
- * and thus should be multiplied by the increments and affect the
- * geometry widget only
+ /* if true, default_width, height should be multiplied by the
+ * increments and affect the geometry widget only
*/
guint default_is_geometry : 1;
+
+ /* if true, resize_width, height should be multiplied by the
+ * increments and affect the geometry widget only
+ */
+ guint resize_is_geometry : 1;
GtkWindowLastGeometryInfo last;
};
@@ -3929,6 +3933,30 @@ gtk_window_set_default_size (GtkWindow *window,
}
/**
+ * gtk_window_set_default_geometry:
+ * @window: a #GtkWindow
+ * @width: width in resize increments, or -1 to unset the default width
+ * @height: height in resize increments, or -1 to unset the default height
+ *
+ * Like gtk_window_set_default_size(), but @width and @height are interpreted
+ * in terms of the base size and increment set with
+ * gtk_window_set_geometry_hints.
+ *
+ * Since: 3.0
+ */
+void
+gtk_window_set_default_geometry (GtkWindow *window,
+ gint width,
+ gint height)
+{
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, TRUE);
+}
+
+/**
* gtk_window_get_default_size:
* @window: a #GtkWindow
* @width: (out) (allow-none): location to store the default width, or %NULL
@@ -3992,6 +4020,39 @@ gtk_window_resize (GtkWindow *window,
info->resize_width = width;
info->resize_height = height;
+ info->resize_is_geometry = FALSE;
+
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
+}
+
+/**
+ * gtk_window_resize_to_geometry:
+ * @window: a #GtkWindow
+ * @width: width in resize increments to resize the window to
+ * @height: height in resize increments to resize the window to
+ *
+ * Like gtk_window_resize(), but @width and @height are interpreted
+ * in terms of the base size and increment set with
+ * gtk_window_set_geometry_hints.
+ *
+ * Since: 3.0
+ */
+void
+gtk_window_resize_to_geometry (GtkWindow *window,
+ gint width,
+ gint height)
+{
+ GtkWindowGeometryInfo *info;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (width > 0);
+ g_return_if_fail (height > 0);
+
+ info = gtk_window_get_geometry_info (window, TRUE);
+
+ info->resize_width = width;
+ info->resize_height = height;
+ info->resize_is_geometry = TRUE;
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
@@ -6061,11 +6122,48 @@ _gtk_window_unset_focus_and_default (GtkWindow *window,
* Functions related to resizing *
*********************************/
+static void
+geometry_size_to_pixels (GdkGeometry *geometry,
+ guint flags,
+ guint *width,
+ guint *height)
+{
+ gint base_width = 0;
+ gint base_height = 0;
+ gint min_width = 0;
+ gint min_height = 0;
+ gint width_inc = 1;
+ gint height_inc = 1;
+
+ if (flags & GDK_HINT_BASE_SIZE)
+ {
+ base_width = geometry->base_width;
+ base_height = geometry->base_height;
+ }
+ if (flags & GDK_HINT_MIN_SIZE)
+ {
+ min_width = geometry->min_width;
+ min_height = geometry->min_height;
+ }
+ if (flags & GDK_HINT_RESIZE_INC)
+ {
+ width_inc = geometry->width_inc;
+ height_inc = geometry->height_inc;
+ }
+
+ if (width)
+ *width = MAX (*width * width_inc + base_width, min_width);
+ if (height)
+ *height = MAX (*height * height_inc + base_height, min_height);
+}
+
/* This function doesn't constrain to geometry hints */
static void
-gtk_window_compute_configure_request_size (GtkWindow *window,
- guint *width,
- guint *height)
+gtk_window_compute_configure_request_size (GtkWindow *window,
+ GdkGeometry *geometry,
+ guint flags,
+ guint *width,
+ guint *height)
{
GtkWindowPrivate *priv = window->priv;
GtkRequisition requisition;
@@ -6098,44 +6196,16 @@ gtk_window_compute_configure_request_size (GtkWindow *window,
/* Override requisition with default size */
if (info)
- {
- gint base_width = 0;
- gint base_height = 0;
- gint min_width = 0;
- gint min_height = 0;
- gint width_inc = 1;
- gint height_inc = 1;
-
- if (info->default_is_geometry &&
- (info->default_width > 0 || info->default_height > 0))
- {
- GdkGeometry geometry;
- guint flags;
-
- gtk_window_compute_hints (window, &geometry, &flags);
-
- if (flags & GDK_HINT_BASE_SIZE)
- {
- base_width = geometry.base_width;
- base_height = geometry.base_height;
- }
- if (flags & GDK_HINT_MIN_SIZE)
- {
- min_width = geometry.min_width;
- min_height = geometry.min_height;
- }
- if (flags & GDK_HINT_RESIZE_INC)
- {
- width_inc = geometry.width_inc;
- height_inc = geometry.height_inc;
- }
- }
-
+ {
if (info->default_width > 0)
- *width = MAX (info->default_width * width_inc + base_width, min_width);
-
+ *width = info->default_width;
if (info->default_height > 0)
- *height = MAX (info->default_height * height_inc + base_height, min_height);
+ *height = info->default_height;
+
+ if (info->default_is_geometry)
+ geometry_size_to_pixels (geometry, flags,
+ info->default_width > 0 ? width : NULL,
+ info->default_height > 0 ? height : NULL);
}
}
else
@@ -6153,10 +6223,14 @@ gtk_window_compute_configure_request_size (GtkWindow *window,
if (info)
{
if (info->resize_width > 0)
- *width = info->resize_width;
-
+ *width = info->resize_width;
if (info->resize_height > 0)
- *height = info->resize_height;
+ *height = info->resize_height;
+
+ if (info->resize_is_geometry)
+ geometry_size_to_pixels (geometry, flags,
+ info->resize_width > 0 ? width : NULL,
+ info->resize_height > 0 ? height : NULL);
}
/* Don't ever request zero width or height, its not supported by
@@ -6308,9 +6382,11 @@ gtk_window_compute_configure_request (GtkWindow *window,
screen = gtk_window_check_screen (window);
- gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
-
gtk_window_compute_hints (window, &new_geometry, &new_flags);
+ gtk_window_compute_configure_request_size (window,
+ &new_geometry, new_flags,
+ (guint *)&w, (guint *)&h);
+
gtk_window_constrain_size (window,
&new_geometry, new_flags,
w, h,
@@ -7084,6 +7160,7 @@ gtk_window_compute_hints (GtkWindow *window,
{
/* For simplicity, we always set the base hint, even when we
* don't expect it to have any visible effect.
+ * (Note: geometry_size_to_pixels() depends on this.)
*/
*new_flags |= GDK_HINT_BASE_SIZE;
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
index bb43bee..96008b8 100644
--- a/gtk/gtkwindow.h
+++ b/gtk/gtkwindow.h
@@ -315,6 +315,14 @@ void gtk_window_get_position (GtkWindow *window,
gint *root_y);
gboolean gtk_window_parse_geometry (GtkWindow *window,
const gchar *geometry);
+
+void gtk_window_set_default_geometry (GtkWindow *window,
+ gint width,
+ gint height);
+void gtk_window_resize_to_geometry (GtkWindow *window,
+ gint width,
+ gint height);
+
GtkWindowGroup *gtk_window_get_group (GtkWindow *window);
gboolean gtk_window_has_group (GtkWindow *window);
diff --git a/tests/testgeometry.c b/tests/testgeometry.c
index 9d3f714..f7eb0fa 100644
--- a/tests/testgeometry.c
+++ b/tests/testgeometry.c
@@ -74,12 +74,26 @@ on_drawing_area_draw (GtkWidget *drawing_area,
}
static void
+on_resize_clicked (GtkWidget *button,
+ gpointer data)
+{
+ GtkWidget *window = gtk_widget_get_toplevel (button);
+ GdkWindowHints mask = GPOINTER_TO_UINT(data);
+
+ if ((mask & GDK_HINT_RESIZE_INC) != 0)
+ gtk_window_resize_to_geometry (GTK_WINDOW (window), 8, 8);
+ else
+ gtk_window_resize_to_geometry (GTK_WINDOW (window), 8 * GRID_SIZE, 8 * GRID_SIZE);
+}
+
+static void
create_window (GdkWindowHints mask)
{
GtkWidget *window;
GtkWidget *drawing_area;
GtkWidget *table;
GtkWidget *label;
+ GtkWidget *button;
GdkGeometry geometry;
GString *label_text = g_string_new (NULL);
int border = 0;
@@ -130,6 +144,15 @@ create_window (GdkWindowHints mask)
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
0, 0);
+ button = gtk_button_new_with_label ("Resize");
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (on_resize_clicked),
+ GUINT_TO_POINTER (mask));
+ gtk_table_attach (GTK_TABLE (table), button,
+ 0, 2, 2, 3,
+ GTK_EXPAND, 0,
+ 0, 8);
+
gtk_container_add (GTK_CONTAINER (window), table);
if ((mask & GDK_HINT_BASE_SIZE) != 0)
@@ -169,6 +192,12 @@ create_window (GdkWindowHints mask)
{
if (geometry_string)
gtk_window_parse_geometry (GTK_WINDOW (window), geometry_string);
+ else
+ gtk_window_set_default_geometry (GTK_WINDOW (window), 10, 10);
+ }
+ else
+ {
+ gtk_window_set_default_geometry (GTK_WINDOW (window), 10 * GRID_SIZE, 10 * GRID_SIZE);
}
gtk_widget_show (window);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]