From 476da8bb9232acbe65b6e0e6b083709df0b239c4 Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Wed, 20 Mar 2024 11:31:50 +0300 Subject: [PATCH] Graphics refactor finished --- Graphics/private/Canvas.cpp | 3 ++ Graphics/private/EventHandler.cpp | 12 +++++- Graphics/private/GraphicApplication.cpp | 9 +++-- Graphics/private/Window.cpp | 2 - Graphics/public/EventHandler.hpp | 14 ++++--- Graphics/public/GraphicApplication.hpp | 5 ++- LibraryViewer/applications/Entry.cpp | 51 +++++++++++------------ LibraryViewer/public/GUI.hpp | 22 +++++----- Sketch3D/applications/Entry.cpp | 54 +++++++++++-------------- Sketch3D/public/Sketch3DWidget.hpp | 14 ++++--- Widgets/examples/ExampleGUI.hpp | 32 +++++++-------- Widgets/public/ScrollableWidget.hpp | 6 +-- 12 files changed, 114 insertions(+), 110 deletions(-) diff --git a/Graphics/private/Canvas.cpp b/Graphics/private/Canvas.cpp index 94c5df8..bd74576 100644 --- a/Graphics/private/Canvas.cpp +++ b/Graphics/private/Canvas.cpp @@ -138,8 +138,11 @@ void Canvas::deleteImageHandle(ImageHandle image) { void Canvas::drawBegin() { const auto size = mContext->window->getSize(); nvgBeginFrame(mContext->vg, size.x, size.y, 1.0); + glViewport(0, 0, size.x, size.y); } void Canvas::drawEnd() { + const auto size = mContext->window->getSize(); + glViewport(0, 0, size.x, size.y); nvgEndFrame(mContext->vg); } diff --git a/Graphics/private/EventHandler.cpp b/Graphics/private/EventHandler.cpp index c8fc0d4..af7d924 100644 --- a/Graphics/private/EventHandler.cpp +++ b/Graphics/private/EventHandler.cpp @@ -1,6 +1,8 @@ #include "EventHandler.hpp" +#include + using namespace tp; EventHandler::EventHandler() = default; @@ -23,13 +25,13 @@ InputState::State transitions[4][4] = { { InputState::State::NONE, InputState::State::PRESSED, InputState::State::PRESSED, InputState::State::NONE }, { InputState::State::PRESSED, InputState::State::PRESSED, InputState::State::HOLD, InputState::State::PRESSED }, { InputState::State::HOLD, InputState::State::RELEASED, InputState::State::RELEASED, InputState::State::HOLD }, - { InputState::State::RELEASED, InputState::State::NONE, InputState::State::RELEASED, InputState::State::RELEASED }, + { InputState::State::RELEASED, InputState::State::NONE, InputState::State::NONE, InputState::State::RELEASED }, }; bool transitionsReduce[4][4] = { { true, true, false, true }, { true, true, false, true }, - { true, false, true, true }, + { true, false, false, true }, { true, false, true, true }, }; @@ -69,6 +71,8 @@ void EventHandler::processEvent() { } } + mPointerPressure = mInputStates[(int) InputID::MOUSE1].mCurrentState != InputState::State::NONE; + mMutex.unlock(); } @@ -82,6 +86,10 @@ bool EventHandler::isReleased(InputID id) const { return mInputStates[(int) id].mCurrentState == InputState::State::RELEASED; } +halnf EventHandler::getPointerPressure() const { + return mPointerPressure; +} + bool EventHandler::isDown(InputID id) const { return mInputStates[(int) id].mCurrentState == InputState::State::PRESSED || mInputStates[(int) id].mCurrentState == InputState::State::HOLD; diff --git a/Graphics/private/GraphicApplication.cpp b/Graphics/private/GraphicApplication.cpp index 6e20c8a..3bfd811 100644 --- a/Graphics/private/GraphicApplication.cpp +++ b/Graphics/private/GraphicApplication.cpp @@ -5,6 +5,7 @@ using namespace tp; Application::Application() { mWindow = Window::createWindow(); + mGraphics = new Graphics(mWindow); mDrawTimer.setDuration(1000.f / mDrawPerSecond); mProcTimer.setDuration(1000.f / mProcPerSecond); @@ -12,7 +13,6 @@ Application::Application() { } void Application::run() { - Graphics graphics(mWindow); auto eventHandler = new EventHandler(); mWindow->setEventHandler(eventHandler); @@ -44,11 +44,11 @@ void Application::run() { mDrawTimer.reset(); if (redrawNeeded) { - graphics.drawBegin(); + mGraphics->drawBegin(); - drawFrame(graphics.getCanvas()); + drawFrame(mGraphics->getCanvas()); - graphics.drawEnd(); + mGraphics->drawEnd(); mWindow->draw(); @@ -79,5 +79,6 @@ void Application::drawFrame(Canvas* canvas) { } Application::~Application() { + delete mGraphics; Window::destroyWindow(mWindow); } \ No newline at end of file diff --git a/Graphics/private/Window.cpp b/Graphics/private/Window.cpp index 00ad986..87c54ae 100644 --- a/Graphics/private/Window.cpp +++ b/Graphics/private/Window.cpp @@ -96,8 +96,6 @@ bool Window::shouldClose() const { return glfwWindowShouldClose(mContext->window void Window::processEvents() { glfwWaitEvents(); checkAxisUpdates(); - - glViewport(0, 0, mSize.x, mSize.y); } void Window::draw() { diff --git a/Graphics/public/EventHandler.hpp b/Graphics/public/EventHandler.hpp index 0f4c3a1..a44dbf5 100644 --- a/Graphics/public/EventHandler.hpp +++ b/Graphics/public/EventHandler.hpp @@ -69,11 +69,13 @@ namespace tp { bool isEvents(); void processEvent(); - const Vec2F& getPointer() const; - bool isPressed(InputID id) const; - bool isReleased(InputID id) const; - bool isDown(InputID id) const; - halnf getScrollY() const; + [[nodiscard]] const Vec2F& getPointer() const; + [[nodiscard]] bool isPressed(InputID id) const; + [[nodiscard]] bool isReleased(InputID id) const; + [[nodiscard]] bool isDown(InputID id) const; + [[nodiscard]] halnf getScrollY() const; + + [[nodiscard]] halnf getPointerPressure() const; private: std::mutex mMutex = {}; @@ -83,7 +85,7 @@ namespace tp { // input states Vec2F mPointer; - halnf pressure = 0; + halnf mPointerPressure = 0; InputState mInputStates[(int) InputID::LAST_KEY_CODE]{}; }; diff --git a/Graphics/public/GraphicApplication.hpp b/Graphics/public/GraphicApplication.hpp index 1fed5bf..bc9e930 100644 --- a/Graphics/public/GraphicApplication.hpp +++ b/Graphics/public/GraphicApplication.hpp @@ -18,8 +18,6 @@ namespace tp { virtual ~Application(); protected: - Window* mWindow = nullptr; - bool mInitialized = false; ualni mDrawPerSecond = 60; @@ -34,5 +32,8 @@ namespace tp { halnf mFramesProcessed = 0; halnf mFramesDrawn = 0; + + Graphics* mGraphics = nullptr; + Window* mWindow = nullptr; }; } \ No newline at end of file diff --git a/LibraryViewer/applications/Entry.cpp b/LibraryViewer/applications/Entry.cpp index 696073c..a24a214 100644 --- a/LibraryViewer/applications/Entry.cpp +++ b/LibraryViewer/applications/Entry.cpp @@ -1,6 +1,7 @@ #include "GUI.hpp" #include "Player.hpp" +#include "GraphicApplication.hpp" // 1) artworks // 2) how to easily add more songs? @@ -13,36 +14,38 @@ // 4) queue & repeat & shuffle... // 5) new database with history -void runApp() { +using namespace tp; +class LibraryViewer : public Application { +public: + LibraryViewer() : gui(&library, &player) { + library.loadJson(getHome() + "Library.json"); + library.checkExisting(); + + gui.updateTracks(); + } + + void processFrame(EventHandler* eventHandler) override { + auto rec = RectF{ { 0, 0 }, mWindow->getSize() }; + gui.proc(*eventHandler, rec, rec); + } + + void drawFrame(Canvas* canvas) override { + gui.draw(*canvas); + } + +private: Player player; Library library; - library.loadJson(getHome() + "Library.json"); - library.checkExisting(); + LibraryWidget gui; +}; +void runApp() { tp::GlobalGUIConfig config; tp::gGlobalGUIConfig = &config; - tp::LibraryWidget gui(&library, &player); - - auto window = tp::Window::createWindow(800, 600, "Window 1"); - - if (window) { - while (!window->shouldClose()) { - window->processEvents(); - - auto area = window->getCanvas().getAvaliableArea(); - - gui.proc(window->getEvents(), { area.x, area.y, area.z, area.w }, { area.x, area.y, area.z, area.w }); - gui.draw(window->getCanvas()); - - // tp::sleep(100); - - window->draw(); - } - } - - tp::Window::destroyWindow(window); + LibraryViewer lib; + lib.run(); } int main() { @@ -54,8 +57,6 @@ int main() { return 1; } - tp::HeapAllocGlobal::disableCallstack(); - runApp(); binModule.deinitialize(); diff --git a/LibraryViewer/public/GUI.hpp b/LibraryViewer/public/GUI.hpp index 0c1f46c..9455730 100644 --- a/LibraryViewer/public/GUI.hpp +++ b/LibraryViewer/public/GUI.hpp @@ -26,9 +26,9 @@ namespace tp { if (!mTrack) return; if (!areaParent.isOverlap(area)) return; - if (area.isInside(events.getPos())) { + if (area.isInside(events.getPointer())) { col.set({ 0.15f, 0.15f, 0.15f, 1.f }); - mSelected = events.isReleased(); + mSelected = events.isReleased(InputID::MOUSE1); } else { col.set({ 0.15f, 0.15f, 0.15f, 0.f }); } @@ -94,6 +94,7 @@ namespace tp { if (!this->mVisible) return; if (!mTrack) return; // canvas.rect(this->mArea, { 0.13f, 0.13f, 0.13f, 1.f }, 4.f); + renderUI(); } void renderUI() { @@ -207,11 +208,16 @@ namespace tp { mLibrary = (lib); mPlayer = (player); + updateTracks(); + + mCurrentTrackInfo.mPlayer = mPlayer; + } + + void updateTracks() { + mTracks.clear(); for (auto track : mLibrary->mTraks) { mTracks.append(TrackWidget(&track.data())); } - - mCurrentTrackInfo.mPlayer = mPlayer; } void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { @@ -219,11 +225,6 @@ namespace tp { this->mVisible = this->mArea.isOverlap(areaParent); if (!this->mVisible) return; - mCurrentTrackInfo.renderUI(); - mNeedRedraw = events.isEvent() || mCurrentTrackInfo.songFilter.IsActive(); - - if (!mNeedRedraw) return; - filter(); mSplitView.proc(events, this->mArea, this->mArea); @@ -249,7 +250,6 @@ namespace tp { mSplitView.draw(canvas); mSongList.draw(canvas); mCurrentTrackInfo.draw(canvas); - // mCurrentTrack.proc(canvas); } void filter() { @@ -292,7 +292,5 @@ namespace tp { ScrollableWindow mSongList; TrackInfoWidget mCurrentTrackInfo; TrackWidget mCurrentTrack; - - bool mNeedRedraw = false; }; } \ No newline at end of file diff --git a/Sketch3D/applications/Entry.cpp b/Sketch3D/applications/Entry.cpp index 39d8ac5..8897fb8 100644 --- a/Sketch3D/applications/Entry.cpp +++ b/Sketch3D/applications/Entry.cpp @@ -1,37 +1,35 @@ +#include "GraphicApplication.hpp" + #include "Sketch3D.hpp" - -#include "Graphics.hpp" -#include "Window.hpp" #include "Sketch3DWidget.hpp" -void runApp() { +using namespace tp; +class Sketch3DApplication : public Application { +public: + Sketch3DApplication() : mGui(*mGraphics->getCanvas(), {1920, 1080}) {} + + void processFrame(EventHandler* eventHandler) override { + auto rec = RectF( { 0, 0 }, mWindow->getSize() ); + mGui.proc(*eventHandler, rec, rec); + } + + void drawFrame(Canvas* canvas) override { + mGui.draw(*canvas); + } + +private: + Sketch3DGUI mGui; +}; + + +void runApp() { tp::GlobalGUIConfig config; tp::gGlobalGUIConfig = &config; - auto window = tp::Window::createWindow(800, 600, "Window 1"); - - { - tp::Sketch3DGUI gui(window->getCanvas(), {1920, 1080}); - - if (window) { - while (!window->shouldClose()) { - window->processEvents(); - - auto area = window->getCanvas().getAvaliableArea(); - - gui.proc(window->getEvents(), { area.x, area.y, area.z, area.w }, { area.x, area.y, area.z, area.w }); - gui.draw(window->getCanvas()); - - tp::sleep(10); - - window->draw(); - } - } - } - - tp::Window::destroyWindow(window); + Sketch3DApplication app; + app.run(); } int main() { @@ -43,11 +41,7 @@ int main() { return 1; } - tp::HeapAllocGlobal::disableCallstack(); - runApp(); - // FIXME : leaks in stacktrace itself - binModule.deinitialize(); } \ No newline at end of file diff --git a/Sketch3D/public/Sketch3DWidget.hpp b/Sketch3D/public/Sketch3DWidget.hpp index b1dec9a..b7efa0a 100644 --- a/Sketch3D/public/Sketch3DWidget.hpp +++ b/Sketch3D/public/Sketch3DWidget.hpp @@ -26,21 +26,21 @@ namespace tp { this->mVisible = area.isOverlap(areaParent); if (!this->mVisible) return; - if (!this->mArea.isInside(events.getPos())) { + if (!this->mArea.isInside(events.getPointer())) { return; } - auto crs = (events.getPos() - this->mArea.pos); + auto crs = (events.getPointer() - this->mArea.pos); crs.x /= this->mArea.z; crs.y /= this->mArea.w; crs = (crs - 0.5) * 2; // TODO : make better api for events - Vec2F absolutePos = events.getPos() - this->mArea.pos; + Vec2F absolutePos = events.getPointer() - this->mArea.pos; - if (events.isPressed()) { + if (events.isPressed(InputID::MOUSE1)) { mAction = true; - } else if (events.isReleased()) { + } else if (events.isReleased(InputID::MOUSE1)) { mAction = false; } @@ -48,6 +48,8 @@ namespace tp { Vec2F relativePosPrev = ((mActionPosAbsolutePrev / this->mArea.size) - 0.5f) * 2.f; Vec2F relativeDelta = relativePos - relativePosPrev; + mProject.mCamera.setRatio(this->mArea.w / this->mArea.z); + switch (mMode) { case Mode::MOVE: { if (mAction) mProject.mCamera.move(relativePos, relativePosPrev); @@ -63,7 +65,7 @@ namespace tp { break; } case Mode::DRAW: { - mProject.sample(events.pressure, this->mArea.w / this->mArea.z, crs); + mProject.sample(events.getPointerPressure(), this->mArea.w / this->mArea.z, crs); break; } default: break; diff --git a/Widgets/examples/ExampleGUI.hpp b/Widgets/examples/ExampleGUI.hpp index 9a208c8..49f5e82 100644 --- a/Widgets/examples/ExampleGUI.hpp +++ b/Widgets/examples/ExampleGUI.hpp @@ -181,7 +181,7 @@ namespace tp { } public: - Buffer*> mMessages; + Buffer> mMessages; ScrollableWindow mHistoryView; TextInputWidget mMessage; ButtonWidget mSend; @@ -196,28 +196,28 @@ namespace tp { this->addValue("Padding", "Padding"); // todo : fetch code - mUsers.append(new UserWidget()); - mUsers.append(new UserWidget()); - mUsers.append(new UserWidget()); + mUsers.append(UserWidget()); + mUsers.append(UserWidget()); + mUsers.append(UserWidget()); - mUsers[0]->mArea = { 0, 0, 100, 100 }; - mUsers[1]->mArea = { 0, 0, 100, 100 }; - mUsers[2]->mArea = { 0, 0, 100, 100 }; + mUsers[0].mArea = { 0, 0, 100, 100 }; + mUsers[1].mArea = { 0, 0, 100, 100 }; + mUsers[2].mArea = { 0, 0, 100, 100 }; for (auto message : mUsers) { - mSideView.mContents.append(message.data()); + mSideView.mContents.append(&message.data()); } - mActive.mMessages.append(new MessageWidget()); - mActive.mMessages.append(new MessageWidget()); - mActive.mMessages.append(new MessageWidget()); + mActive.mMessages.append(MessageWidget()); + mActive.mMessages.append(MessageWidget()); + mActive.mMessages.append(MessageWidget()); - mActive.mMessages[0]->mArea = { 0, 0, 100, 100 }; - mActive.mMessages[1]->mArea = { 0, 0, 100, 100 }; - mActive.mMessages[2]->mArea = { 0, 0, 100, 100 }; + mActive.mMessages[0].mArea = { 0, 0, 100, 100 }; + mActive.mMessages[1].mArea = { 0, 0, 100, 100 }; + mActive.mMessages[2].mArea = { 0, 0, 100, 100 }; for (auto message : mActive.mMessages) { - mActive.mHistoryView.mContents.append(message.data()); + mActive.mHistoryView.mContents.append(&message.data()); } } @@ -240,7 +240,7 @@ namespace tp { } public: - Buffer*> mUsers; + Buffer> mUsers; ScrollableWindow mSideView; ActiveChatWidget mActive; SplitView mSplitView; diff --git a/Widgets/public/ScrollableWidget.hpp b/Widgets/public/ScrollableWidget.hpp index c60a1ca..c2702ac 100644 --- a/Widgets/public/ScrollableWidget.hpp +++ b/Widgets/public/ScrollableWidget.hpp @@ -136,11 +136,7 @@ namespace tp { this->addValue("Padding", "Padding"); } - ~ScrollableWindow() { - for (auto content : mContents) { - delete content.data(); - } - } + ~ScrollableWindow() = default; // takes whole area void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {