This commit is contained in:
IlyaShurupov 2024-05-03 15:09:26 +03:00
parent 86a41c1876
commit e2072d257f
14 changed files with 594 additions and 341 deletions

View file

@ -6,9 +6,9 @@
using namespace tp; using namespace tp;
using namespace obj; using namespace obj;
class ExampleGUI : public Application { class SimpleGUI : public Application {
public: public:
ExampleGUI() { gui.cd(objects_api::create<DictObject>(), "root"); } SimpleGUI() { gui.cd(objects_api::create<DictObject>(), "root"); }
void processFrame(EventHandler* eventHandler) override {} void processFrame(EventHandler* eventHandler) override {}
@ -28,7 +28,7 @@ int main() {
if (module.initialize()) { if (module.initialize()) {
{ {
ExampleGUI gui; SimpleGUI gui;
gui.run(); gui.run();
} }
module.deinitialize(); module.deinitialize();

View file

@ -10,7 +10,12 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Math Graphics Imgui)
### -------------------------- Applications -------------------------- ### ### -------------------------- Applications -------------------------- ###
add_executable(ExampleGui examples/Entry.cpp) add_executable(SimpleGui examples/SimpleGUI.cpp)
target_link_libraries(ExampleGui ${PROJECT_NAME} ${GLEW_LIB}) target_link_libraries(SimpleGui ${PROJECT_NAME} ${GLEW_LIB})
target_include_directories(ExampleGui PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR}) target_include_directories(SimpleGui PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR})
add_executable(ChatGui examples/ChatGUI.cpp)
target_link_libraries(ChatGui ${PROJECT_NAME} ${GLEW_LIB})
target_include_directories(ChatGui PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR})
file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")

View file

@ -1,5 +1,5 @@
#include "ExampleGUI.hpp" #include "ChatGUI.hpp"
#include "GraphicApplication.hpp" #include "GraphicApplication.hpp"
@ -7,16 +7,20 @@ using namespace tp;
class ExampleGUI : public Application { class ExampleGUI : public Application {
public: public:
ExampleGUI() = default; ExampleGUI() { mGui.setupConfig(mWidgetManager); }
void processFrame(EventHandler* eventHandler) override { void processFrame(EventHandler* eventHandler) override {
auto rec = RectF({ 0, 0 }, mWindow->getSize()); auto rec = RectF({ 0, 0 }, mWindow->getSize());
mGui.updateConfigCache(mWidgetManager);
mGui.proc(*eventHandler, rec, rec); mGui.proc(*eventHandler, rec, rec);
} }
void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); } void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); }
private: private:
WidgetManager mWidgetManager;
ComplexWidget<EventHandler, Canvas> mGui; ComplexWidget<EventHandler, Canvas> mGui;
}; };

View file

