/* 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 #include "orxonox_gui.h" #include "orxonox_gui_video.h" #include "orxonox_gui_audio.h" #include "orxonox_gui_exec.h" #include "orxonox_gui_flags.h" #include "orxonox_gui_banner.h" #include "orxonox_gui_keys.h" Window* orxonoxGUI; OrxonoxGuiVideo* video; OrxonoxGuiAudio* audio; OrxonoxGuiExec* exec; OrxonoxGuiFlags* flags; OrxonoxGuiBanner* banner; OrxonoxGuiKeys* keys; int main( int argc, char *argv[] ) { OrxonoxGui* orxonoxgui = new OrxonoxGui(argc, argv); return 0; } /* ORXONOXGUI */ /** * Initializes the Gui */ OrxonoxGui::OrxonoxGui (int argc, char *argv[]) { gtk_init (&argc, &argv); gtk_rc_parse( "rc" ); orxonoxGUI = new Window( "Grafical OrxOnoX loader, "PACKAGE_VERSION ); orxonoxGUI->connectSignal ("destroy", orxonoxGUI->orxonox_gui_quit); orxonoxGUI->connectSignal ("delete_event", orxonoxGUI->orxonox_gui_quit); Box* windowBox = new Box ('h'); banner = new OrxonoxGuiBanner(); windowBox->fill (banner->getWidget()); Box* optionBox = new Box ('v'); Box* avBox = new Box ('h'); video = new OrxonoxGuiVideo (); avBox->fill (video->getWidget ()); audio = new OrxonoxGuiAudio (); avBox->fill (audio->getWidget ()); optionBox->fill (avBox); keys = new OrxonoxGuiKeys (); optionBox->fill (keys->getWidget ()); exec = new OrxonoxGuiExec (orxonoxGUI); optionBox->fill (exec->getWidget ()); flags = new OrxonoxGuiFlags (orxonoxGUI); optionBox->fill (flags->getWidget ()); windowBox->fill (optionBox); orxonoxGUI->fill (windowBox); flags->setTextFromFlags (orxonoxGUI); exec->setFilename ("~/.orxonox.conf"); exec->readFromFile (orxonoxGUI); orxonoxGUI->walkThrough(orxonoxGUI->listOptions); orxonoxGUI->showall (); gtk_main(); } /* WIDGET */ /** \brief deletes any given Widget This is still pretty crappy. */ Widget::~Widget() { // cout << "hiding: " <label <<"\n"; this->hide(); // cout << "check if Packer: "<label <<"\n"; if (this->is_option < 0) { // cout << "get Down "<label <<"\n"; static_cast(this)->down->~Widget(); } // cout << "next != NULL?: " <label <<"\n"; if (this->next != NULL) this->next->~Widget(); cout << "delete Widget: " <label <<"\n"; // delete widget; } /** * Initializes a widget. * Nothing to do here. */ void Widget::init() { return; } /** * makes the widget visible. */ void Widget::show() { gtk_widget_show (this->widget); } /** * hides the widget. */ void Widget::hide() { gtk_widget_hide (this->widget); } /** \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) { gtk_widget_set_usize (this->widget, width, height); } /** * Connect any signal to any given Sub-widget */ void Widget::connectSignal (char* event, gint (*signal)(GtkWidget*, GdkEvent*, void *)) { g_signal_connect (G_OBJECT (this->widget), event, G_CALLBACK (signal), NULL); } /** * Connect a signal with additionally passing the whole Object */ void Widget::connectSignal (char* event, gint (*signal)( GtkWidget*, Widget *)) { g_signal_connect (G_OBJECT (this->widget), event, G_CALLBACK (signal), this); } /** * Connect a signal with additionally passing a whole external Object */ void Widget::connectSignal (char* event, void* extObj, gint (*signal)(GtkWidget*, GdkEvent*, void *)) { g_signal_connect (G_OBJECT (this->widget), event, G_CALLBACK (signal), extObj); } /** * 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. */ void Widget::walkThrough (void (*function)(Widget*)) { function(this); if (this->is_option < 0) { static_cast(this)->down->walkThrough (function); } if (this->next != NULL) this->next->walkThrough(function); } /** * This is for listing the option of "widget" \param widget specifies the widget that should be listed */ void Widget::listOptions (Widget* widget) { if (widget->is_option >= 1) cout << static_cast(widget)->label <<" is : " << static_cast(widget)->value <is_option >= 1) static_cast(widget)->redraw();// <<" is : " << static_cast(this)->value <down == NULL) { gtk_container_add (GTK_CONTAINER (this->widget), lowerWidget->widget); this->down = lowerWidget; } else cout << "!!error!! You try to put more than one Widget into a container.\nnot including this item."<init(); } /** * Creating a Window with a name \param windowName the name the window should get. */ Window::Window (char* windowName) { this->init(); this->setTitle (windowName); } /** *initializes a new Window */ void Window::init() { isOpen = true; is_option = -1; label = ""; this->setGroupName (""); next = NULL; down = NULL; 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); } /** * Shows all Widgets that are included within this->widget. */ void Window::showall () { isOpen = true; gtk_widget_show_all (widget); } /** * Set The Window-title to title \param title title the Window should get. */ void Window::setTitle (char* title) { label=title; gtk_window_set_title (GTK_WINDOW (widget), title); } /** * Quits the orxonox_GUI. * This can be called as a Signal and is therefor static \param widget The widget that called this function \param event the event that happened to execute this function \param data some data passed with the Signal */ gint Window::orxonox_gui_quit (GtkWidget *widget, GdkEvent *event, gpointer data) { if (exec->shouldsave()) exec->writeToFile (orxonoxGUI); gtk_main_quit(); return FALSE; } /* FRAME */ /** * Creates a new Frame without a name */ Frame::Frame (void) { this->init(); } /** * Creates a new Frame with name title */ Frame::Frame (char* title) { this->init(); this->setTitle(title); } /** * Initializes a new Frame with default settings */ void Frame::init() { is_option = -1; label = ""; this->setGroupName(""); next = NULL; down = NULL; widget = gtk_frame_new (""); gtk_container_set_border_width (GTK_CONTAINER (widget), 3); } /** * Sets the Frames name to title \param title The title the Frame should get. */ void Frame::setTitle (char* title) { label = title; gtk_frame_set_label (GTK_FRAME (widget), title); } // EVENTBOX // /** * Creates a new EventBox with default settings. */ EventBox::EventBox () { this->init(); } /** * 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); } /** * Initializes a new EventBox */ void EventBox::init(void) { is_option = -1; label = "eventBox"; this->setGroupName(""); next = NULL; down = NULL; widget = gtk_event_box_new (); gtk_container_set_border_width (GTK_CONTAINER (widget), 3); } /** * Sets the Title of the EventBox (not implemented) \param title Name the EventBox should get (only datastructure-internal). */ void EventBox::setTitle (char* title) { label = title; } /* BOX */ /** * Creates a new horizontal Box */ Box::Box (void) { this->init('h'); } /** * 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); } /** * Initializes a new Box with type boxtype \param boxtype see Box(char boxtype) */ void Box::init(char boxtype) { is_option = -2; label = "box"; this->setGroupName(""); next = NULL; down = NULL; if (boxtype == 'v') { widget = gtk_vbox_new (FALSE, 0); } else { widget = gtk_hbox_new (FALSE, 0); } } /** * Fills a box with a given Widget. * 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 \param lowerWidget the next Widget that should be appendet to this Box */ void Box::fill (Widget *lowerWidget) { /** * Fill a Box with its lowerwidgets */ gtk_box_pack_start (GTK_BOX (this->widget), lowerWidget->widget, TRUE, TRUE, 0); if (this->down == NULL) this->down = lowerWidget; else { Widget* tmp; tmp = this->down; while (tmp->next != NULL) { tmp = tmp->next; } tmp->next = lowerWidget; } } /* IMAGE */ /** * Creates a new Image \param imagename the location of the Image on the Hard Disc */ Image::Image (char* imagename) { this->init(); widget = gtk_image_new_from_file (imagename); label = imagename; } /** * Initializes a new Image */ void Image::init() { is_option = 0; label = ""; next = NULL; } /* OPTION */ /** * Initializes a new Option: nothing to do here */ void Option::init() { return; } /** * This sets The FlagName of an Option and defines its default Values !! Options will be saved if flagname is different from "" !! \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) { flag_name = flagname; default_value = defaultvalue; cout << "Set Flagname of " << label << " to " << flagname << endl; } /** * 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) { flag_name = flagname; flag_name_short = flagnameshort; default_value = defaultvalue; cout << "Set Flagname of " << label << " to " << flagname << endl; } /* BUTTON */ /** * Creates a new Button with a buttonname \param buttonname sets the Name of the Button */ Button::Button(char* buttonname) { this->init(); this->setTitle(buttonname); } /** * Initializes a new Button */ void Button::init(void) { is_option = 0; value = 0; next = NULL; label =""; flag_name = ""; flag_name_short = ""; default_value = 0; widget = gtk_button_new_with_label (""); } /** * Sets a new name to the Button \param title The name the Button should get */ void Button::setTitle (char *title) { label = title; gtk_button_set_label (GTK_BUTTON(widget), title); } /** * redraws the Button * not implemented yet */ void Button::redraw () { } /* CHECKBUTTON */ /** * Creates a new CheckButton with an ame \param buttonname The name the CheckButton should display. */ CheckButton::CheckButton (char* buttonname) { this->init(); this->setTitle(buttonname); this->connectSignal ("clicked", this->OptionChange); } /** * Initiali a new CheckButton with default settings */ void CheckButton::init(void) { is_option = 1; value = 0; next = NULL; label = ""; flag_name = ""; flag_name_short = ""; default_value = 0; widget = gtk_check_button_new_with_label (""); } /** * Sets a new Title to a CheckButton \param title The new Name the CheckButton should display. */ void CheckButton::setTitle(char* title) { label = title; gtk_button_set_label(GTK_BUTTON(widget), title); } /** * Signal OptionChange writes the Value from the CheckButton to its Object-Database. \param widget The widget(CheckButton) that has a changed Value \param checkbutton the CheckButton-Object that should receive the change. */ gint CheckButton::OptionChange (GtkWidget *widget, Widget* checkbutton) { static_cast(checkbutton)->value = (int)gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON ((CheckButton*)checkbutton->widget)); flags->setTextFromFlags(orxonoxGUI); cout << static_cast(checkbutton)->label << " set to: " << static_cast(checkbutton)->value << endl; } /** * 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 () { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value); } /* SLIDER */ /** * 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); this->connectSignal ("value_changed", this->OptionChange); } /** * 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) { is_option = 2; value = 0; next = NULL; label = ""; flag_name = ""; flag_name_short = ""; default_value = 0; widget = gtk_hscale_new_with_range (start, end, 5); } /** * Sets a new Title to the Slider \param title The new Name of the slider */ void Slider::setTitle(char* title) { label = title; } /** * 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; } /** * 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 Slider::OptionChange (GtkWidget *widget, Widget* slider) { static_cast(slider)->value = (int)gtk_range_get_value (GTK_RANGE ((Slider*)slider->widget)); flags->setTextFromFlags(orxonoxGUI); cout << static_cast(slider)->label << " set to: "<< static_cast(slider)->value << endl; } /** * Redraws the widget * Example: see void CheckButton::redraw () */ void Slider::redraw () { gtk_range_set_value (GTK_RANGE (widget), value); } /* MENU */ /** * 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); char *itemName; va_start (itemlist, menuname); while (strcmp (itemName = va_arg (itemlist, char*), "lastItem")) { this->addItem(itemName); } va_end(itemlist); gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu); this->connectSignal ("changed", this->OptionChange); } /** * Initializes a new Menu with no items */ void Menu::init(void) { is_option = 2; value = 0; next = NULL; flag_name = ""; flag_name_short = ""; default_value = 0; widget = gtk_option_menu_new (); menu = gtk_menu_new (); } /** * Sets the Database-Name of this Menu \param title Database-Name to be set. */ void Menu::setTitle(char* title) { label = title; } /** * appends a new Item to the Menu-List. \param itemName the itemName to be appendet. */ void Menu::addItem (char* itemName) { item = gtk_menu_item_new_with_label (itemName); gtk_menu_shell_append(GTK_MENU_SHELL (menu), item); } /** * Signal OptionChange writes the Value from the Menu to its Object-Database. \param widget The widget(Menu) that has a changed Value \param menu the Menu-Object that should receive the change. */gint Menu::OptionChange (GtkWidget *widget, Widget* menu) { static_cast(menu)->value = (int)gtk_option_menu_get_history (GTK_OPTION_MENU (menu->widget)); flags->setTextFromFlags(orxonoxGUI); cout << static_cast(menu)->label << " changed to : " << static_cast(menu)->value << endl; } /** * Redraws the widget * Example: see void CheckButton::redraw () */ void Menu::redraw () { gtk_option_menu_set_history (GTK_OPTION_MENU (widget), value); } /** * Creates a new default Label with no Text. * You migth consider adding Label::setTitle with this. */ Label:: Label () { this->init(); } /** * Creates a new Label with a Text. \param text The text to be displayed. */ Label:: Label (char* text) { this->init(); this->setText(text); } /** * initializes a new Label */ void Label::init(void) { is_option = 0; label = ""; next = NULL; widget = gtk_label_new (""); gtk_label_set_line_wrap (GTK_LABEL(widget), TRUE); } /** * Sets a new Text to a Label. \param text The text to be inserted into the Label. */ void Label::setText (char * text) { label = text; gtk_label_set_text (GTK_LABEL (this->widget), text); } /** * get the Text of a Label \return The Text the Label holds. */ char* Label::getText () { return ((char*)gtk_label_get_text (GTK_LABEL (this->widget))); }