#include "GSlider.h" #include "PackageItem.h" #include "utils/ByteBuffer.h" NS_FGUI_BEGIN USING_NS_AX; GSlider::GSlider() : changeOnClick(false), canDrag(false), _min(0), _max(100), _value(0), _titleType(ProgressTitleType::PERCENT), _reverse(false), _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() { float percent = MIN((_value - _min) / (_max - _min), 1); updateWithPercent(percent, false); } 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((newValue - _min) / (_max - _min)), 0, 1); } 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, AX_CALLBACK_1(GSlider::onGripTouchBegin, this)); _gripObject->addEventListener(UIEventType::TouchMove, AX_CALLBACK_1(GSlider::onGripTouchMove, this)); } addEventListener(UIEventType::TouchBegin, AX_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((_value - _min) / (_max - _min)), 0, 1); 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((_value - _min) / (_max - _min)), 0, 1); } 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