Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/gui: modified savable rutine. now a widget has to be set saveable, otherwise it won't be saved

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