Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/bezierTrack/gui/orxonox_gui.cc @ 3095

Last change on this file since 3095 was 2740, checked in by bensch, 20 years ago

orxonox/trunk/gui: now Building a Window-Chain

File size: 20.1 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software Foundation,
18   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
19
20
21   ### File Specific:
22   main-programmer: Benjamin Grauer
23
24*/
25
26#include <iostream.h>
27
28#include "orxonox_gui.h"
29#include "orxonox_gui_video.h"
30#include "orxonox_gui_audio.h"
31#include "orxonox_gui_exec.h"
32#include "orxonox_gui_flags.h"
33#include "orxonox_gui_banner.h"
34#include "orxonox_gui_keys.h"
35
36  Window* orxonoxGUI;
37  OrxonoxGuiVideo* video;
38  OrxonoxGuiAudio* audio;
39  OrxonoxGuiExec* exec;
40  OrxonoxGuiFlags* flags;
41  OrxonoxGuiBanner* banner;
42  OrxonoxGuiKeys* keys;
43
44int main( int argc, char *argv[] )
45{
46  Window::lastWindow = NULL;
47  OrxonoxGui* orxonoxgui = new OrxonoxGui(argc, argv);
48  return 0;
49}
50
51/* ORXONOXGUI */
52
53/**
54   \brief Initializes the Gui
55*/
56OrxonoxGui::OrxonoxGui (int argc, char *argv[])
57{
58  gtk_init (&argc, &argv);
59  gtk_rc_parse( "rc" );
60 
61  orxonoxGUI = new Window( "Grafical OrxOnoX loader, "PACKAGE_VERSION);
62  orxonoxGUI->connectSignal ("destroy", orxonoxGUI->orxonox_gui_quit);
63  orxonoxGUI->connectSignal ("delete_event", orxonoxGUI->orxonox_gui_quit);
64 
65  Box* windowBox = new Box ('h');
66
67  banner = new OrxonoxGuiBanner();
68  windowBox->fill (banner->getWidget());
69 
70  Box* optionBox = new Box ('v');
71 
72  Box* avBox = new Box ('h');
73
74  video = new OrxonoxGuiVideo ();
75  avBox->fill (video->getWidget ());
76  audio = new OrxonoxGuiAudio ();
77  avBox->fill (audio->getWidget ());
78     
79  optionBox->fill (avBox);
80
81  keys = new OrxonoxGuiKeys ();
82  optionBox->fill (keys->getWidget ());
83
84  exec = new OrxonoxGuiExec (orxonoxGUI);
85  optionBox->fill (exec->getWidget ());
86
87  flags = new OrxonoxGuiFlags (orxonoxGUI);
88
89
90  optionBox->fill (flags->getWidget ());
91  windowBox->fill (optionBox);
92 
93  orxonoxGUI->fill (windowBox);
94  flags->setTextFromFlags (orxonoxGUI);
95
96  exec->setFilename ("~/.orxonox.conf");
97  exec->readFromFile (orxonoxGUI);
98  orxonoxGUI->walkThrough(orxonoxGUI->listOptions);
99
100  orxonoxGUI->showall ();
101
102 
103  gtk_main();
104}
105
106/* WIDGET */
107
108/**
109   \brief deletes any given Widget
110   This is still pretty crappy.
111*/
112Widget::~Widget()
113{
114  //  cout << "hiding: " <<this->label <<"\n";
115  this->hide();
116  //  cout << "check if Packer: "<<this->label <<"\n";
117  if (this->is_option < 0)
118    {
119      //  cout << "get Down "<<this->label <<"\n";
120      static_cast<Packer*>(this)->down->~Widget();
121    }
122  //  cout << "next != NULL?: " <<this->label <<"\n";
123  if (this->next != NULL)
124    this->next->~Widget();
125  cout << "delete Widget: " <<this->label <<"\n";
126  //  delete widget;
127}
128
129/**
130   \brief Initializes a widget.
131   Initializes the next Pointer and the other Widget-specific Defaults.
132*/
133void Widget::init()
134{
135  next = NULL;
136  label = "";
137  return;
138}
139
140/**
141   \brief makes the widget visible.
142*/
143void Widget::show()
144{
145  gtk_widget_show (this->widget);
146}
147
148/**
149   \brief hides the widget.
150*/
151void Widget::hide()
152{
153  gtk_widget_hide (this->widget);
154}
155
156/**
157   \brief Sets the resolution of a specific widget to the given size.
158   \param width the width of the widget to set.
159   \param height the height of the widget to set.
160*/
161void Widget::setSize(int width, int height)
162{
163  gtk_widget_set_usize (this->widget, width, height);
164}
165
166/**
167    \brief Connect any signal to any given Sub-widget
168*/
169void Widget::connectSignal (char* event, gint (*signal)(GtkWidget*, GdkEvent*, void *))
170{
171  g_signal_connect (G_OBJECT (this->widget), event, G_CALLBACK (signal), NULL);
172}
173
174/**
175   \brief Connect a signal with additionally passing the whole Object
176*/
177void Widget::connectSignal (char* event, gint (*signal)( GtkWidget*, Widget *))
178{
179g_signal_connect (G_OBJECT (this->widget), event, G_CALLBACK (signal), this);
180}
181
182/**
183   \brief Connect a signal with additionally passing a whole external Object
184*/
185void Widget::connectSignal (char* event, void* extObj, gint (*signal)(GtkWidget*, GdkEvent*, void *))
186{
187  g_signal_connect (G_OBJECT (this->widget), event, G_CALLBACK (signal), extObj);
188}
189
190/**
191   \brief Connect a signal with additionally passing a whole external Object
192*/
193void Widget::connectSignal (char* event, void* extObj, gint (*signal)(GtkWidget*, GdkEventKey*, void *))
194{
195  g_signal_connect (G_OBJECT (this->widget), event, G_CALLBACK (signal), extObj);
196}
197
198/**
199   \brief Moves through all the Widgets downwards from this and executes the function on them.
200   \param function must be of type void and takes a Widget* as an Input.
201*/
202void Widget::walkThrough (void (*function)(Widget*))
203{
204  function(this);
205  if (this->is_option < 0)
206    {
207      static_cast<Packer*>(this)->down->walkThrough (function);
208    } 
209
210  if (this->next != NULL)
211    this->next->walkThrough(function);
212}
213
214/**
215    \brief This is for listing the option of "widget"
216    \param widget specifies the widget that should be listed
217*/
218void Widget::listOptions (Widget* widget)
219{
220  if (widget->is_option >= 1)
221    cout << static_cast<Option*>(widget)->label <<" is : " << static_cast<Option*>(widget)->value <<endl;
222}
223
224/**
225    \brief This is for setting the option of "widget"
226    \param widget specifies the widget that should be set.
227*/
228void Widget::setOptions (Widget* widget)
229{
230  if (widget->is_option >= 1)
231    static_cast<Option*>(widget)->redraw();// <<" is : " << static_cast<Option*>(this)->value <<endl;
232}
233
234//void deleteWidget(Widget* lastWidget)
235
236
237/* PACKERS */
238
239/**
240   \brief Initializes a Packer.
241   Sets the down-pinter to NULL and other PackerSpecific-values to their defaults.
242*/
243void Packer::init (void)
244{
245  down = NULL;
246  this->setGroupName ("");
247
248
249  static_cast<Widget*>(this)->init();
250  return;
251}
252
253/**
254   \brief Sets the group name under which all the lower widgets of this will be saved.
255   \param name The name of the group.
256*/
257void Packer::setGroupName (char* name)
258{
259  groupName = name;
260}
261
262/**
263   \brief Retrieves the group name under which all the lower widgets of this will be saved.
264   \returns name The name of the group.
265*/
266char* Packer::getGroupName (void)
267{
268  return groupName;
269}
270
271/* CONTAINERS */
272
273/**
274   \brief Initializes a Container.
275   sets the Container-Specific defaults.
276*/
277void Container::init (void)
278{
279  is_option = -1;
280
281  static_cast<Packer*>(this)->init();
282
283  return;
284}
285
286/**
287   \briefFills a Container with lowerWidget.
288   It does this by filling up the down pointer only if down points to NULL.
289   \param lowerWidget the Widget that should be filled into the Container.
290*/
291void Container::fill (Widget *lowerWidget)
292{
293  if (this->down == NULL)
294    {
295      gtk_container_add (GTK_CONTAINER (this->widget), lowerWidget->widget);
296      this->down = lowerWidget;
297    }
298  else
299    cout << "!!error!! You try to put more than one Widget into a container. \nNot including this item.\nThis is only possible with Boxes"<<endl;
300}
301
302// gtk_container_set_border_width (GTK_CONTAINER (widget), 5);
303
304/* WINDOW */
305
306/**
307   \brief Creating a new Window without a Name
308*/
309Window::Window (void)
310{
311  this->init();
312}
313
314/**
315   \brief Creating a Window with a name
316   \param windowName the name the window should get.
317*/
318Window::Window (char* windowName)
319{
320  this->init();
321  this->setTitle (windowName);
322}
323
324Window* Window::lastWindow = NULL;
325
326/**
327   \brief initializes a new Window
328*/
329void Window::init()
330{
331  isOpen = false;
332
333  static_cast<Container*>(this)->init();
334
335  widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
336  gtk_window_set_policy (GTK_WINDOW(widget), TRUE, TRUE, TRUE);
337#if !defined(__WIN32__)
338  gtk_window_set_decorated (GTK_WINDOW (widget), FALSE);
339#endif
340  gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
341
342  //  printf("%p\n",lastWindow);
343
344  if (lastWindow !=NULL)
345    {
346      lastWindow->next = this;
347      printf("%p, %p\n", lastWindow, this);
348    }
349  Window::lastWindow = this;
350}
351
352/**
353   \brief Shows all Widgets that are included within this->widget.
354*/
355void Window::showall ()
356{
357  if (!isOpen)
358    {
359      printf ("showall\n");
360      gtk_widget_show_all  (widget);
361      isOpen = true;
362    }
363  else
364    {
365      printf ("showone\n");
366      gtk_widget_show (widget);
367    }
368}
369
370/**
371   \brief Set The Window-title to title
372   \param title title the Window should get.
373*/
374void Window::setTitle (char* title)
375{
376  label=title;
377  gtk_window_set_title (GTK_WINDOW (widget), title);
378}
379
380/**
381 * Quits the orxonox_GUI.
382 * This can be called as a Signal and is therefor static
383 \param widget The widget that called this function
384 \param event the event that happened to execute this function
385 \param data some data passed with the Signal
386 */
387gint Window::orxonox_gui_quit (GtkWidget *widget, GdkEvent *event, gpointer data)
388{
389  if (exec->shouldsave())
390    exec->writeToFile (orxonoxGUI);
391
392  gtk_main_quit();
393  return FALSE;
394}
395
396
397/* FRAME */
398
399/**
400    \brief Creates a new Frame without a name
401*/
402Frame::Frame (void)
403{
404  this->init();
405}
406
407/**
408   \brief Creates a new Frame with name title
409*/
410Frame::Frame (char* title)
411{
412  this->init();
413  this->setTitle(title);
414}
415
416/**
417    \brief Initializes a new Frame with default settings
418*/
419void Frame::init()
420{
421  static_cast<Container*>(this)->init();
422 
423  widget = gtk_frame_new ("");
424  gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
425}
426
427/**
428   \brief Sets the Frames name to title
429   \param title The title the Frame should get.
430*/
431void Frame::setTitle (char* title)
432{
433  label = title;
434  gtk_frame_set_label (GTK_FRAME (widget), title);
435}
436
437// EVENTBOX //
438
439/**
440   \brief Creates a new EventBox with default settings.
441*/
442EventBox::EventBox ()
443{
444  this->init();
445}
446/**
447   \brief Creates a new EventBox with name title
448   \param title title the Eventbox should get (only data-structure-internal)
449*/
450EventBox::EventBox (char* title)
451{
452  this->init();
453  this->setTitle(title);
454
455}
456
457/**
458   \brief Initializes a new EventBox
459*/
460void EventBox::init(void)
461{
462  is_option = -1;
463
464  static_cast<Container*>(this)->init();
465
466  widget = gtk_event_box_new ();
467  gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
468 
469}
470
471/**
472   \brief Sets the Title of the EventBox (not implemented)
473   \param title Name the EventBox should get (only datastructure-internal).
474*/
475void EventBox::setTitle (char* title)
476{
477  label = title;
478}
479
480/* BOX */
481
482/**
483   \brief Creates a new horizontal Box
484*/
485Box::Box (void)
486{
487  this->init('h');
488}
489
490/**
491   \brief Creates a new Box of type boxtype
492   \param boxtype if 'v' the Box will be vertically, if 'h' the Box will be horizontally
493*/
494Box::Box (char boxtype)
495{
496  this->init(boxtype);
497}
498
499/**
500   \brief Initializes a new Box with type boxtype
501   \param boxtype see Box(char boxtype)
502*/
503void Box::init(char boxtype)
504{
505  is_option = -2;
506
507  static_cast<Packer*>(this)->init();
508  if (boxtype == 'v')
509    {
510      widget = gtk_vbox_new (FALSE, 0);
511    }
512  else
513    {
514      widget = gtk_hbox_new (FALSE, 0);
515    }
516}
517
518/**
519    \brief Fills a box with a given Widget.
520    It does this by apending the first one to its down-pointer and all its following ones to the preceding next-pointer. The last one will receive a NULL pointer as Next
521    \param lowerWidget the next Widget that should be appendet to this Box
522*/
523void Box::fill (Widget *lowerWidget)
524{
525  gtk_box_pack_start (GTK_BOX (this->widget), lowerWidget->widget, TRUE, TRUE, 0);
526  if (this->down == NULL)
527    this->down = lowerWidget;
528  else
529    {
530      Widget* tmp;
531      tmp = this->down;
532      while (tmp->next != NULL)
533        {
534          tmp = tmp->next;
535        }
536      tmp->next = lowerWidget;
537    }
538}
539
540/* IMAGE */
541
542/**
543   \brief Creates a new Image
544   \param imagename the location of the Image on the Hard Disc
545*/
546Image::Image (char* imagename)
547{
548  this->init();
549  widget = gtk_image_new_from_file (imagename);
550  label = imagename;
551}
552
553/**
554    \brief Initializes a new Image
555*/
556void Image::init()
557{
558  is_option = 0;
559
560  static_cast<Widget*>(this)->init();
561}
562
563
564/* OPTION */
565
566/**
567   \brief Initializes a new Option.
568   sets all Option-Specific-Values to their defaults.
569*/
570void Option::init()
571{
572  value = 0;
573  flag_name = "";
574  flag_name_short = "";
575  saveable = false;
576  default_value = 0;
577
578  static_cast<Widget*>(this)->init();
579
580  return;
581}
582
583/**
584   \brief This sets The FlagName of an Option and defines its default Values
585   !! Options will be saved if flagname is different from "" !!
586   \param flagname the Name that will be displayed in the output
587   \param defaultvalue the default Value for this Option (see definition of defaultvalue
588*/
589void Option::setFlagName (char* flagname, int defaultvalue)
590{
591  flag_name = flagname;
592  default_value = defaultvalue;
593  cout << "Set Flagname of " << label << " to " << flagname << endl;
594}
595
596/**
597    \brief see Option::setFlagName (char* flagname, int defaultvalue)
598    \param flagname the Name that will be displayed in the output
599    \param defaultvalue the default Value for this Option (see definition of defaultvalue
600    \param flagnameshort a short flagname to be displayed in the output
601*/
602void Option::setFlagName (char* flagname, char* flagnameshort,  int defaultvalue)
603{
604  flag_name = flagname;
605  flag_name_short = flagnameshort;
606  default_value = defaultvalue;
607  cout << "Set Flagname of " << label << " to " << flagname << endl;
608}
609
610
611/* BUTTON */
612
613/**
614   \brief Creates a new Button with a buttonname
615   \param buttonname sets the Name of the Button
616*/
617Button::Button(char* buttonname)
618{
619  this->init();
620  this->setTitle(buttonname);
621}
622
623/**
624   \brief Initializes a new Button
625*/
626void Button::init(void)
627{
628  is_option = 0;
629
630  static_cast<Option*>(this)->init();
631
632  widget = gtk_button_new_with_label ("");
633}
634
635/**
636   \brief Sets a new name to the Button
637   \param title The name the Button should get
638*/
639void Button::setTitle (char *title)
640{
641  label = title;
642  gtk_button_set_label (GTK_BUTTON(widget), title);
643}
644
645/**
646   \brief redraws the Button
647   not implemented yet
648*/
649void Button::redraw ()
650{
651}
652
653/* CHECKBUTTON */
654
655/**
656   \brief Creates a new CheckButton with an ame
657   \param buttonname The name the CheckButton should display.
658*/
659CheckButton::CheckButton (char* buttonname)
660{
661  this->init();
662  this->setTitle(buttonname);
663
664  this->connectSignal ("clicked", this->OptionChange);
665}
666
667/**
668   \brief Initialize a new CheckButton with default settings
669*/
670void CheckButton::init(void)
671{
672  is_option = 1;
673
674  static_cast<Option*>(this)->init();
675
676  widget = gtk_check_button_new_with_label ("");
677}
678
679/**
680   \brief Sets a new Title to a CheckButton
681   \param title The new Name the CheckButton should display.
682*/
683void CheckButton::setTitle(char* title)
684{
685  label = title;
686  gtk_button_set_label(GTK_BUTTON(widget), title);
687}
688
689
690/**
691    \brief Signal OptionChange writes the Value from the CheckButton to its Object-Database.
692    \param widget The widget(CheckButton) that has a changed Value
693    \param checkbutton the CheckButton-Object that should receive the change.
694*/
695gint CheckButton::OptionChange (GtkWidget *widget, Widget* checkbutton)
696{
697  static_cast<CheckButton*>(checkbutton)->value = (int)gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON ((CheckButton*)checkbutton->widget));
698  flags->setTextFromFlags(orxonoxGUI);
699  cout << static_cast<CheckButton*>(checkbutton)->label << " set to: " << static_cast<CheckButton*>(checkbutton)->value << endl;
700}
701
702/**
703   \brief Redraws the CheckButton (if option has changed).
704   Example: if new settings are loaded the Button must be redrawn for the GUI to display that Change
705*/
706void CheckButton::redraw ()
707{
708  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
709}
710
711/* SLIDER */
712
713/**
714   \brief Creates a new Slider
715   \param slidername The data-structure-name of the slider.
716   \param start The minimal Value of the slider.
717   \param end The maximal Value of the slider.
718*/
719Slider::Slider (char* slidername, int start, int end)
720{
721  this->init(start, end);
722  this->setValue(start);
723  this->setTitle(slidername);
724  this->connectSignal ("value_changed", this->OptionChange);
725}
726
727/**
728   \brief Initializes a Slider with start and end Values
729   params: see Slider::Slider (char* slidername, int start, int end)
730*/
731void Slider::init(int start, int end)
732{
733  is_option = 2;
734
735  static_cast<Option*>(this)->init();
736
737  widget = gtk_hscale_new_with_range (start, end, 5);
738}
739
740/**
741   \brief Sets a new Title to the Slider
742   \param title The new Name of the slider
743*/
744void Slider::setTitle(char* title)
745{
746  label = title;
747}
748
749/**
750   \brief Setting a new value to the Slider.
751   Maybe you also require a Slider::redraw() for this to display
752*/
753void Slider::setValue(int value)
754{
755  this->value = value;
756}
757
758/**
759    \brief Signal OptionChange writes the Value from the Slider to its Object-Database.
760    \param widget The widget(Slider) that has a changed Value
761    \param slider the Slider-Object that should receive the change.
762*/
763gint Slider::OptionChange (GtkWidget *widget, Widget* slider)
764{
765  static_cast<Slider*>(slider)->value = (int)gtk_range_get_value (GTK_RANGE ((Slider*)slider->widget));
766  flags->setTextFromFlags(orxonoxGUI);
767  cout << static_cast<Slider*>(slider)->label << " set to: "<< static_cast<Slider*>(slider)->value << endl;
768}
769
770/**
771   \brief Redraws the widget
772   Example: see void CheckButton::redraw ()
773*/
774void Slider::redraw ()
775{
776  gtk_range_set_value (GTK_RANGE (widget), value);
777}
778
779/* MENU */
780
781/**
782    \brief Creates a Menu-Item-list out of multiple input.
783    !! Consider, that the last input argument has to be "lastItem" for this to work!!
784    \param menuname The Database-Name of this Menu
785    \param ... items to be added to this Menu. !! Consider, that the last input argument has to be "lastItem" for this to work!!
786*/
787Menu::Menu (char* menuname, ...)
788{
789  this->init();
790  this->setTitle(menuname);
791   
792  char *itemName;
793 
794  va_start (itemlist, menuname);
795  while (strcmp (itemName = va_arg (itemlist, char*), "lastItem"))
796    {
797      this->addItem(itemName);
798    }
799  va_end(itemlist);
800
801  gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
802  this->connectSignal ("changed", this->OptionChange);
803}
804
805/**
806   \brief Initializes a new Menu with no items
807*/
808void Menu::init(void)
809{
810  is_option = 2;
811
812  static_cast<Option*>(this)->init();
813
814  widget = gtk_option_menu_new ();
815  menu = gtk_menu_new ();
816
817}
818
819/**
820 * Sets the Database-Name of this Menu
821 \param title Database-Name to be set.
822*/
823void Menu::setTitle(char* title)
824{
825  label = title;
826}
827
828/**
829   \brief appends a new Item to the Menu-List.
830   \param itemName the itemName to be appendet.
831*/
832void Menu::addItem (char* itemName)
833{
834  item = gtk_menu_item_new_with_label (itemName);
835  gtk_menu_shell_append(GTK_MENU_SHELL (menu), item);
836}
837
838/**
839    \brief Signal OptionChange writes the Value from the Menu to its Object-Database.
840    \param widget The widget(Menu) that has a changed Value
841    \param menu the Menu-Object that should receive the change.
842*/
843gint Menu::OptionChange (GtkWidget *widget, Widget* menu)
844{
845  static_cast<Menu*>(menu)->value = (int)gtk_option_menu_get_history (GTK_OPTION_MENU (menu->widget));
846  flags->setTextFromFlags(orxonoxGUI);
847  cout << static_cast<Menu*>(menu)->label << " changed to : " << static_cast<Menu*>(menu)->value << endl;
848}
849
850/**
851   \brief Redraws the widget
852   Example: see void CheckButton::redraw ()
853 */
854void Menu::redraw ()
855{
856  gtk_option_menu_set_history (GTK_OPTION_MENU (widget), value);
857}
858
859/**
860   \brief Creates a new default Label with no Text.
861   You migth consider adding Label::setTitle with this.
862*/
863Label:: Label ()
864{
865  this->init();
866}
867
868/**
869   \brief Creates a new Label with a Text.
870   \param text The text to be displayed.
871*/
872Label:: Label (char* text)
873{
874  this->init();
875  this->setText(text);
876}
877
878/**
879   \brief initializes a new Label
880*/
881void Label::init(void)
882{
883  is_option = 0;
884
885  static_cast<Widget*>(this)->init();
886
887  widget = gtk_label_new ("");
888  gtk_label_set_line_wrap (GTK_LABEL(widget), TRUE);
889}
890
891/**
892   \brief Sets a new Text to a Label.
893   \param text The text to be inserted into the Label.
894*/
895void Label::setText (char* text)
896{
897  label = text;
898  gtk_label_set_text (GTK_LABEL (this->widget), text);
899}
900
901/**
902   \brief get the Text of a Label
903   \return The Text the Label holds.
904*/
905char* Label::getText ()
906{
907  return ((char*)gtk_label_get_text (GTK_LABEL (this->widget)));
908}
Note: See TracBrowser for help on using the repository browser.