Browse Source

Add ModuleWidget selection. (Currently does nothing.)

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
7d2ce0a6bb
5 changed files with 93 additions and 12 deletions
  1. +1
    -0
      include/app/ModuleWidget.hpp
  2. +6
    -1
      include/app/RackWidget.hpp
  3. +7
    -1
      include/math.hpp
  4. +19
    -0
      src/app/ModuleWidget.cpp
  5. +60
    -10
      src/app/RackWidget.cpp

+ 1
- 0
include/app/ModuleWidget.hpp View File

@@ -111,6 +111,7 @@ struct ModuleWidget : widget::OpaqueWidget {
INTERNAL bool& dragEnabled(); INTERNAL bool& dragEnabled();
INTERNAL math::Vec& oldPos(); INTERNAL math::Vec& oldPos();
INTERNAL engine::Module* releaseModule(); INTERNAL engine::Module* releaseModule();
INTERNAL bool& selected();
}; };






+ 6
- 1
include/app/RackWidget.hpp View File

@@ -38,8 +38,12 @@ struct RackWidget : widget::OpaqueWidget {


void onHover(const HoverEvent& e) override; void onHover(const HoverEvent& e) override;
void onHoverKey(const HoverKeyEvent& e) override; void onHoverKey(const HoverKeyEvent& e) override;
void onDragHover(const DragHoverEvent& e) override;
void onButton(const ButtonEvent& e) override; void onButton(const ButtonEvent& e) override;
void onDragStart(const DragStartEvent& e) override;
void onDragEnd(const DragEndEvent& e) override;
void onDragHover(const DragHoverEvent& e) override;

// Rack methods


/** Completely clear the rack's modules and cables */ /** Completely clear the rack's modules and cables */
void clear(); void clear();
@@ -65,6 +69,7 @@ struct RackWidget : widget::OpaqueWidget {
bool isEmpty(); bool isEmpty();
void updateModuleOldPositions(); void updateModuleOldPositions();
history::ComplexAction* getModuleDragAction(); history::ComplexAction* getModuleDragAction();
void updateModuleSelections();


// Cable methods // Cable methods




+ 7
- 1
include/math.hpp View File

@@ -308,10 +308,16 @@ struct Rect {
Rect() {} Rect() {}
Rect(Vec pos, Vec size) : pos(pos), size(size) {} Rect(Vec pos, Vec size) : pos(pos), size(size) {}
Rect(float posX, float posY, float sizeX, float sizeY) : pos(Vec(posX, posY)), size(Vec(sizeX, sizeY)) {} Rect(float posX, float posY, float sizeX, float sizeY) : pos(Vec(posX, posY)), size(Vec(sizeX, sizeY)) {}
/** Constructs a Rect from the upper-left position `a` and lower-right pos `b`. */
/** Constructs a Rect from a top-left and bottom-right vector.
*/
static Rect fromMinMax(Vec a, Vec b) { static Rect fromMinMax(Vec a, Vec b) {
return Rect(a, b.minus(a)); return Rect(a, b.minus(a));
} }
/** Constructs a Rect from any two opposite corners.
*/
static Rect fromCorners(Vec a, Vec b) {
return fromMinMax(a.min(b), a.max(b));
}
/** Returns the infinite Rect. */ /** Returns the infinite Rect. */
static Rect inf() { static Rect inf() {
return Rect(Vec(-INFINITY, -INFINITY), Vec(INFINITY, INFINITY)); return Rect(Vec(-INFINITY, -INFINITY), Vec(INFINITY, INFINITY));


+ 19
- 0
src/app/ModuleWidget.cpp View File

@@ -418,6 +418,8 @@ struct ModuleWidget::Internal {
math::Vec oldPos; math::Vec oldPos;


widget::Widget* panel = NULL; widget::Widget* panel = NULL;

bool selected = false;
}; };




@@ -597,6 +599,17 @@ void ModuleWidget::draw(const DrawArgs& args) {
// bndLabel(args.vg, 0, 0, INFINITY, INFINITY, -1, debugText.c_str()); // bndLabel(args.vg, 0, 0, INFINITY, INFINITY, -1, debugText.c_str());
// } // }


// Selection
if (internal->selected) {
nvgBeginPath(args.vg);
nvgRect(args.vg, 0.0, 0.0, VEC_ARGS(box.size));
nvgFillColor(args.vg, nvgRGBAf(1, 0, 0, 0.25));
nvgFill(args.vg);
nvgStrokeWidth(args.vg, 2.0);
nvgStrokeColor(args.vg, nvgRGBAf(1, 0, 0, 0.5));
nvgStroke(args.vg);
}

nvgResetScissor(args.vg); nvgResetScissor(args.vg);
} }


@@ -1210,5 +1223,11 @@ engine::Module* ModuleWidget::releaseModule() {
} }




bool& ModuleWidget::selected() {
return internal->selected;
}



} // namespace app } // namespace app
} // namespace rack } // namespace rack