@ -7,15 +7,7 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class UserWidget : public Widget<Events, Canvas> { class UserWidget : public Widget<Events, Canvas> {
public: public:
UserWidget() { UserWidget() { this->mId = "UserWidget"; }
this->createConfig("User");
this->addColor("Base", "Base");
this->addValue("Size", "FontSize");
this->addValue("Padding", "Padding");
this->addColor("ColUser", "Front");
this->addColor("Accent", "Accent");
this->addValue("Rounding", "Rounding");
}
void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override {
this->mArea = aArea; this->mArea = aArea;
@ -28,34 +20,48 @@ namespace tp {
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
if (!this->mVisible) return; if (!this->mVisible) return;
if (mIsHover) canvas.rect(this->mArea, this->getColor("Accent"), this->getValue("Rounding")); if (mIsHover) canvas.rect(this->mArea, mAccentColor, mRounding);
else canvas.rect(this->mArea, this->getColor("Base"), this->getValue("Rounding")); else canvas.rect(this->mArea, mBaseColor, mRounding);
const auto padding = this->getValue("Padding"); canvas.text(mUser.c_str(), this->mArea, mFontSize, Canvas::CC, mPadding, mUserColor);
const auto size = this->getValue("Size"); }
const auto colUser = this->getColor("ColUser");
canvas.text(mUser.c_str(), this->mArea, size, Canvas::CC, padding, colUser); public:
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Base", "Base");
wm.addReference(this->mId, "Size", "FontSize");
wm.addReference(this->mId, "Padding", "Padding");
wm.addReference(this->mId, "ColUser", "Front");
wm.addReference(this->mId, "Accent", "Accent");
wm.addReference(this->mId, "Rounding", "Rounding");
}
void updateConfigCache(const WidgetManager& wm) override {
mBaseColor = wm.getColor(this->mId, "Base");
mFontSize = wm.getNumber(this->mId, "Size");
mPadding = wm.getNumber(this->mId, "Padding");
mUserColor = wm.getColor(this->mId, "ColUser");
mAccentColor = wm.getColor(this->mId, "Accent");
mRounding = wm.getNumber(this->mId, "Rounding");
} }
public: public:
std::string mUser = "UserName"; std::string mUser = "UserName";
bool mIsHover = false; bool mIsHover = false;
RGBA mBaseColor;
RGBA mUserColor;
RGBA mAccentColor;
halnf mPadding = 0;
halnf mFontSize = 0;
halnf mRounding = 0;
}; };
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class MessageWidget : public Widget<Events, Canvas> { class MessageWidget : public Widget<Events, Canvas> {
public: public:
MessageWidget() { MessageWidget() { this->mId = "MessageWidget"; }
this->createConfig("Message");
this->addColor("Base", "Base");
this->addValue("Size", "FontSize");
this->addValue("SizeUser", "FontSizeDim");
this->addValue("Padding", "Padding");
this->addColor("ColUser", "Front");
this->addColor("Col", "FrontDim");
this->addValue("Rounding", "Rounding");
}
void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override {
this->mArea = aArea; this->mArea = aArea;
@ -67,14 +73,7 @@ namespace tp {
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
if (!this->mVisible) return; if (!this->mVisible) return;
if (mIsHover) canvas.rect(this->mArea, mBaseColor, mRounding);
if (mIsHover) canvas.rect(this->mArea, this->getColor("Base"), this->getValue("Rounding"));
const auto padding = this->getValue("Padding");
const auto size = this->getValue("Size");
const auto sizeUser = this->getValue("SizeUser");
const auto col = this->getColor("Col");
const auto colUser = this->getColor("ColUser");
auto userName = this->mArea; auto userName = this->mArea;
userName.w = 25; userName.w = 25;
@ -83,22 +82,51 @@ namespace tp {
content.y = userName.y + userName.w; content.y = userName.y + userName.w;
content.w = this->mArea.w - userName.w; content.w = this->mArea.w - userName.w;
canvas.text(mContent.c_str(), content, size, Canvas::LC, padding, col); canvas.text(mContent.c_str(), content, mFontSize, Canvas::LC, mPadding, mUserColorDim);
canvas.text(mUser.c_str(), userName, sizeUser, Canvas::LC, padding, colUser); canvas.text(mUser.c_str(), userName, mFontSizeDim, Canvas::LC, mPadding, mUserColor);
}
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Base", "Base");
wm.addReference(this->mId, "Size", "FontSize");
wm.addReference(this->mId, "SizeUser", "FontSizeDim");
wm.addReference(this->mId, "Padding", "Padding");
wm.addReference(this->mId, "UserColor", "Front");
wm.addReference(this->mId, "UserColorDim", "FrontDim");
wm.addReference(this->mId, "Rounding", "Rounding");
}
void updateConfigCache(const WidgetManager& wm) override {
mBaseColor = wm.getColor(this->mId, "Base");
mFontSize = wm.getNumber(this->mId, "Size");
mFontSizeDim = wm.getNumber(this->mId, "SizeUser");
mPadding = wm.getNumber(this->mId, "Padding");
mUserColor = wm.getColor(this->mId, "UserColor");
mUserColorDim = wm.getColor(this->mId, "UserColorDim");
mRounding = wm.getNumber(this->mId, "Rounding");
} }
public: public:
std::string mContent = "Message Content"; std::string mContent = "Message Content";
std::string mUser = "UserName"; std::string mUser = "UserName";
bool mIsHover = false; bool mIsHover = false;
RGBA mBaseColor;
RGBA mUserColor;
RGBA mUserColorDim;
halnf mPadding = 0;
halnf mFontSize = 0;
halnf mFontSizeDim = 0;
halnf mRounding = 0;
}; };
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class LoginWidget : public Widget<Events, Canvas> { class LoginWidget : public Widget<Events, Canvas> {
public: public:
explicit LoginWidget() { explicit LoginWidget() {
this->createConfig("Login"); this->mId = "Login";
this->addColor("Back", "Background");
mPass.mId = "pass"; mPass.mId = "pass";
mUser.mId = "user"; mUser.mId = "user";
mButton.mLabel.mLabel = "Login"; mButton.mLabel.mLabel = "Login";
@ -120,26 +148,45 @@ namespace tp {
} }
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
canvas.rect(this->mArea, this->getColor("Back")); canvas.rect(this->mArea, mBGColor);
mButton.draw(canvas); mButton.draw(canvas);
mUser.draw(canvas); mUser.draw(canvas);
mPass.draw(canvas); mPass.draw(canvas);
} }
public:
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Back", "Base");
mUser.setupConfig(wm);
mPass.setupConfig(wm);
mButton.setupConfig(wm);
}
void updateConfigCache(const WidgetManager& wm) override {
mBGColor = wm.getColor(this->mId, "Back");
mUser.updateConfigCache(wm);
mPass.updateConfigCache(wm);
mButton.updateConfigCache(wm);
}
public: public:
TextInputWidget<Events, Canvas> mUser; TextInputWidget<Events, Canvas> mUser;
TextInputWidget<Events, Canvas> mPass; TextInputWidget<Events, Canvas> mPass;
ButtonWidget<Events, Canvas> mButton; ButtonWidget<Events, Canvas> mButton;
bool mLogged = false; bool mLogged = false;
RGBA mBGColor;
}; };
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class ActiveChatWidget : public Widget<Events, Canvas> { class ActiveChatWidget : public Widget<Events, Canvas> {
public: public:
ActiveChatWidget() { ActiveChatWidget() {
this->createConfig("ActiveChat"); this->mId = "ActiveWidget";
this->addColor("Back", "Background");
this->addValue("Padding", "Padding");
mSend.mLabel.mLabel = "Send"; mSend.mLabel.mLabel = "Send";
mMessage.mId = "Message"; mMessage.mId = "Message";
} }
@ -152,16 +199,16 @@ namespace tp {
auto input = this->mArea; auto input = this->mArea;
input.y = history.w + 10; input.y = history.w + 10;
input.w = 40 - this->getValue("Padding"); input.w = 40 - mPadding;
input.x += this->getValue("Padding"); input.x += mPadding;
input.z -= this->getValue("Padding"); input.z -= mPadding;
auto inputMessage = input; auto inputMessage = input;
inputMessage.z -= 100; inputMessage.z -= 100;
auto inputSend = input; auto inputSend = input;
inputSend.x = inputMessage.x + inputMessage.z + this->getValue("Padding"); inputSend.x = inputMessage.x + inputMessage.z + mPadding;
inputSend.z = 100 - this->getValue("Padding") * 2; inputSend.z = 100 - mPadding * 2;
mSend.proc(events, this->mArea, inputSend); mSend.proc(events, this->mArea, inputSend);
mMessage.proc(events, this->mArea, inputMessage); mMessage.proc(events, this->mArea, inputMessage);
@ -174,26 +221,53 @@ namespace tp {
} }
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
canvas.rect(this->mArea, this->getColor("Back")); canvas.rect(this->mArea, mBGColor);
mHistoryView.draw(canvas); mHistoryView.draw(canvas);
mMessage.draw(canvas); mMessage.draw(canvas);
mSend.draw(canvas); mSend.draw(canvas);
} }
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Back", "Background");
wm.addReference(this->mId, "Padding", "Padding");
mHistoryView.setupConfig(wm);
mMessage.setupConfig(wm);
mSend.setupConfig(wm);
MessageWidget<Events, Canvas>().setupConfig(wm);
}
void updateConfigCache(const WidgetManager& wm) override {
mBGColor = wm.getColor(this->mId, "Back");
mPadding = wm.getNumber(this->mId, "Padding");
mHistoryView.updateConfigCache(wm);
mMessage.updateConfigCache(wm);
mSend.updateConfigCache(wm);
for (auto message : mMessages) {
message->updateConfigCache(wm);
}
}
public: public:
Buffer<MessageWidget<Events, Canvas>> mMessages; Buffer<MessageWidget<Events, Canvas>> mMessages;
ScrollableWindow<Events, Canvas> mHistoryView; ScrollableWindow<Events, Canvas> mHistoryView;
TextInputWidget<Events, Canvas> mMessage; TextInputWidget<Events, Canvas> mMessage;
ButtonWidget<Events, Canvas> mSend; ButtonWidget<Events, Canvas> mSend;
RGBA mBGColor;
halnf mPadding = 0;
}; };
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class ChattingWidget : public Widget<Events, Canvas> { class ChattingWidget : public Widget<Events, Canvas> {
public: public:
ChattingWidget() { ChattingWidget() {
this->createConfig("Chatting"); this->mId = "Chatting";
this->addColor("Back", "Background");
this->addValue("Padding", "Padding");
// todo : fetch code // todo : fetch code
mUsers.append(UserWidget<Events, Canvas>()); mUsers.append(UserWidget<Events, Canvas>());
@ -225,34 +299,54 @@ namespace tp {
this->mArea = aArea; this->mArea = aArea;
mSplitView.proc(events, aArea, aArea); mSplitView.proc(events, aArea, aArea);
const auto padding = this->getValue("Padding");
mSideView.proc(events, this->mArea, mSplitView.getSecond()); mSideView.proc(events, this->mArea, mSplitView.getSecond());
mActive.proc(events, aArea, mSplitView.getFirst()); mActive.proc(events, aArea, mSplitView.getFirst());
} }
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
canvas.rect(this->mArea, this->getColor("Back")); canvas.rect(this->mArea, mBGColor);
mSplitView.draw(canvas); mSplitView.draw(canvas);
mSideView.draw(canvas); mSideView.draw(canvas);
mActive.draw(canvas); mActive.draw(canvas);
} }
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Back", "Background");
mSideView.setupConfig(wm);
mActive.setupConfig(wm);
mSplitView.setupConfig(wm);
UserWidget<Events, Canvas>().setupConfig(wm);
}
void updateConfigCache(const WidgetManager& wm) override {
mBGColor = wm.getColor(this->mId, "Back");
mSideView.updateConfigCache(wm);
mActive.updateConfigCache(wm);
mSplitView.updateConfigCache(wm);
for (auto user : mUsers) {
user->updateConfigCache(wm);
}
}
public: public:
Buffer<UserWidget<Events, Canvas>> mUsers; Buffer<UserWidget<Events, Canvas>> mUsers;
ScrollableWindow<Events, Canvas> mSideView; ScrollableWindow<Events, Canvas> mSideView;
ActiveChatWidget<Events, Canvas> mActive; ActiveChatWidget<Events, Canvas> mActive;
SplitView<Events, Canvas> mSplitView; SplitView<Events, Canvas> mSplitView;
RGBA mBGColor;
}; };
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class ComplexWidget : public Widget<Events, Canvas> { class ComplexWidget : public Widget<Events, Canvas> {
public: public:
ComplexWidget() { ComplexWidget() { this->mId = "Chat"; }
this->createConfig("chat");
this->addColor("Back", "Background");
}
void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override {
this->mArea = aArea; this->mArea = aArea;
@ -268,14 +362,32 @@ namespace tp {
} }
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
canvas.rect(this->mArea, this->getColor("Back")); canvas.rect(this->mArea, mBGColor);
if (mLogged) mChatting.draw(canvas); if (mLogged) mChatting.draw(canvas);
else mLogin.draw(canvas); else mLogin.draw(canvas);
} }
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Back", "Background");
mLogin.setupConfig(wm);
mChatting.setupConfig(wm);
}
void updateConfigCache(const WidgetManager& wm) override {
mBGColor = wm.getColor(this->mId, "Back");
mLogin.updateConfigCache(wm);
mChatting.updateConfigCache(wm);
}
private: private:
bool mLogged = false; bool mLogged = false;
LoginWidget<Events, Canvas> mLogin; LoginWidget<Events, Canvas> mLogin;
ChattingWidget<Events, Canvas> mChatting; ChattingWidget<Events, Canvas> mChatting;
RGBA mBGColor;
}; };
} }

