aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorMax Horn2005-01-06 19:09:34 +0000
committerMax Horn2005-01-06 19:09:34 +0000
commit4fae197c67b8cecf5a674c710530c44f5cef814e (patch)
treed9b403db62fe8864c8aab2a026466eb16d64d391 /gui
parent5d88c3954968b8eccb86363055bda55300ac2586 (diff)
downloadscummvm-rg350-4fae197c67b8cecf5a674c710530c44f5cef814e.tar.gz
scummvm-rg350-4fae197c67b8cecf5a674c710530c44f5cef814e.tar.bz2
scummvm-rg350-4fae197c67b8cecf5a674c710530c44f5cef814e.zip
Patch #1092994 (Selfscaling GUI)
svn-id: r16455
Diffstat (limited to 'gui')
-rw-r--r--gui/console.cpp19
-rw-r--r--gui/dialog.cpp27
-rw-r--r--gui/newgui.cpp83
-rw-r--r--gui/newgui.h33
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;