Update widgets module. Raster example initial.

This commit is contained in:
IlyaShurupov 2024-04-12 15:27:40 +03:00 committed by Ilya Shurupov
parent aa10424fbb
commit 90244934d9
48 changed files with 1169 additions and 530 deletions

22
3DEditor/CMakeLists.txt Normal file
View file

@ -0,0 +1,22 @@
project(3DEditor)
### ---------------------- Externals --------------------- ###
set(BINDINGS_INCLUDE ../Externals/glfw/include ../Externals)
set(BINDINGS_LIBS glfw Imgui)
### ---------------------- Static Library --------------------- ###
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp")
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE} ./ext/)
target_link_libraries(${PROJECT_NAME} PUBLIC Graphics Connection Widgets Math RasterRender)
target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS})
### -------------------------- Applications -------------------------- ###
add_executable(3DEditorApp ./applications/Entry.cpp ./applications/SceneLoad.cpp)
target_link_libraries(3DEditorApp ${PROJECT_NAME} Lua ImageIO)
file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
file(COPY "rsc/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")

View file

@ -0,0 +1,43 @@
#include "EditorWidget.hpp"
#include "GraphicApplication.hpp"
using namespace tp;
bool loadMeshes(tp::Scene& scene, const std::string& objetsPath);
class EditorGUI : public Application {
public:
EditorGUI() {
Vec2F renderResolution = { 1000, 1000 };
auto canvas = this->mGraphics->getCanvas();
mGui = new EditorWidget<EventHandler, Canvas>(canvas, &geometry, renderResolution);
loadMeshes(geometry, "rsc/scene.obj");
geometry.mCamera.lookAtPoint({ 0, 0, 0 }, { 3, 3, 2 }, { 0, 0, 1 });
}
~EditorGUI() override { delete mGui; }
void processFrame(EventHandler* eventHandler) override {
auto rec = RectF({ 0, 0 }, mWindow->getSize());
mGui->updateConfigCache(mWidgetManager);
mGui->proc(*eventHandler, rec, rec);
}
void drawFrame(Canvas* canvas) override { mGui->draw(*canvas); }
private:
Scene geometry;
WidgetManager mWidgetManager;
EditorWidget<EventHandler, Canvas>* mGui;
};
int main() {
EditorGUI gui;
gui.run();
}

View file

@ -0,0 +1,41 @@
#include "Scene.hpp"
#include "obj/OBJ_Loader.h"
#include <filesystem>
bool loadMeshes(tp::Scene& scene, const std::string& objetsPath) {
using namespace tp;
objl::Loader Loader;
if (!Loader.LoadFile(objetsPath.c_str())) {
std::cout << "Failed to Load File. May have failed to find it or it was not an .obj file.\n";
return false;
}
for (auto& curMesh : Loader.LoadedMeshes) {
scene.mObjects.append(Object());
auto object = &scene.mObjects.last();
for (auto& vertex : curMesh.Vertices) {
// printf("{ %f, %f, %f }, \n", vertex.Position.X, vertex.Position.Y, vertex.Position.Z);
object->mTopology.Points.append(Vec3F{ vertex.Position.X, vertex.Position.Y, vertex.Position.Z });
object->mTopology.Normals.append(Vec3F{ vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z });
}
for (int j = 0; j < curMesh.Indices.size(); j += 3) {
uint idx1 = (int) curMesh.Indices[j];
uint idx2 = (int) curMesh.Indices[j + 1];
uint idx3 = (int) curMesh.Indices[j + 2];
// printf("{ %i, %i, %i },\n", idx1, idx2, idx3);
object->mTopology.Indexes.append({ idx1, idx2, idx3 });
}
if (object->mTopology.Normals.size() != object->mTopology.Points.size()) {
printf("Logic error loading normals\n");
}
}
return scene.mObjects.size();
}

110
3DEditor/private/Render.cpp Normal file
View file

@ -0,0 +1,110 @@
#include "Render.hpp"
#include "GraphicsApi.hpp"
using namespace tp;
class ObjectBuffers {
public:
ObjectBuffers(Object* object) {
mObject = (object);
auto& buff = mObject->mTopology.Points;
auto& indices = mObject->mTopology.Indexes;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3F) * buff.size(), buff.getBuff(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Vec3<uhalni>) * indices.size(), indices.getBuff(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glEnableVertexAttribArray(0);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
Object* mObject = nullptr;
GLuint VAO = 0;
GLuint VBO = 0;
GLuint EBO = 0;
void drawCall() {
auto& indices = mObject->mTopology.Indexes;
glBindVertexArray(VAO);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, indices.size() * 3, GL_UNSIGNED_INT, nullptr);
// glDrawArrays(GL_TRIANGLES, 0, sizeof(buffer) / (2 * sizeof(float)));
// glBindVertexArray(0);
}
~ObjectBuffers() {
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
}
};
Render::Render(Vec2F renderResolution) :
mRenderBuffer(renderResolution) {
mDefaultShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/default.frag", true);
}
Render::~Render() {}
uint4 Render::getRenderBuffer() { return mRenderBuffer.texId(); }
Vec2F Render::getBufferSize() { return mRenderBuffer.getSize(); }
void Render::render(const Scene& geometry, Vec2F size) {
for (auto object : geometry.mObjects) {
if (!object->mBuffers) {
object->mBuffers = std::make_shared<ObjectBuffers>(&object.data());
}
}
mRenderBuffer.mClearCol = { 0.0f, 0.0f, 0.0f, 0.f };
mRenderBuffer.beginDraw();
mRenderBuffer.clear();
mDefaultShader.bind();
Mat4F cameraMat = geometry.mCamera.calculateTransformationMatrix();
glEnable(GL_DEPTH_TEST);
for (auto object : geometry.mObjects) {
static auto origin = (GLint) mDefaultShader.getu("Origin");
static auto basis = (GLint) mDefaultShader.getu("Basis");
static auto camera = (GLint) mDefaultShader.getu("Camera");
Mat4F basisMat;
Vec4F originPoint;
glUniform4fv(origin, 1, &originPoint[0]);
glUniformMatrix4fv(basis, 1, false, &basisMat[0][0]);
glUniformMatrix4fv(camera, 1, true, &cameraMat[0][0]);
object->mBuffers->drawCall();
}
mDefaultShader.unbind();
mRenderBuffer.endDraw();
}

View file

@ -0,0 +1,79 @@
#include "Widgets.hpp"
#include "Render.hpp"
namespace tp {
template <typename Events, typename Canvas>
class ViewportWidget : public Widget<Events, Canvas> {
public:
explicit ViewportWidget(Canvas* canvas, Scene* geometry, Vec2F renderResolution) :
mRender(renderResolution) {
mImage = canvas->createImageFromTextId(mRender.getRenderBuffer(), mRender.getBufferSize());
mGeometry = geometry;
mCanvas = canvas;
}
~ViewportWidget() { mCanvas->deleteImageHandle(mImage); }
void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override {
this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return;
mGeometry->mCamera.rotate(0.01f, 0.0);
}
void draw(Canvas& canvas) override {
if (!this->mVisible) return;
mRender.render(*mGeometry, this->mArea.size);
canvas.drawImage(this->mArea, &mImage, PI);
}
public:
Render mRender;
Scene* mGeometry = nullptr;
Canvas* mCanvas = nullptr;
Canvas::ImageHandle mImage;
};
template <typename Events, typename Canvas>
class EditorWidget : public Widget<Events, Canvas> {
public:
EditorWidget(Canvas* canvas, Scene* geometry, Vec2F renderResolution) :
mViewport(canvas, geometry, renderResolution) {}
void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override {
this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return;
mSplitView.proc(events, aArea, aArea);
mViewport.proc(events, aArea, mSplitView.getFirst());
}
void draw(Canvas& canvas) override {
if (!this->mVisible) return;
canvas.rect(this->mArea, mBaseColor);
mSplitView.draw(canvas);
mViewport.draw(canvas);
}
void updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("3DEditor");
mBaseColor = wm.getColor("Base", "Base");
mViewport.updateConfigCache(wm);
mSplitView.updateConfigCache(wm);
}
public:
ViewportWidget<Events, Canvas> mViewport;
SplitView<Events, Canvas> mSplitView;
RGBA mBaseColor;
};
}

