** 10 20 30 40 50 60 70 80
**
** library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+
- ** Copyright (C) 2012 Free Software Foundation, Inc.
+ ** Copyright (C) 2012, 2013 Free Software Foundation, Inc.
** Copyright (C) 2005-2006 Mirco "MacSlow" Müller <macslow@bangang.de>
**
** This library is free software; you can redistribute it and/or
static void gtk_xpaned_init (GtkXPaned * xpaned);
-static void gtk_xpaned_size_request (GtkWidget * widget,
- GtkRequisition * requisition);
+static void
+gtk_xpaned_get_preferred_width (GtkWidget *widget,
+ gint *minimal_width,
+ gint *natural_width)
+{
+ GtkXPaned *xpaned = GTK_XPANED (widget);
+ gint tl[2], tr[2], bl[2], br[2];
+ gint overhead;
+ gint w[2];
+ int i;
+
+ if (xpaned->top_left_child
+ && gtk_widget_get_visible (xpaned->top_left_child))
+ gtk_widget_get_preferred_width (xpaned->top_left_child, &tl[0], &tl[1]);
+ else
+ tl[0] = tl[1] = 0;
+
+ if (xpaned->top_right_child
+ && gtk_widget_get_visible (xpaned->top_right_child))
+ gtk_widget_get_preferred_width (xpaned->top_right_child, &tr[0], &tr[1]);
+ else
+ tr[0] = tr[1] = 0;
+
+ if (xpaned->bottom_left_child
+ && gtk_widget_get_visible (xpaned->bottom_left_child))
+ gtk_widget_get_preferred_width (xpaned->bottom_left_child, &bl[0], &bl[1]);
+ else
+ bl[0] = bl[1] = 0;
+
+ if (xpaned->bottom_right_child
+ && gtk_widget_get_visible (xpaned->bottom_right_child))
+ gtk_widget_get_preferred_width (xpaned->bottom_right_child,
+ &br[0], &br[1]);
+ else
+ br[0] = br[1] = 0;
+
+ /* add 2 times the set border-width to the GtkXPaneds requisition */
+ overhead = gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
+
+ /* also add the handle "thickness" to GtkXPaned's width requisition */
+ if (xpaned->top_left_child
+ && gtk_widget_get_visible (xpaned->top_left_child)
+ && xpaned->top_right_child
+ && gtk_widget_get_visible (xpaned->top_right_child)
+ && xpaned->bottom_left_child
+ && gtk_widget_get_visible (xpaned->bottom_left_child)
+ && xpaned->bottom_right_child
+ && gtk_widget_get_visible (xpaned->bottom_right_child))
+ {
+ gint handle_size;
+
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+ overhead += handle_size;
+ }
+
+ for (i = 0; i < 2; i++)
+ w[i] = (br[i] ? br[i] : MAX (tl[i] + tr[i], bl[i])) + overhead;
+
+ *minimal_width = w[0];
+ *natural_width = w[1];
+}
+
+static void
+gtk_xpaned_get_preferred_height (GtkWidget *widget,
+ gint *minimal_height,
+ gint *natural_height)
+{
+ GtkXPaned *xpaned = GTK_XPANED (widget);
+ gint tl[2], tr[2], bl[2], br[2];
+ gint overhead;
+ gint h[2];
+ int i;
+
+ if (xpaned->top_left_child
+ && gtk_widget_get_visible (xpaned->top_left_child))
+ gtk_widget_get_preferred_height (xpaned->top_left_child, &tl[0], &tl[1]);
+ else
+ tl[0] = tl[1] = 0;
+
+ if (xpaned->top_right_child
+ && gtk_widget_get_visible (xpaned->top_right_child))
+ gtk_widget_get_preferred_height (xpaned->top_right_child, &tr[0], &tr[1]);
+ else
+ tr[0] = tr[1] = 0;
+
+ if (xpaned->bottom_left_child
+ && gtk_widget_get_visible (xpaned->bottom_left_child))
+ gtk_widget_get_preferred_height (xpaned->bottom_left_child,
+ &bl[0], &bl[1]);
+ else
+ bl[0] = bl[1] = 0;
+
+ if (xpaned->bottom_right_child
+ && gtk_widget_get_visible (xpaned->bottom_right_child))
+ gtk_widget_get_preferred_height (xpaned->bottom_right_child,
+ &br[0], &br[1]);
+ else
+ br[0] = br[1] = 0;
+
+ /* add 2 times the set border-width to the GtkXPaneds requisition */
+ overhead = gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
+
+ /* also add the handle "thickness" to GtkXPaned's height-requisition */
+ if (xpaned->top_left_child
+ && gtk_widget_get_visible (xpaned->top_left_child)
+ && xpaned->top_right_child
+ && gtk_widget_get_visible (xpaned->top_right_child)
+ && xpaned->bottom_left_child
+ && gtk_widget_get_visible (xpaned->bottom_left_child)
+ && xpaned->bottom_right_child
+ && gtk_widget_get_visible (xpaned->bottom_right_child))
+ {
+ gint handle_size;
+
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+ overhead += handle_size;
+ }
+
+ for (i = 0; i < 2; i++)
+ h[i] = (br[i] ? br[i] : bl[i] + MAX (tl[i], tr[i])) + overhead;
+
+ *minimal_height = h[0];
+ *natural_height = h[1];
+}
static void gtk_xpaned_size_allocate (GtkWidget * widget,
GtkAllocation * allocation);
static void gtk_xpaned_unmap (GtkWidget * widget);
-static gboolean gtk_xpaned_expose (GtkWidget * widget,
- GdkEventExpose * event);
+static gboolean gtk_xpaned_draw (GtkWidget * widget,
+ cairo_t *ct);
static gboolean gtk_xpaned_enter (GtkWidget * widget,
GdkEventCrossing * event);
widget_class->unrealize = gtk_xpaned_unrealize;
widget_class->map = gtk_xpaned_map;
widget_class->unmap = gtk_xpaned_unmap;
- widget_class->expose_event = gtk_xpaned_expose;
+ widget_class->draw = gtk_xpaned_draw;
widget_class->focus = gtk_xpaned_focus;
widget_class->enter_notify_event = gtk_xpaned_enter;
widget_class->leave_notify_event = gtk_xpaned_leave;
widget_class->button_press_event = gtk_xpaned_button_press;
widget_class->button_release_event = gtk_xpaned_button_release;
widget_class->motion_notify_event = gtk_xpaned_motion;
- widget_class->size_request = gtk_xpaned_size_request;
+ widget_class->get_preferred_width = gtk_xpaned_get_preferred_width;
+ widget_class->get_preferred_height = gtk_xpaned_get_preferred_height;
+
widget_class->size_allocate = gtk_xpaned_size_allocate;
container_class->add = gtk_xpaned_add;
xpaned->drag_pos.y = -1;
}
-static void
-gtk_xpaned_size_request (GtkWidget * widget, GtkRequisition * requisition)
-{
- GtkXPaned *xpaned = GTK_XPANED (widget);
- GtkRequisition child_requisition;
-
- requisition->width = 0;
- requisition->height = 0;
-
- if (xpaned->top_left_child
- && gtk_widget_get_visible (xpaned->top_left_child))
- {
- gtk_widget_size_request (xpaned->top_left_child, &child_requisition);
-
- requisition->width = child_requisition.width;
- requisition->height = child_requisition.height;
- }
-
- if (xpaned->top_right_child
- && gtk_widget_get_visible (xpaned->top_right_child))
- {
- gtk_widget_size_request (xpaned->top_right_child, &child_requisition);
-
- requisition->width += child_requisition.width;
- requisition->height =
- MAX (requisition->height, child_requisition.height);
- }
-
- if (xpaned->bottom_left_child
- && gtk_widget_get_visible (xpaned->bottom_left_child))
- {
- gtk_widget_size_request (xpaned->bottom_left_child, &child_requisition);
-
- requisition->width = MAX (requisition->width, child_requisition.width);
- requisition->height += child_requisition.height;
- }
-
- if (xpaned->bottom_right_child
- && gtk_widget_get_visible (xpaned->bottom_right_child))
- {
- gtk_widget_size_request (xpaned->bottom_right_child,
- &child_requisition);
-
- requisition->width = child_requisition.width;
- requisition->height = child_requisition.height;
- }
-
- /* add 2 times the set border-width to the GtkXPaneds requisition */
- requisition->width += gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
- requisition->height += gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
-
- /* also add the handle "thickness" to GtkXPaneds width- and height-requisitions */
- if (xpaned->top_left_child
- && gtk_widget_get_visible (xpaned->top_left_child)
- && xpaned->top_right_child
- && gtk_widget_get_visible (xpaned->top_right_child)
- && xpaned->bottom_left_child
- && gtk_widget_get_visible (xpaned->bottom_left_child)
- && xpaned->bottom_right_child
- && gtk_widget_get_visible (xpaned->bottom_right_child))
- {
- gint handle_size;
-
- gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
- requisition->width += handle_size;
- requisition->height += handle_size;
- }
-}
-
void
gtk_xpaned_compute_position (GtkXPaned * xpaned,
const GtkAllocation * allocation,
&& gtk_widget_get_visible (xpaned->bottom_right_child))
{
/* what sizes do the children want to be at least at */
- gtk_widget_get_child_requisition (xpaned->top_left_child,
- &top_left_child_requisition);
- gtk_widget_get_child_requisition (xpaned->top_right_child,
- &top_right_child_requisition);
- gtk_widget_get_child_requisition (xpaned->bottom_left_child,
- &bottom_left_child_requisition);
- gtk_widget_get_child_requisition (xpaned->bottom_right_child,
- &bottom_right_child_requisition);
+ gtk_widget_get_preferred_size (xpaned->top_left_child,
+ &top_left_child_requisition, NULL);
+ gtk_widget_get_preferred_size (xpaned->top_right_child,
+ &top_right_child_requisition, NULL);
+ gtk_widget_get_preferred_size (xpaned->bottom_left_child,
+ &bottom_left_child_requisition, NULL);
+ gtk_widget_get_preferred_size (xpaned->bottom_right_child,
+ &bottom_right_child_requisition, NULL);
/* determine the total requisition-sum of all requisitions of borders,
* handles, children etc. */
gdk_window_set_user_data (xpaned->handle_south, xpaned);
gdk_window_set_user_data (xpaned->handle_middle, xpaned);
- gdk_cursor_unref (attributes_east.cursor);
- gdk_cursor_unref (attributes_west.cursor);
- gdk_cursor_unref (attributes_north.cursor);
- gdk_cursor_unref (attributes_south.cursor);
- gdk_cursor_unref (attributes_middle.cursor);
-
- {
- GtkStyle *style = gtk_widget_get_style (widget);
- style = gtk_style_attach (style, gtk_widget_get_window (widget));
- gtk_widget_set_style (widget, style);
- }
-
+ g_object_unref (attributes_east.cursor);
+ g_object_unref (attributes_west.cursor);
+ g_object_unref (attributes_north.cursor);
+ g_object_unref (attributes_south.cursor);
+ g_object_unref (attributes_middle.cursor);
if (xpaned->top_left_child
&& gtk_widget_get_visible (xpaned->top_left_child)
}
static gboolean
-gtk_xpaned_expose (GtkWidget * widget, GdkEventExpose * event)
+gtk_xpaned_draw (GtkWidget * widget, cairo_t *cr)
{
GtkXPaned *xpaned = GTK_XPANED (widget);
gint handle_size;
- GdkRectangle horizontalClipArea;
- GdkRectangle verticalClipArea;
/* determine size of handle(s) */
gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
&& xpaned->bottom_right_child
&& gtk_widget_get_visible (xpaned->bottom_right_child))
{
- GtkStateType state;
+ GtkStyleContext *context;
- if (gtk_widget_is_focus (widget))
- state = GTK_STATE_SELECTED;
- else if (xpaned->handle_prelit)
- state = GTK_STATE_PRELIGHT;
- else
- state = gtk_widget_get_state (widget);
-
- horizontalClipArea.x = xpaned->handle_pos_west.x;
- horizontalClipArea.y = xpaned->handle_pos_west.y;
- horizontalClipArea.width =
- xpaned->handle_pos_west.width + handle_size +
- xpaned->handle_pos_east.width;
- horizontalClipArea.height = handle_size;
-
- verticalClipArea.x = xpaned->handle_pos_north.x;
- verticalClipArea.y = xpaned->handle_pos_north.y;
- verticalClipArea.width = handle_size;
- verticalClipArea.height =
- xpaned->handle_pos_north.height + handle_size +
- xpaned->handle_pos_south.height;
-
- gtk_paint_handle (gtk_widget_get_style (widget),
- gtk_widget_get_window (widget),
- state,
- GTK_SHADOW_NONE,
- &horizontalClipArea,
- widget,
- "paned",
- xpaned->handle_pos_east.x - handle_size - 256 / 2,
- xpaned->handle_pos_west.y + 1,
- 256 + handle_size, handle_size - 2,
- /*xpaned->handle_pos_west.x,
- xpaned->handle_pos_west.y + 1,
- xpaned->handle_pos_west.width + handle_size + xpaned->handle_pos_east.width,
- handle_size - 2, */
- GTK_ORIENTATION_HORIZONTAL);
- gtk_paint_handle (gtk_widget_get_style (widget),
- gtk_widget_get_window (widget),
- state,
- GTK_SHADOW_NONE,
- &verticalClipArea,
- widget,
- "paned",
- xpaned->handle_pos_north.x + 1,
- xpaned->handle_pos_south.y - handle_size - 256 / 2,
- handle_size - 2, 256 + handle_size,
- /*xpaned->handle_pos_north.x + 1,
- xpaned->handle_pos_north.y,
- handle_size - 2,
- xpaned->handle_pos_north.height + handle_size + xpaned->handle_pos_south.height, */
- GTK_ORIENTATION_VERTICAL);
+ context = gtk_widget_get_style_context (widget);
+ gtk_render_handle (context, cr,
+ xpaned->handle_pos_east.x - handle_size - 256 / 2,
+ xpaned->handle_pos_west.y + 1,
+ 256 + handle_size, handle_size - 2);
+
+ gtk_render_handle (context, cr,
+ xpaned->handle_pos_north.x + 1,
+ xpaned->handle_pos_south.y - handle_size - 256 / 2,
+ handle_size - 2, 256 + handle_size);
}
/* Chain up to draw children */
- GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+ GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
return FALSE;
}
update_drag (GtkXPaned * xpaned)
{
GdkPoint pos;
+ GtkWidget *widget = GTK_WIDGET (xpaned);
gint handle_size;
GtkRequisition size;
GtkAllocation allocation;
- gtk_widget_get_allocation (GTK_WIDGET (xpaned), &allocation);
- gtk_widget_get_pointer (GTK_WIDGET (xpaned), &pos.x, &pos.y);
+ gtk_widget_get_allocation (widget, &allocation);
+
+ gdk_window_get_device_position (gtk_widget_get_window (widget),
+ gdk_device_manager_get_client_pointer (
+ gdk_display_get_device_manager (
+ gtk_widget_get_display (widget))),
+ &pos.x, &pos.y, NULL);
+ if (!gtk_widget_get_has_window (widget))
+ {
+ pos.x -= allocation.x;
+ pos.y -= allocation.y;
+ }
if (xpaned->in_drag_vert)
{
if (is_rtl (xpaned))
{
- gtk_widget_style_get (GTK_WIDGET (xpaned),
- "handle-size", &handle_size, NULL);
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
size.height = allocation.height - pos.y - handle_size;
}
if (is_rtl (xpaned))
{
- gtk_widget_style_get (GTK_WIDGET (xpaned),
- "handle-size", &handle_size, NULL);
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
size.width = allocation.width - pos.x - handle_size;
}
if (is_rtl (xpaned))
{
- gtk_widget_style_get (GTK_WIDGET (xpaned),
- "handle-size", &handle_size, NULL);
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
size.width = allocation.width - pos.x - handle_size;
size.height = allocation.height - pos.y - handle_size;
return retval;
}
+static void
+gtk_xpaned_button_press_grab (GdkWindow *handle, GdkEventButton *event)
+{
+ /* We need a server grab here, not gtk_grab_add(), since
+ * we don't want to pass events on to the widget's children */
+ gdk_device_grab (event->device, handle,
+ GDK_OWNERSHIP_NONE,
+ FALSE,
+ (GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK),
+ NULL, event->time);
+}
+
static gboolean
gtk_xpaned_button_press (GtkWidget * widget, GdkEventButton * event)
{
event->window == xpaned->handle_middle && event->button == 1)
{
xpaned->in_drag_vert_and_horiz = TRUE;
-
- /* We need a server grab here, not gtk_grab_add(), since
- * we don't want to pass events on to the widget's children */
- if (gdk_pointer_grab (xpaned->handle_middle,
- FALSE,
- GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK,
- NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
- {
- }
-
+ gtk_xpaned_button_press_grab (xpaned->handle_middle, event);
xpaned->drag_pos.x = event->x;
xpaned->drag_pos.y = event->y;
event->window != xpaned->handle_middle && event->button == 1)
{
xpaned->in_drag_vert = TRUE;
-
- /* We need a server grab here, not gtk_grab_add(), since
- * we don't want to pass events on to the widget's children */
- if (gdk_pointer_grab (xpaned->handle_east,
- FALSE,
- GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK,
- NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
- {
- }
-
+ gtk_xpaned_button_press_grab (xpaned->handle_east, event);
xpaned->drag_pos.y = event->y;
return TRUE;
event->window != xpaned->handle_middle && event->button == 1)
{
xpaned->in_drag_vert = TRUE;
-
- /* We need a server grab here, not gtk_grab_add(), since
- * we don't want to pass events on to the widget's children */
- if (gdk_pointer_grab (xpaned->handle_west,
- FALSE,
- GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK,
- NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
- {
- }
-
+ gtk_xpaned_button_press_grab (xpaned->handle_west, event);
xpaned->drag_pos.y = event->y;
return TRUE;
event->window != xpaned->handle_middle && event->button == 1)
{
xpaned->in_drag_horiz = TRUE;
-
- /* We need a server grab here, not gtk_grab_add(), since
- * we don't want to pass events on to the widget's children */
- if (gdk_pointer_grab (xpaned->handle_north,
- FALSE,
- GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK,
- NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
- {
- }
-
+ gtk_xpaned_button_press_grab (xpaned->handle_north, event);
xpaned->drag_pos.x = event->x;
return TRUE;
event->window != xpaned->handle_middle && event->button == 1)
{
xpaned->in_drag_horiz = TRUE;
-
- /* We need a server grab here, not gtk_grab_add(), since
- * we don't want to pass events on to the widget's children */
- if (gdk_pointer_grab (xpaned->handle_south,
- FALSE,
- GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK,
- NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
- {
- }
-
+ gtk_xpaned_button_press_grab (xpaned->handle_south, event);
xpaned->drag_pos.x = event->x;
return TRUE;
xpaned->in_drag_vert = FALSE;
xpaned->drag_pos.y = -1;
xpaned->position_set = TRUE;
- gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
- event->time);
+ gdk_device_ungrab (event->device, event->time);
return TRUE;
}
else if (xpaned->in_drag_horiz && (event->button == 1))
xpaned->in_drag_horiz = FALSE;
xpaned->drag_pos.x = -1;
xpaned->position_set = TRUE;
- gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
- event->time);
+ gdk_device_ungrab (event->device, event->time);
return TRUE;
}
else if (xpaned->in_drag_vert_and_horiz && (event->button == 1))
xpaned->drag_pos.x = -1;
xpaned->drag_pos.y = -1;
xpaned->position_set = TRUE;
- gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
- event->time);
+ gdk_device_ungrab (event->device, event->time);
return TRUE;
}