Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/gui/orxonox_gui.cc @ 2622

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

orxonox/trunk/gui: modularity improved. Now init() of Subclasses execute the init() of their superclass to set the default values for specific Widgets

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