📄 gtkhandlebox.c
字号:
hb = GTK_HANDLE_BOX (widget); if (GTK_WIDGET_DRAWABLE (widget)) { if (hb->child_detached) { /* The area parameter does not make sense in this case, so we * repaint everything. */ gtk_handle_box_draw_ghost (hb); area->x = 0; area->y = 0; area->width = 2 * GTK_CONTAINER (hb)->border_width + DRAG_HANDLE_SIZE; area->height = area->width + GTK_BIN (hb)->child->allocation.height; area->width += GTK_BIN (hb)->child->allocation.width; gtk_handle_box_paint (widget, NULL, area); } else gtk_handle_box_paint (widget, NULL, area); }}static gintgtk_handle_box_expose (GtkWidget *widget, GdkEventExpose *event){ GtkHandleBox *hb; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_HANDLE_BOX (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (GTK_WIDGET_DRAWABLE (widget)) { hb = GTK_HANDLE_BOX (widget); if (event->window == widget->window) { if (hb->child_detached) gtk_handle_box_draw_ghost (hb); } else gtk_handle_box_paint (widget, event, NULL); } return FALSE;}static gintgtk_handle_box_button_changed (GtkWidget *widget, GdkEventButton *event){ GtkHandleBox *hb; gboolean event_handled; GdkCursor *fleur; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_HANDLE_BOX (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); hb = GTK_HANDLE_BOX (widget); event_handled = FALSE; if ((event->button == 1) && (event->type == GDK_BUTTON_PRESS || event->type == GDK_2BUTTON_PRESS)) { GtkWidget *child; gboolean in_handle; if (event->window != hb->bin_window) return FALSE; child = GTK_BIN (hb)->child; switch (hb->handle_position) { case GTK_POS_LEFT: in_handle = event->x < DRAG_HANDLE_SIZE; break; case GTK_POS_TOP: in_handle = event->y < DRAG_HANDLE_SIZE; break; case GTK_POS_RIGHT: in_handle = event->x > 2 * GTK_CONTAINER (hb)->border_width + child->allocation.width; break; case GTK_POS_BOTTOM: in_handle = event->y > 2 * GTK_CONTAINER (hb)->border_width + child->allocation.height; break; default: in_handle = FALSE; break; } if (!child) { in_handle = FALSE; event_handled = TRUE; } if (in_handle) { if (event->type == GDK_BUTTON_PRESS) /* Start a drag */ { gint desk_x, desk_y; gint root_x, root_y; gint width, height; gdk_window_get_deskrelative_origin (hb->bin_window, &desk_x, &desk_y); gdk_window_get_origin (hb->bin_window, &root_x, &root_y); gdk_window_get_size (hb->bin_window, &width, &height); hb->float_allocation.x = root_x - event->x_root; hb->float_allocation.y = root_y - event->y_root; hb->float_allocation.width = width; hb->float_allocation.height = height; hb->deskoff_x = desk_x - root_x; hb->deskoff_y = desk_y - root_y; gdk_window_get_origin (widget->window, &root_x, &root_y); gdk_window_get_size (widget->window, &width, &height); hb->attach_allocation.x = root_x; hb->attach_allocation.y = root_y; hb->attach_allocation.width = width; hb->attach_allocation.height = height; hb->in_drag = TRUE; fleur = gdk_cursor_new (GDK_FLEUR); if (gdk_pointer_grab (widget->window, FALSE, (GDK_BUTTON1_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK), NULL, fleur, GDK_CURRENT_TIME) != 0) { hb->in_drag = FALSE; } gdk_cursor_destroy (fleur); event_handled = TRUE; } else if (hb->child_detached) /* Double click */ { gtk_handle_box_reattach (hb); } } } else if (event->type == GDK_BUTTON_RELEASE && hb->in_drag) { if (event->window != widget->window) return FALSE; gdk_pointer_ungrab (GDK_CURRENT_TIME); hb->in_drag = FALSE; event_handled = TRUE; } return event_handled;}static gintgtk_handle_box_motion (GtkWidget *widget, GdkEventMotion *event){ GtkHandleBox *hb; gint new_x, new_y; gint snap_edge; gboolean is_snapped = FALSE; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_HANDLE_BOX (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); hb = GTK_HANDLE_BOX (widget); if (!hb->in_drag) return FALSE; if (!hb->in_drag || (event->window != widget->window)) return FALSE; /* Calculate the attachment point on the float, if the float * were detached */ new_x = 0; new_y = 0; gdk_window_get_pointer (GDK_ROOT_PARENT(), &new_x, &new_y, NULL); new_x += hb->float_allocation.x; new_y += hb->float_allocation.y; snap_edge = hb->snap_edge; if (snap_edge == -1) snap_edge = (hb->handle_position == GTK_POS_LEFT || hb->handle_position == GTK_POS_RIGHT) ? GTK_POS_TOP : GTK_POS_LEFT; /* First, check if the snapped edge is aligned */ switch (snap_edge) { case GTK_POS_TOP: is_snapped = abs (hb->attach_allocation.y - new_y) < TOLERANCE; break; case GTK_POS_BOTTOM: is_snapped = abs (hb->attach_allocation.y + (gint)hb->attach_allocation.height - new_y - (gint)hb->float_allocation.height) < TOLERANCE; break; case GTK_POS_LEFT: is_snapped = abs (hb->attach_allocation.x - new_x) < TOLERANCE; break; case GTK_POS_RIGHT: is_snapped = abs (hb->attach_allocation.x + (gint)hb->attach_allocation.width - new_x - (gint)hb->float_allocation.width) < TOLERANCE; break; } /* Next, check if coordinates in the other direction are sufficiently * aligned */ if (is_snapped) { gint float_pos1 = 0; /* Initialize to suppress warnings */ gint float_pos2 = 0; gint attach_pos1 = 0; gint attach_pos2 = 0; switch (snap_edge) { case GTK_POS_TOP: case GTK_POS_BOTTOM: attach_pos1 = hb->attach_allocation.x; attach_pos2 = hb->attach_allocation.x + hb->attach_allocation.width; float_pos1 = new_x; float_pos2 = new_x + hb->float_allocation.width; break; case GTK_POS_LEFT: case GTK_POS_RIGHT: attach_pos1 = hb->attach_allocation.y; attach_pos2 = hb->attach_allocation.y + hb->attach_allocation.height; float_pos1 = new_y; float_pos2 = new_y + hb->float_allocation.height; break; } is_snapped = ((attach_pos1 - TOLERANCE < float_pos1) && (attach_pos2 + TOLERANCE > float_pos2)) || ((float_pos1 - TOLERANCE < attach_pos1) && (float_pos2 + TOLERANCE > attach_pos2)); } if (is_snapped) { if (hb->child_detached) { hb->child_detached = FALSE; gdk_window_hide (hb->float_window); gdk_window_reparent (hb->bin_window, widget->window, 0, 0); hb->float_window_mapped = FALSE; gtk_signal_emit (GTK_OBJECT (hb), handle_box_signals[SIGNAL_CHILD_ATTACHED], GTK_BIN (hb)->child); gtk_widget_queue_resize (widget); } } else { gint width, height; gdk_window_get_size (hb->float_window, &width, &height); new_x += hb->deskoff_x; new_y += hb->deskoff_y; switch (hb->handle_position) { case GTK_POS_LEFT: new_y += ((gint)hb->float_allocation.height - height) / 2; break; case GTK_POS_RIGHT: new_x += (gint)hb->float_allocation.width - width; new_y += ((gint)hb->float_allocation.height - height) / 2; break; case GTK_POS_TOP: new_x += ((gint)hb->float_allocation.width - width) / 2; break; case GTK_POS_BOTTOM: new_x += ((gint)hb->float_allocation.width - width) / 2; new_y += (gint)hb->float_allocation.height - height; break; } if (hb->child_detached) { gdk_window_move (hb->float_window, new_x, new_y); gdk_window_raise (hb->float_window); } else { gint width; gint height; GtkRequisition child_requisition; hb->child_detached = TRUE; if (GTK_BIN (hb)->child) gtk_widget_get_child_requisition (GTK_BIN (hb)->child, &child_requisition); else { child_requisition.width = 0; child_requisition.height = 0; } width = child_requisition.width + 2 * GTK_CONTAINER (hb)->border_width; height = child_requisition.height + 2 * GTK_CONTAINER (hb)->border_width; gdk_window_move_resize (hb->float_window, new_x, new_y, width, height); gdk_window_reparent (hb->bin_window, hb->float_window, 0, 0); gdk_window_set_hints (hb->float_window, new_x, new_y, 0, 0, 0, 0, GDK_HINT_POS); gdk_window_show (hb->float_window); hb->float_window_mapped = TRUE;#if 0 /* this extra move is neccessary if we use decorations, or our * window manager insists on decorations. */ gdk_flush (); gdk_window_move (hb->float_window, new_x, new_y); gdk_flush ();#endif /* 0 */ gtk_signal_emit (GTK_OBJECT (hb), handle_box_signals[SIGNAL_CHILD_DETACHED], GTK_BIN (hb)->child); gtk_handle_box_draw_ghost (hb); gtk_widget_queue_resize (widget); } } return TRUE;}static voidgtk_handle_box_add (GtkContainer *container, GtkWidget *widget){ g_return_if_fail (GTK_IS_HANDLE_BOX (container)); g_return_if_fail (GTK_BIN (container)->child == NULL); g_return_if_fail (widget->parent == NULL); gtk_widget_set_parent_window (widget, GTK_HANDLE_BOX (container)->bin_window); GTK_CONTAINER_CLASS (parent_class)->add (container, widget);}static voidgtk_handle_box_remove (GtkContainer *container, GtkWidget *widget){ g_return_if_fail (GTK_IS_HANDLE_BOX (container)); g_return_if_fail (GTK_BIN (container)->child == widget); GTK_CONTAINER_CLASS (parent_class)->remove (container, widget); gtk_handle_box_reattach (GTK_HANDLE_BOX (container));}static gintgtk_handle_box_delete_event (GtkWidget *widget, GdkEventAny *event){ GtkHandleBox *hb; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_HANDLE_BOX (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); hb = GTK_HANDLE_BOX (widget); if (event->window == hb->float_window) { gtk_handle_box_reattach (hb); return TRUE; } return FALSE;}static voidgtk_handle_box_reattach (GtkHandleBox *hb){ if (hb->child_detached) { hb->child_detached = FALSE; if (GTK_WIDGET_REALIZED (hb)) { gdk_window_hide (hb->float_window); gdk_window_reparent (hb->bin_window, GTK_WIDGET (hb)->window, 0, 0); if (GTK_BIN (hb)->child) gtk_signal_emit (GTK_OBJECT (hb), handle_box_signals[SIGNAL_CHILD_ATTACHED], GTK_BIN (hb)->child); } hb->float_window_mapped = FALSE; } if (hb->in_drag) { gdk_pointer_ungrab (GDK_CURRENT_TIME); hb->in_drag = FALSE; } gtk_widget_queue_resize (GTK_WIDGET (hb));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -