forked from AuroraMiddleware/gtk
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
This commit is contained in:
parent
519d758711
commit
a4a7a611f2
159
gtk/gtkwindow.c
159
gtk/gtkwindow.c
@ -281,12 +281,16 @@ 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;
|
||||
};
|
||||
|
||||
@ -3928,6 +3932,30 @@ gtk_window_set_default_size (GtkWindow *window,
|
||||
gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -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,9 +6122,46 @@ _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,
|
||||
GdkGeometry *geometry,
|
||||
guint flags,
|
||||
guint *width,
|
||||
guint *height)
|
||||
{
|
||||
@ -6099,43 +6197,15 @@ gtk_window_compute_configure_request_size (GtkWindow *window,
|
||||
|
||||
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
|
||||
@ -6154,9 +6224,13 @@ gtk_window_compute_configure_request_size (GtkWindow *window,
|
||||
{
|
||||
if (info->resize_width > 0)
|
||||
*width = info->resize_width;
|
||||
|
||||
if (info->resize_height > 0)
|
||||
*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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -73,6 +73,19 @@ on_drawing_area_draw (GtkWidget *drawing_area,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -80,6 +93,7 @@ create_window (GdkWindowHints mask)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user