Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: cooler incrementations

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