View file

@ -0,0 +1,50 @@
#include "ChatGUI.hpp"
#include "GraphicApplication.hpp"
using namespace tp;
class SimpleGUI : public Application {
public:
SimpleGUI() {
mGui.setupConfig(mWidgetManager);
mButton.setupConfig(mWidgetManager);
mSlider.setupConfig(mWidgetManager);
mLabel.setupConfig(mWidgetManager);
mGui.mContents.append(&mButton);
mGui.mContents.append(&mSlider);
mGui.mContents.append(&mLabel);
}
void processFrame(EventHandler* eventHandler) override {
mGui.updateConfigCache(mWidgetManager);
mSlider.updateConfigCache(mWidgetManager);
mLabel.updateConfigCache(mWidgetManager);
mButton.updateConfigCache(mWidgetManager);
const auto rec = RectF({ 0, 0 }, mWindow->getSize());
mGui.proc(*eventHandler, rec, rec);
}
void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); }
private:
WidgetManager mWidgetManager;
ScrollableWindow<EventHandler, Canvas> mGui;
ButtonWidget<EventHandler, Canvas> mButton;
LabelWidget<EventHandler, Canvas> mLabel;
SliderWidget<EventHandler, Canvas> mSlider;
};
int main() {
{
SimpleGUI gui;
gui.run();
}
}

View file

@ -9,22 +9,13 @@ namespace tp {
public: public:
ButtonWidget() { ButtonWidget() {
this->mArea = { 0, 0, 100, 100 }; this->mArea = { 0, 0, 100, 100 };
this->createConfig("Button"); this->mId = "Button";
this->addColor("Pressed", "Action");
this->addColor("Hovered", "Interaction");
this->addColor("Default", "Accent");
this->addValue("Rounding", "Rounding");
} }
ButtonWidget(const std::string& label, const tp::RectF& aArea) { ButtonWidget(const std::string& label, const tp::RectF& aArea) {
this->mId = "Button";
this->mArea = aArea; this->mArea = aArea;
this->mLabel.mLabel = label; this->mLabel.mLabel = label;
this->createConfig("Button");
this->addColor("Pressed", "Action");
this->addColor("Hovered", "Interaction");
this->addColor("Default", "Accent");
this->addValue("Rounding", "Rounding");
} }
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
@ -60,19 +51,45 @@ namespace tp {
if (!this->mVisible) return; if (!this->mVisible) return;
if (mIsPressed) { if (mIsPressed) {
canvas.rect(this->mArea, this->getColor("Pressed"), this->getValue("Rounding")); canvas.rect(this->mArea, pressedColor, rounding);
} else if (mIsHover) { } else if (mIsHover) {
canvas.rect(this->mArea, this->getColor("Hovered"), this->getValue("Rounding")); canvas.rect(this->mArea, hoveredColor, rounding);
} else { } else {
canvas.rect(this->mArea, this->getColor("Default"), this->getValue("Rounding")); canvas.rect(this->mArea, accentColor, rounding);
} }
mLabel.draw(canvas); mLabel.draw(canvas);
} }
public:
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Pressed", "Action");
wm.addReference(this->mId, "Hovered", "Interaction");
wm.addReference(this->mId, "Default", "Accent");
wm.addReference(this->mId, "Rounding", "Rounding");
mLabel.setupConfig(wm);
}
void updateConfigCache(const WidgetManager& wm) override {
pressedColor = wm.getColor(this->mId, "Pressed");
hoveredColor = wm.getColor(this->mId, "Hovered");
accentColor = wm.getColor(this->mId, "Default");
rounding = wm.getNumber(this->mId, "Rounding");
mLabel.updateConfigCache(wm);
}
public: public:
LabelWidget<Events, Canvas> mLabel; LabelWidget<Events, Canvas> mLabel;
bool mIsHover = false; bool mIsHover = false;
bool mIsPressed = false; bool mIsPressed = false;
bool mIsReleased = false; bool mIsReleased = false;
RGBA pressedColor;
RGBA hoveredColor;
RGBA accentColor;
halnf rounding = 0;
}; };
} }

