Clean project structure.

This commit is contained in:
jmsgrogan 2023-01-17 10:13:25 +00:00
parent 78a4fa99ff
commit 947bf937fd
496 changed files with 206 additions and 137 deletions

View 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);
}
}

View 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>;

View file

View 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};
};

View 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 )

View 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;
}
}

View 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>;

View 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);
}
}

View 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>;

View 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);
}
}
}

View 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>;

View 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;
}
}

View 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>;

View 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;
}
}

View 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>;