Clean project structure.
This commit is contained in:
parent
78a4fa99ff
commit
947bf937fd
496 changed files with 206 additions and 137 deletions
110
src/ui/ui_controls/Button.cpp
Normal file
110
src/ui/ui_controls/Button.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
#include "Button.h"
|
||||
|
||||
#include "TextNode.h"
|
||||
#include "GeometryNode.h"
|
||||
#include "TransformNode.h"
|
||||
|
||||
#include "MouseEvent.h"
|
||||
#include "FileLogger.h"
|
||||
|
||||
Button::Button()
|
||||
: Widget(),
|
||||
mLabel(),
|
||||
mCachedColor(255, 255, 255),
|
||||
mClickedColor(Color(180, 180, 180)),
|
||||
mClickFunc()
|
||||
{
|
||||
mName = "Button";
|
||||
}
|
||||
|
||||
Button::~Button()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<Button> Button::Create()
|
||||
{
|
||||
return std::make_unique<Button>();
|
||||
}
|
||||
|
||||
void Button::setOnClickFunction(clickFunc func)
|
||||
{
|
||||
mClickFunc = func;
|
||||
}
|
||||
|
||||
void Button::setLabel(const std::string& text)
|
||||
{
|
||||
if (text != mLabel)
|
||||
{
|
||||
mLabel = text;
|
||||
mContentDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Button::onMyMouseEvent(const MouseEvent* event)
|
||||
{
|
||||
MLOG_INFO("Widget mouse event");
|
||||
if(event->getAction() == MouseEvent::Action::Pressed)
|
||||
{
|
||||
mCachedColor = mBackgroundColor;
|
||||
setBackgroundColor(mClickedColor);
|
||||
if(mClickFunc)
|
||||
{
|
||||
mClickFunc(this);
|
||||
}
|
||||
}
|
||||
else if(event->getAction() == MouseEvent::Action::Released)
|
||||
{
|
||||
setBackgroundColor(mCachedColor);
|
||||
}
|
||||
}
|
||||
|
||||
bool Button::isDirty() const
|
||||
{
|
||||
return Widget::isDirty() || mContentDirty;
|
||||
}
|
||||
|
||||
void Button::doPaint(const PaintEvent* event)
|
||||
{
|
||||
updateBackground(event);
|
||||
updateLabel(event);
|
||||
}
|
||||
|
||||
void Button::updateLabel(const PaintEvent* event)
|
||||
{
|
||||
unsigned fontOffset = unsigned(mLabel.size()) * 4;
|
||||
auto middle = DiscretePoint(mLocation.getX() + mSize.mWidth/2 - fontOffset, mLocation.getY() + mSize.mHeight/2 + 4);
|
||||
|
||||
if (!mTextNode)
|
||||
{
|
||||
mTextNode = TextNode::Create(mLabel, middle);
|
||||
mTextNode->setName(mName + "_TextNode");
|
||||
mTextNode->setContent(mLabel);
|
||||
mTextNode->setWidth(mSize.mWidth);
|
||||
mTextNode->setHeight(mSize.mHeight);
|
||||
mRootNode->addChild(mTextNode.get());
|
||||
}
|
||||
|
||||
if (mTransformDirty)
|
||||
{
|
||||
mTextNode->setLocation(middle);
|
||||
mTextNode->setWidth(mSize.mWidth);
|
||||
mTextNode->setHeight(mSize.mHeight);
|
||||
}
|
||||
|
||||
if (mMaterialDirty)
|
||||
{
|
||||
mTextNode->setFillColor(mBackgroundColor);
|
||||
}
|
||||
|
||||
if (mContentDirty)
|
||||
{
|
||||
mTextNode->setContent(mLabel);
|
||||
mContentDirty = false;
|
||||
}
|
||||
|
||||
if (mVisibilityDirty)
|
||||
{
|
||||
mTextNode->setIsVisible(mVisible);
|
||||
}
|
||||
}
|
46
src/ui/ui_controls/Button.h
Normal file
46
src/ui/ui_controls/Button.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
#include "Color.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
class PaintEvent;
|
||||
class MouseEvent;
|
||||
class TextNode;
|
||||
|
||||
class Button : public Widget
|
||||
{
|
||||
public:
|
||||
using clickFunc = std::function<void(Widget* self)>;
|
||||
|
||||
Button();
|
||||
|
||||
~Button();
|
||||
|
||||
static std::unique_ptr<Button> Create();
|
||||
|
||||
void setLabel(const std::string& text);
|
||||
|
||||
void setOnClickFunction(clickFunc func);
|
||||
|
||||
protected:
|
||||
void onMyMouseEvent(const MouseEvent* event) override;
|
||||
|
||||
bool isDirty() const override;
|
||||
void doPaint(const PaintEvent* event) override;
|
||||
|
||||
void updateLabel(const PaintEvent* event);
|
||||
|
||||
private:
|
||||
std::string mLabel;
|
||||
clickFunc mClickFunc;
|
||||
Color mCachedColor;
|
||||
Color mClickedColor;
|
||||
|
||||
std::unique_ptr<TextNode> mTextNode;
|
||||
bool mContentDirty{true};
|
||||
};
|
||||
|
||||
using ButtonUPtr = std::unique_ptr<Button>;
|
0
src/ui/ui_controls/ButtonGroup.cpp
Normal file
0
src/ui/ui_controls/ButtonGroup.cpp
Normal file
23
src/ui/ui_controls/ButtonGroup.h
Normal file
23
src/ui/ui_controls/ButtonGroup.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
class ButtonGroup : public Widget
|
||||
{
|
||||
public:
|
||||
|
||||
enum class Orientation
|
||||
{
|
||||
HORIZONTAL,
|
||||
VERTICAL
|
||||
};
|
||||
|
||||
ButtonGroup();
|
||||
|
||||
~ButtonGroup();
|
||||
|
||||
static std::unique_ptr<ButtonGroup> Create();
|
||||
|
||||
private:
|
||||
bool mExclusiveActivation{true};
|
||||
};
|
32
src/ui/ui_controls/CMakeLists.txt
Normal file
32
src/ui/ui_controls/CMakeLists.txt
Normal file
|
@ -0,0 +1,32 @@
|
|||
set(MODULE_NAME ui_controls)
|
||||
|
||||
list(APPEND HEADERS
|
||||
Button.h
|
||||
ButtonGroup.h
|
||||
Label.h
|
||||
HorizontalSpacer.h
|
||||
VerticalSpacer.h
|
||||
StackWidget.h
|
||||
TextBox.h
|
||||
)
|
||||
|
||||
list(APPEND LIB_INCLUDES
|
||||
Button.cpp
|
||||
ButtonGroup.cpp
|
||||
Label.cpp
|
||||
HorizontalSpacer.cpp
|
||||
VerticalSpacer.cpp
|
||||
StackWidget.cpp
|
||||
TextBox.cpp
|
||||
)
|
||||
|
||||
add_library(${MODULE_NAME} SHARED ${LIB_INCLUDES} ${HEADERS})
|
||||
|
||||
target_include_directories(${MODULE_NAME} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
)
|
||||
target_link_libraries(${MODULE_NAME} PUBLIC ui_elements)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/ui)
|
||||
|
||||
set_target_properties( ${MODULE_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
|
54
src/ui/ui_controls/HorizontalSpacer.cpp
Normal file
54
src/ui/ui_controls/HorizontalSpacer.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "HorizontalSpacer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <iostream>
|
||||
|
||||
HorizontalSpacer::HorizontalSpacer()
|
||||
: Widget(),
|
||||
mScales()
|
||||
{
|
||||
mName = "HorizontalSpacer";
|
||||
}
|
||||
|
||||
std::unique_ptr<HorizontalSpacer> HorizontalSpacer::Create()
|
||||
{
|
||||
return std::make_unique<HorizontalSpacer>();
|
||||
}
|
||||
|
||||
void HorizontalSpacer::addWidget(WidgetUPtr widget)
|
||||
{
|
||||
addWidgetWithScale(std::move(widget), 1.0);
|
||||
}
|
||||
|
||||
void HorizontalSpacer::addWidgetWithScale(WidgetUPtr widget, double scale)
|
||||
{
|
||||
Widget::addWidget(std::move(widget));
|
||||
mScales.push_back(scale);
|
||||
}
|
||||
|
||||
void HorizontalSpacer::updateChildLocations()
|
||||
{
|
||||
double scaleSum = std::accumulate(mScales.begin(), mScales.end(), 0.0);
|
||||
double offset = 0;
|
||||
double height = mSize.mHeight;
|
||||
if (mSize.mMaxHeight > 0 && height > mSize.mMaxHeight)
|
||||
{
|
||||
height = mSize.mMaxHeight;
|
||||
}
|
||||
|
||||
for(std::size_t idx=0; idx<mChildren.size(); idx++)
|
||||
{
|
||||
auto& child = mChildren[idx];
|
||||
double scale = mScales[idx];
|
||||
double delta = height * (scale/scaleSum);
|
||||
auto size = child->getSize();
|
||||
if (size.mMaxHeight > 0 && delta > size.mMaxHeight)
|
||||
{
|
||||
delta = size.mMaxHeight;
|
||||
}
|
||||
child->setBounds(mSize.mWidth, unsigned(delta));
|
||||
child->setLocation(DiscretePoint(mLocation.getX(), mLocation.getY() + unsigned(offset)));
|
||||
offset += delta;
|
||||
}
|
||||
}
|
21
src/ui/ui_controls/HorizontalSpacer.h
Normal file
21
src/ui/ui_controls/HorizontalSpacer.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
#include <vector>
|
||||
|
||||
class HorizontalSpacer : public Widget
|
||||
{
|
||||
public:
|
||||
HorizontalSpacer();
|
||||
|
||||
static std::unique_ptr<HorizontalSpacer> Create();
|
||||
|
||||
void addWidget(WidgetUPtr widget) override;
|
||||
|
||||
void addWidgetWithScale(WidgetUPtr widget, double scale);
|
||||
private:
|
||||
void updateChildLocations() override;
|
||||
std::vector<double> mScales;
|
||||
};
|
||||
|
||||
using HorizontalSpacerUPtr = std::unique_ptr<HorizontalSpacer>;
|
74
src/ui/ui_controls/Label.cpp
Normal file
74
src/ui/ui_controls/Label.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "Label.h"
|
||||
|
||||
#include "TextNode.h"
|
||||
#include "TransformNode.h"
|
||||
#include "GeometryNode.h"
|
||||
|
||||
Label::Label()
|
||||
: Widget(),
|
||||
mLabel()
|
||||
{
|
||||
mName = "Label";
|
||||
}
|
||||
|
||||
std::unique_ptr<Label> Label::Create()
|
||||
{
|
||||
return std::make_unique<Label>();
|
||||
}
|
||||
|
||||
void Label::setLabel(const std::string& text)
|
||||
{
|
||||
if (text != mLabel)
|
||||
{
|
||||
mLabel = text;
|
||||
mContentDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Label::isDirty() const
|
||||
{
|
||||
return Widget::isDirty() || mContentDirty;
|
||||
}
|
||||
|
||||
void Label::doPaint(const PaintEvent* event)
|
||||
{
|
||||
updateBackground(event);
|
||||
updateLabel(event);
|
||||
}
|
||||
|
||||
void Label::updateLabel(const PaintEvent* event)
|
||||
{
|
||||
unsigned fontOffset = unsigned(mLabel.size()) * 4;
|
||||
auto middle = DiscretePoint(mLocation.getX() + mSize.mWidth/2 - fontOffset, mLocation.getY() + mSize.mHeight/2 + 4);
|
||||
|
||||
if (!mTextNode)
|
||||
{
|
||||
mTextNode = TextNode::Create(mLabel, middle);
|
||||
mTextNode->setWidth(mSize.mWidth);
|
||||
mTextNode->setHeight(mSize.mHeight);
|
||||
mRootNode->addChild(mTextNode.get());
|
||||
}
|
||||
|
||||
if (mMaterialDirty)
|
||||
{
|
||||
mTextNode->setFillColor(mBackgroundColor);
|
||||
}
|
||||
|
||||
if (mTransformDirty)
|
||||
{
|
||||
mTextNode->setLocation(middle);
|
||||
mTextNode->setWidth(mSize.mWidth);
|
||||
mTextNode->setHeight(mSize.mHeight);
|
||||
}
|
||||
|
||||
if (mContentDirty)
|
||||
{
|
||||
mTextNode->setContent(mLabel);
|
||||
mContentDirty = false;
|
||||
}
|
||||
|
||||
if (mVisibilityDirty)
|
||||
{
|
||||
mTextNode->setIsVisible(mVisible);
|
||||
}
|
||||
}
|
34
src/ui/ui_controls/Label.h
Normal file
34
src/ui/ui_controls/Label.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class TextNode;
|
||||
|
||||
class Label : public Widget
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Label();
|
||||
|
||||
virtual ~Label() = default;
|
||||
|
||||
static std::unique_ptr<Label> Create();
|
||||
|
||||
void setLabel(const std::string& text);
|
||||
|
||||
private:
|
||||
bool isDirty() const override;
|
||||
void doPaint(const PaintEvent* event) override;
|
||||
|
||||
void updateLabel(const PaintEvent* event);
|
||||
|
||||
std::string mLabel;
|
||||
std::unique_ptr<TextNode> mTextNode;
|
||||
bool mContentDirty{true};
|
||||
|
||||
};
|
||||
|
||||
using LabelUPtr = std::unique_ptr<Label>;
|
28
src/ui/ui_controls/StackWidget.cpp
Normal file
28
src/ui/ui_controls/StackWidget.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "StackWidget.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
StackWidget::StackWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<StackWidget> StackWidget::Create()
|
||||
{
|
||||
return std::make_unique<StackWidget>();
|
||||
}
|
||||
|
||||
void StackWidget::showChild(Widget* target)
|
||||
{
|
||||
for(auto& child : mChildren)
|
||||
{
|
||||
if(child.get() == target)
|
||||
{
|
||||
child->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
child->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
15
src/ui/ui_controls/StackWidget.h
Normal file
15
src/ui/ui_controls/StackWidget.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
class StackWidget : public Widget
|
||||
{
|
||||
public:
|
||||
StackWidget();
|
||||
|
||||
static std::unique_ptr<StackWidget> Create();
|
||||
|
||||
void showChild(Widget* child);
|
||||
};
|
||||
|
||||
using StackWidgetUPtr = std::unique_ptr<StackWidget>;
|
113
src/ui/ui_controls/TextBox.cpp
Normal file
113
src/ui/ui_controls/TextBox.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include "TextBox.h"
|
||||
|
||||
#include "TextNode.h"
|
||||
#include "GeometryNode.h"
|
||||
#include "KeyboardEvent.h"
|
||||
#include "TransformNode.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
TextBox::TextBox()
|
||||
: Widget(),
|
||||
mContent(),
|
||||
mCaps(false)
|
||||
{
|
||||
mBackgroundColor = Color(250, 250, 250);
|
||||
mPadding = {20, 0, 20, 0};
|
||||
}
|
||||
|
||||
std::unique_ptr<TextBox> TextBox::Create()
|
||||
{
|
||||
return std::make_unique<TextBox>();
|
||||
}
|
||||
|
||||
void TextBox::setContent(const std::string& text)
|
||||
{
|
||||
mContent = text;
|
||||
mContentDirty = true;
|
||||
}
|
||||
|
||||
std::string TextBox::getContent() const
|
||||
{
|
||||
return mContent;
|
||||
}
|
||||
|
||||
void TextBox::appendContent(const std::string& text)
|
||||
{
|
||||
mContent += text;
|
||||
mContentDirty = true;
|
||||
}
|
||||
|
||||
bool TextBox::onMyKeyboardEvent(const KeyboardEvent* event)
|
||||
{
|
||||
if(!event || !mVisible) return false;
|
||||
|
||||
if(event->isFunctionKey())
|
||||
{
|
||||
if (event->getFunction() == Keyboard::Function::ENTER)
|
||||
{
|
||||
appendContent("\n");
|
||||
}
|
||||
else if(event->getFunction() == Keyboard::Function::BACKSPACE)
|
||||
{
|
||||
mContent = mContent.substr(0, mContent.size()-1);
|
||||
mContentDirty = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto keyString = event->getKeyString();
|
||||
if (keyString.length() < 2)
|
||||
{
|
||||
appendContent(keyString);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendContent("?");
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextBox::isDirty() const
|
||||
{
|
||||
return Widget::isDirty() || mContentDirty;
|
||||
}
|
||||
|
||||
void TextBox::doPaint(const PaintEvent* event)
|
||||
{
|
||||
updateBackground(event);
|
||||
updateLabel(event);
|
||||
}
|
||||
|
||||
void TextBox::updateLabel(const PaintEvent* event)
|
||||
{
|
||||
auto loc = DiscretePoint(mLocation.getX() + mPadding.mLeft, mLocation.getY() + mPadding.mTop + unsigned(0));
|
||||
|
||||
if (!mTextNode)
|
||||
{
|
||||
mTextNode = TextNode::Create(mContent, loc);
|
||||
mTextNode->setWidth(mSize.mWidth);
|
||||
mTextNode->setHeight(mSize.mHeight);
|
||||
mRootNode->addChild(mTextNode.get());
|
||||
}
|
||||
|
||||
if (mMaterialDirty)
|
||||
{
|
||||
mTextNode->setFillColor(mBackgroundColor);
|
||||
}
|
||||
|
||||
if (mTransformDirty)
|
||||
{
|
||||
mTextNode->setLocation(loc);
|
||||
mTextNode->setWidth(mSize.mWidth);
|
||||
mTextNode->setHeight(mSize.mHeight);
|
||||
}
|
||||
|
||||
if (mContentDirty)
|
||||
{
|
||||
mTextNode->setContent(mContent);
|
||||
mContentDirty = false;
|
||||
}
|
||||
}
|
38
src/ui/ui_controls/TextBox.h
Normal file
38
src/ui/ui_controls/TextBox.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class TextNode;
|
||||
|
||||
class TextBox : public Widget
|
||||
{
|
||||
public:
|
||||
TextBox();
|
||||
|
||||
static std::unique_ptr<TextBox> Create();
|
||||
|
||||
void setContent(const std::string& text);
|
||||
|
||||
std::string getContent() const;
|
||||
|
||||
void appendContent(const std::string& text);
|
||||
|
||||
//void onPaintEvent(const PaintEvent* event) override;
|
||||
|
||||
bool onMyKeyboardEvent(const KeyboardEvent* event) override;
|
||||
|
||||
private:
|
||||
bool isDirty() const override;
|
||||
void doPaint(const PaintEvent* event) override;
|
||||
|
||||
void updateLabel(const PaintEvent* event);
|
||||
|
||||
std::string mContent;
|
||||
std::unique_ptr<TextNode> mTextNode;
|
||||
bool mContentDirty{true};
|
||||
bool mCaps;
|
||||
};
|
||||
|
||||
using TextBoxUPtr = std::unique_ptr<TextBox>;
|
44
src/ui/ui_controls/VerticalSpacer.cpp
Normal file
44
src/ui/ui_controls/VerticalSpacer.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include "VerticalSpacer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
VerticalSpacer::VerticalSpacer()
|
||||
: Widget(),
|
||||
mScales()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<VerticalSpacer> VerticalSpacer::Create()
|
||||
{
|
||||
return std::make_unique<VerticalSpacer>();
|
||||
}
|
||||
|
||||
void VerticalSpacer::addWidget(WidgetUPtr widget)
|
||||
{
|
||||
addWidgetWithScale(std::move(widget), 1.0);
|
||||
}
|
||||
|
||||
void VerticalSpacer::addWidgetWithScale(WidgetUPtr widget, double scale)
|
||||
{
|
||||
Widget::addWidget(std::move(widget));
|
||||
mScales.push_back(scale);
|
||||
}
|
||||
|
||||
void VerticalSpacer::updateChildLocations()
|
||||
{
|
||||
double scaleSum = std::accumulate(mScales.begin(), mScales.end(), 0.0);
|
||||
double offset = 0;
|
||||
unsigned delta = mSize.mWidth / unsigned(mChildren.size());
|
||||
for(std::size_t idx=0; idx<mChildren.size(); idx++)
|
||||
{
|
||||
auto& child = mChildren[idx];
|
||||
double scale = mScales[idx];
|
||||
double delta = mSize.mWidth * (scale/scaleSum);
|
||||
child->setBounds(unsigned(delta), mSize.mHeight);
|
||||
child->setLocation(DiscretePoint(mLocation.getX() + unsigned(offset), mLocation.getY()));
|
||||
offset += delta;
|
||||
}
|
||||
}
|
||||
|
22
src/ui/ui_controls/VerticalSpacer.h
Normal file
22
src/ui/ui_controls/VerticalSpacer.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
class VerticalSpacer : public Widget
|
||||
{
|
||||
|
||||
public:
|
||||
VerticalSpacer();
|
||||
|
||||
static std::unique_ptr<VerticalSpacer> Create();
|
||||
|
||||
void addWidget(WidgetUPtr widget) override;
|
||||
|
||||
void addWidgetWithScale(WidgetUPtr widget, double scale);
|
||||
|
||||
private:
|
||||
void updateChildLocations() override;
|
||||
std::vector<double> mScales;
|
||||
};
|
||||
|
||||
using VerticalSpacerUPtr = std::unique_ptr<VerticalSpacer>;
|
Loading…
Add table
Add a link
Reference in a new issue