static gboolean qtcTreeViewLeave(GtkWidget *widget, GdkEventMotion *event, void *data) { QTC_UNUSED(event); QTC_UNUSED(data); if (GTK_IS_TREE_VIEW(widget)) { QtCTreeView *tv = qtcTreeViewLookupHash(widget, false); if (tv) { GtkTreeView *treeView = GTK_TREE_VIEW(widget); QtcRect rect = {0, 0, -1, -1 }; QtcRect alloc = qtcWidgetGetAllocation(widget); if (tv->path && tv->column) { gtk_tree_view_get_background_area( treeView, tv->path, tv->column, (GdkRectangle*)&rect); } if (tv->fullWidth) { rect.x = 0; rect.width = alloc.width; } if (tv->path) { gtk_tree_path_free(tv->path); } tv->path = NULL; tv->column = NULL; gtk_tree_view_convert_bin_window_to_widget_coords( treeView, rect.x, rect.y, &rect.x, &rect.y); gtk_widget_queue_draw_area( widget, rect.x, rect.y, rect.width, rect.height); } } return false; }
static VALUE rg_convert_bin_window_to_widget_coords(VALUE self, VALUE bx, VALUE by) { gint wx, wy; gtk_tree_view_convert_bin_window_to_widget_coords(_SELF(self), NUM2INT(bx), NUM2INT(by), &wx, &wy); return rb_ary_new3(2, INT2NUM(wx), INT2NUM(wy)); }
/* Position function for the popup menu. * It positions the popup below the selected row, or above if it doesn't fit. * If there is no selection, positions on the top left corner. */ static void tree_view_popup_menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, GguTreeView *self) { GtkTreeView *view = GTK_TREE_VIEW (self); GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (self)), x, y); /* We let GTK do whatever it wants, so we just give a reasonable * suggestion without the need to check if we really end up with something * valuable (though we try hard) */ *push_in = TRUE; selection = gtk_tree_view_get_selection (view); if (gtk_tree_selection_get_selected (selection, &model, &iter)) { GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (self)); GtkTreePath *path; GdkRectangle rect; GtkRequisition menu_req; gtk_widget_size_request (GTK_WIDGET (menu), &menu_req); path = gtk_tree_model_get_path (model, &iter); gtk_tree_view_get_cell_area (view, path, NULL, &rect); gtk_tree_view_convert_bin_window_to_widget_coords (view, 0, rect.y, NULL, &rect.y); gtk_tree_path_free (path); (*y) += rect.y + rect.height; /* If the menu doesn't fit below the row, try above */ if ((*y) + menu_req.height > gdk_screen_get_height (screen)) { (*y) -= rect.height + menu_req.height; } } else { gtk_tree_view_convert_bin_window_to_widget_coords (view, 0, *y, NULL, y); } }
static void queue_redraw (GtkWidget *widget, int x) { int hh, xo; GtkAllocation a; if (x < 0) return; gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (widget), 0, 0, &xo, &hh); gtk_widget_get_allocation (widget, &a); gtk_widget_queue_draw_area (widget, x + xo, hh, 1, a.height - hh); }
static void qtcTreeViewUpdatePosition(GtkWidget *widget, int x, int y) { if (GTK_IS_TREE_VIEW(widget)) { QtCTreeView *tv = qtcTreeViewLookupHash(widget, false); if (tv) { GtkTreeView *treeView = GTK_TREE_VIEW(widget); GtkTreePath *path = NULL; GtkTreeViewColumn *column = NULL; gtk_tree_view_get_path_at_pos(treeView, x, y, &path, &column, 0L, 0L); if (!qtcTreeViewSamePath(tv->path, path)) { // prepare update area // get old rectangle QtcRect oldRect = {0, 0, -1, -1 }; QtcRect newRect = {0, 0, -1, -1 }; QtcRect updateRect; QtcRect alloc = qtcWidgetGetAllocation(widget); if (tv->path && tv->column) { gtk_tree_view_get_background_area( treeView, tv->path, tv->column, (GdkRectangle*)&oldRect); } if (tv->fullWidth) { oldRect.x = 0; oldRect.width = alloc.width; } // get new rectangle and update position if (path && column) { gtk_tree_view_get_background_area( treeView, path, column, (GdkRectangle*)&newRect); } if (path && column && tv->fullWidth) { newRect.x = 0; newRect.width = alloc.width; } // take the union of both rectangles if (oldRect.width > 0 && oldRect.height > 0) { if (newRect.width > 0 && newRect.height > 0) { qtcRectUnion(&oldRect, &newRect, &updateRect); } else { updateRect = oldRect; } } else { updateRect = newRect; } // store new cell info if (tv->path) gtk_tree_path_free(tv->path); tv->path = path ? gtk_tree_path_copy(path) : NULL; tv->column = column; // convert to widget coordinates and schedule redraw gtk_tree_view_convert_bin_window_to_widget_coords( treeView, updateRect.x, updateRect.y, &updateRect.x, &updateRect.y); gtk_widget_queue_draw_area( widget, updateRect.x, updateRect.y, updateRect.width, updateRect.height); } if (path) { gtk_tree_path_free(path); } } } }
static gboolean _dtv_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip) { int bin_x, bin_y; GtkTreePath *path = NULL; GtkTreeViewColumn *column; GtkTreeIter iter; GtkTreeModel *model; GdkRectangle cell_area; GString *markup; gboolean had_info = FALSE; gtk_tree_view_convert_widget_to_bin_window_coords ( GTK_TREE_VIEW (widget), x, y, &bin_x, &bin_y); if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), bin_x, bin_y, &path, &column, NULL, NULL)) { model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); if (gtk_tree_model_get_iter (model, &iter, path)) { /* show some useful information */ Diagram *diagram; Layer *layer; DiaObject *object; gtk_tree_model_get (model, &iter, DIAGRAM_COLUMN, &diagram, -1); gtk_tree_model_get (model, &iter, LAYER_COLUMN, &layer, -1); gtk_tree_model_get (model, &iter, OBJECT_COLUMN, &object, -1); markup = g_string_new (NULL); if (diagram) { gchar *em = g_markup_printf_escaped ("<b>%s</b>: %s\n", _("Diagram"), diagram->filename); g_string_append (markup, em); g_free (em); } if (layer) { gchar *name = layer_get_name (layer); gchar *em = g_markup_printf_escaped ("<b>%s</b>: %s\n", _("Layer"), name); g_string_append (markup, em); g_free (em); g_free (name); } else if (diagram) { int layers = data_layer_count (DIA_DIAGRAM_DATA (diagram)); g_string_append_printf (markup, g_dngettext (GETTEXT_PACKAGE, "%d Layer", "%d Layers", layers), layers); } if (object) { gchar *em = g_markup_printf_escaped ("<b>%s</b>: %s\n", _("Type"), object->type->name); g_string_append (markup, em); g_free (em); g_string_append_printf (markup, "<b>%s</b>: %g,%g\n", Q_("object|Position"), object->position.x, object->position.y); g_string_append_printf (markup, "%d %s", g_list_length (object->children), _("Children")); /* and some dia_object_get_meta ? */ } else if (layer) { int objects = layer_object_count (layer); g_string_append_printf (markup, g_dngettext (GETTEXT_PACKAGE, "%d Object", "%d Objects", objects), objects); } if (markup->len > 0) { gtk_tree_view_get_cell_area (GTK_TREE_VIEW (widget), path, column, &cell_area); gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (widget), cell_area.x, cell_area.y, &cell_area.x, &cell_area.y); gtk_tooltip_set_tip_area (tooltip, &cell_area); gtk_tooltip_set_markup (tooltip, markup->str); had_info = TRUE; } /* drop references */ if (diagram) g_object_unref (diagram); g_string_free (markup, TRUE); } gtk_tree_path_free (path); if (had_info) return TRUE; } return GTK_WIDGET_CLASS (_dtv_parent_class)->query_tooltip (widget, x, y, keyboard_mode, tooltip); }