diff --git a/TODO b/TODO index 1de4009..e14c5f7 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,6 @@ Widgets: + Replace Old Widgets!! + Optimize: Make visual parameters static Make get-areas fetch cache and not animation objects diff --git a/WidgetsNew/examples/Example.cpp b/WidgetsNew/examples/Example.cpp index 0871dfe..4fcb4d7 100644 --- a/WidgetsNew/examples/Example.cpp +++ b/WidgetsNew/examples/Example.cpp @@ -13,7 +13,7 @@ using namespace tp; class WidgetApplication : public Application { public: WidgetApplication() { - exampleAll(); + exampleBasic(); } void exampleAll() { @@ -36,6 +36,19 @@ public: mRootWidget.setRootWidget(&dock); } + void exampleBasic() { + static Widget widget; + static LabelWidget label; + static SliderWidget slider; + static ButtonWidget button; + + widget.addChild(&label); + widget.addChild(&button); + widget.addChild(&slider); + + mRootWidget.setRootWidget(&widget); + } + void exampleScrolling() { static Widget widget; static Widget content; diff --git a/WidgetsNew/private/widgets/SimpleWidgets.cpp b/WidgetsNew/private/widgets/SimpleWidgets.cpp index 47206f5..cdd2c33 100644 --- a/WidgetsNew/private/widgets/SimpleWidgets.cpp +++ b/WidgetsNew/private/widgets/SimpleWidgets.cpp @@ -79,3 +79,52 @@ void ButtonWidget::mouseLeave() { triggerWidgetUpdate("button out of focus"); } + + +void SliderWidget::process(const EventHandler& events) { + const auto pointer = events.getPointer(); + + switch (mState) { + case SLIDING: + if (events.isReleased(InputID::MOUSE1)) { + mState = IDLE; + freeFocus(); + } + + mFactor = ((pointer - mHandleSize / 2) / (getArea().relative().size - mHandleSize)).x; + mFactor = clamp(mFactor, 0.f, 1.f); + break; + + case IDLE: + case HOVER: + mState = getHandleArea().isInside(pointer) ? HOVER : IDLE; + if (getRelativeAreaT().isInside(pointer) && events.isPressed(InputID::MOUSE1)) { + mState = SLIDING; + lockFocus(); + } + break; + } +} + +void SliderWidget::draw(Canvas& canvas) { + canvas.rect(getArea().relative(), mColorBG, mRounding); + + switch (mState) { + case IDLE: canvas.rect(getHandleArea(), mColorIdle, mRounding); break; + case HOVER: canvas.rect(getHandleArea(), mColorHovered, mRounding); break; + case SLIDING: canvas.rect(getHandleArea(), mColorActive, mRounding); break; + } +} + +RectF SliderWidget::getHandleArea() const { + auto area = getArea().relative(); + + const auto& size = area.size; + auto center = area.center(); + auto tilt = -(mFactor - 0.5f) * 2; + + area.pos.x = center.x - (tilt * ((size.x - mHandleSize) / 2)) - mHandleSize / 2; + area.size.x = mHandleSize; + + return area; +} \ No newline at end of file diff --git a/WidgetsNew/public/widgets/SimpleWidgets.hpp b/WidgetsNew/public/widgets/SimpleWidgets.hpp index 91554ea..c618c96 100644 --- a/WidgetsNew/public/widgets/SimpleWidgets.hpp +++ b/WidgetsNew/public/widgets/SimpleWidgets.hpp @@ -56,4 +56,37 @@ namespace tp { RGBA mColorHovered = { 0.0f, 0.4f, 0.4f, 1.f }; RGBA mColor = { 0.13f, 0.13f, 0.13f, 1.f }; }; + + class SliderWidget : public Widget { + enum State { + IDLE, + HOVER, + SLIDING, + }; + + public: + SliderWidget() = default; + + void process(const EventHandler& eventHandler) override; + void draw(Canvas& canvas) override; + + [[nodiscard]] bool processesEvents() const override { return true; } + [[nodiscard]] bool needsNextFrame() const override { return mState != SLIDING; } + + private: + RectF getHandleArea() const; + + private: + halnf mFactor = 0; + State mState = IDLE; + + private: + halnf mHandleSize = 20; + halnf mRounding = 5; + + RGBA mColorActive = { 0.5f, 0.5f, 0.5f, 1.f }; + RGBA mColorHovered = { 0.3f, 0.3f, 0.3f, 1.f }; + RGBA mColorIdle = { 0.2f, 0.2f, 0.2f, 1.f }; + RGBA mColorBG = { 0.08f, 0.08f, 0.08f, 1.0f }; + }; } \ No newline at end of file