diff options
Diffstat (limited to 'gui')
-rw-r--r-- | gui/console.cpp | 19 | ||||
-rw-r--r-- | gui/dialog.cpp | 27 | ||||
-rw-r--r-- | gui/newgui.cpp | 83 | ||||
-rw-r--r-- | gui/newgui.h | 33 |
4 files changed, 104 insertions, 58 deletions
diff --git a/gui/console.cpp b/gui/console.cpp index f4a7ac9b76..d40606697b 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -49,9 +49,9 @@ enum { * - a *lot* of others things, this code is in no way complete and heavily under progress */ ConsoleDialog::ConsoleDialog(float widthPercent, float heightPercent) - : Dialog(0, 0, 1, 1), + : Dialog(0, 0, 1, 1), _widthPercent(widthPercent), _heightPercent(heightPercent) { - + // Setup basic layout/dialog size reflowLayout(); @@ -111,10 +111,13 @@ void ConsoleDialog::slideUpAndClose() { } void ConsoleDialog::open() { + // disable scaling because the console is using non fixed positions + g_gui.enableScaling(false); + // Initiate sliding the console down. We do a very simple trick to achieve // this effect: we simply move the console dialog just above (outside) the // visible screen area, then shift it down in handleTickle() over a - // certain period of time. + // certain period of time. _y = -_h; _slideTime = g_system->getMillis(); _slideMode = kDownSlideMode; @@ -165,7 +168,7 @@ void ConsoleDialog::handleTickle() { _caretTime = time + kCaretBlinkTime; drawCaret(_caretVisible); } - + // Perform the "slide animation". if (_slideMode != kNoSlideMode) { const float tmp = (float)(g_system->getMillis() - _slideTime) / kConsoleSlideDownDuration; @@ -174,7 +177,7 @@ void ConsoleDialog::handleTickle() { } else { _y = (int)(_h * (tmp - 1.0)); } - + if (_slideMode == kDownSlideMode && _y > 0) { // End the slide _slideMode = kNoSlideMode; @@ -195,7 +198,7 @@ void ConsoleDialog::handleMouseWheel(int x, int y, int direction) { void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { int i; - + if (_slideMode != kNoSlideMode) return; @@ -204,7 +207,7 @@ void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { case '\r': { if (_caretVisible) drawCaret(true); - + nextLine(); assert(_promptEndPos >= _promptStartPos); @@ -217,7 +220,7 @@ void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { // We have to allocate the string buffer with new, since VC++ sadly does not // comply to the C++ standard, so we can't use a dynamic sized stack array. char *str = new char[len + 1]; - + // Copy the user input to str for (i = 0; i < len; i++) str[i] = buffer(_promptStartPos + i); diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 1a4f1feb6a..f2ee027f56 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -29,7 +29,7 @@ namespace GUI { /* * TODO list - * - add some sense of the window being "active" (i.e. in front) or not. If it + * - add some sense of the window being "active" (i.e. in front) or not. If it * was inactive and just became active, reset certain vars (like who is focused). * Maybe we should just add lostFocus and receivedFocus methods to Dialog, just * like we have for class Widget? @@ -98,7 +98,7 @@ void Dialog::draw() { } void Dialog::drawDialog() { - + if (!isVisible()) return; @@ -117,9 +117,12 @@ void Dialog::drawDialog() { } void Dialog::handleMouseDown(int x, int y, int button, int clickCount) { + x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor(); + Widget *w; + w = findWidget(x, y); - + _dragWidget = w; // If the click occured inside a widget which is not the currently @@ -141,11 +144,13 @@ void Dialog::handleMouseDown(int x, int y, int button, int clickCount) { } void Dialog::handleMouseUp(int x, int y, int button, int clickCount) { + x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor(); + Widget *w; if (_focusedWidget) { //w = _focusedWidget; - + // Lose focus on mouseup unless the widget requested to retain the focus if (! (_focusedWidget->getFlags() & WIDGET_RETAIN_FOCUS )) { releaseFocus(); @@ -161,6 +166,8 @@ void Dialog::handleMouseUp(int x, int y, int button, int clickCount) { } void Dialog::handleMouseWheel(int x, int y, int direction) { + x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor(); + Widget *w; // This may look a bit backwards, but I think it makes more sense for @@ -212,16 +219,18 @@ void Dialog::handleKeyUp(uint16 ascii, int keycode, int modifiers) { } void Dialog::handleMouseMoved(int x, int y, int button) { + x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor(); + Widget *w; - + //if (!button) // _dragWidget = 0; - + if (_focusedWidget && !_dragWidget) { w = _focusedWidget; int wx = w->getAbsX() - _x; int wy = w->getAbsY() - _y; - + // We still send mouseEntered/Left messages to the focused item // (but to no other items). bool mouseInFocusedWidget = (x >= wx && x < wx + w->_w && y >= wy && y < wy + w->_h); @@ -237,7 +246,7 @@ void Dialog::handleMouseMoved(int x, int y, int button) { w->handleMouseMoved(x - wx, y - wy, button); } - + // While a "drag" is in process (i.e. mouse is moved while a button is pressed), // only deal with the widget in which the click originated. if (_dragWidget) @@ -251,7 +260,7 @@ void Dialog::handleMouseMoved(int x, int y, int button) { if (w) w->handleMouseEntered(button); _mouseWidget = w; - } + } if (w && (w->getFlags() & WIDGET_TRACK_MOUSE)) { w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button); diff --git a/gui/newgui.cpp b/gui/newgui.cpp index 023c248108..34afd17b2a 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -41,7 +41,7 @@ namespace GUI { * - allow multi line (l/c/r aligned) text via StaticTextWidget ? * - add "close" widget to all dialogs (with a flag to turn it off) ? * - make dialogs "moveable" ? - * - come up with a new look & feel / theme for the GUI + * - come up with a new look & feel / theme for the GUI * - ... */ @@ -54,9 +54,9 @@ enum { // Constructor -NewGui::NewGui() : _needRedraw(false), +NewGui::NewGui() : _scaleEnable(true), _needRedraw(false), _stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) { - + _system = &OSystem::instance(); // Clear the cursor @@ -64,6 +64,9 @@ NewGui::NewGui() : _needRedraw(false), // Reset key repeat _currentKeyDown.keycode = 0; + + // updates the scaling factor + updateScaleFactor(); } void NewGui::updateColors() { @@ -75,17 +78,32 @@ void NewGui::updateColors() { _textcolorhi = _system->RGBToColor(0, 255, 0); } +void NewGui::updateScaleFactor() { + if(!_scaleEnable) { + _scaleFactor = 1; + return; + } + + enum { + kDefaultGUIWidth = 320, + kDefaultGUIHeight = 200 + }; + + _scaleFactor = MIN(_system->getWidth() / kDefaultGUIWidth, _system->getHeight() / kDefaultGUIHeight); +} + void NewGui::runLoop() { Dialog *activeDialog = _dialogStack.top(); bool didSaveState = false; if (activeDialog == 0) return; - + // Setup some default GUI colors. Normally this will be done whenever an // EVENT_SCREEN_CHANGED is received. However, not yet all backends support // that event, so we also do it "manually" whenever a run loop is entered. updateColors(); + updateScaleFactor(); if (!_stateIsSaved) { saveState(); @@ -106,7 +124,7 @@ void NewGui::runLoop() { } animateCursor(); - _system->updateScreen(); + _system->updateScreen(); OSystem::Event event; uint32 time = _system->getMillis(); @@ -131,7 +149,7 @@ void NewGui::runLoop() { _currentKeyDown.keycode = 0; break; case OSystem::EVENT_MOUSEMOVE: - activeDialog->handleMouseMoved(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 0); + activeDialog->handleMouseMoved(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 0); break; // We don't distinguish between mousebuttons (for now at least) case OSystem::EVENT_LBUTTONDOWN: @@ -146,23 +164,24 @@ void NewGui::runLoop() { _lastClick.count = 1; } _lastClick.time = time; - activeDialog->handleMouseDown(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count); + activeDialog->handleMouseDown(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 1, _lastClick.count); break; case OSystem::EVENT_LBUTTONUP: case OSystem::EVENT_RBUTTONUP: - activeDialog->handleMouseUp(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count); + activeDialog->handleMouseUp(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 1, _lastClick.count); break; case OSystem::EVENT_WHEELUP: - activeDialog->handleMouseWheel(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, -1); + activeDialog->handleMouseWheel(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), -1); break; case OSystem::EVENT_WHEELDOWN: - activeDialog->handleMouseWheel(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1); + activeDialog->handleMouseWheel(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 1); break; case OSystem::EVENT_QUIT: _system->quit(); return; case OSystem::EVENT_SCREEN_CHANGED: updateColors(); + updateScaleFactor(); activeDialog->handleScreenChanged(); break; } @@ -180,7 +199,7 @@ void NewGui::runLoop() { // Delay for a moment _system->delayMillis(10); } - + if (didSaveState) restoreState(); } @@ -212,6 +231,7 @@ void NewGui::saveState() { _lastClick.count = 0; _stateIsSaved = true; + _scaleEnable = true; } void NewGui::restoreState() { @@ -224,7 +244,7 @@ void NewGui::restoreState() { } _system->updateScreen(); - + _stateIsSaved = false; } @@ -270,20 +290,20 @@ void NewGui::box(int x, int y, int width, int height, OverlayColor colorA, Overl } void NewGui::hLine(int x, int y, int x2, OverlayColor color) { - _screen.hLine(x, y, x2, color); + _screen.hLine(x * _scaleFactor, y * _scaleFactor, x2 * _scaleFactor, color); } void NewGui::vLine(int x, int y, int y2, OverlayColor color) { - _screen.vLine(x, y, y2, color); + _screen.vLine(x * _scaleFactor, y * _scaleFactor, y2 * _scaleFactor, color); } void NewGui::blendRect(int x, int y, int w, int h, OverlayColor color, int level) { #ifdef NEWGUI_256 fillRect(x, y, w, h, color); #else - Common::Rect rect(x, y, x + w, y + h); + Common::Rect rect(x * _scaleFactor, y * _scaleFactor, (x + w) * _scaleFactor, (y + h) * _scaleFactor); rect.clip(_screen.w, _screen.h); - + if (!rect.isValidRect()) return; @@ -311,17 +331,17 @@ void NewGui::blendRect(int x, int y, int w, int h, OverlayColor color, int level } void NewGui::fillRect(int x, int y, int w, int h, OverlayColor color) { - _screen.fillRect(Common::Rect(x, y, x+w, y+h), color); + _screen.fillRect(Common::Rect(x * _scaleFactor, y * _scaleFactor, (x+w) * _scaleFactor, (y+h) * _scaleFactor), color); } void NewGui::frameRect(int x, int y, int w, int h, OverlayColor color) { - _screen.frameRect(Common::Rect(x, y, x+w, y+h), color); + _screen.frameRect(Common::Rect(x * _scaleFactor, y * _scaleFactor, (x+w) * _scaleFactor, (y+h) * _scaleFactor), color); } void NewGui::addDirtyRect(int x, int y, int w, int h) { - Common::Rect rect(x, y, x + w, y + h); + Common::Rect rect(x * _scaleFactor, y * _scaleFactor, (x + w) * _scaleFactor, (y + h) * _scaleFactor); rect.clip(_screen.w, _screen.h); - + if (!rect.isValidRect()) return; @@ -335,7 +355,7 @@ void NewGui::addDirtyRect(int x, int y, int w, int h) { void NewGui::drawChar(byte chr, int xx, int yy, OverlayColor color, const Graphics::Font *font) { if (font == 0) font = &getFont(); - font->drawChar(&_screen, chr, xx, yy, color); + font->drawChar(&_screen, chr, xx, yy, color, _scaleEnable); } int NewGui::getStringWidth(const String &str) { @@ -347,24 +367,31 @@ int NewGui::getCharWidth(byte c) { } void NewGui::drawString(const String &s, int x, int y, int w, OverlayColor color, TextAlignment align, int deltax, bool useEllipsis) { - getFont().drawString(&_screen, s, x, y, w, color, align, deltax, useEllipsis); + getFont().drawString(&_screen, s, x, y, w, color, align, deltax, useEllipsis, _scaleEnable); } // // Draw an 8x8 bitmap at location (x,y) // void NewGui::drawBitmap(uint32 *bitmap, int tx, int ty, OverlayColor color, int h) { + tx *= _scaleFactor; ty *= _scaleFactor; + h *= _scaleFactor; OverlayColor *ptr = getBasePtr(tx, ty); for (int y = 0; y < h; y++, ptr += _screenPitch) { uint32 mask = 0xF0000000; if (ty + y < 0 || ty + y >= _screen.h) continue; - for (int x = 0; x < 8; x++, mask >>= 4) { + for (int x = 0; x < 8 * _scaleFactor; x++) { + if(!(x % 2) && _scaleFactor != 1 && x != 0) + mask >>= 4; + else if(_scaleFactor == 1) + mask >>= 4; + if (tx + x < 0 || tx + x >= _screen.w) continue; - if (bitmap[y] & mask) - ptr[x] = color; + if (bitmap[y / _scaleFactor] & mask) + ptr[x] = color; } } } @@ -374,19 +401,19 @@ void NewGui::drawBitmap(uint32 *bitmap, int tx, int ty, OverlayColor color, int // We could plug in a different cursor here if we like to. // void NewGui::animateCursor() { - int time = _system->getMillis(); + int time = _system->getMillis(); if (time > _cursorAnimateTimer + kCursorAnimateDelay) { const byte colors[4] = { 15, 15, 7, 8 }; const byte color = colors[_cursorAnimateCounter]; int i; - + for (i = 0; i < 15; i++) { if ((i < 6) || (i > 8)) { _cursor[16 * 7 + i] = color; _cursor[16 * i + 7] = color; } } - + _system->setMouseCursor(_cursor, 16, 16, 7, 7); _cursorAnimateTimer = time; diff --git a/gui/newgui.h b/gui/newgui.h index f57cb68488..19791e74ed 100644 --- a/gui/newgui.h +++ b/gui/newgui.h @@ -52,7 +52,7 @@ typedef Common::FixedStack<Dialog *> DialogStack; /** * GUI manager singleton. - */ + */ class NewGui : public Common::Singleton<NewGui> { typedef Common::String String; friend class Dialog; @@ -66,16 +66,22 @@ public: bool isActive() { return ! _dialogStack.empty(); } + int getScaleFactor() { return _scaleFactor; } + void enableScaling(bool enable) { _scaleEnable = enable; updateScaleFactor(); } + protected: - OSystem *_system; - Graphics::Surface _screen; + OSystem *_system; + Graphics::Surface _screen; int _screenPitch; - + + int _scaleFactor; + bool _scaleEnable; + bool _needRedraw; DialogStack _dialogStack; - + bool _stateIsSaved; - + // for continuous events (keyDown) struct { uint16 ascii; @@ -83,30 +89,31 @@ protected: int keycode; } _currentKeyDown; uint32 _keyRepeatTime; - + // position and time of last mouse click (used to detect double clicks) struct { int16 x, y; // Position of mouse when the click occured uint32 time; // Time int count; // How often was it already pressed? } _lastClick; - + // mouse cursor state bool _oldCursorMode; - int _cursorAnimateCounter; - int _cursorAnimateTimer; + int _cursorAnimateCounter; + int _cursorAnimateTimer; byte _cursor[2048]; void saveState(); void restoreState(); - + void openDialog(Dialog *dialog); void closeTopDialog(); - + void loop(); void animateCursor(); void updateColors(); + void updateScaleFactor(); OverlayColor *getBasePtr(int x, int y); @@ -116,7 +123,7 @@ public: OverlayColor _bgcolor; OverlayColor _textcolor; OverlayColor _textcolorhi; - + // Font const Graphics::Font &getFont() const; |