View file

@ -6,14 +6,9 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class LabelWidget : public Widget<Events, Canvas> { class LabelWidget : public Widget<Events, Canvas> {
public: public:
LabelWidget() { LabelWidget() { this->mId = "Label"; }
this->createConfig("Label");
this->addValue("Size", "FontSize");
this->addValue("Padding", "Padding");
this->addColor("Default", "Front");
}
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void proc(const Events&, const tp::RectF& areaParent, const tp::RectF& aArea) override {
this->mArea = aArea; this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea); this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return; if (!this->mVisible) return;
@ -21,18 +16,28 @@ namespace tp {
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
if (!this->mVisible) return; if (!this->mVisible) return;
canvas.text(mLabel.c_str(), this->mArea, fontSize, Canvas::CC, padding, fontColor);
}
canvas.text( public:
mLabel.c_str(), void setupConfig(WidgetManager& wm) {
this->mArea, if (!wm.createWidgetConfig(this->mId)) return;
this->getValue("Size"), wm.addReference(this->mId, "Size", "FontSize");
Canvas::CC, wm.addReference(this->mId, "Padding", "Padding");
this->getValue("Padding"), wm.addReference(this->mId, "Default", "Front");
this->getColor("Default") }
);
void updateConfigCache(const WidgetManager& wm) override {
fontSize = wm.getNumber(this->mId, "Size");
padding = wm.getNumber(this->mId, "Padding");
fontColor = wm.getColor(this->mId, "Default");
} }
public: public:
std::string mLabel = "Label"; std::string mLabel = "Label";
halnf fontSize = 10;
halnf padding = 0;
RGBA fontColor = { 1, 1, 1, 1 };
}; };
} }

View file

