/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

  1. indexing
  2. description: "."
  3. copyright: "[
  4. Copyright (C) 2006 Paolo Redaelli, GTK+ team
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License
  7. as published by the Free Software Foundation; either version 2.1 of
  8. the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301 USA
  17. ]"
  18. class HYPERTEXT
  19. creation make
  20. feature
  21. -- /* Text Widget/Hypertext
  22. -- *
  23. -- * Usually, tags modify the appearance of text in the view, e.g. making it
  24. -- * bold or colored or underlined. But tags are not restricted to appearance.
  25. -- * They can also affect the behavior of mouse and key presses, as this demo
  26. -- * shows.
  27. -- */
  28. -- #include <gtk/gtk.h>
  29. -- #include <gdk/gdkkeysyms.h>
  30. -- /* Inserts a piece of text into the buffer, giving it the usual
  31. -- * appearance of a hyperlink in a web browser: blue and underlined.
  32. -- * Additionally, attaches some data on the tag, to make it recognizable
  33. -- * as a link.
  34. -- */
  35. -- static void
  36. -- insert_link (GtkTextBuffer *buffer,
  37. -- GtkTextIter *iter,
  38. -- gchar *text,
  39. -- gint page)
  40. -- {
  41. -- GtkTextTag *tag;
  42. -- tag = gtk_text_buffer_create_tag (buffer, NULL,
  43. -- "foreground", "blue",
  44. -- "underline", PANGO_UNDERLINE_SINGLE,
  45. -- NULL);
  46. -- g_object_set_data (G_OBJECT (tag), "page", GINT_TO_POINTER (page));
  47. -- gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
  48. -- }
  49. -- /* Fills the buffer with text and interspersed links. In any real
  50. -- * hypertext app, this method would parse a file to identify the links.
  51. -- */
  52. -- static void
  53. -- show_page (GtkTextBuffer *buffer,
  54. -- gint page)
  55. -- {
  56. -- GtkTextIter iter;
  57. -- gtk_text_buffer_set_text (buffer, "", 0);
  58. -- gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
  59. -- if (page == 1)
  60. -- {
  61. -- gtk_text_buffer_insert (buffer, &iter, "Some text to show that simple ", -1);
  62. -- insert_link (buffer, &iter, "hypertext", 3);
  63. -- gtk_text_buffer_insert (buffer, &iter, " can easily be realized with ", -1);
  64. -- insert_link (buffer, &iter, "tags", 2);
  65. -- gtk_text_buffer_insert (buffer, &iter, ".", -1);
  66. -- }
  67. -- else if (page == 2)
  68. -- {
  69. -- gtk_text_buffer_insert (buffer, &iter,
  70. -- "A tag is an attribute that can be applied to some range of text. "
  71. -- "For example, a tag might be called \"bold\" and make the text inside "
  72. -- "the tag bold. However, the tag concept is more general than that; "
  73. -- "tags don't have to affect appearance. They can instead affect the "
  74. -- "behavior of mouse and key presses, \"lock\" a range of text so the "
  75. -- "user can't edit it, or countless other things.\n", -1);
  76. -- insert_link (buffer, &iter, "Go back", 1);
  77. -- }
  78. -- else if (page == 3)
  79. -- {
  80. -- GtkTextTag *tag;
  81. -- tag = gtk_text_buffer_create_tag (buffer, NULL,
  82. -- "weight", PANGO_WEIGHT_BOLD,
  83. -- NULL);
  84. -- gtk_text_buffer_insert_with_tags (buffer, &iter, "hypertext:\n", -1, tag, NULL);
  85. -- gtk_text_buffer_insert (buffer, &iter,
  86. -- "machine-readable text that is not sequential but is organized "
  87. -- "so that related items of information are connected.\n", -1);
  88. -- insert_link (buffer, &iter, "Go back", 1);
  89. -- }
  90. -- }
  91. -- /* Looks at all tags covering the position of iter in the text view,
  92. -- * and if one of them is a link, follow it by showing the page identified
  93. -- * by the data attached to it.
  94. -- */
  95. -- static void
  96. -- follow_if_link (GtkWidget *text_view,
  97. -- GtkTextIter *iter)
  98. -- {
  99. -- GSList *tags = NULL, *tagp = NULL;
  100. -- tags = gtk_text_iter_get_tags (iter);
  101. -- for (tagp = tags; tagp != NULL; tagp = tagp->next)
  102. -- {
  103. -- GtkTextTag *tag = tagp->data;
  104. -- gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page"));
  105. -- if (page != 0)
  106. -- {
  107. -- show_page (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)), page);
  108. -- break;
  109. -- }
  110. -- }
  111. -- if (tags)
  112. -- g_slist_free (tags);
  113. -- }
  114. -- /* Links can be activated by pressing Enter.
  115. -- */
  116. -- static gboolean
  117. -- key_press_event (GtkWidget *text_view,
  118. -- GdkEventKey *event)
  119. -- {
  120. -- GtkTextIter iter;
  121. -- GtkTextBuffer *buffer;
  122. -- switch (event->keyval)
  123. -- {
  124. -- case GDK_Return:
  125. -- case GDK_KP_Enter:
  126. -- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
  127. -- gtk_text_buffer_get_iter_at_mark (buffer, &iter,
  128. -- gtk_text_buffer_get_insert (buffer));
  129. -- follow_if_link (text_view, &iter);
  130. -- break;
  131. -- default:
  132. -- break;
  133. -- }
  134. -- return FALSE;
  135. -- }
  136. -- /* Links can also be activated by clicking.
  137. -- */
  138. -- static gboolean
  139. -- event_after (GtkWidget *text_view,
  140. -- GdkEvent *ev)
  141. -- {
  142. -- GtkTextIter start, end, iter;
  143. -- GtkTextBuffer *buffer;
  144. -- GdkEventButton *event;
  145. -- gint x, y;
  146. -- if (ev->type != GDK_BUTTON_RELEASE)
  147. -- return FALSE;
  148. -- event = (GdkEventButton *)ev;
  149. -- if (event->button != 1)
  150. -- return FALSE;
  151. -- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
  152. -- /* we shouldn't follow a link if the user has selected something */
  153. -- gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
  154. -- if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
  155. -- return FALSE;
  156. -- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
  157. -- GTK_TEXT_WINDOW_WIDGET,
  158. -- event->x, event->y, &x, &y);
  159. -- gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
  160. -- follow_if_link (text_view, &iter);
  161. -- return FALSE;
  162. -- }
  163. -- gboolean hovering_over_link = FALSE;
  164. -- GdkCursor *hand_cursor = NULL;
  165. -- GdkCursor *regular_cursor = NULL;
  166. -- /* Looks at all tags covering the position (x, y) in the text view,
  167. -- * and if one of them is a link, change the cursor to the "hands" cursor
  168. -- * typically used by web browsers.
  169. -- */
  170. -- static void
  171. -- set_cursor_if_appropriate (GtkTextView *text_view,
  172. -- gint x,
  173. -- gint y)
  174. -- {
  175. -- GSList *tags = NULL, *tagp = NULL;
  176. -- GtkTextBuffer *buffer;
  177. -- GtkTextIter iter;
  178. -- gboolean hovering = FALSE;
  179. -- buffer = gtk_text_view_get_buffer (text_view);
  180. -- gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
  181. -- tags = gtk_text_iter_get_tags (&iter);
  182. -- for (tagp = tags; tagp != NULL; tagp = tagp->next)
  183. -- {
  184. -- GtkTextTag *tag = tagp->data;
  185. -- gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page"));
  186. -- if (page != 0)
  187. -- {
  188. -- hovering = TRUE;
  189. -- break;
  190. -- }
  191. -- }
  192. -- if (hovering != hovering_over_link)
  193. -- {
  194. -- hovering_over_link = hovering;
  195. -- if (hovering_over_link)
  196. -- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor);
  197. -- else
  198. -- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor);
  199. -- }
  200. -- if (tags)
  201. -- g_slist_free (tags);
  202. -- }
  203. -- /* Update the cursor image if the pointer moved.
  204. -- */
  205. -- static gboolean
  206. -- motion_notify_event (GtkWidget *text_view,
  207. -- GdkEventMotion *event)
  208. -- {
  209. -- gint x, y;
  210. -- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
  211. -- GTK_TEXT_WINDOW_WIDGET,
  212. -- event->x, event->y, &x, &y);
  213. -- set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
  214. -- gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
  215. -- return FALSE;
  216. -- }
  217. -- /* Also update the cursor image if the window becomes visible
  218. -- * (e.g. when a window covering it got iconified).
  219. -- */
  220. -- static gboolean
  221. -- visibility_notify_event (GtkWidget *text_view,
  222. -- GdkEventVisibility *event)
  223. -- {
  224. -- gint wx, wy, bx, by;
  225. -- gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
  226. -- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
  227. -- GTK_TEXT_WINDOW_WIDGET,
  228. -- wx, wy, &bx, &by);
  229. -- set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by);
  230. -- return FALSE;
  231. -- }
  232. -- GtkWidget *
  233. -- do_hypertext (GtkWidget *do_widget)
  234. -- {
  235. -- static GtkWidget *window = NULL;
  236. -- if (!window)
  237. -- {
  238. -- GtkWidget *view;
  239. -- GtkWidget *sw;
  240. -- GtkTextBuffer *buffer;
  241. -- hand_cursor = gdk_cursor_new (GDK_HAND2);
  242. -- regular_cursor = gdk_cursor_new (GDK_XTERM);
  243. -- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  244. -- gtk_window_set_screen (GTK_WINDOW (window),
  245. -- gtk_widget_get_screen (do_widget));
  246. -- gtk_window_set_default_size (GTK_WINDOW (window),
  247. -- 450, 450);
  248. -- g_signal_connect (window, "destroy",
  249. -- G_CALLBACK (gtk_widget_destroyed), &window);
  250. -- gtk_window_set_title (GTK_WINDOW (window), "Hypertext");
  251. -- gtk_container_set_border_width (GTK_CONTAINER (window), 0);
  252. -- view = gtk_text_view_new ();
  253. -- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
  254. -- g_signal_connect (view, "key-press-event",
  255. -- G_CALLBACK (key_press_event), NULL);
  256. -- g_signal_connect (view, "event-after",
  257. -- G_CALLBACK (event_after), NULL);
  258. -- g_signal_connect (view, "motion-notify-event",
  259. -- G_CALLBACK (motion_notify_event), NULL);
  260. -- g_signal_connect (view, "visibility-notify-event",
  261. -- G_CALLBACK (visibility_notify_event), NULL);
  262. -- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
  263. -- sw = gtk_scrolled_window_new (NULL, NULL);
  264. -- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
  265. -- GTK_POLICY_AUTOMATIC,
  266. -- GTK_POLICY_AUTOMATIC);
  267. -- gtk_container_add (GTK_CONTAINER (window), sw);
  268. -- gtk_container_add (GTK_CONTAINER (sw), view);
  269. -- show_page (buffer, 1);
  270. -- gtk_widget_show_all (sw);
  271. -- }
  272. -- if (!GTK_WIDGET_VISIBLE (window))
  273. -- {
  274. -- gtk_widget_show (window);
  275. -- }
  276. -- else
  277. -- {
  278. -- gtk_widget_destroy (window);
  279. -- window = NULL;
  280. -- }
  281. -- return window;
  282. -- }
  283. end