Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/gui/orxonox_gui_gtk.cc @ 3144

Last change on this file since 3144 was 3144, checked in by bensch, 19 years ago

orxonox/trunk/gui: modularity improvement: taken the gtk-stuff out of the main GUI

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