stuff-from-scratch/src/ui/ui_controls/Button.cpp
2023-01-19 17:37:26 +00:00

284 lines
6 KiB
C++

#include "Button.h"
#include "TextNode.h"
#include "GeometryNode.h"
#include "TransformNode.h"
#include "IconNode.h"
#include "FontTokens.h"
#include "ThemeManager.h"
#include "MediaResourceManager.h"
#include "PaintEvent.h"
#include "MouseEvent.h"
#include "FileLogger.h"
Button::Button(ButtonData::Component component)
: Widget(),
mLabel(),
mClickFunc()
{
mStyle.mComponent = component;
mName = "Button";
setWidth(150);
setMaxWidth(150);
setHeight(mStyle.getContainerHeight());
setMaxHeight(mStyle.getContainerHeight());
setRadius(mStyle.getContainerCornerRadius());
}
Button::~Button()
{
}
std::unique_ptr<Button> Button::Create(ButtonData::Component component)
{
return std::make_unique<Button>(component);
}
void Button::setOnClickFunction(clickFunc func)
{
mClickFunc = func;
}
void Button::setLabel(const std::string& text)
{
if (text != mLabel)
{
mLabel = text;
mContentDirty = true;
}
}
void Button::setSvgIcon(Resource::Icon::Svg icon)
{
if (icon != mIcon)
{
mIcon = icon;
mContentDirty = true;
}
}
void Button::setState(ButtonData::State state)
{
if (mStyle.mState != state)
{
mStyle.mState = state;
mStateDirty = true;
}
}
void Button::setEnabled(bool isEnabled)
{
if (mEnabled != isEnabled)
{
mEnabled = isEnabled;
if (isEnabled && mStyle.mState == ButtonData::State::Disabled)
{
setState(ButtonData::State::Enabled);
}
else if (!isEnabled && mStyle.mState == ButtonData::State::Enabled)
{
setState(ButtonData::State::Disabled);
}
}
}
void Button::updateState()
{
setBackground(mStyle.getContainerColor());
setBackgroundOpacity(mStyle.getStateLayerOverlayOpacity());
setBackgroundTone(mStyle.getContainerSurfaceTintColor());
setElevation(mStyle.getContainerElevation());
setLabelTextColor(mStyle.getLabelTextColor());
setLabelTextOpacity(mStyle.getLabelOpacity());
setLabelTextTypescale(mStyle.getLabelTypescale());
setIconColor(mStyle.getIconColor());
//setIconOpacity()
}
void Button::setLabelTextColor(Theme::Sys::Color color)
{
if (mLabelTextColor != color)
{
mLabelTextColor = color;
mMaterialDirty = true;
}
}
void Button::setLabelTextOpacity(float opacity)
{
if (mLabelOpacity != opacity)
{
mLabelOpacity = opacity;
mMaterialDirty = true;
}
}
void Button::setLabelTextTypescale(Theme::Sys::Typescale typescale)
{
if (mLabelTextTypescale != typescale)
{
mLabelTextTypescale = typescale;
mMaterialDirty = true;
}
}
void Button::setIconColor(Theme::Sys::Color color)
{
if (mIconColor != color)
{
mIconColor = color;
mMaterialDirty = true;
}
}
void Button::setIconOpacity(float opacity)
{
if (mIconOpacity!= opacity)
{
mIconOpacity = opacity;
mMaterialDirty = true;
}
}
void Button::onMyMouseEvent(const MouseEvent* event)
{
if (!mEnabled)
{
return;
}
if (event->getAction() == MouseEvent::Action::Pressed)
{
setState(ButtonData::State::Pressed);
}
else if (event->getAction() == MouseEvent::Action::Released)
{
resetState();
if (mClickFunc)
{
mClickFunc(this);
}
}
else if (event->getAction() == MouseEvent::Action::Enter)
{
resetState();
}
else if (event->getAction() == MouseEvent::Action::Leave)
{
resetState();
}
}
void Button::resetState()
{
if (mHasFocus)
{
setState(ButtonData::State::Focused);
}
else if (mContainsMouse)
{
setState(ButtonData::State::Hovered);
}
else if (mEnabled)
{
setState(ButtonData::State::Enabled);
}
else
{
setState(ButtonData::State::Disabled);
}
}
bool Button::isDirty() const
{
return Widget::isDirty() || mContentDirty;
}
void Button::doPaint(const PaintEvent* event)
{
if (mTransformDirty)
{
mRootNode->setTransform(Transform(mLocation));
mTransformDirty = false;
}
updateBackground(event);
updateLabel(event);
updateIcon(event);
mContentDirty = false;
}
void Button::updateLabel(const PaintEvent* event)
{
if (!mTextNode)
{
mTextNode = TextNode::Create(mLabel, Transform({ mSize.mWidth /2.0, mSize.mHeight / 2.0 }));
mTextNode->setName(mName + "_TextNode");
mTextNode->setContent(mLabel);
mTextNode->setWidth(mSize.mWidth);
mTextNode->setHeight(mSize.mHeight);
mRootNode->addChild(mTextNode.get());
}
if (mMaterialDirty)
{
auto fill_color = event->getThemesManager()->getColor(mLabelTextColor);
fill_color.setAlpha(mLabelOpacity);
mTextNode->setFillColor(fill_color);
auto size = FontTokens::getSize(mLabelTextTypescale);
auto family = FontTokens::getFont(FontTokens::getFont(mLabelTextTypescale));
auto font_data = FontItem(family, static_cast<float>(size));
mTextNode->setFont(font_data);
}
if (mContentDirty)
{
mTextNode->setContent(mLabel);
}
if (mVisibilityDirty)
{
mTextNode->setIsVisible(mVisible);
}
}
void Button::updateIcon(const PaintEvent* event)
{
if (!mIconNode && mIcon != Resource::Icon::Svg::NONE)
{
mIconNode = std::make_unique<IconNode>(Transform());
mIconNode->setName(mName + "_IconNode");
mIconNode->setSvgContent(MediaResourceManager::getSvgIconNode(mIcon));
mRootNode->addChild(mIconNode.get());
}
else if (mContentDirty && mIcon != Resource::Icon::Svg::NONE)
{
mIconNode->setSvgContent(MediaResourceManager::getSvgIconNode(mIcon));
}
if (!mIconNode)
{
return;
}
if (mMaterialDirty)
{
auto icon_fill = event->getThemesManager()->getColor(mIconColor);
icon_fill.setAlpha(mIconOpacity);
mIconNode->setFillColor(icon_fill);
}
if (mVisibilityDirty)
{
mIconNode->setIsVisible(mVisible);
}
}