diff options
author | Max Horn | 2002-07-10 22:49:41 +0000 |
---|---|---|
committer | Max Horn | 2002-07-10 22:49:41 +0000 |
commit | c60670d561b0ad8106cd54adf163a0c39412575e (patch) | |
tree | 63cf3e40942ca6e8f8bc61649abc5beb286fb657 | |
parent | 9b3784ef6dcb26e4864844cc626e472ae49393b2 (diff) | |
download | scummvm-rg350-c60670d561b0ad8106cd54adf163a0c39412575e.tar.gz scummvm-rg350-c60670d561b0ad8106cd54adf163a0c39412575e.tar.bz2 scummvm-rg350-c60670d561b0ad8106cd54adf163a0c39412575e.zip |
added prototype ListWidget (doesn't do anything yet, only serves to demo how it might look); renamed various NewGui methods and added frameRect method; made NewGui use our 'own' GUI colors (no worries if you don't like them, this is just an experiment); StaticTextWidget now clones its label (preventing problems when a game was loaded, thus invalidating string locations in memory)
svn-id: r4513
-rw-r--r-- | Makefile.common | 2 | ||||
-rw-r--r-- | gui/ListWidget.cpp | 125 | ||||
-rw-r--r-- | gui/ListWidget.h | 63 | ||||
-rw-r--r-- | gui/dialog.cpp | 22 | ||||
-rw-r--r-- | gui/widget.cpp | 58 | ||||
-rw-r--r-- | gui/widget.h | 23 | ||||
-rw-r--r-- | newgui.cpp | 44 | ||||
-rw-r--r-- | newgui.h | 10 | ||||
-rw-r--r-- | scummvm.cpp | 17 |
9 files changed, 312 insertions, 52 deletions
diff --git a/Makefile.common b/Makefile.common index b96410b996..9a255d2c43 100644 --- a/Makefile.common +++ b/Makefile.common @@ -6,7 +6,7 @@ ZIPFILE := scummvm-`date '+%Y-%m-%d'`.zip INCS = scumm.h scummsys.h stdafx.h -OBJS += gui/widget.o gui/dialog.o newgui.o \ +OBJS += gui/widget.o gui/dialog.o gui/ListWidget.o newgui.o \ actor.o boxes.o costume.o gfx.o object.o resource.o \ saveload.o script.o scummvm.o sound.o string.o \ sys.o verbs.o script_v1.o script_v2.o debug.o gui.o \ diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp new file mode 100644 index 0000000000..ea2a95ad7c --- /dev/null +++ b/gui/ListWidget.cpp @@ -0,0 +1,125 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002 The ScummVM project + * + * 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 + * of the License, 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. + * + * $Header$ + */ + +#include "stdafx.h" +#include "ListWidget.h" +#include "dialog.h" +#include "newgui.h" + + +/* + * Some thoughts: + * - We should split out the scrollbar into a seperate widget. This will + * simplify the drawing & mouse handling considerably, but also requires + * us to come up with a way to couple both widgets (shouldn't be to hard) + * - Write a class to encapsulate the data instead of using std::list<string>. + * How exactly this will look and what it does has yet to be determined. + * - The handleKey method of widgets is currently never called, code for that has + * to be added to dialog.cpp + * - ... + */ + + +// Height of one entry +#define LINE_HEIGHT 10 + + +// Up/down arrow for the scrollbar +static uint32 up_arrow[8] = { + 0x00000000, + 0x00000000, + 0x00001000, + 0x00001000, + 0x00011100, + 0x00011100, + 0x00110110, + 0x00100010, +}; + +static uint32 down_arrow[8] = { + 0x00000000, + 0x00000000, + 0x00100010, + 0x00110110, + 0x00011100, + 0x00011100, + 0x00001000, + 0x00001000, +}; + +ListWidget::ListWidget(Dialog *boss, int x, int y, int w, int h) + : Widget(boss, x, y, w, h) +{ + _flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG; + _type = kListWidget; +} + +ListWidget::~ListWidget() +{ +} + +void ListWidget::handleClick(int button) +{ + if (_flags & WIDGET_ENABLED) { + } +} + +void ListWidget::handleMouseMoved(int x, int y, int state) +{ +} + + +void ListWidget::handleKey(char key, int modifiers) +{ +} + +void ListWidget::drawWidget(bool hilite) +{ + NewGui *gui = _boss->getGui(); + int rightX = _x + _w - 1; + int leftX = rightX - 8; + int bottomY = _y + _h; + + gui->frameRect(leftX, _y, 9, _h, gui->_shadowcolor); + + // Up arrow + gui->fillRect(leftX, _y, 9, 10, gui->_bgcolor); + gui->frameRect(leftX, _y, 9, 10, gui->_color); + gui->drawBitmap(up_arrow, leftX, _y, gui->_textcolor); + + // Down arrow + gui->fillRect(leftX, bottomY - 9, 9, 10, gui->_bgcolor); + gui->frameRect(leftX, bottomY - 9, 9, 10, gui->_color); + gui->drawBitmap(down_arrow, leftX, bottomY - 9, gui->_textcolor); + + // Slider + // FIXME - determine slider position and size. This depends on: + // * the number of entries/page + // * total number of entries + // * current scroll position (i.e. idx of "first" visible entry + gui->fillRect(leftX, _y+20, 9, 4, gui->_textcolor); + gui->frameRect(leftX, _y+20, 9, 4, gui->_color); + + // Now draw the list items + // FIXME - this is just a temporary demo hack + gui->drawString("1. A simple game", _x+1, _y+1, _w - 10, gui->_textcolor); + gui->drawString("2. This space for rent", _x+1, _y+1 + LINE_HEIGHT, _w - 10, gui->_textcolorhi); + gui->drawString("3. To be or not to be", _x+1, _y+1 + LINE_HEIGHT*2, _w - 10, gui->_textcolor); +} diff --git a/gui/ListWidget.h b/gui/ListWidget.h new file mode 100644 index 0000000000..76e077bc55 --- /dev/null +++ b/gui/ListWidget.h @@ -0,0 +1,63 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002 The ScummVM project + * + * 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 + * of the License, 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. + * + * $Header$ + */ + +#ifndef LISTWIDGET_H +#define LISTWIDGET_H + +#include "widget.h" + +// FIXME - use own list class later, this is for rapid development +#include <string> +#include <vector> +typedef std::vector<std::string> StringList; + + +enum { + kListNumberingOff = -1, + kListNumberingZero = 0, + kListNumberingOne = 1 +}; + +/* ListWidget */ +class ListWidget : public Widget { +protected: + StringList _list; + bool _editable; + int _numberingMode; + int _currentPos; + +public: + ListWidget(Dialog *boss, int x, int y, int w, int h); + virtual ~ListWidget(); + + void setList(const StringList& list) { _list = list; } + const StringList& getList() const { return _list; } + + void setNumberingMode(int numberingMode) { _numberingMode = numberingMode; } + + virtual void handleClick(int button); + virtual void handleMouseMoved(int x, int y, int button); + virtual void handleKey(char key, int modifiers); + +protected: + void drawWidget(bool hilite); +}; + +#endif diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 9942bcfa39..c14f4e769e 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -21,9 +21,10 @@ #include <ctype.h> #include "stdafx.h" +#include "newgui.h" #include "dialog.h" #include "widget.h" -#include "newgui.h" +#include "ListWidget.h" Dialog::~Dialog() { @@ -37,14 +38,14 @@ void Dialog::setupScreenBuf() _screenBuf = new byte[320*200]; // Draw the fixed parts of the dialog: background and border. - _gui->blendArea(_x, _y, _w, _h, _gui->_bgcolor); + _gui->blendRect(_x, _y, _w, _h, _gui->_bgcolor); _gui->box(_x, _y, _w, _h); // Draw a bgcolor rectangle for all widgets which have WIDGET_CLEARBG set. Widget *w = _firstWidget; while (w) { if (w->_flags & WIDGET_CLEARBG) - _gui->fillArea(_x + w->_x, _y + w->_y, w->_w, w->_h, _gui->_bgcolor); + _gui->fillRect(_x + w->_x, _y + w->_y, w->_w, w->_h, _gui->_bgcolor); // FIXME - should we also draw borders here if WIDGET_BORDER is set? w = w->_next; } @@ -68,10 +69,10 @@ void Dialog::draw() if (_screenBuf) { _gui->blitFrom(_screenBuf, _x, _y, _w, _h); } else { - _gui->fillArea(_x, _y, _w, _h, _gui->_bgcolor); + _gui->fillRect(_x, _y, _w, _h, _gui->_bgcolor); _gui->box(_x, _y, _w, _h); } - _gui->setAreaDirty(_x, _y, _w, _h); + _gui->addDirtyRect(_x, _y, _w, _h); while (w) { w->draw(); @@ -102,6 +103,10 @@ void Dialog::handleKey(char key, int modifiers) } w = w->_next; } + + // TODO - introduce the notion of a "focused" widget which receives + // key events (by calling its handleKey method). Required for editfields + // and also for an editable list widget. } void Dialog::handleMouseMoved(int x, int y, int button) @@ -194,10 +199,13 @@ SaveLoadDialog::SaveLoadDialog(NewGui *gui) addButton(200, 100, 54, 16, RES_STRING(8), kQuitCmd, 'Q'); // Quit // FIXME - test - new CheckboxWidget(this, 50, 20, 100, 16, "Toggle me", 0); + new CheckboxWidget(this, 10, 20, 90, 16, "Toggle me", 0); // FIXME - test - new SliderWidget(this, 50, 50, 100, 16, "Volume", 0); + new SliderWidget(this, 110, 20, 80, 16, "Volume", 0); + + // FIXME - test + new ListWidget(this, 10, 40, 180, 70); } void SaveLoadDialog::handleCommand(uint32 cmd) diff --git a/gui/widget.cpp b/gui/widget.cpp index bf45fb522f..82e98f7989 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -45,7 +45,7 @@ void Widget::draw() // Clear background (unless alpha blending is enabled) if (_flags & WIDGET_CLEARBG && !_boss->_screenBuf) - gui->fillArea(_x, _y, _w, _h, gui->_bgcolor); + gui->fillRect(_x, _y, _w, _h, gui->_bgcolor); // Draw border if (_flags & WIDGET_BORDER) { @@ -58,7 +58,7 @@ void Widget::draw() drawWidget(_flags & WIDGET_HILITED); // Flag the draw area as dirty - gui->setAreaDirty(_x, _y, _w, _h); + gui->addDirtyRect(_x, _y, _w, _h); // Restore x/y if (_flags & WIDGET_BORDER) { @@ -74,11 +74,31 @@ void Widget::draw() StaticTextWidget::StaticTextWidget(Dialog *boss, int x, int y, int w, int h, const char *text) - : Widget (boss, x, y, w, h) + : Widget (boss, x, y, w, h), _text(0) { - // FIXME - maybe we should make a real copy of the string? - _text = text; _type = kStaticTextWidget; + setText(text); +} + +StaticTextWidget::~StaticTextWidget() +{ + if (_text) { + free(_text); + _text = 0; + } +} + +void StaticTextWidget::setText(const char *text) +{ + // Free old text if any + if (_text) + free(_text); + + // Duplicate new text + if (text) + _text = strdup(text); + else + _text = 0; } void StaticTextWidget::drawWidget(bool hilite) @@ -148,7 +168,7 @@ void CheckboxWidget::drawWidget(bool hilite) if (_state) gui->drawBitmap(checked_img, _x + 3, _y + 3, gui->_textcolor); else - gui->fillArea(_x + 2, _y + 2, 10, 10, gui->_bgcolor); + gui->fillRect(_x + 2, _y + 2, 10, 10, gui->_bgcolor); // Finally draw the label gui->drawString(_text, _x + 20, _y + 3, _w, gui->_textcolor); @@ -163,6 +183,17 @@ SliderWidget::SliderWidget(Dialog *boss, int x, int y, int w, int h, const char _type = kSliderWidget; } +void SliderWidget::handleMouseMoved(int x, int y, int state) { + if (state == 1) { + int newvalue = x * 100 / _w; + + if (newvalue != _value) { + _value = newvalue; + draw(); + } + } +} + void SliderWidget::drawWidget(bool hilite) { NewGui *gui = _boss->getGui(); @@ -172,21 +203,10 @@ void SliderWidget::drawWidget(bool hilite) // Remove old 'bar' if necessary if (_value != _old_value) { - gui->fillArea(_x + 2 + ((_w - 5) * _old_value / 100), _y + 2, 2, _h - 4, gui->_bgcolor); + gui->fillRect(_x + 2 + ((_w - 5) * _old_value / 100), _y + 2, 2, _h - 4, gui->_bgcolor); _old_value = _value; } // Draw the 'bar' - gui->fillArea(_x + 2 + ((_w - 5) * _value / 100), _y + 2, 2, _h - 4, hilite ? gui->_textcolorhi : gui->_textcolor); -} - -void SliderWidget::handleMouseMoved(int x, int y, int state) { - if (state == 1) { - int newvalue = x * 100 / _w; - - if (newvalue != _value) { - _value = newvalue; - draw(); - } - } + gui->fillRect(_x + 2 + ((_w - 5) * _value / 100), _y + 2, 2, _h - 4, hilite ? gui->_textcolorhi : gui->_textcolor); } diff --git a/gui/widget.h b/gui/widget.h index 651b86a12d..a061e31c85 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -40,7 +40,8 @@ enum { kStaticTextWidget = 'TEXT', kButtonWidget = 'BTTN', kCheckboxWidget = 'CHKB', - kSliderWidget = 'SLDE' + kSliderWidget = 'SLDE', + kListWidget = 'LIST' }; /* Widget */ @@ -56,11 +57,13 @@ protected: int _flags; public: Widget(Dialog *boss, int x, int y, int w, int h); + virtual ~Widget() {} - virtual void handleClick(int button) {} - virtual void handleMouseEntered(int button) {} - virtual void handleMouseLeft(int button) {} + virtual void handleClick(int button) {} + virtual void handleMouseEntered(int button) {} + virtual void handleMouseLeft(int button) {} virtual void handleMouseMoved(int x, int y, int button) {} + virtual void handleKey(char key, int modifiers) {} void draw(); void setFlags(int flags) { _flags |= flags; } @@ -75,11 +78,12 @@ protected: /* StaticTextWidget */ class StaticTextWidget : public Widget { protected: - const char *_text; + char *_text; public: StaticTextWidget(Dialog *boss, int x, int y, int w, int h, const char *text); + ~StaticTextWidget(); void setText(const char *text); - const char *getText(); + const char *getText() const { return _text; } protected: void drawWidget(bool hilite); @@ -95,7 +99,7 @@ protected: public: ButtonWidget(Dialog *boss, int x, int y, int w, int h, const char *label, uint32 cmd = 0, uint8 hotkey = 0); void setCmd(uint32 cmd) { _cmd = cmd; } - uint32 getCmd() { return _cmd; } + uint32 getCmd() const { return _cmd; } void handleClick(int button); void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); } @@ -109,7 +113,7 @@ protected: public: CheckboxWidget(Dialog *boss, int x, int y, int w, int h, const char *label, uint32 cmd = 0, uint8 hotkey = 0); void setState(bool state) { _state = state; } - bool getState() { return _state; } + bool getState() const { return _state; } void handleClick(int button); virtual void handleMouseEntered(int button) {} @@ -126,7 +130,7 @@ protected: public: SliderWidget(Dialog *boss, int x, int y, int w, int h, const char *label, uint32 cmd = 0, uint8 hotkey = 0); void setValue(uint8 value) { _value = value; } - uint8 getValue() { return _value; } + uint8 getValue() const { return _value; } void handleMouseMoved(int x, int y, int button); @@ -135,5 +139,4 @@ protected: }; - #endif diff --git a/newgui.cpp b/newgui.cpp index b16f3fbc83..199fb720ff 100644 --- a/newgui.cpp +++ b/newgui.cpp @@ -24,9 +24,6 @@ #include "guimaps.h" #include "gui/dialog.h" -#define hline(x, y, x2, color) line(x, y, x2, y, color); -#define vline(x, y, y2, color) line(x, y, x, y2, color); - // 8-bit alpha blending routines int BlendCache[256][256]; @@ -51,7 +48,7 @@ int RGBMatch(byte *palette, int r, int g, int b) { } int Blend(int src, int dst, byte *palette) { - int r, g, b, idx; + int r, g, b; int alpha = 128; // Level of transparency [0-256] byte *srcpal = palette + (dst * 3); byte *dstpal = palette + (src * 3); @@ -138,6 +135,18 @@ void NewGui::loop() saveState(); if (_use_alpha_blending) activeDialog->setupScreenBuf(); +#if 1 + // FIXME - hack to encode our own custom GUI colors. Since we have to live + // with a given 8 bit palette, the result is not always as nice as one + // would wish, but this is just an experiment after all. + _bgcolor = RGBMatch(_s->_currentPalette, 0, 0, 0); + + _color = RGBMatch(_s->_currentPalette, 80, 80, 80); + _shadowcolor = RGBMatch(_s->_currentPalette, 64, 64, 64); + + _textcolor = RGBMatch(_s->_currentPalette, 32, 192, 32); + _textcolorhi = RGBMatch(_s->_currentPalette, 0, 256, 0); +#endif _prepare_for_gui = false; } @@ -320,7 +329,7 @@ void NewGui::line(int x, int y, int x2, int y2, byte color) } } -void NewGui::blendArea(int x, int y, int w, int h, byte color) +void NewGui::blendRect(int x, int y, int w, int h, byte color) { byte *ptr = getBasePtr(x, y); if (ptr == NULL) @@ -334,7 +343,7 @@ void NewGui::blendArea(int x, int y, int w, int h, byte color) } } -void NewGui::fillArea(int x, int y, int w, int h, byte color) +void NewGui::fillRect(int x, int y, int w, int h, byte color) { byte *ptr = getBasePtr(x, y); if (ptr == NULL) @@ -348,7 +357,28 @@ void NewGui::fillArea(int x, int y, int w, int h, byte color) } } -void NewGui::setAreaDirty(int x, int y, int w, int h) +void NewGui::frameRect(int x, int y, int w, int h, byte color) +{ + int i; + byte *ptr, *basePtr = getBasePtr(x, y); + if (basePtr == NULL) + return; + + ptr = basePtr; + for (i = 0; i < w; i++, ptr++) + *ptr = color; + ptr--; + for (i = 0; i < h; i++, ptr += 320) + *ptr = color; + ptr = basePtr; + for (i = 0; i < h; i++, ptr += 320) + *ptr = color; + ptr -= 320; + for (i = 0; i < w; i++, ptr++) + *ptr = color; +} + +void NewGui::addDirtyRect(int x, int y, int w, int h) { VirtScreen *vs = _s->findVirtScreen(y); @@ -26,6 +26,9 @@ class Dialog; class Scumm; +#define hline(x, y, x2, color) line(x, y, x2, y, color); +#define vline(x, y, y2, color) line(x, y, x, y2, color); + // Extremly simple stack class, doesn't even do any error checking (for now) class DialogStack { protected: @@ -97,9 +100,10 @@ public: byte *getBasePtr(int x, int y); void box(int x, int y, int width, int height); void line(int x, int y, int x2, int y2, byte color); - void blendArea(int x, int y, int w, int h, byte color); - void fillArea(int x, int y, int w, int h, byte color); - void setAreaDirty(int x, int y, int w, int h); + void blendRect(int x, int y, int w, int h, byte color); + void fillRect(int x, int y, int w, int h, byte color); + void frameRect(int x, int y, int w, int h, byte color); + void addDirtyRect(int x, int y, int w, int h); void drawChar(const char c, int x, int y); void drawString(const char *str, int x, int y, int w, byte color); diff --git a/scummvm.cpp b/scummvm.cpp index 938837c23b..73939f236b 100644 --- a/scummvm.cpp +++ b/scummvm.cpp @@ -1549,10 +1549,17 @@ void Scumm::setupGUIColors() { /* FIXME: strange IF line? */ if (_gameId && !(_features & GF_SMALL_HEADER) && !(_features & GF_AFTER_V7)) { - _newgui->_bgcolor = _gui->_bgcolor = getDefaultGUIColor(0); - _newgui->_color = _gui->_color = getDefaultGUIColor(1); - _newgui->_textcolor = _gui->_textcolor = getDefaultGUIColor(2); - _newgui->_textcolorhi = _gui->_textcolorhi = getDefaultGUIColor(6); - _newgui->_shadowcolor = _gui->_shadowcolor = getDefaultGUIColor(8); + _gui->_bgcolor = getDefaultGUIColor(0); + _gui->_color = getDefaultGUIColor(1); + _gui->_textcolor = getDefaultGUIColor(2); + _gui->_textcolorhi = getDefaultGUIColor(6); + _gui->_shadowcolor = getDefaultGUIColor(8); +#if 0 + _newgui->_bgcolor = getDefaultGUIColor(0); + _newgui->_color = getDefaultGUIColor(1); + _newgui->_textcolor = getDefaultGUIColor(2); + _newgui->_textcolorhi = getDefaultGUIColor(6); + _newgui->_shadowcolor = getDefaultGUIColor(8); +#endif } } |