diff --git a/3DEditor/applications/Entry.cpp b/3DEditor/applications/Entry.cpp index 7c8bc87..bf4c158 100644 --- a/3DEditor/applications/Entry.cpp +++ b/3DEditor/applications/Entry.cpp @@ -22,14 +22,15 @@ public: ~EditorGUI() override { delete mGui; } void processFrame(EventHandler* eventHandler) override { - auto rec = RectF({ 0, 0 }, mWindow->getSize()); - mGui->updateConfigCache(mWidgetManager); - mGui->proc(*eventHandler, rec, rec); + mGui->setArea(rec); + mGui->setVisible(true); + mGui->updateConfigWrapper(mWidgetManager); + mGui->procWrapper(*eventHandler); } - void drawFrame(Canvas* canvas) override { mGui->draw(*canvas); } + void drawFrame(Canvas* canvas) override { mGui->drawWrapper(*canvas); } private: Scene geometry; diff --git a/3DEditor/public/EditorWidget.hpp b/3DEditor/public/EditorWidget.hpp index 4f894a7..c75c839 100644 --- a/3DEditor/public/EditorWidget.hpp +++ b/3DEditor/public/EditorWidget.hpp @@ -16,17 +16,9 @@ namespace tp { ~ViewportWidget() { mCanvas->deleteImageHandle(mImage); } - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; - this->mVisible = areaParent.isOverlap(aArea); - if (!this->mVisible) return; - - mGeometry->mCamera.rotate(0.01f, 0.0); - } - - void draw(Canvas& canvas) override { - if (!this->mVisible) return; + void procCallback(const Events& events) override { mGeometry->mCamera.rotate(0.01f, 0.0); } + void drawCallback(Canvas& canvas) override { mRender.render(*mGeometry, this->mArea.size); canvas.drawImage(this->mArea, &mImage, PI); } @@ -42,32 +34,22 @@ namespace tp { class EditorWidget : public Widget { public: EditorWidget(Canvas* canvas, Scene* geometry, Vec2F renderResolution) : - mViewport(canvas, geometry, renderResolution) {} + mViewport(canvas, geometry, renderResolution) { - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; - this->mVisible = areaParent.isOverlap(aArea); - if (!this->mVisible) return; - - mSplitView.proc(events, aArea, aArea); - mViewport.proc(events, aArea, mSplitView.getFirst()); + this->mChildWidgets.pushBack(&mViewport); + this->mChildWidgets.pushBack(&mSplitView); } - void draw(Canvas& canvas) override { - if (!this->mVisible) return; - - canvas.rect(this->mArea, mBaseColor); - mSplitView.draw(canvas); - mViewport.draw(canvas); + void procCallback(const Events& events) override { + mSplitView.setArea(this->mArea); + mViewport.setArea(mSplitView.getFirst()); } - void updateConfigCache(WidgetManager& wm) override { + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, mBaseColor); } + + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("3DEditor"); - mBaseColor = wm.getColor("Base", "Base"); - - mViewport.updateConfigCache(wm); - mSplitView.updateConfigCache(wm); } public: diff --git a/Containers/public/List.hpp b/Containers/public/List.hpp index 3a36de5..c1fe3d3 100644 --- a/Containers/public/List.hpp +++ b/Containers/public/List.hpp @@ -75,9 +75,12 @@ namespace tp { List(const List& in) { this->operator=(in); } List(const InitialierList& list) { operator=(list); } - [[nodiscard]] inline Node* first() const { return mFirst; } - [[nodiscard]] inline Node* last() const { return mLast; } + [[nodiscard]] inline Type& first() const { return mFirst->data; } + [[nodiscard]] inline Type& last() const { return mLast->data; } + [[nodiscard]] inline Node* firstNode() const { return mFirst; } + [[nodiscard]] inline Node* lastNode() const { return mLast; } [[nodiscard]] inline Index length() const { return mLength; } + [[nodiscard]] inline Index size() const { return length(); } [[nodiscard]] Node* newNode() { return new (mAlloc.allocate(sizeof(Node))) Node(); } [[nodiscard]] Node* newNode(TypeArg arg) { return new (mAlloc.allocate(sizeof(Node))) Node(arg); } @@ -250,8 +253,8 @@ namespace tp { if (in.length() != length()) { return false; } - Node* left = in.first(); - Node* right = first(); + Node* left = in.firstNode(); + Node* right = firstNode(); while (left && right) { if (left->data != right->data) { return false; diff --git a/Graphics/private/EventHandler.cpp b/Graphics/private/EventHandler.cpp index d5b9f40..d8329da 100644 --- a/Graphics/private/EventHandler.cpp +++ b/Graphics/private/EventHandler.cpp @@ -35,10 +35,10 @@ bool transitionsReduce[4][4] = { void EventHandler::processEvent() { mMutex.lock(); - auto lastEvent = mEventQueue.last(); + auto lastEvent = &mEventQueue.last(); - const auto& eventData = lastEvent->data.second; - const auto& inputId = lastEvent->data.first; + const auto& eventData = lastEvent->second; + const auto& inputId = lastEvent->first; switch (eventData.type) { case InputEvent::Type::MOUSE_POS: diff --git a/LibraryViewer/applications/Entry.cpp b/LibraryViewer/applications/Entry.cpp index 2476fc0..a9c0aee 100644 --- a/LibraryViewer/applications/Entry.cpp +++ b/LibraryViewer/applications/Entry.cpp @@ -17,11 +17,13 @@ public: void processFrame(EventHandler* eventHandler) override { auto rec = RectF{ { 0, 0 }, mWindow->getSize() }; - gui.updateConfigCache(mWidgetManager); - gui.proc(*eventHandler, rec, rec); + gui.setVisible(true); + gui.setArea(rec); + gui.updateConfigWrapper(mWidgetManager); + gui.procWrapper(*eventHandler); } - void drawFrame(Canvas* canvas) override { gui.draw(*canvas); } + void drawFrame(Canvas* canvas) override { gui.drawWrapper(*canvas); } private: Player player; diff --git a/LibraryViewer/public/GUI.hpp b/LibraryViewer/public/GUI.hpp index 4befe8a..88e1d2d 100644 --- a/LibraryViewer/public/GUI.hpp +++ b/LibraryViewer/public/GUI.hpp @@ -18,7 +18,7 @@ namespace tp { col.mColor.setNoTransition({ 0.15f, 0.15f, 0.15f, 0.f }); }; - void procBody(const Events& events) override { + void procCallback(const Events& events) override { mSelected = false; if (!mTrack) return; if (this->mArea.isInside(events.getPointer())) { @@ -29,7 +29,7 @@ namespace tp { } } - void drawBody(Canvas& canvas) override { + void drawCallback(Canvas& canvas) override { if (!mTrack) return; canvas.rect(this->mArea, col.get(), 4.f); @@ -76,7 +76,7 @@ namespace tp { items.append({ "Date Last Played" }); } - void drawBody(Canvas&) override { + void drawCallback(Canvas&) override { if (!mTrack) return; // canvas.rect(this->mArea, { 0.13f, 0.13f, 0.13f, 1.f }, 4.f); renderUI(); @@ -196,6 +196,11 @@ namespace tp { updateTracks(); mCurrentTrackInfo.mPlayer = mPlayer; + + this->mChildWidgets.pushBack(&mSplitView); + this->mChildWidgets.pushBack(&mSongList); + this->mChildWidgets.pushBack(&mCurrentTrackInfo); + this->mChildWidgets.pushBack(&mCurrentTrack); } void updateTracks() { @@ -205,36 +210,30 @@ namespace tp { } } - void procBody(const Events& events) override { + void procCallback(const Events& events) override { filter(); - mSplitView.proc(events, this->mArea, this->mArea); - mSongList.proc(events, this->mArea, mSplitView.getFirst()); + mSplitView.setArea(this->mArea); + mSongList.setArea(mSplitView.getFirst()); - for (auto track : mSongList.mContents) { + for (auto track : mSongList.getContent()) { auto trackWidget = (TrackWidget*) track.data(); if (trackWidget->mSelected) { mCurrentTrackInfo.mTrack = trackWidget->mTrack; } } - mCurrentTrackInfo.proc(events, this->mArea, mSplitView.getSecond()); + mCurrentTrackInfo.setArea(mSplitView.getSecond()); // mCurrentTrack.proc(events, this->mArea, mSplitView.getFirst()); } - void drawBody(Canvas& canvas) override { - canvas.rect(this->mArea, { 0.1f, 0.1f, 0.1f, 1.f }); - - mSplitView.draw(canvas); - mSongList.draw(canvas); - mCurrentTrackInfo.draw(canvas); - } + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, { 0.1f, 0.1f, 0.1f, 1.f }); } void filter() { if (!mCurrentTrackInfo.isSongFilterChanged) return; - mSongList.mContents.clear(); + mSongList.clearContent(); for (auto track : mTracks) { if (!mCurrentTrackInfo.songFilter.PassFilter(track->mTrack->mName.c_str()) && @@ -256,20 +255,12 @@ namespace tp { break; } - mSongList.mContents.append(&track.data()); + mSongList.addWidget(&track.data()); } mCurrentTrackInfo.isSongFilterChanged = false; } - void updateConfigCache(WidgetManager& wm) override { - wm.setActiveId("LibraryWidget"); - mSplitView.updateConfigCache(wm); - mCurrentTrack.updateConfigCache(wm); - mCurrentTrackInfo.updateConfigCache(wm); - mSongList.updateConfigCache(wm); - } - private: Library* mLibrary = nullptr; Player* mPlayer = nullptr; diff --git a/Objects/applications/GUI.cpp b/Objects/applications/GUI.cpp index e7eb4b4..97e90c2 100644 --- a/Objects/applications/GUI.cpp +++ b/Objects/applications/GUI.cpp @@ -153,10 +153,10 @@ void obj::ObjectsGUI::cd(obj::Object* child, const std::string& name) { void obj::ObjectsGUI::cdup() { if (mViewStack.length() > 1) { - obj::objects_api::destroy(mViewStack.last()->data.obj); + obj::objects_api::destroy(mViewStack.lastNode()->data.obj); mViewStack.popBack(); - mActive = mViewStack.last()->data.obj; + mActive = mViewStack.lastNode()->data.obj; } } @@ -890,15 +890,15 @@ void obj::ObjectsGUI::explorer() { ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_HorizontalScrollbar ); tp::List rev_path; - for (auto childo = mViewStack.last(); childo; childo = childo->prev) { + for (auto childo = mViewStack.lastNode(); childo; childo = childo->prev) { rev_path.pushBack(&childo->data); } tp::alni idx = 0; - for (auto childo = rev_path.last(); childo; childo = childo->prev) { + for (auto childo = rev_path.lastNode(); childo; childo = childo->prev) { ImGui::PushID((int) idx); bool go_back = false; - if (childo == rev_path.last()) { + if (childo == rev_path.lastNode()) { go_back = ImGui::Button(childo->data->id.c_str()); ImGui::SameLine(); } else { @@ -952,7 +952,7 @@ void obj::ObjectsGUI::explorer() { } if (go_back) { - while (&mViewStack.last()->data != childo->data) { + while (&mViewStack.lastNode()->data != childo->data) { cdup(); } mActive = childo->data->obj; diff --git a/Objects/private/compiler/Functions.cpp b/Objects/private/compiler/Functions.cpp index cbb2b95..cce4ee8 100644 --- a/Objects/private/compiler/Functions.cpp +++ b/Objects/private/compiler/Functions.cpp @@ -543,9 +543,9 @@ void FunctionDefinition::generateByteCode(ByteCode& out) { List::Node* FunctionDefinition::inst(Instruction inst) { mInstructions.pushBack(inst); - auto out = &mInstructions.last()->data; + auto out = &mInstructions.lastNode()->data; out->mInstIdx = (alni) mInstructions.length() - 1; - return mInstructions.last(); + return mInstructions.lastNode(); } void obj::initialize() {} diff --git a/Objects/private/interpreter/ScopeStack.cpp b/Objects/private/interpreter/ScopeStack.cpp index 7ce9189..4022c25 100644 --- a/Objects/private/interpreter/ScopeStack.cpp +++ b/Objects/private/interpreter/ScopeStack.cpp @@ -52,7 +52,7 @@ void ScopeStack::addTemp(obj::Object* tmp) { } void ScopeStack::popTemp() { - objects_api::destroy(mBuff[mIdx - 1].mTemps.last()->data); + objects_api::destroy(mBuff[mIdx - 1].mTemps.last()); mBuff[mIdx - 1].mTemps.popBack(); } diff --git a/Objects/private/primitives/ListObject.cpp b/Objects/private/primitives/ListObject.cpp index 69e5068..73b0a9c 100644 --- a/Objects/private/primitives/ListObject.cpp +++ b/Objects/private/primitives/ListObject.cpp @@ -93,7 +93,7 @@ void ListObject::delNode(tp::List::Node* node) { } void ListObject::popBack() { - auto obj = items.last(); + auto obj = items.lastNode(); if (obj) obj::objects_api::destroy(obj->data); items.popBack(); } diff --git a/Sketch3D/applications/Entry.cpp b/Sketch3D/applications/Entry.cpp index f46a6cb..fe51bd2 100644 --- a/Sketch3D/applications/Entry.cpp +++ b/Sketch3D/applications/Entry.cpp @@ -13,11 +13,14 @@ public: void processFrame(EventHandler* eventHandler) override { auto rec = RectF({ 0, 0 }, mWindow->getSize()); - mGui.updateConfigCache(mWidgetManager); - mGui.proc(*eventHandler, rec, rec); + + mGui.setVisible(true); + mGui.setArea(rec); + mGui.updateConfigWrapper(mWidgetManager); + mGui.procWrapper(*eventHandler); } - void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); } + void drawFrame(Canvas* canvas) override { mGui.drawWrapper(*canvas); } private: WidgetManager mWidgetManager; diff --git a/Sketch3D/private/Sketch3D.cpp b/Sketch3D/private/Sketch3D.cpp index a0a3c63..7c58868 100644 --- a/Sketch3D/private/Sketch3D.cpp +++ b/Sketch3D/private/Sketch3D.cpp @@ -66,7 +66,7 @@ void Stroke::compress(halnf factor) { min_node = nullptr; halnf min_factor = factor; - List::Node* iter = passed_poits.first()->next; + List::Node* iter = passed_poits.firstNode()->next; for (; iter->next; iter = iter->next) { Vec3F dir1 = (iter->data.pos - iter->prev->data.pos).normalize(); Vec3F dir2 = (iter->next->data.pos - iter->data.pos).normalize(); @@ -111,7 +111,7 @@ void Stroke::subdiv(halnf precision, const Camera* cam, halni passes) { auto n_points = new_points.length(); - auto p0 = new_points.first(); + auto p0 = new_points.firstNode(); auto p1 = p0->next; auto p2 = p1->next; auto p3 = p2->next; @@ -234,7 +234,7 @@ void PencilBrush::sample(Project* proj, Vec2F crs, halnf pressure) { mStroke = new Stroke(); mStroke->setColor(mCol); - mStroke->getPoints().append(proj->mLayers[proj->mActiveLayer]->strokes.last()->data->getPoints().last()); + mStroke->getPoints().append(proj->mLayers[proj->mActiveLayer]->strokes.last()->getPoints().last()); } if (!pressure) { diff --git a/Sketch3D/public/Sketch3DWidget.hpp b/Sketch3D/public/Sketch3DWidget.hpp index 942164d..eca1a65 100644 --- a/Sketch3D/public/Sketch3DWidget.hpp +++ b/Sketch3D/public/Sketch3DWidget.hpp @@ -18,12 +18,7 @@ namespace tp { ~Sketch3DWidget() { mCanvas->deleteImageHandle(mImage); } - void proc(const Events& events, const RectF& areaParent, const RectF& area) override { - - this->mArea = area; - this->mVisible = area.isOverlap(areaParent); - if (!this->mVisible) return; - + void procCallback(const Events& events) override { if (!this->mArea.isInside(events.getPointer())) { return; } @@ -76,7 +71,7 @@ namespace tp { mActionPosAbsolutePrev = absolutePos; } - void drawBody(Canvas& canvas) override { + void drawCallback(Canvas& canvas) override { mRenderer.renderToTexture(&mProject, this->mArea.size); canvas.drawImage(this->mArea, &mImage, 0, 1, 12); } @@ -106,31 +101,35 @@ namespace tp { mRotateButton = new ButtonWidget("Rotate view", { 0, 0, 100, 30 }); mZoomButton = new ButtonWidget("Zoom view", { 0, 0, 100, 30 }); - mOptions.mContents.append(mDrawButton); - mOptions.mContents.append(mMoveButton); - mOptions.mContents.append(mRotateButton); - mOptions.mContents.append(mZoomButton); + mOptions.addWidget(mDrawButton); + mOptions.addWidget(mMoveButton); + mOptions.addWidget(mRotateButton); + mOptions.addWidget(mZoomButton); // add color sliders mRed = new NamedSliderWidget("Red"); mGreen = new NamedSliderWidget("Green"); mBlue = new NamedSliderWidget("Blue"); - mOptions.mContents.append(mRed); - mOptions.mContents.append(mGreen); - mOptions.mContents.append(mBlue); + mOptions.addWidget(mRed); + mOptions.addWidget(mGreen); + mOptions.addWidget(mBlue); + + this->mChildWidgets.pushBack(&mViewport); + this->mChildWidgets.pushBack(&mSplitView); + this->mChildWidgets.pushBack(&mOptions); } ~Sketch3DGUI() { - for (auto item : mOptions.mContents) { + for (auto item : mOptions.getContent()) { delete item.data(); } } - void procBody(const Events& events) override { - mSplitView.proc(events, this->mArea, this->mArea); - mViewport.proc(events, this->mArea, mSplitView.getFirst()); - mOptions.proc(events, this->mArea, mSplitView.getSecond()); + void procCallback(const Events& events) override { + mSplitView.setArea(this->mArea); + mViewport.setArea(mSplitView.getFirst()); + mOptions.setArea(mSplitView.getSecond()); if (mDrawButton->mIsPressed) { mViewport.mMode = Sketch3DWidget::Mode::DRAW; @@ -145,23 +144,13 @@ namespace tp { mViewport.setColor(RGBA(mRed->mSlider.mFactor, mGreen->mSlider.mFactor, mBlue->mSlider.mFactor, 1.f)); } - void drawBody(Canvas& canvas) override { - canvas.rect(this->mArea, mBackgroundColor, mRounding); + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, mBackgroundColor, mRounding); } - mSplitView.draw(canvas); - mViewport.draw(canvas); - mOptions.draw(canvas); - } - - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("Sketch3DGui"); mBackgroundColor = wm.getColor("Background", "Background"); mRounding = wm.getNumber("Rounding", "Rounding"); - - mSplitView.updateConfigCache(wm); - mOptions.updateConfigCache(wm); - mViewport.updateConfigCache(wm); } private: diff --git a/Widgets/examples/ChatGUI.cpp b/Widgets/examples/ChatGUI.cpp index 8c7783e..b7fe196 100644 --- a/Widgets/examples/ChatGUI.cpp +++ b/Widgets/examples/ChatGUI.cpp @@ -12,12 +12,14 @@ public: void processFrame(EventHandler* eventHandler) override { auto rec = RectF({ 0, 0 }, mWindow->getSize()); - mGui.updateConfigCache(mWidgetManager); + mGui.updateConfigWrapper(mWidgetManager); + mGui.setArea(rec); + mGui.setVisible(true); - mGui.proc(*eventHandler, rec, rec); + mGui.procWrapper(*eventHandler); } - void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); } + void drawFrame(Canvas* canvas) override { mGui.drawWrapper(*canvas); } private: WidgetManager mWidgetManager; diff --git a/Widgets/examples/ChatGUI.hpp b/Widgets/examples/ChatGUI.hpp index 8ac8d0e..3982887 100644 --- a/Widgets/examples/ChatGUI.hpp +++ b/Widgets/examples/ChatGUI.hpp @@ -9,25 +9,19 @@ namespace tp { public: UserWidget() = default; - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; + void procCallback(const Events& events) override { this->mArea.w = 30; - this->mVisible = areaParent.isOverlap(aArea); - if (!this->mVisible) return; - mIsHover = aArea.isInside(events.getPointer()); + mIsHover = this->mArea.isInside(events.getPointer()); } - void draw(Canvas& canvas) override { - if (!this->mVisible) return; - + void drawCallback(Canvas& canvas) override { if (mIsHover) canvas.rect(this->mArea, mAccentColor, mRounding); else canvas.rect(this->mArea, mBaseColor, mRounding); - canvas.text(mUser.c_str(), this->mArea, mFontSize, Canvas::CC, mPadding, mUserColor); } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("UserWidget"); mBaseColor = wm.getColor("Base", "Base"); @@ -55,16 +49,9 @@ namespace tp { public: MessageWidget() = default; - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; - this->mArea.w = 50; - this->mVisible = areaParent.isOverlap(aArea); - if (!this->mVisible) return; - mIsHover = aArea.isInside(events.getPointer()); - } + void procCallback(const Events& events) override { mIsHover = this->mArea.isInside(events.getPointer()); } - void draw(Canvas& canvas) override { - if (!this->mVisible) return; + void drawCallback(Canvas& canvas) override { if (mIsHover) canvas.rect(this->mArea, mBaseColor, mRounding); auto userName = this->mArea; @@ -78,7 +65,7 @@ namespace tp { canvas.text(mUser.c_str(), userName, mFontSizeDim, Canvas::LC, mPadding, mUserColor); } - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("MessageWidget"); mBaseColor = wm.getColor("Base", "Base"); @@ -111,16 +98,20 @@ namespace tp { mPass.mId = "pass"; mUser.mId = "user"; mButton.mLabel.mLabel = "Login"; + + this->mChildWidgets.pushBack(&mPass); + this->mChildWidgets.pushBack(&mUser); + this->mChildWidgets.pushBack(&mButton); } - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; + void procCallback(const Events& events) override { mLogged = false; - const auto xval = aArea.z / 2 - 100; - mUser.proc(events, aArea, { xval, 10, 200, 30 }); - mPass.proc(events, aArea, { xval, 50, 200, 30 }); - mButton.proc(events, aArea, { xval, 90, 200, 30 }); + const auto xval = this->mArea.z / 2 - 100; + + mUser.setArea({ xval, 10, 200, 30 }); + mPass.setArea({ xval, 50, 200, 30 }); + mButton.setArea({ xval, 90, 200, 30 }); if (mButton.mIsReleased) { mButton.mIsReleased = false; @@ -128,22 +119,12 @@ namespace tp { } } - void draw(Canvas& canvas) override { - canvas.rect(this->mArea, mBGColor); - mButton.draw(canvas); - mUser.draw(canvas); - mPass.draw(canvas); - } + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("LoginWidget"); - mBGColor = wm.getColor("Back", "Base"); - - mUser.updateConfigCache(wm); - mPass.updateConfigCache(wm); - mButton.updateConfigCache(wm); } public: @@ -161,11 +142,13 @@ namespace tp { ActiveChatWidget() { mSend.mLabel.mLabel = "Send"; mMessage.mId = "Message"; + + this->mChildWidgets.pushBack(&mHistoryView); + this->mChildWidgets.pushBack(&mMessage); + this->mChildWidgets.pushBack(&mSend); } - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; - + void procCallback(const Events& events) override { auto history = this->mArea; history.w -= 50; @@ -182,36 +165,22 @@ namespace tp { inputSend.x = inputMessage.x + inputMessage.z + mPadding; inputSend.z = 100 - mPadding * 2; - mSend.proc(events, this->mArea, inputSend); - mMessage.proc(events, this->mArea, inputMessage); + mSend.setArea(inputSend); + mMessage.setArea(inputMessage); if (mSend.mIsReleased) { mSend.mIsReleased = false; } - mHistoryView.proc(events, this->mArea, history); + mHistoryView.setArea(history); } - void draw(Canvas& canvas) override { - canvas.rect(this->mArea, mBGColor); - mHistoryView.draw(canvas); - mMessage.draw(canvas); - mSend.draw(canvas); - } + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); } - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("ActiveChat"); - mBGColor = wm.getColor("Back", "Background"); mPadding = wm.getNumber("Padding", "Padding"); - - mHistoryView.updateConfigCache(wm); - mMessage.updateConfigCache(wm); - mSend.updateConfigCache(wm); - - for (auto message : mMessages) { - message->updateConfigCache(wm); - } } public: @@ -238,49 +207,37 @@ namespace tp { mUsers[2].mArea = { 0, 0, 100, 100 }; for (auto message : mUsers) { - mSideView.mContents.append(&message.data()); + mSideView.addWidget(&message.data()); } 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, 50 }; + mActive.mMessages[1].mArea = { 0, 0, 100, 50 }; + mActive.mMessages[2].mArea = { 0, 0, 100, 50 }; for (auto message : mActive.mMessages) { - mActive.mHistoryView.mContents.append(&message.data()); + mActive.mHistoryView.addWidget(&message.data()); } + + this->mChildWidgets.pushBack(&mSideView); + this->mChildWidgets.pushBack(&mActive); + this->mChildWidgets.pushBack(&mSplitView); } - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; - - mSplitView.proc(events, aArea, aArea); - mSideView.proc(events, this->mArea, mSplitView.getSecond()); - mActive.proc(events, aArea, mSplitView.getFirst()); + void procCallback(const Events& events) override { + mSplitView.setArea(this->mArea); + mSideView.setArea(mSplitView.getSecond()); + mActive.setArea(mSplitView.getFirst()); } - void draw(Canvas& canvas) override { - canvas.rect(this->mArea, mBGColor); - mSplitView.draw(canvas); - mSideView.draw(canvas); - mActive.draw(canvas); - } + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); } - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("ChattingWidget"); - mBGColor = wm.getColor("Back", "Background"); - - mSideView.updateConfigCache(wm); - mActive.updateConfigCache(wm); - mSplitView.updateConfigCache(wm); - - for (auto user : mUsers) { - user->updateConfigCache(wm); - } } public: @@ -295,34 +252,26 @@ namespace tp { template class ComplexWidget : public Widget { public: - ComplexWidget() = default; - - void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { - this->mArea = aArea; - if (mLogged) { - mChatting.proc(events, aArea, aArea); - } else { - mLogin.proc(events, aArea, aArea); - mLogged = mLogin.mLogged; - if (mLogged) { - mChatting.proc(events, aArea, aArea); - } - } + ComplexWidget() { + this->mChildWidgets.pushBack(&mLogin); + this->mChildWidgets.pushBack(&mChatting); } - void draw(Canvas& canvas) override { - canvas.rect(this->mArea, mBGColor); - if (mLogged) mChatting.draw(canvas); - else mLogin.draw(canvas); + void procCallback(const Events& events) override { + mLogged = mLogin.mLogged; + + mLogin.setEnable(!mLogged); + mChatting.setEnable(mLogged); + + mLogin.setArea(this->mArea); + mChatting.setArea(this->mArea); } - void updateConfigCache(WidgetManager& wm) override { + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); } + + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("ChatGui"); - mBGColor = wm.getColor("Back", "Background"); - - mLogin.updateConfigCache(wm); - mChatting.updateConfigCache(wm); } private: diff --git a/Widgets/examples/SimpleGUI.cpp b/Widgets/examples/SimpleGUI.cpp index 142bbf7..6111c17 100644 --- a/Widgets/examples/SimpleGUI.cpp +++ b/Widgets/examples/SimpleGUI.cpp @@ -8,24 +8,24 @@ using namespace tp; class SimpleGUI : public Application { public: SimpleGUI() { - mGui.mContents.append(&mButton); - mGui.mContents.append(&mSlider); - mGui.mContents.append(&mLabel); + mGui.addWidget(&mButton); + mGui.addWidget(&mLabel); + mGui.addWidget(&mSlider); } void processFrame(EventHandler* eventHandler) override { - - mGui.updateConfigCache(mWidgetManager); - - mSlider.updateConfigCache(mWidgetManager); - mLabel.updateConfigCache(mWidgetManager); - mButton.updateConfigCache(mWidgetManager); - const auto rec = RectF({ 0, 0 }, mWindow->getSize()); - mGui.proc(*eventHandler, rec, rec); + + mGui.setArea(rec); + mGui.setVisible(true); + mGui.updateConfigWrapper(mWidgetManager); + mGui.procWrapper(*eventHandler); } - void drawFrame(Canvas* canvas) override { mGui.draw(*canvas); } + void drawFrame(Canvas* canvas) override { + canvas->rect(mGui.mArea, { 0, 0, 0, 1 }); + mGui.drawWrapper(*canvas); + } private: WidgetManager mWidgetManager; @@ -33,7 +33,7 @@ private: ButtonWidget mButton; LabelWidget mLabel; - SliderWidget mSlider; + NamedSliderWidget mSlider; }; int main() { diff --git a/Widgets/private/WidgetConfig.cpp b/Widgets/private/WidgetConfig.cpp deleted file mode 100644 index 5a2cf39..0000000 --- a/Widgets/private/WidgetConfig.cpp +++ /dev/null @@ -1,6 +0,0 @@ - -#include "WidgetBase.hpp" - -#include "Graphics.hpp" - -namespace tp {} \ No newline at end of file diff --git a/Widgets/public/ButtonWidget.hpp b/Widgets/public/ButtonWidget.hpp index 003cdec..4b9e27a 100644 --- a/Widgets/public/ButtonWidget.hpp +++ b/Widgets/public/ButtonWidget.hpp @@ -7,14 +7,20 @@ namespace tp { template class ButtonWidget : public Widget { public: - ButtonWidget() { this->mArea = { 0, 0, 100, 100 }; } - - ButtonWidget(const std::string& label, const tp::RectF& aArea) { - this->mArea = aArea; - this->mLabel.mLabel = label; + ButtonWidget() { + this->setArea({ 0, 0, 100, 100 }); + this->mChildWidgets.pushBack(&mLabel); } - void procBody(const Events& events) { + ButtonWidget(const std::string& label, const tp::RectF& aArea) { + this->setArea(aArea); + mLabel.mLabel = label; + this->mChildWidgets.pushBack(&mLabel); + } + + void procCallback(const Events& events) override { + mLabel.setArea(this->mArea); + mIsHover = this->mArea.isInside(events.getPointer()); if (events.isPressed(InputID::MOUSE1) && mIsHover) { @@ -27,11 +33,9 @@ namespace tp { } if (!mIsHover) mIsPressed = false; - - mLabel.proc(events, this->mArea, this->mArea); } - void drawBody(Canvas& canvas) override { + void drawCallback(Canvas& canvas) override { if (mIsPressed) { canvas.rect(this->mArea, pressedColor, rounding); } else if (mIsHover) { @@ -39,11 +43,10 @@ namespace tp { } else { canvas.rect(this->mArea, accentColor, rounding); } - mLabel.draw(canvas); } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("Button"); pressedColor = wm.getColor("Pressed", "Action"); @@ -52,8 +55,6 @@ namespace tp { rounding = wm.getNumber("Rounding", "Rounding"); // mPressEvent = wm.getEventState("Activate", { { InputID::MOUSE1, InputState::PRESSED } }); - - mLabel.updateConfigCache(wm); } public: @@ -68,6 +69,6 @@ namespace tp { RGBA accentColor; halnf rounding = 0; - InputState mPressEvent; + // InputState mPressEvent; }; } \ No newline at end of file diff --git a/Widgets/public/LabelWidget.hpp b/Widgets/public/LabelWidget.hpp index fcdb7f4..866c4dd 100644 --- a/Widgets/public/LabelWidget.hpp +++ b/Widgets/public/LabelWidget.hpp @@ -8,12 +8,12 @@ namespace tp { public: LabelWidget() = default; - void drawBody(Canvas& canvas) override { + void drawCallback(Canvas& canvas) override { canvas.text(mLabel.c_str(), this->mArea, fontSize, Canvas::CC, padding, fontColor); } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("Label"); fontSize = wm.getNumber("Size", "FontSize"); diff --git a/Widgets/public/ScrollableWidget.hpp b/Widgets/public/ScrollableWidget.hpp index 44841f8..227e70f 100644 --- a/Widgets/public/ScrollableWidget.hpp +++ b/Widgets/public/ScrollableWidget.hpp @@ -11,11 +11,7 @@ namespace tp { ScrollBarWidget() = default; // takes whole area - void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override { - this->mArea = aArea; - this->mVisible = areaParent.isOverlap(aArea); - if (!this->mVisible) return; - + void procCallback(const Events& events) override { auto area = getHandle(); mHovered = getHandleHandle().isInside(events.getPointer()); @@ -24,12 +20,7 @@ namespace tp { return; } - if (!areaParent.isOverlap(area)) { - mIsScrolling = false; - return; - } - - if (events.getScrollY() != 0 && areaParent.isInside(events.getPointer())) { + if (events.getScrollY() != 0) { auto offset = events.getScrollY() < 0 ? 1.0f : -1.0f; if (scrollInertia * offset > 0) { scrollInertia += offset; @@ -61,9 +52,7 @@ namespace tp { mPositionFraction = tp::clamp(mPositionFraction, 0.f, 1.f - mSizeFraction); } - void draw(Canvas& canvas) override { - if (!this->mVisible) return; - + void drawCallback(Canvas& canvas) override { auto area = getHandle(); if (mSizeFraction > 1.f) return; @@ -78,7 +67,6 @@ namespace tp { } canvas.rect(area, mDefaultColor, mRounding); - canvas.rect(getHandleHandle(), col, mRounding); } @@ -104,7 +92,7 @@ namespace tp { } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("Scrollbar"); mDefaultColor = wm.getColor("Default", "Base"); @@ -138,99 +126,89 @@ namespace tp { template class ScrollableWindow : public Widget { public: - ScrollableWindow() = default; + ScrollableWindow() { + this->mChildWidgets.pushBack(&mScroller); + this->mChildWidgets.pushBack(&mContentWidget); + } + ~ScrollableWindow() = default; // takes whole area - void procBody(const Events& events) override { - updateContents(); - updateContentSize(); + void procCallback(const Events& events) override { + List*>& content = mContentWidget.mChildWidgets; + + updateContents(content); + updateContentSize(content); const auto padding = mPadding; - mScroller.mSizeFraction = this->mArea.w / mContentSize; - mScroller.proc(events, this->mArea, this->mArea); + mScroller.mSizeFraction = mContentWidget.mArea.w / mContentSize; + mScroller.setArea(this->mArea); + mContentWidget.setArea(mScroller.getViewport()); if (mScroller.mSizeFraction > 1.f) { - setOffset(0); + setOffset(content, 0); } else { - setOffset((-mScroller.mPositionFraction) * mContentSize); + setOffset(content, (-mScroller.mPositionFraction) * mContentSize); } - for (auto widget : mContents) { - widget->proc( - events, - this->mArea, - { this->mArea.x + padding, widget->mArea.y, mScroller.getViewport().z - padding * 2, widget->mArea.w } - ); + for (auto widget : content) { + widget->setArea({ mContentWidget.mArea.x + padding, + widget->mArea.y, + mScroller.getViewport().z - padding * 2, + widget->mArea.w }); } } - void drawBody(Canvas& canvas) override { - mScroller.draw(canvas); + void addWidget(Widget* widget) { mContentWidget.mChildWidgets.pushBack(widget); } + void clearContent() { mContentWidget.mChildWidgets.removeAll(); } + List*>& getContent() { return mContentWidget.mChildWidgets; } - canvas.pushClamp(this->mArea); - for (auto widget : mContents) { - widget->draw(canvas); - } - canvas.popClamp(); - } - - public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("ScrollableWidget"); - - mDefaultColor = wm.getColor("Default", "Base"); mPadding = wm.getNumber("Padding", "Padding"); - - mScroller.updateConfigCache(wm); - - for (auto item : mContents) { - item->updateConfigCache(wm); - } } private: - void updateContents() { - if (mContents.size()) { - const halnf offset = mContents.first()->mArea.y + mPadding; + void updateContents(List*>& contentWidgets) { + if (contentWidgets.size()) { + const halnf offset = contentWidgets.first()->mArea.y + mPadding; halnf start = 0; - for (auto widget : mContents) { + for (auto widget : contentWidgets) { widget->mArea.y = start; start += widget->mArea.w + mPadding; } - for (auto widget : mContents) { + for (auto widget : contentWidgets) { widget->mArea.y += offset; } } } - void updateContentSize() { + void updateContentSize(List*>& contentWidgets) { mContentSize = 0; - if (mContents.size()) { - mContentSize = mContents.last()->mArea.y - mContents.first()->mArea.y; - mContentSize += mContents.last()->mArea.w; + if (contentWidgets.size()) { + mContentSize = contentWidgets.last()->mArea.y - contentWidgets.first()->mArea.y; + mContentSize += contentWidgets.last()->mArea.w; mContentSize += 2 * mPadding; } } - void setOffset(const halnf offset) { - if (!mContents.size()) return; - auto newOffset = offset - mContents.first()->mArea.y + mPadding; - for (auto widget : mContents) { + void setOffset(List*>& contentWidgets, const halnf offset) { + if (!contentWidgets.size()) return; + auto newOffset = offset - contentWidgets.first()->mArea.y + mPadding; + for (auto widget : contentWidgets) { widget->mArea.y += newOffset; } } - public: - halnf mContentSize = 0; - - Buffer*> mContents; + private: + Widget mContentWidget; ScrollBarWidget mScroller; - RGBA mDefaultColor; + halnf mContentSize = 0; + halnf mPadding = 0; }; } \ No newline at end of file diff --git a/Widgets/public/SliderWidget.hpp b/Widgets/public/SliderWidget.hpp index aa068a8..3ed63c1 100644 --- a/Widgets/public/SliderWidget.hpp +++ b/Widgets/public/SliderWidget.hpp @@ -9,7 +9,7 @@ namespace tp { public: SliderWidget() = default; - void procBody(const Events& events) override { + void procCallback(const Events& events) override { if (events.isPressed(InputID::MOUSE1) && this->mArea.isInside(events.getPointer())) { mIsSliding = true; } else if (events.isReleased(InputID::MOUSE1)) { @@ -23,7 +23,7 @@ namespace tp { mFactor = tp::clamp(mFactor, 0.f, 1.f); } - void drawBody(Canvas& canvas) override { + void drawCallback(Canvas& canvas) override { canvas.rect(this->mArea, defaultColor, rounding); canvas.rect(getHandle(), handleColor, rounding); } @@ -34,7 +34,7 @@ namespace tp { } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("Slider"); defaultColor = wm.getColor("Default", "Base"); handleColor = wm.getColor("Handle", "Accent"); @@ -58,32 +58,24 @@ namespace tp { explicit NamedSliderWidget(const char* name = "Value") { mLabel.mLabel = name; this->mArea = { 0, 0, 100, 30 }; + + this->mChildWidgets.pushBack(&mSlider); + this->mChildWidgets.pushBack(&mLabel); } - void procBody(const Events& events) override { + void procCallback(const Events& events) override { const auto widthFirst = this->mArea.z * mFactor; const auto widthSecond = this->mArea.z * (1.f - mFactor); RectF rec = this->mArea; rec.size.x = widthFirst; - mLabel.proc(events, this->mArea, rec); + mLabel.setArea(rec); rec.pos.x += widthFirst; rec.size.x = widthSecond; - mSlider.proc(events, this->mArea, rec); - } - - void drawBody(Canvas& canvas) override { - mSlider.draw(canvas); - mLabel.draw(canvas); - } - - virtual void updateConfigCache(WidgetManager& wm) { - wm.setActiveId("NamedSlider"); - mSlider.updateConfigCache(wm); - mLabel.updateConfigCache(wm); + mSlider.setArea(rec); } public: diff --git a/Widgets/public/SplitViewWidget.hpp b/Widgets/public/SplitViewWidget.hpp index bca050c..e7ab724 100644 --- a/Widgets/public/SplitViewWidget.hpp +++ b/Widgets/public/SplitViewWidget.hpp @@ -8,7 +8,8 @@ namespace tp { public: SplitView() = default; - void procBody(const Events& events) override { + // takes whole area + void procCallback(const Events& events) override { mIsHover = getHandle().isInside(events.getPointer()); if (events.isPressed(InputID::MOUSE1) && mIsHover) { @@ -30,8 +31,7 @@ namespace tp { } } - // takes whole area - void drawBody(Canvas& canvas) override { + void drawCallback(Canvas& canvas) override { if (mResizeInProcess) canvas.rect(getHandle(), mResizingColor); else if (mIsHover) canvas.rect(getHandle(), mHoveredColor); else canvas.rect(getHandle(), mHandleColor); @@ -53,7 +53,7 @@ namespace tp { } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("SplitView"); mHandleColor = wm.getColor("Handle", "Accent"); diff --git a/Widgets/public/TextInputWidget.hpp b/Widgets/public/TextInputWidget.hpp index e4f2da4..2fe0392 100644 --- a/Widgets/public/TextInputWidget.hpp +++ b/Widgets/public/TextInputWidget.hpp @@ -11,7 +11,7 @@ namespace tp { public: TextInputWidget() = default; - void drawBody(Canvas& canvas) override { + void drawCallback(Canvas&) override { nChanged = false; const auto col = mAccentColor; @@ -51,7 +51,7 @@ namespace tp { } public: - void updateConfigCache(WidgetManager& wm) override { + void updateConfigCallback(WidgetManager& wm) override { wm.setActiveId("TextInput"); mAccentColor = wm.getColor("Accent", "Accent"); diff --git a/Widgets/public/WidgetBase.hpp b/Widgets/public/WidgetBase.hpp index 6554a25..86aae3f 100644 --- a/Widgets/public/WidgetBase.hpp +++ b/Widgets/public/WidgetBase.hpp @@ -2,42 +2,69 @@ #include "EventHandler.hpp" #include "WidgetManager.hpp" +#include "List.hpp" namespace tp { template class Widget { public: - Widget() { this->mArea = { 0, 0, 100, 100 }; } + Widget() { mArea = { 0, 0, 100, 100 }; } - virtual void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) { - mVisible = areaParent.isOverlap(aArea); - if (!mVisible) { - return; + virtual ~Widget() = default; + + virtual void procWrapper(const Events& events) { + if (!mEnable) return; + if (!mVisible) return; + + procCallback(events); + + for (auto child : mChildWidgets) { + const bool isChildVisible = getArea().isOverlap(child->getArea()); + child->setVisible(isChildVisible); + child->procWrapper(events); } - - this->mArea = aArea; - this->mAreaParent = areaParent; - - procBody(events); } - virtual void draw(Canvas& canvas) { - if (!mVisible) { - return; + virtual void drawWrapper(Canvas& canvas) { + if (!mEnable) return; + if (!mVisible) return; + + drawCallback(canvas); + + canvas.pushClamp(this->mArea); + + for (auto child : mChildWidgets) { + child->drawWrapper(canvas); } - drawBody(canvas); + canvas.popClamp(); } - virtual void procBody(const Events& events) {} - virtual void drawBody(Canvas& canvas) {} + virtual void updateConfigWrapper(WidgetManager& wm) { + wm.setActiveId("Global"); - virtual void updateConfigCache(WidgetManager& wm) {} + updateConfigCallback(wm); + + for (auto child : mChildWidgets) { + child->updateConfigWrapper(wm); + } + } + + virtual void procCallback(const Events& events) {} + virtual void drawCallback(Canvas& canvas) {} + virtual void updateConfigCallback(WidgetManager& wm) {} + + public: + void setEnable(bool enable) { mEnable = enable; } + void setVisible(bool visible) { mVisible = visible; } + const RectF& getArea() const { return mArea; } + void setArea(const RectF& area) { mArea = area; } public: RectF mArea; - RectF mAreaParent; + List*> mChildWidgets; bool mVisible = false; + bool mEnable = true; }; } \ No newline at end of file