Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/gui: added keystrokes, and for testing added them to button Player

File size: 19.6 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  default_value = 0;
555
556  static_cast<Widget*>(this)->init();
557
558  return;
559}
560
561/**
562   \brief This sets The FlagName of an Option and defines its default Values
563   !! Options will be saved if flagname is different from "" !!
564   \param flagname the Name that will be displayed in the output
565   \param defaultvalue the default Value for this Option (see definition of defaultvalue
566*/
567void Option::setFlagName (char* flagname, int defaultvalue)
568{
569  flag_name = flagname;
570  default_value = defaultvalue;
571  cout << "Set Flagname of " << label << " to " << flagname << endl;
572}
573
574/**
575    \brief see Option::setFlagName (char* flagname, int defaultvalue)
576    \param flagname the Name that will be displayed in the output
577    \param defaultvalue the default Value for this Option (see definition of defaultvalue
578    \param flagnameshort a short flagname to be displayed in the output
579*/
580void Option::setFlagName (char* flagname, char* flagnameshort,  int defaultvalue)
581{
582  flag_name = flagname;
583  flag_name_short = flagnameshort;
584  default_value = defaultvalue;
585  cout << "Set Flagname of " << label << " to " << flagname << endl;
586}
587
588
589/* BUTTON */
590
591/**
592   \brief Creates a new Button with a buttonname
593   \param buttonname sets the Name of the Button
594*/
595Button::Button(char* buttonname)
596{
597  this->init();
598  this->setTitle(buttonname);
599}
600
601/**
602   \brief Initializes a new Button
603*/
604void Button::init(void)
605{
606  is_option = 0;
607
608  static_cast<Option*>(this)->init();
609
610  widget = gtk_button_new_with_label ("");
611}
612
613/**
614   \brief Sets a new name to the Button
615   \param title The name the Button should get
616*/
617void Button::setTitle (char *title)
618{
619  label = title;
620  gtk_button_set_label (GTK_BUTTON(widget), title);
621}
622
623/**
624   \brief redraws the Button
625   not implemented yet
626*/
627void Button::redraw ()
628{
629}
630
631/* CHECKBUTTON */
632
633/**
634   \brief Creates a new CheckButton with an ame
635   \param buttonname The name the CheckButton should display.
636*/
637CheckButton::CheckButton (char* buttonname)
638{
639  this->init();
640  this->setTitle(buttonname);
641
642  this->connectSignal ("clicked", this->OptionChange);
643}
644
645/**
646   \brief Initialize a new CheckButton with default settings
647*/
648void CheckButton::init(void)
649{
650  is_option = 1;
651
652  static_cast<Option*>(this)->init();
653
654  widget = gtk_check_button_new_with_label ("");
655}
656
657/**
658   \brief Sets a new Title to a CheckButton
659   \param title The new Name the CheckButton should display.
660*/
661void CheckButton::setTitle(char* title)
662{
663  label = title;
664  gtk_button_set_label(GTK_BUTTON(widget), title);
665}
666
667
668/**
669    \brief Signal OptionChange writes the Value from the CheckButton to its Object-Database.
670    \param widget The widget(CheckButton) that has a changed Value
671    \param checkbutton the CheckButton-Object that should receive the change.
672*/
673gint CheckButton::OptionChange (GtkWidget *widget, Widget* checkbutton)
674{
675  static_cast<CheckButton*>(checkbutton)->value = (int)gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON ((CheckButton*)checkbutton->widget));
676  flags->setTextFromFlags(orxonoxGUI);
677  cout << static_cast<CheckButton*>(checkbutton)->label << " set to: " << static_cast<CheckButton*>(checkbutton)->value << endl;
678}
679
680/**
681   \brief Redraws the CheckButton (if option has changed).
682   Example: if new settings are loaded the Button must be redrawn for the GUI to display that Change
683*/
684void CheckButton::redraw ()
685{
686  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
687}
688
689/* SLIDER */
690
691/**
692   \brief Creates a new Slider
693   \param slidername The data-structure-name of the slider.
694   \param start The minimal Value of the slider.
695   \param end The maximal Value of the slider.
696*/
697Slider::Slider (char* slidername, int start, int end)
698{
699  this->init(start, end);
700  this->setValue(start);
701  this->setTitle(slidername);
702  this->connectSignal ("value_changed", this->OptionChange);
703}
704
705/**
706   \brief Initializes a Slider with start and end Values
707   params: see Slider::Slider (char* slidername, int start, int end)
708*/
709void Slider::init(int start, int end)
710{
711  is_option = 2;
712
713  static_cast<Option*>(this)->init();
714
715  widget = gtk_hscale_new_with_range (start, end, 5);
716}
717
718/**
719   \brief Sets a new Title to the Slider
720   \param title The new Name of the slider
721*/
722void Slider::setTitle(char* title)
723{
724  label = title;
725}
726
727/**
728   \brief Setting a new value to the Slider.
729   Maybe you also require a Slider::redraw() for this to display
730*/
731void Slider::setValue(int value)
732{
733  this->value = value;
734}
735
736/**
737    \brief Signal OptionChange writes the Value from the Slider to its Object-Database.
738    \param widget The widget(Slider) that has a changed Value
739    \param slider the Slider-Object that should receive the change.
740*/
741gint Slider::OptionChange (GtkWidget *widget, Widget* slider)
742{
743  static_cast<Slider*>(slider)->value = (int)gtk_range_get_value (GTK_RANGE ((Slider*)slider->widget));
744  flags->setTextFromFlags(orxonoxGUI);
745  cout << static_cast<Slider*>(slider)->label << " set to: "<< static_cast<Slider*>(slider)->value << endl;
746}
747
748/**
749   \brief Redraws the widget
750   Example: see void CheckButton::redraw ()
751*/
752void Slider::redraw ()
753{
754  gtk_range_set_value (GTK_RANGE (widget), value);
755}
756
757/* MENU */
758
759/**
760    \brief Creates a Menu-Item-list out of multiple input.
761    !! Consider, that the last input argument has to be "lastItem" for this to work!!
762    \param menuname The Database-Name of this Menu
763    \param ... items to be added to this Menu. !! Consider, that the last input argument has to be "lastItem" for this to work!!
764*/
765Menu::Menu (char* menuname, ...)
766{
767  this->init();
768  this->setTitle(menuname);
769   
770  char *itemName;
771 
772  va_start (itemlist, menuname);
773  while (strcmp (itemName = va_arg (itemlist, char*), "lastItem"))
774    {
775      this->addItem(itemName);
776    }
777  va_end(itemlist);
778
779  gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
780  this->connectSignal ("changed", this->OptionChange);
781}
782
783/**
784   \brief Initializes a new Menu with no items
785*/
786void Menu::init(void)
787{
788  is_option = 2;
789
790  static_cast<Option*>(this)->init();
791
792  widget = gtk_option_menu_new ();
793  menu = gtk_menu_new ();
794
795}
796
797/**
798 * Sets the Database-Name of this Menu
799 \param title Database-Name to be set.
800*/
801void Menu::setTitle(char* title)
802{
803  label = title;
804}
805
806/**
807   \brief appends a new Item to the Menu-List.
808   \param itemName the itemName to be appendet.
809*/
810void Menu::addItem (char* itemName)
811{
812  item = gtk_menu_item_new_with_label (itemName);
813  gtk_menu_shell_append(GTK_MENU_SHELL (menu), item);
814}
815
816/**
817    \brief Signal OptionChange writes the Value from the Menu to its Object-Database.
818    \param widget The widget(Menu) that has a changed Value
819    \param menu the Menu-Object that should receive the change.
820*/
821gint Menu::OptionChange (GtkWidget *widget, Widget* menu)
822{
823  static_cast<Menu*>(menu)->value = (int)gtk_option_menu_get_history (GTK_OPTION_MENU (menu->widget));
824  flags->setTextFromFlags(orxonoxGUI);
825  cout << static_cast<Menu*>(menu)->label << " changed to : " << static_cast<Menu*>(menu)->value << endl;
826}
827
828/**
829   \brief Redraws the widget
830   Example: see void CheckButton::redraw ()
831 */
832void Menu::redraw ()
833{
834  gtk_option_menu_set_history (GTK_OPTION_MENU (widget), value);
835}
836
837/**
838   \brief Creates a new default Label with no Text.
839   You migth consider adding Label::setTitle with this.
840*/
841Label:: Label ()
842{
843  this->init();
844}
845
846/**
847   \brief Creates a new Label with a Text.
848   \param text The text to be displayed.
849*/
850Label:: Label (char* text)
851{
852  this->init();
853  this->setText(text);
854}
855
856/**
857   \brief initializes a new Label
858*/
859void Label::init(void)
860{
861  is_option = 0;
862
863  static_cast<Widget*>(this)->init();
864
865  widget = gtk_label_new ("");
866  gtk_label_set_line_wrap (GTK_LABEL(widget), TRUE);
867}
868
869/**
870   \brief Sets a new Text to a Label.
871   \param text The text to be inserted into the Label.
872*/
873void Label::setText (char * text)
874{
875  label = text;
876  gtk_label_set_text (GTK_LABEL (this->widget), text);
877}
878
879/**
880   \brief get the Text of a Label
881   \return The Text the Label holds.
882*/
883char* Label::getText ()
884{
885  return ((char*)gtk_label_get_text (GTK_LABEL (this->widget)));
886}
Note: See TracBrowser for help on using the repository browser.