Initial commit
This commit is contained in:
256
engines/ultima/ultima8/gumps/widgets/button_widget.cpp
Normal file
256
engines/ultima/ultima8/gumps/widgets/button_widget.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/gumps/widgets/button_widget.h"
|
||||
#include "ultima/ultima8/gumps/widgets/text_widget.h"
|
||||
#include "ultima/ultima8/games/game_data.h"
|
||||
#include "ultima/ultima8/gfx/shape_archive.h"
|
||||
#include "ultima/ultima8/gfx/shape.h"
|
||||
#include "ultima/ultima8/kernel/mouse.h"
|
||||
#include "ultima/ultima8/world/get_object.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
// p_dynamic_class stuff
|
||||
DEFINE_RUNTIME_CLASSTYPE_CODE(ButtonWidget)
|
||||
|
||||
ButtonWidget::ButtonWidget() : Gump(), _shapeUp(nullptr), _shapeDown(nullptr),
|
||||
_mouseOver(false), _origW(0), _origH(0), _frameNumUp(0),
|
||||
_frameNumDown(0), _mouseOverBlendCol(0), _textWidget(0) {
|
||||
}
|
||||
|
||||
ButtonWidget::ButtonWidget(int x, int y, Std::string txt, bool gamefont,
|
||||
int font, uint32 mouseOverBlendCol,
|
||||
int w, int h, int32 layer) :
|
||||
Gump(x, y, w, h, 0, 0, layer), _shapeUp(nullptr), _shapeDown(nullptr),
|
||||
_mouseOver(false), _origW(w), _origH(h), _frameNumUp(0), _frameNumDown(0) {
|
||||
TextWidget *widget = new TextWidget(0, 0, txt, gamefont, font, w, h);
|
||||
// FIXME: Do we ever free this widget?
|
||||
_textWidget = widget->getObjId();
|
||||
_mouseOverBlendCol = mouseOverBlendCol;
|
||||
_mouseOver = (_mouseOverBlendCol != 0);
|
||||
}
|
||||
|
||||
ButtonWidget::ButtonWidget(int x, int y, FrameID frame_up, FrameID frame_down,
|
||||
bool mouseOver, int32 layer)
|
||||
: Gump(x, y, 5, 5, 0, 0, layer), _textWidget(0), _mouseOver(mouseOver),
|
||||
_origW(0), _origH(0), _mouseOverBlendCol(0) {
|
||||
_shapeUp = GameData::get_instance()->getShape(frame_up);
|
||||
_shapeDown = GameData::get_instance()->getShape(frame_down);
|
||||
_frameNumUp = frame_up._frameNum;
|
||||
_frameNumDown = frame_down._frameNum;
|
||||
}
|
||||
|
||||
|
||||
ButtonWidget::~ButtonWidget(void) {
|
||||
}
|
||||
|
||||
void ButtonWidget::InitGump(Gump *newparent, bool take_focus) {
|
||||
Gump::InitGump(newparent, take_focus);
|
||||
|
||||
if (_textWidget != 0) {
|
||||
Gump *widget = getGump(_textWidget);
|
||||
assert(widget);
|
||||
widget->InitGump(this);
|
||||
_dims = widget->getDims(); // transfer child dimension to self
|
||||
widget->Move(0, _dims.top); // move it to the correct height
|
||||
} else {
|
||||
assert(_shapeUp != nullptr);
|
||||
assert(_shapeDown != nullptr);
|
||||
|
||||
SetShape(_shapeUp, _frameNumUp);
|
||||
UpdateDimsFromShape();
|
||||
}
|
||||
}
|
||||
|
||||
int ButtonWidget::getVlead() {
|
||||
if (_textWidget != 0) {
|
||||
Gump *widget = getGump(_textWidget);
|
||||
TextWidget *txtWidget = dynamic_cast<TextWidget *>(widget);
|
||||
assert(txtWidget);
|
||||
return txtWidget->getVlead();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ButtonWidget::PointOnGump(int mx, int my) {
|
||||
// CHECKME: this makes the ButtonWidget accept any point in its rectangle,
|
||||
// effectively ignoring shape transparency. For some buttons (like those
|
||||
// in U8's diary), this is desirable. For others it may not be, so this
|
||||
// behaviour may need to be changed. (bool ignoreShapeTransparency or
|
||||
// something)
|
||||
|
||||
int32 gx = mx, gy = my;
|
||||
ParentToGump(gx, gy);
|
||||
|
||||
return _dims.contains(gx, gy);
|
||||
}
|
||||
|
||||
Gump *ButtonWidget::onMouseDown(int button, int32 mx, int32 my) {
|
||||
Gump *ret = Gump::onMouseDown(button, mx, my);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (button == Mouse::BUTTON_LEFT) {
|
||||
// CHECKME: change dimensions or not?
|
||||
if (!_mouseOver) {
|
||||
_shape = _shapeDown;
|
||||
_frameNum = _frameNumDown;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint16 ButtonWidget::TraceObjId(int32 mx, int32 my) {
|
||||
if (PointOnGump(mx, my))
|
||||
return getObjId();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ButtonWidget::onMouseUp(int button, int32 mx, int32 my) {
|
||||
if (button == Mouse::BUTTON_LEFT) {
|
||||
if (!_mouseOver) {
|
||||
_shape = _shapeUp;
|
||||
_frameNum = _frameNumUp;
|
||||
}
|
||||
if (PointOnGump(mx, my))
|
||||
_parent->ChildNotify(this, BUTTON_UP);
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonWidget::onMouseClick(int button, int32 mx, int32 my) {
|
||||
if (PointOnGump(mx, my))
|
||||
_parent->ChildNotify(this, BUTTON_CLICK);
|
||||
}
|
||||
|
||||
void ButtonWidget::onMouseDouble(int button, int32 mx, int32 my) {
|
||||
if (PointOnGump(mx, my))
|
||||
_parent->ChildNotify(this, BUTTON_DOUBLE);
|
||||
}
|
||||
|
||||
void ButtonWidget::onMouseOver() {
|
||||
if (_mouseOver) {
|
||||
if (_textWidget) {
|
||||
Gump *widget = getGump(_textWidget);
|
||||
TextWidget *txtWidget = dynamic_cast<TextWidget *>(widget);
|
||||
assert(txtWidget);
|
||||
txtWidget->setBlendColour(_mouseOverBlendCol);
|
||||
} else {
|
||||
_shape = _shapeDown;
|
||||
_frameNum = _frameNumDown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonWidget::onMouseLeft() {
|
||||
if (_mouseOver) {
|
||||
if (_textWidget) {
|
||||
Gump *widget = getGump(_textWidget);
|
||||
TextWidget *txtWidget = dynamic_cast<TextWidget *>(widget);
|
||||
assert(txtWidget);
|
||||
txtWidget->setBlendColour(0);
|
||||
} else {
|
||||
_shape = _shapeUp;
|
||||
_frameNum = _frameNumUp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonWidget::saveData(Common::WriteStream *ws) {
|
||||
// HACK ALERT
|
||||
int w = 0, h = 0;
|
||||
if (_textWidget != 0) {
|
||||
w = _dims.width();
|
||||
h = _dims.height();
|
||||
_dims.setWidth(_origW);
|
||||
_dims.setHeight(_origH);
|
||||
}
|
||||
|
||||
Gump::saveData(ws);
|
||||
|
||||
// HACK ALERT
|
||||
if (_textWidget != 0) {
|
||||
_dims.setWidth(w);
|
||||
_dims.setHeight(h);
|
||||
}
|
||||
|
||||
uint16 flex = 0;
|
||||
uint32 shapenum = 0;
|
||||
if (_shapeUp) {
|
||||
_shapeUp->getShapeId(flex, shapenum);
|
||||
}
|
||||
ws->writeUint16LE(flex);
|
||||
ws->writeUint32LE(shapenum);
|
||||
ws->writeUint32LE(_frameNumUp);
|
||||
|
||||
flex = 0;
|
||||
shapenum = 0;
|
||||
if (_shapeDown) {
|
||||
_shapeDown->getShapeId(flex, shapenum);
|
||||
}
|
||||
ws->writeUint16LE(flex);
|
||||
ws->writeUint32LE(shapenum);
|
||||
ws->writeUint32LE(_frameNumDown);
|
||||
ws->writeUint16LE(_textWidget);
|
||||
ws->writeUint32LE(_mouseOverBlendCol);
|
||||
|
||||
uint8 m = (_mouseOver ? 1 : 0);
|
||||
ws->writeByte(m);
|
||||
}
|
||||
|
||||
bool ButtonWidget::loadData(Common::ReadStream *rs, uint32 version) {
|
||||
if (!Gump::loadData(rs, version)) return false;
|
||||
|
||||
_shapeUp = nullptr;
|
||||
ShapeArchive *flex = GameData::get_instance()->getShapeFlex(rs->readUint16LE());
|
||||
uint32 shapenum = rs->readUint32LE();
|
||||
if (flex) {
|
||||
_shapeUp = flex->getShape(shapenum);
|
||||
}
|
||||
_frameNumUp = rs->readUint32LE();
|
||||
|
||||
_shapeDown = nullptr;
|
||||
flex = GameData::get_instance()->getShapeFlex(rs->readUint16LE());
|
||||
shapenum = rs->readUint32LE();
|
||||
if (flex) {
|
||||
_shapeDown = flex->getShape(shapenum);
|
||||
}
|
||||
_frameNumDown = rs->readUint32LE();
|
||||
_textWidget = rs->readUint16LE();
|
||||
_mouseOverBlendCol = rs->readUint32LE();
|
||||
_mouseOver = (rs->readByte() != 0);
|
||||
|
||||
// HACK ALERT
|
||||
if (_textWidget != 0) {
|
||||
Gump *widget = getGump(_textWidget);
|
||||
_dims = widget->getDims(); // transfer child dimension to self
|
||||
widget->Move(0, _dims.top); // move it to the correct height
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
88
engines/ultima/ultima8/gumps/widgets/button_widget.h
Normal file
88
engines/ultima/ultima8/gumps/widgets/button_widget.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GUMPS_WIDGETS_BUTTONWIDGET_H
|
||||
#define ULTIMA8_GUMPS_WIDGETS_BUTTONWIDGET_H
|
||||
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/ultima8/gumps/gump.h"
|
||||
#include "ultima/ultima8/gfx/frame_id.h"
|
||||
#include "ultima/ultima8/misc/classtype.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class ButtonWidget : public Gump {
|
||||
public:
|
||||
// p_dynamic_class stuff
|
||||
ENABLE_RUNTIME_CLASSTYPE()
|
||||
|
||||
ButtonWidget();
|
||||
ButtonWidget(int x, int y, Std::string txt, bool gamefont, int font,
|
||||
uint32 mouseOverBlendCol = 0, int width = 0, int height = 0,
|
||||
int32 layer = LAYER_NORMAL);
|
||||
ButtonWidget(int x, int y, FrameID frame_up, FrameID frame_down,
|
||||
bool mouseOver = false, int32 layer = LAYER_NORMAL);
|
||||
~ButtonWidget() override;
|
||||
|
||||
void InitGump(Gump *newparent, bool take_focus = true) override;
|
||||
uint16 TraceObjId(int32 mx, int32 my) override;
|
||||
bool PointOnGump(int mx, int my) override;
|
||||
|
||||
Gump *onMouseDown(int button, int32 mx, int32 my) override;
|
||||
void onMouseUp(int button, int32 mx, int32 my) override;
|
||||
void onMouseClick(int button, int32 mx, int32 my) override;
|
||||
void onMouseDouble(int button, int32 mx, int32 my) override;
|
||||
|
||||
void onMouseOver() override;
|
||||
void onMouseLeft() override;
|
||||
|
||||
//! return the textwidget's vlead, or 0 for an image button
|
||||
int getVlead();
|
||||
|
||||
//void SetShapeDown(Shape *_shape, uint32 frameNum);
|
||||
//void SetShapeUp(Shape *_shape, uint32 frameNum);
|
||||
|
||||
enum Message {
|
||||
BUTTON_CLICK = 0,
|
||||
BUTTON_UP = 1,
|
||||
BUTTON_DOUBLE = 2
|
||||
};
|
||||
|
||||
protected:
|
||||
Shape *_shapeUp;
|
||||
uint32 _frameNumUp;
|
||||
Shape *_shapeDown;
|
||||
uint32 _frameNumDown;
|
||||
uint16 _textWidget;
|
||||
uint32 _mouseOverBlendCol;
|
||||
bool _mouseOver;
|
||||
int _origW, _origH;
|
||||
|
||||
public:
|
||||
bool loadData(Common::ReadStream *rs, uint32 version);
|
||||
void saveData(Common::WriteStream *ws) override;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
273
engines/ultima/ultima8/gumps/widgets/edit_widget.cpp
Normal file
273
engines/ultima/ultima8/gumps/widgets/edit_widget.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/gumps/widgets/edit_widget.h"
|
||||
#include "ultima/ultima8/gfx/fonts/rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/render_surface.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font_manager.h"
|
||||
#include "common/system.h"
|
||||
#include "common/events.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
DEFINE_RUNTIME_CLASSTYPE_CODE(EditWidget)
|
||||
|
||||
EditWidget::EditWidget(int x, int y, Std::string txt, bool gamefont, int font,
|
||||
int w, int h, unsigned int maxlength, bool multiline)
|
||||
: Gump(x, y, w, h), _text(txt), _gameFont(gamefont), _fontNum(font),
|
||||
_maxLength(maxlength), _multiLine(multiline),
|
||||
_cursorChanged(0), _cursorVisible(true), _cachedText(nullptr) {
|
||||
_cursor = _text.size();
|
||||
}
|
||||
|
||||
EditWidget::~EditWidget(void) {
|
||||
delete _cachedText;
|
||||
}
|
||||
|
||||
// Init the gump, call after construction
|
||||
void EditWidget::InitGump(Gump *newparent, bool take_focus) {
|
||||
Gump::InitGump(newparent, take_focus);
|
||||
|
||||
Font *font = getFont();
|
||||
|
||||
// Y offset is always baseline
|
||||
_dims.moveTo(0, -font->getBaseline());
|
||||
|
||||
if (_gameFont && getFont()->isHighRes()) {
|
||||
Common::Rect32 rect(_dims);
|
||||
ScreenSpaceToGumpRect(rect, ROUND_OUTSIDE);
|
||||
_dims.moveTo(0, rect.top);
|
||||
}
|
||||
}
|
||||
|
||||
Font *EditWidget::getFont() const {
|
||||
if (_gameFont)
|
||||
return FontManager::get_instance()->getGameFont(_fontNum, true);
|
||||
else
|
||||
return FontManager::get_instance()->getTTFont(_fontNum);
|
||||
}
|
||||
|
||||
void EditWidget::setText(const Std::string &t) {
|
||||
_text = t;
|
||||
_cursor = _text.size();
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
}
|
||||
|
||||
void EditWidget::ensureCursorVisible() {
|
||||
_cursorVisible = true;
|
||||
_cursorChanged = g_system->getMillis();
|
||||
}
|
||||
|
||||
bool EditWidget::textFits(Std::string &t) {
|
||||
Font *font = getFont();
|
||||
|
||||
unsigned int remaining;
|
||||
int32 width, height;
|
||||
|
||||
int32 max_width = _multiLine ? _dims.width() : 0;
|
||||
int32 max_height = _dims.height();
|
||||
if (_gameFont && font->isHighRes()) {
|
||||
Common::Rect32 rect(0, 0, max_width, max_height);
|
||||
GumpRectToScreenSpace(rect, ROUND_INSIDE);
|
||||
|
||||
max_width = rect.width();
|
||||
max_height = rect.height();
|
||||
}
|
||||
|
||||
font->getTextSize(t, width, height, remaining,
|
||||
max_width, max_height,
|
||||
Font::TEXT_LEFT, false);
|
||||
|
||||
if (_gameFont && font->isHighRes()) {
|
||||
Common::Rect32 rect(0, 0, width, height);
|
||||
ScreenSpaceToGumpRect(rect, ROUND_OUTSIDE);
|
||||
|
||||
width = rect.width();
|
||||
height = rect.height();
|
||||
}
|
||||
|
||||
if (_multiLine)
|
||||
return (remaining >= t.size());
|
||||
else
|
||||
return (width <= _dims.width());
|
||||
}
|
||||
|
||||
void EditWidget::renderText() {
|
||||
bool cv = _cursorVisible;
|
||||
if (!IsFocus()) {
|
||||
cv = false;
|
||||
} else {
|
||||
uint32 now = g_system->getMillis();
|
||||
if (now > _cursorChanged + 750) {
|
||||
cv = !_cursorVisible;
|
||||
_cursorChanged = now;
|
||||
}
|
||||
}
|
||||
|
||||
if (cv != _cursorVisible) {
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
_cursorVisible = cv;
|
||||
}
|
||||
|
||||
if (!_cachedText) {
|
||||
Font *font = getFont();
|
||||
|
||||
int32 max_width = _multiLine ? _dims.width() : 0;
|
||||
int32 max_height = _dims.height();
|
||||
if (_gameFont && font->isHighRes()) {
|
||||
Common::Rect32 rect(0, 0, max_width, max_height);
|
||||
GumpRectToScreenSpace(rect, ROUND_INSIDE);
|
||||
|
||||
max_width = rect.width();
|
||||
max_height = rect.height();
|
||||
}
|
||||
|
||||
unsigned int remaining;
|
||||
_cachedText = font->renderText(_text, remaining,
|
||||
max_width, max_height,
|
||||
Font::TEXT_LEFT,
|
||||
false, false,
|
||||
cv ? _cursor : Std::string::npos);
|
||||
|
||||
// Trim text to fit
|
||||
if (remaining < _text.size()) {
|
||||
_text.erase(remaining);
|
||||
_cursor = _text.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Overloadable method to Paint just this Gump (RenderSurface is relative to this)
|
||||
void EditWidget::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
|
||||
Gump::PaintThis(surf, lerp_factor, scaled);
|
||||
|
||||
renderText();
|
||||
|
||||
if (scaled && _gameFont && getFont()->isHighRes()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_cachedText->draw(surf, 0, 0);
|
||||
}
|
||||
|
||||
// Overloadable method to Paint just this gumps unscaled components that require compositing (RenderSurface is relative to parent).
|
||||
void EditWidget::PaintComposited(RenderSurface *surf, int32 lerp_factor, int32 sx, int32 sy) {
|
||||
Font *font = getFont();
|
||||
|
||||
if (!_gameFont || !font->isHighRes()) return;
|
||||
|
||||
int32 x = 0, y = 0;
|
||||
GumpToScreenSpace(x, y, ROUND_BOTTOMRIGHT);
|
||||
|
||||
_cachedText->draw(surf, x, y, true);
|
||||
|
||||
Common::Rect32 rect(_dims);
|
||||
GumpRectToScreenSpace(rect, ROUND_OUTSIDE);
|
||||
}
|
||||
|
||||
// don't handle any mouse motion events, so let parent handle them for us.
|
||||
Gump *EditWidget::onMouseMotion(int32 mx, int32 my) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool EditWidget::OnKeyDown(int key, int mod) {
|
||||
switch (key) {
|
||||
case Common::KEYCODE_RETURN:
|
||||
case Common::KEYCODE_KP_ENTER:
|
||||
_parent->ChildNotify(this, EDIT_ENTER);
|
||||
break;
|
||||
case Common::KEYCODE_ESCAPE:
|
||||
_parent->ChildNotify(this, EDIT_ESCAPE);
|
||||
break;
|
||||
case Common::KEYCODE_BACKSPACE:
|
||||
if (_cursor > 0) {
|
||||
_text.erase(--_cursor, 1);
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
ensureCursorVisible();
|
||||
}
|
||||
break;
|
||||
case Common::KEYCODE_DELETE:
|
||||
if (_cursor != _text.size()) {
|
||||
_text.erase(_cursor, 1);
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
}
|
||||
break;
|
||||
case Common::KEYCODE_LEFT:
|
||||
if (_cursor > 0) {
|
||||
_cursor--;
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
ensureCursorVisible();
|
||||
}
|
||||
break;
|
||||
case Common::KEYCODE_RIGHT:
|
||||
if (_cursor < _text.size()) {
|
||||
_cursor++;
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
ensureCursorVisible();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditWidget::OnKeyUp(int key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EditWidget::OnTextInput(int unicode) {
|
||||
if (_maxLength > 0 && _text.size() >= _maxLength)
|
||||
return true;
|
||||
|
||||
char c = 0;
|
||||
if (unicode >= 0 && unicode < 256)
|
||||
c = reverse_encoding[unicode];
|
||||
if (!c) return true;
|
||||
|
||||
Std::string newtext = _text;
|
||||
newtext.insertChar(c, _cursor);
|
||||
|
||||
if (textFits(newtext)) {
|
||||
_text = newtext;
|
||||
_cursor++;
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditWidget::OnFocus(bool gain) {
|
||||
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, gain);
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
95
engines/ultima/ultima8/gumps/widgets/edit_widget.h
Normal file
95
engines/ultima/ultima8/gumps/widgets/edit_widget.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GUMPS_WIDGETS_EDITWIDGET_H
|
||||
#define ULTIMA8_GUMPS_WIDGETS_EDITWIDGET_H
|
||||
|
||||
//
|
||||
// EditWidget. Widget for text input (single or multi-line)
|
||||
//
|
||||
|
||||
#include "ultima/ultima8/gumps/gump.h"
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
#include "ultima/ultima8/misc/classtype.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class RenderedText;
|
||||
|
||||
class EditWidget : public Gump {
|
||||
public:
|
||||
ENABLE_RUNTIME_CLASSTYPE()
|
||||
|
||||
EditWidget(int x, int y, Std::string txt, bool gamefont, int fontnum,
|
||||
int width, int height, unsigned int maxlength = 0,
|
||||
bool multiline = false);
|
||||
~EditWidget() override;
|
||||
|
||||
void InitGump(Gump *newparent, bool take_focus = true) override;
|
||||
|
||||
void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
|
||||
void PaintComposited(RenderSurface *surf, int32 lerp_factor, int32 sx, int32 sy) override;
|
||||
|
||||
Gump *onMouseMotion(int32 mx, int32 my) override;
|
||||
bool OnKeyDown(int key, int mod) override;
|
||||
bool OnKeyUp(int key) override;
|
||||
bool OnTextInput(int unicode) override;
|
||||
|
||||
void OnFocus(bool gain) override;
|
||||
|
||||
//! get the current text
|
||||
Std::string getText() const {
|
||||
return _text;
|
||||
}
|
||||
void setText(const Std::string &t);
|
||||
|
||||
enum Message {
|
||||
EDIT_ENTER = 16,
|
||||
EDIT_ESCAPE = 17
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
Std::string _text;
|
||||
Std::string::size_type _cursor;
|
||||
bool _gameFont;
|
||||
int _fontNum;
|
||||
unsigned int _maxLength;
|
||||
bool _multiLine;
|
||||
|
||||
uint32 _cursorChanged;
|
||||
bool _cursorVisible;
|
||||
|
||||
void ensureCursorVisible();
|
||||
bool textFits(Std::string &t);
|
||||
void renderText();
|
||||
Font *getFont() const;
|
||||
|
||||
RenderedText *_cachedText;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
107
engines/ultima/ultima8/gumps/widgets/sliding_widget.cpp
Normal file
107
engines/ultima/ultima8/gumps/widgets/sliding_widget.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/gumps/widgets/sliding_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
DEFINE_RUNTIME_CLASSTYPE_CODE(SlidingWidget)
|
||||
|
||||
SlidingWidget::SlidingWidget()
|
||||
: Gump(), _dragBounds() {
|
||||
}
|
||||
|
||||
SlidingWidget::SlidingWidget(int x, int y, FrameID frame, const Common::Rect32 &dragBounds)
|
||||
: Gump(x, y, 5, 5, 0, FLAG_DRAGGABLE), _dragBounds(dragBounds) {
|
||||
SetShape(frame, true);
|
||||
if (_dragBounds.width() < _dims.width())
|
||||
_dragBounds.setWidth(_dims.width());
|
||||
if (_dragBounds.height() < _dims.height())
|
||||
_dragBounds.setHeight(_dims.height());
|
||||
}
|
||||
|
||||
SlidingWidget::~SlidingWidget() {
|
||||
}
|
||||
|
||||
int SlidingWidget::getValueForRange(int min, int max) {
|
||||
int val = min;
|
||||
if (_dragBounds.isValidRect()) {
|
||||
val = min + (_x - _dragBounds.left) * (max - min) / (_dragBounds.width() - _dims.width());
|
||||
if (val < min)
|
||||
val = min;
|
||||
if (val > max)
|
||||
val = max;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
void SlidingWidget::setValueForRange(int value, int min, int max) {
|
||||
assert(_dragBounds.isValidRect());
|
||||
_x = _dragBounds.left + (value - min) * (_dragBounds.width() - _dims.width()) / (max - min);
|
||||
}
|
||||
|
||||
void SlidingWidget::InitGump(Gump *newparent, bool take_focus) {
|
||||
Gump::InitGump(newparent, take_focus);
|
||||
|
||||
UpdateDimsFromShape();
|
||||
}
|
||||
|
||||
uint16 SlidingWidget::TraceObjId(int32 mx, int32 my) {
|
||||
if (PointOnGump(mx, my))
|
||||
return getObjId();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SlidingWidget::Move(int32 x, int32 y) {
|
||||
if (_dragBounds.isValidRect()) {
|
||||
if (x < _dragBounds.left)
|
||||
x = _dragBounds.left;
|
||||
if (x > _dragBounds.right - _dims.width())
|
||||
x = _dragBounds.right - _dims.width();
|
||||
if (y < _dragBounds.top)
|
||||
y = _dragBounds.top;
|
||||
if (y > _dragBounds.bottom - _dims.height())
|
||||
y = _dragBounds.bottom - _dims.height();
|
||||
}
|
||||
|
||||
_x = x;
|
||||
_y = y;
|
||||
}
|
||||
|
||||
void SlidingWidget::onDrag(int32 mx, int32 my) {
|
||||
Gump::onDrag(mx, my);
|
||||
_parent->ChildNotify(this, DRAGGING);
|
||||
}
|
||||
|
||||
void SlidingWidget::saveData(Common::WriteStream *ws) {
|
||||
Gump::saveData(ws);
|
||||
}
|
||||
|
||||
bool SlidingWidget::loadData(Common::ReadStream *rs, uint32 version) {
|
||||
if (!Gump::loadData(rs, version)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
62
engines/ultima/ultima8/gumps/widgets/sliding_widget.h
Normal file
62
engines/ultima/ultima8/gumps/widgets/sliding_widget.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GUMPS_WIDGETS_SLIDINGWIDGET_H
|
||||
#define ULTIMA8_GUMPS_WIDGETS_SLIDINGWIDGET_H
|
||||
|
||||
#include "ultima/ultima8/gumps/gump.h"
|
||||
#include "ultima/ultima8/misc/classtype.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class SlidingWidget : public Gump {
|
||||
protected:
|
||||
Common::Rect32 _dragBounds;
|
||||
|
||||
public:
|
||||
ENABLE_RUNTIME_CLASSTYPE()
|
||||
|
||||
SlidingWidget();
|
||||
SlidingWidget(int x, int y, FrameID frame, const Common::Rect32 &dragBounds);
|
||||
~SlidingWidget() override;
|
||||
|
||||
int getValueForRange(int min, int max);
|
||||
void setValueForRange(int value, int min, int max);
|
||||
|
||||
void InitGump(Gump *newparent, bool take_focus = true) override;
|
||||
uint16 TraceObjId(int32 mx, int32 my) override;
|
||||
|
||||
void Move(int32 x, int32 y) override;
|
||||
void onDrag(int32 mx, int32 my) override;
|
||||
|
||||
bool loadData(Common::ReadStream *rs, uint32 version);
|
||||
void saveData(Common::WriteStream *ws) override;
|
||||
|
||||
enum Message {
|
||||
DRAGGING = 0
|
||||
};
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
260
engines/ultima/ultima8/gumps/widgets/text_widget.cpp
Normal file
260
engines/ultima/ultima8/gumps/widgets/text_widget.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/gumps/widgets/text_widget.h"
|
||||
#include "ultima/ultima8/gfx/fonts/rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/render_surface.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font_manager.h"
|
||||
#include "ultima/ultima8/gumps/bark_gump.h"
|
||||
#include "ultima/ultima8/gumps/ask_gump.h"
|
||||
#include "ultima/ultima8/gumps/widgets/button_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
DEFINE_RUNTIME_CLASSTYPE_CODE(TextWidget)
|
||||
|
||||
TextWidget::TextWidget() : Gump(), _gameFont(false), _fontNum(0), _blendColour(0),
|
||||
_tx(0), _ty(0), _currentStart(0), _currentEnd(0), _targetWidth(0), _targetHeight(0),
|
||||
_cachedText(nullptr), _textAlign(Font::TEXT_LEFT) {
|
||||
}
|
||||
|
||||
TextWidget::TextWidget(int x, int y, const Std::string &txt, bool gamefont, int font,
|
||||
int w, int h, Font::TextAlign align, bool dopaging) :
|
||||
Gump(x, y, w, h), _text(txt), _gameFont(gamefont), _fontNum(font),
|
||||
_blendColour(0), _currentStart(0), _currentEnd(0), _tx(0), _ty(0),
|
||||
_doPaging(dopaging), _targetWidth(w), _targetHeight(h),
|
||||
_cachedText(nullptr), _textAlign(align) {
|
||||
}
|
||||
|
||||
TextWidget::~TextWidget(void) {
|
||||
delete _cachedText;
|
||||
}
|
||||
|
||||
// Init the gump, call after construction
|
||||
void TextWidget::InitGump(Gump *newparent, bool take_focus) {
|
||||
Gump::InitGump(newparent, take_focus);
|
||||
|
||||
Font *font = getFont();
|
||||
|
||||
// Y offset is always baseline
|
||||
_dims.moveTo(0, -font->getBaseline());
|
||||
|
||||
if (_gameFont && getFont()->isHighRes()) {
|
||||
Common::Rect32 rect(_dims);
|
||||
ScreenSpaceToGumpRect(rect, ROUND_OUTSIDE);
|
||||
_dims.moveTo(0, rect.top);
|
||||
|
||||
// Note that GumpRectToScreenSpace is guaranteed to keep
|
||||
// _targetWidth/_targetHeight zero if they already were.
|
||||
Common::Rect32 target(_dims);
|
||||
GumpRectToScreenSpace(target, ROUND_OUTSIDE);
|
||||
|
||||
_targetWidth = target.width();
|
||||
_targetHeight = target.height();
|
||||
|
||||
Common::Rect32 sr(0, 0, _targetWidth, _targetHeight);
|
||||
ScreenSpaceToGumpRect(sr, ROUND_OUTSIDE);
|
||||
_dims.setWidth(sr.width());
|
||||
_dims.setHeight(sr.height());
|
||||
}
|
||||
|
||||
setupNextText();
|
||||
}
|
||||
|
||||
int TextWidget::getVlead() {
|
||||
renderText();
|
||||
assert(_cachedText);
|
||||
|
||||
int32 vlead = _cachedText->getVlead();
|
||||
|
||||
if (_gameFont && getFont()->isHighRes()) {
|
||||
Common::Rect32 rect(0, 0, 0, vlead);
|
||||
ScreenSpaceToGumpRect(rect, ROUND_OUTSIDE);
|
||||
vlead = rect.height();
|
||||
}
|
||||
|
||||
return vlead;
|
||||
}
|
||||
|
||||
Font *TextWidget::getFont() const {
|
||||
if (_gameFont)
|
||||
return FontManager::get_instance()->getGameFont(_fontNum, true);
|
||||
else
|
||||
return FontManager::get_instance()->getTTFont(_fontNum);
|
||||
}
|
||||
|
||||
bool TextWidget::setupNextText() {
|
||||
_currentStart = _currentEnd;
|
||||
|
||||
if (_currentStart >= _text.size()) return false;
|
||||
|
||||
Font *font = getFont();
|
||||
|
||||
unsigned int remaining;
|
||||
font->getTextSize(_text.substr(_currentStart), _tx, _ty, remaining,
|
||||
_targetWidth, _targetHeight, _textAlign, true, _doPaging);
|
||||
|
||||
|
||||
_dims.top = -font->getBaseline();
|
||||
_dims.left = 0;
|
||||
_dims.setWidth(_tx);
|
||||
_dims.setHeight(_ty);
|
||||
_currentEnd = _currentStart + remaining;
|
||||
|
||||
delete _cachedText;
|
||||
_cachedText = nullptr;
|
||||
|
||||
if (_gameFont) {
|
||||
Font *fontP = getFont();
|
||||
if (fontP->isHighRes()) {
|
||||
Common::Rect32 sr(0, 0, _dims.width(), _dims.height());
|
||||
ScreenSpaceToGumpRect(sr, ROUND_OUTSIDE);
|
||||
_dims.setWidth(sr.width());
|
||||
_dims.setHeight(sr.height());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextWidget::rewind() {
|
||||
_currentStart = 0;
|
||||
_currentEnd = 0;
|
||||
setupNextText();
|
||||
}
|
||||
|
||||
void TextWidget::renderText() {
|
||||
if (!_cachedText) {
|
||||
Font *font = getFont();
|
||||
|
||||
unsigned int remaining;
|
||||
_cachedText = font->renderText(_text.substr(_currentStart,
|
||||
_currentEnd - _currentStart),
|
||||
remaining, _targetWidth, _targetHeight,
|
||||
_textAlign, true, _doPaging);
|
||||
}
|
||||
}
|
||||
|
||||
// Overloadable method to Paint just this Gump (RenderSurface is relative to this)
|
||||
void TextWidget::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
|
||||
Gump::PaintThis(surf, lerp_factor, scaled);
|
||||
|
||||
renderText();
|
||||
|
||||
if (scaled && _gameFont && getFont()->isHighRes()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_blendColour)
|
||||
_cachedText->draw(surf, 0, 0);
|
||||
else
|
||||
_cachedText->drawBlended(surf, 0, 0, _blendColour);
|
||||
}
|
||||
|
||||
// Overloadable method to Paint just this gumps unscaled components that require compositing (RenderSurface is relative to parent).
|
||||
void TextWidget::PaintComposited(RenderSurface *surf, int32 lerp_factor, int32 sx, int32 sy) {
|
||||
Font *font = getFont();
|
||||
|
||||
if (!_gameFont || !font->isHighRes()) return;
|
||||
|
||||
int32 x = 0, y = 0;
|
||||
GumpToScreenSpace(x, y, ROUND_BOTTOMRIGHT);
|
||||
|
||||
if (!_blendColour)
|
||||
_cachedText->draw(surf, x, y, true);
|
||||
else
|
||||
_cachedText->drawBlended(surf, x, y, _blendColour, true);
|
||||
|
||||
if (dynamic_cast<BarkGump *>(_parent))
|
||||
return;
|
||||
|
||||
if (dynamic_cast<ButtonWidget *>(_parent) && dynamic_cast<AskGump *>(_parent->GetParent()))
|
||||
return;
|
||||
|
||||
Common::Rect32 rect(_dims);
|
||||
GumpRectToScreenSpace(rect, ROUND_OUTSIDE);
|
||||
}
|
||||
|
||||
// don't handle any mouse motion events, so let parent handle them for us.
|
||||
Gump *TextWidget::onMouseMotion(int32 mx, int32 my) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void TextWidget::saveData(Common::WriteStream *ws) {
|
||||
Gump::saveData(ws);
|
||||
|
||||
ws->writeByte(_gameFont ? 1 : 0);
|
||||
ws->writeUint32LE(static_cast<uint32>(_fontNum));
|
||||
ws->writeUint32LE(_blendColour);
|
||||
ws->writeUint32LE(static_cast<uint32>(_currentStart));
|
||||
ws->writeUint32LE(static_cast<uint32>(_currentEnd));
|
||||
ws->writeUint32LE(static_cast<uint32>(_targetWidth));
|
||||
ws->writeUint32LE(static_cast<uint32>(_targetHeight));
|
||||
ws->writeUint16LE(static_cast<uint16>(_textAlign));
|
||||
ws->writeUint32LE(_text.size());
|
||||
ws->write(_text.c_str(), _text.size());
|
||||
}
|
||||
|
||||
bool TextWidget::loadData(Common::ReadStream *rs, uint32 version) {
|
||||
if (!Gump::loadData(rs, version)) return false;
|
||||
|
||||
_gameFont = (rs->readByte() != 0);
|
||||
_fontNum = static_cast<int>(rs->readUint32LE());
|
||||
_blendColour = rs->readUint32LE();
|
||||
_currentStart = static_cast<int>(rs->readUint32LE());
|
||||
_currentEnd = static_cast<int>(rs->readUint32LE());
|
||||
_targetWidth = static_cast<int>(rs->readUint32LE());
|
||||
_targetHeight = static_cast<int>(rs->readUint32LE());
|
||||
_textAlign = static_cast<Font::TextAlign>(rs->readUint16LE());
|
||||
|
||||
uint32 slen = rs->readUint32LE();
|
||||
if (slen > 0) {
|
||||
char *buf = new char[slen + 1];
|
||||
rs->read(buf, slen);
|
||||
buf[slen] = 0;
|
||||
_text = buf;
|
||||
delete[] buf;
|
||||
} else {
|
||||
_text = "";
|
||||
}
|
||||
|
||||
// HACK ALERT: this is to deal with possibly changing font sizes
|
||||
// after loading.
|
||||
Font *font = getFont();
|
||||
|
||||
int32 tx, ty;
|
||||
unsigned int remaining;
|
||||
font->getTextSize(_text.substr(_currentStart), tx, ty, remaining,
|
||||
_targetWidth, _targetHeight, _textAlign, true, _doPaging);
|
||||
|
||||
// Y offset is always baseline
|
||||
_dims.top = -font->getBaseline();
|
||||
_dims.setWidth(tx);
|
||||
_dims.setHeight(ty);
|
||||
_currentEnd = _currentStart + remaining;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
114
engines/ultima/ultima8/gumps/widgets/text_widget.h
Normal file
114
engines/ultima/ultima8/gumps/widgets/text_widget.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GUMPS_WIDGETS_TEXTWIDGET_H
|
||||
#define ULTIMA8_GUMPS_WIDGETS_TEXTWIDGET_H
|
||||
|
||||
//
|
||||
// TextWidget. Displays text in either a fixed-size or a fit-to-text rectangle.
|
||||
//
|
||||
|
||||
#include "ultima/ultima8/gumps/gump.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
#include "ultima/ultima8/misc/classtype.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class RenderedText;
|
||||
|
||||
class TextWidget : public Gump {
|
||||
protected:
|
||||
Std::string _text;
|
||||
bool _gameFont;
|
||||
int _fontNum;
|
||||
uint32 _blendColour;
|
||||
int32 _tx, _ty;
|
||||
bool _doPaging;
|
||||
|
||||
unsigned int _currentStart; //!< start of currently displaying text
|
||||
unsigned int _currentEnd; //!< start of remaining text
|
||||
|
||||
int32 _targetWidth, _targetHeight;
|
||||
|
||||
RenderedText *_cachedText;
|
||||
Font::TextAlign _textAlign;
|
||||
public:
|
||||
ENABLE_RUNTIME_CLASSTYPE()
|
||||
|
||||
TextWidget();
|
||||
TextWidget(int x, int y, const Std::string &txt, bool gamefont, int fontnum,
|
||||
int width = 0, int height = 0,
|
||||
Font::TextAlign align = Font::TEXT_LEFT,
|
||||
bool dopaging = false);
|
||||
~TextWidget() override;
|
||||
|
||||
// Init the gump, call after construction
|
||||
void InitGump(Gump *newparent, bool take_focus = true) override;
|
||||
|
||||
// Overloadable method to Paint just this Gump (RenderSurface is relative to this)
|
||||
void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
|
||||
|
||||
void PaintComposited(RenderSurface *surf, int32 lerp_factor, int32 scalex, int32 scaley) override;
|
||||
|
||||
Gump *onMouseMotion(int32 mx, int32 my) override;
|
||||
|
||||
//! display the next part of the text
|
||||
//! \return false if there is no more text to display
|
||||
bool setupNextText();
|
||||
|
||||
//! reset the widget to the start of the text
|
||||
void rewind();
|
||||
|
||||
//! get the text that's currently being displayed
|
||||
//! \param start Returns the start of the text
|
||||
//! \param end Returns the start of the remaining text
|
||||
void getCurrentText(unsigned int &start, unsigned int &end) const {
|
||||
start = _currentStart;
|
||||
end = _currentEnd;
|
||||
}
|
||||
|
||||
//! set the colour to blend the rendered text with. (0 to disable)
|
||||
void setBlendColour(uint32 col) {
|
||||
_blendColour = col;
|
||||
}
|
||||
|
||||
//! get the RenderedText's vlead
|
||||
int getVlead();
|
||||
|
||||
const Std::string &getText() const {
|
||||
return _text;
|
||||
}
|
||||
|
||||
protected:
|
||||
void renderText();
|
||||
|
||||
Font *getFont() const;
|
||||
|
||||
public:
|
||||
bool loadData(Common::ReadStream *rs, uint32 version);
|
||||
void saveData(Common::WriteStream *ws) override;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user