* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <config.h>
+#include "config.h"
#include "gtkintl.h"
#include "gtkpaned.h"
#include "gtkbindings.h"
-#include "gtksignal.h"
#include "gdk/gdkkeysyms.h"
#include "gtkwindow.h"
#include "gtkmain.h"
LAST_SIGNAL
};
-static void gtk_paned_class_init (GtkPanedClass *klass);
-static void gtk_paned_init (GtkPaned *paned);
static void gtk_paned_set_property (GObject *object,
guint prop_id,
const GValue *value,
static void gtk_paned_unrealize (GtkWidget *widget);
static void gtk_paned_map (GtkWidget *widget);
static void gtk_paned_unmap (GtkWidget *widget);
+static void gtk_paned_state_changed (GtkWidget *widget,
+ GtkStateType previous_state);
static gboolean gtk_paned_expose (GtkWidget *widget,
GdkEventExpose *event);
static gboolean gtk_paned_enter (GtkWidget *widget,
static gboolean gtk_paned_toggle_handle_focus (GtkPaned *paned);
static GType gtk_paned_child_type (GtkContainer *container);
-
-static GtkContainerClass *parent_class = NULL;
+static void gtk_paned_grab_notify (GtkWidget *widget,
+ gboolean was_grabbed);
struct _GtkPanedPrivate
{
GtkWidget *saved_focus;
- GtkPaned *first_paned;
- guint32 grab_time;
+ GtkPaned *first_paned;
+ guint32 grab_time;
};
-GType
-gtk_paned_get_type (void)
-{
- static GType paned_type = 0;
-
- if (!paned_type)
- {
- static const GTypeInfo paned_info =
- {
- sizeof (GtkPanedClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_paned_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkPaned),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gtk_paned_init,
- NULL, /* value_table */
- };
-
- paned_type = g_type_register_static (GTK_TYPE_CONTAINER, g_intern_static_string ("GtkPaned"),
- &paned_info, G_TYPE_FLAG_ABSTRACT);
- }
-
- return paned_type;
-}
+G_DEFINE_ABSTRACT_TYPE (GtkPaned, gtk_paned, GTK_TYPE_CONTAINER)
static guint signals[LAST_SIGNAL] = { 0 };
container_class = (GtkContainerClass *) class;
paned_class = (GtkPanedClass *) class;
- parent_class = g_type_class_peek_parent (class);
-
object_class->set_property = gtk_paned_set_property;
object_class->get_property = gtk_paned_get_property;
object_class->finalize = gtk_paned_finalize;
widget_class->button_release_event = gtk_paned_button_release;
widget_class->motion_notify_event = gtk_paned_motion;
widget_class->grab_broken_event = gtk_paned_grab_broken;
+ widget_class->grab_notify = gtk_paned_grab_notify;
+ widget_class->state_changed = gtk_paned_state_changed;
container_class->add = gtk_paned_add;
container_class->remove = gtk_paned_remove;
TRUE,
GTK_PARAM_READWRITE));
+ /**
+ * GtkPaned::cycle-child-focus:
+ * @widget: the object that received the signal
+ * @reversed: whether cycling backward or forward
+ *
+ * The ::cycle-child-focus signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted to cycle the focus between the children of the paned.
+ *
+ * The default binding is f6.
+ *
+ * Since: 2.0
+ */
signals [CYCLE_CHILD_FOCUS] =
- g_signal_new ("cycle_child_focus",
+ g_signal_new (I_("cycle_child_focus"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkPanedClass, cycle_child_focus),
G_TYPE_BOOLEAN, 1,
G_TYPE_BOOLEAN);
+ /**
+ * GtkPaned::toggle-handle-focus:
+ * @widget: the object that received the signal
+ *
+ * The ::toggle-handle-focus is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted to accept the current position of the handle and then
+ * move focus to the next widget in the focus chain.
+ *
+ * The default binding is Tab.
+ *
+ * Since: 2.0
+ */
signals [TOGGLE_HANDLE_FOCUS] =
- g_signal_new ("toggle_handle_focus",
+ g_signal_new (I_("toggle_handle_focus"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkPanedClass, toggle_handle_focus),
_gtk_marshal_BOOLEAN__VOID,
G_TYPE_BOOLEAN, 0);
+ /**
+ * GtkPaned::move-handle:
+ * @widget: the object that received the signal
+ * @scroll_type: a #GtkScrollType
+ *
+ * The ::move-handle signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted to move the handle when the user is using key bindings
+ * to move it.
+ *
+ * Since: 2.0
+ */
signals[MOVE_HANDLE] =
- g_signal_new ("move_handle",
+ g_signal_new (I_("move_handle"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkPanedClass, move_handle),
G_TYPE_BOOLEAN, 1,
GTK_TYPE_SCROLL_TYPE);
+ /**
+ * GtkPaned::cycle-handle-focus:
+ * @widget: the object that received the signal
+ * @reversed: whether cycling backward or forward
+ *
+ * The ::cycle-handle-focus signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted to cycle whether the paned should grab focus to allow
+ * the user to change position of the handle by using key bindings.
+ *
+ * The default binding for this signal is f8.
+ *
+ * Since: 2.0
+ */
signals [CYCLE_HANDLE_FOCUS] =
- g_signal_new ("cycle_handle_focus",
+ g_signal_new (I_("cycle_handle_focus"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkPanedClass, cycle_handle_focus),
G_TYPE_BOOLEAN, 1,
G_TYPE_BOOLEAN);
+ /**
+ * GtkPaned::accept-position:
+ * @widget: the object that received the signal
+ *
+ * The ::accept-position signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted to accept the current position of the handle when
+ * moving it using key bindings.
+ *
+ * The default binding for this signal is Return or Space.
+ *
+ * Since: 2.0
+ */
signals [ACCEPT_POSITION] =
- g_signal_new ("accept_position",
+ g_signal_new (I_("accept_position"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkPanedClass, accept_position),
_gtk_marshal_BOOLEAN__VOID,
G_TYPE_BOOLEAN, 0);
+ /**
+ * GtkPaned::cancel-position:
+ * @widget: the object that received the signal
+ *
+ * The ::cancel-position signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted to cancel moving the position of the handle using key
+ * bindings. The position of the handle will be reset to the value prior to
+ * moving it.
+ *
+ * The default binding for this signal is Escape.
+ *
+ * Since: 2.0
+ */
signals [CANCEL_POSITION] =
- g_signal_new ("cancel_position",
+ g_signal_new (I_("cancel_position"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkPanedClass, cancel_position),
gtk_binding_entry_add_signal (binding_set,
GDK_Return, 0,
"accept_position", 0);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_ISO_Enter, 0,
+ "accept_position", 0);
gtk_binding_entry_add_signal (binding_set,
GDK_KP_Enter, 0,
"accept_position", 0);
add_move_binding (binding_set, GDK_KP_Home, 0, GTK_SCROLL_START);
add_move_binding (binding_set, GDK_End, 0, GTK_SCROLL_END);
add_move_binding (binding_set, GDK_KP_End, 0, GTK_SCROLL_END);
+
+ g_type_class_add_private (object_class, sizeof (GtkPanedPrivate));
}
static GType
paned->last_allocation = -1;
paned->in_drag = FALSE;
- paned->priv = g_new0 (GtkPanedPrivate, 1);
+ paned->priv = G_TYPE_INSTANCE_GET_PRIVATE (paned, GTK_TYPE_PANED, GtkPanedPrivate);
paned->last_child1_focus = NULL;
paned->last_child2_focus = NULL;
paned->in_recursion = FALSE;
gtk_paned_set_saved_focus (paned, NULL);
gtk_paned_set_first_paned (paned, NULL);
- g_free (paned->priv);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ G_OBJECT_CLASS (gtk_paned_parent_class)->finalize (object);
}
static void
attributes.y = paned->handle_pos.y;
attributes.width = paned->handle_pos.width;
attributes.height = paned->handle_pos.height;
- attributes.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
- paned->cursor_type);
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK);
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR;
+ attributes_mask = GDK_WA_X | GDK_WA_Y;
+ if (GTK_WIDGET_IS_SENSITIVE (widget))
+ {
+ attributes.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+ paned->cursor_type);
+ attributes_mask |= GDK_WA_CURSOR;
+ }
paned->handle = gdk_window_new (widget->window,
&attributes, attributes_mask);
gdk_window_set_user_data (paned->handle, paned);
- gdk_cursor_unref (attributes.cursor);
+ if (attributes_mask & GDK_WA_CURSOR)
+ gdk_cursor_unref (attributes.cursor);
widget->style = gtk_style_attach (widget->style, widget->window);
gtk_paned_set_saved_focus (paned, NULL);
gtk_paned_set_first_paned (paned, NULL);
- if (GTK_WIDGET_CLASS (parent_class)->unrealize)
- (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+ if (GTK_WIDGET_CLASS (gtk_paned_parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (gtk_paned_parent_class)->unrealize) (widget);
}
static void
gdk_window_show (paned->handle);
- GTK_WIDGET_CLASS (parent_class)->map (widget);
+ GTK_WIDGET_CLASS (gtk_paned_parent_class)->map (widget);
}
static void
gdk_window_hide (paned->handle);
- GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+ GTK_WIDGET_CLASS (gtk_paned_parent_class)->unmap (widget);
}
static gboolean
}
/* Chain up to draw children */
- GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+ GTK_WIDGET_CLASS (gtk_paned_parent_class)->expose_event (widget, event);
return FALSE;
}
*/
GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
- retval = (* GTK_WIDGET_CLASS (parent_class)->focus) (widget, direction);
+ retval = (* GTK_WIDGET_CLASS (gtk_paned_parent_class)->focus) (widget, direction);
GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
return retval;
return TRUE;
}
+static void
+stop_drag (GtkPaned *paned)
+{
+ paned->in_drag = FALSE;
+ paned->drag_pos = -1;
+ paned->position_set = TRUE;
+ gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (paned)),
+ paned->priv->grab_time);
+}
+
+static void
+gtk_paned_grab_notify (GtkWidget *widget,
+ gboolean was_grabbed)
+{
+ GtkPaned *paned = GTK_PANED (widget);
+
+ if (!was_grabbed && paned->in_drag)
+ stop_drag (paned);
+}
+
+static void
+gtk_paned_state_changed (GtkWidget *widget,
+ GtkStateType previous_state)
+{
+ GtkPaned *paned = GTK_PANED (widget);
+ GdkCursor *cursor;
+
+ if (GTK_WIDGET_REALIZED (paned))
+ {
+ if (GTK_WIDGET_IS_SENSITIVE (widget))
+ cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+ paned->cursor_type);
+ else
+ cursor = NULL;
+
+ gdk_window_set_cursor (paned->handle, cursor);
+
+ if (cursor)
+ gdk_cursor_unref (cursor);
+ }
+}
+
static gboolean
gtk_paned_button_release (GtkWidget *widget,
GdkEventButton *event)
if (paned->in_drag && (event->button == 1))
{
- paned->in_drag = FALSE;
- paned->drag_pos = -1;
- paned->position_set = TRUE;
- gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
- paned->priv->grab_time);
+ stop_drag (paned);
+
return TRUE;
}
g_object_thaw_notify (object);
gtk_widget_queue_resize (GTK_WIDGET (paned));
+
+#ifdef G_OS_WIN32
+ /* Hacky work-around for bug #144269 */
+ if (paned->child2 != NULL)
+ {
+ gtk_widget_queue_draw (paned->child2);
+ }
+#endif
}
/**
paned->min_position,
paned->max_position);
- gtk_widget_set_child_visible (paned->child1, paned->child1_size != 0);
- gtk_widget_set_child_visible (paned->child2, paned->child1_size != allocation);
+ if (paned->child1)
+ gtk_widget_set_child_visible (paned->child1, paned->child1_size != 0);
+
+ if (paned->child2)
+ gtk_widget_set_child_visible (paned->child2, paned->child1_size != allocation);
g_object_freeze_notify (G_OBJECT (paned));
if (paned->child1_size != old_position)
}
}
- if (parent_class->set_focus_child)
- (* parent_class->set_focus_child) (container, focus_child);
+ if (GTK_CONTAINER_CLASS (gtk_paned_parent_class)->set_focus_child)
+ (* GTK_CONTAINER_CLASS (gtk_paned_parent_class)->set_focus_child) (container, focus_child);
}
static void
}
else if (GTK_IS_CONTAINER (widget))
{
- gtk_container_foreach (GTK_CONTAINER (widget),
+ gtk_container_forall (GTK_CONTAINER (widget),
(GtkCallback)get_child_panes, panes);
}
}