@ -8,17 +8,7 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class ScrollBarWidget : public Widget<Events, Canvas> { class ScrollBarWidget : public Widget<Events, Canvas> {
public: public:
ScrollBarWidget() { ScrollBarWidget() { this->mId = "ScrollBar"; }
this->createConfig("ScrollBar");
this->addColor("Default", "Base");
this->addColor("Handle", "Accent");
this->addColor("Hovered", "Interaction");
this->addColor("Scrolling", "Action");
this->addValue("Padding", "Padding");
this->addValue("HandleSize", 20.f);
this->addValue("MinSize", 20.f);
this->addValue("Rounding", "Rounding");
}
// takes whole area // takes whole area
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
@ -79,28 +69,22 @@ namespace tp {
if (mSizeFraction > 1.f) return; if (mSizeFraction > 1.f) return;
// if (!areaParent.isOverlap(getHandle())) return; // if (!areaParent.isOverlap(getHandle())) return;
tp::RGBA col = this->getColor("Handle"); tp::RGBA col = mHandleColor;
if (mIsScrolling) { if (mIsScrolling) {
col = this->getColor("Scrolling"); col = mScrollingColor;
} else if (mHovered) { } else if (mHovered) {
col = this->getColor("Hovered"); col = mHoveredColor;
} }
canvas.rect(area, this->getColor("Default"), this->getValue("Rounding")); canvas.rect(area, mDefaultColor, mRounding);
canvas.rect(getHandleHandle(), col, this->getValue("Rounding")); canvas.rect(getHandleHandle(), col, mRounding);
} }
RectF getHandleHandle() const { RectF getHandleHandle() const {
auto minSize = this->getValue("MinSize");
if (mIsScrolling) {
minSize = this->getValue("MinSize") * 2;
} else if (mHovered) {
minSize = this->getValue("MinSize") * 2;
}
auto area = getHandle(); auto area = getHandle();
auto sliderSize = tp::clamp(area.w * mSizeFraction, minSize, area.w); auto sliderSize = tp::clamp(area.w * mSizeFraction, mMinSize * 2, area.w);
auto diffSize = sliderSize - area.w * mSizeFraction; auto diffSize = sliderSize - area.w * mSizeFraction;
return { area.x, area.y + (area.w - diffSize) * mPositionFraction, area.z, sliderSize }; return { area.x, area.y + (area.w - diffSize) * mPositionFraction, area.z, sliderSize };
} }
@ -109,14 +93,39 @@ namespace tp {
if (mSizeFraction > 1.f) { if (mSizeFraction > 1.f) {
return this->mArea; return this->mArea;
} }
return { this->mArea.x, this->mArea.y, this->mArea.z - this->getValue("HandleSize"), this->mArea.w }; return { this->mArea.x, this->mArea.y, this->mArea.z - mHandleSize, this->mArea.w };
} }
RectF getHandle() const { RectF getHandle() const {
return { this->mArea.x + this->mArea.z - this->getValue("HandleSize") + this->getValue("Padding"), return { this->mArea.x + this->mArea.z - mHandleSize + mPadding,
this->mArea.y + this->getValue("Padding"), this->mArea.y + mPadding,
this->getValue("HandleSize") - this->getValue("Padding") * 2, mHandleSize - mPadding * 2,
this->mArea.w - this->getValue("Padding") * 2 }; this->mArea.w - mPadding * 2 };
}
public:
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Default", "Base");
wm.addReference(this->mId, "Handle", "Accent");
wm.addReference(this->mId, "Hovered", "Interaction");
wm.addReference(this->mId, "Scrolling", "Action");
wm.addReference(this->mId, "Padding", "Padding");
wm.addNumber(this->mId, "HandleSize", 20.f);
wm.addNumber(this->mId, "MinSize", 20.f);
wm.addReference(this->mId, "Rounding", "Rounding");
}
void updateConfigCache(const WidgetManager& wm) override {
mDefaultColor = wm.getColor(this->mId, "Default");
mHandleColor = wm.getColor(this->mId, "Handle");
mHoveredColor = wm.getColor(this->mId, "Hovered");
mScrollingColor = wm.getColor(this->mId, "Scrolling");
mPadding = wm.getNumber(this->mId, "Padding");
mHandleSize = wm.getNumber(this->mId, "HandleSize");
mMinSize = wm.getNumber(this->mId, "MinSize");
mRounding = wm.getNumber(this->mId, "Rounding");
} }
public: public:
@ -126,16 +135,21 @@ namespace tp {
halnf mSizeFraction = 1.f; halnf mSizeFraction = 1.f;
halnf mPositionFraction = 0.f; halnf mPositionFraction = 0.f;
bool mHovered = false; bool mHovered = false;
RGBA mDefaultColor;
RGBA mHandleColor;
RGBA mHoveredColor;
RGBA mScrollingColor;
halnf mPadding = 0;
halnf mHandleSize = 10;
halnf mMinSize = 10;
halnf mRounding = 10;
}; };
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class ScrollableWindow : public Widget<Events, Canvas> { class ScrollableWindow : public Widget<Events, Canvas> {
public: public:
ScrollableWindow() { ScrollableWindow() { this->mId = "ScrollableWindow"; }
this->createConfig("ScrollableWindow");
this->addColor("Default", "Base");
this->addValue("Padding", "Padding");
}
~ScrollableWindow() = default; ~ScrollableWindow() = default;
@ -148,7 +162,7 @@ namespace tp {
updateContents(); updateContents();
updateContentSize(); updateContentSize();
const auto padding = this->getValue("Padding"); const auto padding = mPadding;
mScroller.mSizeFraction = this->mArea.w / mContentSize; mScroller.mSizeFraction = this->mArea.w / mContentSize;
mScroller.proc(events, this->mArea, this->mArea); mScroller.proc(events, this->mArea, this->mArea);
@ -180,16 +194,37 @@ namespace tp {
canvas.popClamp(); canvas.popClamp();
} }
public:
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Default", "Base");
wm.addReference(this->mId, "Padding", "Padding");
wm.addReference(this->mId, "Rounding", "Rounding");
mScroller.setupConfig(wm);
}
void updateConfigCache(const WidgetManager& wm) override {
mDefaultColor = wm.getColor(this->mId, "Default");
mPadding = wm.getNumber(this->mId, "Padding");
mScroller.updateConfigCache(wm);
for (auto item : mContents) {
item->updateConfigCache(wm);
}
}
private: private:
void updateContents() { void updateContents() {
if (mContents.size()) { if (mContents.size()) {
const auto padding = this->getValue("Padding"); const halnf offset = mContents.first()->mArea.y + mPadding;
const halnf offset = mContents.first()->mArea.y + padding;
halnf start = 0; halnf start = 0;
for (auto widget : mContents) { for (auto widget : mContents) {
widget->mArea.y = start; widget->mArea.y = start;
start += widget->mArea.w + padding; start += widget->mArea.w + mPadding;
} }
for (auto widget : mContents) { for (auto widget : mContents) {
@ -201,17 +236,15 @@ namespace tp {
void updateContentSize() { void updateContentSize() {
mContentSize = 0; mContentSize = 0;
if (mContents.size()) { if (mContents.size()) {
const auto padding = this->getValue("Padding");
mContentSize = mContents.last()->mArea.y - mContents.first()->mArea.y; mContentSize = mContents.last()->mArea.y - mContents.first()->mArea.y;
mContentSize += mContents.last()->mArea.w; mContentSize += mContents.last()->mArea.w;
mContentSize += 2 * padding; mContentSize += 2 * mPadding;
} }
} }
void setOffset(const halnf offset) { void setOffset(const halnf offset) {
if (!mContents.size()) return; if (!mContents.size()) return;
const auto padding = this->getValue("Padding"); auto newOffset = offset - mContents.first()->mArea.y + mPadding;
auto newOffset = offset - mContents.first()->mArea.y + padding;
for (auto widget : mContents) { for (auto widget : mContents) {
widget->mArea.y += newOffset; widget->mArea.y += newOffset;
} }
@ -219,7 +252,11 @@ namespace tp {
public: public:
halnf mContentSize = 0; halnf mContentSize = 0;
Buffer<Widget<Events, Canvas>*> mContents; Buffer<Widget<Events, Canvas>*> mContents;
ScrollBarWidget<Events, Canvas> mScroller; ScrollBarWidget<Events, Canvas> mScroller;
RGBA mDefaultColor;
halnf mPadding = 0;
}; };
} }

View file

@ -7,17 +7,7 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class SliderWidget : public Widget<Events, Canvas> { class SliderWidget : public Widget<Events, Canvas> {
public: public:
SliderWidget() { SliderWidget() { this->mId = "SliderWidget"; }
this->createConfig("SliderWidget");
this->addColor("Default", "Base");
this->addColor("Handle", "Accent");
this->addColor("Hovered", "Interaction");
this->addColor("Scrolling", "Action");
this->addValue("Padding", "Padding");
this->addValue("HandleSize", 20.f);
this->addValue("MinSize", 20.f);
this->addValue("Rounding", "Rounding");
}
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
this->mArea = aArea; this->mArea = aArea;
@ -31,7 +21,6 @@ namespace tp {
} }
if (mIsSliding) { if (mIsSliding) {
const auto handleSize = this->getValue("HandleSize");
mFactor = (events.getPointer().x - this->mArea.x - handleSize / 2.f) / (this->mArea.z - handleSize); mFactor = (events.getPointer().x - this->mArea.x - handleSize / 2.f) / (this->mArea.z - handleSize);
} }
@ -40,26 +29,47 @@ namespace tp {
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
if (!this->mVisible) return; if (!this->mVisible) return;
canvas.rect(this->mArea, this->getColor("Default"), this->getValue("Rounding")); canvas.rect(this->mArea, defaultColor, rounding);
canvas.rect(getHandle(), this->getColor("Handle"), this->getValue("Rounding")); canvas.rect(getHandle(), handleColor, rounding);
} }
RectF getHandle() const { RectF getHandle() const {
const auto handle = this->getValue("HandleSize"); const auto halfHandle = handleSize / 2.f;
const auto halfHandle = handle / 2.f; const auto left = this->mArea.x + (this->mArea.z - handleSize) * mFactor;
const auto left = this->mArea.x + (this->mArea.z - handle) * mFactor; return { left, this->mArea.y, handleSize, this->mArea.w };
return { left, this->mArea.y, handle, this->mArea.w }; }
public:
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Default", "Base");
wm.addReference(this->mId, "Handle", "Accent");
wm.addNumber(this->mId, "HandleSize", 20.f);
wm.addReference(this->mId, "Rounding", "Rounding");
}
void updateConfigCache(const WidgetManager& wm) override {
defaultColor = wm.getColor(this->mId, "Default");
handleColor = wm.getColor(this->mId, "Handle");
handleSize = wm.getNumber(this->mId, "HandleSize");
rounding = wm.getNumber(this->mId, "Rounding");
} }
public: public:
halnf mFactor = 0.f; halnf mFactor = 0.f;
bool mIsSliding = false; bool mIsSliding = false;
RGBA defaultColor;
RGBA handleColor;
halnf handleSize = 0;
halnf rounding = 0;
}; };
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class NamedSliderWidget : public Widget<Events, Canvas> { class NamedSliderWidget : public Widget<Events, Canvas> {
public: public:
NamedSliderWidget(const char* name = "Value") { explicit NamedSliderWidget(const char* name = "Value") {
this->mId = "NamedSliderWidget";
mLabel.mLabel = name; mLabel.mLabel = name;
this->mArea = { 0, 0, 100, 30 }; this->mArea = { 0, 0, 100, 30 };
} }
@ -89,6 +99,7 @@ namespace tp {
mLabel.draw(canvas); mLabel.draw(canvas);
} }
public:
public: public:
SliderWidget<Events, Canvas> mSlider; SliderWidget<Events, Canvas> mSlider;
LabelWidget<Events, Canvas> mLabel; LabelWidget<Events, Canvas> mLabel;

View file

@ -6,14 +6,7 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class SplitView : public Widget<Events, Canvas> { class SplitView : public Widget<Events, Canvas> {
public: public:
SplitView() { SplitView() { this->mId = "SplitView"; }
this->createConfig("SplitView");
this->addColor("Handle", "Accent");
this->addColor("Hovered", "Interaction");
this->addColor("Resizing", "Action");
this->addValue("Min", 200.f);
this->addValue("HandleSize", 7.f);
}
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
this->mArea = aArea; this->mArea = aArea;
@ -38,9 +31,9 @@ namespace tp {
mFactor += diff / this->mArea.z; mFactor += diff / this->mArea.z;
} }
mFactor = tp::clamp(mFactor, this->getValue("Min") / this->mArea.z, 1 - this->getValue("Min") / this->mArea.z); mFactor = tp::clamp(mFactor, mMinSize / this->mArea.z, 1 - mMinSize / this->mArea.z);
if (this->getValue("Min") * 2.f > this->mArea.z) { if (mMinSize * 2.f > this->mArea.z) {
mFactor = 0.5f; mFactor = 0.5f;
} }
} }
@ -49,34 +42,52 @@ namespace tp {
void draw(Canvas& canvas) override { void draw(Canvas& canvas) override {
if (!this->mVisible) return; if (!this->mVisible) return;
if (mResizeInProcess) canvas.rect(getHandle(), this->getColor("Resizing")); if (mResizeInProcess) canvas.rect(getHandle(), mResizingColor);
else if (mIsHover) canvas.rect(getHandle(), this->getColor("Hovered")); else if (mIsHover) canvas.rect(getHandle(), mHoveredColor);
else canvas.rect(getHandle(), this->getColor("Handle")); else canvas.rect(getHandle(), mHandleColor);
} }
RectF getFirst() const { RectF getFirst() const {
return { return { this->mArea.x, this->mArea.y, mFactor * this->mArea.z - mHandleSize / 2.f, this->mArea.w };
this->mArea.x, this->mArea.y, mFactor * this->mArea.z - this->getValue("HandleSize") / 2.f, this->mArea.w
};
} }
RectF getSecond() const { RectF getSecond() const {
return { this->mArea.x + mFactor * this->mArea.z + this->getValue("HandleSize") / 2.f, return { this->mArea.x + mFactor * this->mArea.z + mHandleSize / 2.f,
this->mArea.y, this->mArea.y,
(1.f - mFactor) * this->mArea.z - this->getValue("HandleSize") / 2.f, (1.f - mFactor) * this->mArea.z - mHandleSize / 2.f,
this->mArea.w }; this->mArea.w };
} }
RectF getHandle() const { RectF getHandle() const {
return { this->mArea.x + mFactor * this->mArea.z - this->getValue("HandleSize") / 2.f, return { this->mArea.x + mFactor * this->mArea.z - mHandleSize / 2.f, this->mArea.y, mHandleSize, this->mArea.w };
this->mArea.y, }
this->getValue("HandleSize"),
this->mArea.w }; void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Handle", "Accent");
wm.addReference(this->mId, "Hovered", "Interaction");
wm.addReference(this->mId, "Resizing", "Action");
wm.addNumber(this->mId, "Min", 200.f);
wm.addNumber(this->mId, "HandleSize", 7.f);
}
void updateConfigCache(const WidgetManager& wm) override {
mHandleColor = wm.getColor(this->mId, "Handle");
mHoveredColor = wm.getColor(this->mId, "Hovered");
mResizingColor = wm.getColor(this->mId, "Resizing");
mMinSize = wm.getNumber(this->mId, "Min");
mHandleSize = wm.getNumber(this->mId, "HandleSize");
} }
public: public:
halnf mFactor = 0.7f; halnf mFactor = 0.7f;
bool mResizeInProcess = false; bool mResizeInProcess = false;
bool mIsHover = false; bool mIsHover = false;
RGBA mHandleColor;
RGBA mHoveredColor;
RGBA mResizingColor;
halnf mMinSize = 0;
halnf mHandleSize = 0;
}; };
} }

