forked from AuroraMiddleware/gtk
#408327, improve tooltip positioning.
2007-07-13 Kristian Rietveld <kris@imendio.com> #408327, improve tooltip positioning. * gtk/gtk.symbols: updated. * gtk/gtktooltip.[ch] (gtk_tooltip_position): factor out positioning code in here, (gtk_tooltip_set_tip_area): new function to set the tooltip area, (gtk_tooltip_reset), (_gtk_tooltip_handle_event): hide tooltip once the pointer leaves the tip area. * gtk/gtktreeview.[ch] (gtk_tree_view_set_tooltip_row), (gtk_tree_view_set_tooltip_cell): convenience functions to set tip area for row/column/cell. * tests/testtooltips.c (query_tooltip_tree_view_cb): use gtk_tree_view_set_tooltip_row. svn path=/trunk/; revision=18464
This commit is contained in:
parent
07c3dc414d
commit
da989212f3
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
||||
2007-07-13 Kristian Rietveld <kris@imendio.com>
|
||||
|
||||
#408327, improve tooltip positioning.
|
||||
|
||||
* gtk/gtk.symbols: updated.
|
||||
|
||||
* gtk/gtktooltip.[ch] (gtk_tooltip_position): factor out
|
||||
positioning code in here,
|
||||
(gtk_tooltip_set_tip_area): new function to set the tooltip
|
||||
area,
|
||||
(gtk_tooltip_reset), (_gtk_tooltip_handle_event): hide tooltip
|
||||
once the pointer leaves the tip area.
|
||||
|
||||
* gtk/gtktreeview.[ch] (gtk_tree_view_set_tooltip_row),
|
||||
(gtk_tree_view_set_tooltip_cell): convenience functions to set
|
||||
tip area for row/column/cell.
|
||||
|
||||
* tests/testtooltips.c (query_tooltip_tree_view_cb): use
|
||||
gtk_tree_view_set_tooltip_row.
|
||||
|
||||
2007-07-12 Cody Russell <bratsche@gnome.org>
|
||||
|
||||
* gdk/win32/gdkevents-win32.c
|
||||
|
@ -4079,6 +4079,7 @@ gtk_tooltip_set_icon
|
||||
gtk_tooltip_set_icon_from_stock
|
||||
gtk_tooltip_set_markup
|
||||
gtk_tooltip_set_text
|
||||
gtk_tooltip_set_tip_area
|
||||
gtk_tooltip_trigger_tooltip_query
|
||||
#endif
|
||||
#endif
|
||||
@ -4466,6 +4467,8 @@ gtk_tree_view_set_search_entry
|
||||
gtk_tree_view_set_search_equal_func
|
||||
gtk_tree_view_set_search_position_func
|
||||
gtk_tree_view_set_show_expanders
|
||||
gtk_tree_view_set_tooltip_row
|
||||
gtk_tree_view_set_tooltip_cell
|
||||
gtk_tree_view_set_vadjustment
|
||||
#ifndef GTK_DISABLE_DEPRECATED
|
||||
gtk_tree_view_tree_to_widget_coords
|
||||
|
188
gtk/gtktooltip.c
188
gtk/gtktooltip.c
@ -64,8 +64,11 @@ struct _GtkTooltip
|
||||
guint timeout_id;
|
||||
guint browse_mode_timeout_id;
|
||||
|
||||
GdkRectangle tip_area;
|
||||
|
||||
guint browse_mode_enabled : 1;
|
||||
guint keyboard_mode_enabled : 1;
|
||||
guint tip_area_set : 1;
|
||||
};
|
||||
|
||||
struct _GtkTooltipClass
|
||||
@ -327,6 +330,37 @@ gtk_tooltip_set_custom (GtkTooltip *tooltip,
|
||||
tooltip->custom_widget = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tooltip_set_tip_area:
|
||||
* @tooltip: a #GtkTooltip
|
||||
* @rect: a #GdkRectangle
|
||||
*
|
||||
* Sets the area of the widget, where the contents of this tooltip apply,
|
||||
* to be @rect (in widget coordinates). This is especially useful for
|
||||
* properly setting tooltips on #GtkTreeView rows and cells, #GtkIconViews,
|
||||
* etc.
|
||||
*
|
||||
* For setting tooltips on #GtkTreeView, please refer to the convenience
|
||||
* functions for this: gtk_tree_view_set_tooltip_row() and
|
||||
* gtk_tree_view_set_tooltip_cell().
|
||||
*
|
||||
* Since: 2.12
|
||||
*/
|
||||
void
|
||||
gtk_tooltip_set_tip_area (GtkTooltip *tooltip,
|
||||
GdkRectangle *rect)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TOOLTIP (tooltip));
|
||||
|
||||
if (!rect)
|
||||
tooltip->tip_area_set = FALSE;
|
||||
else
|
||||
{
|
||||
tooltip->tip_area_set = TRUE;
|
||||
tooltip->tip_area = *rect;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tooltip_trigger_tooltip_query:
|
||||
* @display: a #GdkDisplay
|
||||
@ -367,6 +401,7 @@ gtk_tooltip_reset (GtkTooltip *tooltip)
|
||||
gtk_tooltip_set_markup (tooltip, NULL);
|
||||
gtk_tooltip_set_icon (tooltip, NULL);
|
||||
gtk_tooltip_set_custom (tooltip, NULL);
|
||||
gtk_tooltip_set_tip_area (tooltip, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -633,6 +668,76 @@ gtk_tooltip_run_requery (GtkWidget **widget,
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tooltip_position (GtkTooltip *tooltip,
|
||||
GdkDisplay *display,
|
||||
GtkWidget *new_tooltip_widget)
|
||||
{
|
||||
gint x, y;
|
||||
GdkScreen *screen;
|
||||
|
||||
tooltip->tooltip_widget = new_tooltip_widget;
|
||||
|
||||
/* Position the tooltip */
|
||||
/* FIXME: should we swap this when RTL is enabled? */
|
||||
if (tooltip->keyboard_mode_enabled)
|
||||
{
|
||||
gdk_window_get_origin (new_tooltip_widget->window, &x, &y);
|
||||
if (GTK_WIDGET_NO_WINDOW (new_tooltip_widget))
|
||||
{
|
||||
x += new_tooltip_widget->allocation.x;
|
||||
y += new_tooltip_widget->allocation.y;
|
||||
}
|
||||
|
||||
/* For keyboard mode we position the tooltip below the widget,
|
||||
* right of the center of the widget.
|
||||
*/
|
||||
x += new_tooltip_widget->allocation.width / 2;
|
||||
y += new_tooltip_widget->allocation.height + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
guint cursor_size;
|
||||
|
||||
x = tooltip->last_x;
|
||||
y = tooltip->last_y;
|
||||
|
||||
/* For mouse mode, we position the tooltip right of the cursor,
|
||||
* a little below the cursor's center.
|
||||
*/
|
||||
cursor_size = gdk_display_get_default_cursor_size (display);
|
||||
x += cursor_size / 2;
|
||||
y += cursor_size / 2;
|
||||
}
|
||||
|
||||
screen = gtk_widget_get_screen (new_tooltip_widget);
|
||||
|
||||
/* Show it */
|
||||
if (tooltip->current_window)
|
||||
{
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GtkRequisition requisition;
|
||||
|
||||
gtk_widget_size_request (GTK_WIDGET (tooltip->current_window),
|
||||
&requisition);
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
|
||||
if (x + requisition.width > monitor.x + monitor.width)
|
||||
x -= x - (monitor.x + monitor.width) + requisition.width;
|
||||
else if (x < monitor.x)
|
||||
x = monitor.x;
|
||||
|
||||
if (y + requisition.height > monitor.y + monitor.height)
|
||||
y -= y - (monitor.y + monitor.height) + requisition.height;
|
||||
|
||||
gtk_window_move (GTK_WINDOW (tooltip->current_window), x, y);
|
||||
gtk_widget_show (GTK_WIDGET (tooltip->current_window));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tooltip_show_tooltip (GdkDisplay *display)
|
||||
{
|
||||
@ -687,40 +792,9 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
|
||||
tooltip->current_window = GTK_WINDOW (GTK_TOOLTIP (tooltip)->window);
|
||||
}
|
||||
|
||||
/* Position the tooltip */
|
||||
/* FIXME: should we swap this when RTL is enabled? */
|
||||
if (tooltip->keyboard_mode_enabled)
|
||||
{
|
||||
gdk_window_get_origin (tooltip_widget->window, &x, &y);
|
||||
if (GTK_WIDGET_NO_WINDOW (tooltip_widget))
|
||||
{
|
||||
x += tooltip_widget->allocation.x;
|
||||
y += tooltip_widget->allocation.y;
|
||||
}
|
||||
|
||||
/* For keyboard mode we position the tooltip below the widget,
|
||||
* right of the center of the widget.
|
||||
*/
|
||||
x += tooltip_widget->allocation.width / 2;
|
||||
y += tooltip_widget->allocation.height + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
guint cursor_size;
|
||||
|
||||
x = tooltip->last_x;
|
||||
y = tooltip->last_y;
|
||||
|
||||
/* For mouse mode, we position the tooltip right of the cursor,
|
||||
* a little below the cursor's center.
|
||||
*/
|
||||
cursor_size = gdk_display_get_default_cursor_size (display);
|
||||
x += cursor_size / 2;
|
||||
y += cursor_size / 2;
|
||||
}
|
||||
|
||||
screen = gtk_widget_get_screen (tooltip_widget);
|
||||
|
||||
/* FIXME: should use tooltip->current_window iso tooltip->window */
|
||||
if (screen != gtk_widget_get_screen (tooltip->window))
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (display,
|
||||
@ -733,32 +807,7 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
|
||||
G_CALLBACK (gtk_tooltip_display_closed), tooltip);
|
||||
}
|
||||
|
||||
tooltip->tooltip_widget = tooltip_widget;
|
||||
|
||||
/* Show it */
|
||||
if (tooltip->current_window)
|
||||
{
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GtkRequisition requisition;
|
||||
|
||||
gtk_widget_size_request (GTK_WIDGET (tooltip->current_window),
|
||||
&requisition);
|
||||
|
||||
monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
|
||||
if (x + requisition.width > monitor.x + monitor.width)
|
||||
x -= x - (monitor.x + monitor.width) + requisition.width;
|
||||
else if (x < monitor.x)
|
||||
x = monitor.x;
|
||||
|
||||
if (y + requisition.height > monitor.y + monitor.height)
|
||||
y -= y - (monitor.y + monitor.height) + requisition.height;
|
||||
|
||||
gtk_window_move (GTK_WINDOW (tooltip->current_window), x, y);
|
||||
gtk_widget_show (GTK_WIDGET (tooltip->current_window));
|
||||
}
|
||||
gtk_tooltip_position (tooltip, display, tooltip_widget);
|
||||
|
||||
/* Now a tooltip is visible again on the display, make sure browse
|
||||
* mode is enabled.
|
||||
@ -1063,11 +1112,32 @@ _gtk_tooltip_handle_event (GdkEvent *event)
|
||||
case GDK_SCROLL:
|
||||
if (current_tooltip)
|
||||
{
|
||||
gboolean tip_area_set;
|
||||
GdkRectangle tip_area;
|
||||
gboolean hide_tooltip;
|
||||
|
||||
tip_area_set = current_tooltip->tip_area_set;
|
||||
tip_area = current_tooltip->tip_area;
|
||||
|
||||
return_value = gtk_tooltip_run_requery (&has_tooltip_widget,
|
||||
current_tooltip,
|
||||
&x, &y);
|
||||
|
||||
if (!return_value)
|
||||
/* Requested to be hidden? */
|
||||
hide_tooltip = !return_value;
|
||||
|
||||
/* Is the pointer above another widget now? */
|
||||
if (GTK_TOOLTIP_VISIBLE (current_tooltip))
|
||||
hide_tooltip |= has_tooltip_widget != current_tooltip->tooltip_widget;
|
||||
|
||||
/* Did the pointer move out of the previous "context area"? */
|
||||
if (tip_area_set)
|
||||
hide_tooltip |= (x <= tip_area.x
|
||||
|| x >= tip_area.x + tip_area.width
|
||||
|| y <= tip_area.y
|
||||
|| y >= tip_area.y + tip_area.height);
|
||||
|
||||
if (hide_tooltip)
|
||||
gtk_tooltip_hide_tooltip (current_tooltip);
|
||||
else
|
||||
gtk_tooltip_start_delay (display);
|
||||
|
@ -45,6 +45,9 @@ void gtk_tooltip_set_icon_from_stock (GtkTooltip *tooltip,
|
||||
void gtk_tooltip_set_custom (GtkTooltip *tooltip,
|
||||
GtkWidget *custom_widget);
|
||||
|
||||
void gtk_tooltip_set_tip_area (GtkTooltip *tooltip,
|
||||
GdkRectangle *rect);
|
||||
|
||||
void gtk_tooltip_trigger_tooltip_query (GdkDisplay *display);
|
||||
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "gtkentry.h"
|
||||
#include "gtkframe.h"
|
||||
#include "gtktreemodelsort.h"
|
||||
#include "gtktooltip.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkalias.h"
|
||||
|
||||
@ -15171,5 +15172,112 @@ gtk_tree_view_get_level_indentation (GtkTreeView *tree_view)
|
||||
return tree_view->priv->level_indentation;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_view_set_tooltip_row:
|
||||
* @tree_view: a #GtkTreeView
|
||||
* @tooltip: a #GtkTooltip
|
||||
* @path: a #GtkTreePath
|
||||
*
|
||||
* Sets the tip area of @tooltip to be the area covered by the row at @path.
|
||||
* See also gtk_tooltip_set_tip_area().
|
||||
*
|
||||
* Since: 2.12
|
||||
*/
|
||||
void
|
||||
gtk_tree_view_set_tooltip_row (GtkTreeView *tree_view,
|
||||
GtkTooltip *tooltip,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
|
||||
g_return_if_fail (GTK_IS_TOOLTIP (tooltip));
|
||||
|
||||
gtk_tree_view_set_tooltip_cell (tree_view, tooltip, path, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_view_set_tooltip_cell:
|
||||
* @tree_view: a #GtkTreeView
|
||||
* @tooltip: a #GtkTooltip
|
||||
* @path: a #GtkTreePath or %NULL
|
||||
* @column: a #GtkTreeViewColumn or %NULL
|
||||
* @cell: a #GtkCellRendererText or %NULL
|
||||
*
|
||||
* Sets the tip area of @tooltip to the area @path, @column and @cell have
|
||||
* in common. For example if @path is %NULL and @column is set, the tip
|
||||
* area will be set to the full area covered by @column. See also
|
||||
* gtk_tooltip_set_tip_area().
|
||||
*
|
||||
* Since: 2.12
|
||||
*/
|
||||
void
|
||||
gtk_tree_view_set_tooltip_cell (GtkTreeView *tree_view,
|
||||
GtkTooltip *tooltip,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
GtkCellRenderer *cell)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
|
||||
g_return_if_fail (GTK_IS_TOOLTIP (tooltip));
|
||||
|
||||
if (column)
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (column));
|
||||
|
||||
if (cell)
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
|
||||
/* Determine x values. */
|
||||
if (column && cell)
|
||||
{
|
||||
GdkRectangle tmp;
|
||||
gint start, width;
|
||||
|
||||
gtk_tree_view_get_cell_area (tree_view, NULL, column, &tmp);
|
||||
gtk_tree_view_column_cell_get_position (column, cell, &start, &width);
|
||||
|
||||
/* FIXME: a need a path here to correctly correct for indent */
|
||||
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (tree_view,
|
||||
tmp.x + start, 0,
|
||||
&rect.x, NULL);
|
||||
rect.width = width;
|
||||
}
|
||||
else if (column)
|
||||
{
|
||||
GdkRectangle tmp;
|
||||
|
||||
gtk_tree_view_get_background_area (tree_view, NULL, column, &tmp);
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (tree_view,
|
||||
tmp.x, 0,
|
||||
&rect.x, NULL);
|
||||
rect.width = tmp.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.x = GTK_WIDGET (tree_view)->allocation.x;
|
||||
rect.width = GTK_WIDGET (tree_view)->allocation.width;
|
||||
}
|
||||
|
||||
/* Determine y values. */
|
||||
if (path)
|
||||
{
|
||||
GdkRectangle tmp;
|
||||
|
||||
gtk_tree_view_get_background_area (tree_view, path, NULL, &tmp);
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (tree_view,
|
||||
0, tmp.y,
|
||||
NULL, &rect.y);
|
||||
rect.height = tmp.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.y = 0;
|
||||
rect.height = tree_view->priv->vadjustment->page_size;
|
||||
}
|
||||
|
||||
gtk_tooltip_set_tip_area (tooltip, &rect);
|
||||
}
|
||||
|
||||
#define __GTK_TREE_VIEW_C__
|
||||
#include "gtkaliasdef.c"
|
||||
|
@ -402,6 +402,16 @@ void gtk_tree_view_set_level_indentation (GtkTreeView
|
||||
gint indentation);
|
||||
gint gtk_tree_view_get_level_indentation (GtkTreeView *tree_view);
|
||||
|
||||
/* Convenience functions for setting tooltips */
|
||||
void gtk_tree_view_set_tooltip_row (GtkTreeView *tree_view,
|
||||
GtkTooltip *tooltip,
|
||||
GtkTreePath *path);
|
||||
void gtk_tree_view_set_tooltip_cell (GtkTreeView *tree_view,
|
||||
GtkTooltip *tooltip,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
GtkCellRenderer *cell);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
|
@ -135,6 +135,8 @@ query_tooltip_tree_view_cb (GtkWidget *widget,
|
||||
g_snprintf (buffer, 511, "<b>Path %s:</b> %s", pathstring, tmp);
|
||||
gtk_tooltip_set_markup (tooltip, buffer);
|
||||
|
||||
gtk_tree_view_set_tooltip_row (tree_view, tooltip, path);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
g_free (pathstring);
|
||||
g_free (tmp);
|
||||
|
Loading…
Reference in New Issue
Block a user