PageRenderTime 25ms CodeModel.GetById 15ms app.highlight 5ms RepoModel.GetById 2ms app.codeStats 0ms

/src/wrappers/gtk/examples/gtk-demo/gtk_demo.e

http://github.com/tybor/Liberty
Specman e | 567 lines | 221 code | 92 blank | 254 comment | 6 complexity | 5b23e7aa5369ebe7d72d4a1cd014d2b4 MD5 | raw file
  1indexing
  2	description: "Gtk demo."
  3	copyright: "[
  4					Copyright (C) 2006 Paolo Redaelli, GTK team
  5					
  6					This program is free software; you can redistribute it and/or
  7					modify it under the terms of the GNU General Public License
  8					as published by the Free Software Foundation; either version 2.0 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 GTK_DEMO
 23
 24insert
 25	GTK
 26	G_TYPES
 27	GTK_STANDARD_ENUMERATIONS
 28	PANGO_STYLE
 29	-- Eventually insert this - when it will be implemented:
 30	-- PANGO_STANDARD_ENUMERATIONS
 31
 32creation make
 33
 34feature -- Buffers
 35	info_buffer, source_buffer: GTK_TEXT_BUFFER
 36	current_file: STRING
 37
 38feature -- column numbers
 39  title_column: INTEGER is 0
 40  filename_column: INTEGER is 1
 41  italic_column: INTEGER is 2
 42  columns_number: INTEGER is 3
 43
 44feature -- labels text
 45	window_title: STRING is "GTK+ Code Demos"
 46	info_label_string: STRING is "_Info"
 47	source_label_string: STRING is "_Source"
 48	
 49feature -- widgets
 50	window: GTK_WINDOW is
 51		once 
 52			create Result.make -- a new toplevel window
 53			Result.set_title (window_title);
 54			Result.connect_to_destroy_signal (agent quit)
 55			Result.add (hbox)
 56
 57			-- TODO: provide Eiffel syntax highlighting
 58			Result.set_default_size (600, 400)			
 59		end
 60
 61   hbox: GTK_HBOX is
 62		once 
 63			create Result.make (False, 0)
 64			Result.pack_start (demo_list, False, False, 0)
 65			Result.pack_start (notebook, True, True, 0)
 66		end
 67
 68   notebook: GTK_NOTEBOOK is
 69		once 
 70			create Result.make
 71			Result.append_page (text_from (info_buffer),
 72									  create {GTK_LABEL}.with_mnemonic 
 73									  (info_label_string))
 74			Result.append_page (source_widget_from (source_buffer),
 75									  create {GTK_LABEL}.with_mnemonic (source_label_string));
 76		end
 77
 78   tag: GTK_TEXT_TAG
 79
 80	demo_list: GTK_TREE_VIEW is
 81		local
 82			tree_view: GTK_TREE_VIEW
 83			selection: GTK_TREE_SELECTION;
 84			cell: GTK_CELL_RENDERER_TEXT;
 85			column: GTK_TREE_VIEW_COLUMN;
 86			-- box: GTK_NOTEBOOK
 87			label: GTK_LABEL;
 88			scrolled_window: GTK_SCROLLED_WINDOW
 89		once
 90			create tree_view.with_model (model)
 91			selection := tree_view.selection -- Short-cut to avoid retrieving the selection everytime
 92			selection.set_browse_mode
 93			tree_view.set_size_request (200, -1)
 94					
 95			create cell.make
 96			cell.set_style (pango_style_italic)
 97			
 98			create column.with_attributes ("Widget (double click for demo)", cell,
 99													 <<["text",title_column], ["style_set",italic_column]>>)
