axmol/extensions/fairygui/GSlider.cpp

292 lines
6.7 KiB
C++
Raw Normal View History

2020-08-04 12:31:33 +08:00
#include "GSlider.h"
#include "PackageItem.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_AX;
2020-08-04 12:31:33 +08:00
GSlider::GSlider()
: changeOnClick(false),
canDrag(false),
_min(0),
_max(100),
_value(0),
_titleType(ProgressTitleType::PERCENT),
_reverse(false),
2020-08-04 12:31:33 +08:00
_titleObject(nullptr),
_barObjectH(nullptr),
_barObjectV(nullptr),
_barMaxWidth(0),
_barMaxHeight(0),
_barMaxWidthDelta(0),
_barMaxHeightDelta(0),
_gripObject(nullptr),
_clickPercent(0),
_barStartX(0),
_barStartY(0),
_wholeNumbers(false)
{
}
GSlider::~GSlider()
{
}
void GSlider::setTitleType(ProgressTitleType value)
{
if (_titleType != value)
{
_titleType = value;
update();
}
}
void GSlider::setMin(double value)
{
if (_min != value)
{
_min = value;
update();
}
}
void GSlider::setMax(double value)
{
if (_max != value)
{
_max = value;
update();
}
}
void GSlider::setValue(double value)
{
if (_value != value)
{
_value = value;
update();
}
}
void GSlider::setWholeNumbers(bool value)
{
if (_wholeNumbers != value)
{
_wholeNumbers = value;
update();
}
}
void GSlider::update()
{
2021-11-11 18:33:29 +08:00
float percent = MIN((_value - _min) / (_max - _min), 1);
updateWithPercent(percent, false);
2020-08-04 12:31:33 +08:00
}
void GSlider::updateWithPercent(float percent, bool manual)
{
percent = clampf(percent, 0, 1);
if (manual)
{
double newValue = _min + (_max - _min) * percent;
if (newValue < _min)
newValue = _min;
if (newValue > _max)
newValue = _max;
if (_wholeNumbers)
{
newValue = round(newValue);
percent = clampf(static_cast<float>((newValue - _min) / (_max - _min)), 0, 1);
2020-08-04 12:31:33 +08:00
}
if (newValue != _value)
{
_value = newValue;
if (dispatchEvent(UIEventType::Changed))
return;
}
}
if (_titleObject != nullptr)
{
std::ostringstream oss;
switch (_titleType)
{
case ProgressTitleType::PERCENT:
oss << floor(percent * 100) << "%";
break;
case ProgressTitleType::VALUE_MAX:
oss << floor(_value) << "/" << floor(_max);
break;
case ProgressTitleType::VALUE:
oss << _value;
break;
case ProgressTitleType::MAX:
oss << _max;
break;
}
_titleObject->setText(oss.str());
}
float fullWidth = this->getWidth() - _barMaxWidthDelta;
float fullHeight = this->getHeight() - _barMaxHeightDelta;
if (!_reverse)
{
if (_barObjectH != nullptr)
_barObjectH->setWidth(round(fullWidth * percent));
if (_barObjectV != nullptr)
_barObjectV->setHeight(round(fullHeight * percent));
}
else
{
if (_barObjectH != nullptr)
{
_barObjectH->setWidth(round(fullWidth * percent));
_barObjectH->setX(_barStartX + (fullWidth - _barObjectH->getWidth()));
}
if (_barObjectV != nullptr)
{
_barObjectV->setHeight(round(fullHeight * percent));
_barObjectV->setY(_barStartY + (fullHeight - _barObjectV->getHeight()));
}
}
}
void GSlider::handleSizeChanged()
{
GComponent::handleSizeChanged();
if (_barObjectH != nullptr)
_barMaxWidth = getWidth() - _barMaxWidthDelta;
if (_barObjectV != nullptr)
_barMaxHeight = getHeight() - _barMaxHeightDelta;
if (!_underConstruct)
update();
}
void GSlider::constructExtension(ByteBuffer* buffer)
{
_titleType = (ProgressTitleType)buffer->readByte();
_reverse = buffer->readBool();
if (buffer->version >= 2)
{
_wholeNumbers = buffer->readBool();
changeOnClick = buffer->readBool();
}
_titleObject = getChild("title");
_barObjectH = getChild("bar");
_barObjectV = getChild("bar_v");
_gripObject = getChild("grip");
if (_barObjectH != nullptr)
{
_barMaxWidth = _barObjectH->getWidth();
_barMaxWidthDelta = getWidth() - _barMaxWidth;
_barStartX = _barObjectH->getX();
}
if (_barObjectV != nullptr)
{
_barMaxHeight = _barObjectV->getHeight();
_barMaxHeightDelta = getHeight() - _barMaxHeight;
_barStartY = _barObjectV->getY();
}
if (_gripObject != nullptr)
{
_gripObject->addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GSlider::onGripTouchBegin, this));
_gripObject->addEventListener(UIEventType::TouchMove, CC_CALLBACK_1(GSlider::onGripTouchMove, this));
}
addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GSlider::onTouchBegin, this));
}
void GSlider::setup_afterAdd(ByteBuffer* buffer, int beginPos)
{
GComponent::setup_afterAdd(buffer, beginPos);
if (!buffer->seek(beginPos, 6))
{
update();
return;
}
if ((ObjectType)buffer->readByte() != _packageItem->objectType)
{
update();
return;
}
_value = buffer->readInt();
_max = buffer->readInt();
if (buffer->version >= 2)
_min = buffer->readInt();
update();
}
void GSlider::onTouchBegin(EventContext* context)
{
if (!changeOnClick)
return;
InputEvent* evt = context->getInput();
if (evt->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
return;
Vec2 pt = _gripObject->globalToLocal(evt->getPosition());
float percent = clampf(static_cast<float>((_value - _min) / (_max - _min)), 0, 1);
2020-08-04 12:31:33 +08:00
float delta = 0;
if (_barObjectH != nullptr)
delta = pt.x / _barMaxWidth;
if (_barObjectV != nullptr)
delta = pt.y / _barMaxHeight;
if (_reverse)
percent -= delta;
else
percent += delta;
updateWithPercent(percent, true);
}
void GSlider::onGripTouchBegin(EventContext* context)
{
if (context->getInput()->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
return;
canDrag = true;
context->stopPropagation();
context->captureTouch();
_clickPos = globalToLocal(context->getInput()->getPosition());
_clickPercent = clampf(static_cast<float>((_value - _min) / (_max - _min)), 0, 1);
2020-08-04 12:31:33 +08:00
}
void GSlider::onGripTouchMove(EventContext* context)
{
if (!canDrag)
return;
Vec2 pt = globalToLocal(context->getInput()->getPosition());
float deltaX = pt.x - _clickPos.x;
float deltaY = pt.y - _clickPos.y;
if (_reverse)
{
deltaX = -deltaX;
deltaY = -deltaY;
}
float percent;
if (_barObjectH != nullptr)
percent = _clickPercent + deltaX / _barMaxWidth;
else
percent = _clickPercent + deltaY / _barMaxHeight;
updateWithPercent(percent, true);
}
NS_FGUI_END