View file

@ -9,14 +9,7 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class TextInputWidget : public Widget<Events, Canvas> { class TextInputWidget : public Widget<Events, Canvas> {
public: public:
TextInputWidget() { TextInputWidget() { this->mId = "TextInput"; }
this->createConfig("TextInput");
this->addColor("Accent", "Accent");
this->addColor("Base", "Base");
this->addValue("Rounding", "Rounding");
this->addColor("Hovered", "Interaction");
this->addValue("Padding", "Padding");
}
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
this->mArea = aArea; this->mArea = aArea;
@ -29,8 +22,8 @@ namespace tp {
nChanged = false; nChanged = false;
const auto col = this->getColor("Accent"); const auto col = mAccentColor;
const auto colSel = this->getColor("Hovered"); const auto colSel = mHoveredColor;
ImGui::GetStyle().Colors[ImGuiCol_FrameBg] = { col.r, col.g, col.b, col.a }; ImGui::GetStyle().Colors[ImGuiCol_FrameBg] = { col.r, col.g, col.b, col.a };
ImGui::GetStyle().Colors[ImGuiCol_TextSelectedBg] = { colSel.r, colSel.g, colSel.b, colSel.a }; ImGui::GetStyle().Colors[ImGuiCol_TextSelectedBg] = { colSel.r, colSel.g, colSel.b, colSel.a };
@ -38,8 +31,8 @@ namespace tp {
ImGui::SetNextWindowPos({ this->mArea.x, this->mArea.y }); ImGui::SetNextWindowPos({ this->mArea.x, this->mArea.y });
ImGui::SetNextWindowSize({ this->mArea.z, this->mArea.w }); ImGui::SetNextWindowSize({ this->mArea.z, this->mArea.w });
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 0, 0 }); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 0, 0 });
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, this->getValue("Rounding") * 1.5f); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, mRounding * 1.5f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { this->getValue("Padding"), this->getValue("Padding") }); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { mPadding, mPadding });
// ImGui::PushID((int) alni(this)); // ImGui::PushID((int) alni(this));
ImGui::Begin( ImGui::Begin(
@ -65,11 +58,36 @@ namespace tp {
ImGui::PopStyleVar(3); ImGui::PopStyleVar(3);
} }
public:
void setupConfig(WidgetManager& wm) {
if (!wm.createWidgetConfig(this->mId)) return;
wm.addReference(this->mId, "Accent", "Accent");
wm.addReference(this->mId, "Base", "Base");
wm.addReference(this->mId, "Rounding", "Rounding");
wm.addReference(this->mId, "Hovered", "Accent");
wm.addReference(this->mId, "Padding", "Padding");
}
void updateConfigCache(const WidgetManager& wm) override {
mAccentColor = wm.getColor(this->mId, "Accent");
mBaseColor = wm.getColor(this->mId, "Base");
mHoveredColor = wm.getColor(this->mId, "Hovered");
mRounding = wm.getNumber(this->mId, "Rounding");
mPadding = wm.getNumber(this->mId, "Padding");
}
public:
enum { mMaxBufferSize = 512 }; enum { mMaxBufferSize = 512 };
char mBuff[mMaxBufferSize] = ""; char mBuff[mMaxBufferSize] = "";
bool nChanged = false; bool nChanged = false;
std::string mValue; std::string mValue;
std::string mId = "id"; std::string mId = "id";
bool mMultiline = false; bool mMultiline = false;
RGBA mAccentColor;
RGBA mHoveredColor;
RGBA mBaseColor;
halnf mRounding = 0;
halnf mPadding = 0;
}; };
} }

