Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/gui/orxonox_gui_gtk.cc @ 3152

Last change on this file since 3152 was 3152, checked in by bensch, 19 years ago

orxonox/trunk/gui: keys in the new Style

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