Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/physics/src/lib/gui/gui/gui_gtk.cc @ 4319

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

orxonox/branches/physics: slider now supports floats

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