Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/gui: typo, toDo and so on

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