100			tree_view.append_column (column)
101			
102			-- Why should I select the first? Let the user do it.
103			-- tree_iter := model.get_iterator_first
104			-- selection.select_iter (tree_iter)
105			
106			selection.connect_to_changed_signal (agent selection_callback)
107			tree_view.connect_to_row_activated_signal (agent row_activated_callback)
108			-- Note: changed and row_activated signals should receive
109			-- model somehow. In C it is passed throught the data
110			-- gpointer argument. In Eiffel this is not needed, since it 
111			-- is already available as a feature of Current's GTK_DEMO.
112
113			tree_view.expand_all -- collapse_all
114			tree_view.set_headers_visible
115			
116			create scrolled_window.make (Void,Void)
117			Result.set_policy(gtk_policy_never,gtk_policy_automatic)	
118			
119			Result.add (tree_view)
120			
121			create label.with_label ("Widget (double click for demo)")
122			
123			notebook.append_page (scrolled_window, label)
124			
125			tree_view.grab_focus
126		end
127														 
128	setup_default_icon is
129		local
130			pixbuf, transparent: GDK_PIXBUF
131			list: G_LIST [GDK_PIXBUF]
132		do
133
134			debug print ("TODO: implement and use find_file; it requires GLib's g_file%N") end
135			
136			--   filename = demo_find_file ("gtk-logo-rgb.gif", &err);
137			--   if (filename)
138			create pixbuf.from_file ("gtk-logo-rgb.gif")
139			
140			-- Ignoring this error (not handling G_ERROR once it is
141			-- implemented above) would probably be reasonable for most
142			-- apps.  We're just showing off.
143
144			--       GList *list;      
145			--       GdkPixbuf *transparent;
146			
147			-- The gtk-logo-rgb icon has a white background, make it transparent
148			debug print("TODO: transparent := pixbuf.add_alpha (True, 0xff, 0xff, 0xff)%N") end
149			transparent := pixbuf
150			
151			create list.empty
152			list.append (transparent)
153			debug print("TODO: gtk_window_set_default_icon_list (list)%N") end
154			gtk.set_default_icon_list (list)
155		end
156
157feature {} -- Creation
158	make is
159		do
160			gtk.initialize
161			
162			setup_default_icon
163			window.show_all
164			--   load_file (testgtk_demos[0].filename);
165			gtk.run_main_loop
166		end
167
168	find_file (a_base_filename: STRING): STRING is
169			-- Looks for `a_base_filename' first in the current directory, then in the
170			-- location GTK+ where it will be installed on make install,
171			-- returns the first file found. If `a_base_filename' is not found 
172			-- it is Void; `error' will be set accordingly
173		require a_base_filename /=Void
174		do
175			--   if (g_file_test ("gtk-logo-rgb.gif", G_FILE_TEST_EXISTS) &&
176			--       g_file_test (base, G_FILE_TEST_EXISTS))
177			--     return g_strdup (base);
178			--   else
179			--     {
180			--       char *filename = g_build_filename (DEMOCODEDIR, base, NULL);
181			--       if (!g_file_test (filename, G_FILE_TEST_EXISTS))
182			-- 	{
183			-- 	  g_set_error (err, G_FILE_ERROR, G_FILE_ERROR_NOENT,
184			-- 		       "Cannot find demo data file \"%s\"", base);
185			-- 	  g_free (filename);
186			-- 	  return NULL;
187			-- 	}
188			--       return filename;
189			--     }
190			-- }
191		ensure implemented: False
192		end
193	
194	window_closed_callback (a_window: GTK_WINDOW) is
195		do
196			--   CallbackData *cbdata = data;
197			--   GtkTreeIter iter;
198			--   gboolean italic;
199			
200			--   gtk_tree_model_get_iter (cbdata->model, &iter, cbdata->path);
201			--   gtk_tree_model_get (GTK_TREE_MODEL (cbdata->model), &iter,
202			-- 		      ITALIC_COLUMN, &italic,
203			-- 		      -1);
204			--   if (italic)
205			--     gtk_tree_store_set (GTK_TREE_STORE (cbdata->model), &iter,
206			-- 			ITALIC_COLUMN, !italic,
207			-- 			-1);
208			
209			--   gtk_tree_path_free (cbdata->path);
210			--   g_free (cbdata);
211		end
212
213
214	-- void
215	-- load_file (const gchar *filename)
216	-- {
217	--   FILE *file;
218	--   GtkTextIter start, end;
219	--   char *full_filename;
220	--   GError *err = NULL;
221	--   GString *buffer = g_string_new (NULL);
222	--   int state = 0;
223	--   gboolean in_para = 0;
224
225	--   if (current_file && !strcmp (current_file, filename))
226	--     {
227	--       g_string_free (buffer, TRUE);
228	--       return;
229	--     }
230
231	--   g_free (current_file);
232	--   current_file = g_strdup (filename);
233  
234	--   gtk_text_buffer_get_bounds (info_buffer, &start, &end);
235	--   gtk_text_buffer_delete (info_buffer, &start, &end);
236
237	--   gtk_text_buffer_get_bounds (source_buffer, &start, &end);
238	--   gtk_text_buffer_delete (source_buffer, &start, &end);
239
240	--   full_filename = demo_find_file (filename, &err);
241	--   if (!full_filename)
242	--     {
243	--       g_warning ("%s", err->message);
244	--       g_error_free (err);
245	--       return;
246	--     }
247
248	--   file = g_fopen (full_filename, "r");
249
250	--   if (!file)
251	--     g_warning ("Cannot open %s: %s\n", full_filename, g_strerror (errno));
252
253	--   g_free (full_filename);
254
255	--   if (!file)
256	--     return;
257
258	--   gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
259	--   while (read_line (file, buffer))
260	--     {
261	--       gchar *p = buffer->str;
262	--       gchar *q;
263	--       gchar *r;
264      
265	--       switch (state)
266	-- 	{
267	-- 	case 0:
268	-- 	  /* Reading title */
269	-- 	  while (*p == '/' || *p == '*' || g_ascii_isspace (*p))
270	-- 	    p++;
271	-- 	  r = p;
272	-- 	  while (*r != '/' && strlen (r))
273	-- 	    r++;
274	-- 	  if (strlen (r) > 0)
275	-- 	    p = r + 1;
276	-- 	  q = p + strlen (p);
277	-- 	  while (q > p && g_ascii_isspace (*(q - 1)))
278	-- 	    q--;
279
280	-- 	  if (q > p)
281	-- 	    {
282	-- 	      int len_chars = g_utf8_pointer_to_offset (p, q);
283
284	-- 	      end = start;
285
286	-- 	      g_assert (strlen (p) >= q - p);
287	-- 	      gtk_text_buffer_insert (info_buffer, &end, p, q - p);
288	-- 	      start = end;
289
290	-- 	      gtk_text_iter_backward_chars (&start, len_chars);
291	-- 	      gtk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end);
292
293	-- 	      start = end;
294	      
295	-- 	      state++;
296	-- 	    }
297	-- 	  break;
298	    
299	-- 	case 1:
300	-- 	  /* Reading body of info section */
301	-- 	  while (g_ascii_isspace (*p))
302	-- 	    p++;
303	-- 	  if (*p == '*' && *(p + 1) == '/')
304	-- 	    {
305	-- 	      gtk_text_buffer_get_iter_at_offset (source_buffer, &start, 0);
306	-- 	      state++;
307	-- 	    }
308	-- 	  else
309	-- 	    {
310	-- 	      int len;
311	      
312	-- 	      while (*p == '*' || g_ascii_isspace (*p))
313	-- 		p++;
314
315	-- 	      len = strlen (p);
316	-- 	      while (g_ascii_isspace (*(p + len - 1)))
317	-- 		len--;
318	      
319	-- 	      if (len > 0)
320	-- 		{
321	-- 		  if (in_para)
322	-- 		    gtk_text_buffer_insert (info_buffer, &start, " ", 1);
323
324	-- 		  g_assert (strlen (p) >= len);
325	-- 		  gtk_text_buffer_insert (info_buffer, &start, p, len);
326	-- 		  in_para = 1;
327	-- 		}
328	-- 	      else
329	-- 		{
330	-- 		  gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
331	-- 		  in_para = 0;
332	-- 		}
333	-- 	    }
334	-- 	  break;
335
336	-- 	case 2:
337	-- 	  /* Skipping blank lines */
338	-- 	  while (g_ascii_isspace (*p))
339	-- 	    p++;
340	-- 	  if (*p)
341	-- 	    {
342	-- 	      p = buffer->str;
343	-- 	      state++;
344	-- 	      /* Fall through */
345	-- 	    }
346	-- 	  else
347	-- 	    break;
348	  
349	-- 	case 3:
350	-- 	  /* Reading program body */
351	-- 	  gtk_text_buffer_insert (source_buffer, &start, p, -1);
352	-- 	  gtk_text_buffer_insert (source_buffer, &start, "\n", 1);
353	-- 	  break;
354	-- 	}
355	--     }
356
357	--   fontify ();
358
359	--   g_string_free (buffer, TRUE);
360	-- }
361
362	row_activated_callback (a_path: GTK_TREE_PATH;
363									a_column: GTK_TREE_VIEW_COLUMN;
364									a_tree_view: GTK_TREE_VIEW) is
365		do
366			-- {
367			--   GtkTreeIter iter;
368			--   gboolean italic;
369			--   GDoDemoFunc func;
370			--   GtkWidget *window;
371			--   GtkTreeModel *model;
372
373			--   model = gtk_tree_view_get_model (tree_view);
374			
375			--   gtk_tree_model_get_iter (model, &iter, path);
376			--   gtk_tree_model_get (GTK_TREE_MODEL (model),
377			-- 		      &iter,
378			-- 		      FUNC_COLUMN, &func,
379			-- 		      ITALIC_COLUMN, &italic,
380			-- 		      -1);
381			
382			--   if (func)
383			--     {
384			--       gtk_tree_store_set (GTK_TREE_STORE (model),
385			-- 			  &iter,
386			-- 			  ITALIC_COLUMN, !italic,
387			-- 			  -1);
388			--       window = (func) (gtk_widget_get_toplevel (GTK_WIDGET (tree_view)));
389			
390			--       if (window != NULL)
391			-- 	{
392			-- 	  CallbackData *cbdata;
393			
394			-- 	  cbdata = g_new (CallbackData, 1);
395			-- 	  cbdata->model = model;
396			-- 	  cbdata->path = gtk_tree_path_copy (path);
397			
398			-- 	  g_signal_connect (window, "destroy",
399			-- 			    G_CALLBACK (window_closed_cb), cbdata);
400			-- 	}
401			--     }
402			-- }
403		end
404	
405	selection_callback (a_selection: GTK_TREE_SELECTION) is
406		local iter: GTK_TREE_ITER
407		do
408			debug print ("selection_callback unimplemented%N") end
409			-- demo := model.value(iter, demo_column)
410			-- notebook
411			if a_selection.is_node_selected then
412				print("TODO: load_file (model.value (iter, filename_column))")
413			end
414		end
415
416	text_from (a_buffer: GTK_TEXT_BUFFER): GTK_SCROLLED_WINDOW is
417		local
418			text_view: GTK_TEXT_VIEW
419			buffer: GTK_TEXT_BUFFER
420		do
421			-- static GtkWidget *
422			-- create_text (GtkTextBuffer **buffer,
423			-- 	     gboolean        is_source)
424			-- {
425			--   GtkWidget *scrolled_window;
426			--   GtkWidget *text_view;
427			--   PangoFontDescription *font_desc;
428
429			create Result.make (Void,Void)
430			Result.set_policy (gtk_policy_automatic,
431									 gtk_policy_automatic)
432			Result.set_shadow_type (gtk_shadow_in)
433
434			create text_view.make
435			create buffer.make
436			text_view.set_buffer (buffer)
437			text_view.set_uneditable
438			text_view.set_cursor_invisible
439			text_view.set_wrap_mode (gtk_wrap_word) -- Make text a little nicer
440			-- TODO: text_view.set_pixels_above_lines (2)
441			-- TODO: text_view.set_pixels_below_lines (2)
442
443			Result.add (text_view)
444		end
445
446	source_widget_from (a_buffer: GTK_TEXT_BUFFER): GTK_SCROLLED_WINDOW is
447		local
448			text_view: GTK_TEXT_VIEW
449			buffer: GTK_TEXT_BUFFER
450		do
451			-- static GtkWidget *
452			-- create_text (GtkTextBuffer **buffer,
453			-- 	     gboolean        is_source)
454			-- {
455			--   GtkWidget *scrolled_window;
456			--   GtkWidget *text_view;
457			--   PangoFontDescription *font_desc;
458
459			create Result.make (Void,Void)
460			Result.set_policy (gtk_policy_automatic,gtk_policy_automatic)
461			Result.set_shadow_type (gtk_shadow_in)
462
463			create text_view.make
464			create buffer.make
465			text_view.set_buffer (buffer)
466			text_view.set_uneditable
467			text_view.set_cursor_invisible
468			Result.add (text_view)
469
470			-- Note: original C program used monospace font to display
471			-- source. Eiffel are better viewed with proportional fonts.
472
473			-- font_desc = pango_font_description_from_string ("monospace");
474			-- gtk_widget_modify_font (text_view, font_desc);
475			-- pango_font_description_free (font_desc);
476
477			text_view.set_wrap_mode (gtk_wrap_none)
478		ensure implemented: Result /= Void
479		end
480
481feature -- Demos
482	
483	model: GTK_TREE_STORE is
484		local
485			demo, subdemo: DEMO;
486			demos_iterator, child_iterator: ITERATOR [DEMO];
487			tree_iter, subtree_iter: GTK_TREE_ITER;			
488		once
489			create Result.make (<<g_type_string, g_type_string, g_type_boolean>>)
490
491			from 
492				demos_iterator := demos.get_new_iterator
493				demos_iterator.start 
494				create tree_iter.make_from_model (Result)
495				create subtree_iter.make_from_model (Result)
496			until demos_iterator.is_off
497			loop
498				demo := demos_iterator.item
499				debug print ("Adding "+demo.name+" demo%N") end
500				Result.append (tree_iter, Void)
501				Result.set_string (tree_iter, title_column, demo.name)
502				Result.set_string (tree_iter, filename_column, demo.filename)
503				-- Ahhh! A pointer to a function into a model!
504				-- FUNC_COLUMN, d->func,
505				-- This should be replaced with a proper Eiffel object
506				-- stored somewhere.
507				Result.set_boolean (tree_iter, italic_column, False)
508				
509				if demo.has_children then
510					from
511						child_iterator := demo.subdemos.get_new_iterator
512						child_iterator.start
513					until child_iterator.is_off
514					loop 
515						subdemo := child_iterator.item
516						Result.append (subtree_iter, tree_iter)
517						Result.set_string (subtree_iter, title_column, subdemo.name)
518						Result.set_string (subtree_iter, filename_column, subdemo.filename)
519						-- aaargh! another FUNC_COLUMN, subdemo->func,
520						Result.set_boolean (subtree_iter, italic_column, False)
521						child_iterator.next
522					end -- loop over children
523				end -- has childres
524				demos_iterator.next
525			end -- loop over demos
526		end
527	
528	demos:  LINKED_LIST [DEMO] is
529		once
530			Result := {LINKED_LIST[DEMO] << application_window,
531													  -- button_box,
532													  -- change_display,
533													  -- color_selector,
534													  -- dialog,
535													  -- drawing_area,
536													  -- entry_completion,
537													  expander
538													  -- icon_views,
539													  -- "Icon View Basics", "iconview.e",
540													  -- "Editing and Drag-and-Drop", 
541													  --"iconview_edit.e",
542													  -- images,
543													  -- menus,
544													  -- paned
545													  -- TODO: pixbufs
546													  -- rotated_text size_groups
547													  -- stock_browser text_demos
548													  -- [hypertext, multipleviews]
549													  -- tree_demos
550													  -- [editable_cells,
551													  -- list_store, tree_store]
552													  -- ui_manager
553													  >>}
554		end
555
556
557feature 	-- demos singletons 
558	application_window: APP_WINDOW is once create Result.make end
559	expander: EXPANDER is once create Result.make end
560	
561feature -- callbacks
562	quit (an_object: GTK_OBJECT) is
563		do
564			print (once "Quitting Eiffel Gtk-demo applicaiton%N")
565			gtk.quit
566		end
567end -- GTK_DEMO