diff options
-rw-r--r-- | Makefile.common | 2 | ||||
-rw-r--r-- | common/str.cpp | 16 | ||||
-rw-r--r-- | common/str.h | 43 | ||||
-rw-r--r-- | gui/ListWidget.h | 5 | ||||
-rw-r--r-- | gui/message.cpp | 73 | ||||
-rw-r--r-- | gui/message.h | 35 | ||||
-rw-r--r-- | gui/newgui.cpp | 17 | ||||
-rw-r--r-- | gui/newgui.h | 13 | ||||
-rw-r--r-- | scumm/dialogs.h | 11 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 16 |
10 files changed, 198 insertions, 33 deletions
diff --git a/Makefile.common b/Makefile.common index 7f67006613..758bfce9e5 100644 --- a/Makefile.common +++ b/Makefile.common @@ -14,7 +14,7 @@ COMMON_OBJS = common/config-file.o common/engine.o common/file.o \ common/timer.o common/util.o GUI_OBJS = gui/gui.o gui/newgui.o gui/widget.o gui/dialog.o gui/ListWidget.o \ - gui/ScrollBarWidget.o + gui/ScrollBarWidget.o gui/message.o SCUMM_OBJS = scumm/actor.o scumm/akos.o scumm/boxes.o scumm/bundle.o \ scumm/costume.o scumm/debug.o scumm/debugrl.o scumm/gfx.o scumm/imuse.o \ diff --git a/common/str.cpp b/common/str.cpp index 9390f6ff47..6a2333d39c 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -22,19 +22,27 @@ #include "str.h" #include "util.h" + #ifdef _MSC_VER + # pragma warning( disable : 4068 ) // unknown pragmas + #endif + namespace ScummVM { -String::String(const char *str) +String::String(const char *str, int len) { _refCount = new int(1); - if (str) { - _capacity = _len = resStrLen(str); + if (str) { + if (len) + _capacity = _len = len; + else + _capacity = _len = resStrLen(str); _str = (char *)calloc(1, _capacity+1); - memcpy(_str, str, _len+1); + memcpy(_str, str, _len); + _str[_len] = 0; } else { _capacity = _len = 0; _str = 0; diff --git a/common/str.h b/common/str.h index b35c42d0e5..3776ab64c3 100644 --- a/common/str.h +++ b/common/str.h @@ -33,7 +33,7 @@ namespace ScummVM { Only constructor: ConstString(const char *ptr) Then whenever you now use "const String &" in a parameter, use "const ConstString &" instead (mayhaps make a typedef even). Thus, parameters are passed w/o - causing a free/malloc. Then only for permenant storage, when we assign it to a + causing a free/malloc. Then only for permanent storage, when we assign it to a real String object, will a malloc be issued (to this end, make String aware of ConstString ?!? */ @@ -46,7 +46,7 @@ protected: public: ConstString() : _str(0), _len(0) {} - ConstString(const char *str) : _str((char*)str) { _len = str ? strlen(str) : 0; } + ConstString(const char *str, int len = 0) : _str((char*)str) { _len = str ? (len ? len : strlen(str)) : 0; } virtual ~ConstString() {} bool operator ==(const ConstString& x) const; @@ -58,6 +58,12 @@ public: bool operator >(const ConstString& x) const; bool operator >=(const ConstString& x) const; + char operator [](int idx) const + { + assert(_str && idx >= 0 && idx < _len); + return _str[idx]; + } + const char *c_str() const { return _str; } int size() const { return _len; } @@ -71,17 +77,33 @@ protected: public: String() : _capacity(0) { _refCount = new int(1); } - String(const char *str); + String(const char *str, int len = 0); String(const ConstString &str); String(const String &str); virtual ~String(); String& operator =(const char* str); +// TODO - We should use RTTI here - that is, not real C++ RTTI but some magic +// constant in each string object. We want to be able to optimize the case when +// a real 'String' object is passed to a function as a ConstString obj and then +// assigned to a 'String' object String& operator =(const String& str); String& operator +=(const char* str); String& operator +=(const String& str); String& operator +=(char c); + char operator [](int idx) const + { + assert(_str && idx >= 0 && idx < _len); + return _str[idx]; + } + + char &operator [](int idx) + { + assert(_str && idx >= 0 && idx < _len); + return _str[idx]; + } + void deleteLastChar(); void clear(); @@ -99,8 +121,19 @@ public: void push_back(const char* str) { ensureCapacity(_size + 1); - _data[_size] = str; - _size++; + _data[_size++] = str; + } + + void push_back(const ConstString& str) + { + ensureCapacity(_size + 1); + _data[_size++] = str; + } + + void push_back(const String& str) + { + ensureCapacity(_size + 1); + _data[_size++] = str; } }; diff --git a/gui/ListWidget.h b/gui/ListWidget.h index c778b2e807..106e61ceb6 100644 --- a/gui/ListWidget.h +++ b/gui/ListWidget.h @@ -32,11 +32,6 @@ enum { kListNumberingOne = 1 }; -// Height of a signle entry line -enum { - kLineHeight = 11 -}; - // Some special commands enum { kListItemDoubleClickedCmd = 'LIdb', // 'data' will be item index diff --git a/gui/message.cpp b/gui/message.cpp new file mode 100644 index 0000000000..351b120797 --- /dev/null +++ b/gui/message.cpp @@ -0,0 +1,73 @@ +/* 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 "message.h" +#include "newgui.h" + +#include "common/list.h" + + +MessageDialog::MessageDialog(NewGui *gui, const String &message) + : Dialog(gui, 30, 20, 260, 124) +{ + // First, determine the size the dialog needs. For this we have to break + // down the string into lines, and taking the maximum of their widths. + // Using this, and accounting for the space the button(s) need, we can set + // the real size of the dialog + ScummVM::StringList lines; + String tmp; + const char *str = message.c_str(); + const char *start = str; + int lineWidth, maxlineWidth = 0; + + while (*str) { + if (*str == '\n') { + tmp = String(start, str - start); + lines.push_back(tmp); + lineWidth = _gui->getStringWidth(tmp); + if (maxlineWidth < lineWidth) + maxlineWidth = lineWidth; + start = str + 1; + } + + ++str; + } + if (*start) { + tmp = String(start, str - start); + lines.push_back(tmp); + lineWidth = _gui->getStringWidth(tmp); + if (maxlineWidth < lineWidth) + maxlineWidth = lineWidth; + } + + // TODO - we should probably check for over/underflows here + _w = maxlineWidth + 20; + _h = lines.size() * kLineHeight + 30; + _x = (320 - _w) / 2; + + for (int i = 0; i < lines.size(); i++) { + new StaticTextWidget(this, 10, 10+i*kLineHeight, maxlineWidth, kLineHeight, + lines[i], kTextAlignCenter); + } + + // FIXME - the vertical position has to be adjusted + addButton((_w - 54)/2, _h - 20, 54, 16, "OK", kCloseCmd, '\n'); // Confirm dialog +} diff --git a/gui/message.h b/gui/message.h new file mode 100644 index 0000000000..136d96be98 --- /dev/null +++ b/gui/message.h @@ -0,0 +1,35 @@ +/* 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 MESSAGE_DIALOG_H +#define MESSAGE_DIALOG_H + +#include "dialog.h" +#include "common/str.h" + +class MessageDialog : public Dialog { + typedef ScummVM::String String; +public: + MessageDialog(NewGui *gui, const String &message); + +protected: +}; + +#endif diff --git a/gui/newgui.cpp b/gui/newgui.cpp index 7adfa1aaea..dbdf9d170d 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -401,11 +401,12 @@ void NewGui::drawChar(const char chr, int xx, int yy, int16 color) } } -int NewGui::getStringWidth(const char *str) +int NewGui::getStringWidth(const String &str) { int space = 0; - while (*str) - space += getCharWidth(*str++); + + for (int i = 0; i < str.size(); ++i) + space += getCharWidth(str[i]); return space; } @@ -414,17 +415,17 @@ int NewGui::getCharWidth(char c) return guifont[c+6]; } -void NewGui::drawString(const char *str, int x, int y, int w, int16 color, int align) +void NewGui::drawString(const String &str, int x, int y, int w, int16 color, int align) { int width = getStringWidth(str); if (align == kTextAlignCenter) x = x + (w - width - 1)/2; else if (align == kTextAlignRight) x = x + w - width; - while (*str) { - drawChar(*str, x, y, color); - x += getCharWidth(*str); - str++; + + for (int i = 0; i < str.size(); ++i) { + drawChar(str[i], x, y, color); + x += getCharWidth(str[i]); } } diff --git a/gui/newgui.h b/gui/newgui.h index b1ce4daeea..455904026d 100644 --- a/gui/newgui.h +++ b/gui/newgui.h @@ -23,12 +23,20 @@ #include "scummsys.h" #include "system.h" // For events +#include "common/str.h" class Dialog; #define hline(x, y, x2, color) line(x, y, x2, y, color); #define vline(x, y, y2, color) line(x, y, x, y2, color); +// Height of a single text line +enum { + kLineHeight = 11 +}; + + +// Text alignment modes for drawString() enum { kTextAlignLeft, kTextAlignCenter, @@ -59,6 +67,7 @@ public: // This class hopefully will replace the old Gui class completly one day class NewGui { friend class Dialog; + typedef ScummVM::String String; public: // Main entry for the GUI: this will start an event loop that keeps running @@ -123,9 +132,9 @@ public: void frameRect(int x, int y, int w, int h, int16 color); void addDirtyRect(int x, int y, int w, int h); void drawChar(char c, int x, int y, int16 color); - int getStringWidth(const char *str); + int getStringWidth(const String &str); int getCharWidth(char c); - void drawString(const char *str, int x, int y, int w, int16 color, int align = kTextAlignLeft); + void drawString(const String &str, int x, int y, int w, int16 color, int align = kTextAlignLeft); void drawBitmap(uint32 bitmap[8], int x, int y, int16 color); }; diff --git a/scumm/dialogs.h b/scumm/dialogs.h index 61260ac6ca..bc8111ea8b 100644 --- a/scumm/dialogs.h +++ b/scumm/dialogs.h @@ -63,16 +63,13 @@ public: AboutDialog(NewGui *gui, Scumm *scumm); }; -class SoundDialog; -class KeysDialog; -class MiscDialog; class OptionsDialog : public ScummDialog { protected: - AboutDialog *_aboutDialog; - SoundDialog *_soundDialog; - KeysDialog *_keysDialog; - MiscDialog *_miscDialog; + Dialog *_aboutDialog; + Dialog *_soundDialog; + Dialog *_keysDialog; + Dialog *_miscDialog; public: OptionsDialog(NewGui *gui, Scumm *scumm); diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index 6a8e9df268..cc5fdde180 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -33,6 +33,7 @@ #include "gameDetector.h" #include "gui/gui.h" #include "gui/newgui.h" +#include "gui/message.h" #include "object.h" #include "resource.h" #include "string.h" @@ -936,8 +937,21 @@ void Scumm::runDialog(Dialog *dialog) void Scumm::pauseDialog() { - if (!_pauseDialog) + if (!_pauseDialog) { +#if 1 + // HACK HACK + const char *message = "This demonstrates MessageDialog's abilities.\n" + "For example it supports multi line text.\n" + " \n" + "Well, not much more right now, really :-)\n" + "And there are still some bugs in it, too\n" + " "; // <- FIXME: This is needed due to a bug... + _pauseDialog = new MessageDialog(_newgui, message); +#else _pauseDialog = new PauseDialog(_newgui, this); +#endif + } + runDialog(_pauseDialog); } |