📄 gtkcontainer.c
字号:
/* Get a list of the containers children */ children = NULL; gtk_container_forall (container, gtk_container_children_callback, &children); children = g_list_reverse (children); /* children = gtk_container_children (container); */ if (children) { /* Remove any children which are inappropriate for focus movement */ tmp_list = children; while (tmp_list) { if (GTK_WIDGET_IS_SENSITIVE (tmp_list->data) && GTK_WIDGET_DRAWABLE (tmp_list->data) && (GTK_IS_CONTAINER (tmp_list->data) || GTK_WIDGET_CAN_FOCUS (tmp_list->data))) tmp_list = tmp_list->next; else { tmp_list2 = tmp_list; tmp_list = tmp_list->next; children = g_list_remove_link (children, tmp_list2); g_list_free_1 (tmp_list2); } } switch (direction) { case GTK_DIR_TAB_FORWARD: case GTK_DIR_TAB_BACKWARD: return_val = gtk_container_focus_tab (container, children, direction); break; case GTK_DIR_UP: case GTK_DIR_DOWN: return_val = gtk_container_focus_up_down (container, children, direction); break; case GTK_DIR_LEFT: case GTK_DIR_RIGHT: return_val = gtk_container_focus_left_right (container, children, direction); break; } g_list_free (children); } } return return_val;}static gintgtk_container_focus_tab (GtkContainer *container, GList *children, GtkDirectionType direction){ GtkWidget *child; GtkWidget *child2; GList *tmp_list; guint length; guint i, j; length = g_list_length (children); /* sort the children in the y direction */ for (i = 1; i < length; i++) { j = i; tmp_list = g_list_nth (children, j); child = tmp_list->data; while (j > 0) { child2 = tmp_list->prev->data; if (child->allocation.y < child2->allocation.y) { tmp_list->data = tmp_list->prev->data; tmp_list = tmp_list->prev; j--; } else break; } tmp_list->data = child; } /* sort the children in the x direction while * maintaining the y direction sort. */ for (i = 1; i < length; i++) { j = i; tmp_list = g_list_nth (children, j); child = tmp_list->data; while (j > 0) { child2 = tmp_list->prev->data; if ((child->allocation.x < child2->allocation.x) && (child->allocation.y == child2->allocation.y)) { tmp_list->data = tmp_list->prev->data; tmp_list = tmp_list->prev; j--; } else break; } tmp_list->data = child; } /* if we are going backwards then reverse the order * of the children. */ if (direction == GTK_DIR_TAB_BACKWARD) children = g_list_reverse (children); return gtk_container_focus_move (container, children, direction);}static gintgtk_container_focus_up_down (GtkContainer *container, GList *children, GtkDirectionType direction){ GtkWidget *child; GtkWidget *child2; GList *tmp_list; gint dist1, dist2; gint focus_x; gint focus_width; guint length; guint i, j; /* return failure if there isn't a focus child */ if (container->focus_child) { focus_width = container->focus_child->allocation.width / 2; focus_x = container->focus_child->allocation.x + focus_width; } else { focus_width = GTK_WIDGET (container)->allocation.width; if (GTK_WIDGET_NO_WINDOW (container)) focus_x = GTK_WIDGET (container)->allocation.x; else focus_x = 0; } length = g_list_length (children); /* sort the children in the y direction */ for (i = 1; i < length; i++) { j = i; tmp_list = g_list_nth (children, j); child = tmp_list->data; while (j > 0) { child2 = tmp_list->prev->data; if (child->allocation.y < child2->allocation.y) { tmp_list->data = tmp_list->prev->data; tmp_list = tmp_list->prev; j--; } else break; } tmp_list->data = child; } /* sort the children in distance in the x direction * in distance from the current focus child while maintaining the * sort in the y direction */ for (i = 1; i < length; i++) { j = i; tmp_list = g_list_nth (children, j); child = tmp_list->data; dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x; while (j > 0) { child2 = tmp_list->prev->data; dist2 = (child2->allocation.x + child2->allocation.width / 2) - focus_x; if ((dist1 < dist2) && (child->allocation.y >= child2->allocation.y)) { tmp_list->data = tmp_list->prev->data; tmp_list = tmp_list->prev; j--; } else break; } tmp_list->data = child; } /* go and invalidate any widget which is too * far from the focus widget. */ if (!container->focus_child && (direction == GTK_DIR_UP)) focus_x += focus_width; tmp_list = children; while (tmp_list) { child = tmp_list->data; dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x; if (((direction == GTK_DIR_DOWN) && (dist1 < 0)) || ((direction == GTK_DIR_UP) && (dist1 > 0))) tmp_list->data = NULL; tmp_list = tmp_list->next; } if (direction == GTK_DIR_UP) children = g_list_reverse (children); return gtk_container_focus_move (container, children, direction);}static gintgtk_container_focus_left_right (GtkContainer *container, GList *children, GtkDirectionType direction){ GtkWidget *child; GtkWidget *child2; GList *tmp_list; gint dist1, dist2; gint focus_y; gint focus_height; guint length; guint i, j; /* return failure if there isn't a focus child */ if (container->focus_child) { focus_height = container->focus_child->allocation.height / 2; focus_y = container->focus_child->allocation.y + focus_height; } else { focus_height = GTK_WIDGET (container)->allocation.height; if (GTK_WIDGET_NO_WINDOW (container)) focus_y = GTK_WIDGET (container)->allocation.y; else focus_y = 0; } length = g_list_length (children); /* sort the children in the x direction */ for (i = 1; i < length; i++) { j = i; tmp_list = g_list_nth (children, j); child = tmp_list->data; while (j > 0) { child2 = tmp_list->prev->data; if (child->allocation.x < child2->allocation.x) { tmp_list->data = tmp_list->prev->data; tmp_list = tmp_list->prev; j--; } else break; } tmp_list->data = child; } /* sort the children in distance in the y direction * in distance from the current focus child while maintaining the * sort in the x direction */ for (i = 1; i < length; i++) { j = i; tmp_list = g_list_nth (children, j); child = tmp_list->data; dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y; while (j > 0) { child2 = tmp_list->prev->data; dist2 = (child2->allocation.y + child2->allocation.height / 2) - focus_y; if ((dist1 < dist2) && (child->allocation.x >= child2->allocation.x)) { tmp_list->data = tmp_list->prev->data; tmp_list = tmp_list->prev; j--; } else break; } tmp_list->data = child; } /* go and invalidate any widget which is too * far from the focus widget. */ if (!container->focus_child && (direction == GTK_DIR_LEFT)) focus_y += focus_height; tmp_list = children; while (tmp_list) { child = tmp_list->data; dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y; if (((direction == GTK_DIR_RIGHT) && (dist1 < 0)) || ((direction == GTK_DIR_LEFT) && (dist1 > 0))) tmp_list->data = NULL; tmp_list = tmp_list->next; } if (direction == GTK_DIR_LEFT) children = g_list_reverse (children); return gtk_container_focus_move (container, children, direction);}static gintgtk_container_focus_move (GtkContainer *container, GList *children, GtkDirectionType direction){ GtkWidget *focus_child; GtkWidget *child; focus_child = container->focus_child; gtk_container_set_focus_child (container, NULL); while (children) { child = children->data; children = children->next; if (!child) continue; if (focus_child) { if (focus_child == child) { focus_child = NULL; if (GTK_WIDGET_DRAWABLE (child) && GTK_IS_CONTAINER (child) && !GTK_WIDGET_HAS_FOCUS (child)) if (gtk_container_focus (GTK_CONTAINER (child), direction)) return TRUE; } } else if (GTK_WIDGET_DRAWABLE (child)) { if (GTK_IS_CONTAINER (child)) { if (gtk_container_focus (GTK_CONTAINER (child), direction)) return TRUE; } else if (GTK_WIDGET_CAN_FOCUS (child)) { gtk_widget_grab_focus (child); return TRUE; } } } return FALSE;}static voidgtk_container_children_callback (GtkWidget *widget, gpointer client_data){ GList **children; children = (GList**) client_data; *children = g_list_prepend (*children, widget);}voidgtk_container_set_focus_vadjustment (GtkContainer *container, GtkAdjustment *adjustment){ g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); if (adjustment) g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); if (adjustment) gtk_object_ref (GTK_OBJECT(adjustment)); gtk_object_set_data_by_id_full (GTK_OBJECT (container), vadjustment_key_id, adjustment, (GtkDestroyNotify) gtk_object_unref);}voidgtk_container_set_focus_hadjustment (GtkContainer *container, GtkAdjustment *adjustment){ g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); if (adjustment) g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); if (adjustment) gtk_object_ref (GTK_OBJECT (adjustment)); gtk_object_set_data_by_id_full (GTK_OBJECT (container), hadjustment_key_id, adjustment, (GtkDestroyNotify) gtk_object_unref);}static voidgtk_container_show_all (GtkWidget *widget){ g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_CONTAINER (widget)); gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) gtk_widget_show_all, NULL); gtk_widget_show (widget);}static voidgtk_container_hide_all (GtkWidget *widget){ g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_CONTAINER (widget)); gtk_widget_hide (widget); gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) gtk_widget_hide_all, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -