@@ -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<std::string>& paths); | |||
bool handleZoom(); | |||
bool handleDirty(); | |||
}; | |||
@@ -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(); | |||
@@ -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) {} | |||
@@ -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 { | |||
@@ -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); | |||
@@ -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<std::string>& 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<std::string>& 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; | |||
} | |||
@@ -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(); | |||
@@ -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; | |||
@@ -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) { | |||
@@ -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; | |||
} | |||