Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/gui/gui_gtk.cc @ 5015

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

orxonox/trunk: robust IniParser

File size: 45.9 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 "gui_gtk.h"
28
29#include <stdarg.h>
30#include <string.h>
31#include <stdlib.h>
32#include <math.h>
33
34using namespace std;
35
36#include "gui_flags.h"
37#include "gui_exec.h"
38
39extern GuiFlags* flags;
40
41char* executable;
42
43/**
44 *  Initializes the Guis GTK-stuff.
45 * @param argc the argument count.
46 * @param argv The Argument strings.
47*/
48bool initGUI(int argc, char *argv[])
49{
50  if (argv)
51    {
52      executable = new char[strlen(argv[0])+1];
53      strcpy(executable, argv[0]);
54    }
55  else
56    executable = NULL;
57
58#ifdef HAVE_GTK2
59  gtk_init(&argc, &argv);
60#include "rc"
61  gtk_rc_parse_string( rc_string );
62#endif /* HAVE_GTK2 */
63}
64
65/**
66 *  enters the GUI's main-loop
67*/
68bool mainloopGUI()
69{
70#ifdef HAVE_GTK2
71  gtk_main();
72#else /* HAVE_GTK2 */
73  char boolAns = 'y';
74  char ans[1000];
75  PRINT(0)("================================\n");
76  PRINT(0)("= ORXONOX CONFIGURATION WIZARD =\n");
77  PRINT(0)("================================ - v." PACKAGE_VERSION "\n");
78
79  while(true)
80    {
81      PRINT(0)("\n Listing all the Orxonox Options: \n");
82      PRINT(0)("  #############################\n");
83      Window::mainWindow->walkThrough(Widget::listOptionsAndGroups, 1);
84
85      PRINT(0)("\nDo you want change any of the above values now? [Yn] ");
86      scanf("%s", ans);
87      if (ans[0] =='n' || ans[0]=='N')
88        break;
89
90      PRINT(0)("\n Listing all groups\n");
91      PRINT(0)("  #################\n");
92      int groupCount = 0;
93      Window::mainWindow->walkThrough(Widget::listGroups, &groupCount, 1);
94
95      PRINT(0)("\nIn which Group? [1-%d] ", groupCount);
96      Packer* group;
97      while(true)
98        {
99          scanf("%s", ans);
100          int ansIp = atoi(ans);
101          if (ansIp <= groupCount)
102            {
103              group = static_cast<Packer*>(Window::mainWindow->findGroupByNumber(&ansIp, 1));
104              break;
105            }
106          else
107            PRINT(0)("\nChoose a smaller Number please: [1-%d] ", groupCount);
108        }
109      PRINT(0)("\n\nGroup: [%s]\n\n", group->groupName);
110      int optionCount = 0;
111      group->walkThrough(Widget::listOptions, &optionCount, 0);
112      PRINT(0)("\nWhich Option? [1-%d] ", optionCount);
113      Option* option;
114      while(true)
115        {
116          scanf("%s", ans);
117          int ansIp = atoi(ans);
118          if (ansIp <= groupCount)
119            {
120              option = static_cast<Option*>(group->findOptionByNumber(&ansIp, 0));
121              break;
122            }
123          else
124            PRINT(0)("\nChoose a smaler Number please: [1-%d] ", optionCount);
125        }
126      PRINT(0)("\n\n:: %s ::\n", option->title);
127      option->changeOption();
128
129      // here follows the rest.... this will be nasty.
130      //! @todo finish it.
131      //! @todo memory leek at save(); and save is a BAD word, use saveString instead, or something like it.
132    }
133#endif /* HAVE_GTK2 */
134
135}
136
137
138//////////////////////////////
139/// DEFINING WIDGET-CLASES ///
140//////////////////////////////
141
142////////////
143/* WIDGET */
144////////////
145/**
146 *  constructs a Widget
147*/
148Widget::Widget()
149{
150  next = NULL;
151  this->title = NULL;
152}
153
154/**
155 *  deletes any given Widget
156   This is still pretty crappy.
157*/
158Widget::~Widget()
159{
160  if (this->title)
161    {
162      delete []this->title;
163    }
164
165  PRINTF(5)("deleting the Widget part.\n");
166
167  // deleting next item if existent
168  if (this->next)
169    delete this->next;
170  this->next = NULL;
171
172  //!  @todo not hiding widget, deleting.
173  //  this->hide();
174  // gtk_destroy_widget(this->widget);
175}
176
177/**
178 *  sets a new Title to a Widget
179 * @param title The new Title to set to the Widget
180*/
181void Widget::setTitle(const char* title)
182{
183  if (this->title)
184    delete []this->title;
185  this->title = new char[strlen(title)+1];
186  strcpy(this->title, title);
187}
188
189/**
190 *  makes the widget visible.
191*/
192void Widget::show()
193{
194#ifdef HAVE_GTK2
195  gtk_widget_show(this->widget);
196#endif /* HAVE_GTK2 */
197}
198
199/**
200 *  hides the widget.
201*/
202void Widget::hide()
203{
204#ifdef HAVE_GTK2
205  gtk_widget_hide(this->widget);
206#endif /* HAVE_GTK2 */
207}
208
209/**
210 *  Sets the resolution of a specific widget to the given size.
211 * @param width the width of the widget to set.
212 * @param height the height of the widget to set.
213*/
214void Widget::setSize(int width, int height)
215{
216#ifdef HAVE_GTK2
217  gtk_widget_set_usize(this->widget, width, height);
218#endif /* HAVE_GTK2 */
219}
220
221/**
222 *  searches through widgets for a Name.
223*/
224Widget* Widget::findWidgetByName(char* name, unsigned int depth)
225{
226
227  if (this->title && !strcmp(this->title, name))
228    return this;
229
230  if (this->optionType < GUI_NOTHING && static_cast<Packer*>(this)->down)
231    {
232      Widget* tmp = static_cast<Packer*>(this)->down->findWidgetByName(name, depth+1);
233      if (tmp)
234        return tmp;
235    }
236
237  if (depth>0 && this->next)
238    return this->next->findWidgetByName(name, depth);
239
240  return NULL;
241}
242
243/**
244 *  Moves through all the Widgets downwards from this and executes the function on them.
245 * @param function must be of type void and takes a Widget* as an Input.
246 * @param depth the current depth. if > 0 then the next Widget will also be walked through.
247*/
248void Widget::walkThrough(void(*function)(Widget*), unsigned int depth)
249{
250  function(this);
251  if (this->optionType < GUI_NOTHING)
252    {
253      static_cast<Packer*>(this)->down->walkThrough(function, depth+1);
254    }
255
256  if (this->next && depth != 0)
257    this->next->walkThrough(function, depth);
258}
259
260/**
261 *  Moves through all the Widgets downwards from this and executes the function on them.
262 * @param function must be of type void and takes a Widget* as an Input.
263 * @param data Additional Data you want to pass to the function.
264 * @param depth the current depth. if > 0 then the next Widget will also be walked through.
265*/
266void Widget::walkThrough(void(*function)(Widget*, void*), void* data, unsigned int depth)
267{
268  function(this, data);
269  if (this->optionType < GUI_NOTHING)
270    {
271      static_cast<Packer*>(this)->down->walkThrough(function, data, depth+1);
272    }
273  if (this->next && depth != 0)
274    this->next->walkThrough(function, data, depth);
275}
276
277/**
278  *  This is for listing the options of "widget"
279  * @param widget specifies the widget that should be listed
280*/
281void Widget::listOptionsAndGroups(Widget* widget)
282{
283  if (widget->optionType < GUI_NOTHING && static_cast<Packer*>(widget)->groupName)
284    PRINT(0)("[%s]\n", static_cast<Packer*>(widget)->groupName);
285  if (widget->optionType > GUI_NOTHING)
286    {
287      Widget::listOptions(widget);
288    }
289}
290
291/**
292  *  This is for listing the options of "widget"
293  * @param widget specifies the widget that should be listed
294*/
295void Widget::listOptions(Widget* widget)
296{
297  if(widget->optionType > GUI_NOTHING)
298    PRINT(0)("  %s is %s\n", static_cast<Option*>(widget)->title, static_cast<Option*>(widget)->save());
299}
300
301/**
302  *  This is for listing the options of "widget"
303  * @param widget specifies the widget that should be listed
304  * @param data A Counter, that always knows how many Options have been found yet.
305*/
306void Widget::listOptions(Widget* widget, void* data)
307{
308
309  if (widget->optionType > GUI_NOTHING)
310    {
311      int* count =(int*)data;
312      *count = *count +1;
313      PRINT(0)(" %d:%s is %s\n", *count,
314               static_cast<Option*>(widget)->title,
315               static_cast<Option*>(widget)->save());
316    }
317}
318
319/**
320  *  This is for listing the options of "widget"
321  * @param widget specifies the widget that should be listed
322  * @param data A Counter, that always knows how many Options have been found yet.
323*/
324void Widget::printHelp(Widget* widget)
325{
326  int helpLen=0;
327
328  if (widget->optionType > GUI_NOTHING)
329    {
330      Option* option = (Option*)widget;
331      if (option->flagName || option->flagNameShort)
332        {
333          PRINT(0)("  ");
334          if (option->flagNameShort)
335            {
336              PRINT(0)("-%s", option->flagNameShort);
337              helpLen += strlen(option->flagNameShort)+1;
338            }
339          if (option->flagName)
340            {
341              if (helpLen > 0)
342                {
343                  PRINT(0)("|");
344                  helpLen++;
345                }
346              PRINT(0)("--%s:", option->flagName);
347              helpLen += strlen(option->flagName)+2;
348            }
349          while ((helpLen ++) < 29)
350            PRINT(0)(" ");
351          if (option->shortDescription)
352            PRINT(0)("%s\n", option->shortDescription);
353          else
354            PRINT(0)("\n");
355        }
356    }
357}
358
359/**
360  *  Finds an Option by a given number(the n'th option found away from this Widget)
361  * @param number The Count of options to wait(by reference)
362  * @param depth The depth of the sarch. if 0 it will not search next pointer
363
364    @todo should return Option* would be much sexier.
365*/
366Widget* Widget::findOptionByNumber(int* number, unsigned int depth)
367{
368  if (optionType > GUI_NOTHING)
369    {
370      --*number;
371      if (*number <= 0)
372        {
373          return this;
374        }
375    }
376  if (this->optionType < GUI_NOTHING && static_cast<Packer*>(this)->down)
377    {
378      Widget* tmp = static_cast<Packer*>(this)->down->findOptionByNumber(number, depth+1);
379      if (tmp)
380        return tmp;
381    }
382  if (depth>0 && this->next)
383    return this->next->findOptionByNumber(number, depth);
384
385  return NULL;
386}
387
388/**
389  *  This is for listing the groups of "widget"
390  * @param widget specifies the widget that should be listed
391*/
392void Widget::listGroups(Widget* widget)
393{
394  if (widget->optionType < GUI_NOTHING && static_cast<Packer*>(widget)->groupName)
395    PRINT(0)("[%s]\n", static_cast<Packer*>(widget)->groupName);
396}
397
398/**
399  *  This is for listing the Groups of "widget". It also displays the n'th number found.
400  * @param widget specifies the widget that should be listed
401  * @param data the Counter, that will show the number(this function will raise it by one if a Group is fount.
402*/
403void Widget::listGroups(Widget* widget, void* data)
404{
405  int* count = (int*)data;
406  if (widget->optionType < GUI_NOTHING && static_cast<Packer*>(widget)->groupName)
407    PRINT(0)("%d: [%s]\n", ++*count, static_cast<Packer*>(widget)->groupName);
408}
409
410/**
411  *  Finds a Group by a given number(the n'th Group found away from this Widget)
412  * @param number The Count of options to wait(by reference)
413  * @param depth The depth of the sarch. if 0 it will not search next pointer
414*/
415Widget* Widget::findGroupByNumber(int* number, unsigned int depth)
416{
417  if (optionType < GUI_NOTHING && static_cast<Packer*>(this)->groupName)
418    {
419      --*number;
420      if (*number <= 0)
421        {
422          return this;
423        }
424    }
425  if (this->optionType < GUI_NOTHING && static_cast<Packer*>(this)->down)
426    {
427      Widget* tmp = static_cast<Packer*>(this)->down->findGroupByNumber(number, depth+1);
428      if (tmp)
429        return tmp;
430    }
431  if (depth>0 && this->next)
432    return this->next->findGroupByNumber(number, depth);
433
434  return NULL;
435}
436
437/**
438  *  This is for setting the option of "widget"
439  * @param widget specifies the widget that should be set.
440*/
441void Widget::setOptions(Widget* widget)
442{
443  if (widget->optionType > GUI_NOTHING)
444    static_cast<Option*>(widget)->redraw();
445}
446
447/**
448 *  redraws all the Widgets down from widget
449 * @param widget The topmost Widget
450 * @param data ...
451*/
452void Widget::redrawOptions(Widget* widget)
453{
454  if (widget->optionType > GUI_NOTHING)
455    static_cast<Option*>(widget)->redraw();
456}
457
458/**
459 *  Walks through all the Flags given at startuptime.
460*/
461void Widget::flagCheck(Widget* widget, void* flagName)
462{
463  if (widget->optionType > GUI_NOTHING)
464    {
465      Option* option =(Option*)widget;
466      char* name =(char*)flagName;
467      char* value = NULL;
468      bool found = false;
469      // check if long flag matches
470      if ((option->flagName && strlen(name) > 2 &&
471           !strncmp(name+2, option->flagName, strlen(option->flagName)) &&
472           (name[strlen(option->flagName)+2] == '\0' || name[strlen(option->flagName)+2] == '=') ))
473        {
474          found = true;
475          if (name[strlen(option->flagName)+2] == '=')
476            {
477              value = name+strlen(option->flagName)+3;
478            }
479        }
480      // check if short flag matches
481      else if (option->flagNameShort && strlen(name)>1 &&
482               !strncmp(name+1, option->flagNameShort, strlen(option->flagNameShort)) &&
483               (name[strlen(option->flagNameShort)+1] == '\0' || name[strlen(option->flagNameShort)+1] == '='))
484        {
485          found = true;
486          if (name[strlen(option->flagNameShort)+1] == '=')
487            {
488              value = name+strlen(option->flagNameShort)+2;
489            }
490        }
491
492      if (found)
493        {
494          PRINT(4)("found matching Flag %s\n", name);
495          if (value)
496            {
497              PRINT(4)("with Value %s\n", value);
498              option->value = atoi(value);
499            }
500          else
501            {
502              option->value = !option->defaultValue;
503            }
504          option->redraw();
505        }
506
507    }
508}
509
510#ifdef HAVE_GTK2
511/**
512  *  Connect any signal to any given Sub-widget
513*/
514gulong Widget::connectSignal(char* event, gint(*signal)(GtkWidget*, GdkEvent*, void *))
515{
516  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), NULL);
517}
518
519/**
520 *  Connect a signal with additionally passing the whole Object
521*/
522gulong Widget::connectSignal(char* event, gint(*signal)( GtkWidget*, Widget *))
523{
524  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), this);
525}
526
527/**
528 *  Connect a signal with additionally passing a whole external Object
529*/
530gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEvent*, void *))
531{
532  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj);
533}
534
535/**
536 *  Connect a signal with additionally passing a whole external Object
537*/
538gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, void *))
539{
540  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj);
541}
542
543/**
544 *  Connect a signal with additionally passing a whole external Object
545*/
546gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEventKey*, void *))
547{
548  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj);
549}
550
551void Widget::disconnectSignal(gulong signalID)
552{
553  g_signal_handler_disconnect(G_OBJECT(this->widget), signalID);
554}
555
556/**
557 *  Signal that does absolutely nothing
558 * @param widget The widget that initiated the Signal
559 * @param event The event-type.
560 * @param nothing nothin.
561*/
562gint Widget::doNothingSignal(GtkWidget *widget, GdkEvent* event, void* nothing)
563{
564}
565#endif /* HAVE_GTK2 */
566
567/////////////
568/* PACKERS */
569/////////////
570/**
571 *  Constructs a Packer
572*/
573Packer::Packer()
574{
575  this->down = NULL;
576  this->groupName = NULL;
577}
578
579/**
580 *  Destroys a Packer.
581*/
582Packer::~Packer()
583{
584  PRINTF(5)("deleting the Packer part.\n");
585  if (this->groupName)
586    delete []this->groupName;
587
588  //deleting recursively.
589  if (this->down)
590    delete this->down;
591}
592
593/**
594 *  Sets the group name under which all the lower widgets of this will be saved.
595 * @param name The name of the group.
596*/
597void Packer::setGroupName(const char* name)
598{
599  if (this->groupName)
600    delete []this->groupName;
601  this->groupName = new char[strlen(name)+1];
602  strcpy(this->groupName, name);
603}
604
605////////////////
606/* CONTAINERS */
607////////////////
608/**
609 *  Initializes a Container.
610
611   sets the Container-Specific defaults.
612*/
613Container::Container()
614{
615  this->optionType = GUI_CONTAINER;
616}
617
618/**
619 *  Destroys a Container.
620*/
621Container::~Container()
622{
623  PRINTF(5)("deleting the Container part.\n");
624}
625
626/**
627 * Fills a Container with lowerWidget.
628 * @param lowerWidget the Widget that should be filled into the Container.
629
630   It does this by filling up the down pointer only if down points to NULL.
631*/
632void Container::fill(Widget* lowerWidget)
633{
634  if (this->down == NULL)
635    {
636#ifdef HAVE_GTK2
637      gtk_container_add(GTK_CONTAINER(this->widget), lowerWidget->widget);
638#endif /* HAVE_GTK2 */
639
640      this->down = lowerWidget;
641    }
642  else
643    PRINTF(2)("You tried to put more than one Widget into a Container. \nNot including this item.\nThis is only possible with Boxes.\n");
644}
645
646/**
647 * @param borderwidth sets the Width of the border
648*/
649void Container::setBorderWidth(int borderwidth)
650{
651  this->borderwidth = borderwidth;
652
653#ifdef HAVE_GTK2
654  gtk_container_set_border_width(GTK_CONTAINER(widget), borderwidth);
655#endif /* HAVE_GTK2 */
656}
657
658////////////
659/* WINDOW */
660////////////
661
662/**
663 *  The main Window of Th Gui
664*/
665Window* Window::mainWindow = NULL;
666
667/**
668 *  Creating a Window with a name
669 * @param windowName the name the window should get.
670*/
671Window::Window(const char* windowName)
672{
673  if (!mainWindow)
674    {
675      mainWindow = this;
676      this->isOpen = true;
677    }
678  isOpen = false;
679
680#ifdef HAVE_GTK2
681  widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
682  gtk_window_set_policy(GTK_WINDOW(widget), TRUE, TRUE, TRUE);
683#if !defined(__WIN32__)
684  //  gtk_window_set_decorated(GTK_WINDOW(widget), FALSE);
685#endif
686  gtk_container_set_border_width(GTK_CONTAINER(widget), 3);
687#endif /* HAVE_GTK2 */
688
689  if (windowName)
690    this->setTitle(windowName);
691}
692
693/**
694 *  Destructs a Window.
695*/
696Window::~Window()
697{
698  PRINTF(5)("deleting the Window: %s\n", this->title);
699}
700
701/**
702 *  Adds a new Window Windows to the List of Windows.
703 * @param windowToAdd The Windows that should be added to the List
704   @todo this instead of windowToAdd(possibly)
705*/
706void Window::addWindow(Window* windowToAdd)
707{
708  if (!mainWindow)
709    {
710      mainWindow = windowToAdd;
711      windowToAdd->isOpen = true;
712    }
713  else
714    {
715      Widget* tmpWindow = mainWindow;
716      while(tmpWindow->next)
717        tmpWindow = tmpWindow->next;
718      tmpWindow->next = windowToAdd;
719      windowToAdd->isOpen = false;
720    }
721  return;
722}
723
724/**
725 *  Shows all Widgets that are included within this->widget.
726*/
727void Window::showall()
728{
729#ifdef HAVE_GTK2
730  if (!this->isOpen)
731    gtk_widget_show_all(this->widget);
732  else
733    gtk_widget_show(this->widget);
734#endif /* HAVE_GTK2 */
735}
736
737/**
738 *  Set The Window-title to title
739 * @param title title the Window should get.
740*/
741void Window::setTitle(const char* title)
742{
743  if (this->title)
744    delete []this->title;
745  this->title = new char[strlen(title)+1];
746  strcpy(this->title, title);
747#ifdef HAVE_GTK2
748  gtk_window_set_title(GTK_WINDOW(widget), title);
749#endif /* HAVE_GTK2 */
750}
751
752/**
753 *  opens up a Window and fixes the Focus to it
754*/
755void Window::open()
756{
757  if (this != mainWindow)
758    {
759      isOpen = true;
760#ifdef HAVE_GTK2
761      gtk_widget_show_all(this->widget);
762      gtk_grab_add(this->widget);
763#endif /* HAVE_GTK2 */
764    }
765}
766
767/**
768 *  closes up a Window and removes the Focus from it
769*/
770void Window::close()
771{
772  if (this != mainWindow)
773    {
774      this->isOpen = false;
775#ifdef HAVE_GTK2
776      gtk_grab_remove(this->widget);
777      gtk_widget_hide(this->widget);
778#endif /* HAVE_GTK2 */
779    }
780}
781
782/**
783 *  opens up a window(not topmost Window).
784   this is the Signal that does it. !!SIGNALS ARE STATIC!!
785 * @param widget the widget that did it.
786 * @param event the event that did it.
787 * @param window the Window that should be opened
788*/
789#ifdef HAVE_GTK2
790gint Window::windowOpen(GtkWidget* widget, GdkEvent* event, void* window)
791{
792  static_cast<Window*>(window)->open();
793}
794#else /* HAVE_GTK2 */
795int Window::windowOpen(void* widget, void* event, void* window){}
796#endif /* HAVE_GTK2 */
797
798/**
799 *  closes a window(not topmost Window).
800   this is the Signal that does it. !!SIGNALS ARE STATIC!!
801 * @param widget the widget that did it!
802 * @param event the event that did it!
803 * @param window the Window that should be closed
804*/
805#ifdef HAVE_GTK2
806gint Window::windowClose(GtkWidget* widget, GdkEvent* event, void* window)
807{
808  static_cast<Window*>(window)->close();
809}
810#else /* HAVE_GTK2 */
811int Window::windowClose(void* widget, void* event, void* window){}
812#endif /* HAVE_GTK2 */
813
814///////////
815/* FRAME */
816///////////
817/**
818 *  Creates a new Frame with name title
819*/
820Frame::Frame(const char* frameName)
821{
822#ifdef HAVE_GTK2
823  this->widget = gtk_frame_new("");
824  gtk_container_set_border_width(GTK_CONTAINER(this->widget), 3);
825#endif /* HAVE_GTK2 */
826  if (frameName)
827    this->setTitle(frameName);
828}
829
830/**
831 *  destrcucts a Frame
832*/
833Frame::~Frame()
834{
835  PRINTF(5)("deleting the Frame: %s\n", this->title);
836}
837
838/**
839 *  Sets the Frames name to title
840 * @param title The title the Frame should get.
841*/
842void Frame::setTitle(const char* title)
843{
844  if (this->title)
845    delete []this->title;
846  this->title = new char[strlen(title)+1];
847  strcpy(this->title, title);
848#ifdef HAVE_GTK2
849  gtk_frame_set_label(GTK_FRAME(widget), this->title);
850#endif /* HAVE_GTK2 */
851}
852
853//////////////
854/* EVENTBOX */
855//////////////
856/**
857 *  Creates a new EventBox with name title
858 * @param eventBoxName title the Eventbox should get(only data-structure-internal)
859*/
860EventBox::EventBox(const char* eventBoxName)
861{
862#ifdef HAVE_GTK2
863  this->widget = gtk_event_box_new();
864  gtk_container_set_border_width(GTK_CONTAINER(this->widget), 3);
865#endif /* HAVE_GTK2 */
866
867  if (eventBoxName)
868    this->setTitle(eventBoxName);
869}
870
871/**
872 *  destructs an EventBox.
873*/
874EventBox::~EventBox()
875{
876  PRINTF(5)("deleting the EventBox: %s\n", this->title);
877}
878
879/////////
880/* BOX */
881/////////
882/**
883 *  Creates a new Box of type boxtype
884 * @param boxtype if 'v' the Box will be vertically, if 'h' the Box will be horizontally
885*/
886Box::Box(char boxtype)
887{
888  this->optionType = GUI_BOX;
889
890#ifdef HAVE_GTK2
891  if (boxtype == 'v')
892    this->widget = gtk_vbox_new(FALSE, 0);
893  else
894    this->widget = gtk_hbox_new(FALSE, 0);
895#endif /* HAVE_GTK2 */
896}
897
898/**
899 *  destructs a Box.
900*/
901Box::~Box()
902{
903  PRINTF(5)("deleting the Box: %s\n", this->title);
904}
905
906/**
907  *  Fills a box with a given Widget.
908  * @param lowerWidget the next Widget that should be appendet to this Box
909
910    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
911*/
912void Box::fill(Widget* lowerWidget)
913{
914#ifdef HAVE_GTK2
915  gtk_box_pack_start(GTK_BOX(this->widget), lowerWidget->widget, TRUE, TRUE, 0);
916#endif /* HAVE_GTK2 */
917  if (this->down == NULL)
918    this->down = lowerWidget;
919  else
920    {
921      Widget* tmp;
922      tmp = this->down;
923      while(tmp->next != NULL)
924        tmp = tmp->next;
925      tmp->next = lowerWidget;
926    }
927}
928
929////////////
930/* OPTION */
931////////////
932/**
933 *  Initializes a new Option.
934   sets all Option-Specific-Values to their defaults.
935*/
936Option::Option()
937{
938  this->value = 0;
939  this->flagName = NULL;
940  this->flagNameShort = NULL;
941
942  this->shortDescription = NULL;
943  this->longDescription = NULL;
944
945  this->saveable = false;
946  this->defaultValue = 0;
947}
948
949/**
950 *  Destroys an Option.
951*/
952Option::~Option()
953{
954  PRINTF(5)("deleting the Option Part.\n");
955  if (this->flagName)
956    delete []this->flagName;
957  if (this->flagNameShort)
958    delete []this->flagNameShort;
959  if (this->shortDescription)
960    delete []this->shortDescription;
961  if (this->longDescription)
962    delete []this->longDescription;
963}
964
965/**
966 * @param defaultValue new defaultValue for this option
967*/
968void Option::setDefaultValue(int defaultValue)
969{
970  this->value = this->defaultValue = defaultValue;
971}
972
973/**
974 *  This sets The FlagName of an Option and defines its default Values
975   !! Options will be saved if flagname is different from NULL !!
976 * @param flagname the Name that will be displayed in the output
977 * @param defaultvalue the default Value for this Option(see definition of defaultvalue
978*/
979void Option::setFlagName(const char* flagname, int defaultvalue)
980{
981  if (this->flagName)
982    delete this->flagName;
983  this->flagName = new char [strlen(flagname)+1];
984  strcpy(this->flagName, flagname);
985
986  this->setDefaultValue(defaultvalue);
987
988  if (this->flagNameShort)
989    {
990      delete this->flagNameShort;
991      this->flagNameShort = NULL;
992    }
993
994  //  cout << "Set Flagname of " << this->title << " to " << flagname << endl;
995}
996
997/**
998  *  see Option::setFlagName(char* flagname, int defaultvalue)
999  * @param flagname the Name that will be displayed in the output
1000  * @param defaultvalue the default Value for this Option(see definition of defaultvalue
1001  * @param flagnameshort a short flagname to be displayed in the output
1002*/
1003void Option::setFlagName(const char* flagname, const char* flagnameshort,  int defaultvalue)
1004{
1005  if (this->flagName)
1006    delete []this->flagName;
1007  this->flagName = new char [strlen(flagname)+1];
1008  strcpy(this->flagName, flagname);
1009
1010  if (this->flagNameShort)
1011    delete []this->flagNameShort;
1012  this->flagNameShort = new char [strlen(flagnameshort)+1];
1013  strcpy(this->flagNameShort, flagnameshort);
1014  this->setDefaultValue(defaultvalue);
1015  //  cout << "Set Flagname of " << this->title << " to " << flagname << endl;
1016}
1017
1018void Option::setDescription(const char* shortDescription, const char* longDescription)
1019{
1020  // setting up the short description
1021  if (this->shortDescription)
1022    delete []this->shortDescription;
1023  this->shortDescription = new char [strlen(shortDescription)+1];
1024  strcpy(this->shortDescription, shortDescription);
1025
1026  //setting up the long description
1027  if (this->longDescription)
1028    delete []this->longDescription;
1029  if (longDescription)
1030    {
1031      this->longDescription = new char [strlen(longDescription)+1];
1032      strcpy(this->longDescription, longDescription);
1033    }
1034  else
1035    this->longDescription = NULL;
1036}
1037
1038/**
1039 *  Sets the saveable-state of the option.
1040 * @param isSaveable the saveable-state to set.
1041*/
1042void Option::saveability(bool isSaveable)
1043{
1044  this->saveable = isSaveable;
1045}
1046
1047/**
1048 *  saves an Option
1049 * @returns the String that should be saved. (this string __should__ be deleted)
1050
1051   this is a default Option save
1052*/
1053char* Option::save()
1054{
1055  char* value = new char [30];
1056  sprintf (value, "%d", this->value);
1057  return value;
1058}
1059
1060/**
1061 *  loads an Option from of its loadString
1062 * @param loadString the string from which to load the data from
1063*/
1064void Option::load(const char* loadString)
1065{
1066  this->value = atoi(loadString);
1067  PRINT(5)("Loading %s: %s %d\n", this->title, loadString, value);
1068  this->redraw();
1069}
1070
1071/**
1072 * @returns The saveable-state.
1073*/
1074bool Option::isSaveable()
1075{
1076  return this->saveable;
1077}
1078
1079#ifdef HAVE_GTK2
1080/**
1081  *  Signal OptionChange writes the Value from the Option to its Object-Database.
1082  * @param widget The widget(Option) that has a changed Value
1083  * @param option the Option-Object that should receive the change.
1084*/
1085gint Option::OptionChange(GtkWidget *widget, Widget* option)
1086{
1087  static_cast<Option*>(option)->changeOption();
1088#ifdef BUILD_ORXONOX
1089  flags->setTextFromFlags(Window::mainWindow);
1090#endif
1091}
1092#endif /* HAVE_GTK2 */
1093
1094////////////
1095/* BUTTON */
1096////////////
1097/**
1098 *  Creates a new Button with a buttonname
1099 * @param buttonName sets the Name of the Button
1100*/
1101Button::Button(const char* buttonName)
1102{
1103  this->optionType = GUI_NOTHING;
1104
1105#ifdef HAVE_GTK2
1106  widget = gtk_button_new_with_label("");
1107#endif /* HAVE_GTK2 */
1108
1109  if (buttonName)
1110    this->setTitle(buttonName);
1111}
1112
1113/**
1114 *  destructs a Button.
1115*/
1116Button::~Button()
1117{
1118  PRINTF(5)("deleting the Label: %s\n", this->title);
1119}
1120
1121/**
1122 *  Sets a new name to the Button
1123 * @param title The name the Button should get
1124*/
1125void Button::setTitle(const char *title)
1126{
1127  if (this->title)
1128    delete []this->title;
1129  this->title = new char[strlen(title)+1];
1130  strcpy(this->title, title);
1131#ifdef HAVE_GTK2
1132  gtk_button_set_label(GTK_BUTTON(widget), title);
1133#endif /* HAVE_GTK2 */
1134}
1135
1136/**
1137 *  redraws the Button
1138   @todo not implemented yet
1139*/
1140void Button::redraw()
1141{
1142}
1143
1144/**
1145 *  Button can not be changed, optionChange is empty)
1146
1147   @todo Actions for non-GTK-mode
1148*/
1149void Button::changeOption()
1150{
1151  // This will possibly be used for ACTIONS !
1152}
1153
1154/////////////////
1155/* CHECKBUTTON */
1156/////////////////
1157/**
1158 *  Creates a new CheckButton with an ame
1159 * @param buttonName The name the CheckButton should display.
1160*/
1161CheckButton::CheckButton(const char* buttonName)
1162{
1163  this->optionType = GUI_BOOL;
1164
1165#ifdef HAVE_GTK2
1166  this->widget = gtk_check_button_new_with_label("");
1167#endif /* HAVE_GTK2 */
1168
1169  if (buttonName)
1170    this->setTitle(buttonName);
1171
1172#ifdef HAVE_GTK2
1173  this->connectSignal("clicked", this->OptionChange);
1174#endif /* HAVE_GTK2 */
1175}
1176
1177/**
1178 *  destructs a CheckButton.
1179*/
1180CheckButton::~CheckButton()
1181{
1182  if (this->title)
1183    PRINTF(5)("deleting the CheckButton: %s\n", this->title);
1184  else
1185    PRINTF(5)("deleting the CheckButton.\n");
1186}
1187
1188/**
1189 *  Sets a new Title to a CheckButton
1190 * @param title The new Name the CheckButton should display.
1191*/
1192void CheckButton::setTitle(const char* title)
1193{
1194  if (this->title)
1195    delete []this->title;
1196  this->title = new char[strlen(title)+1];
1197  strcpy(this->title, title);
1198#ifdef HAVE_GTK2
1199  gtk_button_set_label(GTK_BUTTON(widget), title);
1200#endif /* HAVE_GTK2 */
1201}
1202
1203/**
1204 * @returns the Active state of the checkButton
1205*/
1206bool CheckButton::isActive()
1207{
1208#ifdef HAVE_GTK2
1209  return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1210#endif /* HAVE_GTK2 */
1211}
1212
1213/**
1214 *  Changed the Option, call this Function
1215*/
1216void CheckButton::changeOption()
1217{
1218#ifdef HAVE_GTK2
1219  this->value =(int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->widget));
1220#else /* HAVE_GTK2 */
1221  char tmpChar[200];
1222  PRINT(0)("\nPlease give me a new value for %s [0,1](default:%d): ",this->title, this->defaultValue);
1223  scanf("%s", tmpChar);
1224
1225  if ((this->value = atoi(tmpChar))=!0)
1226    this->value = 1;
1227
1228  PRINT(0)("%s set to: %d\n", this->title, this->value);
1229#endif /* HAVE_GTK2 */
1230}
1231
1232/**
1233 *  Redraws the CheckButton(if option has changed).
1234   Example: if new settings are loaded the Button must be redrawn for the GUI to display that Change
1235*/
1236void CheckButton::redraw()
1237{
1238#ifdef HAVE_GTK2
1239  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(this->widget), value);
1240#endif /* HAVE_GTK2 */
1241}
1242
1243////////////
1244/* SLIDER */
1245////////////
1246/**
1247 *  Creates a new Slider
1248 * @param slidername The data-structure-name of the slider.
1249 * @param start The minimal Value of the slider.
1250 * @param end The maximal Value of the slider.
1251*/
1252Slider::Slider(const char* slidername, float start, float end)
1253{
1254  this->optionType = GUI_FLOAT;
1255
1256  this->start = start;
1257  this->end = end;
1258#ifdef HAVE_GTK2
1259 widget = gtk_hscale_new_with_range(this->start, this->end, 5);
1260#endif /* HAVE_GTK2 */
1261
1262  this->setValue(start);
1263  this->setTitle(slidername);
1264#ifdef HAVE_GTK2
1265  this->connectSignal("value_changed", this->OptionChange);
1266#endif /* HAVE_GTK2 */
1267}
1268
1269/**
1270 *  destructs a Slider.
1271*/
1272Slider::~Slider()
1273{
1274  PRINTF(5)("deleting the Slider: %s\n", this->title);
1275}
1276
1277/**
1278 *  sets the exactness of the widget
1279 * @param exactness count of digits after the dot
1280*/
1281void Slider::setExactness(int exactness)
1282{
1283#ifdef HAVE_GTK2
1284 gtk_scale_set_digits(GTK_SCALE(this->widget), exactness);
1285 gtk_range_set_increments(GTK_RANGE(this->widget), pow(.1, exactness), pow(.1, exactness-1));
1286#endif /* HAVE_GTK2 */
1287}
1288
1289/**
1290 *  Setting a new value to the Slider.
1291   Maybe you also require a Slider::redraw() for this to display
1292*/
1293void Slider::setValue(float value)
1294{
1295  this->fValue = value;
1296}
1297
1298/**
1299 *  Redraws the widget
1300   Example: see void CheckButton::redraw()
1301*/
1302void Slider::redraw()
1303{
1304#ifdef HAVE_GTK2
1305  gtk_range_set_value(GTK_RANGE(this->widget), this->fValue);
1306#endif /* HAVE_GTK2 */
1307}
1308
1309/**
1310 *  Changed the Option, call this Function
1311*/
1312void Slider::changeOption()
1313{
1314#ifdef HAVE_GTK2
1315  this->fValue = gtk_range_get_value(GTK_RANGE(this->widget));
1316#else /* HAVE_GTK2 */
1317  char tmpChar[20];
1318  PRINT(0)("\nPlease give me a new value for %s [%d-%d] (default:%d): ", this->title, this->start, this->end, this->defaultValue);
1319  scanf("%s", tmpChar);
1320
1321  if ((this->fValue = atof(tmpChar))> this->end)
1322    this->fValue = this->end;
1323  if (this->fValue <= this->start)
1324    this->fValue = this->start;
1325
1326  PRINT(0)("%s set to: %d\n",this->title, this->fValue);
1327#endif /* HAVE_GTK2 */
1328}
1329
1330char* Slider::save()
1331{
1332  char* value = new char [30];
1333  sprintf (value, "%f", this->fValue);
1334  return value;
1335}
1336void Slider::load(const char* loadString)
1337{
1338  this->fValue = atof(loadString);
1339  PRINT(5)("Loading %s: %s %f\n", this->title, loadString, fValue);
1340  this->redraw();
1341}
1342
1343
1344//////////
1345/* MENU */
1346//////////
1347/**
1348 *  constructs a new Menu, without adding any items to it.
1349 * @param menuName the Name the Menu gets.
1350*/
1351Menu::Menu(const char* menuName)
1352{
1353  this->init();
1354  this->setTitle(menuName);
1355}
1356
1357/**
1358  *  Creates a Menu-Item-list out of multiple input.
1359    !! Consider, that the last input argument has to be "lastItem" for this to work!!
1360  * @param menuname The Database-Name of this Menu
1361  * @param ... items to be added to this Menu. !! Consider, that the last input argument has to be "lastItem" for this to work!!
1362*/
1363Menu::Menu(char* menuname, ...)
1364{
1365  this->init();
1366  this->setTitle(menuname);
1367  va_list itemlist;                     //!< The list to readin multiple Options.
1368
1369  char *itemName;
1370
1371  va_start(itemlist, menuname);
1372  while(strcmp(itemName = va_arg(itemlist, char*), "lastItem"))
1373    {
1374      this->addItem(itemName);
1375    }
1376  va_end(itemlist);
1377}
1378
1379/**
1380 *  destructs a Menu.
1381*/
1382Menu::~Menu()
1383{
1384  PRINTF(5)("deleting the Menu: %s\n", this->title);
1385  this->currItem = this->firstItem;
1386  while(this->currItem)
1387    {
1388      delete []this->currItem->name;
1389      //! @todo destroy menu
1390      /*
1391        #ifdef HAVE_GTK2
1392        gtk_widget_destroy(this->currItem->item);
1393        #endif /* HAVE_GTK2 */
1394      MenuItem* tmpItem = this->currItem;
1395      this->currItem = this->currItem->next;
1396      delete tmpItem;
1397    }
1398}
1399
1400/**
1401 *  Initializes a new Menu with no items
1402*/
1403void Menu::init()
1404{
1405  this->optionType = GUI_INT;
1406  this->firstItem = NULL;
1407
1408#ifdef HAVE_GTK2
1409  this->widget = gtk_option_menu_new();
1410  this->menu = gtk_menu_new();
1411  gtk_option_menu_set_menu(GTK_OPTION_MENU(this->widget), menu);
1412  this->connectSignal("changed", this->OptionChange);
1413#endif /* HAVE_GTK2 */
1414}
1415
1416/**
1417 *  saves the Label of the Menu
1418 * @returns the name of the selected Menu-Item
1419*/
1420char* Menu::save()
1421{
1422  MenuItem* tmpItem = this->firstItem;
1423  for (int i = 0; i < this->value; i++)
1424    if (tmpItem)
1425      tmpItem = tmpItem->next;
1426    else
1427      break;
1428  if (tmpItem)
1429    {
1430      char* tmpName = new char[strlen(tmpItem->name)+1];
1431      strcpy(tmpName, tmpItem->name);
1432      return tmpName;
1433    }
1434  else
1435    return NULL;
1436}
1437
1438/**
1439 *  loads a Menu from of its loadString
1440 * @param loadString the string from which to load the data from
1441*/
1442void Menu::load(const char* loadString)
1443{
1444  MenuItem* tmpItem = firstItem;
1445  bool foundItem = false;
1446  while (tmpItem)
1447    {
1448      if (!strcmp(loadString, tmpItem->name))
1449        {foundItem = true; break;}
1450      tmpItem = tmpItem->next;
1451    }
1452  if (foundItem)
1453    this->value = tmpItem->itemNumber;
1454  else
1455    {
1456      this->value = 0;
1457      PRINTF(2)("%s has not been found in the Itemlist of %s\n", loadString, this->title);
1458    }
1459  PRINTF(5)( "Loading %s: setting to %d\n", this->title, this->value);
1460  this->redraw();
1461}
1462
1463/**
1464 *  appends a new Item to the Menu-List.
1465 * @param itemName the itemName to be appendet.
1466*/
1467void Menu::addItem(char* itemName)
1468{
1469  if (!this->firstItem)
1470    {
1471      this->firstItem = this->currItem = new MenuItem;
1472      this->currItem->itemNumber = 0;
1473    }
1474  else
1475    {
1476      int tmpI = this->currItem->itemNumber;
1477      this->currItem = this->currItem->next = new MenuItem;
1478      this->currItem->itemNumber = tmpI+1;
1479    }
1480
1481  this->currItem->name = new char[strlen(itemName)+1];
1482  strcpy(this->currItem->name, itemName);
1483
1484#ifdef HAVE_GTK2
1485  this->currItem->item = gtk_menu_item_new_with_label(itemName);
1486  gtk_menu_shell_append(GTK_MENU_SHELL(this->menu), this->currItem->item);
1487#endif /* HAVE_GTK2 */
1488  this->currItem->next = NULL;
1489}
1490
1491/**
1492 *  Redraws the widget
1493   Example: see void CheckButton::redraw()
1494*/
1495void Menu::redraw()
1496{
1497#ifdef HAVE_GTK2
1498  gtk_option_menu_set_history(GTK_OPTION_MENU(this->widget), this->value);
1499#endif /* HAVE_GTK2 */
1500}
1501
1502/**
1503 *  Changed the Option, call this Function
1504*/
1505void Menu::changeOption()
1506{
1507#ifdef HAVE_GTK2
1508  this->value =(int)gtk_option_menu_get_history(GTK_OPTION_MENU(this->widget));
1509#else /* HAVE_GTK2 */
1510  char tmpChar[20];
1511  PRINT(0)("\nPlease give me a new value for %s (default: %d): ", this->title, this->defaultValue);
1512  scanf("%s",tmpChar);
1513  this->value = atoi(tmpChar);
1514
1515#endif /* HAVE_GTK2 */
1516  PRINT(4)("%s set to: %d\n", this->title, this->value);
1517}
1518
1519/* OPTION LABEL */
1520
1521/**
1522 *  Creates a new OptionLabel with a LabelName and a Value.
1523 * @param label The name of the OptionLabel.
1524 * @param value The Value of the OptionLabel(what will be displayed).
1525*/
1526OptionLabel::OptionLabel(const char* label, const char* value)
1527{
1528  this->optionType = GUI_CHAR_ARRAY;
1529  cValue = NULL;
1530
1531#ifdef HAVE_GTK2
1532  this->widget = gtk_label_new("");
1533#endif /* HAVE_GTK2 */
1534
1535  this->setTitle(label);
1536  this->setValue(value);
1537}
1538
1539/**
1540 *  destructs an OptionLabel.
1541*/
1542OptionLabel::~OptionLabel()
1543{
1544  PRINTF(5)("deleting the OptionLabel: %s\n", this->title);
1545  if (this->cValue)
1546    delete []this->cValue;
1547}
1548
1549/**
1550 *  Updates the value of an OptionLabel
1551 * @param newValue The new Name that should be displayed.
1552*/
1553void OptionLabel::setValue(const char* newValue)
1554{
1555  if (this->cValue)
1556    delete []this->cValue;
1557  this->cValue = new char [strlen(newValue)+1];
1558  strcpy(this->cValue, newValue);
1559
1560  this->redraw();
1561}
1562
1563/**
1564 *  Redraws an OptionLabel(not implemented yet, but it works).
1565*/
1566void OptionLabel::redraw()
1567{
1568#ifdef HAVE_GTK2
1569  gtk_label_set_text(GTK_LABEL(widget), cValue);
1570#endif /* HAVE_GTK2 */
1571}
1572
1573/**
1574 *  Changed the Option, call this Function
1575*/
1576void OptionLabel::changeOption()
1577{
1578#ifdef HAVE_GTK2
1579  this->cValue = (char*)gtk_label_get_text(GTK_LABEL(this->widget));
1580#else /* HAVE_GTK2 */
1581  PRINT(0)("\nPlease give me a new input for %s: ", this->title);
1582  char tmpChar[100];
1583  scanf("%s",tmpChar);
1584  this->setValue(tmpChar);
1585#endif /* HAVE_GTK2 */
1586  PRINT(4)("%s set to: %s\n", this->title,  this->cValue);
1587}
1588
1589
1590/**
1591 *  creates the Optionlabel save-string
1592 * @returns the String to save.
1593*/
1594char* OptionLabel::save()
1595{
1596  return cValue;
1597}
1598
1599/**
1600 *  loads an Option from of its loadString
1601 * @param loadString the string from which to load the data from
1602*/
1603void OptionLabel::load(const char* loadString)
1604{
1605  PRINTF(5)("Loading %s: setting to %s\n", this->title, loadString);
1606  this->setValue(loadString);
1607}
1608
1609///////////
1610/* LABEL */
1611///////////
1612/**
1613 *  Creates a new Label with a Text.
1614 * @param text The text to be displayed.
1615*/
1616Label:: Label(const char* text)
1617{
1618  this->optionType = GUI_NOTHING;
1619
1620#ifdef HAVE_GTK2
1621  this->widget = gtk_label_new("");
1622  gtk_label_set_line_wrap(GTK_LABEL(this->widget), TRUE);
1623#endif /* HAVE_GTK2 */
1624
1625  if (text)
1626    this->setTitle(text);
1627}
1628
1629/**
1630 *  destructs a Label.
1631*/
1632Label::~Label()
1633{
1634  PRINTF(5)("deleting the Label: %s\n", this->title);
1635}
1636
1637/**
1638 *  Sets a new Text to a Label.
1639 * @param text The text to be inserted into the Label.
1640*/
1641void Label::setTitle(const char* text)
1642{
1643  if (this->title)
1644    delete []this->title;
1645  this->title = new char[strlen(text)+1];
1646  strcpy(this->title, text);
1647#ifdef HAVE_GTK2
1648  gtk_label_set_text(GTK_LABEL(this->widget), this->title);
1649#endif /* HAVE_GTK2 */
1650}
1651
1652/**
1653 *  ereases the Text of a Label
1654*/
1655void Label::ereaseText()
1656{
1657  this->setTitle("");
1658}
1659
1660/**
1661  *  appends some Text to a Label
1662  * @param textToAppend The text that will be appended to this Label
1663*/
1664void Label::appendText(char* textToAppend)
1665{
1666  if (this->title)
1667    {
1668      char* tmpTitle = new char[strlen(this->title)+strlen(textToAppend)+1];
1669      strcpy(tmpTitle, title);
1670      strcat(tmpTitle, textToAppend);
1671      delete []this->title;
1672      this->title = tmpTitle;
1673    }
1674  else
1675    this->title = new char[strlen(textToAppend)];
1676
1677#ifdef HAVE_GTK2
1678  gtk_label_set_text(GTK_LABEL(this->widget), title);
1679#endif /* HAVE_GTK2 */
1680}
1681
1682/**
1683  *  Appends some integer to the Label
1684  * @param intToAppend The Int that will be added.
1685
1686    it does this by just converting the int into a char* and send it to appendText
1687*/
1688void Label::appendInt(int intToAppend)
1689{
1690  char append [32];
1691  sprintf(append, "%d", intToAppend);
1692  this->appendText(append);
1693}
1694
1695
1696/**
1697 *  get the Text of a Label
1698 * @return The Text the Label holds.
1699*/
1700const char* Label::getText()
1701{
1702  return this->title;
1703}
1704
1705//////////////////
1706/* PROGRESS-BAR */
1707//////////////////
1708/**
1709 *  Creates a new ProgressBar.
1710 * @param label The name you want to get the ProgressBar.
1711*/
1712ProgressBar::ProgressBar(const char* label)
1713{
1714  this->optionType = GUI_NOTHING;
1715  this->progress = 0.0;
1716  this->totalSize = 0.0;
1717
1718#ifdef HAVE_GTK2
1719  this->adjustment =(GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
1720  this->widget = gtk_progress_bar_new_with_adjustment(this->adjustment);
1721#endif /* HAVE_GTK2 */
1722
1723  if (label)
1724    this->setTitle(label);
1725}
1726
1727/**
1728 *  destructs a ProgressBar
1729*/
1730ProgressBar::~ProgressBar()
1731{
1732  PRINTF(5)("deleting the ProgressBar: %s\n", this->title);
1733}
1734
1735/**
1736 *  Sets the Total size of the Bar.(ex. The maximum one can download)
1737*/
1738void ProgressBar::setTotalSize(double totalSize)
1739{
1740  this->totalSize = totalSize;
1741}
1742
1743/**
1744 *  Sets the progress maximum is this->totalSize
1745*/
1746void ProgressBar::setProgress(double progress)
1747{
1748  this->progress = progress;
1749
1750  if (this->progress > this->totalSize)
1751    this->progress = this->totalSize;
1752
1753#ifdef HAVE_GTK2
1754  gtk_progress_set_value(GTK_PROGRESS(widget), this->progress*100.0/this->totalSize);
1755  PRINTF(5)("Progress: %f%%\n", this->progress*100.0/this->totalSize);
1756#else /* HVE_GTK2 */
1757  PRINT(0)("Progress: %f%%\n", this->progress*100.0/this->totalSize);
1758#endif /* HAVE_GTK2 */
1759}
1760
1761/**
1762  *  returns the Progress Status
1763*/
1764double ProgressBar::getProgress()
1765{
1766  return this->progress;
1767}
1768
1769///////////
1770/* IMAGE */
1771///////////
1772/**
1773 *  Creates a new Image
1774 * @param imageName the location of the Image on the Hard Disc
1775*/
1776Image::Image(const char* imageName)
1777{
1778  this->init(imageName);
1779
1780#ifdef HAVE_GTK2
1781  widget = gtk_image_new_from_file(imageName);
1782#endif /* HAVE_GTK2 */
1783}
1784
1785/**
1786 *  Creates a new Image
1787 * @param imageData data to the PixBuff
1788*/
1789Image::Image(char** imageData)
1790{
1791  this->init("pixBuffImage");
1792
1793#ifdef HAVE_GTK2
1794  widget = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data((const char**)imageData));
1795#endif /* HAVE_GTK2 */
1796}
1797
1798
1799/**
1800 *  destructs an Image.
1801*/
1802Image::~Image()
1803{
1804  PRINTF(5)("deleting the Image: %s\n", this->title);
1805}
1806
1807/**
1808  *  Initializes a new Image
1809  * @param name the name to set to the Image
1810*/
1811void Image::init(const char* name)
1812{
1813  optionType = GUI_NOTHING;
1814
1815  if (this->title)
1816    delete []this->title;
1817  this->title = new char[strlen(name)+1];
1818  strcpy(this->title, name);
1819}
1820
1821
1822/////////////////
1823/* FILE DIALOG */
1824/////////////////
1825/**
1826 *  Creates a new FileDialog
1827 * @param fileDialogName a Name for the Dialog
1828*/
1829FileDialog::FileDialog(const char* fileDialogName)
1830{
1831  this->optionType = GUI_NOTHING;
1832  this->isOpen = false;
1833  this->changeOption = NULL;
1834  this->openUpButton = NULL;
1835  this->okObject = NULL;
1836  this->okFunc = NULL;
1837
1838#ifdef HAVE_GTK2
1839  this->widget = gtk_file_selection_new(fileDialogName);
1840
1841  gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION (this->widget), FALSE);
1842
1843  g_signal_connect(GTK_FILE_SELECTION (this->widget)->cancel_button,
1844                     "button_release_event",
1845                     G_CALLBACK (FileDialog::dialogClose),
1846                     this);
1847  g_signal_connect(GTK_FILE_SELECTION (this->widget),
1848                     "delete_event",
1849                     G_CALLBACK (FileDialog::dialogClose),
1850                     this);
1851  g_signal_connect(GTK_FILE_SELECTION (this->widget)->ok_button,
1852                     "button_release_event",
1853                     G_CALLBACK (FileDialog::dialogOK),
1854                     this);
1855#endif /* HAVE_GTK2 */
1856  if (fileDialogName)
1857    this->setTitle(fileDialogName);
1858}
1859
1860/**
1861 *  destructs a FileDialog
1862*/
1863FileDialog::~FileDialog()
1864{
1865  PRINTF(5)("deleting FileDialog %s\n", this->title);
1866}
1867
1868void FileDialog::setChangeOption(OptionLabel* changeOption)
1869{
1870  this->changeOption = changeOption;
1871}
1872
1873void FileDialog::setOKFunc(void* okObject, bool(*function)(const char* , void*))
1874{
1875  this->okObject = okObject;
1876  this->okFunc = function;
1877}
1878
1879
1880void FileDialog::setOpenUpButton(Button* openUpButton)
1881{
1882  this->openUpButton = openUpButton;
1883
1884  openUpButton->connectSignal("button_release_event", this, FileDialog::dialogOpen);
1885}
1886
1887
1888void FileDialog::setDefaultFileName(const char* defaultFileName)
1889{
1890#ifdef HAVE_GTK2
1891  gtk_file_selection_set_filename (GTK_FILE_SELECTION(this->widget), defaultFileName);
1892#endif /* HAVE_GTK2 */
1893}
1894
1895void FileDialog::setMask(const char* mask)
1896{
1897#ifdef HAVE_GTK2
1898  gtk_file_selection_complete(GTK_FILE_SELECTION(this->widget), mask);
1899#endif /* HAVE_GTK2 */
1900}
1901
1902/**
1903 *  disables the File Operator Buttons
1904*/
1905void FileDialog::disableFileOpts()
1906{
1907#ifdef HAVE_GTK2
1908  gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(this->widget));
1909#endif /* HAVE_GTK2 */
1910}
1911
1912/**
1913 *  The ok-button has been pressed
1914*/
1915void FileDialog::okEvent()
1916{
1917  if (this->okFunc)
1918    {
1919#ifdef HAVE_GTK2
1920      if(this->okFunc((const char*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->widget)), this->okObject))
1921         this->close();
1922#endif /* HAVE_GTK2 */
1923    }
1924  else if (this->changeOption)
1925    {
1926#ifdef HAVE_GTK2
1927      changeOption->setValue(gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->widget)));
1928#endif /* HAVE_GTK2 */
1929      this->close();
1930    }
1931  else
1932    this->close();
1933}
1934
1935/**
1936   \biref opens up the FileDialog-Window
1937*/
1938void FileDialog::open()
1939{
1940  isOpen = true;
1941#ifdef HAVE_GTK2
1942  gtk_widget_show_all(this->widget);
1943  gtk_grab_add(this->widget);
1944#endif /* HAVE_GTK2 */
1945}
1946
1947/**
1948   \closes the FileDialog-Window
1949*/
1950void FileDialog::close()
1951{
1952  this->isOpen = false;
1953#ifdef HAVE_GTK2
1954  gtk_grab_remove(this->widget);
1955  gtk_widget_hide(this->widget);
1956#endif /* HAVE_GTK2 */
1957}
1958
1959#ifdef HAVE_GTK2
1960gint FileDialog::dialogOK(GtkWidget* widget, GdkEvent* event, void* dialog)
1961{
1962  static_cast<FileDialog*>(dialog)->okEvent();
1963}
1964#else /* HAVE_GTK2 */
1965int FileDialog::dialogOK(void* widget, void* event, void* dialog){}
1966#endif /* HAVE_GTK2 */
1967
1968#ifdef HAVE_GTK2
1969gint FileDialog::dialogOpen(GtkWidget* widget, GdkEvent* event, void* dialog)
1970{
1971  static_cast<FileDialog*>(dialog)->open();
1972}
1973#else /* HAVE_GTK2 */
1974int FileDialog::dialogOpen(void* widget, void* event, void* dialog){}
1975#endif /* HAVE_GTK2 */
1976
1977#ifdef HAVE_GTK2
1978gint FileDialog::dialogClose(GtkWidget* widget, GdkEvent* event, void* dialog)
1979{
1980  static_cast<FileDialog*>(dialog)->close();
1981}
1982#else /* HAVE_GTK2 */
1983int FileDialog::dialogClose(void* widget, void* event, void* dialog){}
1984#endif /* HAVE_GTK2 */
Note: See TracBrowser for help on using the repository browser.