/src/wrappers/gtk/examples/gtk-demo/hypertext.e
http://github.com/tybor/Liberty · Specman e · 345 lines · 21 code · 62 blank · 262 comment · 2 complexity · d422b995cd7105597be7814287040650 MD5 · raw file
- indexing
- description: "."
- copyright: "[
- Copyright (C) 2006 Paolo Redaelli, GTK+ team
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License
- as published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA
- ]"
- class HYPERTEXT
- creation make
- feature
- -- /* Text Widget/Hypertext
- -- *
- -- * Usually, tags modify the appearance of text in the view, e.g. making it
- -- * bold or colored or underlined. But tags are not restricted to appearance.
- -- * They can also affect the behavior of mouse and key presses, as this demo
- -- * shows.
- -- */
- -- #include <gtk/gtk.h>
- -- #include <gdk/gdkkeysyms.h>
- -- /* Inserts a piece of text into the buffer, giving it the usual
- -- * appearance of a hyperlink in a web browser: blue and underlined.
- -- * Additionally, attaches some data on the tag, to make it recognizable
- -- * as a link.
- -- */
- -- static void
- -- insert_link (GtkTextBuffer *buffer,
- -- GtkTextIter *iter,
- -- gchar *text,
- -- gint page)
- -- {
- -- GtkTextTag *tag;
-
- -- tag = gtk_text_buffer_create_tag (buffer, NULL,
- -- "foreground", "blue",
- -- "underline", PANGO_UNDERLINE_SINGLE,
- -- NULL);
- -- g_object_set_data (G_OBJECT (tag), "page", GINT_TO_POINTER (page));
- -- gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
- -- }
- -- /* Fills the buffer with text and interspersed links. In any real
- -- * hypertext app, this method would parse a file to identify the links.
- -- */
- -- static void
- -- show_page (GtkTextBuffer *buffer,
- -- gint page)
- -- {
- -- GtkTextIter iter;
- -- gtk_text_buffer_set_text (buffer, "", 0);
- -- gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
- -- if (page == 1)
- -- {
- -- gtk_text_buffer_insert (buffer, &iter, "Some text to show that simple ", -1);
- -- insert_link (buffer, &iter, "hypertext", 3);
- -- gtk_text_buffer_insert (buffer, &iter, " can easily be realized with ", -1);
- -- insert_link (buffer, &iter, "tags", 2);
- -- gtk_text_buffer_insert (buffer, &iter, ".", -1);
- -- }
- -- else if (page == 2)
- -- {
- -- gtk_text_buffer_insert (buffer, &iter,
- -- "A tag is an attribute that can be applied to some range of text. "
- -- "For example, a tag might be called \"bold\" and make the text inside "
- -- "the tag bold. However, the tag concept is more general than that; "
- -- "tags don't have to affect appearance. They can instead affect the "
- -- "behavior of mouse and key presses, \"lock\" a range of text so the "
- -- "user can't edit it, or countless other things.\n", -1);
- -- insert_link (buffer, &iter, "Go back", 1);
- -- }
- -- else if (page == 3)
- -- {
- -- GtkTextTag *tag;
-
- -- tag = gtk_text_buffer_create_tag (buffer, NULL,
- -- "weight", PANGO_WEIGHT_BOLD,
- -- NULL);
- -- gtk_text_buffer_insert_with_tags (buffer, &iter, "hypertext:\n", -1, tag, NULL);
- -- gtk_text_buffer_insert (buffer, &iter,
- -- "machine-readable text that is not sequential but is organized "
- -- "so that related items of information are connected.\n", -1);
- -- insert_link (buffer, &iter, "Go back", 1);
- -- }
- -- }
- -- /* Looks at all tags covering the position of iter in the text view,
- -- * and if one of them is a link, follow it by showing the page identified
- -- * by the data attached to it.
- -- */
- -- static void
- -- follow_if_link (GtkWidget *text_view,
- -- GtkTextIter *iter)
- -- {
- -- GSList *tags = NULL, *tagp = NULL;
- -- tags = gtk_text_iter_get_tags (iter);
- -- for (tagp = tags; tagp != NULL; tagp = tagp->next)
- -- {
- -- GtkTextTag *tag = tagp->data;
- -- gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page"));
- -- if (page != 0)
- -- {
- -- show_page (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)), page);
- -- break;
- -- }
- -- }
- -- if (tags)
- -- g_slist_free (tags);
- -- }
- -- /* Links can be activated by pressing Enter.
- -- */
- -- static gboolean
- -- key_press_event (GtkWidget *text_view,
- -- GdkEventKey *event)
- -- {
- -- GtkTextIter iter;
- -- GtkTextBuffer *buffer;
- -- switch (event->keyval)
- -- {
- -- case GDK_Return:
- -- case GDK_KP_Enter:
- -- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
- -- gtk_text_buffer_get_iter_at_mark (buffer, &iter,
- -- gtk_text_buffer_get_insert (buffer));
- -- follow_if_link (text_view, &iter);
- -- break;
- -- default:
- -- break;
- -- }
- -- return FALSE;
- -- }
- -- /* Links can also be activated by clicking.
- -- */
- -- static gboolean
- -- event_after (GtkWidget *text_view,
- -- GdkEvent *ev)
- -- {
- -- GtkTextIter start, end, iter;
- -- GtkTextBuffer *buffer;
- -- GdkEventButton *event;
- -- gint x, y;
- -- if (ev->type != GDK_BUTTON_RELEASE)
- -- return FALSE;
- -- event = (GdkEventButton *)ev;
- -- if (event->button != 1)
- -- return FALSE;
- -- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
- -- /* we shouldn't follow a link if the user has selected something */
- -- gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
- -- if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
- -- return FALSE;
- -- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
- -- GTK_TEXT_WINDOW_WIDGET,
- -- event->x, event->y, &x, &y);
- -- gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
- -- follow_if_link (text_view, &iter);
- -- return FALSE;
- -- }
- -- gboolean hovering_over_link = FALSE;
- -- GdkCursor *hand_cursor = NULL;
- -- GdkCursor *regular_cursor = NULL;
- -- /* Looks at all tags covering the position (x, y) in the text view,
- -- * and if one of them is a link, change the cursor to the "hands" cursor
- -- * typically used by web browsers.
- -- */
- -- static void
- -- set_cursor_if_appropriate (GtkTextView *text_view,
- -- gint x,
- -- gint y)
- -- {
- -- GSList *tags = NULL, *tagp = NULL;
- -- GtkTextBuffer *buffer;
- -- GtkTextIter iter;
- -- gboolean hovering = FALSE;
- -- buffer = gtk_text_view_get_buffer (text_view);
- -- gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
-
- -- tags = gtk_text_iter_get_tags (&iter);
- -- for (tagp = tags; tagp != NULL; tagp = tagp->next)
- -- {
- -- GtkTextTag *tag = tagp->data;
- -- gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page"));
- -- if (page != 0)
- -- {
- -- hovering = TRUE;
- -- break;
- -- }
- -- }
- -- if (hovering != hovering_over_link)
- -- {
- -- hovering_over_link = hovering;
- -- if (hovering_over_link)
- -- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor);
- -- else
- -- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor);
- -- }
- -- if (tags)
- -- g_slist_free (tags);
- -- }
- -- /* Update the cursor image if the pointer moved.
- -- */
- -- static gboolean
- -- motion_notify_event (GtkWidget *text_view,
- -- GdkEventMotion *event)
- -- {
- -- gint x, y;
- -- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
- -- GTK_TEXT_WINDOW_WIDGET,
- -- event->x, event->y, &x, &y);
- -- set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
- -- gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
- -- return FALSE;
- -- }
- -- /* Also update the cursor image if the window becomes visible
- -- * (e.g. when a window covering it got iconified).
- -- */
- -- static gboolean
- -- visibility_notify_event (GtkWidget *text_view,
- -- GdkEventVisibility *event)
- -- {
- -- gint wx, wy, bx, by;
-
- -- gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
-
- -- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
- -- GTK_TEXT_WINDOW_WIDGET,
- -- wx, wy, &bx, &by);
- -- set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by);
- -- return FALSE;
- -- }
- -- GtkWidget *
- -- do_hypertext (GtkWidget *do_widget)
- -- {
- -- static GtkWidget *window = NULL;
- -- if (!window)
- -- {
- -- GtkWidget *view;
- -- GtkWidget *sw;
- -- GtkTextBuffer *buffer;
- -- hand_cursor = gdk_cursor_new (GDK_HAND2);
- -- regular_cursor = gdk_cursor_new (GDK_XTERM);
-
- -- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- -- gtk_window_set_screen (GTK_WINDOW (window),
- -- gtk_widget_get_screen (do_widget));
- -- gtk_window_set_default_size (GTK_WINDOW (window),
- -- 450, 450);
-
- -- g_signal_connect (window, "destroy",
- -- G_CALLBACK (gtk_widget_destroyed), &window);
- -- gtk_window_set_title (GTK_WINDOW (window), "Hypertext");
- -- gtk_container_set_border_width (GTK_CONTAINER (window), 0);
- -- view = gtk_text_view_new ();
- -- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
- -- g_signal_connect (view, "key-press-event",
- -- G_CALLBACK (key_press_event), NULL);
- -- g_signal_connect (view, "event-after",
- -- G_CALLBACK (event_after), NULL);
- -- g_signal_connect (view, "motion-notify-event",
- -- G_CALLBACK (motion_notify_event), NULL);
- -- g_signal_connect (view, "visibility-notify-event",
- -- G_CALLBACK (visibility_notify_event), NULL);
- -- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
- -- sw = gtk_scrolled_window_new (NULL, NULL);
- -- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- -- GTK_POLICY_AUTOMATIC,
- -- GTK_POLICY_AUTOMATIC);
- -- gtk_container_add (GTK_CONTAINER (window), sw);
- -- gtk_container_add (GTK_CONTAINER (sw), view);
- -- show_page (buffer, 1);
- -- gtk_widget_show_all (sw);
- -- }
- -- if (!GTK_WIDGET_VISIBLE (window))
- -- {
- -- gtk_widget_show (window);
- -- }
- -- else
- -- {
- -- gtk_widget_destroy (window);
- -- window = NULL;
- -- }
- -- return window;
- -- }
- end