View file

@ -0,0 +1,23 @@
#pragma once
#include "Scene.hpp"
#include "Rect.hpp"
#include "FrameBuffer.hpp"
#include "Shader.hpp"
namespace tp {
class Render {
public:
explicit Render(Vec2F renderResolution);
~Render();
void render(const Scene& geometry, Vec2F size);
uint4 getRenderBuffer();
Vec2F getBufferSize();
private:
RenderBuffer mRenderBuffer;
RenderShader mDefaultShader;
};
}

34
3DEditor/public/Scene.hpp Normal file
View file

@ -0,0 +1,34 @@
#pragma once
#include "Topology.hpp"
#include <memory>
class ObjectBuffers;
namespace tp {
class Object {
public:
Object() = default;
public:
Topology mTopology;
std::shared_ptr<ObjectBuffers> mBuffers;
};
struct PointLight {
Vec3F pos;
halnf fallOut = 1.f;
halnf intensity = 1.f;
};
class Scene {
public:
Scene() = default;
public:
Buffer<Object> mObjects;
Buffer<PointLight> mLights;
Camera mCamera;
};
}

BIN
3DEditor/rsc/Font.ttf Normal file

Binary file not shown.

112
3DEditor/rsc/scene.obj Normal file
View file

@ -0,0 +1,112 @@
# Blender v3.0.1 OBJ File: 'scene.blend'
# www.blender.org
mtllib meshes.mtl
o Cube
v -1.039076 1.039076 1.792917
v -1.039076 1.039076 -1.285234
v 1.039076 1.039076 1.792917
v 1.039076 1.039076 -1.285234
v -1.039076 -1.039076 1.792917
v -1.039076 -1.039076 -1.285234
v 1.039076 -1.039076 1.792917
v 1.039076 -1.039076 -1.285234
vt 0.625000 0.500000
vt 0.625000 0.750000
vt 0.875000 0.750000
vt 0.875000 0.500000
vt 0.375000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.375000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.375000 0.500000
vn 0.0000 0.0000 -1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 1.0000 0.0000 0.0000
usemtl Material
s off
f 1/1/1 3/2/1 7/3/1 5/4/1
f 4/5/2 8/6/2 7/7/2 3/2/2
f 8/8/3 6/9/3 5/10/3 7/11/3
f 6/12/4 8/13/4 4/5/4 2/14/4
f 6/9/5 2/14/5 1/1/5 5/10/5
o Cube.001
v 0.411013 -0.208216 -1.264212
v 0.411013 -0.208216 -0.612621
v -0.208216 -0.411013 -1.264212
v -0.208216 -0.411013 -0.612621
v 0.208216 0.411013 -1.264212
v 0.208216 0.411013 -0.612621
v -0.411013 0.208216 -1.264212
v -0.411013 0.208216 -0.612621
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
vn 0.3112 -0.9503 0.0000
vn -0.9503 -0.3112 0.0000
vn -0.3112 0.9503 0.0000
vn 0.9503 0.3112 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl None
s off
f 9/15/6 10/16/6 12/17/6 11/18/6
f 11/18/7 12/17/7 16/19/7 15/20/7
f 15/20/8 16/19/8 14/21/8 13/22/8
f 13/22/9 14/21/9 10/23/9 9/24/9
f 11/25/10 15/20/10 13/22/10 9/26/10
f 16/19/11 12/27/11 10/28/11 14/21/11
o Cube.002
v -0.351718 -0.467100 -0.602050
v -0.351718 -0.467100 0.049542
v -0.800825 0.004996 -0.602050
v -0.800825 0.004996 0.049542
v 0.120377 -0.017993 -0.602050
v 0.120377 -0.017993 0.049542
v -0.328730 0.454103 -0.602050
v -0.328730 0.454103 0.049542
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
vn -0.7245 -0.6892 0.0000
vn -0.6892 0.7245 0.0000
vn 0.7245 0.6892 0.0000
vn 0.6892 -0.7245 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl None
s off
f 17/29/12 18/30/12 20/31/12 19/32/12
f 19/32/13 20/31/13 24/33/13 23/34/13
f 23/34/14 24/33/14 22/35/14 21/36/14
f 21/36/15 22/35/15 18/37/15 17/38/15
f 19/39/16 23/34/16 21/36/16 17/40/16
f 24/33/17 20/41/17 18/42/17 22/35/17

View file

@ -0,0 +1,7 @@
#version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(gl_FragCoord.z, gl_FragCoord.z, gl_FragCoord.z, 1.f);
}

View file

@ -0,0 +1,11 @@
#version 330 core
layout(location = 0) in vec3 Point;
uniform vec4 Origin;
uniform mat4 Basis;
uniform mat4 Camera;
void main() {
gl_Position = Camera * vec4(Point.xyz, 1.0);
}

View file

@ -22,4 +22,6 @@ add_subdirectory(DataAnalysis)
add_subdirectory(Objects) add_subdirectory(Objects)
add_subdirectory(Widgets) add_subdirectory(Widgets)
add_subdirectory(LibraryViewer) add_subdirectory(LibraryViewer)
add_subdirectory(RasterRender)
add_subdirectory(Sketch3D) add_subdirectory(Sketch3D)
add_subdirectory(3DEditor)

View file

