Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/gui: banner Window is as it should be

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