diff --git a/.gitmodules b/.gitmodules index 7bafd8b..9d1d1de 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,6 +19,3 @@ [submodule "Externals/asio"] path = Externals/asio url = https://github.com/elushaX/asio.git -[submodule "Externals/implot"] - path = Externals/implot - url = https://github.com/epezent/implot.git diff --git a/3DEditor/private/Editor.cpp b/3DEditor/private/Editor.cpp index 59facdf..26599a0 100644 --- a/3DEditor/private/Editor.cpp +++ b/3DEditor/private/Editor.cpp @@ -57,7 +57,7 @@ void Editor::loadDefaults() { } void Editor::setViewportSize(const Vec2F& size) { - if (size.x <= 0 || size.y <= 0) return; + if (size.x < 0 || size.y < 0) return; // TODO remove // mScene.mCamera.rotate(0.01f, 0.0); diff --git a/3DEditor/public/EditorWidget.hpp b/3DEditor/public/EditorWidget.hpp index 2d1f63c..00899df 100644 --- a/3DEditor/public/EditorWidget.hpp +++ b/3DEditor/public/EditorWidget.hpp @@ -2,7 +2,7 @@ #include "DockWidget.hpp" #include "Editor.hpp" -#include "MenuWidgets.hpp" +#include "FloatingWidget.hpp" namespace tp { @@ -17,7 +17,7 @@ namespace tp { ~ViewportWidget() override { mCanvas->deleteImageHandle(mImage); } void process(const EventHandler& events) override { - mEditor->setViewportSize(getAreaT().size); + mEditor->setViewportSize(getArea().size); } void draw(Canvas& canvas) override { @@ -40,11 +40,11 @@ namespace tp { mViewport(canvas, editor) { mEditor = editor; - // mPanel.setText("Controls"); - //mPanel.addToMenu(&mNavigationMenu); - //mPanel.addToMenu(&mRenderMenu); + mPanel.setText("Controls"); + mPanel.addToMenu(&mNavigationMenu); + mPanel.addToMenu(&mRenderMenu); - dockWidget(&mNavigationMenu, DockLayout::RIGHT); + dockWidget(&mPanel, DockLayout::RIGHT); setCenterWidget(&mViewport); // Render @@ -120,10 +120,10 @@ namespace tp { ViewportWidget mViewport; - FloatingScrollableMenu mPanel; + FloatingMenu mPanel; // Controls - FloatingScrollableMenu mRenderMenu; + FloatingMenu mRenderMenu; ButtonWidget mRenderPathTracer; ButtonWidget mRenderRaster; ButtonWidget mRenderDeNoise; @@ -131,7 +131,7 @@ namespace tp { // Navigation enum NavigationType { ORBIT, PAN, ZOOM } mNavigationType = ORBIT; - FloatingScrollableMenu mNavigationMenu; + FloatingMenu mNavigationMenu; ButtonWidget mNavigationPan; ButtonWidget mNavigationOrbit; ButtonWidget mNavigationZoom; diff --git a/Externals/CMakeLists.txt b/Externals/CMakeLists.txt index dcfd02d..ce5f9b4 100644 --- a/Externals/CMakeLists.txt +++ b/Externals/CMakeLists.txt @@ -49,14 +49,11 @@ set(${PROJECT_NAME}_SOURCES imgui/backends/imgui_impl_glfw.cpp imgui/backends/imgui_impl_opengl3.cpp - - implot/implot.cpp - implot/implot_items.cpp ) add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_SOURCES}) include_directories(${PROJECT_NAME} ./glfw/include) -target_include_directories(${PROJECT_NAME} PUBLIC ./imgui/ ./imgui/backends/ ./implot/) +target_include_directories(${PROJECT_NAME} PUBLIC ./imgui/ ./imgui/backends/) project(Nanovg) set(${PROJECT_NAME}_SOURCES diff --git a/Externals/implot b/Externals/implot deleted file mode 160000 index f156599..0000000 --- a/Externals/implot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f156599faefe316f7dd20fe6c783bf87c8bb6fd9 diff --git a/Graphics/private/DebugGUI.cpp b/Graphics/private/DebugGUI.cpp index 03f6b1f..d824a88 100644 --- a/Graphics/private/DebugGUI.cpp +++ b/Graphics/private/DebugGUI.cpp @@ -9,8 +9,6 @@ #include #include -#include "implot.h" - namespace tp { class DebugGUI::Context { public: @@ -43,8 +41,6 @@ DebugGUI::DebugGUI(Window* window) { // appearance io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - ImPlot::CreateContext(); - return; auto& colors = ImGui::GetStyle().Colors; @@ -79,13 +75,10 @@ DebugGUI::DebugGUI(Window* window) { } DebugGUI::~DebugGUI() { - ImPlot::DestroyContext(); - ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); - delete mContext; } diff --git a/Graphics/private/Window.cpp b/Graphics/private/Window.cpp index 4f9c756..ac8e958 100644 --- a/Graphics/private/Window.cpp +++ b/Graphics/private/Window.cpp @@ -29,8 +29,6 @@ Window::Window(Vec2F size, const char* title) { // glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1); // glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); - mSize = size; - // Create a window and OpenGL context mContext->window = glfwCreateWindow((int) size.x, (int) size.y, title, nullptr, nullptr); if (!mContext->window) { diff --git a/Graphics/public/EventHandler.hpp b/Graphics/public/EventHandler.hpp index ea35c89..c62bd89 100644 --- a/Graphics/public/EventHandler.hpp +++ b/Graphics/public/EventHandler.hpp @@ -87,7 +87,6 @@ namespace tp { [[nodiscard]] halnf getPointerPressure() const; void setEnableKeyEvents(bool); - [[nodiscard]] bool isKeyEventsEnabled() const { return mEnableKeyEvents; } private: void processEventUnguarded(); diff --git a/LibraryViewer/public/GUI.hpp b/LibraryViewer/public/GUI.hpp index 10a1ad7..9ab1060 100644 --- a/LibraryViewer/public/GUI.hpp +++ b/LibraryViewer/public/GUI.hpp @@ -248,7 +248,7 @@ namespace tp { void process(const EventHandler& events) override { filter(); - for (auto track : mSongList.getContainer()->getChildren()) { + for (auto track : mSongList.getContent()) { if (auto trackWidget = dynamic_cast(track.data())) { if (trackWidget->mState == TrackWidget::SELECTED) { mCurrentTrackInfo.mTrack = trackWidget->mTrack; @@ -268,7 +268,7 @@ namespace tp { void filter() { if (!mCurrentTrackInfo.isSongFilterChanged) return; - mSongList.getContainer()->clear(); + mSongList.clearChildren(); for (auto track : mTracks) { if (!mCurrentTrackInfo.songFilter.PassFilter(track->mTrack->mName.c_str()) && @@ -290,7 +290,7 @@ namespace tp { break; } - mSongList.getContainer()->addChild(track.data()); + mSongList.addToMenu(track.data()); } mCurrentTrackInfo.isSongFilterChanged = false; @@ -302,7 +302,7 @@ namespace tp { Buffer mTracks; - ScrollableWidget mSongList; + FloatingMenu mSongList; TrackInfoWidget mCurrentTrackInfo; TrackWidget mCurrentTrack; }; diff --git a/Modules/public/Timing.hpp b/Modules/public/Timing.hpp index 505738b..52d91c7 100644 --- a/Modules/public/Timing.hpp +++ b/Modules/public/Timing.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include "Environment.hpp" namespace tp { @@ -57,19 +56,4 @@ namespace tp { } } }; - - struct TimerWrapper { - explicit TimerWrapper(const std::function& arg) { - codeSnippet = arg; - } - - time_ms exec() { - Timer timer; - codeSnippet(); - return timer.timePassed(); - } - - private: - std::function codeSnippet; - }; } \ No newline at end of file diff --git a/Sketch3D/public/Sketch3DWidget.hpp b/Sketch3D/public/Sketch3DWidget.hpp index d59213b..9859525 100644 --- a/Sketch3D/public/Sketch3DWidget.hpp +++ b/Sketch3D/public/Sketch3DWidget.hpp @@ -3,7 +3,7 @@ #include "Sketch3D.hpp" #include "Widget.hpp" #include "DockWidget.hpp" -#include "MenuWidgets.hpp" +#include "FloatingWidget.hpp" namespace tp { @@ -150,15 +150,15 @@ namespace tp { private: Sketch3DWidget mViewport; - FloatingScrollableMenu mPanel; + FloatingMenu mPanel; - FloatingScrollableMenu mControls; + FloatingMenu mControls; ButtonWidget mDrawButton; ButtonWidget mMoveButton; ButtonWidget mRotateButton; ButtonWidget mZoomButton; - FloatingScrollableMenu mColorPicker; + FloatingMenu mColorPicker; SliderWidget mRed; SliderWidget mGreen; SliderWidget mBlue; diff --git a/TODO b/TODO index f13e92e..e14c5f7 100644 --- a/TODO +++ b/TODO @@ -1,18 +1,13 @@ Widgets: - Basic scrollable widget - Collapsing menus - - Icons - Toolbar widget - Fix focus locking mechanism - Hover PopUps - Color Picker + Replace Old Widgets!! Optimize: Make visual parameters static Make get-areas fetch cache and not animation objects New Widgets: + Collapsing menu + Sliders Check Boxes Drop-Downs Toaster notifications diff --git a/Widgets/CMakeLists.txt b/Widgets/CMakeLists.txt index 0589f17..126d59f 100644 --- a/Widgets/CMakeLists.txt +++ b/Widgets/CMakeLists.txt @@ -10,8 +10,8 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Math Graphics Imgui) ### -------------------------- Applications -------------------------- ### -add_executable(WidgetsExample examples/Example.cpp) -target_link_libraries(WidgetsExample ${PROJECT_NAME} ${GLEW_LIB}) -target_include_directories(WidgetsExample PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR}) +add_executable(Widgets2Example examples/Example.cpp) +target_link_libraries(Widgets2Example ${PROJECT_NAME} ${GLEW_LIB}) +target_include_directories(Widgets2Example PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR}) file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") \ No newline at end of file diff --git a/Widgets/examples/Example.cpp b/Widgets/examples/Example.cpp index 0682651..288d1b1 100644 --- a/Widgets/examples/Example.cpp +++ b/Widgets/examples/Example.cpp @@ -2,7 +2,7 @@ #include "WidgetApplication.hpp" #include "RootWidget.hpp" -#include "MenuWidgets.hpp" +#include "FloatingWidget.hpp" #include "DockWidget.hpp" #include "ScrollableLayout.hpp" @@ -13,15 +13,15 @@ using namespace tp; class Example : public WidgetApplication { public: Example() { - exampleNestedMenus(); + exampleScrolling(); } void exampleAll() { static DockWidget dock; static LabelWidget centralWidget; - static FloatingScrollableMenu menus[4]; - static FloatingScrollableMenu nestedMenus[4]; - static FloatingScrollableMenu buttons[10]; + static FloatingMenu menus[4]; + static FloatingMenu nestedMenus[4]; + static FloatingMenu buttons[10]; dock.setCenterWidget(¢ralWidget); @@ -36,30 +36,6 @@ public: setRoot(&dock); } - void exampleCollapsingMenus() { - static DockWidget dock; - static CollapsingMenuWidget mainMenu; - static CollapsingMenuWidget menus[3]; - static ButtonWidget buttons[5]; - - for (auto& menu : menus) { - mainMenu.getContainer()->addChild(&menu); - } - - menus[0].getContainer()->addChild(&buttons[0]); - menus[0].getContainer()->addChild(&buttons[1]); - menus[0].getContainer()->addChild(&buttons[2]); - - menus[1].getContainer()->addChild(&buttons[3]); - menus[1].getContainer()->addChild(&buttons[4]); - - // dock.addChild(&menus[0]); - - setRoot(&menus[0]); - - // RootWidget::setWidgetArea(mainMenu, { 333, 333, 522, 522 }); - } - void exampleBasic() { static Widget widget; static LabelWidget label; @@ -74,44 +50,40 @@ public: } void exampleScrolling() { - static ScrollableWidget widget; + static Widget widget; + static Widget content; static ButtonWidget buttons[10]; - - // widget.setDirection(false); + static ScrollableBarWidget scrollBar; setRoot(&widget); + widget.addChild(&scrollBar); + widget.addChild(&content); + for (auto& button : buttons) { - widget.getContainer()->addChild(&button); + content.addChild(&button); } - RootWidget::setWidgetArea(*widget.getContainer(), { 333, 333, 522, 522 }); + widget.setLayout(new ScrollableLayout(&widget)); + + RootWidget::setWidgetArea(content, { 333, 333, 522, 522 }); } void examplePopup() { static Widget root; - static Widget popup; - static ButtonWidget closeButton; static ButtonWidget openButton; - static ButtonWidget buttons[3]; - - for (auto& button : buttons) { - popup.addChild(&button); - } - - popup.addChild(&closeButton); root.addChild(&openButton); ((BasicLayout*)root.getLayout())->setLayoutPolicy(LayoutPolicy::Passive); openButton.setAction([&](){ - popup.setArea({ 50, 50, 300, 300 }); - openButton.openPopup(&popup); + closeButton.setArea({ 50, 50, 100, 100 }); + openButton.openPopup(&closeButton); }); closeButton.setAction([&](){ - closeButton.closePopup(&popup); + closeButton.closePopup(&closeButton); }); openButton.setText("open"); @@ -124,8 +96,8 @@ public: void exampleNestedMenus() { static DockWidget dock; - static FloatingScrollableMenu menu1; - static FloatingScrollableMenu menu2; + static FloatingMenu menu1; + static FloatingMenu menu2; static ButtonWidget buttons[15]; setRoot(&dock); @@ -197,8 +169,8 @@ public: void exampleDock() { static DockWidget dock; - static FloatingScrollableMenu menu1; - static FloatingScrollableMenu menu2; + static FloatingMenu menu1; + static FloatingMenu menu2; static ButtonWidget buttons[15]; setRoot(&dock); diff --git a/Widgets/private/Layout.cpp b/Widgets/private/Layout.cpp index 2eab62e..bd56f95 100644 --- a/Widgets/private/Layout.cpp +++ b/Widgets/private/Layout.cpp @@ -29,11 +29,7 @@ const Vec2& WidgetLayout::getSizePolicy() const { return mSizePolicy void WidgetLayout::setSizePolicy(SizePolicy x, SizePolicy y) { mSizePolicy = { x, y }; } -WidgetLayout* WidgetLayout::lay(Widget* w) { return w->getLayout(); } - RangeF WidgetLayout::pickRange(const RangeF& current, const RangeF& children, const RangeF& parent, bool vertical) const { - return current; - RangeF out; switch (mSizePolicy[vertical]) { @@ -48,16 +44,10 @@ RangeF WidgetLayout::pickRange(const RangeF& current, const RangeF& children, co void WidgetLayout::clampMinMaxSize() { auto current = getArea(); - auto minContent = minContentArea(); - minContent.size.clamp(mMinSize, mMaxSize); - current.clamp(minContent); + current.size.clamp(mMinSize, mMaxSize); setArea(current); } -void WidgetLayout::pickMinimalRect(bool dir) { - setArea(minContentArea()); -} - RangeF WidgetLayout::clampRange(const RangeF& current, const RangeF& child, const RangeF& parent, bool vertical) const { auto out = current; @@ -94,17 +84,13 @@ RectF WidgetLayout::getChildrenEnclosure() const { return out; } -RectF WidgetLayout::availableChildArea() const { +RectF WidgetLayout::getAvailableChildArea() const { return getArea().relative(); } -RectF WidgetLayout::minContentArea() const { - return getChildrenEnclosure(); -} - RectF WidgetLayout::getParentEnclosure() const { DEBUG_ASSERT(parent()) if (!parent()) return { { 0, 0 }, mMaxSize }; - auto out = parent()->getLayout()->availableChildArea(); + auto out = parent()->getLayout()->getAvailableChildArea(); return out; } \ No newline at end of file diff --git a/Widgets/private/RootWidget.cpp b/Widgets/private/RootWidget.cpp index 78f2c17..1203b58 100644 --- a/Widgets/private/RootWidget.cpp +++ b/Widgets/private/RootWidget.cpp @@ -8,8 +8,6 @@ using namespace tp; -#define SAMPLE(label, scope) gDebugWidget.##label.addSample(TimerWrapper([&]() scope ).exec()); - WidgetLayout* WidgetManagerInterface::defaultLayout(Widget* widget) { return new BasicLayout(widget); } @@ -37,30 +35,26 @@ void RootWidget::setRootWidget(Widget* widget) { void RootWidget::processFrame(EventHandler* events, const RectF& screenArea) { mRoot.setArea(screenArea); - gDebugWidget.mUpdManager.addSample(TimerWrapper([&]() { - // construct hierarchy tree of widgets to process - mUpdateManager.updateTreeToProcess(&mRoot); + if (!gDebugWidget.update(this, *events)) return; - updateAnimations(); - updateAreaCache(&mRoot, true); + // construct hierarchy tree of widgets to process + mUpdateManager.updateTreeToProcess(&mRoot); - // update all events and call all event processing callbacks - mUpdateManager.processWidgets(&mRoot, *events); + updateAnimations(); + updateAreaCache(&mRoot, true); - updateAreaCache(&mRoot, true); - }).exec()); + // update all events and call all event processing callbacks + mUpdateManager.processWidgets(&mRoot, *events); - gDebugWidget.mLayManager.addSample(TimerWrapper([&]() { - // update widget sizes base on individual size policies - mLayoutManager.adjust(&mRoot); - }).exec()); + updateAreaCache(&mRoot, true); + + // update widget sizes base on individual size policies + mLayoutManager.adjust(&mRoot); updateAreaCache(&mRoot, false); // trigger some widgets by moise pointer - auto prevFocus = mUpdateManager.getFocusWidget(); - auto newFocus = mUpdateManager.findFocusWidget(&mRoot, *events); - mUpdateManager.handleFocusChanges(newFocus, prevFocus); + mUpdateManager.handleFocusChanges(&mRoot, *events); // check triggered widgets for removal mUpdateManager.clean(); @@ -73,9 +67,13 @@ bool RootWidget::needsUpdate() const { void RootWidget::drawFrame(Canvas& canvas) { canvas.rect(mRoot.getAreaT(), RGBA(0, 0, 0, 1)); + drawRecursion(canvas, &mRoot, { 0, 0 }); + + gDebugWidget.drawDebug(this, canvas); } + void RootWidget::drawRecursion(Canvas& canvas, Widget* active, const Vec2F& pos) { if (!active->mFlags.get(ENABLED)) return; @@ -83,9 +81,7 @@ void RootWidget::drawRecursion(Canvas& canvas, Widget* active, const Vec2F& pos) canvas.pushClamp({ pos, active->getArea().size }); if (canvas.getClampedArea().size.length2() > EPSILON) { - if (active->getArea().sizeVecW() > active->getArea().pos) { - active->draw(canvas); - } + active->draw(canvas); for (auto child = active->mDepthOrder.lastNode(); child; child = child->prev) { drawRecursion(canvas, child->data, pos + child->data->getArea().pos); @@ -156,3 +152,4 @@ void RootWidget::closePopup(Widget* widget) { void RootWidget::lockFocus(Widget* widget) { mUpdateManager.lockFocus(widget); } void RootWidget::freeFocus(Widget* widget) { mUpdateManager.freeFocus(widget); } +bool RootWidget::isDebug() const { return gDebugWidget.isDebug(); } diff --git a/Widgets/private/Widget.cpp b/Widgets/private/Widget.cpp index 3db3244..5b7dc2c 100644 --- a/Widgets/private/Widget.cpp +++ b/Widgets/private/Widget.cpp @@ -5,8 +5,7 @@ using namespace tp; Widget::Widget() { - mArea.setTargetRect({ 100, 100, 50, 50 }); - + mArea.setTargetRect({ 100, 100, 10, 10 }); setLayout(WidgetManagerInterface::defaultLayout(this)); mArea.endAnimation(); diff --git a/Widgets/private/WidgetApplication.cpp b/Widgets/private/WidgetApplication.cpp index 70e5aa0..9f0e99d 100644 --- a/Widgets/private/WidgetApplication.cpp +++ b/Widgets/private/WidgetApplication.cpp @@ -5,58 +5,6 @@ using namespace tp; void WidgetApplication::debugUI() { - // pass + ImGui::Text("Proc ms : %i", (int) mProcTime); + ImGui::SameLine(); ImGui::Text("Draw ms : %i", (int) mDrawTime); } - -void WidgetApplication::setRoot(Widget* widget) { - mRootWidget.setRootWidget(widget); - - tp::RootWidget::setWidgetArea(*widget, {{}, mWindow->getSize()}); -} - -void WidgetApplication::processFrame(EventHandler* eventHandler, halnf deltaTime) { - const auto area = RectF({ 0, 0 }, mWindow->getSize()); - - gDebugWidget.update(&mRootWidget, *eventHandler); - - if (gDebugWidget.isDebug()) { - mGuiArea = area.splitByFactorHL(mDebugSplitFactor); - mDebugArea = area.splitByFactorHR(mDebugSplitFactor); - } else { - mGuiArea = area; - } - - if (gDebugWidget.isFrozen()) return; - - Timer timer; - mRootWidget.processFrame(eventHandler, mGuiArea); - gDebugWidget.mProcTime.addSample(timer.timePassed()); -} - -void WidgetApplication::drawFrame(Canvas* canvas) { - Timer timer; - mRootWidget.drawFrame(*canvas); - gDebugWidget.mDrawTime.addSample(timer.timePassed()); - - if (gDebugWidget.isDebug()) { - ImGui::SetNextWindowPos(ImVec2(mDebugArea.x, mDebugArea.y)); - ImGui::SetNextWindowSize(ImVec2(mDebugArea.z, mDebugArea.w)); - - if (ImGui::Begin( - "Existing Window Name", - nullptr, - ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDecoration - )) { - - drawDebug(); - debugUI(); - - gDebugWidget.drawDebug(&mRootWidget, *canvas); - } - ImGui::End(); - } -} - -bool WidgetApplication::forceNewFrame() { - return mRootWidget.needsUpdate(); -} \ No newline at end of file diff --git a/Widgets/private/layouts/BasicLayout.cpp b/Widgets/private/layouts/BasicLayout.cpp index eedf61a..c02b14d 100644 --- a/Widgets/private/layouts/BasicLayout.cpp +++ b/Widgets/private/layouts/BasicLayout.cpp @@ -26,7 +26,20 @@ void BasicLayout::pickRect(bool vertical) { setArea(newArea); } -void BasicLayout::arrangeChildren(bool vertical) { +void BasicLayout::clampRect() { + DEBUG_ASSERT(0) + + auto current = getArea(); + auto children = getChildrenEnclosure(); + auto parent = getParentEnclosure(); + + auto rangeX = clampRange(current.getRangeX(), children.getRangeX(), parent.getRangeX(), false); + auto rangeY = clampRange(current.getRangeY(), children.getRangeY(), parent.getRangeY(), true); + + setArea(RectF(rangeX, rangeY)); +} + +void BasicLayout::updateLayout(bool vertical) { if (children().empty()) return; if (vertical) { @@ -44,64 +57,61 @@ void BasicLayout::arrangeChildren(bool vertical) { } } -halnf BasicLayout::shrinkLayoutSize(WidgetLayout* widget, halnf diff, bool vertical) { - auto area = widget->getArea(); - auto prevSize = area.size[vertical]; - area.size[vertical] += diff; - widget->setArea(area); - //widget->clampMinMaxSize(); - return widget->getArea().size[vertical] - prevSize; -} -bool BasicLayout::canChange(Widget* widget, bool vertical) { - return widget->getLayout()->getSizePolicy()[vertical] == SizePolicy::Expanding; +halnf BasicLayout::changeChildSize(tp::Widget* widget, halnf diff, bool vertical) { + auto prevSize = widget->getLayout()->getArea().size[vertical]; + { + auto area = widget->getLayout()->getArea(); + area.size[vertical] += diff; + widget->setAreaCache(area); + + widget->getLayout()->clampMinMaxSize(); + } + auto newSize = widget->getLayout()->getArea().size[vertical]; + return newSize - prevSize; } void BasicLayout::adjustLayout(bool vertical) { + std::vector> contributors; + Vec2F contentSize = { 0, 0 }; + Vec2F availableSize = getArea().size; - std::vector> contributors; - halnf contentSize = 0; + for (auto child : children()) { + child->getLayout()->pickRect(vertical); - // find contributors - for (Widget* child : children()) { - if (canChange(child, vertical)) { - contributors.emplace_back( lay(child), true ); + if (child->getLayout()->getSizePolicy()[vertical] == SizePolicy::Expanding) { + contributors.emplace_back( child, true ); + + auto area = child->getLayout()->getArea(); + area.size[vertical] = 0; + child->setAreaCache(area); + child->getLayout()->clampMinMaxSize(); } + + contentSize += child->getLayout()->getArea().size; } - // let each child to chose desired rect - for (Widget* child : children()) { - if (canChange(child, vertical)) { - lay(child)->pickMinimalRect(vertical); - } else { - lay(child)->pickRect(vertical); - } - } + availableSize -= mLayoutGap * ((halnf) children().size() - 1) + mLayoutMargin * 2; - // calculate content size - for (Widget* child : children()) { - contentSize += lay(child)->getArea().size[vertical]; - } - - halnf availableSize = getArea().size[vertical] - (mLayoutGap * ((halnf) children().size() - 1) + mLayoutMargin * 2); - - if (availableSize < 0) return; - - halnf totalQuota = availableSize - contentSize; + auto diff = availableSize - contentSize; // expand or contract as much as possible - while (!contributors.empty() && (totalQuota != 0)) { - halnf quotaPerContributor = totalQuota / (halnf) contributors.size(); + while (!contributors.empty() && (diff[vertical] != 0)) { + auto quota = diff / (halnf) contributors.size(); for (auto& contributor : contributors) { - halnf contribution = shrinkLayoutSize(contributor.first, quotaPerContributor, vertical); + if (!contributor.second) continue; + + // contributor.first->endAnimations(); + auto contribution = changeChildSize(contributor.first, quota[vertical], vertical); + if (contribution == 0) { contributor.second = false; } - totalQuota -= contribution; + + diff[vertical] -= contribution; } - // remove useless contributors contributors.erase( std::remove_if(contributors.begin(), contributors.end(), [](auto node) { return !node.second; }), contributors.end() @@ -110,31 +120,30 @@ void BasicLayout::adjustLayout(bool vertical) { // set opposite direction size for (auto child : children()) { - RectF area = lay(child)->getArea(); - area.size[!vertical] = getArea().size[!vertical] - mLayoutMargin * 2; - child->setAreaCache(area); + // if (child->getLayout()->getSizePolicy()[!vertical] != SizePolicy::Minimal) { + auto area = child->getLayout()->getArea(); + area.size[!vertical] = getArea().size[!vertical] - mLayoutMargin * 2; + child->setAreaCache(area); + // } } // set pos halnf iterPos = mLayoutMargin; for (auto child : children()) { - RectF area = lay(child)->getArea(); + auto area = child->getLayout()->getArea(); area.pos[vertical] = iterPos; area.pos[!vertical] = mLayoutMargin; iterPos += area.size[vertical] + mLayoutGap; - lay(child)->setArea(area); + child->setAreaCache(area); + + // child->updateAnimations(); + // child->triggerWidgetUpdate("layout changed"); } } -RectF BasicLayout::availableChildArea() const { - auto out = WidgetLayout::availableChildArea(); +RectF BasicLayout::getAvailableChildArea() const { + auto out = WidgetLayout::getAvailableChildArea(); return out.shrinkFromCenter(mLayoutMargin, true); -} - -RectF BasicLayout::minContentArea() const { - auto out = WidgetLayout::getChildrenEnclosure(); - out.shrinkFromCenter(-mLayoutMargin, true); - return out; } \ No newline at end of file diff --git a/Widgets/private/layouts/DockLayout.cpp b/Widgets/private/layouts/DockLayout.cpp index 20ab1c2..e4c60d7 100644 --- a/Widgets/private/layouts/DockLayout.cpp +++ b/Widgets/private/layouts/DockLayout.cpp @@ -61,8 +61,6 @@ void DockLayout::toggleWidgetVisibility(Side side) { void DockLayout::calculateSideAreas() { auto startArea = getArea().relative(); - if (startArea.size.x <= 0 || startArea.size.y <= 0) return; - for (auto& sideWidget : mSideWidgets) { const auto side = sideWidget.order; @@ -101,13 +99,11 @@ void DockLayout::calculateResizeHandles() { RectF area = getArea().relative(); for (auto& sideWidget : mSideWidgets) { - if (!sideWidget.widget) continue; - auto& sideSize = sideWidget.absoluteSize; auto& resizeHandle = sideWidget.resizeHandle; if (resizeHandle.end < mSideSizePadding * 2) { - // sideSize = resizeHandle.end / 2.f; + sideSize = resizeHandle.end / 2.f; } else { sideSize = clamp(sideSize, resizeHandle.start + mSideSizePadding, resizeHandle.end - mSideSizePadding); } @@ -188,7 +184,7 @@ auto DockLayout::getSideFromWidget(Widget* widget) -> Side { return DockLayout::NONE; } -void DockLayout::arrangeChildren(bool vertical) { +void DockLayout::updateLayout(bool vertical) { for (auto child : children()) { child->getLayout()->pickRect(vertical); } diff --git a/Widgets/private/layouts/OverlayLayout.cpp b/Widgets/private/layouts/OverlayLayout.cpp index 1630117..e30ce16 100644 --- a/Widgets/private/layouts/OverlayLayout.cpp +++ b/Widgets/private/layouts/OverlayLayout.cpp @@ -5,7 +5,7 @@ using namespace tp; -void OverlayLayout::arrangeChildren(bool vertical) { +void OverlayLayout::updateLayout(bool vertical) { if (vertical) return; if (children().empty()) return; diff --git a/Widgets/private/layouts/ScrollableLayout.cpp b/Widgets/private/layouts/ScrollableLayout.cpp index 100977d..43f9c39 100644 --- a/Widgets/private/layouts/ScrollableLayout.cpp +++ b/Widgets/private/layouts/ScrollableLayout.cpp @@ -5,7 +5,7 @@ using namespace tp; -void ScrollableLayout::arrangeChildren(bool vertical) { +void ScrollableLayout::updateLayout(bool vertical) { if (vertical) return; // TODO : make better interface to get scroller and content widget @@ -30,9 +30,9 @@ void ScrollableLayout::updateWidgetRects(const RectF& area, Widget* content, Scr auto sizeFactor = (area.size[dir] / content->getLayout()->getArea().size[dir]); auto splitFactor = 1 - ((sizeFactor > 1.f) ? 0 : mScrollerSize / area.size[!dir]); - auto holderArea = dir ? area.splitByFactorHL(splitFactor) : area.splitByFactorVT(splitFactor); + auto holderArea = area.splitByFactorHL(splitFactor); auto contentArea = content->getLayout()->getArea(); - auto scrollerArea = dir ? area.splitByFactorHR(splitFactor) : area.splitByFactorVB(splitFactor); + auto scrollerArea = area.splitByFactorHR(splitFactor); scroller->updateSizeFactor(sizeFactor); @@ -44,7 +44,7 @@ void ScrollableLayout::updateWidgetRects(const RectF& area, Widget* content, Scr content->getLayout()->setArea(contentArea); } -RectF ScrollableLayout::availableChildArea() const { +RectF ScrollableLayout::getAvailableChildArea() const { auto out = getArea(); // dont constrain on scroll axis out.pos = -FLT_MAX / 4; diff --git a/Widgets/private/managers/DebugManager.cpp b/Widgets/private/managers/DebugManager.cpp index bd0de0a..0e390fe 100644 --- a/Widgets/private/managers/DebugManager.cpp +++ b/Widgets/private/managers/DebugManager.cpp @@ -3,26 +3,28 @@ #include "BasicLayout.hpp" #include "imgui.h" -#include "implot.h" - #include using namespace tp; DebugManager tp::gDebugWidget; -#define LIST_SIZE \ - { -FLT_MIN, 150 } +#define LIST_SIZE { -FLT_MIN, 150 } -void DebugManager::update(RootWidget* rootWidget, EventHandler& events) { +bool DebugManager::update(RootWidget* rootWidget, EventHandler& events) { mRootWidget = rootWidget; events.setEnableKeyEvents(true); if (events.isPressed(InputID::D)) mDebug = !mDebug; if (mDebug) { + auto area = rootWidget->mRoot.getAreaT(); + area.size -= { 400, 0 }; + rootWidget->mRoot.setArea(area); + events.setEnableKeyEvents(true); if (events.isPressed(InputID::K)) mDebugStopProcessing = !mDebugStopProcessing; + if (mDebugStopProcessing) return false; if (auto widget = rootWidget->mUpdateManager.mInFocusWidget) { if (auto lay = dynamic_cast(widget->getLayout())) { @@ -47,6 +49,8 @@ void DebugManager::update(RootWidget* rootWidget, EventHandler& events) { if (events.isPressed(InputID::L)) mLayBreakpoints.insert(breakWidget); } } + + return true; } void DebugManager::drawDebug(RootWidget* rootWidget, Canvas& canvas) { @@ -56,24 +60,20 @@ void DebugManager::drawDebug(RootWidget* rootWidget, Canvas& canvas) { return; } - drawPerformance(); - // ImGui::Checkbox("Draw debug", &mDebug); - ImGui::SameLine(); - ImGui::Text("To Toggle processing press k"); + ImGui::SameLine(); ImGui::Text("To Toggle processing press k"); auto& upd = rootWidget->mUpdateManager; + recursiveDraw(canvas, &rootWidget->mRoot, { 0, 0 }, 0); + ImGui::Text("Triggered: %i", (int) upd.mTriggeredWidgets.size()); - ImGui::SameLine(); - ImGui::Text("Processing: %i", upd.mDebugWidgetsToProcess); + ImGui::SameLine(); ImGui::Text("Processing: %i", upd.mDebugWidgetsToProcess); ImGui::Checkbox("Stop processing", &mDebugStopProcessing); - ImGui::SameLine(); - ImGui::Checkbox("Force new frames", &mDebugRedrawAlways); - ImGui::SameLine(); - ImGui::Checkbox("Detailed", &mDetailed); + ImGui::SameLine(); ImGui::Checkbox("Force new frames", &mDebugRedrawAlways); + ImGui::SameLine(); ImGui::Checkbox("Slow-mo", &mSlowMotion); if (upd.mInFocusWidget) { ImGui::Text("Under cursor"); @@ -87,21 +87,17 @@ void DebugManager::drawDebug(RootWidget* rootWidget, Canvas& canvas) { } } - if (mDetailed) { - ImGui::Text("Triggered"); - { - if (ImGui::BeginListBox("##triggered", LIST_SIZE)) { - for (auto widget : upd.mTriggeredWidgets) { - widgetMenu(widget.first); - } - ImGui::EndListBox(); + ImGui::Text("Triggered"); + { + if (ImGui::BeginListBox("##triggered", LIST_SIZE)) { + for (auto widget : upd.mTriggeredWidgets) { + widgetMenu(widget.first); } + ImGui::EndListBox(); } - - drawLayoutOrder(); - - recursiveDraw(canvas, &rootWidget->mRoot, { 0, 0 }, 0); } + + drawLayoutOrder(); } void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& pos, int depthOrder) { @@ -113,17 +109,14 @@ void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& po canvas.text((active->mDebug.id + ":" + std::to_string(depthOrder)).c_str(), area, 22, Canvas::Align::LC, 2, color); } - if (active == mRootWidget->mUpdateManager.mFocusLockWidget) { - canvas.frame(area, { 0, 1, 0, 1 }); - } - if (active->mFlags.get(Widget::IN_FOCUS)) { if (active->isUpdate()) { canvas.circle(pos + active->mDebug.pLocal, 5, active->mDebug.col); canvas.circle(active->mDebug.pGlobal, 15, active->mDebug.col); } - canvas.debugCross(area, { 0, 1, 0, 1 }); + RGBA color = { 1, 0, 0, 0.3f }; + canvas.debugCross(area, color); } int orderIdx = 0; @@ -181,14 +174,4 @@ void DebugManager::drawLayoutOrder() { } ImGui::EndListBox(); } -} - -void DebugManager::drawPerformance() { - if (ImPlot::BeginPlot("Per Frame Time")) { - ImPlot::PlotLine("Proc ms", mProcTime.get(), mProcTime.size()); - ImPlot::PlotLine("Draw ms", mDrawTime.get(), mDrawTime.size()); - ImPlot::PlotLine("UPD ms", mUpdManager.get(), mUpdManager.size()); - ImPlot::PlotLine("LAY ms", mLayManager.get(), mLayManager.size()); - ImPlot::EndPlot(); - } } \ No newline at end of file diff --git a/Widgets/private/managers/LayoutManager.cpp b/Widgets/private/managers/LayoutManager.cpp index 87ff23a..749b7e6 100644 --- a/Widgets/private/managers/LayoutManager.cpp +++ b/Widgets/private/managers/LayoutManager.cpp @@ -3,7 +3,6 @@ #include "DockLayout.hpp" #include "ScrollableLayout.hpp" -#include "BasicLayout.hpp" #include @@ -34,11 +33,7 @@ void LayoutManager::findDependencies(Widget* root) { Widget::dfs(root, [this](Widget* widget) { mDepGraph.insert({ widget, {} }); }); for (auto& [widget, deps] : mDepGraph) { - if (!widget->isUpdate()) continue; - for (auto child : widget->mChildren) { - if (!child->isUpdate()) continue; - mDepGraph.insert({ child, {} }); if (auto depOrder = getLayoutOrder(widget->getLayout(), child->getLayout())) { @@ -79,7 +74,7 @@ void LayoutManager::adjustLayouts() { }); for (auto& [iter, _] : mLayOrder) { - iter->getLayout()->arrangeChildren(mVertical); + iter->getLayout()->updateLayout(mVertical); } } @@ -93,13 +88,10 @@ static int sizePolicyDep[3][3] = { int LayoutManager::getLayoutOrder(WidgetLayout* parent, WidgetLayout* child) const { if (!parent || !child) return 0; - return 1; - auto policyParent = parent->getSizePolicy()[mVertical]; auto policyChild = parent->getSizePolicy()[mVertical]; - // if (dynamic_cast(parent)) return -1; - // if (dynamic_cast(parent)) return -1; + if (dynamic_cast(parent)) return -1; // if (dynamic_cast(parent)) return -1; return sizePolicyDep[int(policyParent)][int(policyChild)]; diff --git a/Widgets/private/managers/UpdateManager.cpp b/Widgets/private/managers/UpdateManager.cpp index c02c8e7..4dcf24c 100644 --- a/Widgets/private/managers/UpdateManager.cpp +++ b/Widgets/private/managers/UpdateManager.cpp @@ -69,36 +69,26 @@ void UpdateManager::getWidgetPath(Widget* widget, std::vector& out) { } } -Widget* UpdateManager::findFocusWidget(Widget* root, EventHandler& events) { +void UpdateManager::handleFocusChanges(Widget* root, EventHandler& events) { + auto prevFocus = mInFocusWidget; + events.setCursorOrigin({ 0, 0 }); mInFocusWidget = nullptr; - findMouseFocusWidget(root, &mInFocusWidget, events.getPointer()); - if (mFocusLockWidget) { - bool hasLockedWidget = false; - for (auto iter = mInFocusWidget; iter; iter = iter->mParent) { - if (iter == mFocusLockWidget) { - hasLockedWidget = true; - break; - } - } - if (!hasLockedWidget) { - mInFocusWidget = mFocusLockWidget; - } + if (!mFocusLockWidget) { + findFocusWidget(root, &mInFocusWidget, events.getPointer()); + } else { + mInFocusWidget = mFocusLockWidget; } - return mInFocusWidget; -} - -void UpdateManager::handleFocusChanges(Widget* active, Widget* prevActive) { // if (mInFocusWidget == prevFocus) return; - if (active) scheduleUpdate(active, "focus entered"); + if (mInFocusWidget) scheduleUpdate(mInFocusWidget, "focus entered"); - if (!active && !prevActive) return; + if (!mInFocusWidget && !prevFocus) return; std::vector path2; - getWidgetPath(active, path2); + getWidgetPath(mInFocusWidget, path2); size_t propLen2 = path2.size(); for (auto i = 0; i < path2.size(); i++) { if (!path2[i]->propagateEventsToChildren()) { @@ -108,7 +98,7 @@ void UpdateManager::handleFocusChanges(Widget* active, Widget* prevActive) { } std::vector path1; - getWidgetPath(prevActive, path1); + getWidgetPath(prevFocus, path1); size_t propLen1 = path1.size(); for (auto i = 0; i < path1.size(); i++) { if (!path1[i]->propagateEventsToChildren()) { @@ -136,7 +126,7 @@ void UpdateManager::handleFocusChanges(Widget* active, Widget* prevActive) { } } -void UpdateManager::findMouseFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer) { +void UpdateManager::findFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer) { if (!iter->mArea.getTargetRect().isInside(pointer) || !iter->mFlags.get(Widget::ENABLED)) return; if (iter->processesEvents()) { @@ -144,7 +134,7 @@ void UpdateManager::findMouseFocusWidget(Widget* iter, Widget** focus, const Vec } for (auto child = iter->mDepthOrder.lastNode(); child; child = child->prev) { - findMouseFocusWidget(child->data, focus, pointer - iter->mArea.getTargetRect().pos); + findFocusWidget(child->data, focus, pointer - iter->mArea.getTargetRect().pos); } } @@ -216,6 +206,6 @@ void UpdateManager::lockFocus(tp::Widget* widget) { } void UpdateManager::freeFocus(tp::Widget* widget) { - DEBUG_ASSERT(mFocusLockWidget == widget) + // DEBUG_ASSERT(mFocusLockWidget == widget) mFocusLockWidget = nullptr; } \ No newline at end of file diff --git a/Widgets/private/widgets/DockWidget.cpp b/Widgets/private/widgets/DockWidget.cpp index a4a9bc3..565d087 100644 --- a/Widgets/private/widgets/DockWidget.cpp +++ b/Widgets/private/widgets/DockWidget.cpp @@ -80,11 +80,9 @@ void DockWidget::process(const EventHandler& events) { if (events.isPressed(InputID::MOUSE1)) { if (layout()->startResize(events.getPointer())) { triggerWidgetUpdate("dock layout resizing"); - lockFocus(); } } else if (events.isReleased(InputID::MOUSE1)) { layout()->endResize(); - freeFocus(); } if (layout()->isResizing()) { diff --git a/Widgets/private/widgets/FloatingWidget.cpp b/Widgets/private/widgets/FloatingWidget.cpp index 72eae98..0a8579a 100644 --- a/Widgets/private/widgets/FloatingWidget.cpp +++ b/Widgets/private/widgets/FloatingWidget.cpp @@ -47,3 +47,30 @@ FloatingLayout* FloatingWidget::layout() { return dynamic_cast( const FloatingLayout* FloatingWidget::layout() const { return dynamic_cast(Widget::getLayout()); } + +FloatingMenu::FloatingMenu() : FloatingWidget() { + setDebug("float menu", { 0.0, 0.9, 0.1, 0.7 }); + + // addChild(&mMenuLayout); + + addChild(&mHeader); + addChild(&mBodyLayout); + + mHeader.setText("Menu"); + + mHeader.setSizePolicy(SizePolicy::Expanding, SizePolicy::Minimal); + mBodyLayout.setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding); + + mBodyLayout.setLayout(new ScrollableLayout(&mBodyLayout)); + mBodyLayout.addChild(&mScrollBar); + mBodyLayout.addChild(&mContentWidget); + + mContentWidget.setSizePolicy(SizePolicy::Minimal, SizePolicy::Minimal); + + // getLayout()->setLayoutPolicy(LayoutPolicy::Vertical); + // mBodyLayout.getLayout()->setLayoutPolicy(LayoutPolicy::Vertical); +} + +void FloatingMenu::setText(const std::string& text) { + mHeader.setText(text); +} diff --git a/Widgets/private/widgets/MenuWidgets.cpp b/Widgets/private/widgets/MenuWidgets.cpp deleted file mode 100644 index 56f2dc4..0000000 --- a/Widgets/private/widgets/MenuWidgets.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "MenuWidgets.hpp" - -#include "ScrollableLayout.hpp" - -using namespace tp; - -CollapsingMenuWidget::CollapsingMenuWidget() { - setDebug("Collapsing Menu", {1}); - - setSizePolicy(SizePolicy::Expanding, SizePolicy::Minimal); - - addChild(&mHeader); - addChild(&mContent); -} - -void CollapsingMenuWidget::process(const EventHandler& events) { - mHover = mHeader.getArea().isInside(events.getPointer()); - - if (events.isPressed(InputID::MOUSE1) && mHover) setCollapsed(!mContent.getEnabled()); -} - -void CollapsingMenuWidget::setCollapsed(bool collapsed) { - mContent.setEnabled(collapsed); -} - -void CollapsingMenuWidget::draw(Canvas& canvas) { - canvas.rect(getArea().relative(), colorBG, rounding); - if (mHover) { - canvas.rect(mHeader.getArea(), colorHover, rounding); - } -} - -FloatingScrollableMenu::FloatingScrollableMenu() : FloatingWidget() { - setDebug("float menu", { 0.0, 0.9, 0.1, 0.7 }); - - // addChild(&mMenuLayout); - - addChild(&mHeader); - addChild(&mBodyLayout); - - mHeader.setText("Menu"); - - mHeader.setSizePolicy(SizePolicy::Expanding, SizePolicy::Minimal); - mBodyLayout.setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding); - - mBodyLayout.setLayout(new ScrollableLayout(&mBodyLayout)); - mBodyLayout.addChild(&mScrollBar); - mBodyLayout.addChild(&mContentWidget); - - mContentWidget.setSizePolicy(SizePolicy::Minimal, SizePolicy::Minimal); - - // getLayout()->setLayoutPolicy(LayoutPolicy::Vertical); - // mBodyLayout.getLayout()->setLayoutPolicy(LayoutPolicy::Vertical); -} - -void FloatingScrollableMenu::setText(const std::string& text) { - mHeader.setText(text); -} diff --git a/Widgets/private/widgets/ScrollableWidget.cpp b/Widgets/private/widgets/ScrollableWidget.cpp index 81836c1..6497947 100644 --- a/Widgets/private/widgets/ScrollableWidget.cpp +++ b/Widgets/private/widgets/ScrollableWidget.cpp @@ -1,16 +1,13 @@ #include "ScrollableWidget.hpp" -#include "ScrollableLayout.hpp" -#include "BasicLayout.hpp" using namespace tp; void ScrollableBarWidget::process(const EventHandler& events) { // all content is visible no need to process anything if (mSizeFactor >= 1) { - if (mScrolling) freeFocus(); - mScrolling = false; mPosFactor = mSizeFactor / 2.f; + freeFocus(); return; } @@ -87,21 +84,4 @@ void ScrollableBarWidget::updateHandleRect() { const RectF& ScrollableBarWidget::getHandleRect() const { return mHandleRect; -} - -ScrollableWidget::ScrollableWidget() { - addChild(&mScroller); - addChild(&mContent); - - setLayout(new ScrollableLayout(this)); - - mContent.setSizePolicy(SizePolicy::Minimal, SizePolicy::Minimal); -} - -void ScrollableWidget::setDirection(bool direction) { - if (auto lay = dynamic_cast(mContent.getLayout())) { - lay->setLayoutPolicy(direction ? LayoutPolicy::Vertical : LayoutPolicy::Horizontal); - } - - mScroller.setDirection(direction); -} +} \ No newline at end of file diff --git a/Widgets/private/widgets/SimpleWidgets.cpp b/Widgets/private/widgets/SimpleWidgets.cpp index ca74076..cdd2c33 100644 --- a/Widgets/private/widgets/SimpleWidgets.cpp +++ b/Widgets/private/widgets/SimpleWidgets.cpp @@ -107,7 +107,7 @@ void SliderWidget::process(const EventHandler& events) { } void SliderWidget::draw(Canvas& canvas) { - canvas.rect(getRelativeArea(), mColorBG, mRounding); + canvas.rect(getArea().relative(), mColorBG, mRounding); switch (mState) { case IDLE: canvas.rect(getHandleArea(), mColorIdle, mRounding); break; diff --git a/Widgets/public/Layout.hpp b/Widgets/public/Layout.hpp index 9c570dc..2b437fe 100644 --- a/Widgets/public/Layout.hpp +++ b/Widgets/public/Layout.hpp @@ -26,20 +26,11 @@ namespace tp { explicit WidgetLayout(Widget* widget) { mWidget = widget; } virtual ~WidgetLayout() = default; - public: - // picks own position and size - // modifies only own area + virtual void updateLayout(bool vertical) {} + virtual void pickRect(bool vertical) {} - - // arranges all children layouts inside itself - // modifies children areas - virtual void arrangeChildren(bool vertical) {} - - // area that any child can have - [[nodiscard]] virtual RectF availableChildArea() const; - - // minimal size base on the content of the layout - [[nodiscard]] virtual RectF minContentArea() const; + virtual void clampRect() {} + [[nodiscard]] virtual RectF getAvailableChildArea() const; public: const Vec2F& getMinSize(); @@ -48,8 +39,6 @@ namespace tp { [[nodiscard]] const Vec2& getSizePolicy() const; void setSizePolicy(SizePolicy x, SizePolicy y); - static WidgetLayout* lay(Widget* w); - public: [[nodiscard]] const RectF& getArea() const; [[nodiscard]] RectF getAnimatedArea() const; @@ -60,7 +49,6 @@ namespace tp { public: void clampMinMaxSize(); - void pickMinimalRect(bool dir); [[nodiscard]] RangeF pickRange(const RangeF& current, const RangeF& child, const RangeF& parent, bool v) const; [[nodiscard]] RangeF clampRange(const RangeF& current, const RangeF& child, const RangeF& parent, bool v) const; @@ -73,7 +61,7 @@ namespace tp { protected: Vec2 mSizePolicy = { SizePolicy::Fixed, SizePolicy::Fixed }; - Vec2F mMinSize = { 30, 30 }; + Vec2F mMinSize = { 50, 50 }; Vec2F mMaxSize = { FLT_MAX / 2, FLT_MAX / 2 }; private: diff --git a/Widgets/public/RootWidget.hpp b/Widgets/public/RootWidget.hpp index d66b1b0..75f5dbd 100644 --- a/Widgets/public/RootWidget.hpp +++ b/Widgets/public/RootWidget.hpp @@ -18,6 +18,8 @@ namespace tp { void setRootWidget(Widget* widget); static void setWidgetArea(Widget& widget, const RectF& rect); + [[nodiscard]] bool isDebug() const; + // Graphic Application Interface public: void processFrame(EventHandler* events, const RectF& screenArea); diff --git a/Widgets/public/Widget.hpp b/Widgets/public/Widget.hpp index 77c1c50..6c3ca28 100644 --- a/Widgets/public/Widget.hpp +++ b/Widgets/public/Widget.hpp @@ -31,8 +31,6 @@ namespace tp { using DFSAction = std::function; - protected: - enum Flags : int1 { ENABLED = 0, NEEDS_UPDATE, @@ -61,7 +59,6 @@ namespace tp { void setSizePolicy(SizePolicy x, SizePolicy y); void setEnabled(bool val) { mFlags.set(ENABLED, val); } - [[nodiscard]] bool getEnabled() const { return mFlags.get(ENABLED); } WidgetLayout* getLayout(); [[nodiscard]] const WidgetLayout* getLayout() const; diff --git a/Widgets/public/WidgetApplication.hpp b/Widgets/public/WidgetApplication.hpp index 8f6c697..3548c6e 100644 --- a/Widgets/public/WidgetApplication.hpp +++ b/Widgets/public/WidgetApplication.hpp @@ -9,24 +9,41 @@ namespace tp { public: WidgetApplication() = default; - void setRoot(Widget* widget); + void setRoot(Widget* widget) { + mRootWidget.setRootWidget(widget); + } private: - void processFrame(EventHandler* eventHandler, halnf deltaTime) override; + void processFrame(EventHandler* eventHandler, halnf deltaTime) override { + const auto rec = RectF({ 0, 0 }, mWindow->getSize()); - void drawFrame(Canvas* canvas) override; - bool forceNewFrame() override ; + Timer timer; + mRootWidget.processFrame(eventHandler, rec); + mProcTime = timer.timePassed(); + } + + void drawFrame(Canvas* canvas) override { + Timer timer; + mRootWidget.drawFrame(*canvas); + mDrawTime = timer.timePassed(); + + if (mRootWidget.isDebug()) { + drawDebug(); + debugUI(); + } + } + + bool forceNewFrame() override { + return mRootWidget.needsUpdate(); + } private: void debugUI(); private: - halnf mDebugSplitFactor = 0.7; + time_ms mProcTime = 0; + time_ms mDrawTime = 0; RootWidget mRootWidget; - - private: - RectF mGuiArea; - RectF mDebugArea; }; } \ No newline at end of file diff --git a/Widgets/public/layouts/BasicLayout.hpp b/Widgets/public/layouts/BasicLayout.hpp index 9660e1e..185e154 100644 --- a/Widgets/public/layouts/BasicLayout.hpp +++ b/Widgets/public/layouts/BasicLayout.hpp @@ -10,21 +10,17 @@ namespace tp { public: explicit BasicLayout(Widget* widget) : WidgetLayout(widget) {} - void arrangeChildren(bool vertical) override; + void updateLayout(bool vertical) override; void pickRect(bool vertical) override; - - [[nodiscard]] RectF availableChildArea() const override; - [[nodiscard]] RectF minContentArea() const override; + void clampRect() override; + [[nodiscard]] RectF getAvailableChildArea() const override; void setLayoutPolicy(LayoutPolicy layout) { mLayoutPolicy = layout; } - private: - static bool canChange(Widget*, bool); - private: void adjustLayout(bool vertical); - static halnf shrinkLayoutSize(WidgetLayout* widget, halnf diff, bool vertical); + static halnf changeChildSize(Widget*, halnf diff, bool vertical); private: LayoutPolicy mLayoutPolicy = LayoutPolicy::Vertical; diff --git a/Widgets/public/layouts/DockLayout.hpp b/Widgets/public/layouts/DockLayout.hpp index b999e05..e5b49ab 100644 --- a/Widgets/public/layouts/DockLayout.hpp +++ b/Widgets/public/layouts/DockLayout.hpp @@ -43,7 +43,8 @@ namespace tp { public: void pickRect(bool vertical) override {} - void arrangeChildren(bool vertical) override; + void clampRect() override {}; + void updateLayout(bool vertical) override; void adjustChildrenRect(); public: @@ -95,7 +96,7 @@ namespace tp { bool mResizing = false; Widget* mCenterWidget = nullptr; - RectF mCenterArea { 0, 0, 10, 10 }; + RectF mCenterArea {}; // Parameters const halnf mHandleSplitFactor = 0.3; diff --git a/Widgets/public/layouts/OverlayLayout.hpp b/Widgets/public/layouts/OverlayLayout.hpp index 2b1b3bc..e674327 100644 --- a/Widgets/public/layouts/OverlayLayout.hpp +++ b/Widgets/public/layouts/OverlayLayout.hpp @@ -10,8 +10,9 @@ namespace tp { public: explicit OverlayLayout(Widget* widget) : WidgetLayout(widget) {} - void arrangeChildren(bool vertical) override; + void updateLayout(bool vertical) override; void pickRect(bool vertical) override {} + void clampRect() override {} }; } \ No newline at end of file diff --git a/Widgets/public/layouts/ScrollableLayout.hpp b/Widgets/public/layouts/ScrollableLayout.hpp index d4d0916..329131e 100644 --- a/Widgets/public/layouts/ScrollableLayout.hpp +++ b/Widgets/public/layouts/ScrollableLayout.hpp @@ -12,8 +12,8 @@ namespace tp { setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding); } - void arrangeChildren(bool vertical) override; - [[nodiscard]] RectF availableChildArea() const override; + void updateLayout(bool vertical) override; + [[nodiscard]] RectF getAvailableChildArea() const override; private: void updateWidgetRects(const RectF& area, Widget* content, ScrollableBarWidget* scroller) const; diff --git a/Widgets/public/mangers/DebugManager.hpp b/Widgets/public/mangers/DebugManager.hpp index 6c84ef8..938fd6f 100644 --- a/Widgets/public/mangers/DebugManager.hpp +++ b/Widgets/public/mangers/DebugManager.hpp @@ -5,56 +5,12 @@ #include namespace tp { - class DebugTimeline { - enum { - STEP = 10, - LEN = 200, - }; - - public: - DebugTimeline() = default; - - void addSample(time_ms time) { - samples[end] = time; - start++; - end++; - shift(); - } - - [[nodiscard]] int size() const { - return LEN - STEP; - } - - [[nodiscard]] const time_ms* get() const { - return samples + start; - } - - private: - void shift() { - if (end >= LEN) { - for (ualni i = STEP; i < LEN; i++) { - samples[i - STEP] = samples[i]; - } - start = 0; - end = LEN - STEP; - } - } - - private: - ualni start = 0; - ualni end = LEN - STEP; - - time_ms samples[LEN + 1] {}; - }; - class DebugManager { public: DebugManager() = default; - [[nodiscard]] bool isFrozen() const { return mDebugStopProcessing; } - [[nodiscard]] bool isRedrawAlways() const { return mDebugRedrawAlways; } - - void update(RootWidget* rootWidget, EventHandler& events); + bool isRedrawAlways() const { return mDebugRedrawAlways; } + bool update(RootWidget* rootWidget, EventHandler& events); void drawDebug(RootWidget* rootWidget, Canvas& canvas); void checkProcBreakPoints(Widget* widget) { @@ -76,7 +32,6 @@ namespace tp { private: void recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& pos, int depthOrder); - void drawPerformance(); static void widgetMenu(Widget*); void drawLayoutOrder(); @@ -87,17 +42,10 @@ namespace tp { bool mDebug = false; bool mDebugStopProcessing = false; bool mDebugRedrawAlways = false; - bool mDetailed = true; + bool mSlowMotion = false; std::set mProcBreakpoints; std::set mLayBreakpoints; - - public: - DebugTimeline mProcTime; - DebugTimeline mUpdManager; - DebugTimeline mLayManager; - - DebugTimeline mDrawTime; }; extern DebugManager gDebugWidget; diff --git a/Widgets/public/mangers/UpdateManager.hpp b/Widgets/public/mangers/UpdateManager.hpp index f97ba62..33c5ecf 100644 --- a/Widgets/public/mangers/UpdateManager.hpp +++ b/Widgets/public/mangers/UpdateManager.hpp @@ -25,16 +25,13 @@ namespace tp { void clean(); void updateTreeToProcess(Widget* root); - void handleFocusChanges(Widget* active, Widget* prevActive); - Widget* findFocusWidget(Widget* root, EventHandler& events); + void handleFocusChanges(Widget* root, EventHandler& events); - void findMouseFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer); + void findFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer); static void getWidgetPath(Widget* widget, std::vector& out); void processActiveTree(Widget* iter, EventHandler& events, Vec2F pos); void processFocusItems(EventHandler& events); - Widget* getFocusWidget() { return mInFocusWidget; } - private: static void procWidget(Widget* widget, EventHandler& events, bool withEvents = false); diff --git a/Widgets/public/widgets/FloatingWidget.hpp b/Widgets/public/widgets/FloatingWidget.hpp index 30a5139..71f1686 100644 --- a/Widgets/public/widgets/FloatingWidget.hpp +++ b/Widgets/public/widgets/FloatingWidget.hpp @@ -13,8 +13,10 @@ namespace tp { } void process(const EventHandler& events) override; + void draw(Canvas& canvas) override; + [[nodiscard]] bool needsNextFrame() const override; [[nodiscard]] bool propagateEventsToChildren() const override; @@ -26,4 +28,35 @@ namespace tp { FloatingLayout* layout(); [[nodiscard]] const FloatingLayout* layout() const; }; + + class FloatingMenu : public FloatingWidget { + public: + FloatingMenu(); + + public: + void addToMenu(Widget* widget) { + widget->setSizePolicy(SizePolicy::Expanding, SizePolicy::Minimal); + mContentWidget.addChild(widget); + } + + const List& getContent() { + return mContentWidget.getChildren(); + } + + void clearChildren() { + mContentWidget.clear(); + } + + void setText(const std::string& text); + + private: + // VerticalLayout mMenuLayout; + Widget mBodyLayout; + Widget mContentWidget; + ScrollableBarWidget mScrollBar; + + LabelWidget mHeader; + + // ButtonWidget mTestButton; + }; } \ No newline at end of file diff --git a/Widgets/public/widgets/MenuWidgets.hpp b/Widgets/public/widgets/MenuWidgets.hpp deleted file mode 100644 index 36fcbac..0000000 --- a/Widgets/public/widgets/MenuWidgets.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include "FloatingWidget.hpp" - -namespace tp { - class CollapsingMenuWidget : public Widget { - public: - CollapsingMenuWidget(); - - void process(const EventHandler& events) override; - void draw(Canvas& canvas) override; - [[nodiscard]] bool processesEvents() const override { return true; } - - public: - void setCollapsed(bool val); - LabelWidget* getHeader() { return &mHeader; } - Widget* getContainer() { return &mContent; } - - private: - bool mHover = false; - LabelWidget mHeader; - Widget mContent; - - private: - halnf rounding = 5; - RGBA colorHover = RGBA(0.7); - RGBA colorBG = RGBA(0.3); - }; - - class FloatingScrollableMenu : public FloatingWidget { - public: - FloatingScrollableMenu(); - - public: - void addToMenu(Widget* widget) { - widget->setSizePolicy(SizePolicy::Expanding, SizePolicy::Minimal); - mContentWidget.addChild(widget); - } - - const List& getContent() { - return mContentWidget.getChildren(); - } - - void clearChildren() { - mContentWidget.clear(); - } - - void setText(const std::string& text); - - private: - // VerticalLayout mMenuLayout; - Widget mBodyLayout; - Widget mContentWidget; - ScrollableBarWidget mScrollBar; - - LabelWidget mHeader; - - // ButtonWidget mTestButton; - }; -} \ No newline at end of file diff --git a/Widgets/public/widgets/ScrollableWidget.hpp b/Widgets/public/widgets/ScrollableWidget.hpp index 1903df2..13026ca 100644 --- a/Widgets/public/widgets/ScrollableWidget.hpp +++ b/Widgets/public/widgets/ScrollableWidget.hpp @@ -20,8 +20,6 @@ namespace tp { [[nodiscard]] bool getDirection() const { return mVertical; } [[nodiscard]] halnf getPosFactor() const { return mPosFactor - mSizeFactor / 2; } - void setDirection(bool direction) { mVertical = direction; } - private: [[nodiscard]] const RectF& getHandleRect() const; void updateHandleRect(); @@ -55,13 +53,5 @@ namespace tp { class ScrollableWidget : public Widget { public: ScrollableWidget(); - - void setDirection(bool direction); - - Widget* getContainer() { return &mContent; } - - private: - Widget mContent; - ScrollableBarWidget mScroller; }; } \ No newline at end of file diff --git a/Widgets/public/widgets/SimpleWidgets.hpp b/Widgets/public/widgets/SimpleWidgets.hpp index a55274e..b67ba75 100644 --- a/Widgets/public/widgets/SimpleWidgets.hpp +++ b/Widgets/public/widgets/SimpleWidgets.hpp @@ -71,7 +71,7 @@ namespace tp { void draw(Canvas& canvas) override; [[nodiscard]] bool processesEvents() const override { return true; } - [[nodiscard]] bool needsNextFrame() const override { return mState != IDLE; } + [[nodiscard]] bool needsNextFrame() const override { return mState != SLIDING; } [[nodiscard]] halnf val() const { return mFactor; }