@ -11,7 +11,12 @@ namespace tp {
return hash(key); return hash(key);
} }
template <typename tKey, typename tVal, class tAllocator = DefaultAllocator, ualni (*tHashFunc)(SelectValueOrReference<tKey>) = DefaultHashFunc<tKey>, int tTableInitialSize = 4> template <
typename tKey,
typename tVal,
class tAllocator = DefaultAllocator,
ualni (*tHashFunc)(SelectValueOrReference<tKey>) = DefaultHashFunc<tKey>,
int tTableInitialSize = 4>
class Map { class Map {
enum { enum {
@ -223,6 +228,13 @@ namespace tp {
return mTable[slot]->val; return mTable[slot]->val;
} }
tVal& operator[](KeyArg key) {
auto idx = presents(key);
if (idx.isValid()) return getSlotVal(idx);
put(key, {});
return get(key);
}
tVal& getSlotVal(ualni slot) { tVal& getSlotVal(ualni slot) {
DEBUG_ASSERT(slot < mNSlots && (mTable[slot] && !isDeletedNode(mTable[slot])) && "Key Error") DEBUG_ASSERT(slot < mNSlots && (mTable[slot] && !isDeletedNode(mTable[slot])) && "Key Error")
return mTable[slot]->val; return mTable[slot]->val;

View file

@ -1,8 +1,6 @@
#include "EventHandler.hpp" #include "EventHandler.hpp"
#include <stdio.h>
using namespace tp; using namespace tp;
EventHandler::EventHandler() = default; EventHandler::EventHandler() = default;
@ -35,7 +33,6 @@ bool transitionsReduce[4][4] = {
{ true, false, true, true }, { true, false, true, true },
}; };
void EventHandler::processEvent() { void EventHandler::processEvent() {
mMutex.lock(); mMutex.lock();
auto lastEvent = mEventQueue.last(); auto lastEvent = mEventQueue.last();
@ -86,9 +83,7 @@ bool EventHandler::isReleased(InputID id) const {
return mInputStates[(int) id].mCurrentState == InputState::State::RELEASED; return mInputStates[(int) id].mCurrentState == InputState::State::RELEASED;
} }
halnf EventHandler::getPointerPressure() const { halnf EventHandler::getPointerPressure() const { return mPointerPressure; }
return mPointerPressure;
}
bool EventHandler::isDown(InputID id) const { bool EventHandler::isDown(InputID id) const {
return mInputStates[(int) id].mCurrentState == InputState::State::PRESSED || return mInputStates[(int) id].mCurrentState == InputState::State::PRESSED ||

View file

@ -62,7 +62,7 @@ namespace tp {
ImageHandle createImageFromTextId(ualni id, Vec2F size); ImageHandle createImageFromTextId(ualni id, Vec2F size);
void deleteImageHandle(ImageHandle image); void deleteImageHandle(ImageHandle image);
void drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding); void drawImage(const RectF& rec, ImageHandle* image, halnf angle = 0, halnf alpha = 1.f, halnf rounding = 0.f);
private: private:
Buffer<RectF> mScissors; Buffer<RectF> mScissors;
@ -71,7 +71,9 @@ namespace tp {
class Graphics { class Graphics {
public: public:
explicit Graphics(Window* window) : mGui(window), mCanvas(window) {} explicit Graphics(Window* window) :
mGui(window),
mCanvas(window) {}
void procBegin() { void procBegin() {
mCanvas.procBegin(); mCanvas.procBegin();
@ -93,9 +95,7 @@ namespace tp {
mGui.drawEnd(); mGui.drawEnd();
} }
Canvas* getCanvas() { Canvas* getCanvas() { return &mCanvas; }
return &mCanvas;
}
private: private:
Canvas mCanvas; Canvas mCanvas;

View file

@ -18,7 +18,8 @@ using namespace tp;
class LibraryViewer : public Application { class LibraryViewer : public Application {
public: public:
LibraryViewer() : gui(&library, &player) { LibraryViewer() :
gui(&library, &player) {
library.loadJson(getHome() + "Library.json"); library.loadJson(getHome() + "Library.json");
library.checkExisting(); library.checkExisting();
@ -27,22 +28,22 @@ public:
void processFrame(EventHandler* eventHandler) override { void processFrame(EventHandler* eventHandler) override {
auto rec = RectF{ { 0, 0 }, mWindow->getSize() }; auto rec = RectF{ { 0, 0 }, mWindow->getSize() };
gui.updateConfigCache(mWidgetManager);
gui.proc(*eventHandler, rec, rec); gui.proc(*eventHandler, rec, rec);
} }
void drawFrame(Canvas* canvas) override { void drawFrame(Canvas* canvas) override { gui.draw(*canvas); }
gui.draw(*canvas);
}
private: private:
Player player; Player player;
Library library; Library library;
tp::WidgetManager mWidgetManager;
LibraryWidget<EventHandler, Canvas> gui; LibraryWidget<EventHandler, Canvas> gui;
}; };
int main() { int main() {
tp::GlobalGUIConfig config;
tp::gGlobalGUIConfig = &config;
LibraryViewer lib; LibraryViewer lib;
lib.run(); lib.run();

View file

@ -18,15 +18,10 @@ namespace tp {
col.mColor.setNoTransition({ 0.15f, 0.15f, 0.15f, 0.f }); col.mColor.setNoTransition({ 0.15f, 0.15f, 0.15f, 0.f });
}; };
void proc(const Events& events, const RectF& areaParent, const RectF& area) override { void procBody(const Events& events) override {
mSelected = false; mSelected = false;
this->mArea = area;
this->mVisible = area.isOverlap(areaParent);
if (!this->mVisible) return;
if (!mTrack) return; if (!mTrack) return;
if (!areaParent.isOverlap(area)) return; if (this->mArea.isInside(events.getPointer())) {
if (area.isInside(events.getPointer())) {
col.set({ 0.15f, 0.15f, 0.15f, 1.f }); col.set({ 0.15f, 0.15f, 0.15f, 1.f });
mSelected = events.isReleased(InputID::MOUSE1); mSelected = events.isReleased(InputID::MOUSE1);
} else { } else {
@ -34,8 +29,7 @@ namespace tp {
} }
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return;
if (!mTrack) return; if (!mTrack) return;
canvas.rect(this->mArea, col.get(), 4.f); canvas.rect(this->mArea, col.get(), 4.f);
@ -82,16 +76,7 @@ namespace tp {
items.append({ "Date Last Played" }); items.append({ "Date Last Played" });
} }
void proc(const Events&, const RectF& areaParent, const RectF& area) override { void drawBody(Canvas&) override {
this->mArea = area;
this->mVisible = area.isOverlap(areaParent);
if (!this->mVisible) return;
if (!mTrack) return;
// renderUI();
}
void draw(Canvas&) override {
if (!this->mVisible) return;
if (!mTrack) return; if (!mTrack) return;
// canvas.rect(this->mArea, { 0.13f, 0.13f, 0.13f, 1.f }, 4.f); // canvas.rect(this->mArea, { 0.13f, 0.13f, 0.13f, 1.f }, 4.f);
renderUI(); renderUI();
@ -220,11 +205,7 @@ namespace tp {
} }
} }
void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { void procBody(const Events& events) override {
this->mArea = aArea;
this->mVisible = this->mArea.isOverlap(areaParent);
if (!this->mVisible) return;
filter(); filter();
mSplitView.proc(events, this->mArea, this->mArea); mSplitView.proc(events, this->mArea, this->mArea);
@ -242,9 +223,7 @@ namespace tp {
// mCurrentTrack.proc(events, this->mArea, mSplitView.getFirst()); // mCurrentTrack.proc(events, this->mArea, mSplitView.getFirst());
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return;
canvas.rect(this->mArea, { 0.1f, 0.1f, 0.1f, 1.f }); canvas.rect(this->mArea, { 0.1f, 0.1f, 0.1f, 1.f });
mSplitView.draw(canvas); mSplitView.draw(canvas);
@ -283,6 +262,14 @@ namespace tp {
mCurrentTrackInfo.isSongFilterChanged = false; mCurrentTrackInfo.isSongFilterChanged = false;
} }
void updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("LibraryWidget");
mSplitView.updateConfigCache(wm);
mCurrentTrack.updateConfigCache(wm);
mCurrentTrackInfo.updateConfigCache(wm);
mSongList.updateConfigCache(wm);
}
private: private:
Library* mLibrary = nullptr; Library* mLibrary = nullptr;
Player* mPlayer = nullptr; Player* mPlayer = nullptr;

View file

@ -34,7 +34,7 @@ namespace tp {
Buffer<Vec3F> Points; Buffer<Vec3F> Points;
Buffer<Vec3F> Normals; Buffer<Vec3F> Normals;
Buffer<Vec3I> Indexes; Buffer<Vec3<uhalni>> Indexes;
}; };
struct TopologyCache { struct TopologyCache {

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

@ -0,0 +1,15 @@
project(RasterRender)
### ---------------------- Externals --------------------- ###
set(BINDINGS_INCLUDE ${GLEW_INCLUDE_DIR})
set(BINDINGS_LIBS ${GLEW_LIB})
### ---------------------- Static Library --------------------- ###
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp")
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE} ./ext/)
target_link_libraries(${PROJECT_NAME} PUBLIC Math Connection)
target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS})

View file

@ -5,7 +5,12 @@
#include <stdio.h> #include <stdio.h>
void glerr(GLenum type) { printf("GL ERROR\n"); } void glerr(GLenum type) { printf("GL ERROR\n"); }
#define AssertGL(x) { x; GLenum __gle = glGetError(); if (__gle != GL_NO_ERROR) glerr(__gle); } #define AssertGL(x) \
{ \
x; \
GLenum __gle = glGetError(); \
if (__gle != GL_NO_ERROR) glerr(__gle); \
}
using namespace tp; using namespace tp;
@ -18,7 +23,8 @@ RenderBuffer::RenderBuffer(const Vec2F& size) :
AssertGL(glGenTextures(1, &mTextureId)); AssertGL(glGenTextures(1, &mTextureId));
AssertGL(glBindTexture(GL_TEXTURE_2D, mTextureId)); AssertGL(glBindTexture(GL_TEXTURE_2D, mTextureId));
// Give an empty image to OpenGL ( the last "0" ) // Give an empty image to OpenGL ( the last "0" )
AssertGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)size.x, (GLsizei)size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); AssertGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei) size.x, (GLsizei) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)
);
// Poor filtering. Needed // Poor filtering. Needed
AssertGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); AssertGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
AssertGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); AssertGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
@ -49,9 +55,13 @@ RenderBuffer::RenderBuffer(const Vec2F& size, tp::uint1 samples) :
AssertGL(glGenTextures(1, &mTextureId)); AssertGL(glGenTextures(1, &mTextureId));
AssertGL(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextureId)); AssertGL(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextureId));
#ifdef ENV_OS_ANDROID #ifdef ENV_OS_ANDROID
AssertGL(glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei)size.x, (GLsizei)size.y, GL_TRUE)); AssertGL(
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei) size.x, (GLsizei) size.y, GL_TRUE)
);
#else #else
AssertGL(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei)size.x, (GLsizei)size.y, GL_TRUE)); AssertGL(
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei) size.x, (GLsizei) size.y, GL_TRUE)
);
#endif #endif
// !? // !?
// AssertGL(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); // AssertGL(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
@ -60,7 +70,9 @@ RenderBuffer::RenderBuffer(const Vec2F& size, tp::uint1 samples) :
// ------- depth ------- // ------- depth -------
AssertGL(glGenRenderbuffers(1, &mDepthBufferID)); AssertGL(glGenRenderbuffers(1, &mDepthBufferID));
AssertGL(glBindRenderbuffer(GL_RENDERBUFFER, mDepthBufferID)); AssertGL(glBindRenderbuffer(GL_RENDERBUFFER, mDepthBufferID));
AssertGL(glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GLW_CONTEXT_DEPTH_COMPONENT, (GLsizei)size.x, (GLsizei)size.y)); AssertGL(glRenderbufferStorageMultisample(
GL_RENDERBUFFER, samples, GLW_CONTEXT_DEPTH_COMPONENT, (GLsizei) size.x, (GLsizei) size.y
));
// ------- fbuff ------- // ------- fbuff -------
AssertGL(glGenFramebuffers(1, &mFrameBufferID)); AssertGL(glGenFramebuffers(1, &mFrameBufferID));
@ -72,9 +84,7 @@ RenderBuffer::RenderBuffer(const Vec2F& size, tp::uint1 samples) :
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
uint4 RenderBuffer::buffId() const { uint4 RenderBuffer::buffId() const { return mFrameBufferID; }
return mFrameBufferID;
}
void RenderBuffer::beginDraw() { void RenderBuffer::beginDraw() {
AssertGL(glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID)); AssertGL(glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID));
@ -102,9 +112,6 @@ RenderBuffer::~RenderBuffer() {
glDeleteRenderbuffers(1, &mDepthBufferID); glDeleteRenderbuffers(1, &mDepthBufferID);
} }
uint4 RenderBuffer::texId() const { uint4 RenderBuffer::texId() const { return mTextureId; }
return mTextureId;
}
const Vec2F& RenderBuffer::getSize() const { return mSize; } const Vec2F& RenderBuffer::getSize() const { return mSize; }

