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
|
||||
Reference in New Issue
Block a user