Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/gui: added simple config-file stuffing. (only save needs it now, load still has to do it)

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