PageRenderTime 19ms CodeModel.GetById 10ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

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