X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Flibgdl%2Fgdl-dock-item.c;h=e8ae3d54b1cc343052af09c77b8f2b9fa8e9a58a;hb=c4c17e735501a09577fecb91cbeae69e8516b8be;hp=87fbb41a08474779f71ded6b803a787d499ab471;hpb=88203f7fac722a3539389dbc0e580176f3458653;p=inkscape.git diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index 87fbb41a0..e8ae3d54b 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 }; @@ -191,6 +199,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) { @@ -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) @@ -623,6 +695,19 @@ gdl_dock_item_child_type (GtkContainer *container) return G_TYPE_NONE; } +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)) { @@ -1200,7 +1298,7 @@ gdl_dock_item_dock (GdlDockObject *object, } if (req.width > 1) g_object_set (object, "preferred-width", req.width, NULL); - if (req.height > 1) + if (req.height > 1 && object_req.height > req.height) g_object_set (object, "preferred-height", object_req.height - req.height, NULL); break; @@ -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