[gtk+/resizegrips] Get scrollbars out of the way of the window's resize grip.
- From: Cody Russell <bratsche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/resizegrips] Get scrollbars out of the way of the window's resize grip.
- Date: Thu, 30 Sep 2010 19:11:26 +0000 (UTC)
commit a303eec75f24aa404c051c999fa8d4e555cfe9a7
Author: Cody Russell <bratsche gnome org>
Date: Thu Sep 30 14:11:09 2010 -0500
Get scrollbars out of the way of the window's resize grip.
gtk/gtkrange.c | 112 ++++++++++++++++++++++++++++++
gtk/gtkwindow.c | 207 +++++++++++++++++++++++++++++++++++++-----------------
gtk/gtkwindow.h | 10 +++
3 files changed, 264 insertions(+), 65 deletions(-)
---
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index 07d89e1..0da7247 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -37,6 +37,7 @@
#include "gtkrange.h"
#include "gtkscale.h"
#include "gtkscrollbar.h"
+#include "gtkwindow.h"
#include "gtkprivate.h"
#include "gtkintl.h"
@@ -1569,12 +1570,123 @@ gtk_range_size_request (GtkWidget *widget,
requisition->height = range_rect.height + border.top + border.bottom;
}
+static GtkWidget *
+find_toplevel_window (GtkWidget *widget)
+{
+ if (GTK_IS_WINDOW (widget))
+ {
+ return widget;
+ }
+ else if (gtk_widget_get_parent (widget))
+ {
+ return find_toplevel_window (gtk_widget_get_parent (widget));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static gint
+get_fixup_for_window_grip (GtkWidget *widget)
+{
+ GtkWidget *window;
+ GtkRange *range = GTK_RANGE (widget);
+
+ window = find_toplevel_window (widget);
+ if (window == NULL)
+ {
+ return 0;
+ }
+
+ if (!gtk_window_resize_grip_is_visible (GTK_WINDOW (window)))
+ {
+ return 0;
+ }
+
+ if (gtk_window_get_has_resize_grip (GTK_WINDOW (window)))
+ {
+ GtkRangePrivate *priv;
+ GdkRectangle grip_rect;
+ GdkRectangle orig_rect;
+ GdkRectangle translated_rect;
+ gint x = 0;
+ gint y = 0;
+
+ priv = range->priv;
+
+ gtk_range_calc_layout (range, priv->adjustment->value);
+
+ /* Get the area of the window's corner grip */
+ gtk_window_get_resize_grip_area (GTK_WINDOW (window),
+ &grip_rect);
+
+ /* Get the area of the stepper that might be blocked by the grip */
+ if (gtk_widget_get_direction (window) == GTK_TEXT_DIR_LTR)
+ {
+ orig_rect = priv->stepper_d;
+ }
+ else
+ {
+ orig_rect = priv->stepper_a;
+ }
+
+ /* Translate the stepper's area into window coords */
+ if (gtk_widget_translate_coordinates (widget,
+ window,
+ orig_rect.x,
+ orig_rect.y,
+ &x,
+ &y))
+ {
+ translated_rect.x = x;
+ translated_rect.y = y;
+ translated_rect.width = orig_rect.width;
+ translated_rect.height = orig_rect.height;
+
+ /* If the stepper button intersects the window resize grip.. */
+ if (gdk_rectangle_intersect (&grip_rect, &translated_rect, NULL))
+ {
+ gint grip_height;
+ gint grip_width;
+
+ /* Return the height of the grip */
+ gtk_widget_style_get (window,
+ "resize-grip-height", &grip_height,
+ "resize-grip-width", &grip_width,
+ NULL);
+
+ if (gtk_orientable_get_orientation (GTK_ORIENTABLE (range)) == GTK_ORIENTATION_HORIZONTAL)
+ return grip_width;
+ else
+ return grip_height;
+ }
+ }
+ }
+
+ return 0;
+}
+
static void
gtk_range_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkRange *range = GTK_RANGE (widget);
GtkRangePrivate *priv = range->priv;
+ gint fixup;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ fixup = get_fixup_for_window_grip (widget);
+
+ if (gtk_orientable_get_orientation (GTK_ORIENTABLE (range)) == GTK_ORIENTATION_VERTICAL)
+ {
+ allocation->height -= fixup;
+ }
+ else
+ {
+ allocation->width -= fixup;
+ }
gtk_widget_set_allocation (widget, allocation);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 83b0fde..5867753 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -391,12 +391,9 @@ static GList *icon_list_from_theme (GtkWidget *widget,
const gchar *name);
static void gtk_window_realize_icon (GtkWindow *window);
static void gtk_window_unrealize_icon (GtkWindow *window);
-static void get_grip_rect (GtkWindow *window,
- GdkRectangle *rect);
-static void gtk_window_set_has_resize_grip (GtkWindow *window,
- gboolean value);
static void resize_grip_create_window (GtkWindow *window);
static void resize_grip_destroy_window (GtkWindow *window);
+static void update_grip_visibility (GtkWindow *window);
static void gtk_window_notify_keys_changed (GtkWindow *window);
static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
@@ -846,7 +843,7 @@ gtk_window_class_init (GtkWindowClass *klass)
*
* Whether the window should have a corner resize grip.
*
- * Since: 2.20
+ * Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_HAS_RESIZE_GRIP,
@@ -909,6 +906,24 @@ gtk_window_class_init (GtkWindowClass *klass)
1.0,
GTK_PARAM_READWRITE));
+
+ /* Style properties.
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("resize-grip-width",
+ P_("Width of resize grip"),
+ P_("Width of resize grip"),
+ 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("resize-grip-height",
+ P_("Height of resize grip"),
+ P_("Height of resize grip"),
+ 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
+
+
+ /* Signals
+ */
window_signals[SET_FOCUS] =
g_signal_new (I_("set-focus"),
G_TYPE_FROM_CLASS (gobject_class),
@@ -4993,7 +5008,7 @@ set_grip_position (GtkWindow *window)
if (priv->grip_window == NULL)
return;
- get_grip_rect (window, &rect);
+ gtk_window_get_resize_grip_area (window, &rect);
gdk_window_raise (priv->grip_window);
gdk_window_move_resize (priv->grip_window,
rect.x, rect.y,
@@ -5166,63 +5181,11 @@ gtk_window_configure_event (GtkWidget *widget,
return TRUE;
}
-static void
-get_grip_rect (GtkWindow *window,
- GdkRectangle *rect)
-{
- GtkWidget *widget;
- GtkAllocation allocation;
- GtkStyle *style;
- gint w, h;
-
- widget = GTK_WIDGET (window);
- gtk_widget_get_allocation (widget, &allocation);
- style = gtk_widget_get_style (widget);
-
- /* These are in effect the max/default size of the grip. */
- /* FIXME: need to take from style */
- w = 18;
- h = 18;
-
- if (w > allocation.width)
- w = allocation.width;
-
- if (h > allocation.height - style->ythickness)
- h = allocation.height - style->ythickness;
-
- rect->width = w;
- rect->height = h;
- rect->y = allocation.y + allocation.height - h;
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- rect->x = allocation.x + allocation.width - w;
- else
- rect->x = allocation.x + style->xthickness;
-}
-
-static void
-set_grip_visibility (GtkWindow *window)
-{
- GtkWindowPrivate *priv = window->priv;
- GdkWindowState state;
-
- if (priv->grip_window == NULL)
- return;
-
- state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)));
-
- if (priv->has_resize_grip && priv->resizable &&
- (state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) == 0)
- gdk_window_show (priv->grip_window);
- else
- gdk_window_hide (priv->grip_window);
-}
-
static gboolean
gtk_window_state_event (GtkWidget *widget,
GdkEventWindowState *event)
{
- set_grip_visibility (GTK_WINDOW (widget));
+ update_grip_visibility (GTK_WINDOW (widget));
return FALSE;
}
@@ -5245,7 +5208,7 @@ gtk_window_state_changed (GtkWidget *widget,
GtkWindow *window = GTK_WINDOW (widget);
set_grip_cursor (window);
- set_grip_visibility (window);
+ update_grip_visibility (window);
}
static void
@@ -5263,7 +5226,7 @@ resize_grip_create_window (GtkWindow *window)
g_return_if_fail (gtk_widget_get_realized (widget));
g_return_if_fail (priv->grip_window == NULL);
- get_grip_rect (window, &rect);
+ gtk_window_get_resize_grip_area (window, &rect);
attributes.x = rect.x;
attributes.y = rect.y;
@@ -5287,7 +5250,7 @@ resize_grip_create_window (GtkWindow *window)
set_grip_cursor (window);
set_grip_shape (window);
- set_grip_visibility (window);
+ update_grip_visibility (window);
}
static void
@@ -5300,7 +5263,7 @@ resize_grip_destroy_window (GtkWindow *window)
priv->grip_window = NULL;
}
-static void
+void
gtk_window_set_has_resize_grip (GtkWindow *window,
gboolean value)
{
@@ -5326,6 +5289,120 @@ gtk_window_set_has_resize_grip (GtkWindow *window,
}
}
+static void
+update_grip_visibility (GtkWindow *window)
+{
+ if (gtk_window_resize_grip_is_visible (window))
+ {
+ gdk_window_show (window->priv->grip_window);
+ }
+ else
+ {
+ gdk_window_hide (window->priv->grip_window);
+ }
+}
+
+/**
+ * gtk_window_resize_grip_is_visible:
+ * @window: a #GtkWindow
+ *
+ * Determines whether a resize grip is visible for the specified window.
+ *
+ * Returns %TRUE if a resize grip exists and is visible.
+ *
+ * Since: 3.0
+ */
+gboolean
+gtk_window_resize_grip_is_visible (GtkWindow *window)
+{
+ GdkWindowState state;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+
+ if (!gtk_widget_get_realized (GTK_WIDGET (window)))
+ return FALSE;
+
+ state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)));
+
+ if (state & GDK_WINDOW_STATE_MAXIMIZED || state & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ return FALSE;
+ }
+
+ return window->priv->has_resize_grip;
+}
+
+/**
+ * gtk_window_get_has_resize_grip:
+ * @window: a #GtkWindow
+ *
+ * Determines whether the window has a resize grip.
+ *
+ * Returns: %TRUE if the window has a resize grip.
+ *
+ * Since: 3.0
+ */
+gboolean
+gtk_window_get_has_resize_grip (GtkWindow *window)
+{
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+
+ return window->priv->has_resize_grip;
+}
+
+/**
+ * gtk_window_get_resize_grip_area:
+ * @window: a #GtkWindow
+ * @rect: a pointer to a #GdkRectangle which we should store the resize grip area.
+ *
+ * If a window has a resize grip, this will retrieve the grip position, width
+ * and height into the specified #GdkRectangle.
+ *
+ * Returns: %TRUE if the resize grip's area was retrieved.
+ *
+ * Since: 3.0
+ */
+gboolean
+gtk_window_get_resize_grip_area (GtkWindow *window,
+ GdkRectangle *rect)
+{
+ GtkWidget *widget = GTK_WIDGET (window);
+ GtkAllocation allocation;
+ GtkStyle *style;
+ gint grip_width;
+ gint grip_height;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+
+ if (!window->priv->has_resize_grip)
+ return FALSE;
+
+ gtk_widget_get_allocation (widget, &allocation);
+ style = gtk_widget_get_style (widget);
+
+ gtk_widget_style_get (widget,
+ "resize-grip-width", &grip_width,
+ "resize-grip-height", &grip_height,
+ NULL);
+
+ if (grip_width > allocation.width)
+ grip_width = allocation.width;
+
+ if (grip_height > allocation.height)
+ grip_height = allocation.height;
+
+ rect->width = grip_width;
+ rect->height = grip_height;
+ rect->y = allocation.y + allocation.height - grip_height;
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ rect->x = allocation.x + allocation.width - grip_width;
+ else
+ rect->x = allocation.x + style->xthickness;
+
+ return TRUE;
+}
+
/* the accel_key and accel_mods fields of the key have to be setup
* upon calling this function. it'll then return whether that key
* is at all used as accelerator, and if so will OR in the
@@ -7004,7 +7081,7 @@ gtk_window_draw (GtkWidget *widget,
cairo_save (cr);
gtk_cairo_transform_to_window (cr, widget, priv->grip_window);
- get_grip_rect (GTK_WINDOW (widget), &rect);
+ gtk_window_get_resize_grip_area (GTK_WINDOW (widget), &rect);
gtk_paint_resize_grip (gtk_widget_get_style (widget),
cr,
gtk_widget_get_state (widget),
@@ -7658,7 +7735,7 @@ gtk_window_set_resizable (GtkWindow *window,
g_object_notify (G_OBJECT (window), "resizable");
if (priv->grip_window != NULL)
- set_grip_visibility (window);
+ update_grip_visibility (window);
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
index 792eeea..eb7d4d9 100644
--- a/gtk/gtkwindow.h
+++ b/gtk/gtkwindow.h
@@ -340,6 +340,16 @@ GtkWidget * gtk_window_group_get_current_device_grab (GtkWindowGroup *windo
GdkDevice *device);
+/* Window grips
+ */
+void gtk_window_set_has_resize_grip (GtkWindow *window,
+ gboolean value);
+gboolean gtk_window_get_has_resize_grip (GtkWindow *window);
+gboolean gtk_window_resize_grip_is_visible (GtkWindow *window);
+gboolean gtk_window_get_resize_grip_area (GtkWindow *window,
+ GdkRectangle *rect);
+
+
/* --- internal functions --- */
void _gtk_window_internal_set_focus (GtkWindow *window,
GtkWidget *focus);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]