diff --git a/include/event.hpp b/include/event.hpp index 4e314c18..7a0e33bb 100644 --- a/include/event.hpp +++ b/include/event.hpp @@ -346,10 +346,10 @@ struct Change : Base { }; -/** Occurs after the zoom level of a Widget is changed. +/** Occurs when the pixel buffer of this module must be refreshed. Recurses. */ -struct Zoom : Base { +struct Dirty : Base { }; @@ -436,7 +436,7 @@ struct State { bool handleText(math::Vec pos, int codepoint); bool handleKey(math::Vec pos, int key, int scancode, int action, int mods); bool handleDrop(math::Vec pos, const std::vector& paths); - bool handleZoom(); + bool handleDirty(); }; diff --git a/include/widget/FramebufferWidget.hpp b/include/widget/FramebufferWidget.hpp index e83ec25b..d8419c35 100644 --- a/include/widget/FramebufferWidget.hpp +++ b/include/widget/FramebufferWidget.hpp @@ -33,6 +33,7 @@ struct FramebufferWidget : Widget { FramebufferWidget(); ~FramebufferWidget(); + void onDirty(const event::Dirty& e) override; void step() override; void draw(const DrawArgs& args) override; virtual void drawFramebuffer(); diff --git a/include/widget/Widget.hpp b/include/widget/Widget.hpp index 4d63730b..448df63f 100644 --- a/include/widget/Widget.hpp +++ b/include/widget/Widget.hpp @@ -34,9 +34,18 @@ struct Widget { virtual ~Widget(); void setPosition(math::Vec pos); + math::Vec getPosition() { + return box.pos; + } void setSize(math::Vec size); + math::Vec getSize() { + return box.size; + } void show(); void hide(); + bool isVisible() { + return visible; + } void requestDelete(); virtual math::Rect getChildrenBoundingBox(); @@ -180,8 +189,8 @@ struct Widget { } virtual void onAction(const event::Action& e) {} virtual void onChange(const event::Change& e) {} - virtual void onZoom(const event::Zoom& e) { - recurseEvent(&Widget::onZoom, e); + virtual void onDirty(const event::Dirty& e) { + recurseEvent(&Widget::onDirty, e); } virtual void onReposition(const event::Reposition& e) {} virtual void onResize(const event::Resize& e) {} diff --git a/include/widget/ZoomWidget.hpp b/include/widget/ZoomWidget.hpp index 10003720..ee3f5cfc 100644 --- a/include/widget/ZoomWidget.hpp +++ b/include/widget/ZoomWidget.hpp @@ -13,6 +13,9 @@ struct ZoomWidget : Widget { math::Vec getRelativeOffset(math::Vec v, Widget* relative) override; math::Rect getViewport(math::Rect r) override; void setZoom(float zoom); + float getZoom() { + return zoom; + } void draw(const DrawArgs& args) override; void onHover(const event::Hover& e) override { diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index a227a6ab..07d7729e 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -402,13 +402,12 @@ bool RackWidget::requestModulePos(ModuleWidget* mw, math::Vec pos) { if (!w2->visible) continue; // Check intersection - if (mwBox.isIntersecting(w2->box)) { + if (mwBox.isIntersecting(w2->box)) return false; - } } // Accept requested position - mw->box = mwBox; + mw->setPosition(mwBox.pos); RackWidget_updateAdjacent(this); return true; } @@ -459,11 +458,11 @@ void RackWidget::setModulePosNearest(ModuleWidget* mw, math::Vec pos) { } // We failed to find a box. This shouldn't happen on an infinite rack. - assert(0); + assert(false); } void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) { - mw->box.pos = pos.div(RACK_GRID_SIZE).round().mult(RACK_GRID_SIZE); + mw->setPosition(pos.div(RACK_GRID_SIZE).round().mult(RACK_GRID_SIZE)); // Comparison of center X coordinates auto cmp = [&](const widget::Widget * a, const widget::Widget * b) { @@ -489,24 +488,26 @@ void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) { float xLimit = mw->box.pos.x; for (auto it = leftModules.rbegin(); it != leftModules.rend(); it++) { widget::Widget* w = *it; - float x = xLimit - w->box.size.x; - x = std::round(x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; - if (w->box.pos.x < x) + math::Vec newPos = w->box.pos; + newPos.x = xLimit - w->box.size.x; + newPos.x = std::round(newPos.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; + if (w->box.pos.x < newPos.x) break; - w->box.pos.x = x; - xLimit = x; + w->setPosition(newPos); + xLimit = newPos.x; } // Shove right modules xLimit = mw->box.pos.x + mw->box.size.x; for (auto it = rightModules.begin(); it != rightModules.end(); it++) { widget::Widget* w = *it; - float x = xLimit; - x = std::round(x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; - if (w->box.pos.x > x) + math::Vec newPos = w->box.pos; + newPos.x = xLimit; + newPos.x = std::round(newPos.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; + if (w->box.pos.x > newPos.x) break; - w->box.pos.x = x; - xLimit = x + w->box.size.x; + w->setPosition(newPos); + xLimit = newPos.x + w->box.size.x; } RackWidget_updateAdjacent(this); diff --git a/src/event.cpp b/src/event.cpp index 7471ba79..b6beb07f 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -13,14 +13,14 @@ void State::setHovered(widget::Widget* w) { return; if (hoveredWidget) { - // Leave + // Trigger Leave event Leave eLeave; hoveredWidget->onLeave(eLeave); hoveredWidget = NULL; } if (w) { - // Enter + // Trigger Enter event Context cEnter; cEnter.target = w; Enter eEnter; @@ -35,7 +35,7 @@ void State::setDragged(widget::Widget* w, int button) { return; if (draggedWidget) { - // DragEnd + // Trigger DragEnd event DragEnd eDragEnd; eDragEnd.button = dragButton; draggedWidget->onDragEnd(eDragEnd); @@ -45,7 +45,7 @@ void State::setDragged(widget::Widget* w, int button) { dragButton = button; if (w) { - // DragStart + // Trigger DragStart event Context cDragStart; cDragStart.target = w; DragStart eDragStart; @@ -61,7 +61,7 @@ void State::setDragHovered(widget::Widget* w) { return; if (dragHoveredWidget) { - // DragLeave + // Trigger DragLeave event DragLeave eDragLeave; eDragLeave.button = dragButton; eDragLeave.origin = draggedWidget; @@ -70,7 +70,7 @@ void State::setDragHovered(widget::Widget* w) { } if (w) { - // DragEnter + // Trigger DragEnter event Context cDragEnter; cDragEnter.target = w; DragEnter eDragEnter; @@ -87,14 +87,14 @@ void State::setSelected(widget::Widget* w) { return; if (selectedWidget) { - // Deselect + // Trigger Deselect event Deselect eDeselect; selectedWidget->onDeselect(eDeselect); selectedWidget = NULL; } if (w) { - // Select + // Trigger Select event Context cSelect; cSelect.target = w; Select eSelect; @@ -122,7 +122,7 @@ bool State::handleButton(math::Vec pos, int button, int action, int mods) { widget::Widget* clickedWidget = NULL; if (!cursorLocked) { - // Button + // Trigger Button event Context cButton; Button eButton; eButton.context = &cButton; @@ -142,7 +142,7 @@ bool State::handleButton(math::Vec pos, int button, int action, int mods) { setDragHovered(NULL); if (clickedWidget && draggedWidget) { - // DragDrop + // Trigger DragDrop event DragDrop eDragDrop; eDragDrop.button = dragButton; eDragDrop.origin = draggedWidget; @@ -163,7 +163,7 @@ bool State::handleButton(math::Vec pos, int button, int action, int mods) { if (clickedWidget && clickTime - lastClickTime <= doubleClickDuration && lastClickedWidget == clickedWidget) { - // DoubleClick + // Trigger DoubleClick event DoubleClick eDoubleClick; clickedWidget->onDoubleClick(eDoubleClick); // Reset double click @@ -193,14 +193,14 @@ bool State::handleHover(math::Vec pos, math::Vec mouseDelta) { } if (draggedWidget) { - // DragMove + // Trigger DragMove event DragMove eDragMove; eDragMove.button = dragButton; eDragMove.mouseDelta = mouseDelta; draggedWidget->onDragMove(eDragMove); if (!cursorLocked) { - // DragHover + // Trigger DragHover event Context cDragHover; DragHover eDragHover; eDragHover.context = &cDragHover; @@ -217,7 +217,7 @@ bool State::handleHover(math::Vec pos, math::Vec mouseDelta) { } if (!cursorLocked) { - // Hover + // Trigger Hover event Context cHover; Hover eHover; eHover.context = &cHover; @@ -240,7 +240,7 @@ bool State::handleLeave() { } bool State::handleScroll(math::Vec pos, math::Vec scrollDelta) { - // HoverScroll + // Trigger HoverScroll event Context cHoverScroll; HoverScroll eHoverScroll; eHoverScroll.context = &cHoverScroll; @@ -252,7 +252,7 @@ bool State::handleScroll(math::Vec pos, math::Vec scrollDelta) { } bool State::handleDrop(math::Vec pos, const std::vector& paths) { - // PathDrop + // Trigger PathDrop event Context cPathDrop; PathDrop ePathDrop(paths); ePathDrop.context = &cPathDrop; @@ -264,7 +264,7 @@ bool State::handleDrop(math::Vec pos, const std::vector& paths) { bool State::handleText(math::Vec pos, int codepoint) { if (selectedWidget) { - // SelectText + // Trigger SelectText event Context cSelectText; SelectText eSelectText; eSelectText.context = &cSelectText; @@ -274,7 +274,7 @@ bool State::handleText(math::Vec pos, int codepoint) { return true; } - // HoverText + // Trigger HoverText event Context cHoverText; HoverText eHoverText; eHoverText.context = &cHoverText; @@ -297,7 +297,7 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods } if (selectedWidget) { - // SelectKey + // Trigger SelectKey event Context cSelectKey; SelectKey eSelectKey; eSelectKey.context = &cSelectKey; @@ -313,7 +313,7 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods return true; } - // HoverKey + // Trigger HoverKey event Context cHoverKey; HoverKey eHoverKey; eHoverKey.context = &cHoverKey; @@ -329,12 +329,12 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods return !!cHoverKey.target; } -bool State::handleZoom() { - // Zoom - Context cZoom; - Zoom eZoom; - eZoom.context = &cZoom; - rootWidget->onZoom(eZoom); +bool State::handleDirty() { + // Trigger Dirty event + Context cDirty; + Dirty eDirty; + eDirty.context = &cDirty; + rootWidget->onDirty(eDirty); return true; } diff --git a/src/widget/FramebufferWidget.cpp b/src/widget/FramebufferWidget.cpp index c9a34de7..f50539b7 100644 --- a/src/widget/FramebufferWidget.cpp +++ b/src/widget/FramebufferWidget.cpp @@ -15,6 +15,11 @@ FramebufferWidget::~FramebufferWidget() { nvgluDeleteFramebuffer(fb); } +void FramebufferWidget::onDirty(const event::Dirty& e) { + dirty = true; + Widget::onDirty(e); +} + void FramebufferWidget::step() { Widget::step(); diff --git a/src/widget/Widget.cpp b/src/widget/Widget.cpp index dfc94d02..fd8dec96 100644 --- a/src/widget/Widget.cpp +++ b/src/widget/Widget.cpp @@ -15,6 +15,8 @@ Widget::~Widget() { } void Widget::setPosition(math::Vec pos) { + if (pos.isEqual(box.pos)) + return; box.pos = pos; // event::Reposition event::Reposition eReposition; @@ -22,6 +24,8 @@ void Widget::setPosition(math::Vec pos) { } void Widget::setSize(math::Vec size) { + if (size.isEqual(box.size)) + return; box.size = size; // event::Resize event::Resize eResize; diff --git a/src/widget/ZoomWidget.cpp b/src/widget/ZoomWidget.cpp index 4543c160..c4ffca85 100644 --- a/src/widget/ZoomWidget.cpp +++ b/src/widget/ZoomWidget.cpp @@ -23,10 +23,11 @@ void ZoomWidget::setZoom(float zoom) { return; this->zoom = zoom; - event::Context cZoom; - event::Zoom eZoom; - eZoom.context = &cZoom; - Widget::onZoom(eZoom); + // Trigger Dirty event + event::Context cDirty; + event::Dirty eDirty; + eDirty.context = &cDirty; + Widget::onDirty(eDirty); } void ZoomWidget::draw(const DrawArgs& args) { diff --git a/src/window.cpp b/src/window.cpp index 789c9614..a04fbcc9 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -384,7 +384,7 @@ void Window::run() { glfwGetWindowContentScale(win, &newPixelRatio, NULL); newPixelRatio = std::floor(newPixelRatio + 0.5); if (newPixelRatio != pixelRatio) { - APP->event->handleZoom(); + APP->event->handleDirty(); pixelRatio = newPixelRatio; }