Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8310 was 8145, checked in by bensch, 18 years ago

trunk: merged the gui back
merged with command:
svn merge -r8114:HEAD https://svn.orxonox.net/orxonox/branches/gui .
→ no conflicts

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