View file

@ -18,9 +18,10 @@ namespace tp {
uint4 getu(const char* uid); uint4 getu(const char* uid);
void unbind(); void unbind();
void load(const char* vert, const char* geom, const char* frag, bool paths);
private: private:
bool compile_shader(const char* ShaderCode, uint4 ShaderID); bool compile_shader(const char* ShaderCode, uint4 ShaderID);
void load(const char* vert, const char* geom, const char* frag, bool paths);
private: private:
uint4 programm; uint4 programm;

View file

@ -4,7 +4,7 @@ project(RayTracer)
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp") file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp" "./applications/*.hpp") file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp" "./applications/*.hpp")
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC ./public/) target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ../Externals/)
target_link_libraries(${PROJECT_NAME} PUBLIC Math Connection) target_link_libraries(${PROJECT_NAME} PUBLIC Math Connection)
### -------------------------- Applications -------------------------- ### ### -------------------------- Applications -------------------------- ###

View file

@ -6,7 +6,7 @@ extern "C" {
#include "lualib.h" #include "lualib.h"
} }
#include "OBJ_Loader.h" #include "obj/OBJ_Loader.h"
#include <filesystem> #include <filesystem>
@ -32,11 +32,11 @@ bool loadMeshes(tp::Scene& scene, const std::string& objetsPath) {
} }
for (int j = 0; j < curMesh.Indices.size(); j += 3) { for (int j = 0; j < curMesh.Indices.size(); j += 3) {
int idx1 = (int) curMesh.Indices[j]; auto idx1 = (uhalni) curMesh.Indices[j];
int idx2 = (int) curMesh.Indices[j + 1]; auto idx2 = (uhalni) curMesh.Indices[j + 1];
int idx3 = (int) curMesh.Indices[j + 2]; auto idx3 = (uhalni) curMesh.Indices[j + 2];
// printf("{ %i, %i, %i },\n", idx1, idx2, idx3); // printf("{ %i, %i, %i },\n", idx1, idx2, idx3);
object->mTopology.Indexes.append(Vec3I{ idx1, idx2, idx3 }); object->mTopology.Indexes.append(Vec3<uhalni>{ idx1, idx2, idx3 });
} }
if (object->mTopology.Normals.size() != object->mTopology.Points.size()) { if (object->mTopology.Normals.size() != object->mTopology.Points.size()) {
@ -139,7 +139,6 @@ void loadScene(tp::Scene& scene, const std::string& scenePath, tp::RayTracer::Re
// Remove the filename from the path // Remove the filename from the path
fs::path directoryPath = fullPath.remove_filename(); fs::path directoryPath = fullPath.remove_filename();
if (luaL_dofile(L, scenePath.c_str()) != 0) { if (luaL_dofile(L, scenePath.c_str()) != 0) {
lua_close(L); lua_close(L);
printf("Cant open scene script.\n"); printf("Cant open scene script.\n");

View file

@ -1,8 +1,8 @@
project(Sketch3D) project(Sketch3D)
### ---------------------- Externals --------------------- ### ### ---------------------- Externals --------------------- ###
set(BINDINGS_INCLUDE ../Externals/glfw/include ${GLEW_INCLUDE_DIR}) set(BINDINGS_INCLUDE ../Externals/glfw/include)
set(BINDINGS_LIBS glfw Imgui ${GLEW_LIB}) set(BINDINGS_LIBS glfw Imgui)
### ---------------------- Static Library --------------------- ### ### ---------------------- Static Library --------------------- ###
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp") file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
@ -11,7 +11,7 @@ file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp")
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE} ./ext/) target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE} ./ext/)
target_link_libraries(${PROJECT_NAME} PUBLIC Graphics Connection Widgets Math) target_link_libraries(${PROJECT_NAME} PUBLIC Graphics Connection Widgets Math RasterRender)
target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS}) target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS})
### -------------------------- Applications -------------------------- ### ### -------------------------- Applications -------------------------- ###

View file

@ -8,30 +8,25 @@ using namespace tp;
class Sketch3DApplication : public Application { class Sketch3DApplication : public Application {
public: public:
Sketch3DApplication() : mGui(*mGraphics->getCanvas(), {1920, 1080}) {} Sketch3DApplication() :
mGui(*mGraphics->getCanvas(), { 1920, 1080 }) {}
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 { void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); }
mGui.draw(*canvas);
}
private: private:
WidgetManager mWidgetManager;
Sketch3DGUI<EventHandler, Canvas> mGui; Sketch3DGUI<EventHandler, Canvas> mGui;
}; };
void runApp() { void runApp() {
tp::GlobalGUIConfig config;
tp::gGlobalGUIConfig = &config;
Sketch3DApplication app; Sketch3DApplication app;
app.run(); app.run();
} }
int main() { int main() { runApp(); }
runApp();
}

View file

@ -16,9 +16,7 @@ namespace tp {
mProject.mBackgroundColor = { 0.13f, 0.13f, 0.13f, 1.f }; mProject.mBackgroundColor = { 0.13f, 0.13f, 0.13f, 1.f };
} }
~Sketch3DWidget() { ~Sketch3DWidget() { mCanvas->deleteImageHandle(mImage); }
mCanvas->deleteImageHandle(mImage);
}
void proc(const Events& events, const RectF& areaParent, const RectF& area) override { void proc(const Events& events, const RectF& areaParent, const RectF& area) override {
@ -51,20 +49,24 @@ namespace tp {
mProject.mCamera.setRatio(this->mArea.w / this->mArea.z); mProject.mCamera.setRatio(this->mArea.w / this->mArea.z);
switch (mMode) { switch (mMode) {
case Mode::MOVE: { case Mode::MOVE:
{
if (mAction) mProject.mCamera.move(relativePos, relativePosPrev); if (mAction) mProject.mCamera.move(relativePos, relativePosPrev);
break; break;
} }
case Mode::ZOOM: { case Mode::ZOOM:
{
halnf factor = absolutePos.y / mActionPosAbsolutePrev.y; halnf factor = absolutePos.y / mActionPosAbsolutePrev.y;
if (mAction) mProject.mCamera.zoom(factor); if (mAction) mProject.mCamera.zoom(factor);
break; break;
} }
case Mode::ROTATE: { case Mode::ROTATE:
{
if (mAction) mProject.mCamera.rotate(-relativeDelta.x * halnf(PI), -relativeDelta.y * halnf(PI)); if (mAction) mProject.mCamera.rotate(-relativeDelta.x * halnf(PI), -relativeDelta.y * halnf(PI));
break; break;
} }
case Mode::DRAW: { case Mode::DRAW:
{
mProject.sample(events.getPointerPressure(), this->mArea.w / this->mArea.z, crs); mProject.sample(events.getPointerPressure(), this->mArea.w / this->mArea.z, crs);
break; break;
} }
@ -74,20 +76,15 @@ namespace tp {
mActionPosAbsolutePrev = absolutePos; mActionPosAbsolutePrev = absolutePos;
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return;
mRenderer.renderToTexture(&mProject, this->mArea.size); mRenderer.renderToTexture(&mProject, this->mArea.size);
canvas.drawImage(this->mArea, &mImage, 0, 1, 12); canvas.drawImage(this->mArea, &mImage, 0, 1, 12);
} }
void setColor(const RGBA& color) { void setColor(const RGBA& color) { ((PencilBrush*) mProject.mBrushes.get("pencil"))->mCol = color; }
((PencilBrush*) mProject.mBrushes.get("pencil"))->mCol = color;
}
public: public:
enum class Mode { enum class Mode { MOVE, ROTATE, ZOOM, DRAW, NONE } mMode = Mode::NONE;
MOVE, ROTATE, ZOOM, DRAW, NONE
} mMode = Mode::NONE;
Vec2F mActionPosAbsolutePrev = { 0, 0 }; Vec2F mActionPosAbsolutePrev = { 0, 0 };
bool mAction = false; bool mAction = false;
@ -102,12 +99,8 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class Sketch3DGUI : public Widget<Events, Canvas> { class Sketch3DGUI : public Widget<Events, Canvas> {
public: public:
Sketch3DGUI(Canvas& canvas, Vec2F renderResolution) : mViewport(canvas, renderResolution) { Sketch3DGUI(Canvas& canvas, Vec2F renderResolution) :
this->createConfig("Sketch3D"); mViewport(canvas, renderResolution) {
this->addColor("Background", "Background");
this->addValue("Rounding", "Rounding");
mDrawButton = new ButtonWidget<Events, Canvas>("Draw", { 0, 0, 100, 30 }); mDrawButton = new ButtonWidget<Events, Canvas>("Draw", { 0, 0, 100, 30 });
mMoveButton = new ButtonWidget<Events, Canvas>("Pan View", { 0, 0, 100, 30 }); mMoveButton = new ButtonWidget<Events, Canvas>("Pan View", { 0, 0, 100, 30 });
mRotateButton = new ButtonWidget<Events, Canvas>("Rotate view", { 0, 0, 100, 30 }); mRotateButton = new ButtonWidget<Events, Canvas>("Rotate view", { 0, 0, 100, 30 });
@ -134,11 +127,7 @@ namespace tp {
} }
} }
void proc(const Events& events, const RectF& areaParent, const RectF& area) override { void procBody(const Events& events) override {
this->mArea = area;
this->mVisible = area.isOverlap(areaParent);
if (!this->mVisible) return;
mSplitView.proc(events, this->mArea, this->mArea); mSplitView.proc(events, this->mArea, this->mArea);
mViewport.proc(events, this->mArea, mSplitView.getFirst()); mViewport.proc(events, this->mArea, mSplitView.getFirst());
mOptions.proc(events, this->mArea, mSplitView.getSecond()); mOptions.proc(events, this->mArea, mSplitView.getSecond());
@ -156,16 +145,25 @@ namespace tp {
mViewport.setColor(RGBA(mRed->mSlider.mFactor, mGreen->mSlider.mFactor, mBlue->mSlider.mFactor, 1.f)); mViewport.setColor(RGBA(mRed->mSlider.mFactor, mGreen->mSlider.mFactor, mBlue->mSlider.mFactor, 1.f));
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return; canvas.rect(this->mArea, mBackgroundColor, mRounding);
canvas.rect(this->mArea, this->getColor("Background"), this->getValue("Rounding"));
mSplitView.draw(canvas); mSplitView.draw(canvas);
mViewport.draw(canvas); mViewport.draw(canvas);
mOptions.draw(canvas); mOptions.draw(canvas);
} }
void updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("Sketch3DGui");
mBackgroundColor = wm.getColor("Background", "Background");
mRounding = wm.getNumber("Rounding", "Rounding");
mSplitView.updateConfigCache(wm);
mOptions.updateConfigCache(wm);
mViewport.updateConfigCache(wm);
}
private: private:
Sketch3DWidget<Events, Canvas> mViewport; Sketch3DWidget<Events, Canvas> mViewport;
SplitView<Events, Canvas> mSplitView; SplitView<Events, Canvas> mSplitView;
@ -179,5 +177,8 @@ namespace tp {
NamedSliderWidget<Events, Canvas>* mRed = nullptr; NamedSliderWidget<Events, Canvas>* mRed = nullptr;
NamedSliderWidget<Events, Canvas>* mGreen = nullptr; NamedSliderWidget<Events, Canvas>* mGreen = nullptr;
NamedSliderWidget<Events, Canvas>* mBlue = nullptr; NamedSliderWidget<Events, Canvas>* mBlue = nullptr;
RGBA mBackgroundColor;
halnf mRounding = 0;
}; };
} }

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"
@ -11,21 +11,20 @@ public:
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 { void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); }
mGui.draw(*canvas);
}
private: private:
WidgetManager mWidgetManager;
ComplexWidget<EventHandler, Canvas> mGui; ComplexWidget<EventHandler, Canvas> mGui;
}; };
int main() { int main() {
GlobalGUIConfig mConfig;
gGlobalGUIConfig = &mConfig;
{ {
ExampleGUI gui; ExampleGUI gui;
gui.run(); gui.run();

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() = default;
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,40 @@ 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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("UserWidget");
mBaseColor = wm.getColor("Base", "Base");
mFontSize = wm.getNumber("Size", "FontSize");
mPadding = wm.getNumber("Padding", "Padding");
mUserColor = wm.getColor("ColUser", "Front");
mAccentColor = wm.getColor("Accent", "Accent");
mRounding = wm.getNumber("Rounding", "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() = default;
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 +65,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 +74,40 @@ 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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("MessageWidget");
mBaseColor = wm.getColor("Base", "Base");
mFontSize = wm.getNumber("Size", "FontSize");
mFontSizeDim = wm.getNumber("SizeUser", "FontSizeDim");
mPadding = wm.getNumber("Padding", "Padding");
mUserColor = wm.getColor("UserColor", "Front");
mUserColorDim = wm.getColor("UserColorDim", "FrontDim");
mRounding = wm.getNumber("Rounding", "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->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 +129,36 @@ 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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("LoginWidget");
mBGColor = wm.getColor("Back", "Base");
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->addColor("Back", "Background");
this->addValue("Padding", "Padding");
mSend.mLabel.mLabel = "Send"; mSend.mLabel.mLabel = "Send";
mMessage.mId = "Message"; mMessage.mId = "Message";
} }
@ -152,16 +171,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,27 +193,41 @@ 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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("ActiveChat");
mBGColor = wm.getColor("Back", "Background");
mPadding = wm.getNumber("Padding", "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->addColor("Back", "Background");
this->addValue("Padding", "Padding");
// todo : fetch code // todo : fetch code
mUsers.append(UserWidget<Events, Canvas>()); mUsers.append(UserWidget<Events, Canvas>());
mUsers.append(UserWidget<Events, Canvas>()); mUsers.append(UserWidget<Events, Canvas>());
@ -225,34 +258,44 @@ 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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("ChattingWidget");
mBGColor = wm.getColor("Back", "Background");
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() = default;
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 +311,25 @@ 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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("ChatGui");
mBGColor = wm.getColor("Back", "Background");
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,44 @@
#include "ChatGUI.hpp"
#include "GraphicApplication.hpp"
using namespace tp;
class SimpleGUI : public Application {
public:
SimpleGUI() {
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

@ -3,6 +3,4 @@
#include "Graphics.hpp" #include "Graphics.hpp"
namespace tp { namespace tp {}
GlobalGUIConfig* gGlobalGUIConfig = nullptr;
}

View file

@ -7,40 +7,15 @@ namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class ButtonWidget : public Widget<Events, Canvas> { class ButtonWidget : public Widget<Events, Canvas> {
public: public:
ButtonWidget() { ButtonWidget() { this->mArea = { 0, 0, 100, 100 }; }
this->mArea = { 0, 0, 100, 100 };
this->createConfig("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->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 procBody(const Events& events) {
this->mArea = aArea; mIsHover = this->mArea.isInside(events.getPointer());
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return;
mIsHover = false;
if (!areaParent.isOverlap(aArea)) {
mIsReleased = false;
mIsPressed = false;
return;
}
mIsHover = aArea.isInside(events.getPointer());
if (events.isPressed(InputID::MOUSE1) && mIsHover) { if (events.isPressed(InputID::MOUSE1) && mIsHover) {
mIsPressed = true; mIsPressed = true;
@ -53,26 +28,46 @@ namespace tp {
if (!mIsHover) mIsPressed = false; if (!mIsHover) mIsPressed = false;
mLabel.proc(events, aArea, aArea); mLabel.proc(events, this->mArea, this->mArea);
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("Button");
pressedColor = wm.getColor("Pressed", "Action");
hoveredColor = wm.getColor("Hovered", "Interaction");
accentColor = wm.getColor("Default", "Accent");
rounding = wm.getNumber("Rounding", "Rounding");
// mPressEvent = wm.getEventState("Activate", { { InputID::MOUSE1, InputState::PRESSED } });
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;
InputState mPressEvent;
}; };
} }

View file

@ -6,33 +6,26 @@ 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() = default;
this->createConfig("Label");
this->addValue("Size", "FontSize"); void drawBody(Canvas& canvas) override {
this->addValue("Padding", "Padding"); canvas.text(mLabel.c_str(), this->mArea, fontSize, Canvas::CC, padding, fontColor);
this->addColor("Default", "Front");
} }
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { public:
this->mArea = aArea; void updateConfigCache(WidgetManager& wm) override {
this->mVisible = areaParent.isOverlap(aArea); wm.setActiveId("Label");
if (!this->mVisible) return;
}
void draw(Canvas& canvas) override { fontSize = wm.getNumber("Size", "FontSize");
if (!this->mVisible) return; padding = wm.getNumber("Padding", "Padding");
fontColor = wm.getColor("Default", "Front");
canvas.text(
mLabel.c_str(),
this->mArea,
this->getValue("Size"),
Canvas::CC,
this->getValue("Padding"),
this->getColor("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() = default;
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,28 @@ 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 updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("Scrollbar");
mDefaultColor = wm.getColor("Default", "Base");
mHandleColor = wm.getColor("Handle", "Accent");
mHoveredColor = wm.getColor("Hovered", "Interaction");
mScrollingColor = wm.getColor("Scrolling", "Action");
mPadding = wm.getNumber("Padding", "Padding");
mHandleSize = wm.getNumber("HandleSize", 20.f);
mMinSize = wm.getNumber("MinSize", 20.f);
mRounding = wm.getNumber("Rounding", "Rounding");
} }
public: public:
@ -126,29 +124,29 @@ 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() = default;
this->createConfig("ScrollableWindow");
this->addColor("Default", "Base");
this->addValue("Padding", "Padding");
}
~ScrollableWindow() = default; ~ScrollableWindow() = default;
// takes whole area // takes whole area
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void procBody(const Events& events) override {
this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return;
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);
@ -168,9 +166,7 @@ namespace tp {
} }
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return;
mScroller.draw(canvas); mScroller.draw(canvas);
canvas.pushClamp(this->mArea); canvas.pushClamp(this->mArea);
@ -180,16 +176,29 @@ namespace tp {
canvas.popClamp(); canvas.popClamp();
} }
public:
void updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("ScrollableWidget");
mDefaultColor = wm.getColor("Default", "Base");
mPadding = wm.getNumber("Padding", "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 +210,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 +226,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,23 +7,9 @@ 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() = default;
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 {
this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return;
void procBody(const Events& events) override {
if (events.isPressed(InputID::MOUSE1) && this->mArea.isInside(events.getPointer())) { if (events.isPressed(InputID::MOUSE1) && this->mArea.isInside(events.getPointer())) {
mIsSliding = true; mIsSliding = true;
} else if (events.isReleased(InputID::MOUSE1)) { } else if (events.isReleased(InputID::MOUSE1)) {
@ -31,44 +17,50 @@ 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);
} }
mFactor = tp::clamp(mFactor, 0.f, 1.f); mFactor = tp::clamp(mFactor, 0.f, 1.f);
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return; canvas.rect(this->mArea, defaultColor, rounding);
canvas.rect(this->mArea, this->getColor("Default"), this->getValue("Rounding")); canvas.rect(getHandle(), handleColor, rounding);
canvas.rect(getHandle(), this->getColor("Handle"), this->getValue("Rounding"));
} }
RectF getHandle() const { RectF getHandle() const {
const auto handle = this->getValue("HandleSize"); const auto left = this->mArea.x + (this->mArea.z - handleSize) * mFactor;
const auto halfHandle = handle / 2.f; return { left, this->mArea.y, handleSize, this->mArea.w };
const auto left = this->mArea.x + (this->mArea.z - handle) * mFactor; }
return { left, this->mArea.y, handle, this->mArea.w };
public:
void updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("Slider");
defaultColor = wm.getColor("Default", "Base");
handleColor = wm.getColor("Handle", "Accent");
handleSize = wm.getNumber("HandleSize", 20.f);
rounding = wm.getNumber("Rounding", "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") {
mLabel.mLabel = name; mLabel.mLabel = name;
this->mArea = { 0, 0, 100, 30 }; this->mArea = { 0, 0, 100, 30 };
} }
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { void procBody(const Events& events) override {
this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return;
const auto widthFirst = this->mArea.z * mFactor; const auto widthFirst = this->mArea.z * mFactor;
const auto widthSecond = this->mArea.z * (1.f - mFactor); const auto widthSecond = this->mArea.z * (1.f - mFactor);
@ -83,12 +75,17 @@ namespace tp {
mSlider.proc(events, this->mArea, rec); mSlider.proc(events, this->mArea, rec);
} }
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return;
mSlider.draw(canvas); mSlider.draw(canvas);
mLabel.draw(canvas); mLabel.draw(canvas);
} }
virtual void updateConfigCache(WidgetManager& wm) {
wm.setActiveId("NamedSlider");
mSlider.updateConfigCache(wm);
mLabel.updateConfigCache(wm);
}
public: public:
SliderWidget<Events, Canvas> mSlider; SliderWidget<Events, Canvas> mSlider;
LabelWidget<Events, Canvas> mLabel; LabelWidget<Events, Canvas> mLabel;

View file

@ -6,24 +6,9 @@ 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() = default;
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 {
this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) {
mResizeInProcess = false;
return;
}
void procBody(const Events& events) override {
mIsHover = getHandle().isInside(events.getPointer()); mIsHover = getHandle().isInside(events.getPointer());
if (events.isPressed(InputID::MOUSE1) && mIsHover) { if (events.isPressed(InputID::MOUSE1) && mIsHover) {
@ -38,45 +23,55 @@ 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;
} }
} }
// takes whole area // takes whole area
void draw(Canvas& canvas) override { void drawBody(Canvas& canvas) override {
if (!this->mVisible) return; if (mResizeInProcess) canvas.rect(getHandle(), mResizingColor);
else if (mIsHover) canvas.rect(getHandle(), mHoveredColor);
if (mResizeInProcess) canvas.rect(getHandle(), this->getColor("Resizing")); else canvas.rect(getHandle(), mHandleColor);
else if (mIsHover) canvas.rect(getHandle(), this->getColor("Hovered"));
else canvas.rect(getHandle(), this->getColor("Handle"));
} }
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 }; public:
void updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("SplitView");
mHandleColor = wm.getColor("Handle", "Accent");
mHoveredColor = wm.getColor("Hovered", "Interaction");
mResizingColor = wm.getColor("Resizing", "Action");
mMinSize = wm.getNumber("Min", 200.f);
mHandleSize = wm.getNumber("HandleSize", 7.f);
} }
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,28 +9,13 @@ 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() = default;
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 {
this->mArea = aArea;
this->mVisible = areaParent.isOverlap(aArea);
if (!this->mVisible) return;
}
void draw(Canvas& canvas) override {
if (!this->mVisible) return;
void drawBody(Canvas& canvas) override {
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 +23,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 +50,29 @@ namespace tp {
ImGui::PopStyleVar(3); ImGui::PopStyleVar(3);
} }
public:
void updateConfigCache(WidgetManager& wm) override {
wm.setActiveId("TextInput");
mAccentColor = wm.getColor("Accent", "Accent");
mBaseColor = wm.getColor("Base", "Base");
mRounding = wm.getNumber("Rounding", "Rounding");
mHoveredColor = wm.getColor("Hovered", "Accent");
mPadding = wm.getNumber("Padding", "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,46 +1,14 @@
#pragma once #pragma once
#include "WidgetConfig.hpp" #include "EventHandler.hpp"
#include "WidgetManager.hpp"
namespace tp { namespace tp {
template <typename Events, typename Canvas> template <typename Events, typename Canvas>
class Widget { class Widget {
public: public:
Widget() { Widget() { this->mArea = { 0, 0, 100, 100 }; }
this->mArea = { 0, 0, 100, 100 };
}
[[nodiscard]] const RGBA& getColor(const std::string& name) const {
const auto& node = cfg->values.get(name);
if (node.type == WidgetConfig::Node::REF) {
return globalCfg->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 == WidgetConfig::Node::REF) {
return globalCfg->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, WidgetConfig::Node(val)); }
void addValue(const std::string& name, halnf val) { cfg->values.put(name, WidgetConfig::Node(val)); }
void addColor(const std::string& name, const std::string& presetName) {
cfg->values.put(name, WidgetConfig::Node(presetName));
}
void addValue(const std::string& name, const std::string& presetName) {
cfg->values.put(name, WidgetConfig::Node(presetName));
}
void createConfig(const std::string& name) {
globalCfg->configs.put(name, {});
cfg = &globalCfg->configs.get(name);
}
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);
@ -49,18 +17,27 @@ namespace tp {
} }
this->mArea = aArea; this->mArea = aArea;
this->mAreaParent = areaParent;
procBody(events);
} }
virtual void draw(Canvas& canvas) { virtual void draw(Canvas& canvas) {
if (!mVisible) { if (!mVisible) {
return; return;
} }
drawBody(canvas);
} }
virtual void procBody(const Events& events) {}
virtual void drawBody(Canvas& canvas) {}
virtual void updateConfigCache(WidgetManager& wm) {}
public: public:
GlobalGUIConfig* globalCfg = gGlobalGUIConfig;
WidgetConfig* cfg = nullptr;
RectF mArea; RectF mArea;
RectF mAreaParent;
bool mVisible = false; bool mVisible = false;
}; };
} }

View file

@ -1,73 +0,0 @@
#pragma once
#include "Animations.hpp"
#include "Map.hpp"
#include "Rect.hpp"
#include "InputCodes.hpp"
namespace tp {
struct WidgetConfig {
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;
};
struct GlobalGUIConfig {
GlobalGUIConfig() {
configs.put("Presets", {});
auto& presets = configs.get("Presets");
presets.values.put("FontSize", WidgetConfig::Node(15.f));
presets.values.put("FontSizeDim", WidgetConfig::Node(12.f));
presets.values.put("Rounding", WidgetConfig::Node(5.f));
presets.values.put("Padding", WidgetConfig::Node(5.f));
presets.values.put("HandleSize", WidgetConfig::Node(5.f));
presets.values.put("Background", WidgetConfig::Node(RGBA{ 0.03f, 0.03f, 0.03f, 1.f }));
presets.values.put("Base", WidgetConfig::Node(RGBA{ 0.07f, 0.07f, 0.07f, 1.f }));
presets.values.put("Accent", WidgetConfig::Node(RGBA{ 0.13f, 0.13f, 0.13f, 1.f }));
presets.values.put("Interaction", WidgetConfig::Node(RGBA{ 0.33f, 0.33f, 0.3f, 1.f }));
presets.values.put("Action", WidgetConfig::Node(RGBA{ 0.44f, 0.44f, 0.4f, 1.f }));
presets.values.put("Front", WidgetConfig::Node(RGBA{ 1.f, 1.f, 1.f, 1.f }));
presets.values.put("FrontDim", WidgetConfig::Node(RGBA{ 0.7f, 0.7f, 0.7f, 1.f }));
}
Map<std::string, WidgetConfig> configs;
~GlobalGUIConfig() {
configs.removeAll();
}
};
extern GlobalGUIConfig* gGlobalGUIConfig;
}

View file

@ -0,0 +1,144 @@
#pragma once
#include "Animations.hpp"
#include "Map.hpp"
#include "Rect.hpp"
#include "InputCodes.hpp"
#include "Buffer.hpp"
namespace tp {
struct WidgetConfig {
struct Shortcut {
struct Condition {
std::string name;
std::string state;
};
std::string callbackName;
Shortcut() = default;
Shortcut(const InitialierList<Condition>&) {}
};
struct Parameter {
enum Type { NONE, VAL, COL };
halnf value = 0.f;
RGBA color = {};
Type type = NONE;
bool globalReference = false;
std::string globalId;
Parameter() = default;
explicit Parameter(halnf val) {
type = VAL;
value = val;
}
explicit Parameter(const RGBA& val) {
type = COL;
color = val;
}
explicit Parameter(const std::string& id, const Type& referenceType) {
type = referenceType;
globalId = id;
globalReference = true;
}
};
Map<std::string, Parameter> mParameters;
Buffer<Shortcut> mShortcuts;
};
class WidgetManager {
public:
using Parameter = WidgetConfig::Parameter;
public:
WidgetManager() { initGlobalParameters(); }
~WidgetManager() { mConfigurations.removeAll(); }
const RGBA& getColor(const std::string& parameterId, const RGBA& defaultValue) {
WidgetConfig& config = getWidgetConfig(mActiveId);
Parameter& parameter = getParameter(config, parameterId, Parameter(defaultValue));
return parameter.color;
}
const RGBA& getColor(const std::string& parameterId, const char* globalRef) {
WidgetConfig& config = getWidgetConfig(mActiveId);
Parameter& parameter = getParameter(config, parameterId, Parameter(globalRef, Parameter::COL));
return parameter.color;
}
halnf getNumber(const std::string& parameterId, halnf defaultValue) {
WidgetConfig& config = getWidgetConfig(mActiveId);
Parameter& parameter = getParameter(config, parameterId, Parameter(defaultValue));
return parameter.value;
}
halnf getNumber(const std::string& parameterId, const char* globalRef) {
WidgetConfig& config = getWidgetConfig(mActiveId);
Parameter& parameter = getParameter(config, parameterId, Parameter(globalRef, Parameter::VAL));
return parameter.value;
}
void setActiveId(const std::string& id) { mActiveId = id; }
private:
WidgetConfig& getWidgetConfig(const std::string& id) {
auto idx = mConfigurations.presents(id);
if (idx) return mConfigurations.getSlotVal(idx);
mConfigurations.put(id, {});
return mConfigurations.get(id);
}
Parameter& getParameter(WidgetConfig& config, const std::string& id, const Parameter& defaultValue) {
auto idx = config.mParameters.presents(id);
if (!idx) {
config.mParameters.put(id, defaultValue);
}
Parameter& parameter = config.mParameters.get(id);
if (parameter.globalReference) {
return mGlobalConfig.mParameters.get(parameter.globalId);
} else {
return parameter;
}
}
void initGlobalParameters() {
auto& params = mGlobalConfig.mParameters;
params.put("FontSize", Parameter(15.f));
params.put("FontSizeDim", Parameter(12.f));
params.put("Rounding", Parameter(5.f));
params.put("Padding", Parameter(5.f));
params.put("HandleSize", Parameter(5.f));
params.put("Background", Parameter(RGBA{ 0.03f, 0.03f, 0.03f, 1.f }));
params.put("Base", Parameter(RGBA{ 0.07f, 0.07f, 0.07f, 1.f }));
params.put("Accent", Parameter(RGBA{ 0.13f, 0.13f, 0.13f, 1.f }));
params.put("Interaction", Parameter(RGBA{ 0.33f, 0.33f, 0.3f, 1.f }));
params.put("Action", Parameter(RGBA{ 0.44f, 0.44f, 0.4f, 1.f }));
params.put("Front", Parameter(RGBA{ 1.f, 1.f, 1.f, 1.f }));
params.put("FrontDim", Parameter(RGBA{ 0.7f, 0.7f, 0.7f, 1.f }));
}
private:
Map<std::string, WidgetConfig> mConfigurations;
WidgetConfig mGlobalConfig;
RGBA mErrorColor = { 0, 0, 0, 1 };
halnf mErrorNumber = 0;
std::string mActiveId;
};
}