Skip to content

Commit

Permalink
[SUTK] Factored out Button Graphic implementaions and added DefaultBu…
Browse files Browse the repository at this point in the history
…ttonGraphicNoLabel
  • Loading branch information
ravi688 committed Sep 12, 2024
1 parent beebd42 commit 3a40b32
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 186 deletions.
81 changes: 2 additions & 79 deletions sutk/include/sutk/Button.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,89 +9,12 @@

#include <sutk/defines.hpp>
#include <sutk/Container.hpp>
#include <sutk/RenderableContainer.hpp> // for SUTK::RenderableContainer
#include <sutk/RenderRectFillRound.hpp> // for SUTK::RenderRectFillRound
#include <sutk/ColorTransitionAutomaton.hpp> // for SUTK::ColorTransitionAutomaton
#include <sutk/InputEventHandlerObject.hpp> // for SUTK::MouseMoveHandlerObject, and SUTK::MouseClickHandlerObject

#include <sutk/Label.hpp> // for SUTK::Label

namespace SUTK
{
class SUTK_API VisualButtonRect : public RenderRectFillRound
{
// States
enum State : u32
{
Hover,
Press,
Idle
};

ColorTransitionAutomaton m_cta;

friend class DefaultButtonGraphic;
public:
VisualButtonRect(SUTK::UIDriver& driver, SUTK::RenderableContainer* container) noexcept;

virtual void setActive(bool isActive) noexcept override;

virtual bool isDirty() noexcept override;
virtual void update() noexcept override;

void setTransitionDelay(const f32 transitionDelay) noexcept;

void setHoverColor(Color4 color) noexcept;
void setPressColor(Color4 color) noexcept;
void setIdleColor(Color4 color) noexcept;


void setState(State state) noexcept;
};

struct HoverInfo
{
Vec2Df position;
bool isEnter;
bool isExit;
};

class SUTK_API IButtonGraphic
{
public:
// Called every time mouse pointer changes its position but still stays within the boundaries of Button's Rect
// position is in local coordinates of the Button's Rect
virtual void onHover(HoverInfo info) = 0;
// Called once for each left-mouse-button down within the boundaries of Button's Rect
virtual void onPress() = 0;
// Called once for each left-mouse-button up/release within the boundaries of Button's Rect or even outside if earlier press was within the boundaries.
virtual void onRelease() = 0;
virtual Vec2Df getMinBoundSize() = 0;
};

class Label;

class SUTK_API DefaultButtonGraphic : public RenderableContainer, public IButtonGraphic
{
private:

// Visual Representation of the Button's existence
VisualButtonRect* m_visualButton;
Label* m_label;

public:
DefaultButtonGraphic(UIDriver& driver, Container* parent) noexcept;

// Implementation of IButtonGraphic's functions
virtual void onHover(HoverInfo info) noexcept override;
virtual void onPress() noexcept override;
virtual void onRelease() noexcept override;
virtual Vec2Df getMinBoundSize() noexcept override;

VisualButtonRect& getVisualButtonRect() noexcept { return *m_visualButton; }
Label& getLabel() noexcept { return *m_label; }
};

class IButtonGraphic;

class SUTK_API Button : public Container,
public MouseMoveHandlerObject,
public MouseClickHandlerObject
Expand Down
94 changes: 94 additions & 0 deletions sutk/include/sutk/ButtonGraphic.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#pragma once

#include <sutk/defines.hpp>
#include <sutk/RenderRectFillRound.hpp> // for SUTK::RenderRectFillRound
#include <sutk/ColorTransitionAutomaton.hpp> // for SUTK::ColorTransitionAutomaton
#include <sutk/RenderableContainer.hpp> // for SUTK::RenderableContainer

namespace SUTK
{
struct HoverInfo
{
Vec2Df position;
bool isEnter;
bool isExit;
};

class SUTK_API IButtonGraphic
{
public:
// Called every time mouse pointer changes its position but still stays within the boundaries of Button's Rect
// position is in local coordinates of the Button's Rect
virtual void onHover(HoverInfo info) = 0;
// Called once for each left-mouse-button down within the boundaries of Button's Rect
virtual void onPress() = 0;
// Called once for each left-mouse-button up/release within the boundaries of Button's Rect or even outside if earlier press was within the boundaries.
virtual void onRelease() = 0;
virtual Vec2Df getMinBoundSize() = 0;
};

class SUTK_API VisualButtonRect : public RenderRectFillRound
{
// States
enum State : u32
{
Hover,
Press,
Idle
};

ColorTransitionAutomaton m_cta;

friend class DefaultButtonGraphicNoLabel;
public:
VisualButtonRect(SUTK::UIDriver& driver, SUTK::RenderableContainer* container) noexcept;

virtual void setActive(bool isActive) noexcept override;

virtual bool isDirty() noexcept override;
virtual void update() noexcept override;

void setTransitionDelay(const f32 transitionDelay) noexcept;

void setHoverColor(Color4 color) noexcept;
void setPressColor(Color4 color) noexcept;
void setIdleColor(Color4 color) noexcept;


void setState(State state) noexcept;
};


class SUTK_API DefaultButtonGraphicNoLabel : public RenderableContainer, public IButtonGraphic
{
private:

// Visual Representation of the Button's existence
VisualButtonRect* m_visualButton;

public:
DefaultButtonGraphicNoLabel(UIDriver& driver, Container* parent) noexcept;

// Implementation of IButtonGraphic's functions
virtual void onHover(HoverInfo info) noexcept override;
virtual void onPress() noexcept override;
virtual void onRelease() noexcept override;
virtual Vec2Df getMinBoundSize() noexcept override;

VisualButtonRect& getVisualButtonRect() noexcept { return *m_visualButton; }
};

class Label;
class SUTK_API DefaultButtonGraphic : public DefaultButtonGraphicNoLabel
{
private:
Label* m_label;
public:
DefaultButtonGraphic(UIDriver& driver, Container* parent) noexcept;

// Overrides
virtual Vec2Df getMinBoundSize() noexcept override;

Label& getLabel() noexcept { return *m_label; }
};
}
112 changes: 5 additions & 107 deletions sutk/source/Button.cpp
Original file line number Diff line number Diff line change
@@ -1,113 +1,9 @@
#include <sutk/Button.hpp>

#include <sutk/SmallText.hpp> // for SUTK::SmallText
#include <sutk/Label.hpp> // for SUTK::Label
#include <sutk/ButtonGraphic.hpp>

namespace SUTK
{
VisualButtonRect::VisualButtonRect(SUTK::UIDriver& driver, SUTK::RenderableContainer* container) noexcept : RenderRectFillRound(driver, container),
m_cta({ { State::Hover, Color4::grey(0.7f) },
{ State::Press, Color4::grey(0.3f) },
{ State::Idle, Color4::grey(1.0f) } })
{
m_cta.setDefault(State::Idle);
}

void VisualButtonRect::setActive(bool isActive) noexcept
{
RenderRectFillRound::setActive(isActive);
if(isActive)
{
m_cta.setDefault(State::Idle);
setColor(m_cta.getValue());
}
}

bool VisualButtonRect::isDirty() noexcept
{
return m_cta.isRunning() || RenderRectFillRound::isDirty();
}
void VisualButtonRect::update() noexcept
{
if(m_cta.isRunning())
{
m_cta.update();
setColor(m_cta.getValue());
}
RenderRectFillRound::update();
}

void VisualButtonRect::setTransitionDelay(const f32 transitionDelay) noexcept
{
m_cta.setTransitionDelay(transitionDelay);
}

void VisualButtonRect::setHoverColor(Color4 color) noexcept
{
m_cta.set(State::Hover, color);
}
void VisualButtonRect::setPressColor(Color4 color) noexcept
{
m_cta.set(State::Press, color);
}
void VisualButtonRect::setIdleColor(Color4 color) noexcept
{
m_cta.set(State::Idle, color);
m_cta.setDefault(State::Idle);
setColor(m_cta.getValue());
}
void VisualButtonRect::setState(State state) noexcept
{
m_cta.transitionTo(state);
}

DefaultButtonGraphic::DefaultButtonGraphic(UIDriver& driver, Container* parent) noexcept : RenderableContainer(driver, parent)
{
_com_assert(parent != NULL);

// size of this graphic should be as that of Button's rect
setRect({ { 0, 0 }, parent->getSize() });
getAnchorRect()->setRect( { 0, 0, 1, 1 });

m_visualButton = driver.createRenderable<VisualButtonRect>(this);

m_label = driver.createContainer<Label>(this);
// size of the label's rect should be as that of ButtonGraphic's rect
m_label->setRect({ { 0, 0 }, getSize() });
m_label->getAnchorRect()->setRect({ 0.0f, 0.0f, 1.0f, 1.0f });
m_label->setAlignment(HorizontalAlignment::Middle, VerticalAlignment::Middle);
}

/* ____________
\|/ |
Idle Color --> Hover Color --> Press Color
/|\ |
|_______________|
*/

void DefaultButtonGraphic::onHover(HoverInfo info) noexcept
{
if(info.isEnter)
m_visualButton->setState(VisualButtonRect::State::Hover);
else if(info.isExit)
m_visualButton->setState(VisualButtonRect::State::Idle);
}
void DefaultButtonGraphic::onPress() noexcept
{
m_visualButton->setState(VisualButtonRect::State::Press);
}
void DefaultButtonGraphic::onRelease() noexcept
{
m_visualButton->setState(VisualButtonRect::State::Hover);
}
Vec2Df DefaultButtonGraphic::getMinBoundSize() noexcept
{
f32 xCoord = m_label->getText().getCoordFromColPos(END_OF_LINE);
Vec2Df size = getSize();
return { xCoord, size.height };
}

Button::Button(UIDriver& driver, Container* parent, bool isCreateDefaultGraphic) noexcept : Container(driver, parent),
MouseMoveHandlerObject(driver, this),
MouseClickHandlerObject(driver, this),
Expand Down Expand Up @@ -164,12 +60,14 @@ namespace SUTK
if(action == KeyEvent::Press)
{
m_onPressEvent.publish();
m_graphic->onPress();
if(m_graphic != NULL)
m_graphic->onPress();
}
else if(action == KeyEvent::Release)
{
m_onReleaseEvent.publish();
m_graphic->onRelease();
if(m_graphic != NULL)
m_graphic->onRelease();
}
}
}
Loading

0 comments on commit 3a40b32

Please sign in to comment.