Add link support to GtkLabel
This patch is based on SexyUrlLabel, but with significantly enhanced functionality: keynav, tooltips, context menu, theming.
This commit is contained in:
@@ -3,7 +3,7 @@ include $(top_srcdir)/Makefile.decl
|
||||
|
||||
democodedir=$(datadir)/gtk-2.0/demo
|
||||
|
||||
## These should be in the order you want them to appear in the
|
||||
## These should be in the order you want them to appear in the
|
||||
## demo app, which means alphabetized by demo title, not filename
|
||||
demos = \
|
||||
appwindow.c \
|
||||
@@ -23,6 +23,7 @@ demos = \
|
||||
iconview.c \
|
||||
iconview_edit.c \
|
||||
images.c \
|
||||
links.c \
|
||||
list_store.c \
|
||||
menus.c \
|
||||
panes.c \
|
||||
|
||||
88
demos/gtk-demo/links.c
Normal file
88
demos/gtk-demo/links.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/* Links
|
||||
*
|
||||
* GtkLabel can show hyperlinks. The default action is to call
|
||||
* gtk_show_uri() on their URI, but it is possible to override
|
||||
* this with a custom handler.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
response_cb (GtkWidget *dialog,
|
||||
gint response_id,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
activate_link (GtkWidget *label,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *uri;
|
||||
|
||||
uri = gtk_label_get_current_uri (GTK_LABEL (label));
|
||||
|
||||
if (g_strcmp0 (uri, "keynav") == 0)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *parent;
|
||||
|
||||
parent = gtk_widget_get_toplevel (label);
|
||||
dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (parent),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
"The term <i>keynav</i> is a shorthand for "
|
||||
"keyboard navigation and refers to the process of using "
|
||||
"a program (exclusively) via keyboard input.");
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (response_cb), NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_links (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_screen (GTK_WINDOW (window),
|
||||
gtk_widget_get_screen (do_widget));
|
||||
gtk_container_set_border_width (GTK_CONTAINER (window), 12);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK(gtk_widget_destroyed), &window);
|
||||
g_signal_connect (window, "delete-event",
|
||||
G_CALLBACK (gtk_true), NULL);
|
||||
|
||||
label = gtk_label_new ("Some <a href=\"http://en.wikipedia.org/wiki/Text\""
|
||||
"title=\"plain text\">text</a> may be marked up\n"
|
||||
"as hyperlinks, which can be clicked\n"
|
||||
"or activated via <a href=\"keynav\">keynav</a>");
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), label);
|
||||
gtk_widget_show (label);
|
||||
}
|
||||
|
||||
if (!GTK_WIDGET_VISIBLE (window))
|
||||
{
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -162,6 +162,24 @@ aligns in its available space, see gtk_misc_set_alignment().
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Links</title>
|
||||
|
||||
<para>
|
||||
Since 2.18, GTK+ supports markup for clickable hyperlinks in addition
|
||||
to regular Pango markup. The markup for links is borrowed from HTML, using the
|
||||
<tag>a</tag> with href and title attributes. GTK+ renders links similar to the
|
||||
way they appear in web browsers, with colored, underlined text. The title
|
||||
attribute is displayed as a tooltip on the link. An example looks like this:
|
||||
<informalexample><programlisting>
|
||||
gtk_label_set_markup (label, "Go to the <a href=\"http://www.gtk.org\" title=\"&lt;i&gt;Our&/i&gt; website\">GTK+ website</a> for more...");
|
||||
</programlisting></informalexample>
|
||||
It is possible to implement custom handling for links with the
|
||||
#GtkLabel::activate-link signal and the gtk_label_get_current_uri() function.
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<!-- ##### SECTION See_Also ##### -->
|
||||
<para>
|
||||
|
||||
|
||||
@@ -2210,6 +2210,7 @@ gtk_label_set_text_with_mnemonic
|
||||
gtk_label_set_use_markup
|
||||
gtk_label_set_use_underline
|
||||
gtk_label_set_width_chars
|
||||
gtk_label_get_current_uri
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
1513
gtk/gtklabel.c
1513
gtk/gtklabel.c
File diff suppressed because it is too large
Load Diff
@@ -96,11 +96,12 @@ struct _GtkLabelClass
|
||||
void (* populate_popup) (GtkLabel *label,
|
||||
GtkMenu *menu);
|
||||
|
||||
gboolean (*activate_link) (GtkLabel *label);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
};
|
||||
|
||||
GType gtk_label_get_type (void) G_GNUC_CONST;
|
||||
@@ -174,6 +175,8 @@ void gtk_label_set_single_line_mode (GtkLabel *label,
|
||||
gboolean single_line_mode);
|
||||
gboolean gtk_label_get_single_line_mode (GtkLabel *label);
|
||||
|
||||
G_CONST_RETURN gchar *gtk_label_get_current_uri (GtkLabel *label);
|
||||
|
||||
#ifndef GTK_DISABLE_DEPRECATED
|
||||
|
||||
#define gtk_label_set gtk_label_set_text
|
||||
|
||||
@@ -2961,6 +2961,49 @@ create_selectable_control (GtkWidget *widget)
|
||||
return button;
|
||||
}
|
||||
|
||||
static void
|
||||
dialog_response (GtkWidget *dialog, gint response_id, GtkLabel *label)
|
||||
{
|
||||
const gchar *text;
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
text = "Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
|
||||
"as hyperlinks, which can be clicked\n"
|
||||
"or activated via <a href=\"keynav\">keynav</a>.\n"
|
||||
"The links remain the same.";
|
||||
gtk_label_set_markup (label, text);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
activate_link (GtkWidget *label, gpointer data)
|
||||
{
|
||||
const gchar *uri;
|
||||
|
||||
uri = gtk_label_get_current_uri (GTK_LABEL (label));
|
||||
|
||||
if (g_strcmp0 (uri, "keynav") == 0)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_toplevel (label)),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
"The term <i>keynav</i> is a shorthand for "
|
||||
"keyboard navigation and refers to the process of using a program "
|
||||
"(exclusively) via keyboard input.");
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (dialog_response), label);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void create_labels (GtkWidget *widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
@@ -3048,6 +3091,15 @@ void create_labels (GtkWidget *widget)
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||
|
||||
frame = gtk_frame_new ("Links in a label");
|
||||
label = gtk_label_new ("Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
|
||||
"as hyperlinks, which can be clicked\n"
|
||||
"or activated via <a href=\"keynav\">keynav</a>");
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 5);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
|
||||
frame = gtk_frame_new ("Line wrapped label");
|
||||
|
||||
@@ -78,6 +78,14 @@ style "button" = "default"
|
||||
# bg[PRELIGHT] = { 0.75, 0, 0x00 }
|
||||
}
|
||||
|
||||
style "label" = "default"
|
||||
{
|
||||
base[PRELIGHT] = "gray"
|
||||
base[ACTIVE] = mix (0.9, "gray", "purple")
|
||||
}
|
||||
|
||||
class "GtkLabel" style "label"
|
||||
|
||||
style "toggle_button" = "button"
|
||||
{
|
||||
fg[NORMAL] = { 1.0, 0, 0 }
|
||||
|
||||
Reference in New Issue
Block a user