diff options
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | src/gui/chat.cpp | 1 | ||||
-rw-r--r-- | src/gui/chatinput.cpp | 3 | ||||
-rw-r--r-- | src/gui/window.cpp | 87 | ||||
-rw-r--r-- | src/gui/window.h | 51 | ||||
-rw-r--r-- | src/gui/windowcontainer.cpp | 124 | ||||
-rw-r--r-- | src/gui/windowcontainer.h | 53 | ||||
-rw-r--r-- | src/main.cpp | 4 |
9 files changed, 90 insertions, 237 deletions
@@ -4,6 +4,8 @@ - Added confirmation dialog before quitting - Added button to show/hide equipment window - Added framerate limiter to config options +- Upgraded to Guichan 0.4.0 +- Dialogs are now modal when appropriate - Fixed a crash in OpenGL mode - Fixed rendering of minimap, progress bars and player sprite in OpenGL mode @@ -19,7 +19,7 @@ and some libraries. The required libraries are: 1) SDL http://www.libsdl.org/ 2) SDL_mixer http://www.libsdl.org/projects/SDL_mixer/ 3) SDL_image http://www.libsdl.org/projects/SDL_image/ -4) Guichan 0.3.0 http://guichan.sourceforge.net/ +4) Guichan 0.4.0 http://guichan.sourceforge.net/ 5) libxml2 http://www.xmlsoft.org/ 6) physfs 1.0.0 http://icculus.org/physfs/ diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index cc625358..84a12585 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -231,7 +231,6 @@ void ChatWindow::action(const std::string& eventId) // Remove focus and hide input gui->focusNone(); - chatInput->setVisible(false); } } diff --git a/src/gui/chatinput.cpp b/src/gui/chatinput.cpp index 55417ac8..52e91f3a 100644 --- a/src/gui/chatinput.cpp +++ b/src/gui/chatinput.cpp @@ -30,6 +30,5 @@ ChatInput::ChatInput() void ChatInput::lostFocus() { - // TODO: Never mind this, it'll probably work in next Guichan version. - //setVisible(false); + setVisible(false); } diff --git a/src/gui/window.cpp b/src/gui/window.cpp index c9042ffd..54bce746 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -27,9 +27,12 @@ #include "../main.h" WindowContainer *Window::windowContainer = NULL; +int Window::instances = 0; +ImageRect Window::border; Window::Window(const std::string& caption, bool modal, Window *parent): gcn::Window(caption), + prevModal(NULL), parent(parent), snapSize(8), modal(modal), @@ -41,25 +44,27 @@ Window::Window(const std::string& caption, bool modal, Window *parent): { logger->log("Window::Window(\"%s\")", caption.c_str()); - setBorderSize(0); - setPadding(3); - - // Load dialog title bar image - ResourceManager *resman = ResourceManager::getInstance(); - Image *dBorders = resman->getImage("graphics/gui/vscroll_grey.png"); + if (instances == 0) + { + // Load static resources + ResourceManager *resman = ResourceManager::getInstance(); + Image *dBorders = resman->getImage("graphics/gui/vscroll_grey.png"); + border.grid[0] = dBorders->getSubImage(0, 0, 4, 4); + border.grid[1] = dBorders->getSubImage(4, 0, 3, 4); + border.grid[2] = dBorders->getSubImage(7, 0, 4, 4); + border.grid[3] = dBorders->getSubImage(0, 4, 4, 10); + border.grid[4] = resman->getImage("graphics/gui/bg_quad_dis.png"); + border.grid[5] = dBorders->getSubImage(7, 4, 4, 10); + border.grid[6] = dBorders->getSubImage(0, 15, 4, 4); + border.grid[7] = dBorders->getSubImage(4, 15, 3, 4); + border.grid[8] = dBorders->getSubImage(7, 15, 4, 4); + dBorders->decRef(); + } - border.grid[0] = dBorders->getSubImage(0, 0, 4, 4); - border.grid[1] = dBorders->getSubImage(4, 0, 3, 4); - border.grid[2] = dBorders->getSubImage(7, 0, 4, 4); - border.grid[3] = dBorders->getSubImage(0, 4, 4, 10); - border.grid[4] = resman->getImage("graphics/gui/bg_quad_dis.png"); - border.grid[5] = dBorders->getSubImage(7, 4, 4, 10); - border.grid[6] = dBorders->getSubImage(0, 15, 4, 4); - border.grid[7] = dBorders->getSubImage(4, 15, 3, 4); - border.grid[8] = dBorders->getSubImage(7, 15, 4, 4); + instances++; - dBorders->decRef(); - dBorders = NULL; + setBorderSize(0); + setPadding(3); // Add chrome chrome = new gcn::Container(); @@ -68,7 +73,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent): // Add this window to the window container if (windowContainer) { - windowContainer->add(this, modal); + windowContainer->add(this); } else { throw GCN_EXCEPTION("Window::Window. no windowContainer set"); @@ -77,19 +82,49 @@ Window::Window(const std::string& caption, bool modal, Window *parent): // Send GUI alpha changed for initialization optionChanged("guialpha"); config.addListener("guialpha", this); + + if (modal) + { + gcn::FocusHandler *focusHandler = _getFocusHandler(); + prevModal = focusHandler->getModalFocused(); + focusHandler->releaseModalFocus(prevModal); + requestModalFocus(); + } } Window::~Window() { logger->log("Window::~Window(\"%s\")", getCaption().c_str()); - // Free dialog bitmaps - //release_bitmap(dLeft); - //release_bitmap(dMid); - //release_bitmap(dRight); + instances--; + + if (instances == 0) + { + // Clean up static resources + delete border.grid[0]; + delete border.grid[1]; + delete border.grid[2]; + delete border.grid[3]; + border.grid[4]->decRef(); + delete border.grid[5]; + delete border.grid[6]; + delete border.grid[7]; + delete border.grid[8]; + } config.removeListener("guialpha", this); delete chrome; + + if (hasModalFocus()) + { + releaseModalFocus(); + } + + if (prevModal) + { + gcn::FocusHandler *focusHandler = _getFocusHandler(); + focusHandler->requestModalFocus(prevModal); + } } void Window::setWindowContainer(WindowContainer *wc) @@ -97,14 +132,6 @@ void Window::setWindowContainer(WindowContainer *wc) windowContainer = wc; } -void Window::logic() -{ - if (mContent != NULL) - { - mContent->logic(); - } -} - void Window::draw(gcn::Graphics* graphics) { int x, y; diff --git a/src/gui/window.h b/src/gui/window.h index 5632a292..d0112e97 100644 --- a/src/gui/window.h +++ b/src/gui/window.h @@ -38,24 +38,6 @@ */ class Window : public gcn::Window, public ConfigListener { - protected: - gcn::Container *chrome; /**< Contained container */ - Window *parent; /**< The parent window */ - int snapSize; /**< Snap distance to window edge */ - bool modal; /**< Window is modal */ - - ImageRect border; /**< The window border and background */ - - bool resizeable; /**< Window can be resized */ - int minWinWidth; /**< Minimum window width */ - int minWinHeight; /**< Minimum window height */ - int maxWinWidth; /**< Maximum window width */ - int maxWinHeight; /**< Maximum window height */ - - - /** The window container windows add themselves to. */ - static WindowContainer* windowContainer; - public: /** * Constructor. Initializes the title to the given text and hooks @@ -86,11 +68,6 @@ class Window : public gcn::Window, public ConfigListener void draw(gcn::Graphics *graphics); /** - * Calls logic on content widget (cause Guichan 0.3.0 forgot this) - */ - void logic(); - - /** * Adds a widget to the window. */ void add(gcn::Widget *w); @@ -174,6 +151,34 @@ class Window : public gcn::Window, public ConfigListener * Called when an config option changes. */ void optionChanged(const std::string &name); + + protected: + gcn::Container *chrome; /**< Contained container */ + gcn::Widget *prevModal; /**< Previous modal widget */ + Window *parent; /**< The parent window */ + int snapSize; /**< Snap distance to window edge */ + bool modal; /**< Window is modal */ + bool resizeable; /**< Window can be resized */ + int minWinWidth; /**< Minimum window width */ + int minWinHeight; /**< Minimum window height */ + int maxWinWidth; /**< Maximum window width */ + int maxWinHeight; /**< Maximum window height */ + + /** The window container windows add themselves to. */ + static WindowContainer* windowContainer; + + static int instances; /**< Number of Window instances */ + static ImageRect border; /**< The window border and background */ + + /** + * Loads window resources. + */ + void loadResources(); + + /** + * Unloads window resources. + */ + void unloadResources(); }; #endif diff --git a/src/gui/windowcontainer.cpp b/src/gui/windowcontainer.cpp index fad46137..9fd9b002 100644 --- a/src/gui/windowcontainer.cpp +++ b/src/gui/windowcontainer.cpp @@ -25,9 +25,7 @@ #include "windowcontainer.h" #include "window.h" -WindowContainer::WindowContainer(): - mouseDown(false), - modalWindow(NULL) +WindowContainer::WindowContainer() { } @@ -41,128 +39,8 @@ void WindowContainer::logic() gcn::Container::logic(); } -/* -void WindowContainer::_mouseInputMessage(const gcn::MouseInput &mouseInput) -{ - if (mouseInput.getType() == gcn::MouseInput::PRESS) - { - mouseDown = true; - } - else if (mouseInput.getType() == gcn::MouseInput::RELEASE) - { - mouseDown = false; - } - - // Make drag events not change widget with mouse. The Window instances - // need this behaviour to be able to handle window dragging. - if (!(mouseInput.getType() == gcn::MouseInput::MOTION && mouseDown)) - { - Widget* tempWidgetWithMouse = NULL; - - WidgetIterator iter; - for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++) - { - if ((*iter)->getDimension().isPointInRect( - mouseInput.x, mouseInput.y) && - (*iter)->isVisible()) - { - tempWidgetWithMouse = (*iter); - } - } - - if (tempWidgetWithMouse != mWidgetWithMouse) - { - if (mWidgetWithMouse) { - mWidgetWithMouse->_mouseOutMessage(); - } - - if (tempWidgetWithMouse) { - tempWidgetWithMouse->_mouseInMessage(); - } - - mWidgetWithMouse = tempWidgetWithMouse; - } - } - - if (mWidgetWithMouse && !mWidgetWithMouse->hasFocus() && - (!modalWindow || (gcn::Widget*)modalWindow == mWidgetWithMouse)) { - gcn::MouseInput mi = mouseInput; - mi.x -= mWidgetWithMouse->getX(); - mi.y -= mWidgetWithMouse->getY(); - mWidgetWithMouse->_mouseInputMessage(mi); - } - - if (mWidgetWithMouse == NULL) { - gcn::Widget::_mouseInputMessage(mouseInput); - } -} -*/ -void WindowContainer::add(gcn::Widget *widget) -{ - gcn::Container::add(widget); -} - -void WindowContainer::add(Window *window, bool modal) -{ - gcn::Container::add(window); - if (modal) { - setModalWindow(window); - } -} - -void WindowContainer::remove(gcn::Widget *widget) -{ - if (modalWindow == widget) { - setModalWindow(NULL); - } - gcn::Container::remove(widget); -} - -void WindowContainer::_announceDeath(gcn::Widget *widget) -{ - if (modalWindow == widget) { - setModalWindow(NULL); - } - gcn::Container::_announceDeath(widget); -} - -void WindowContainer::clear() -{ - modalWindow = NULL; - gcn::Container::clear(); -} - -void WindowContainer::setModalWindow(Window *window) -{ - if (modalWindow != window) { - if (!window) { - // Removing modal window, at this point there must be a modal - // window set. - Window *modalParent = modalWindow->getParentWindow(); - if (modalParent && modalParent->isModal()) { - // Return modality to parent. - modalWindow = modalParent; - return; - } - } - else if (modalWindow && window->getParentWindow() != modalWindow) { - // Adding a modal window, but failed sanity check. - std::cerr << "Error: existing modal window not parent.\n"; - return; - } - modalWindow = window; - } -} - -gcn::Widget *WindowContainer::getModalWindow() -{ - return modalWindow; -} void WindowContainer::scheduleDelete(gcn::Widget *widget) { - if (widget == (gcn::Widget*)modalWindow) { - setModalWindow(NULL); - } deathList.push_back(widget); } diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h index d9c49a2f..b0596f33 100644 --- a/src/gui/windowcontainer.h +++ b/src/gui/windowcontainer.h @@ -47,65 +47,12 @@ class WindowContainer : public gcn::Container { void logic(); /** - * Handles mouse input messages. Differs from standard behaviour in - * that widget with mouse doesn't change while a button is pressed. - */ - //void _mouseInputMessage(const gcn::MouseInput &mouseInput); - - /** - * Adds a widget. The widget can be set to be modal, which will ensure - * only that widget will receive input. - */ - void add(gcn::Widget *widget); - - /** - * Adds a window. The window can be set to be modal, which will ensure - * only that window will receive input. Note that when a modal widget - * has already been set, a new window can only be made model when the - * previously modal window is its parent. - */ - void WindowContainer::add(Window *window, bool modal); - - /** - * Removes a widget. - */ - void remove(gcn::Widget *widget); - - /** - * This function is called by the containers children when they get - * destroyed. - */ - void _announceDeath(gcn::Widget *widget); - - /** - * Clears the container of all widgets. - */ - void clear(); - - /** - * Sets the modal widget. This will ensure only this widget will - * receive mouse or keyboard input events. - * - * @see Window::Window - */ - void setModalWindow(Window *window); - - /** - * Returns the current modal widget, or <code>NULL</code> if there - * is none. - */ - gcn::Widget *getModalWindow(); - - /** * Schedule a widget for deletion. It will be deleted at the start of * the next logic update. */ void scheduleDelete(gcn::Widget *widget); protected: - bool mouseDown; - Window *modalWindow; - std::list<gcn::Widget*> deathList; }; diff --git a/src/main.cpp b/src/main.cpp index daa41569..9759d047 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -368,14 +368,10 @@ int main(int argc, char *argv[]) guiInput->pushInput(event); } - ResourceManager *resman = ResourceManager::getInstance(); - switch (state) { case LOGIN: logger->log("State: LOGIN"); sound.playMusic(TMW_DATADIR "data/music/Ivano(de)Jeanette.ogg"); - /*bgm = resman->getMusic("music/Ivano(de)Jeanette.ogg"); - bgm->play(-1);*/ login(); break; case CHAR_SERVER: |