View file

@ -1,56 +1,14 @@
;
#pragma once #pragma once
#include "WidgetConfig.hpp" #include "WidgetManager.hpp"
namespace tp { namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class Widget { class Widget {
public: public:
using WidgetConfig = WidgetConfig<Events, Canvas>;
using WidgetNode = WidgetConfig::Node;
using GlobalGUIConfig = GlobalGUIConfig<Events, Canvas>;
Widget() { this->mArea = { 0, 0, 100, 100 }; } Widget() { this->mArea = { 0, 0, 100, 100 }; }
virtual void populateConfig() {}
[[nodiscard]] const RGBA& getColor(const std::string& name) const {
const auto& node = cfg->values.get(name);
if (node.type == WidgetNode::REF) {
return mGlobalCfg.configs.get(node.refGroup).values.get(node.refName).color;
}
return cfg->values.get(name).color;
}
[[nodiscard]] halnf getValue(const std::string& name) const {
const auto& node = cfg->values.get(name);
if (node.type == WidgetNode::REF) {
return mGlobalCfg.configs.get(node.refGroup).values.get(node.refName).value;
}
return cfg->values.get(name).value;
}
void addColor(const std::string& name, const RGBA& val) { cfg->values.put(name, WidgetNode(val)); }
void addValue(const std::string& name, halnf val) { cfg->values.put(name, WidgetNode(val)); }
void addColor(const std::string& name, const std::string& presetName) {
cfg->values.put(name, WidgetNode(presetName));
}
void addValue(const std::string& name, const std::string& presetName) {
cfg->values.put(name, WidgetNode(presetName));
}
bool createConfig(const std::string& name) {
auto idx = mGlobalCfg.configs.presents(name);
if (idx) return false;
mGlobalCfg.configs.put(name, {});
cfg = &mGlobalCfg.configs.get(name);
populateConfig();
return true;
}
virtual void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) { virtual void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) {
mVisible = areaParent.isOverlap(aArea); mVisible = areaParent.isOverlap(aArea);
if (!mVisible) { if (!mVisible) {
@ -66,19 +24,11 @@ namespace tp {
} }
} }
void addOperator(const std::string& name, WidgetConfig::WidgetCallback callback) { virtual void updateConfigCache(const WidgetManager& wm) = 0;
cfg->mOperators.put(name, callback);
}
Buffer<WidgetShortcut>& getShortcuts(const std::string& name) { return cfg->mShortcuts[name]; }
public: public:
static GlobalGUIConfig mGlobalCfg; std::string mId;
WidgetConfig* cfg = nullptr;
RectF mArea; RectF mArea;
bool mVisible = false; bool mVisible = false;
}; };
template <typename Events, typename Canvas>
GlobalGUIConfig<Events, Canvas> Widget<Events, Canvas>::mGlobalCfg;
} }

View file