+ 60
- 10
src/app/RackWidget.cpp View File

@@ -72,12 +72,15 @@ struct CableContainer : widget::TransparentWidget {
}; };




// struct RackWidget::Internal {
// };
struct RackWidget::Internal {
bool selecting = false;
math::Vec selectionStart;
math::Vec selectionEnd;
};




RackWidget::RackWidget() { RackWidget::RackWidget() {
// internal = new Internal;
internal = new Internal;


rail = new RailWidget; rail = new RailWidget;
addChild(rail); addChild(rail);
@@ -91,7 +94,7 @@ RackWidget::RackWidget() {


RackWidget::~RackWidget() { RackWidget::~RackWidget() {
clear(); clear();
// delete internal;
delete internal;
} }


void RackWidget::step() { void RackWidget::step() {
@@ -104,11 +107,24 @@ void RackWidget::draw(const DrawArgs& args) {
nvgGlobalTint(args.vg, nvgRGBAf(b, b, b, 1)); nvgGlobalTint(args.vg, nvgRGBAf(b, b, b, 1));


Widget::draw(args); Widget::draw(args);

// Draw selection rectangle
if (internal->selecting) {
nvgBeginPath(args.vg);
math::Rect selectionBox = math::Rect::fromCorners(internal->selectionStart, internal->selectionEnd);
nvgRect(args.vg, RECT_ARGS(selectionBox));
nvgFillColor(args.vg, nvgRGBAf(1, 0, 0, 0.25));
nvgFill(args.vg);
nvgStrokeWidth(args.vg, 2.0);
nvgStrokeColor(args.vg, nvgRGBAf(1, 0, 0, 0.5));
nvgStroke(args.vg);
}
} }


void RackWidget::onHover(const HoverEvent& e) { void RackWidget::onHover(const HoverEvent& e) {
// Set before calling children's onHover() // Set before calling children's onHover()
mousePos = e.pos; mousePos = e.pos;

OpaqueWidget::onHover(e); OpaqueWidget::onHover(e);
} }


@@ -125,12 +141,6 @@ void RackWidget::onHoverKey(const HoverKeyEvent& e) {
} }
} }


void RackWidget::onDragHover(const DragHoverEvent& e) {
// Set before calling children's onDragHover()
mousePos = e.pos;
OpaqueWidget::onDragHover(e);
}

void RackWidget::onButton(const ButtonEvent& e) { void RackWidget::onButton(const ButtonEvent& e) {
Widget::onButton(e); Widget::onButton(e);
e.stopPropagating(); e.stopPropagating();
@@ -141,6 +151,37 @@ void RackWidget::onButton(const ButtonEvent& e) {
APP->scene->moduleBrowser->show(); APP->scene->moduleBrowser->show();
e.consume(this); e.consume(this);
} }
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT) {
e.consume(this);
}
}

void RackWidget::onDragStart(const DragStartEvent& e) {
if (e.button == GLFW_MOUSE_BUTTON_LEFT) {
// Deselect all modules
updateModuleSelections();
internal->selecting = true;
internal->selectionStart = mousePos;
internal->selectionEnd = mousePos;
}
}

void RackWidget::onDragEnd(const DragEndEvent& e) {
if (e.button == GLFW_MOUSE_BUTTON_LEFT) {
internal->selecting = false;
}
}

void RackWidget::onDragHover(const DragHoverEvent& e) {
// Set before calling children's onDragHover()
mousePos = e.pos;

if (internal->selecting) {
internal->selectionEnd = mousePos;
updateModuleSelections();
}

OpaqueWidget::onDragHover(e);
} }


void RackWidget::clear() { void RackWidget::clear() {
@@ -590,6 +631,15 @@ history::ComplexAction* RackWidget::getModuleDragAction() {
return h; return h;
} }


void RackWidget::updateModuleSelections() {
math::Rect selectionBox = math::Rect::fromCorners(internal->selectionStart, internal->selectionEnd);
for (widget::Widget* w : moduleContainer->children) {
ModuleWidget* mw = dynamic_cast<ModuleWidget*>(w);
assert(mw);
bool selected = internal->selecting && selectionBox.intersects(mw->box);
mw->selected() = selected;
}
}


void RackWidget::clearCables() { void RackWidget::clearCables() {
incompleteCable = NULL; incompleteCable = NULL;


Loading…
Cancel
Save