Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/particles: new Sliders

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
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 Option to its Object-Database.
1081    \param widget The widget(Option) that has a changed Value
1082    \param option the Option-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 sets the exactness of the widget
1278   \param exactness count of digits after the dot
1279*/
1280void Slider::setExactness(int exactness)
1281{
1282#ifdef HAVE_GTK2
1283 gtk_scale_set_digits(GTK_SCALE(this->widget), exactness);
1284#endif /* HAVE_GTK2 */
1285}
1286
1287/**
1288   \brief Setting a new value to the Slider.
1289   Maybe you also require a Slider::redraw() for this to display
1290*/
1291void Slider::setValue(float value)
1292{
1293  this->fValue = value;
1294}
1295
1296/**
1297   \brief Redraws the widget
1298   Example: see void CheckButton::redraw(void)
1299*/
1300void Slider::redraw(void)
1301{
1302#ifdef HAVE_GTK2
1303  gtk_range_set_value(GTK_RANGE(this->widget), this->fValue);
1304#endif /* HAVE_GTK2 */
1305}
1306
1307/**
1308   \brief Changed the Option, call this Function
1309*/
1310void Slider::changeOption(void)
1311{
1312#ifdef HAVE_GTK2
1313  this->fValue = gtk_range_get_value(GTK_RANGE(this->widget));
1314#else /* HAVE_GTK2 */
1315  char tmpChar[20];
1316  PRINT(0)("\nPlease give me a new value for %s [%d-%d] (default:%d): ", this->title, this->start, this->end, this->defaultValue);
1317  scanf("%s", tmpChar);
1318
1319  if ((this->fValue = atof(tmpChar))> this->end)
1320    this->fValue = this->end;
1321  if (this->fValue <= this->start)
1322    this->fValue = this->start;
1323
1324  PRINT(0)("%s set to: %d\n",this->title, this->fValue);
1325#endif /* HAVE_GTK2 */
1326}
1327
1328char* Slider::save(void)
1329{
1330  char* value = new char [30];
1331  sprintf (value, "%f", this->fValue);
1332  return value;
1333}
1334void Slider::load(char* loadString)
1335{
1336  this->fValue = atof(loadString);
1337  PRINT(5)("Loading %s: %s %f\n", this->title, loadString, fValue); 
1338  this->redraw();
1339}
1340
1341
1342//////////
1343/* MENU */
1344//////////
1345/**
1346   \brief constructs a new Menu, without adding any items to it.
1347   \param menuName the Name the Menu gets.
1348*/
1349Menu::Menu(const char* menuName)
1350{
1351  this->init();
1352  this->setTitle(menuName);
1353}
1354
1355/**
1356    \brief Creates a Menu-Item-list out of multiple input.
1357    !! Consider, that the last input argument has to be "lastItem" for this to work!!
1358    \param menuname The Database-Name of this Menu
1359    \param ... items to be added to this Menu. !! Consider, that the last input argument has to be "lastItem" for this to work!!
1360*/
1361Menu::Menu(char* menuname, ...)
1362{
1363  this->init();
1364  this->setTitle(menuname);
1365  va_list itemlist;                     //!< The list to readin multiple Options.
1366
1367  char *itemName;
1368
1369  va_start(itemlist, menuname);
1370  while(strcmp(itemName = va_arg(itemlist, char*), "lastItem"))
1371    {
1372      this->addItem(itemName);
1373    }
1374  va_end(itemlist);
1375}
1376
1377/**
1378   \brief destructs a Menu.
1379*/
1380Menu::~Menu(void)
1381{
1382  PRINTF(5)("deleting the Menu: %s\n", this->title);
1383  this->currItem = this->firstItem;
1384  while(this->currItem)
1385    {
1386      delete []this->currItem->name;
1387      //! \todo destroy menu
1388      /*
1389        #ifdef HAVE_GTK2
1390        gtk_widget_destroy(this->currItem->item);
1391        #endif /* HAVE_GTK2 */
1392      MenuItem* tmpItem = this->currItem;
1393      this->currItem = this->currItem->next;
1394      delete tmpItem;
1395    }
1396}
1397
1398/**
1399   \brief Initializes a new Menu with no items
1400*/
1401void Menu::init(void)
1402{
1403  this->optionType = GUI_INT;
1404  this->firstItem = NULL;
1405
1406#ifdef HAVE_GTK2
1407  this->widget = gtk_option_menu_new();
1408  this->menu = gtk_menu_new();
1409  gtk_option_menu_set_menu(GTK_OPTION_MENU(this->widget), menu);
1410  this->connectSignal("changed", this->OptionChange);
1411#endif /* HAVE_GTK2 */
1412}
1413
1414/**
1415   \brief saves the Label of the Menu
1416   \returns the name of the selected Menu-Item
1417*/
1418char* Menu::save(void)
1419{
1420  MenuItem* tmpItem = this->firstItem;
1421  for (int i = 0; i<this->value; i++)
1422    tmpItem = tmpItem->next;
1423     
1424  return tmpItem->name;
1425}
1426
1427/**
1428   \brief loads a Menu from of its loadString
1429   \param loadString the string from which to load the data from
1430*/
1431void Menu::load(char* loadString)
1432{
1433  MenuItem* tmpItem = firstItem;
1434  bool foundItem = false;
1435  while (tmpItem)
1436    {
1437      if (!strcmp(loadString, tmpItem->name))
1438        {foundItem = true; break;}
1439      tmpItem = tmpItem->next;
1440    }
1441  if (foundItem)
1442    this->value = tmpItem->itemNumber;
1443  else
1444    {
1445      this->value = 0;
1446      PRINTF(2)("%s has not been found in the Itemlist of %s\n", loadString, this->title);
1447    }
1448  PRINTF(5)( "Loading %s: setting to %d\n", this->title, this->value); 
1449  this->redraw();
1450}
1451
1452/**
1453   \brief appends a new Item to the Menu-List.
1454   \param itemName the itemName to be appendet.
1455*/
1456void Menu::addItem(char* itemName)
1457{
1458  if (!this->firstItem)
1459    {
1460      this->firstItem = this->currItem = new MenuItem;
1461      this->currItem->itemNumber = 0;
1462    }
1463  else
1464    {
1465      int tmpI = this->currItem->itemNumber;
1466      this->currItem = this->currItem->next = new MenuItem;
1467      this->currItem->itemNumber = tmpI+1;
1468    }
1469
1470  this->currItem->name = new char[strlen(itemName)+1];
1471  strcpy(this->currItem->name, itemName);
1472
1473#ifdef HAVE_GTK2
1474  this->currItem->item = gtk_menu_item_new_with_label(itemName);
1475  gtk_menu_shell_append(GTK_MENU_SHELL(this->menu), this->currItem->item);
1476#endif /* HAVE_GTK2 */
1477  this->currItem->next = NULL;
1478}
1479
1480/**
1481   \brief Redraws the widget
1482   Example: see void CheckButton::redraw(void)
1483*/
1484void Menu::redraw(void)
1485{
1486#ifdef HAVE_GTK2
1487  gtk_option_menu_set_history(GTK_OPTION_MENU(this->widget), this->value);
1488#endif /* HAVE_GTK2 */
1489}
1490
1491/**
1492   \brief Changed the Option, call this Function
1493*/
1494void Menu::changeOption(void)
1495{
1496#ifdef HAVE_GTK2
1497  this->value =(int)gtk_option_menu_get_history(GTK_OPTION_MENU(this->widget));
1498#else /* HAVE_GTK2 */
1499  char tmpChar[20];
1500  PRINT(0)("\nPlease give me a new value for %s (default: %d): ", this->title, this->defaultValue);
1501  scanf("%s",tmpChar);
1502  this->value = atoi(tmpChar);
1503
1504#endif /* HAVE_GTK2 */
1505  PRINT(5)("%s set to: %d\n", this->title, this->value);
1506}
1507
1508/* OPTION LABEL */
1509
1510/**
1511   \brief Creates a new OptionLabel with a LabelName and a Value.
1512   \param label The name of the OptionLabel.
1513   \param value The Value of the OptionLabel(what will be displayed).
1514*/
1515OptionLabel::OptionLabel(const char* label, const char* value)
1516{
1517  this->optionType = GUI_CHAR_ARRAY;
1518  cValue = NULL;
1519
1520#ifdef HAVE_GTK2
1521  this->widget = gtk_label_new("");
1522#endif /* HAVE_GTK2 */
1523
1524  this->setTitle(label);
1525  this->setValue(value);
1526}
1527
1528/**
1529   \brief destructs an OptionLabel.
1530*/
1531OptionLabel::~OptionLabel(void)
1532{
1533  PRINTF(5)("deleting the OptionLabel: %s\n", this->title);
1534  if (this->cValue)
1535    delete []this->cValue;
1536}
1537
1538/**
1539   \brief Updates the value of an OptionLabel
1540   \param newValue The new Name that should be displayed.
1541*/
1542void OptionLabel::setValue(const char* newValue)
1543{
1544  if (this->cValue)
1545    delete []this->cValue;
1546  this->cValue = new char [strlen(newValue)+1];
1547  strcpy(this->cValue, newValue);
1548
1549  this->redraw();
1550}
1551
1552/**
1553   \brief Redraws an OptionLabel(not implemented yet, but it works).
1554*/
1555void OptionLabel::redraw(void)
1556{
1557#ifdef HAVE_GTK2
1558  gtk_label_set_text(GTK_LABEL(widget), cValue);
1559#endif /* HAVE_GTK2 */
1560}
1561
1562/**
1563   \brief Changed the Option, call this Function
1564*/
1565void OptionLabel::changeOption(void)
1566{
1567#ifdef HAVE_GTK2
1568  this->cValue = (char*)gtk_label_get_text(GTK_LABEL(this->widget));
1569#else /* HAVE_GTK2 */
1570  PRINT(0)("\nPlease give me a new input for %s: ", this->title);
1571  char tmpChar[100];
1572  scanf("%s",tmpChar);
1573  this->setValue(tmpChar);
1574#endif /* HAVE_GTK2 */
1575  PRINT(4)("%s set to: %s\n", this->title,  this->cValue);
1576}
1577
1578
1579/**
1580   \brief creates the Optionlabel save-string
1581   \returns the String to save.
1582*/
1583char* OptionLabel::save(void)
1584{
1585  return cValue;
1586}
1587
1588/**
1589   \brief loads an Option from of its loadString
1590   \param loadString the string from which to load the data from
1591*/
1592void OptionLabel::load(char* loadString)
1593{
1594  PRINTF(5)("Loading %s: setting to %s\n", this->title, loadString); 
1595  this->setValue(loadString);
1596}
1597
1598///////////
1599/* LABEL */
1600///////////
1601/**
1602   \brief Creates a new Label with a Text.
1603   \param text The text to be displayed.
1604*/
1605Label:: Label(const char* text)
1606{
1607  this->optionType = GUI_NOTHING;
1608 
1609#ifdef HAVE_GTK2
1610  this->widget = gtk_label_new("");
1611  gtk_label_set_line_wrap(GTK_LABEL(this->widget), TRUE);
1612#endif /* HAVE_GTK2 */
1613 
1614  if (text)
1615    this->setTitle(text);
1616}
1617
1618/**
1619   \brief destructs a Label.
1620*/
1621Label::~Label(void)
1622{
1623  PRINTF(5)("deleting the Label: %s\n", this->title);
1624}
1625
1626/**
1627   \brief Sets a new Text to a Label.
1628   \param text The text to be inserted into the Label.
1629*/
1630void Label::setTitle(const char* text)
1631{
1632  if (this->title)
1633    delete []this->title;
1634  this->title = new char[strlen(text)+1];
1635  strcpy(this->title, text);
1636#ifdef HAVE_GTK2
1637  gtk_label_set_text(GTK_LABEL(this->widget), this->title);
1638#endif /* HAVE_GTK2 */
1639}
1640
1641/**
1642   \brief ereases the Text of a Label
1643*/
1644void Label::ereaseText(void)
1645{
1646  this->setTitle("");
1647}
1648
1649/**
1650    \brief appends some Text to a Label
1651    \param textToAppend The text that will be appended to this Label
1652*/
1653void Label::appendText(char* textToAppend)
1654{
1655  if (this->title)
1656    {
1657      char* tmpTitle = new char[strlen(this->title)+strlen(textToAppend)+1];
1658      strcpy(tmpTitle, title); 
1659      strcat(tmpTitle, textToAppend);
1660      delete []this->title;
1661      this->title = tmpTitle;
1662    }
1663  else
1664    this->title = new char[strlen(textToAppend)];
1665 
1666#ifdef HAVE_GTK2
1667  gtk_label_set_text(GTK_LABEL(this->widget), title);
1668#endif /* HAVE_GTK2 */
1669}
1670
1671/**
1672    \brief Appends some integer to the Label
1673    \param intToAppend The Int that will be added.
1674   
1675    it does this by just converting the int into a char* and send it to appendText
1676*/
1677void Label::appendInt(int intToAppend)
1678{
1679  char append [32];
1680  sprintf(append, "%d", intToAppend);
1681  this->appendText(append);
1682}
1683
1684
1685/**
1686   \brief get the Text of a Label
1687   \return The Text the Label holds.
1688*/
1689const char* Label::getText(void)
1690{
1691  return this->title;
1692}
1693
1694//////////////////
1695/* PROGRESS-BAR */
1696//////////////////
1697/**
1698   \brief Creates a new ProgressBar.
1699   \param label The name you want to get the ProgressBar.
1700*/
1701ProgressBar::ProgressBar(const char* label)
1702{
1703  this->optionType = GUI_NOTHING;
1704  this->progress = 0.0;
1705  this->totalSize = 0.0;
1706
1707#ifdef HAVE_GTK2
1708  this->adjustment =(GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
1709  this->widget = gtk_progress_bar_new_with_adjustment(this->adjustment);
1710#endif /* HAVE_GTK2 */
1711
1712  if (label)
1713    this->setTitle(label);
1714}
1715
1716/**
1717   \brief destructs a ProgressBar
1718*/
1719ProgressBar::~ProgressBar(void)
1720{
1721  PRINTF(5)("deleting the ProgressBar: %s\n", this->title);
1722}
1723
1724/**
1725   \brief Sets the Total size of the Bar.(ex. The maximum one can download)
1726*/
1727void ProgressBar::setTotalSize(double totalSize)
1728{
1729  this->totalSize = totalSize;
1730}
1731
1732/**
1733   \brief Sets the progress maximum is this->totalSize
1734*/
1735void ProgressBar::setProgress(double progress)
1736{
1737  this->progress = progress;
1738
1739  if (this->progress > this->totalSize)
1740    this->progress = this->totalSize;
1741
1742#ifdef HAVE_GTK2
1743  gtk_progress_set_value(GTK_PROGRESS(widget), this->progress*100.0/this->totalSize);
1744  PRINTF(5)("Progress: %f%%\n", this->progress*100.0/this->totalSize);
1745#else /* HVE_GTK2 */
1746  PRINT(0)("Progress: %f%%\n", this->progress*100.0/this->totalSize);
1747#endif /* HAVE_GTK2 */
1748}
1749
1750/**
1751    \brief returns the Progress Status
1752*/
1753double ProgressBar::getProgress(void)
1754{
1755  return this->progress;
1756}
1757
1758///////////
1759/* IMAGE */
1760///////////
1761/**
1762   \brief Creates a new Image
1763   \param imageName the location of the Image on the Hard Disc
1764*/
1765Image::Image(const char* imageName)
1766{
1767  this->init(imageName);
1768
1769#ifdef HAVE_GTK2
1770  widget = gtk_image_new_from_file(imageName);
1771#endif /* HAVE_GTK2 */
1772}
1773
1774/**
1775   \brief Creates a new Image
1776   \param imageData data to the PixBuff
1777*/
1778Image::Image(char** imageData)
1779{
1780  this->init("pixBuffImage");
1781
1782#ifdef HAVE_GTK2
1783  widget = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data((const char**)imageData));
1784#endif /* HAVE_GTK2 */
1785}
1786
1787
1788/**
1789   \brief destructs an Image.
1790*/
1791Image::~Image(void)
1792{
1793  PRINTF(5)("deleting the Image: %s\n", this->title);
1794}
1795
1796/**
1797    \brief Initializes a new Image
1798    \param name the name to set to the Image
1799*/
1800void Image::init(const char* name)
1801{
1802  optionType = GUI_NOTHING;
1803
1804  if (this->title)
1805    delete []this->title;
1806  this->title = new char[strlen(name)+1];
1807  strcpy(this->title, name);
1808}
1809
1810
1811/////////////////
1812/* FILE DIALOG */
1813/////////////////
1814/**
1815   \brief Creates a new FileDialog
1816   \param fileDialogName a Name for the Dialog
1817*/
1818FileDialog::FileDialog(const char* fileDialogName)
1819{
1820  this->optionType = GUI_NOTHING;
1821  this->isOpen = false;
1822  this->changeOption = NULL;
1823  this->openUpButton = NULL;
1824  this->okObject = NULL;
1825  this->okFunc = NULL;
1826
1827#ifdef HAVE_GTK2
1828  this->widget = gtk_file_selection_new(fileDialogName);
1829
1830  gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION (this->widget), FALSE);
1831
1832  g_signal_connect(GTK_FILE_SELECTION (this->widget)->cancel_button,
1833                     "button_release_event",
1834                     G_CALLBACK (FileDialog::dialogClose),
1835                     this);
1836  g_signal_connect(GTK_FILE_SELECTION (this->widget),
1837                     "delete_event",
1838                     G_CALLBACK (FileDialog::dialogClose),
1839                     this);
1840  g_signal_connect(GTK_FILE_SELECTION (this->widget)->ok_button,
1841                     "button_release_event",
1842                     G_CALLBACK (FileDialog::dialogOK),
1843                     this);
1844#endif /* HAVE_GTK2 */
1845  if (fileDialogName)
1846    this->setTitle(fileDialogName);
1847}
1848
1849/**
1850   \brief destructs a FileDialog
1851*/
1852FileDialog::~FileDialog(void)
1853{
1854  PRINTF(5)("deleting FileDialog %s\n", this->title);
1855}
1856
1857void FileDialog::setChangeOption(OptionLabel* changeOption)
1858{
1859  this->changeOption = changeOption;
1860}
1861
1862void FileDialog::setOKFunc(void* okObject, bool(*function)(const char* , void*))
1863{
1864  this->okObject = okObject;
1865  this->okFunc = function;
1866}
1867
1868
1869void FileDialog::setOpenUpButton(Button* openUpButton)
1870{
1871  this->openUpButton = openUpButton;
1872
1873  openUpButton->connectSignal("button_release_event", this, FileDialog::dialogOpen);
1874}
1875
1876
1877void FileDialog::setDefaultFileName(const char* defaultFileName)
1878{
1879#ifdef HAVE_GTK2
1880  gtk_file_selection_set_filename (GTK_FILE_SELECTION(this->widget), defaultFileName);
1881#endif /* HAVE_GTK2 */
1882}
1883
1884void FileDialog::setMask(const char* mask)
1885{
1886#ifdef HAVE_GTK2
1887  gtk_file_selection_complete(GTK_FILE_SELECTION(this->widget), mask);
1888#endif /* HAVE_GTK2 */
1889}
1890
1891/**
1892   \brief disables the File Operator Buttons
1893*/
1894void FileDialog::disableFileOpts(void)
1895{
1896#ifdef HAVE_GTK2
1897  gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(this->widget));
1898#endif /* HAVE_GTK2 */
1899}
1900
1901/**
1902   \brief The ok-button has been pressed
1903*/
1904void FileDialog::okEvent(void)
1905{
1906  if (this->okFunc)
1907    {
1908#ifdef HAVE_GTK2
1909      if(this->okFunc((const char*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->widget)), this->okObject))
1910         this->close();
1911#endif /* HAVE_GTK2 */
1912    }
1913  else if (this->changeOption)
1914    {
1915#ifdef HAVE_GTK2
1916      changeOption->setValue(gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->widget)));
1917#endif /* HAVE_GTK2 */
1918      this->close();
1919    }
1920  else
1921    this->close();
1922}
1923
1924/**
1925   \biref opens up the FileDialog-Window
1926*/
1927void FileDialog::open(void)
1928{
1929  isOpen = true;
1930#ifdef HAVE_GTK2
1931  gtk_widget_show_all(this->widget);
1932  gtk_grab_add(this->widget);
1933#endif /* HAVE_GTK2 */
1934}
1935
1936/**
1937   \closes the FileDialog-Window
1938*/
1939void FileDialog::close(void)
1940{
1941  this->isOpen = false;
1942#ifdef HAVE_GTK2
1943  gtk_grab_remove(this->widget);
1944  gtk_widget_hide(this->widget);
1945#endif /* HAVE_GTK2 */
1946}
1947
1948#ifdef HAVE_GTK2
1949gint FileDialog::dialogOK(GtkWidget* widget, GdkEvent* event, void* dialog)
1950{
1951  static_cast<FileDialog*>(dialog)->okEvent();
1952}
1953#else /* HAVE_GTK2 */
1954int FileDialog::dialogOK(void* widget, void* event, void* dialog){}
1955#endif /* HAVE_GTK2 */
1956
1957#ifdef HAVE_GTK2
1958gint FileDialog::dialogOpen(GtkWidget* widget, GdkEvent* event, void* dialog)
1959{
1960  static_cast<FileDialog*>(dialog)->open();
1961}
1962#else /* HAVE_GTK2 */
1963int FileDialog::dialogOpen(void* widget, void* event, void* dialog){}
1964#endif /* HAVE_GTK2 */
1965
1966#ifdef HAVE_GTK2
1967gint FileDialog::dialogClose(GtkWidget* widget, GdkEvent* event, void* dialog)
1968{
1969  static_cast<FileDialog*>(dialog)->close();
1970}
1971#else /* HAVE_GTK2 */
1972int FileDialog::dialogClose(void* widget, void* event, void* dialog){}
1973#endif /* HAVE_GTK2 */
Note: See TracBrowser for help on using the repository browser.