@ -1,98 +0,0 @@
#pragma once
#include "Animations.hpp"
#include "Map.hpp"
#include "Rect.hpp"
#include "InputCodes.hpp"
#include "Buffer.hpp"
namespace tp {
struct WidgetShortcut {
struct Condition {
std::string name;
std::string state;
};
WidgetShortcut() = default;
WidgetShortcut(const InitialierList<Condition>&) {}
};
template <typename Events, typename Canvas>
struct WidgetConfig {
struct WidgetCallback {
using CallbackType = void (*)(void* self, const Events&);
void* self;
CallbackType callback;
};
struct Node {
enum Type { NONE, VAL, COL, REF };
halnf value = 0.f;
RGBA color = {};
Type type = NONE;
std::string refGroup;
std::string refName;
Node() = default;
explicit Node(halnf val) {
type = VAL;
value = val;
}
explicit Node(const RGBA& val) {
type = COL;
color = val;
}
explicit Node(const std::string& val) {
refGroup = "Presets";
refName = val;
type = REF;
}
};
Map<std::string, Node> values;
Map<std::string, WidgetCallback> mOperators;
Map<std::string, Buffer<WidgetShortcut>> mShortcuts;
};
template <typename Events, typename Canvas>
struct GlobalGUIConfig {
using WidgetConfig = WidgetConfig<Events, Canvas>;
using WidgetNode = WidgetConfig::Node;
GlobalGUIConfig() {
configs.put("Presets", {});
auto& presets = configs.get("Presets");
presets.values.put("FontSize", WidgetNode(15.f));
presets.values.put("FontSizeDim", WidgetNode(12.f));
presets.values.put("Rounding", WidgetNode(5.f));
presets.values.put("Padding", WidgetNode(5.f));
presets.values.put("HandleSize", WidgetNode(5.f));
presets.values.put("Background", WidgetNode(RGBA{ 0.03f, 0.03f, 0.03f, 1.f }));
presets.values.put("Base", WidgetNode(RGBA{ 0.07f, 0.07f, 0.07f, 1.f }));
presets.values.put("Accent", WidgetNode(RGBA{ 0.13f, 0.13f, 0.13f, 1.f }));
presets.values.put("Interaction", WidgetNode(RGBA{ 0.33f, 0.33f, 0.3f, 1.f }));
presets.values.put("Action", WidgetNode(RGBA{ 0.44f, 0.44f, 0.4f, 1.f }));
presets.values.put("Front", WidgetNode(RGBA{ 1.f, 1.f, 1.f, 1.f }));
presets.values.put("FrontDim", WidgetNode(RGBA{ 0.7f, 0.7f, 0.7f, 1.f }));
}
~GlobalGUIConfig() { configs.removeAll(); }
void processShortcuts(const Events& events) {
//
}
Map<std::string, WidgetConfig> configs;
};
}

View file

@ -0,0 +1,131 @@
#pragma once
#include "Animations.hpp"
#include "Map.hpp"
#include "Rect.hpp"
#include "InputCodes.hpp"
#include "Buffer.hpp"
namespace tp {
struct WidgetConfig {
struct WidgetShortcut {
struct Condition {
std::string name;
std::string state;
};
std::string callbackName;
WidgetShortcut() = default;
WidgetShortcut(const InitialierList<Condition>&) {}
};
struct WidgetParameter {
enum Type { NONE, VAL, COL, REF };
halnf value = 0.f;
RGBA color = {};
std::string refName;
std::string refWidgetId;
Type type = NONE;
WidgetParameter() = default;
explicit WidgetParameter(halnf val) {
type = VAL;
value = val;
}
explicit WidgetParameter(const RGBA& val) {
type = COL;
color = val;
}
explicit WidgetParameter(const std::string& widgetId, const std::string& val) {
type = REF;
refName = val;
refWidgetId = widgetId;
}
};
Map<std::string, WidgetParameter> mParameters;
Buffer<WidgetShortcut> mShortcuts;
};
class WidgetManager {
public:
WidgetManager() {
createWidgetConfig("Default");
addNumber("Default", "FontSize", 15.f);
addNumber("Default", "FontSizeDim", 12.f);
addNumber("Default", "Rounding", 5.f);
addNumber("Default", "Padding", 5.f);
addNumber("Default", "HandleSize", 5.f);
addColor("Default", "Background", RGBA{ 0.03f, 0.03f, 0.03f, 1.f });
addColor("Default", "Base", RGBA{ 0.07f, 0.07f, 0.07f, 1.f });
addColor("Default", "Accent", RGBA{ 0.13f, 0.13f, 0.13f, 1.f });
addColor("Default", "Interaction", RGBA{ 0.33f, 0.33f, 0.3f, 1.f });
addColor("Default", "Action", RGBA{ 0.44f, 0.44f, 0.4f, 1.f });
addColor("Default", "Front", RGBA{ 1.f, 1.f, 1.f, 1.f });
addColor("Default", "FrontDim", RGBA{ 0.7f, 0.7f, 0.7f, 1.f });
}
~WidgetManager() { mConfigurations.removeAll(); }
bool createWidgetConfig(const std::string& widgetId) {
auto idx = mConfigurations.presents(widgetId);
if (idx) return false;
mConfigurations.put(widgetId, {});
return true;
}
[[nodiscard]] const RGBA& getColor(const std::string& widgetId, const std::string& name) const {
const WidgetConfig& config = mConfigurations.get(widgetId);
const WidgetConfig::WidgetParameter& parameter = config.mParameters.get(name);
if (parameter.type == WidgetConfig::WidgetParameter::REF) {
return mConfigurations.get(parameter.refWidgetId).mParameters.get(parameter.refName).color;
} else {
return parameter.color;
}
}
[[nodiscard]] halnf getNumber(const std::string& widgetId, const std::string& name) const {
const WidgetConfig& config = mConfigurations.get(widgetId);
const WidgetConfig::WidgetParameter& parameter = config.mParameters.get(name);
if (parameter.type == WidgetConfig::WidgetParameter::REF) {
return mConfigurations.get(parameter.refWidgetId).mParameters.get(parameter.refName).value;
} else {
return parameter.value;
}
}
void addColor(const std::string& widgetId, const std::string& name, const RGBA& val) {
WidgetConfig& config = mConfigurations.get(widgetId);
config.mParameters.put(name, WidgetConfig::WidgetParameter(val));
}
void addNumber(const std::string& widgetId, const std::string& name, halnf val) {
WidgetConfig& config = mConfigurations.get(widgetId);
config.mParameters.put(name, WidgetConfig::WidgetParameter(val));
}
void addReference(const std::string& widgetId, const std::string& refName, const std::string& name) {
WidgetConfig& config = mConfigurations.get(widgetId);
config.mParameters.put(refName, WidgetConfig::WidgetParameter("Default", name));
}
private:
Map<std::string, WidgetConfig> mConfigurations;
RGBA mErrorColor = { 0, 0, 0, 1 };
halnf mErrorNumber = 0;
};
}