new widgets
This commit is contained in:
parent
5cc982fa00
commit
285ca80b4b
18 changed files with 373 additions and 43 deletions
|
|
@ -58,7 +58,7 @@ void Editor::loadDefaults() {
|
||||||
|
|
||||||
void Editor::setViewportSize(const Vec2F& size) {
|
void Editor::setViewportSize(const Vec2F& size) {
|
||||||
// TODO remove
|
// TODO remove
|
||||||
mScene.mCamera.rotate(0.01f, 0.0);
|
// mScene.mCamera.rotate(0.01f, 0.0);
|
||||||
|
|
||||||
mScene.mRenderSettings.size = size;
|
mScene.mRenderSettings.size = size;
|
||||||
|
|
||||||
|
|
@ -100,3 +100,19 @@ void Editor::denoisePathRenderBuffers() {
|
||||||
void Editor::setRenderType(Editor::RenderType type) {
|
void Editor::setRenderType(Editor::RenderType type) {
|
||||||
mRenderType = type;
|
mRenderType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::navigationOrbit(const Vec2F& delta) {
|
||||||
|
mScene.mCamera.rotate(delta.x, delta.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::navigationPan(const Vec2F& pos, const Vec2F& prevPos) {
|
||||||
|
mScene.mCamera.move(pos, prevPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::navigationZoom(halnf factor) {
|
||||||
|
mScene.mCamera.zoom(factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::navigationReset() {
|
||||||
|
mScene.mCamera.lookAtPoint({ 0, 0, 0 }, { 1, 5, 1 }, { 0, 0, 1 });
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,12 @@ namespace tp {
|
||||||
void setRenderType(RenderType type);
|
void setRenderType(RenderType type);
|
||||||
void denoisePathRenderBuffers();
|
void denoisePathRenderBuffers();
|
||||||
|
|
||||||
|
void navigationOrbit(const Vec2F& delta);
|
||||||
|
void navigationPan(const Vec2F& pos, const Vec2F& prevPos);
|
||||||
|
void navigationZoom(halnf factor);
|
||||||
|
void navigationReset();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendBuffersToGPU();
|
void sendBuffersToGPU();
|
||||||
void denoise();
|
void denoise();
|
||||||
|
|
|
||||||
|
|
@ -45,13 +45,36 @@ namespace tp {
|
||||||
this->mChildWidgets.pushBack(&mSplitView);
|
this->mChildWidgets.pushBack(&mSplitView);
|
||||||
this->mChildWidgets.pushBack(&mSettingsWidget);
|
this->mChildWidgets.pushBack(&mSettingsWidget);
|
||||||
|
|
||||||
mRenderPathTracer.mLabel.mLabel = "Render with Path Tracer";
|
// Render
|
||||||
mRenderRaster.mLabel.mLabel = "Render with Raster";
|
{
|
||||||
mDenoiseButton.mLabel.mLabel = "Denoise (IntelOpenImage)";
|
mRenderPathTracer.setLabel("Render with Path Tracer");
|
||||||
|
mRenderRaster.setLabel("Render with Raster");
|
||||||
|
mRenderDeNoise.setLabel("Denoise (IntelOpenImage)");
|
||||||
|
|
||||||
mSettingsWidget.addWidget(&mRenderPathTracer);
|
mRenderMenu.addWidgetToMenu(&mRenderPathTracer);
|
||||||
mSettingsWidget.addWidget(&mRenderRaster);
|
mRenderMenu.addWidgetToMenu(&mRenderRaster);
|
||||||
mSettingsWidget.addWidget(&mDenoiseButton);
|
mRenderMenu.addWidgetToMenu(&mRenderDeNoise);
|
||||||
|
|
||||||
|
mRenderMenu.setLabel("Render");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigation
|
||||||
|
{
|
||||||
|
mNavigationPan.setLabel("Pan");
|
||||||
|
mNavigationOrbit.setLabel("Orbit");
|
||||||
|
mNavigationZoom.setLabel("Zoom");
|
||||||
|
mNavigationReset.setLabel("Reset");
|
||||||
|
|
||||||
|
mNavigationMenu.addWidgetToMenu(&mNavigationPan);
|
||||||
|
mNavigationMenu.addWidgetToMenu(&mNavigationOrbit);
|
||||||
|
mNavigationMenu.addWidgetToMenu(&mNavigationZoom);
|
||||||
|
mNavigationMenu.addWidgetToMenu(&mNavigationReset);
|
||||||
|
|
||||||
|
mNavigationMenu.setLabel("Navigation");
|
||||||
|
}
|
||||||
|
|
||||||
|
mSettingsWidget.addWidget(&mRenderMenu);
|
||||||
|
mSettingsWidget.addWidget(&mNavigationMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventProcess(const Events& events) override {
|
void eventProcess(const Events& events) override {
|
||||||
|
|
@ -60,17 +83,60 @@ namespace tp {
|
||||||
mViewport.setArea(mSplitView.getFirst());
|
mViewport.setArea(mSplitView.getFirst());
|
||||||
mSettingsWidget.setArea(mSplitView.getSecond());
|
mSettingsWidget.setArea(mSplitView.getSecond());
|
||||||
|
|
||||||
if (mRenderPathTracer.isFired()) {
|
// render settings
|
||||||
mEditor->renderPathFrame();
|
{
|
||||||
mEditor->setRenderType(Editor::RenderType::PATH_TRACER);
|
if (mRenderPathTracer.isFired()) {
|
||||||
|
mEditor->renderPathFrame();
|
||||||
|
mEditor->setRenderType(Editor::RenderType::PATH_TRACER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRenderRaster.isFired()) {
|
||||||
|
mEditor->setRenderType(Editor::RenderType::RASTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRenderDeNoise.isFired()) {
|
||||||
|
mEditor->denoisePathRenderBuffers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRenderRaster.isFired()) {
|
// navigation
|
||||||
mEditor->setRenderType(Editor::RenderType::RASTER);
|
{
|
||||||
}
|
if (mNavigationOrbit.isFired()) {
|
||||||
|
mNavigationType = ORBIT;
|
||||||
|
}
|
||||||
|
|
||||||
if (mDenoiseButton.isFired()) {
|
if (mNavigationPan.isFired()) {
|
||||||
mEditor->denoisePathRenderBuffers();
|
mNavigationType = PAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNavigationZoom.isFired()) {
|
||||||
|
mNavigationType = ZOOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNavigationReset.isFired()) {
|
||||||
|
mEditor->navigationReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& activeArea = mViewport.mArea;
|
||||||
|
if (this->isHolding() && activeArea.isInside(events.getPointer())) {
|
||||||
|
switch (mNavigationType) {
|
||||||
|
case ORBIT:
|
||||||
|
mEditor->navigationOrbit(events.getPointerDelta() / activeArea.size * 3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAN:
|
||||||
|
{
|
||||||
|
auto pointer = (((events.getPointer() - activeArea.pos) / activeArea.size) - 0.5f) * 2;
|
||||||
|
auto prevPointer = (((events.getPointerPrev() - activeArea.pos) / activeArea.size) - 0.5f) * 2;
|
||||||
|
mEditor->navigationPan(prevPointer, pointer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZOOM:
|
||||||
|
mEditor->navigationZoom(1 + (events.getPointerDelta().y / activeArea.size.y));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,12 +155,22 @@ namespace tp {
|
||||||
SplitView<Events, Canvas> mSplitView;
|
SplitView<Events, Canvas> mSplitView;
|
||||||
|
|
||||||
ViewportWidget<Events, Canvas> mViewport;
|
ViewportWidget<Events, Canvas> mViewport;
|
||||||
|
ScrollableWindow<Events, Canvas> mSettingsWidget;
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
ScrollableWindow<Events, Canvas> mSettingsWidget;
|
CollapsableMenu<Events, Canvas> mRenderMenu;
|
||||||
ButtonWidget<Events, Canvas> mRenderPathTracer;
|
ButtonWidget<Events, Canvas> mRenderPathTracer;
|
||||||
ButtonWidget<Events, Canvas> mRenderRaster;
|
ButtonWidget<Events, Canvas> mRenderRaster;
|
||||||
ButtonWidget<Events, Canvas> mDenoiseButton;
|
ButtonWidget<Events, Canvas> mRenderDeNoise;
|
||||||
|
|
||||||
|
// Navigation
|
||||||
|
enum NavigationType { ORBIT, PAN, ZOOM } mNavigationType = ORBIT;
|
||||||
|
|
||||||
|
CollapsableMenu<Events, Canvas> mNavigationMenu;
|
||||||
|
ButtonWidget<Events, Canvas> mNavigationPan;
|
||||||
|
ButtonWidget<Events, Canvas> mNavigationOrbit;
|
||||||
|
ButtonWidget<Events, Canvas> mNavigationZoom;
|
||||||
|
ButtonWidget<Events, Canvas> mNavigationReset;
|
||||||
|
|
||||||
RGBA mBaseColor;
|
RGBA mBaseColor;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ void EventHandler::processEvent() {
|
||||||
switch (eventData.type) {
|
switch (eventData.type) {
|
||||||
case InputEvent::Type::MOUSE_POS:
|
case InputEvent::Type::MOUSE_POS:
|
||||||
{
|
{
|
||||||
|
mPointerPrev = mPointer;
|
||||||
mPointer = eventData.mouseEvent;
|
mPointer = eventData.mouseEvent;
|
||||||
mEventQueue.popFront();
|
mEventQueue.popFront();
|
||||||
break;
|
break;
|
||||||
|
|
@ -77,6 +78,8 @@ void EventHandler::processEvent() {
|
||||||
|
|
||||||
const Vec2F& EventHandler::getPointer() const { return mPointer; }
|
const Vec2F& EventHandler::getPointer() const { return mPointer; }
|
||||||
|
|
||||||
|
const Vec2F& EventHandler::getPointerPrev() const { return mPointerPrev; }
|
||||||
|
|
||||||
bool EventHandler::isPressed(InputID id) const {
|
bool EventHandler::isPressed(InputID id) const {
|
||||||
return mInputStates[(int) id].mCurrentState == InputState::State::PRESSED;
|
return mInputStates[(int) id].mCurrentState == InputState::State::PRESSED;
|
||||||
}
|
}
|
||||||
|
|
@ -92,4 +95,6 @@ bool EventHandler::isDown(InputID id) const {
|
||||||
mInputStates[(int) id].mCurrentState == InputState::State::HOLD;
|
mInputStates[(int) id].mCurrentState == InputState::State::HOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
halnf EventHandler::getScrollY() const { return 0; }
|
halnf EventHandler::getScrollY() const { return 0; }
|
||||||
|
|
||||||
|
Vec2F EventHandler::getPointerDelta() const { return mPointer - mPointerPrev; }
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,17 @@ void Application::run() {
|
||||||
|
|
||||||
bool redrawNeeded = false;
|
bool redrawNeeded = false;
|
||||||
|
|
||||||
|
// proc first frame by default
|
||||||
|
{
|
||||||
|
mWindow->processEvents();
|
||||||
|
processFrame(eventHandler);
|
||||||
|
|
||||||
|
mGraphics->drawBegin();
|
||||||
|
drawFrame(mGraphics->getCanvas());
|
||||||
|
mGraphics->drawEnd();
|
||||||
|
mWindow->draw();
|
||||||
|
}
|
||||||
|
|
||||||
while (!mWindow->shouldClose()) {
|
while (!mWindow->shouldClose()) {
|
||||||
if (mProcTimer.isTimeout()) {
|
if (mProcTimer.isTimeout()) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,9 @@ namespace tp {
|
||||||
void processEvent();
|
void processEvent();
|
||||||
|
|
||||||
[[nodiscard]] const Vec2F& getPointer() const;
|
[[nodiscard]] const Vec2F& getPointer() const;
|
||||||
|
[[nodiscard]] const Vec2F& getPointerPrev() const;
|
||||||
|
[[nodiscard]] Vec2F getPointerDelta() const;
|
||||||
|
|
||||||
[[nodiscard]] bool isPressed(InputID id) const;
|
[[nodiscard]] bool isPressed(InputID id) const;
|
||||||
[[nodiscard]] bool isReleased(InputID id) const;
|
[[nodiscard]] bool isReleased(InputID id) const;
|
||||||
[[nodiscard]] bool isDown(InputID id) const;
|
[[nodiscard]] bool isDown(InputID id) const;
|
||||||
|
|
@ -85,6 +88,8 @@ namespace tp {
|
||||||
|
|
||||||
// input states
|
// input states
|
||||||
Vec2F mPointer;
|
Vec2F mPointer;
|
||||||
|
Vec2F mPointerPrev;
|
||||||
|
|
||||||
halnf mPointerPressure = 0;
|
halnf mPointerPressure = 0;
|
||||||
|
|
||||||
InputState mInputStates[(int) InputID::LAST_KEY_CODE]{};
|
InputState mInputStates[(int) InputID::LAST_KEY_CODE]{};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace tp {
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Window* createWindow(Vec2F size = { 1000.f, 900.f }, const char* title = "Window");
|
static Window* createWindow(Vec2F size = { 500.f, 500.f }, const char* title = "Window");
|
||||||
static void destroyWindow(Window* window);
|
static void destroyWindow(Window* window);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,16 @@ namespace tp {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void lookAtPoint(const Vec3F& aTarget, const Vec3F& aPos, Vec3F aUp);
|
void lookAtPoint(const Vec3F& aTarget, const Vec3F& aPos, Vec3F aUp);
|
||||||
void rotate(halnf anglex, halnf angleY);
|
|
||||||
|
// -1 -1 is top left 1 1 is bottom right
|
||||||
void move(Vec2F aPos, Vec2F aPrevPos);
|
void move(Vec2F aPos, Vec2F aPrevPos);
|
||||||
|
|
||||||
|
// keeps z axis above your head
|
||||||
|
void rotate(halnf anglex, halnf angleY);
|
||||||
|
|
||||||
|
// -1 -1 is top left 1 1 is bottom right
|
||||||
void zoom(halnf ratio);
|
void zoom(halnf ratio);
|
||||||
|
|
||||||
void offset_target(halnf val);
|
void offset_target(halnf val);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,10 @@ namespace tp {
|
||||||
size = p3 - pos;
|
size = p3 - pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect<Type> shrink(Type val) const {
|
||||||
|
return { pos + val, size - val * 2 };
|
||||||
|
}
|
||||||
|
|
||||||
// if only one point isInside
|
// if only one point isInside
|
||||||
bool clampOutside(Vec2<Type>& v1, Vec2<Type>& v2) {
|
bool clampOutside(Vec2<Type>& v1, Vec2<Type>& v2) {
|
||||||
bool const in1 = isInside(v1);
|
bool const in1 = isInside(v1);
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ void RasterRender::render(const Scene& geometry, const Vec2<ualni>& size) {
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// glPolygonMode(GL_FRONT, GL_LINE);
|
||||||
|
// glPolygonMode(GL_BACK, GL_LINE);
|
||||||
|
|
||||||
for (auto object : geometry.mObjects) {
|
for (auto object : geometry.mObjects) {
|
||||||
|
|
||||||
static auto origin = (GLint) mDefaultShader.getu("Origin");
|
static auto origin = (GLint) mDefaultShader.getu("Origin");
|
||||||
|
|
@ -52,6 +55,10 @@ void RasterRender::render(const Scene& geometry, const Vec2<ualni>& size) {
|
||||||
|
|
||||||
mDefaultShader.unbind();
|
mDefaultShader.unbind();
|
||||||
|
|
||||||
|
|
||||||
|
// glPolygonMode(GL_FRONT, GL_FILL);
|
||||||
|
// glPolygonMode(GL_BACK, GL_FILL);
|
||||||
|
|
||||||
mRenderBuffer.endDraw();
|
mRenderBuffer.endDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
|
|
||||||
#include "ChatGUI.hpp"
|
#include "SimpleGUI.hpp"
|
||||||
|
|
||||||
#include "GraphicApplication.hpp"
|
#include "GraphicApplication.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
class SimpleGUI : public Application {
|
class SimpleGUI : public Application {
|
||||||
public:
|
public:
|
||||||
SimpleGUI() {
|
SimpleGUI() {
|
||||||
mGui.addWidget(&mButton);
|
|
||||||
mGui.addWidget(&mLabel);
|
|
||||||
mGui.addWidget(&mSlider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void processFrame(EventHandler* eventHandler) override {
|
void processFrame(EventHandler* eventHandler) override {
|
||||||
|
|
@ -22,17 +21,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFrame(Canvas* canvas) override {
|
void drawFrame(Canvas* canvas) override {
|
||||||
canvas->rect(mGui.mArea, { 0, 0, 0, 1 });
|
canvas->rect(mGui.mArea, { 0.1f, 0.1f, 0.1f, 1.f });
|
||||||
mGui.drawWrapper(*canvas);
|
mGui.drawWrapper(*canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WidgetManager mWidgetManager;
|
WidgetManager mWidgetManager;
|
||||||
ScrollableWindow<EventHandler, Canvas> mGui;
|
|
||||||
|
|
||||||
ButtonWidget<EventHandler, Canvas> mButton;
|
SimpleWidget2<EventHandler, Canvas> mGui;
|
||||||
LabelWidget<EventHandler, Canvas> mLabel;
|
|
||||||
NamedSliderWidget<EventHandler, Canvas> mSlider;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
||||||
45
Widgets/examples/SimpleGUI.hpp
Normal file
45
Widgets/examples/SimpleGUI.hpp
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "Widgets.hpp"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
|
||||||
|
template <typename Events, typename Canvas>
|
||||||
|
class SimpleWidget : public ScrollableWindow<Events, Canvas> {
|
||||||
|
public:
|
||||||
|
SimpleWidget() {
|
||||||
|
this->addWidget(&mLabel);
|
||||||
|
this->addWidget(&mButton);
|
||||||
|
this->addWidget(&mSlider);
|
||||||
|
this->addWidget(&mCollapsableMenu);
|
||||||
|
|
||||||
|
mCollapsableMenu.addWidgetToMenu(&mInMenuButton1);
|
||||||
|
mCollapsableMenu.addWidgetToMenu(&mInMenuButton2);
|
||||||
|
|
||||||
|
mInMenuButton1.mLabel.mLabel = "Button1";
|
||||||
|
mInMenuButton2.mLabel.mLabel = "Button2";
|
||||||
|
|
||||||
|
this->mArea.size = { 500, 500 };
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CollapsableMenu<Events, Canvas> mCollapsableMenu;
|
||||||
|
ButtonWidget<EventHandler, Canvas> mInMenuButton1;
|
||||||
|
ButtonWidget<EventHandler, Canvas> mInMenuButton2;
|
||||||
|
|
||||||
|
ButtonWidget<EventHandler, Canvas> mButton;
|
||||||
|
LabelWidget<EventHandler, Canvas> mLabel;
|
||||||
|
NamedSliderWidget<EventHandler, Canvas> mSlider;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Events, typename Canvas>
|
||||||
|
class SimpleWidget2 : public Widget<Events, Canvas> {
|
||||||
|
public:
|
||||||
|
SimpleWidget2() {
|
||||||
|
this->mChildWidgets.pushBack(&mFloating);
|
||||||
|
mFloating.addWidgetToMenu(&mWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FloatingWidget<EventHandler, Canvas> mFloating;
|
||||||
|
SimpleWidget<EventHandler, Canvas> mWidget;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -32,6 +32,10 @@ namespace tp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLabel(const std::string& string) {
|
||||||
|
mLabel.mLabel = string;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||||
wm.setActiveId("Button");
|
wm.setActiveId("Button");
|
||||||
|
|
|
||||||
91
Widgets/public/CollapsableMenu.hpp
Normal file
91
Widgets/public/CollapsableMenu.hpp
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ScrollableWidget.hpp"
|
||||||
|
#include "ButtonWidget.hpp"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
|
||||||
|
template <typename Events, typename Canvas>
|
||||||
|
class CollapsableMenu : public Widget<Events, Canvas> {
|
||||||
|
public:
|
||||||
|
CollapsableMenu() {
|
||||||
|
this->mChildWidgets.pushBack(&mHeader);
|
||||||
|
this->mChildWidgets.pushBack(&mBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
void eventProcess(const Events&) override {
|
||||||
|
if (mHeader.isReleased()) {
|
||||||
|
mCollapsed = !mCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHeader.setArea(getHeaderRect());
|
||||||
|
|
||||||
|
mBody.mEnable = !mCollapsed;
|
||||||
|
if (mCollapsed) {
|
||||||
|
this->mArea.size.y = headerHeight;
|
||||||
|
} else {
|
||||||
|
this->mArea.size.y = headerHeight + getBodyRect().size.y + mPadding * 2;
|
||||||
|
mBody.setArea(getBodyRect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eventDraw(Canvas& canvas) override {
|
||||||
|
canvas.rect(this->mArea, mBorderColor, rounding);
|
||||||
|
canvas.rect(this->mArea.shrink(mBorderSize), mMenuColor, rounding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void addWidgetToMenu(Widget<Events, Canvas>* widget) {
|
||||||
|
mBody.addWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLabel(const std::string& string) {
|
||||||
|
mHeader.mLabel = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RectF getHeaderRect() {
|
||||||
|
RectF out = { this->mArea.pos, { this->mArea.size.x, headerHeight } };
|
||||||
|
return out.shrink(mPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
RectF getBodyRect() {
|
||||||
|
RectF out = { { this->mArea.pos.x, this->mArea.pos.y + headerHeight },
|
||||||
|
{ this->mArea.size.x, mBody.getContentSize() }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mBody.getContentSize()) {
|
||||||
|
out = out.shrink(mPadding);
|
||||||
|
out.size.y += mPadding * 2 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||||
|
wm.setActiveId("CollapsableMenu");
|
||||||
|
|
||||||
|
headerHeight = wm.getNumber("HeaderHeight", 35);
|
||||||
|
mMenuColor = wm.getColor("MenuColor", RGBA(0, 0, 0, 1.f));
|
||||||
|
rounding = wm.getNumber("Rounding", "Rounding");
|
||||||
|
mBorderColor = wm.getColor("BorderColor", RGBA(0.16, 0.16, 0.16, 1.f));
|
||||||
|
mBorderSize = wm.getNumber("BorderSize", 2.f);
|
||||||
|
mPadding = wm.getNumber("Padding", "Padding");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ScrollableWindow<Events, Canvas> mBody;
|
||||||
|
LabelWidget<Events, Canvas> mHeader;
|
||||||
|
|
||||||
|
RGBA mMenuColor;
|
||||||
|
RGBA mBorderColor;
|
||||||
|
|
||||||
|
halnf headerHeight = 30;
|
||||||
|
halnf rounding = 0;
|
||||||
|
halnf mBorderSize = 0;
|
||||||
|
halnf mPadding = 0;
|
||||||
|
|
||||||
|
bool mCollapsed = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
46
Widgets/public/FloatingWidget.hpp
Normal file
46
Widgets/public/FloatingWidget.hpp
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CollapsableMenu.hpp"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
template <typename Events, typename Canvas>
|
||||||
|
class FloatingWidget : public CollapsableMenu<Events, Canvas> {
|
||||||
|
public:
|
||||||
|
FloatingWidget() {
|
||||||
|
this->mArea = { 0, 0, 300, 300 };
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void procWrapper(const Events& events, const RectF& parentArea) override {
|
||||||
|
if (!this->mEnable) return;
|
||||||
|
|
||||||
|
this->checkVisibility(events, parentArea);
|
||||||
|
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
|
this->checkFocus(events);
|
||||||
|
|
||||||
|
this->checkClicked(events);
|
||||||
|
|
||||||
|
mParentArea = parentArea;
|
||||||
|
this->eventProcess(events);
|
||||||
|
|
||||||
|
for (auto child : this->mChildWidgets) {
|
||||||
|
child->procWrapper(events, this->getArea());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eventProcess(const Events& events) override {
|
||||||
|
CollapsableMenu<Events, Canvas>::eventProcess(events);
|
||||||
|
|
||||||
|
if (this->mHeader.isHolding()) {
|
||||||
|
this->mArea.pos += events.getPointerDelta();
|
||||||
|
if (!this->mArea.isEnclosedIn(mParentArea)) {
|
||||||
|
this->mArea.pos -= events.getPointerDelta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RectF mParentArea;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -6,10 +6,12 @@ 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() = default;
|
LabelWidget() {
|
||||||
|
this->mArea = { 0, 0, 100, 30 };
|
||||||
|
}
|
||||||
|
|
||||||
void eventDraw(Canvas& canvas) override {
|
void eventDraw(Canvas& canvas) override {
|
||||||
canvas.text(mLabel.c_str(), this->mArea, fontSize, Canvas::CC, padding, fontColor);
|
canvas.text(mLabel.c_str(), this->mArea, fontSize, Canvas::LC, padding, fontColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ namespace tp {
|
||||||
this->mChildWidgets.pushBack(&mContentWidget);
|
this->mChildWidgets.pushBack(&mContentWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScrollableWindow() = default;
|
virtual ~ScrollableWindow() = default;
|
||||||
|
|
||||||
// takes whole area
|
// takes whole area
|
||||||
void eventProcess(const Events& events) override {
|
void eventProcess(const Events& events) override {
|
||||||
|
|
@ -154,7 +154,7 @@ namespace tp {
|
||||||
|
|
||||||
for (auto widget : content) {
|
for (auto widget : content) {
|
||||||
widget->setArea({ mContentWidget.mArea.x + padding,
|
widget->setArea({ mContentWidget.mArea.x + padding,
|
||||||
widget->mArea.y,
|
mContentWidget.mArea.y + widget->mArea.y,
|
||||||
mScroller.getViewport().z - padding * 2,
|
mScroller.getViewport().z - padding * 2,
|
||||||
widget->mArea.w });
|
widget->mArea.w });
|
||||||
}
|
}
|
||||||
|
|
@ -169,23 +169,30 @@ namespace tp {
|
||||||
mPadding = wm.getNumber("Padding", "Padding");
|
mPadding = wm.getNumber("Padding", "Padding");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] halnf getContentSize() const {
|
||||||
|
return mContentSize;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateContents(List<Widget<Events, Canvas>*>& contentWidgets) {
|
void updateContents(List<Widget<Events, Canvas>*>& contentWidgets) {
|
||||||
if (contentWidgets.size()) {
|
if (!contentWidgets.size()) {
|
||||||
const halnf offset = contentWidgets.first()->mArea.y + mPadding;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
halnf start = 0;
|
const halnf offset = contentWidgets.first()->mArea.y + mPadding;
|
||||||
for (auto widget : contentWidgets) {
|
|
||||||
widget->mArea.y = start;
|
|
||||||
start += widget->mArea.w + mPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto widget : contentWidgets) {
|
halnf start = 0;
|
||||||
widget->mArea.y += offset;
|
for (auto widget : contentWidgets) {
|
||||||
}
|
widget->mArea.y = start;
|
||||||
|
start += widget->mArea.w + mPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto widget : contentWidgets) {
|
||||||
|
widget->mArea.y += offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ready content size
|
||||||
void updateContentSize(List<Widget<Events, Canvas>*>& contentWidgets) {
|
void updateContentSize(List<Widget<Events, Canvas>*>& contentWidgets) {
|
||||||
mContentSize = 0;
|
mContentSize = 0;
|
||||||
if (contentWidgets.size()) {
|
if (contentWidgets.size()) {
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,6 @@
|
||||||
#include "SplitViewWidget.hpp"
|
#include "SplitViewWidget.hpp"
|
||||||
#include "TextInputWidget.hpp"
|
#include "TextInputWidget.hpp"
|
||||||
#include "SliderWidget.hpp"
|
#include "SliderWidget.hpp"
|
||||||
|
#include "CollapsableMenu.hpp"
|
||||||
|
#include "FloatingWidget.hpp"
|
||||||
#include "Animations.hpp"
|
#include "Animations.hpp"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue