📄 dw_tooltip.c
字号:
/* * A few notes: * * - Currently, a window is created every time before it is shown, and * destroyed, before it is hidden. This saves (probably?) some * memory, but can simply be changed. An alternative is having a * global window for all tooltips. * * - Tooltips are positioned near the pointer, as opposed to Gtk+ * tooltips, which are positioned near the widget. * * Sebastian */#include <gtk/gtk.h>#include "dw_tooltip.h"/* The amount of space around the text, including the border. */#define PADDING 4/* The difference between pointer position and upper left corner of the * tooltip. */#define DIFF 10static gboolean Dw_tooltip_draw (DwTooltip *tooltip);static DwTooltip *Dw_tooltip_new0 (const char *text, gint ref_count){ DwTooltip *tooltip; tooltip = g_new (DwTooltip, 1); tooltip->ref_count = ref_count; tooltip->window = NULL; tooltip->timeout_id = 0; tooltip->text = g_strdup (text); return tooltip;}/* * Create a new tooltip, with ref_count set to 1. */DwTooltip* a_Dw_tooltip_new (const gchar *text){ return Dw_tooltip_new0(text, 1);}/* * Create a new tooltip, with ref_count set to 0. Tyically used for DwStyle. */DwTooltip* a_Dw_tooltip_new_no_ref (const gchar *text){ return Dw_tooltip_new0(text, 0);}/* * Destroy the tooltip. Used by Dw_tooltip_unref. */void Dw_tooltip_destroy (DwTooltip *tooltip){ a_Dw_tooltip_on_leave (tooltip); g_free (tooltip->text); g_free (tooltip);}/* * Call this function if the pointer has entered the widget/word. */void a_Dw_tooltip_on_enter (DwTooltip *tooltip){ a_Dw_tooltip_on_leave (tooltip); tooltip->timeout_id = gtk_timeout_add (500, (GtkFunction)Dw_tooltip_draw, tooltip);}/* * Call this function if the pointer has left the widget/word. */void a_Dw_tooltip_on_leave (DwTooltip *tooltip){ if (tooltip->timeout_id != 0) { gtk_timeout_remove (tooltip->timeout_id); tooltip->timeout_id = 0; } if (tooltip->window != NULL) { gtk_widget_destroy (tooltip->window); tooltip->window = NULL; }}/* * Call this function if the pointer has moved within the widget/word. */void a_Dw_tooltip_on_motion (DwTooltip *tooltip){ a_Dw_tooltip_on_enter (tooltip);}/* * Draw the tooltip. Called as a timeout function. */static gboolean Dw_tooltip_draw (DwTooltip *tooltip){ GtkStyle *style; gint px, py, x, y, width, ascent, descent, screen_w, screen_h, ttw, tth; gdk_window_get_pointer (NULL, &px, &py, NULL); x = px + DIFF; y = py + DIFF; tooltip->window = gtk_window_new (GTK_WINDOW_POPUP); gtk_widget_set_app_paintable (tooltip->window, TRUE); gtk_widget_set_name (tooltip->window, "gtk-tooltips"); gtk_widget_ensure_style (tooltip->window); style = tooltip->window->style; width = gdk_string_width (style->font, tooltip->text); ascent = style->font->ascent; descent = style->font->descent; ttw = width + 2 * PADDING; tth = ascent + descent + 2 * PADDING; gtk_widget_set_usize (tooltip->window, ttw, tth); screen_w = gdk_screen_width(); screen_h = gdk_screen_height(); if (ttw >= screen_w) /* If the width of a tooltips does not fit into the screen, put * them at x = 0. (Yes, that's far from perfect ...) */ x = 0; else if (x + ttw > screen_w) /* If they would otherwise reach out of the screen, move them * a bit left. */ x = screen_w - ttw; /* The case that the height of a tooltip of the screen is greater * that the screen height is ignored ;-) If the tooltip reaches * out of the screen at the bottom, it is displayed *above* the * pointer: to process events properly, it is necessary to keep * the pointer out of the tooltip. */ if (y + tth > screen_h) y = py - tth - DIFF; gtk_widget_popup (tooltip->window, x, y); style = tooltip->window->style; gtk_paint_flat_box (style, tooltip->window->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, GTK_WIDGET (tooltip->window), "tooltip", 0, 0, -1, -1); gtk_paint_string (style, tooltip->window->window, GTK_STATE_NORMAL, NULL, GTK_WIDGET (tooltip->window), "tooltip", PADDING, ascent + PADDING, tooltip->text); tooltip->timeout_id = 0; return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -