summaryrefslogtreecommitdiffstats
path: root/src/libgdl
diff options
context:
space:
mode:
authorgustav_b <gustav_b@users.sourceforge.net>2007-09-16 15:30:50 +0000
committergustav_b <gustav_b@users.sourceforge.net>2007-09-16 15:30:50 +0000
commit71c54d4ca81eb9735c8d8b0d710667ac05798a5e (patch)
tree9864aa4e6b03f98c6357c4ba82802192753de63b /src/libgdl
parentnoop: (SvgBuilder::setTransform): Mark argument as not being written through. (diff)
downloadinkscape-71c54d4ca81eb9735c8d8b0d710667ac05798a5e.tar.gz
inkscape-71c54d4ca81eb9735c8d8b0d710667ac05798a5e.zip
Add handling of focus tabbing for GdlDockItem + various DockItem focus
fixes. (bzr r3764)
Diffstat (limited to 'src/libgdl')
-rw-r--r--src/libgdl/gdl-dock-item-grip.c11
-rw-r--r--src/libgdl/gdl-dock-item.c120
-rw-r--r--src/libgdl/gdl-dock-item.h20
-rw-r--r--src/libgdl/libgdlmarshal.c13
-rw-r--r--src/libgdl/libgdlmarshal.h13
-rw-r--r--src/libgdl/libgdlmarshal.list1
6 files changed, 155 insertions, 23 deletions
diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c
index d1ba2372c..86e7bc14c 100644
--- a/src/libgdl/gdl-dock-item-grip.c
+++ b/src/libgdl/gdl-dock-item-grip.c
@@ -135,14 +135,17 @@ gdl_dock_item_grip_expose (GtkWidget *widget,
gint layout_height;
gint text_x;
gint text_y;
+ gboolean item_or_child_has_focus;
grip = GDL_DOCK_ITEM_GRIP (widget);
gdl_dock_item_grip_get_title_area (grip, &title_area);
- /* draw background, highlight it if the dock item has focus */
- bg_style = (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (grip->item)) ?
- gtk_widget_get_style (widget)->mid_gc[widget->state] :
- gtk_widget_get_style (widget)->dark_gc[widget->state]);
+ /* draw background, highlight it if the dock item or any of its
+ * descendants have focus */
+ bg_style = (gdl_dock_item_or_child_has_focus (grip->item) ?
+ gtk_widget_get_style (widget)->dark_gc[widget->state] :
+ gtk_widget_get_style (widget)->mid_gc[widget->state]);
+
gdk_draw_rectangle (GDK_DRAWABLE (widget->window), bg_style, TRUE,
1, 0, widget->allocation.width - 1, widget->allocation.height);
diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c
index 87fbb41a0..3be8dd3e2 100644
--- a/src/libgdl/gdl-dock-item.c
+++ b/src/libgdl/gdl-dock-item.c
@@ -81,6 +81,10 @@ static void gdl_dock_item_forall (GtkContainer *container,
gpointer callback_data);
static GtkType gdl_dock_item_child_type (GtkContainer *container);
+static void gdl_dock_item_set_focus_child (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer callback_data);
+
static void gdl_dock_item_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gdl_dock_item_size_allocate (GtkWidget *widget,
@@ -93,6 +97,9 @@ static void gdl_dock_item_style_set (GtkWidget *widget,
static gint gdl_dock_item_expose (GtkWidget *widget,
GdkEventExpose *event);
+static void gdl_dock_item_move_focus_child (GdlDockItem *item,
+ GtkDirectionType dir);
+
static gint gdl_dock_item_button_changed (GtkWidget *widget,
GdkEventButton *event);
static gint gdl_dock_item_motion (GtkWidget *widget,
@@ -157,6 +164,7 @@ enum {
DOCK_DRAG_BEGIN,
DOCK_DRAG_MOTION,
DOCK_DRAG_END,
+ MOVE_FOCUS_CHILD,
LAST_SIGNAL
};
@@ -192,6 +200,40 @@ struct _GdlDockItemPrivate {
GDL_CLASS_BOILERPLATE (GdlDockItem, gdl_dock_item, GdlDockObject, GDL_TYPE_DOCK_OBJECT);
static void
+add_tab_bindings (GtkBindingSet *binding_set,
+ GdkModifierType modifiers,
+ GtkDirectionType direction)
+{
+ gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
+ "move_focus_child", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
+ "move_focus_child", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
+}
+
+static void
+add_arrow_bindings (GtkBindingSet *binding_set,
+ guint keysym,
+ GtkDirectionType direction)
+{
+ guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
+
+ gtk_binding_entry_add_signal (binding_set, keysym, 0,
+ "move_focus_child", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
+ gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
+ "move_focus_child", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
+ gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
+ "move_focus_child", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
+ gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
+ "move_focus_child", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
+}
+
+static void
gdl_dock_item_class_init (GdlDockItemClass *klass)
{
static gboolean style_initialized = FALSE;
@@ -201,6 +243,7 @@ gdl_dock_item_class_init (GdlDockItemClass *klass)
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
GdlDockObjectClass *object_class;
+ GtkBindingSet *binding_set;
g_object_class = G_OBJECT_CLASS (klass);
gtk_object_class = GTK_OBJECT_CLASS (klass);
@@ -230,6 +273,7 @@ gdl_dock_item_class_init (GdlDockItemClass *klass)
container_class->remove = gdl_dock_item_remove;
container_class->forall = gdl_dock_item_forall;
container_class->child_type = gdl_dock_item_child_type;
+ container_class->set_focus_child = gdl_dock_item_set_focus_child;
object_class->is_compound = FALSE;
@@ -332,10 +376,38 @@ gdl_dock_item_class_init (GdlDockItemClass *klass)
1,
G_TYPE_BOOLEAN);
+ gdl_dock_item_signals [MOVE_FOCUS_CHILD] =
+ g_signal_new ("move_focus_child",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GdlDockItemClass, move_focus_child),
+ NULL, /* accumulator */
+ NULL, /* accu_data */
+ gdl_marshal_VOID__ENUM,
+ G_TYPE_NONE,
+ 1,
+ GTK_TYPE_DIRECTION_TYPE);
+
+
+ /* key bindings */
+
+ binding_set = gtk_binding_set_by_class (klass);
+
+ add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
+ add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
+ add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
+ add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
+
+ add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
+ add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
+ add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
+ add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
+
klass->has_grip = TRUE;
klass->dock_drag_begin = NULL;
klass->dock_drag_motion = NULL;
klass->dock_drag_end = NULL;
+ klass->move_focus_child = gdl_dock_item_move_focus_child;
klass->set_orientation = gdl_dock_item_real_set_orientation;
if (!style_initialized)
@@ -624,6 +696,19 @@ gdl_dock_item_child_type (GtkContainer *container)
}
static void
+gdl_dock_item_set_focus_child (GtkContainer *container,
+ GtkWidget *child,
+ gpointer callback_data)
+{
+ g_return_if_fail (GDL_IS_DOCK_ITEM (container));
+
+ if (GTK_CONTAINER_CLASS (parent_class)->set_focus_child)
+ (* GTK_CONTAINER_CLASS (parent_class)->set_focus_child) (container, child);
+
+ gdl_dock_item_showhide_grip (GDL_DOCK_ITEM (container));
+}
+
+static void
gdl_dock_item_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
@@ -879,6 +964,14 @@ gdl_dock_item_expose (GtkWidget *widget,
return FALSE;
}
+static void
+gdl_dock_item_move_focus_child (GdlDockItem *item,
+ GtkDirectionType dir)
+{
+ g_return_if_fail (GDL_IS_DOCK_ITEM (item));
+ gtk_widget_child_focus (GTK_WIDGET (item->child), dir);
+}
+
#define EVENT_IN_GRIP_EVENT_WINDOW(ev,gr) \
((gr) != NULL && (ev)->window == GDL_DOCK_ITEM_GRIP (gr)->title_window)
@@ -923,6 +1016,10 @@ gdl_dock_item_button_changed (GtkWidget *widget,
/* Left mousebutton click on dockitem. */
if (!locked && event->button == 1 && event->type == GDK_BUTTON_PRESS) {
+
+ if (!gdl_dock_item_or_child_has_focus (item))
+ gtk_widget_grab_focus (GTK_WIDGET (item));
+
/* Set in_drag flag, grab pointer and call begin drag operation. */
if (in_handle) {
item->_priv->start_x = event->x;
@@ -943,6 +1040,7 @@ gdl_dock_item_button_changed (GtkWidget *widget,
if (GDL_DOCK_ITEM_IN_DRAG (item)) {
/* User dropped widget somewhere. */
gdl_dock_item_drag_end (item, FALSE);
+ gtk_widget_grab_focus (GTK_WIDGET (item));
event_handled = TRUE;
}
else if (GDL_DOCK_ITEM_IN_PREDRAG (item)) {
@@ -1348,6 +1446,8 @@ gdl_dock_item_dock (GdlDockObject *object,
gdl_dock_object_thaw (new_parent);
if (parent)
gdl_dock_object_thaw (parent);
+
+
}
static void
@@ -1917,6 +2017,26 @@ gdl_dock_item_preferred_size (GdlDockItem *item,
}
+gboolean
+gdl_dock_item_or_child_has_focus (GdlDockItem *item)
+{
+ GtkWidget *item_child;
+ gboolean item_or_child_has_focus;
+
+ g_return_val_if_fail (GDL_IS_DOCK_ITEM (item), FALSE);
+
+ for (item_child = GTK_CONTAINER (item)->focus_child;
+ item_child && GTK_IS_CONTAINER (item_child) && GTK_CONTAINER (item_child)->focus_child;
+ item_child = GTK_CONTAINER (item_child)->focus_child) ;
+
+ item_or_child_has_focus =
+ (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (item)) ||
+ (GTK_IS_WIDGET (item_child) && GTK_WIDGET_HAS_FOCUS (item_child)));
+
+ return item_or_child_has_focus;
+}
+
+
/* ----- gtk orientation type exporter/importer ----- */
static void
diff --git a/src/libgdl/gdl-dock-item.h b/src/libgdl/gdl-dock-item.h
index 6eec28aeb..17484ad04 100644
--- a/src/libgdl/gdl-dock-item.h
+++ b/src/libgdl/gdl-dock-item.h
@@ -93,15 +93,17 @@ struct _GdlDockItemClass {
gboolean has_grip;
/* virtuals */
- void (* dock_drag_begin) (GdlDockItem *item);
- void (* dock_drag_motion) (GdlDockItem *item,
- gint x,
- gint y);
- void (* dock_drag_end) (GdlDockItem *item,
- gboolean cancelled);
+ void (* dock_drag_begin) (GdlDockItem *item);
+ void (* dock_drag_motion) (GdlDockItem *item,
+ gint x,
+ gint y);
+ void (* dock_drag_end) (GdlDockItem *item,
+ gboolean cancelled);
+ void (* move_focus_child) (GdlDockItem *item,
+ GtkDirectionType direction);
- void (* set_orientation) (GdlDockItem *item,
- GtkOrientation orientation);
+ void (* set_orientation) (GdlDockItem *item,
+ GtkOrientation orientation);
};
/* additional macros */
@@ -186,6 +188,8 @@ void gdl_dock_item_set_default_position (GdlDockItem *item,
void gdl_dock_item_preferred_size (GdlDockItem *item,
GtkRequisition *req);
+gboolean gdl_dock_item_or_child_has_focus (GdlDockItem *item);
+
G_END_DECLS
#endif
diff --git a/src/libgdl/libgdlmarshal.c b/src/libgdl/libgdlmarshal.c
index 06a4e7596..764f6fed0 100644
--- a/src/libgdl/libgdlmarshal.c
+++ b/src/libgdl/libgdlmarshal.c
@@ -1,4 +1,3 @@
-#include "libgdlmarshal.h"
#include <glib-object.h>
@@ -50,7 +49,9 @@
/* VOID:VOID (./libgdlmarshal.list:1) */
-/* VOID:INT,INT (./libgdlmarshal.list:2) */
+/* VOID:ENUM (./libgdlmarshal.list:2) */
+
+/* VOID:INT,INT (./libgdlmarshal.list:3) */
void
gdl_marshal_VOID__INT_INT (GClosure *closure,
GValue *return_value,
@@ -87,7 +88,7 @@ gdl_marshal_VOID__INT_INT (GClosure *closure,
data2);
}
-/* VOID:UINT,UINT (./libgdlmarshal.list:3) */
+/* VOID:UINT,UINT (./libgdlmarshal.list:4) */
void
gdl_marshal_VOID__UINT_UINT (GClosure *closure,
GValue *return_value,
@@ -124,9 +125,9 @@ gdl_marshal_VOID__UINT_UINT (GClosure *closure,
data2);
}
-/* VOID:BOOLEAN (./libgdlmarshal.list:4) */
+/* VOID:BOOLEAN (./libgdlmarshal.list:5) */
-/* VOID:OBJECT,ENUM,BOXED (./libgdlmarshal.list:5) */
+/* VOID:OBJECT,ENUM,BOXED (./libgdlmarshal.list:6) */
void
gdl_marshal_VOID__OBJECT_ENUM_BOXED (GClosure *closure,
GValue *return_value,
@@ -165,5 +166,5 @@ gdl_marshal_VOID__OBJECT_ENUM_BOXED (GClosure *closure,
data2);
}
-/* VOID:BOXED (./libgdlmarshal.list:6) */
+/* VOID:BOXED (./libgdlmarshal.list:7) */
diff --git a/src/libgdl/libgdlmarshal.h b/src/libgdl/libgdlmarshal.h
index 3e0116e1a..2d6bc800f 100644
--- a/src/libgdl/libgdlmarshal.h
+++ b/src/libgdl/libgdlmarshal.h
@@ -9,7 +9,10 @@ G_BEGIN_DECLS
/* VOID:VOID (./libgdlmarshal.list:1) */
#define gdl_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID
-/* VOID:INT,INT (./libgdlmarshal.list:2) */
+/* VOID:ENUM (./libgdlmarshal.list:2) */
+#define gdl_marshal_VOID__ENUM g_cclosure_marshal_VOID__ENUM
+
+/* VOID:INT,INT (./libgdlmarshal.list:3) */
extern void gdl_marshal_VOID__INT_INT (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -17,7 +20,7 @@ extern void gdl_marshal_VOID__INT_INT (GClosure *closure,
gpointer invocation_hint,
gpointer marshal_data);
-/* VOID:UINT,UINT (./libgdlmarshal.list:3) */
+/* VOID:UINT,UINT (./libgdlmarshal.list:4) */
extern void gdl_marshal_VOID__UINT_UINT (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -25,10 +28,10 @@ extern void gdl_marshal_VOID__UINT_UINT (GClosure *closure,
gpointer invocation_hint,
gpointer marshal_data);
-/* VOID:BOOLEAN (./libgdlmarshal.list:4) */
+/* VOID:BOOLEAN (./libgdlmarshal.list:5) */
#define gdl_marshal_VOID__BOOLEAN g_cclosure_marshal_VOID__BOOLEAN
-/* VOID:OBJECT,ENUM,BOXED (./libgdlmarshal.list:5) */
+/* VOID:OBJECT,ENUM,BOXED (./libgdlmarshal.list:6) */
extern void gdl_marshal_VOID__OBJECT_ENUM_BOXED (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -36,7 +39,7 @@ extern void gdl_marshal_VOID__OBJECT_ENUM_BOXED (GClosure *closure,
gpointer invocation_hint,
gpointer marshal_data);
-/* VOID:BOXED (./libgdlmarshal.list:6) */
+/* VOID:BOXED (./libgdlmarshal.list:7) */
#define gdl_marshal_VOID__BOXED g_cclosure_marshal_VOID__BOXED
G_END_DECLS
diff --git a/src/libgdl/libgdlmarshal.list b/src/libgdl/libgdlmarshal.list
index f3200d6d2..750989abc 100644
--- a/src/libgdl/libgdlmarshal.list
+++ b/src/libgdl/libgdlmarshal.list
@@ -1,4 +1,5 @@
VOID:VOID
+VOID:ENUM
VOID:INT,INT
VOID:UINT,UINT
VOID:BOOLEAN