diff options
-rw-r--r-- | base/main.cpp | 2 | ||||
-rw-r--r-- | gui/InterfaceManager.cpp | 119 | ||||
-rw-r--r-- | gui/InterfaceManager.h | 127 | ||||
-rw-r--r-- | gui/dialog.h | 2 |
4 files changed, 211 insertions, 39 deletions
diff --git a/base/main.cpp b/base/main.cpp index 53b4cb7cf4..72766292b3 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -70,7 +70,7 @@ static bool launcherDialog(OSystem &system) { // Clear the main screen system.clearScreen(); -#if 1 +#if defined LOL g_InterfaceManager.runGUI(); return true; diff --git a/gui/InterfaceManager.cpp b/gui/InterfaceManager.cpp index 7a779df593..f7a197f2fb 100644 --- a/gui/InterfaceManager.cpp +++ b/gui/InterfaceManager.cpp @@ -70,7 +70,8 @@ const char *InterfaceManager::kDrawDataStrings[] = { InterfaceManager::InterfaceManager() : _vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled), - _screen(0), _bytesPerPixel(0), _initOk(false), _themeOk(false) { + _screen(0), _bytesPerPixel(0), _initOk(false), _themeOk(false), + _needThemeLoad(false), _enabled(false) { _system = g_system; _parser = new ThemeParser(); @@ -78,7 +79,11 @@ InterfaceManager::InterfaceManager() : _widgets[i] = 0; } - setGraphicsMode(kGfxStandard16bit); + _graphicsMode = kGfxAntialias16bit; // default GFX mode + // TODO: load this from a config file + +// setGraphicsMode(kGfxStandard16bit); +// printf("Singleton init!"); } template<typename PixelType> @@ -91,11 +96,6 @@ void InterfaceManager::screenInit() { } void InterfaceManager::setGraphicsMode(Graphics_Mode mode) { - if (mode == _graphicsMode) - return; - - _graphicsMode = mode; - switch (mode) { case kGfxStandard16bit: case kGfxAntialias16bit: @@ -127,7 +127,6 @@ bool InterfaceManager::addDrawData(DrawData data_id, bool cached) { _widgets[data_id] = new WidgetDrawData; _widgets[data_id]->_cached = cached; - _widgets[data_id]->_type = data_id; return true; } @@ -174,8 +173,15 @@ bool InterfaceManager::loadThemeXML(Common::String themeName) { return parser()->parse(); } -bool InterfaceManager::init() { - return false; +void InterfaceManager::init() { + if (!_screen || _system->getOverlayWidth() != _screen->w || + _system->getOverlayHeight() != _screen->h ) + setGraphicsMode(_graphicsMode); + + if (needThemeReload()) + loadTheme(); + + _initOk = true; } bool InterfaceManager::isWidgetCached(DrawData type, const Common::Rect &r) { @@ -199,7 +205,7 @@ void InterfaceManager::drawDD(DrawData type, const Common::Rect &r) { } void InterfaceManager::drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, uint16 hints) { - if (!_initOk) + if (!ready()) return; if (state == kStateEnabled) @@ -213,7 +219,7 @@ void InterfaceManager::drawButton(const Common::Rect &r, const Common::String &s } void InterfaceManager::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) { - if (!_initOk) + if (!ready()) return; drawDD(kDDSeparator, r); @@ -221,7 +227,7 @@ void InterfaceManager::drawLineSeparator(const Common::Rect &r, WidgetStateInfo } void InterfaceManager::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) { - if (!_initOk) + if (!ready()) return; drawDD(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r); @@ -236,7 +242,7 @@ void InterfaceManager::drawCheckbox(const Common::Rect &r, const Common::String } void InterfaceManager::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) { - if (!_initOk) + if (!ready()) return; drawDD(kDDSliderEmpty, r); @@ -250,20 +256,27 @@ void InterfaceManager::drawSlider(const Common::Rect &r, int width, WidgetStateI } void InterfaceManager::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState sb_state, WidgetStateInfo state) { - if (!_initOk) + if (!ready()) return; } int InterfaceManager::runGUI() { + if (!ready()) + return 0; + Common::EventManager *eventMan = _system->getEventManager(); + Dialog *activeDialog = getTopDialog(); - if (!loadTheme("modern_theme.xml")) + if (!activeDialog) return 0; - _system->showOverlay(); - + bool didSaveState = false; bool running = true; - while (running) { // draw!! + + int button; + uint32 time; + + while (!_dialogStack.empty() && activeDialog == getTopDialog()) { // draw!! drawDD(kDDMainDialogBackground, Common::Rect()); drawDD(kDDButtonIdle, Common::Rect(32, 32, 128, 128)); @@ -272,10 +285,74 @@ int InterfaceManager::runGUI() { Common::Event event; _system->delayMillis(100); + while (eventMan->pollEvent(event)) { - if (event.type == Common::EVENT_QUIT) - running = false; + + if (activeDialog != getTopDialog() && + event.type != Common::EVENT_QUIT && + event.type != Common::EVENT_SCREEN_CHANGED) + continue; + + Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); + + switch (event.type) { + case Common::EVENT_KEYDOWN: + activeDialog->handleKeyDown(event.kbd); + break; + + case Common::EVENT_KEYUP: + activeDialog->handleKeyUp(event.kbd); + break; + + case Common::EVENT_MOUSEMOVE: + activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); + break; + + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); + time = _system->getMillis(); + if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) + && ABS(_lastClick.x - event.mouse.x) < 3 + && ABS(_lastClick.y - event.mouse.y) < 3) { + _lastClick.count++; + } else { + _lastClick.x = event.mouse.x; + _lastClick.y = event.mouse.y; + _lastClick.count = 1; + } + _lastClick.time = time; + activeDialog->handleMouseDown(mouse.x, mouse.y, button, _lastClick.count); + break; + + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); + activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); + break; + + case Common::EVENT_WHEELUP: + activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); + break; + + case Common::EVENT_WHEELDOWN: + activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); + break; + + case Common::EVENT_QUIT: + _system->quit(); + return 1; + + case Common::EVENT_SCREEN_CHANGED: + screenChange(); + break; + + default: + break; + } } + + _system->delayMillis(10); } _system->hideOverlay(); diff --git a/gui/InterfaceManager.h b/gui/InterfaceManager.h index 906c5173e1..779f9aab57 100644 --- a/gui/InterfaceManager.h +++ b/gui/InterfaceManager.h @@ -33,6 +33,7 @@ #include "graphics/surface.h" #include "graphics/fontman.h" +#include "gui/dialog.h" #include "gui/ThemeParser.h" #include "graphics/VectorRenderer.h" @@ -43,12 +44,37 @@ namespace GUI { struct WidgetDrawData; class InterfaceManager; +struct WidgetDrawData { + Common::Array<Graphics::DrawStep*> _steps; + + bool _cached; + Graphics::Surface *_surfaceCache; + uint32 _cachedW, _cachedH; + + ~WidgetDrawData() { + for (uint i = 0; i < _steps.size(); ++i) + delete _steps[i]; + + _steps.clear(); + + if (_surfaceCache) { + _surfaceCache->free(); + delete _surfaceCache; + } + } +}; + class InterfaceManager : public Common::Singleton<InterfaceManager> { - friend class Common::Singleton<SingletonBaseType>; typedef Common::String String; + typedef GUI::Dialog Dialog; + + friend class GUI::Dialog; + friend class GUI::GuiObject; + friend class Common::Singleton<SingletonBaseType>; static const char *kDrawDataStrings[]; + static const int kMaxDialogDepth = 4; public: enum Graphics_Mode { @@ -57,6 +83,11 @@ public: kGfxAntialias16bit }; + enum { + kDoubleClickDelay = 500, // milliseconds + kCursorAnimateDelay = 250 + }; + enum DrawData { kDDMainDialogBackground, kDDSpecialColorBackground, @@ -150,8 +181,7 @@ public: void setGraphicsMode(Graphics_Mode mode); int runGUI(); - bool init(); - bool deinit(); + void init(); /** Font management */ const Graphics::Font *getFont(FontStyle font) const { return _font; } @@ -190,6 +220,43 @@ public: return _initOk && _themeOk; } + void refresh() { + init(); + if (_enabled) { + _system->showOverlay(); +// CursorMan.replaceCursorPalette(_cursorPal, 0, MAX_CURS_COLORS); +// CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale); + } + } + + void enable() { + init(); + _system->showOverlay(); + _enabled = true; + } + + void disable() { + _system->hideOverlay(); + _enabled = false; + } + + void deinit() { + if (_initOk) { + _system->hideOverlay(); + _initOk = false; + } + } + + bool loadTheme() { + ConfMan.registerDefault("gui_theme", "default"); + Common::String style(ConfMan.get("gui_theme")); + + if (style.compareToIgnoreCase("default") == 0) + style = "modern"; + + return loadTheme(style); + } + bool loadTheme(Common::String themeName); protected: @@ -198,6 +265,18 @@ protected: bool loadThemeXML(Common::String themeName); bool loadDefaultXML(); + void unloadTheme() { + if (!_themeOk) + return; + + for (int i = 0; i < kDrawDataMAX; ++i) { + delete _widgets[i]; + _widgets[i] = 0; + } + } + + void screenChange() {} + void freeRenderer() { delete _vectorRenderer; _vectorRenderer = 0; @@ -211,17 +290,33 @@ protected: } } + Dialog *getTopDialog() const { + if (_dialogStack.empty()) + return 0; + return _dialogStack.top(); + } + + bool needThemeReload() { + return (_themeOk == false || _needThemeLoad == true); + } + + bool isWidgetCached(DrawData type, const Common::Rect &r); void drawCached(DrawData type, const Common::Rect &r); inline void drawDD(DrawData type, const Common::Rect &r); - void addDirtyRect(const Common::Rect &r) {} + + void addDirtyRect(const Common::Rect &r) { + _dirtyScreen.extend(r); + } OSystem *_system; Graphics::VectorRenderer *_vectorRenderer; - Graphics::Surface *_screen; GUI::ThemeParser *_parser; + Graphics::Surface *_screen; + Graphics::Surface *_screenCache; + int _bytesPerPixel; Graphics_Mode _graphicsMode; @@ -229,22 +324,20 @@ protected: const Graphics::Font *_font; WidgetDrawData *_widgets[kDrawDataMAX]; + Common::FixedStack<Dialog *, kMaxDialogDepth> _dialogStack; + Common::Rect _dirtyScreen; bool _initOk; bool _themeOk; bool _caching; - - static const char *_defaultXML; -}; - -struct WidgetDrawData { - Common::Array<Graphics::DrawStep*> _steps; - - bool _cached; - Graphics::Surface *_surfaceCache; - uint32 _cachedW, _cachedH; - - InterfaceManager::DrawData _type; + bool _needThemeLoad; + bool _enabled; + + struct { + int16 x, y; // Position of mouse when the click occured + uint32 time; // Time + int count; // How often was it already pressed? + } _lastClick; }; } // end of namespace GUI. diff --git a/gui/dialog.h b/gui/dialog.h index d17d3a5ad1..f34e9d2e0d 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -42,7 +42,9 @@ enum { }; class Dialog : public GuiObject { + // TANOKU-TODO: remove newgui from here friend class NewGui; + friend class InterfaceManager; protected: Widget *_mouseWidget; Widget *_focusedWidget; |