Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/buerli/gui/orxonox_gui.cc @ 2736

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

orxonox/branches/buerli: merged back from trunk, with new configure makefile and so forth.

File size: 19.4 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   \brief 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   \brief Initializes a widget.
130   Initializes the next Pointer and the other Widget-specific Defaults.
131*/
132void Widget::init()
133{
134  next = NULL;
135  label = "";
136  return;
137}
138
139/**
140   \brief makes the widget visible.
141*/
142void Widget::show()
143{
144  gtk_widget_show (this->widget);
145}
146
147/**
148   \brief 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    \brief 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   \brief 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   \brief 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   \brief 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*/
193void Widget::walkThrough (void (*function)(Widget*))
194{
195  function(this);
196  if (this->is_option < 0)
197    {
198      static_cast<Packer*>(this)->down->walkThrough (function);
199    } 
200
201  if (this->next != NULL)
202    this->next->walkThrough(function);
203}
204
205/**
206    \brief This is for listing the option of "widget"
207    \param widget specifies the widget that should be listed
208*/
209void Widget::listOptions (Widget* widget)
210{
211  if (widget->is_option >= 1)
212    cout << static_cast<Option*>(widget)->label <<" is : " << static_cast<Option*>(widget)->value <<endl;
213}
214
215/**
216    \brief This is for setting the option of "widget"
217    \param widget specifies the widget that should be set.
218*/
219void Widget::setOptions (Widget* widget)
220{
221  if (widget->is_option >= 1)
222    static_cast<Option*>(widget)->redraw();// <<" is : " << static_cast<Option*>(this)->value <<endl;
223}
224
225//void deleteWidget(Widget* lastWidget)
226
227
228/* PACKERS */
229
230/**
231   \brief Initializes a Packer.
232   Sets the down-pinter to NULL and other PackerSpecific-values to their defaults.
233*/
234void Packer::init (void)
235{
236  down = NULL;
237  this->setGroupName ("");
238
239
240  static_cast<Widget*>(this)->init();
241  return;
242}
243
244/**
245   \brief Sets the group name under which all the lower widgets of this will be saved.
246   \param name The name of the group.
247*/
248void Packer::setGroupName (char* name)
249{
250  groupName = name;
251}
252
253/**
254   \brief Retrieves the group name under which all the lower widgets of this will be saved.
255   \returns name The name of the group.
256*/
257char* Packer::getGroupName (void)
258{
259  return groupName;
260}
261
262/* CONTAINERS */
263
264/**
265   \brief Initializes a Container.
266   sets the Container-Specific defaults.
267*/
268void Container::init (void)
269{
270  is_option = -1;
271
272  static_cast<Packer*>(this)->init();
273
274  return;
275}
276
277/**
278   \briefFills 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   \brief Creating a new Window without a Name
299*/
300Window::Window (void)
301{
302  this->init();
303}
304
305/**
306   \brief 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   \brief 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   \brief 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   \brief 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    \brief Creates a new Frame without a name
372*/
373Frame::Frame (void)
374{
375  this->init();
376}
377
378/**
379   \brief Creates a new Frame with name title
380*/
381Frame::Frame (char* title)
382{
383  this->init();
384  this->setTitle(title);
385}
386
387/**
388    \brief 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   \brief 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   \brief Creates a new EventBox with default settings.
412*/
413EventBox::EventBox ()
414{
415  this->init();
416}
417/**
418   \brief 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   \brief 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   \brief 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   \brief Creates a new horizontal Box
455*/
456Box::Box (void)
457{
458  this->init('h');
459}
460
461/**
462   \brief 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   \brief 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    \brief 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  gtk_box_pack_start (GTK_BOX (this->widget), lowerWidget->widget, TRUE, TRUE, 0);
497  if (this->down == NULL)
498    this->down = lowerWidget;
499  else
500    {
501      Widget* tmp;
502      tmp = this->down;
503      while (tmp->next != NULL)
504        {
505          tmp = tmp->next;
506        }
507      tmp->next = lowerWidget;
508    }
509}
510
511/* IMAGE */
512
513/**
514   \brief Creates a new Image
515   \param imagename the location of the Image on the Hard Disc
516*/
517Image::Image (char* imagename)
518{
519  this->init();
520  widget = gtk_image_new_from_file (imagename);
521  label = imagename;
522}
523
524/**
525    \brief Initializes a new Image
526*/
527void Image::init()
528{
529  is_option = 0;
530
531  static_cast<Widget*>(this)->init();
532}
533
534
535/* OPTION */
536
537/**
538   \brief Initializes a new Option.
539   sets all Option-Specific-Values to their defaults.
540*/
541void Option::init()
542{
543  value = 0;
544  flag_name = "";
545  flag_name_short = "";
546  default_value = 0;
547
548  static_cast<Widget*>(this)->init();
549
550  return;
551}
552
553/**
554   \brief This sets The FlagName of an Option and defines its default Values
555   !! Options will be saved if flagname is different from "" !!
556   \param flagname the Name that will be displayed in the output
557   \param defaultvalue the default Value for this Option (see definition of defaultvalue
558*/
559void Option::setFlagName (char* flagname, int defaultvalue)
560{
561  flag_name = flagname;
562  default_value = defaultvalue;
563  cout << "Set Flagname of " << label << " to " << flagname << endl;
564}
565
566/**
567    \brief see Option::setFlagName (char* flagname, int defaultvalue)
568    \param flagname the Name that will be displayed in the output
569    \param defaultvalue the default Value for this Option (see definition of defaultvalue
570    \param flagnameshort a short flagname to be displayed in the output
571*/
572void Option::setFlagName (char* flagname, char* flagnameshort,  int defaultvalue)
573{
574  flag_name = flagname;
575  flag_name_short = flagnameshort;
576  default_value = defaultvalue;
577  cout << "Set Flagname of " << label << " to " << flagname << endl;
578}
579
580
581/* BUTTON */
582
583/**
584   \brief Creates a new Button with a buttonname
585   \param buttonname sets the Name of the Button
586*/
587Button::Button(char* buttonname)
588{
589  this->init();
590  this->setTitle(buttonname);
591}
592
593/**
594   \brief Initializes a new Button
595*/
596void Button::init(void)
597{
598  is_option = 0;
599
600  static_cast<Option*>(this)->init();
601
602  widget = gtk_button_new_with_label ("");
603}
604
605/**
606   \brief Sets a new name to the Button
607   \param title The name the Button should get
608*/
609void Button::setTitle (char *title)
610{
611  label = title;
612  gtk_button_set_label (GTK_BUTTON(widget), title);
613}
614
615/**
616   \brief redraws the Button
617   not implemented yet
618*/
619void Button::redraw ()
620{
621}
622
623/* CHECKBUTTON */
624
625/**
626   \brief Creates a new CheckButton with an ame
627   \param buttonname The name the CheckButton should display.
628*/
629CheckButton::CheckButton (char* buttonname)
630{
631  this->init();
632  this->setTitle(buttonname);
633
634  this->connectSignal ("clicked", this->OptionChange);
635}
636
637/**
638   \brief Initialize a new CheckButton with default settings
639*/
640void CheckButton::init(void)
641{
642  is_option = 1;
643
644  static_cast<Option*>(this)->init();
645
646  widget = gtk_check_button_new_with_label ("");
647}
648
649/**
650   \brief Sets a new Title to a CheckButton
651   \param title The new Name the CheckButton should display.
652*/
653void CheckButton::setTitle(char* title)
654{
655  label = title;
656  gtk_button_set_label(GTK_BUTTON(widget), title);
657}
658
659
660/**
661    \brief Signal OptionChange writes the Value from the CheckButton to its Object-Database.
662    \param widget The widget(CheckButton) that has a changed Value
663    \param checkbutton the CheckButton-Object that should receive the change.
664*/
665gint CheckButton::OptionChange (GtkWidget *widget, Widget* checkbutton)
666{
667  static_cast<CheckButton*>(checkbutton)->value = (int)gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON ((CheckButton*)checkbutton->widget));
668  flags->setTextFromFlags(orxonoxGUI);
669  cout << static_cast<CheckButton*>(checkbutton)->label << " set to: " << static_cast<CheckButton*>(checkbutton)->value << endl;
670}
671
672/**
673   \brief Redraws the CheckButton (if option has changed).
674   Example: if new settings are loaded the Button must be redrawn for the GUI to display that Change
675*/
676void CheckButton::redraw ()
677{
678  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
679}
680
681/* SLIDER */
682
683/**
684   \brief Creates a new Slider
685   \param slidername The data-structure-name of the slider.
686   \param start The minimal Value of the slider.
687   \param end The maximal Value of the slider.
688*/
689Slider::Slider (char* slidername, int start, int end)
690{
691  this->init(start, end);
692  this->setValue(start);
693  this->setTitle(slidername);
694  this->connectSignal ("value_changed", this->OptionChange);
695}
696
697/**
698   \brief Initializes a Slider with start and end Values
699   params: see Slider::Slider (char* slidername, int start, int end)
700*/
701void Slider::init(int start, int end)
702{
703  is_option = 2;
704
705  static_cast<Option*>(this)->init();
706
707  widget = gtk_hscale_new_with_range (start, end, 5);
708}
709
710/**
711   \brief Sets a new Title to the Slider
712   \param title The new Name of the slider
713*/
714void Slider::setTitle(char* title)
715{
716  label = title;
717}
718
719/**
720   \brief Setting a new value to the Slider.
721   Maybe you also require a Slider::redraw() for this to display
722*/
723void Slider::setValue(int value)
724{
725  this->value = value;
726}
727
728/**
729    \brief Signal OptionChange writes the Value from the Slider to its Object-Database.
730    \param widget The widget(Slider) that has a changed Value
731    \param slider the Slider-Object that should receive the change.
732*/
733gint Slider::OptionChange (GtkWidget *widget, Widget* slider)
734{
735  static_cast<Slider*>(slider)->value = (int)gtk_range_get_value (GTK_RANGE ((Slider*)slider->widget));
736  flags->setTextFromFlags(orxonoxGUI);
737  cout << static_cast<Slider*>(slider)->label << " set to: "<< static_cast<Slider*>(slider)->value << endl;
738}
739
740/**
741   \brief Redraws the widget
742   Example: see void CheckButton::redraw ()
743*/
744void Slider::redraw ()
745{
746  gtk_range_set_value (GTK_RANGE (widget), value);
747}
748
749/* MENU */
750
751/**
752    \brief Creates a Menu-Item-list out of multiple input.
753    !! Consider, that the last input argument has to be "lastItem" for this to work!!
754    \param menuname The Database-Name of this Menu
755    \param ... items to be added to this Menu. !! Consider, that the last input argument has to be "lastItem" for this to work!!
756*/
757Menu::Menu (char* menuname, ...)
758{
759  this->init();
760  this->setTitle(menuname);
761   
762  char *itemName;
763 
764  va_start (itemlist, menuname);
765  while (strcmp (itemName = va_arg (itemlist, char*), "lastItem"))
766    {
767      this->addItem(itemName);
768    }
769  va_end(itemlist);
770
771  gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
772  this->connectSignal ("changed", this->OptionChange);
773}
774
775/**
776   \brief Initializes a new Menu with no items
777*/
778void Menu::init(void)
779{
780  is_option = 2;
781
782  static_cast<Option*>(this)->init();
783
784  widget = gtk_option_menu_new ();
785  menu = gtk_menu_new ();
786
787}
788
789/**
790 * Sets the Database-Name of this Menu
791 \param title Database-Name to be set.
792*/
793void Menu::setTitle(char* title)
794{
795  label = title;
796}
797
798/**
799   \brief appends a new Item to the Menu-List.
800   \param itemName the itemName to be appendet.
801*/
802void Menu::addItem (char* itemName)
803{
804  item = gtk_menu_item_new_with_label (itemName);
805  gtk_menu_shell_append(GTK_MENU_SHELL (menu), item);
806}
807
808/**
809    \brief Signal OptionChange writes the Value from the Menu to its Object-Database.
810    \param widget The widget(Menu) that has a changed Value
811    \param menu the Menu-Object that should receive the change.
812*/
813gint Menu::OptionChange (GtkWidget *widget, Widget* menu)
814{
815  static_cast<Menu*>(menu)->value = (int)gtk_option_menu_get_history (GTK_OPTION_MENU (menu->widget));
816  flags->setTextFromFlags(orxonoxGUI);
817  cout << static_cast<Menu*>(menu)->label << " changed to : " << static_cast<Menu*>(menu)->value << endl;
818}
819
820/**
821   \brief Redraws the widget
822   Example: see void CheckButton::redraw ()
823 */
824void Menu::redraw ()
825{
826  gtk_option_menu_set_history (GTK_OPTION_MENU (widget), value);
827}
828
829/**
830   \brief Creates a new default Label with no Text.
831   You migth consider adding Label::setTitle with this.
832*/
833Label:: Label ()
834{
835  this->init();
836}
837
838/**
839   \brief Creates a new Label with a Text.
840   \param text The text to be displayed.
841*/
842Label:: Label (char* text)
843{
844  this->init();
845  this->setText(text);
846}
847
848/**
849   \brief initializes a new Label
850*/
851void Label::init(void)
852{
853  is_option = 0;
854
855  static_cast<Widget*>(this)->init();
856
857  widget = gtk_label_new ("");
858  gtk_label_set_line_wrap (GTK_LABEL(widget), TRUE);
859}
860
861/**
862   \brief Sets a new Text to a Label.
863   \param text The text to be inserted into the Label.
864*/
865void Label::setText (char * text)
866{
867  label = text;
868  gtk_label_set_text (GTK_LABEL (this->widget), text);
869}
870
871/**
872   \brief get the Text of a Label
873   \return The Text the Label holds.
874*/
875char* Label::getText ()
876{
877  return ((char*)gtk_label_get_text (GTK_LABEL (this->widget)));
878}
Note: See TracBrowser for help on using the repository browser.