/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ### File Specific: main-programmer: Benjamin Grauer */ #include "orxonox_gui_gtk.h" #include #include using namespace std; // temporarily. #include "orxonox_gui_flags.h" extern Window* orxonoxGUI; extern OrxonoxGuiFlags* flags; /** \brief Initializes the Guis GTK-stuff. \param argc the argument count. \param argv The Argument strings. */ bool initGUI(int argc, char *argv[]) { #ifdef HAVE_GTK2 #ifdef HAVE_GTHREAD PRINTF(3)("Initializing the ThreadSystem of the GUI\n"); g_thread_init(NULL); gdk_threads_init(); #endif /* HAVE_GTHREAD */ gtk_init(&argc, &argv); gtk_rc_parse( "rc" ); #endif /* HAVE_GTK2 */ } /** \brief enters the GUI's main-loop */ bool mainloopGUI(void) { #ifdef HAVE_GTK2 gdk_threads_enter(); gtk_main(); gdk_threads_leave(); delete Window::mainWindow; #else /* HAVE_GTK2 */ char boolAns = 'y'; char ans[10]; while(true) { PRINT(0)(" Listing all the Orxonox Options: \n"); PRINT(0)(" #############################\n"); Window::mainWindow->walkThrough(Widget::listOptionsAndGroups, 1); PRINT(0)("\nDo you want change any of the above values now? [Yn] "); cin >>boolAns ; if (boolAns =='n' || boolAns=='N') break; PRINT(0)("\n Listing all groups\n"); PRINT(0)(" #################\n"); int groupCount = 0; Window::mainWindow->walkThrough(Widget::listGroups, &groupCount, 1); PRINT(0)("\nIn which Group? [1-%d] ", groupCount); Packer* group; while(true) { cin >> ans; int ansIp = atoi(ans); if (ansIp <= groupCount) { group = static_cast(Window::mainWindow->findGroupByNumber(&ansIp, 1)); break; } else PRINT(0)("\nChoose a smaler Number please: [1-%d] ", groupCount); } PRINT(0)("\n\nGroup: [%s]\n\n", group->groupName); int optionCount = 0; group->walkThrough(Widget::listOptions, &optionCount, 0); PRINT(0)("\nWhich Option? [1-%d] ", optionCount); Option* option; while(true) { cin >> ans; int ansIp = atoi(ans); if (ansIp <= groupCount) { option = static_cast(group->findOptionByNumber(&ansIp, 0)); break; } else PRINT(0)("\nChoose a smaler Number please: [1-%d] ", optionCount); } PRINT(0)("\n\n:: %s ::\n", option->title); option->changeOption(); // here follows the rest.... this will be nasty. //! \todo move this into the gui-gtk-file //! \todo finish it. } #endif /* HAVE_GTK2 */ } ////////////////////////////// /// DEFINING WIDGET-CLASES /// ////////////////////////////// /* WIDGET */ /** \brief constructs a Widget */ Widget::Widget(void) { next = NULL; this->title = NULL; return; } /** \brief deletes any given Widget This is still pretty crappy. */ Widget::~Widget(void) { if (this->title) { delete []this->title; } PRINTF(4)("deleting the Widget part.\n"); PRINTF(4)("deleting recursively\n"); // deleting next item if existent if (this->next) delete this->next; this->next = NULL; //! \todo not hiding widget, deleting. // this->hide(); // delete this->widget; } /** \brief sets a new Title to a Widget \param title The new Title to set to the Widget */ void Widget::setTitle(const char* title) { if (this->title) delete []this->title; this->title = new char[strlen(title)+1]; strcpy(this->title, title); } /** \brief makes the widget visible. */ void Widget::show(void) { #ifdef HAVE_GTK2 gtk_widget_show(this->widget); #endif /* HAVE_GTK2 */ } /** \brief hides the widget. */ void Widget::hide(void) { #ifdef HAVE_GTK2 gtk_widget_hide(this->widget); #endif /* HAVE_GTK2 */ } /** \brief Sets the resolution of a specific widget to the given size. \param width the width of the widget to set. \param height the height of the widget to set. */ void Widget::setSize(int width, int height) { #ifdef HAVE_GTK2 gtk_widget_set_usize(this->widget, width, height); #endif /* HAVE_GTK2 */ } /** \brief searches through widgets for a Name. */ Widget* Widget::findWidgetByName(char* name, unsigned int depth) { if (this->title && !strcmp(this->title, name)) return this; if (this->isOption < 0 && static_cast(this)->down) { Widget* tmp = static_cast(this)->down->findWidgetByName(name, depth+1); if (tmp) return tmp; } if (depth>0 && this->next) return this->next->findWidgetByName(name, depth); return NULL; } /** \brief Moves through all the Widgets downwards from this and executes the function on them. \param function must be of type void and takes a Widget* as an Input. \param depth the current depth. if > 0 then the next Widget will also be walked through. */ void Widget::walkThrough(void(*function)(Widget*), unsigned int depth) { function(this); if (this->isOption < 0) { static_cast(this)->down->walkThrough(function, depth+1); } if (this->next && depth != 0) this->next->walkThrough(function, depth); } /** \brief Moves through all the Widgets downwards from this and executes the function on them. \param function must be of type void and takes a Widget* as an Input. \param data Additional Data you want to pass to the function. \param depth the current depth. if > 0 then the next Widget will also be walked through. */ void Widget::walkThrough(void(*function)(Widget*, void*), void* data, unsigned int depth) { function(this, data); if (this->isOption < 0) { static_cast(this)->down->walkThrough(function, data, depth+1); } if (this->next && depth != 0) this->next->walkThrough(function, data, depth); } /** \brief This is for listing the options of "widget" \param widget specifies the widget that should be listed */ void Widget::listOptionsAndGroups(Widget* widget) { if (widget->isOption < 0 && static_cast(widget)->groupName) cout << "[" << static_cast(widget)->groupName << "]\n"; if (widget->isOption >= 1 && widget->isOption <= 3) cout << " " << static_cast(widget)->title <<" is : " << static_cast(widget)->value <isOption == 5) cout << " " << static_cast(widget)->title <<" is : " << static_cast(widget)->cValue <isOption >= 1 && widget->isOption <= 3) cout << " " << static_cast(widget)->title <<" is : " << static_cast(widget)->value <isOption == 5) cout << " " << static_cast(widget)->title <<" is : " << static_cast(widget)->cValue <isOption >= 1 && widget->isOption <= 3) { int* count =(int*)data; *count = *count +1; cout << *count << ": " << static_cast(widget)->title <<" is : " << static_cast(widget)->value <isOption == 5) { int* count =(int*)data; *count = *count +1; cout << *count << ": " << static_cast(widget)->title <<" is : " << static_cast(widget)->cValue < 0) { --*number; if (*number <= 0) { return this; } } if (this->isOption < 0 && static_cast(this)->down) { Widget* tmp = static_cast(this)->down->findOptionByNumber(number, depth+1); if (tmp) return tmp; } if (depth>0 && this->next) return this->next->findOptionByNumber(number, depth); return NULL; } /** \brief This is for listing the groups of "widget" \param widget specifies the widget that should be listed */ void Widget::listGroups(Widget* widget) { if (widget->isOption < 0 && static_cast(widget)->groupName) cout << "[" << static_cast(widget)->groupName << "]\n"; } /** \brief This is for listing the Groups of "widget". It also displays the n'th number found. \param widget specifies the widget that should be listed \param data the Counter, that will show the number(this function will raise it by one if a Group is fount. */ void Widget::listGroups(Widget* widget, void* data) { if (widget->isOption < 0 && static_cast(widget)->groupName) { int* count =(int*)data; *count = *count +1; cout << *count <<": [" << static_cast(widget)->groupName << "]\n"; } } /** \brief Finds a Group by a given number(the n'th Group found away from this Widget) \param number The Count of options to wait(by reference) \param depth The depth of the sarch. if 0 it will not search next pointer */ Widget* Widget::findGroupByNumber(int* number, unsigned int depth) { if (isOption < 0 && static_cast(this)->groupName) { --*number; if (*number <= 0) { return this; } } if (this->isOption < 0 && static_cast(this)->down) { Widget* tmp = static_cast(this)->down->findGroupByNumber(number, depth+1); if (tmp) return tmp; } if (depth>0 && this->next) return this->next->findGroupByNumber(number, depth); return NULL; } /** \brief This is for setting the option of "widget" \param widget specifies the widget that should be set. */ void Widget::setOptions(Widget* widget) { if (widget->isOption >= 1) static_cast(widget)->redraw(); } /** \brief Walks through all the Flags given at startuptime. */ void Widget::flagCheck(Widget* widget, void* flagName) { if (widget->isOption>=1) { Option* option =(Option*)widget; char* name =(char*)flagName; char* value = NULL; bool found = false; // check if long flag matches if ((option->flagName && strlen(name)>2 && !strncmp(name+2, option->flagName, strlen(option->flagName)) &&(name[strlen(option->flagName)+2] == '\0' || name[strlen(option->flagName)+2] == '=') )) { found = true; if (name[strlen(option->flagName)+2] == '=') { value = name+strlen(option->flagName)+3; } } else if (option->flagNameShort && strlen(name)>1 && !strncmp(name+1, option->flagNameShort, strlen(option->flagNameShort))&&(name[strlen(option->flagNameShort)+1] == '\0' || name[strlen(option->flagNameShort)+1] == '=')) // check if short flag matches { found = true; if (name[strlen(option->flagNameShort)+1] == '=') { value = name+strlen(option->flagNameShort)+2; } } if (found) { PRINT(3)("found matching Flag %s\n", name); if (value) { PRINT(3)("with Value %s\n", value); option->value = atoi(value); } else { option->value = !option->defaultValue; } option->redraw(); } } } #ifdef HAVE_GTK2 /** \brief Connect any signal to any given Sub-widget */ gulong Widget::connectSignal(char* event, gint(*signal)(GtkWidget*, GdkEvent*, void *)) { return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), NULL); } /** \brief Connect a signal with additionally passing the whole Object */ gulong Widget::connectSignal(char* event, gint(*signal)( GtkWidget*, Widget *)) { return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), this); } /** \brief Connect a signal with additionally passing a whole external Object */ gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEvent*, void *)) { return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj); } /** \brief Connect a signal with additionally passing a whole external Object */ gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, void *)) { return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj); } /** \brief Connect a signal with additionally passing a whole external Object */ gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEventKey*, void *)) { return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj); } void Widget::disconnectSignal(gulong signalID) { g_signal_handler_disconnect(G_OBJECT(this->widget), signalID); } /** \brief Signal that does absolutely nothing \param widget The widget that initiated the Signal \param event The event-type. \param nothing nothin. */ gint Widget::doNothingSignal(GtkWidget *widget, GdkEvent* event, void* nothing) { } #endif /* HAVE_GTK2 */ //void deleteWidget(Widget* lastWidget) /* PACKERS */ /** \brief Constructs a Packer */ Packer::Packer(void) { this->down = NULL; this->groupName = NULL; } /** \brief Destroys a Packer. */ Packer::~Packer(void) { PRINTF(4)("deleting the Packer part.\n"); if (this->groupName) delete []this->groupName; //deleting recursively. if (this->down) delete this->down; this->down = NULL; } /** \brief Sets the group name under which all the lower widgets of this will be saved. \param name The name of the group. */ void Packer::setGroupName(char* name) { if (this->groupName) delete []this->groupName; this->groupName = new char[strlen(name)+1]; strcpy(this->groupName, name); } /** \brief Retrieves the group name under which all the lower widgets of this will be saved. \returns name The name of the group. */ char* Packer::getGroupName(void) { return this->groupName; } /* CONTAINERS */ /** \brief Initializes a Container. sets the Container-Specific defaults. */ Container::Container(void) { this->isOption = -1; } /** \brief Destroys a Container. */ Container::~Container(void) { PRINTF(4)("deleting the Container part.\n"); } /** \briefFills a Container with lowerWidget. \param lowerWidget the Widget that should be filled into the Container. It does this by filling up the down pointer only if down points to NULL. */ void Container::fill(Widget *lowerWidget) { if (this->down == NULL) { #ifdef HAVE_GTK2 gtk_container_add(GTK_CONTAINER(this->widget), lowerWidget->widget); #endif /* HAVE_GTK2 */ this->down = lowerWidget; } else PRINTF(1)("!!error!! You try to put more than one Widget into a Container. \nNot including this item.\nThis is only possible with Boxes.\n"); } // gtk_container_set_border_width(GTK_CONTAINER(widget), 5); /* WINDOW */ Window* Window::mainWindow = NULL; /** \brief Adds a new Window Windows to the List of Windows. \param windowToAdd The Windows that should be added to the List \todo this instead of windowToAdd(possibly) */ void Window::addWindow(Window* windowToAdd) { if (!mainWindow) { mainWindow = windowToAdd; return; } Widget* tmpWindow = mainWindow; while(tmpWindow->next) tmpWindow = tmpWindow->next; tmpWindow->next = windowToAdd; return; } /** \brief Creating a new Window without a Name */ Window::Window(void) { this->init(); } /** \brief Creating a Window with a name \param windowName the name the window should get. */ Window::Window(char* windowName) { this->init(); this->setTitle(windowName); } /** \brief Destructs a Window. */ Window::~Window(void) { if (this->title) PRINTF(3)("deleting the Window: %s\n", this->title); else PRINTF(3)("deleting the Window.\n"); // this->hide(); } /** \brief initializes a new Window */ void Window::init(void) { if (!mainWindow) mainWindow = this; isOpen = false; #ifdef HAVE_GTK2 widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_policy(GTK_WINDOW(widget), TRUE, TRUE, TRUE); #if !defined(__WIN32__) // gtk_window_set_decorated(GTK_WINDOW(widget), FALSE); #endif gtk_container_set_border_width(GTK_CONTAINER(widget), 3); #endif /* HAVE_GTK2 */ } /** \brief Shows all Widgets that are included within this->widget. */ void Window::showall(void) { if (!this->isOpen) { // printf("showall\n"); #ifdef HAVE_GTK2 gtk_widget_show_all(this->widget); #endif /* HAVE_GTK2 */ this->isOpen = true; } else { // printf("showone\n"); #ifdef HAVE_GTK2 gtk_widget_show(this->widget); #endif /* HAVE_GTK2 */ } } /** \brief Set The Window-title to title \param title title the Window should get. */ void Window::setTitle(const char* title) { if (this->title) delete []this->title; this->title = new char[strlen(title)+1]; strcpy(this->title, title); #ifdef HAVE_GTK2 gtk_window_set_title(GTK_WINDOW(widget), title); #endif /* HAVE_GTK2 */ } /** \brief opens up a Window and fixes the Focus to it */ void Window::open(void) { if (this != mainWindow) { isOpen = true; #ifdef HAVE_GTK2 gtk_widget_show_all(this->widget); gtk_grab_add(this->widget); #endif /* HAVE_GTK2 */ } } /** \brief closes up a Window and removes the Focus from it */ void Window::close(void) { if (this != mainWindow) { this->isOpen = false; #ifdef HAVE_GTK2 gtk_grab_remove(this->widget); gtk_widget_hide(this->widget); #endif /* HAVE_GTK2 */ } } #ifdef HAVE_GTK2 /** \brief opens up a window(not topmost Window). this is the Signal that does it. !!SIGNALS ARE STATIC!! \param widget the widget that did it. \param event the event that did it. \param window the Window that should be opened */ gint Window::windowOpen(GtkWidget *widget, GdkEvent* event, void* window) { static_cast(window)->open(); } /** \brief closes a window(not topmost Window). this is the Signal that does it. !!SIGNALS ARE STATIC!! \param widget the widget that did it! \param event the event that did it! \param window the Window that should be closed */ gint Window::windowClose(GtkWidget *widget, GdkEvent* event, void* window) { static_cast(window)->close(); } #endif /* HAVE_GTK2 */ /* FRAME */ /** \brief Creates a new Frame without a name */ Frame::Frame(void) { this->init(); } /** \brief Creates a new Frame with name title */ Frame::Frame(char* title) { this->init(); this->setTitle(title); } /** \brief destrcucts a Frame */ Frame::~Frame(void) { if (this->title) PRINTF(3)("deleting the Frame: %s\n", this->title); else PRINTF(3)("deleting the Frame.\n"); } /** \brief Initializes a new Frame with default settings */ void Frame::init(void) { #ifdef HAVE_GTK2 this->widget = gtk_frame_new(""); gtk_container_set_border_width(GTK_CONTAINER(this->widget), 3); #endif /* HAVE_GTK2 */ } /** \brief Sets the Frames name to title \param title The title the Frame should get. */ void Frame::setTitle(const char* title) { if (this->title) delete []this->title; this->title = new char[strlen(title)+1]; strcpy(this->title, title); #ifdef HAVE_GTK2 gtk_frame_set_label(GTK_FRAME(widget), title); #endif /* HAVE_GTK2 */ } // EVENTBOX // /** \brief Creates a new EventBox with default settings. */ EventBox::EventBox(void) { this->init(); } /** \brief Creates a new EventBox with name title \param title title the Eventbox should get(only data-structure-internal) */ EventBox::EventBox(char* title) { this->init(); this->setTitle(title); } /** \brief destructs an EventBox. */ EventBox::~EventBox(void) { if (this->title) PRINTF(3)("deleting the EventBox: %s\n", this->title); else PRINTF(3)("deleting the EventBox.\n"); } /** \brief Initializes a new EventBox */ void EventBox::init(void) { this->isOption = -1; #ifdef HAVE_GTK2 this->widget = gtk_event_box_new(); gtk_container_set_border_width(GTK_CONTAINER(this->widget), 3); #endif /* HAVE_GTK2 */ } /* BOX */ /** \brief Creates a new horizontal Box */ Box::Box(void) { this->init('h'); } /** \brief Creates a new Box of type boxtype \param boxtype if 'v' the Box will be vertically, if 'h' the Box will be horizontally */ Box::Box(char boxtype) { this->init(boxtype); } /** \brief destructs a Box. */ Box::~Box(void) { if (this->title) PRINTF(3)("deleting the Box: %s\n", this->title); else PRINTF(3)("deleting the Box.\n"); } /** \brief Initializes a new Box with type boxtype \param boxtype see Box(char boxtype) */ void Box::init(char boxtype) { this->isOption = -2; #ifdef HAVE_GTK2 if (boxtype == 'v') { this->widget = gtk_vbox_new(FALSE, 0); } else { this->widget = gtk_hbox_new(FALSE, 0); } #endif /* HAVE_GTK2 */ } /** \brief Fills a box with a given Widget. \param lowerWidget the next Widget that should be appendet to this Box 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 */ void Box::fill(Widget* lowerWidget) { #ifdef HAVE_GTK2 gtk_box_pack_start(GTK_BOX(this->widget), lowerWidget->widget, TRUE, TRUE, 0); #endif /* HAVE_GTK2 */ if (this->down == NULL) this->down = lowerWidget; else { Widget* tmp; tmp = this->down; while(tmp->next != NULL) { tmp = tmp->next; } tmp->next = lowerWidget; } } /* OPTION */ /** \brief Initializes a new Option. sets all Option-Specific-Values to their defaults. */ Option::Option(void) { this->value = 0; this->flagName = NULL; this->flagNameShort = NULL; this->saveable = false; this->defaultValue = 0; } /** \brief Destroys an Option. */ Option::~Option(void) { PRINTF(4)("deleting the Option Part.\n"); if (this->flagName) delete []this->flagName; if (this->flagNameShort) delete []this->flagNameShort; } /** \brief This sets The FlagName of an Option and defines its default Values !! Options will be saved if flagname is different from NULL !! \param flagname the Name that will be displayed in the output \param defaultvalue the default Value for this Option(see definition of defaultvalue */ void Option::setFlagName(char* flagname, int defaultvalue) { if (this->flagName) delete this->flagName; this->flagName = new char [strlen(flagname)+1]; strcpy(this->flagName, flagname); this->defaultValue = defaultvalue; // cout << "Set Flagname of " << this->title << " to " << flagname << endl; } /** \brief see Option::setFlagName(char* flagname, int defaultvalue) \param flagname the Name that will be displayed in the output \param defaultvalue the default Value for this Option(see definition of defaultvalue \param flagnameshort a short flagname to be displayed in the output */ void Option::setFlagName(char* flagname, char* flagnameshort, int defaultvalue) { if (this->flagName) delete []this->flagName; this->flagName = new char [strlen(flagname)+1]; strcpy(this->flagName, flagname); if (this->flagNameShort) delete []this->flagNameShort; this->flagNameShort = new char [strlen(flagnameshort)+1]; strcpy(this->flagNameShort, flagnameshort); this->defaultValue = defaultvalue; // cout << "Set Flagname of " << this->title << " to " << flagname << endl; } /** \brief Sets the saveable-state of the option to true. */ void Option::saveability(void) { this->saveable = true; } /** \brief Sets the saveable-state of the option. \param isSaveable the saveable-state to set. */ void Option::saveability(bool isSaveable) { this->saveable = isSaveable; } /** \brief saves an Option \returns the String that should be saved. this is a default Option save */ char* Option::save(void) { char* value = new char [10]; sprintf (value, "%d", this->value); return value; } /** \brief loads an Option from of its loadString \param loadString the string from which to load the data from */ void Option::load(char* loadString) { this->value = atoi(loadString); PRINT(3)("Loading %s: %s %d\n", this->title, loadString, value); this->redraw(); } /** \returns The saveable-state. */ bool Option::isSaveable(void) { return this->saveable; } #ifdef HAVE_GTK2 /** \brief Signal OptionChange writes the Value from the Slider to its Object-Database. \param widget The widget(Slider) that has a changed Value \param slider the Slider-Object that should receive the change. */ gint Option::OptionChange(GtkWidget *widget, Widget* option) { static_cast(option)->changeOption(); flags->setTextFromFlags(Window::mainWindow); //// must be different !!! } #endif /* HAVE_GTK2 */ /* BUTTON */ /** \brief Creates a new Button with a buttonname \param buttonname sets the Name of the Button */ Button::Button(char* buttonname) { this->init(); this->setTitle(buttonname); } /** \brief destructs a Button. */ Button::~Button(void) { if (this->title) PRINTF(3)("deleting the Label: %s\n", this->title); else PRINTF(3)("deleting the Label.\n"); } /** \brief Initializes a new Button */ void Button::init(void) { isOption = 0; #ifdef HAVE_GTK2 widget = gtk_button_new_with_label(""); #endif /* HAVE_GTK2 */ } /** \brief Sets a new name to the Button \param title The name the Button should get */ void Button::setTitle(const char *title) { if (this->title) delete []this->title; this->title = new char[strlen(title)+1]; strcpy(this->title, title); #ifdef HAVE_GTK2 gtk_button_set_label(GTK_BUTTON(widget), title); #endif /* HAVE_GTK2 */ } /** \brief redraws the Button not implemented yet */ void Button::redraw(void) { } /** \brief Button can not be changed, optionChange is empty) \todo Actions for non-GTK-mode */ void Button::changeOption(void) { // This will possibly be used for ACTIONS ! } /* CHECKBUTTON */ /** \brief Creates a new CheckButton with an ame \param buttonname The name the CheckButton should display. */ CheckButton::CheckButton(char* buttonname) { this->init(); this->setTitle(buttonname); #ifdef HAVE_GTK2 this->connectSignal("clicked", this->OptionChange); #endif /* HAVE_GTK2 */ } /** \brief destructs a CheckButton. */ CheckButton::~CheckButton(void) { if (this->title) PRINTF(3)("deleting the CheckButton: %s\n", this->title); else PRINTF(3)("deleting the CheckButton.\n"); } /** \brief Initialize a new CheckButton with default settings */ void CheckButton::init(void) { this->isOption = 1; #ifdef HAVE_GTK2 this->widget = gtk_check_button_new_with_label(""); #endif /* HAVE_GTK2 */ } /** \brief Sets a new Title to a CheckButton \param title The new Name the CheckButton should display. */ void CheckButton::setTitle(const char* title) { if (this->title) delete []this->title; this->title = new char[strlen(title)+1]; strcpy(this->title, title); #ifdef HAVE_GTK2 gtk_button_set_label(GTK_BUTTON(widget), title); #endif /* HAVE_GTK2 */ } bool CheckButton::isActive(void) { #ifdef HAVE_GTK2 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); #endif /* HAVE_GTK2 */ } /** \brief Changed the Option, call this Function */ void CheckButton::changeOption(void) { #ifdef HAVE_GTK2 this->value =(int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->widget)); #else /* HAVE_GTK2 */ char tmpChar[20]; cout << "\nPlease give me a new value for " << this->title << " [0,1](default:" << this->defaultValue << "): "; cin >> tmpChar; if ((this->value = atoi(tmpChar))=!0) this->value = 1; #endif /* HAVE_GTK2 */ cout << this->title << " set to: " << this->value << endl; } /** \brief Redraws the CheckButton(if option has changed). Example: if new settings are loaded the Button must be redrawn for the GUI to display that Change */ void CheckButton::redraw(void) { #ifdef HAVE_GTK2 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(this->widget), value); #endif /* HAVE_GTK2 */ } /* SLIDER */ /** \brief Creates a new Slider \param slidername The data-structure-name of the slider. \param start The minimal Value of the slider. \param end The maximal Value of the slider. */ Slider::Slider(char* slidername, int start, int end) { this->init(start, end); this->setValue(start); this->setTitle(slidername); #ifdef HAVE_GTK2 this->connectSignal("value_changed", this->OptionChange); #endif /* HAVE_GTK2 */ } /** \brief destructs a Slider. */ Slider::~Slider(void) { if (this->title) PRINTF(3)("deleting the Slider: %s\n", this->title); else PRINTF(3)("deleting the Slider.\n"); } /** \brief Initializes a Slider with start and end Values params: see Slider::Slider(char* slidername, int start, int end) */ void Slider::init(int start, int end) { this->isOption = 2; this->start = start; this->end = end; #ifdef HAVE_GTK2 widget = gtk_hscale_new_with_range(this->start, this->end, 5); #endif /* HAVE_GTK2 */ } /** \brief Setting a new value to the Slider. Maybe you also require a Slider::redraw() for this to display */ void Slider::setValue(int value) { this->value = value; } /** \brief Redraws the widget Example: see void CheckButton::redraw(void) */ void Slider::redraw(void) { #ifdef HAVE_GTK2 gtk_range_set_value(GTK_RANGE(this->widget), value); #endif /* HAVE_GTK2 */ } /** \brief Changed the Option, call this Function */ void Slider::changeOption(void) { #ifdef HAVE_GTK2 this->value =(int)gtk_range_get_value(GTK_RANGE(this->widget)); #else /* HAVE_GTK2 */ char tmpChar[20]; cout << "\nPlease give me a new value for " << this->title << " [" <start << "-" << this->end << "](default:" << this->defaultValue << "): "; cin >> tmpChar; if ((this->value = atoi(tmpChar))> this->end) this->value = this->end; if (this->value <= this->start) this->value = this->start; #endif /* HAVE_GTK2 */ cout << this->title << " set to: " << this->value << endl; } /* MENU */ /** \brief constructs a new Menu, without adding any items to it. \param menuName the Name the Menu gets. */ Menu::Menu(const char* menuName) { this->init(); this->setTitle(menuName); } /** \brief Creates a Menu-Item-list out of multiple input. !! Consider, that the last input argument has to be "lastItem" for this to work!! \param menuname The Database-Name of this Menu \param ... items to be added to this Menu. !! Consider, that the last input argument has to be "lastItem" for this to work!! */ Menu::Menu(char* menuname, ...) { this->init(); this->setTitle(menuname); va_list itemlist; //!< The list to readin multiple Options. char *itemName; va_start(itemlist, menuname); while(strcmp(itemName = va_arg(itemlist, char*), "lastItem")) { this->addItem(itemName); } va_end(itemlist); } /** \brief destructs a Menu. */ Menu::~Menu(void) { if (this->title) PRINTF(3)("deleting the Menu: %s\n", this->title); else PRINTF(3)("deleting the Menu.\n"); //! \todo destroy menu this->currItem = this->firstItem; while(this->currItem) { delete []this->currItem->name; /* #ifdef HAVE_GTK2 free(this->currItem->item); #endif /* HAVE_GTK2 */ MenuItem* tmpItem = this->currItem; this->currItem = this->currItem->next; delete tmpItem; } } /** \brief Initializes a new Menu with no items */ void Menu::init(void) { this->isOption = 2; this->firstItem = NULL; #ifdef HAVE_GTK2 this->widget = gtk_option_menu_new(); this->menu = gtk_menu_new(); gtk_option_menu_set_menu(GTK_OPTION_MENU(this->widget), menu); this->connectSignal("changed", this->OptionChange); #endif /* HAVE_GTK2 */ } /** \brief saves the Label of the Menu \returns the name of the selected Menu-Item */ char* Menu::save(void) { MenuItem* tmpItem = this->firstItem; for (int i = 0; ivalue; i++) tmpItem = tmpItem->next; return tmpItem->name; } /** \brief loads a Menu from of its loadString \param loadString the string from which to load the data from */ void Menu::load(char* loadString) { MenuItem* tmpItem = firstItem; bool foundItem = false; while (tmpItem) { if (!strcmp(loadString, tmpItem->name)) {foundItem = true; break;} tmpItem = tmpItem->next; } if (foundItem) this->value = tmpItem->itemNumber; else { this->value = 0; PRINTF(2)("Sorry, but %s has not been found in the Itemlist of %s\n", loadString, this->title); } PRINTF(3)( "Loading %s: setting to %d\n", this->title, this->value); this->redraw(); } /** \brief appends a new Item to the Menu-List. \param itemName the itemName to be appendet. */ void Menu::addItem(char* itemName) { if (!this->firstItem) { this->firstItem = this->currItem = new MenuItem; this->currItem->itemNumber = 0; } else { int tmpI = this->currItem->itemNumber; this->currItem = this->currItem->next = new MenuItem; this->currItem->itemNumber = tmpI+1; } this->currItem->name = new char[strlen(itemName)+1]; strcpy(this->currItem->name, itemName); #ifdef HAVE_GTK2 this->currItem->item = gtk_menu_item_new_with_label(itemName); gtk_menu_shell_append(GTK_MENU_SHELL(this->menu), this->currItem->item); #endif /* HAVE_GTK2 */ this->currItem->next = NULL; } /** \brief Redraws the widget Example: see void CheckButton::redraw(void) */ void Menu::redraw(void) { #ifdef HAVE_GTK2 gtk_option_menu_set_history(GTK_OPTION_MENU(this->widget), this->value); #endif /* HAVE_GTK2 */ } /** \brief Changed the Option, call this Function */ void Menu::changeOption(void) { #ifdef HAVE_GTK2 this->value =(int)gtk_option_menu_get_history(GTK_OPTION_MENU(this->widget)); #else /* HAVE_GTK2 */ char tmpChar[20]; cout << "\nPlease give me a new value for " << this->title << "(default:" << this->defaultValue << "): "; cin >> tmpChar; this->value = atoi(tmpChar); #endif /* HAVE_GTK2 */ cout << this->title << " set to: " << this->value << endl; } /* OPTION LABEL */ /** \brief Creates a new OptionLabel with a LabelName and a Value. \param label The name of the OptionLabel. \param value The Value of the OptionLabel(what will be displayed). */ OptionLabel::OptionLabel(char* label, char* value) { this->init(); this->setTitle(label); this->setValue(value); } /** \brief destructs an OptionLabel. */ OptionLabel::~OptionLabel(void) { if (this->title) PRINTF(3)("deleting the OptionLabel: %s\n", this->title); else PRINTF(3)("deleting the OptionLabel.\n"); if (this->cValue) delete []this->cValue; } /** \brief Initializes an OptionLabel */ void OptionLabel::init(void) { this->isOption = 5; cValue = NULL; #ifdef HAVE_GTK2 this->widget = gtk_label_new(""); #endif /* HAVE_GTK2 */ } /** \brief Updates the value of an OptionLabel \param newValue The new Name that should be displayed. */ void OptionLabel::setValue(char* newValue) { if (this->cValue) delete []this->cValue; this->cValue = new char [strlen(newValue)+1]; strcpy(this->cValue, newValue); #ifdef HAVE_GTK2 gtk_label_set_text(GTK_LABEL(this->widget), this->cValue); #endif /* HAVE_GTK2 */ } /** \brief Redraws an OptionLabel(not implemented yet, but it works). */ void OptionLabel::redraw(void) { #ifdef HAVE_GTK2 gtk_label_set_text(GTK_LABEL(widget), title); #endif /* HAVE_GTK2 */ } /** \brief Changed the Option, call this Function */ void OptionLabel::changeOption(void) { #ifdef HAVE_GTK2 this->cValue =(char*)gtk_label_get_text(GTK_LABEL(this->widget)); #else /* HAVE_GTK2 */ cout << "\nPlease give me a new input for " << this->title << ": "; cin >> this->cValue; #endif /* HAVE_GTK2 */ cout << this->title << " set to: " << this->cValue << endl; } /** \brief creates the Optionlabel save-string \returns the String to save. */ char* OptionLabel::save(void) { return cValue; } /** \brief loads an Option from of its loadString \param loadString the string from which to load the data from */ void OptionLabel::load(char* loadString) { PRINTF(3)( "Loading %s: setting to %s\n", this->title, loadString); this->setValue(loadString); } /** \brief Creates a new default Label with no Text. You migth consider adding Label::setTitle with this. */ Label::Label(void) { this->init(); } /** \brief Creates a new Label with a Text. \param text The text to be displayed. */ Label:: Label(char* text) { this->init(); this->setTitle(text); } /** \brief destructs a Label. */ Label::~Label(void) { if (this->title) PRINTF(3)("deleting the Label: %s\n", this->title); else PRINTF(3)("deleting the Label.\n"); } /** \brief initializes a new Label */ void Label::init(void) { this->isOption = 0; #ifdef HAVE_GTK2 this->widget = gtk_label_new(""); gtk_label_set_line_wrap(GTK_LABEL(this->widget), TRUE); #endif /* HAVE_GTK2 */ } /** \brief Sets a new Text to a Label. \param text The text to be inserted into the Label. */ void Label::setTitle(char* text) { if (this->title) delete []this->title; this->title = new char[strlen(text)+1]; strcpy(this->title, text); #ifdef HAVE_GTK2 gtk_label_set_text(GTK_LABEL(this->widget), this->title); #endif /* HAVE_GTK2 */ } /** \brief ereases the Text of a Label */ void Label::ereaseText(void) { this->setTitle(""); } /** \brief appends some Text to a Label \param textToAppend The text that will be appended to this Label */ void Label::appendText(char* textToAppend) { if (this->title) { char* tmpTitle = new char[strlen(this->title)+strlen(textToAppend)+1]; strcpy(tmpTitle, title); strcat(tmpTitle, textToAppend); delete []this->title; this->title = tmpTitle; } else { this->title = new char[strlen(textToAppend)]; } #ifdef HAVE_GTK2 gtk_label_set_text(GTK_LABEL(this->widget), title); #endif /* HAVE_GTK2 */ } /** \brief Appends some integer to the Label \param intToAppend The Int that will be added. it does this by just converting the int into a char* and send it to appendText */ void Label::appendInt(int intToAppend) { char append [32]; sprintf(append, "%d", intToAppend); this->appendText(append); } /** \brief get the Text of a Label \return The Text the Label holds. */ char* Label::getText(void) { return this->title; } /** \brief Creates a new ProgressBar. */ ProgressBar::ProgressBar(void) { this->init(); } /** \brief Creates a new ProgressBar. \param label The name you want to get the ProgressBar. */ ProgressBar::ProgressBar(char* label) { this->init(); this->setTitle(label); } /** \brief destructs a ProgressBar */ ProgressBar::~ProgressBar(void) { if (this->title) PRINTF(3)("deleting the ProgressBar: %s\n", this->title); else PRINTF(3)("deleting the ProgressBar.\n"); } /** \brief Initializes a ProgressBar */ void ProgressBar::init(void) { this->isOption = 0; this->progress = 0.0; this->totalSize = 0.0; #ifdef HAVE_GTK2 this->adjustment =(GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0); this->widget = gtk_progress_bar_new_with_adjustment(this->adjustment); #endif /* HAVE_GTK2 */ } /** \brief Sets the Total size of the Bar.(ex. The maximum one can download) */ void ProgressBar::setTotalSize(double totalSize) { this->totalSize = totalSize; } /** \brief Sets the progress maximum is this->totalSize */ void ProgressBar::setProgress(double progress) { this->progress = progress; if (this->progress > this->totalSize) this->progress = this->totalSize; #ifdef HAVE_GTK2 gtk_progress_set_value(GTK_PROGRESS(widget), this->progress*100.0/this->totalSize); #endif /* HAVE_GTK2 */ PRINTF(3)("Progress: %f\n", this->progress*100.0/this->totalSize); } /** \brief returns the Progress Status */ double ProgressBar::getProgress(void) { return this->progress; } /* IMAGE */ /** \brief Creates a new Image \param imagename the location of the Image on the Hard Disc */ Image::Image(char* imagename) { this->init(); if (this->title) delete []this->title; this->title = new char[strlen(imagename)+1]; strcpy(this->title, imagename); #ifdef HAVE_GTK2 widget = gtk_image_new_from_file(imagename); #endif /* HAVE_GTK2 */ } /** \brief destructs an Image. */ Image::~Image(void) { if (this->title) PRINTF(3)("deleting the Image: %s\n", this->title); else PRINTF(3)("deleting the Image.\n"); } /** \brief Initializes a new Image */ void Image::init(void) { isOption = 0; }