On Fri, 2004-10-22 at 18:47 +0200, Christof Petig wrote: > Hi, > > After having commented on bug #80980 and #50619 without an answer in a > week I'm asking here for further comments. > > Up to now the tooltip design is based on a static tip per widget. To > support per row (or column or cell) tooltips in treeview the tooltip API > has to get redesigned. > > Two possible implementations come to my mind: > > 1) Adding the option of using a function pointer as an argument to > gtk_tooltips_set_tip. Storing that in GtkTooltipsData and using it (if > !=NULL) to query the tip according to the relative mouse position. > [perhaps using a boolean argument to distinguish between normal and > private tip]. > > E.g. void gtk_tooltips_set_tip_function(GtkTooltips *tooltips, > GtkWidget *widget, const gchar *(fun)(GtkWidget*,gint x,gint y,gboolean > private_tip)); > > This option keeps the current logic of an (widget-)external tip object. > > 2) Adding a signal to each widget to query for the matching tip. (three > arguments: x,y,private) call this signal if there is no tip registered > for this widget. This could gradually eliminate the need to store the > tips outside of the widget structure. > > This option delegates figuring out the tip text back to the widget. > > Which way to go? (I'd prefer 2 since I do not know the reason for > starting with 1 in the past). I'm not really enthused about a callback-based approach here. It seems simple at first glance, but I think it would get pretty complex for the case where tooltip texts or tooltip areas change dynamically. (For tooltip areas, think scrolling in a GtkTreeView.) It also doesn't handle the case of "keyboard_mode" for tooltips - try Control-F1 in a dialog with tooltips - the tooltip for the currently selected widget is displayed and you can browse tooltips by tabbing between widgets. And it isn't very extensible - think about setting markup for a tooltip, or as suggested recently putting a widget in a tooltip (not sure that is a good idea, but it's at least a conceivable approach) Are these problems addressable within the callback model? Yes, I think so. But I think you'd lose the essential simplicity of it. You'd have to introduce some objects and/or interfaces that are passed around, multiple callbacks, etc. (Feel free to prove me wrong and come up with a detailed proposal.) Here's an alternate approach I came up with talking to Jonathan (he's promised a more detailed writeup of GtkTreeView requirements) is a little more of a radical change. * We ditch (deprecate) GtkTooltips; GtkTooltips objects are 90% just annoying to create and memory manage. * The one case where the tooltips object isn't just annoying is the sticky delay behavior where mousing between tooltips in a single group doesn't involve a full delay for it to pop up. For this functionality, we add GtkTooltipsGroup, along the lines of GtkSizeGroup. * For simple cases, we add "tooltip" and "tooltip-uses-markup" properties to GtkWidget. * We can reimplement GtkTooltips using GtkTooltipsGroup and gtk_widget_set_tooltip(). * For custom tooltips, we introduce the GtkTooltipsWindow widget, There is a singleton GtkTooltipsWindow object per toplevel, which can be retrieved with: gtk_widget_get_tooltips_window() This both handles the display of the yellow rectangle, and the logic for showing/hiding the tooltip based on keyboard and mouse actions. typedef enum { GTK_TOOLTIPS_MOUSE, GTK_TOOLTIPS_KEYBOARD } GtkTooltipsContext; void gtk_tooltips_window_begin (GtkTooltipsWindow *window, GtkTooltipsContext context, GObject *owner); void gtk_tooltips_window_end (GtkTooltipsWindow *window, GtkTooltipsContext context, GObject *owner); void gtk_tooltips_window_set_text (GtkTooltipsWindow *window, GtkTooltipsContext context, GObject *owner, const char *text); void gtk_tooltips_window_set_markup (GtkTooltipsWindow *window, GtkTooltipsContext context, GObject *owner, const char *markup); void gtk_tooltips_window_set_area (GtkTooltipsWindow *window, GtkTooltipsContext context, GdkWindow *relative_to, int x, int y, int width, int height); void gtk_tooltips_window_set_group (GtkTooltipsWindow *window, GtkTooltipsContext context, GObject *owner, GtkTooltipsGroup group); The concepts of the above are: - The GtkTooltipsWindow keeps two stacks of "active objects" for keyboard and mouse focus. With each object in the stack, we store text/markup rectangle, and possible GtkTooltipsGroup. - You call tw.begin (MOUSE) on when the mouse enters a tooltips area, tw.begin (KEYBOARD) on a tooltips object getting keyboard focus and tw.end (MOUSE/KEYBOARD) on mouse leave / focus out. - The 'GObject *owner*' arguments allow proper handling of nested tooltips areas. (think a treeview with tooltips with tooltips on individual rows.) It can be any GObject - the widget itself, a GdkWindow, whatever. A lot of the details of the above maybe should be a little different than I've sketched out, but I think it is a whole lot simpler than any callback-based mechanism with the same set of functionality. Regards, Owen
Attachment:
signature.asc
Description: This is a digitally signed message part