Browse Source

Fix dropdown menu offset when zooming

tags/v0.5.0
Andrew Belt 7 years ago
parent
commit
caa1a5798e
12 changed files with 59 additions and 37 deletions
  1. +15
    -0
      include/math.hpp
  2. +7
    -1
      include/widgets.hpp
  3. +1
    -1
      src/app/RackScrollWidget.cpp
  4. +2
    -2
      src/app/Toolbar.cpp
  5. +4
    -8
      src/app/WireWidget.cpp
  6. +3
    -3
      src/core/AudioInterface.cpp
  7. +1
    -1
      src/core/MidiClockToCV.cpp
  8. +2
    -2
      src/core/MidiIO.cpp
  9. +1
    -1
      src/core/QuadMidiToCV.cpp
  10. +1
    -1
      src/widgets/Tooltip.cpp
  11. +17
    -17
      src/widgets/Widget.cpp
  12. +5
    -0
      src/widgets/ZoomWidget.cpp

+ 15
- 0
include/math.hpp View File

@@ -271,6 +271,21 @@ struct Rect {
r.pos.y = clampf(pos.y, bound.pos.y, bound.pos.y + bound.size.y - size.y);
return r;
}
/** Expands this Rect to contain `other` */
Rect expand(Rect other) {
Rect r;
r.pos.x = fminf(pos.x, other.pos.x);
r.pos.y = fminf(pos.y, other.pos.y);
r.size.x = fmaxf(pos.x + size.x, other.pos.x + other.size.x) - r.pos.x;
r.size.y = fmaxf(pos.y + size.y, other.pos.y + other.size.y) - r.pos.y;
return r;
}
/** Returns a Rect with its position set to zero */
Rect zeroPos() {
Rect r;
r.size = size;
return r;
}
};




+ 7
- 1
include/widgets.hpp View File

@@ -56,8 +56,13 @@ struct Widget {

virtual ~Widget();

Vec getAbsolutePos();
Rect getChildrenBoundingBox();
/** Returns `v` transformed into the coordinate system of `relative` */
virtual Vec getRelativeOffset(Vec v, Widget *relative);
/** Returns `v` transformed into world coordinates */
Vec getAbsoluteOffset(Vec v) {
return getRelativeOffset(v, NULL);
}
/** Returns a subset of the given Rect bounded by the box of this widget and all ancestors */
virtual Rect getViewport(Rect r);

@@ -149,6 +154,7 @@ struct TransformWidget : Widget {

struct ZoomWidget : Widget {
float zoom = 1.0;
Vec getRelativeOffset(Vec v, Widget *relative) override;
Rect getViewport(Rect r) override;
void setZoom(float zoom);
void draw(NVGcontext *vg) override;


+ 1
- 1
src/app/RackScrollWidget.cpp View File

@@ -6,7 +6,7 @@ namespace rack {


void RackScrollWidget::step() {
Vec pos = gMousePos.minus(getAbsolutePos());
Vec pos = gRackWidget->lastMousePos;
// Scroll rack if dragging cable near the edge of the screen
if (gRackWidget->wireContainer->activeWire) {
float margin = 20.0;


+ 2
- 2
src/app/Toolbar.cpp View File

@@ -39,7 +39,7 @@ struct QuitItem : MenuItem {
struct FileChoice : ChoiceButton {
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;

{
@@ -70,7 +70,7 @@ struct SampleRateItem : MenuItem {
struct SampleRateChoice : ChoiceButton {
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;

PauseItem *pauseItem = new PauseItem();


+ 4
- 8
src/app/WireWidget.cpp View File

@@ -124,31 +124,27 @@ void WireWidget::updateWire() {
}

Vec WireWidget::getOutputPos() {
Vec pos;
if (outputPort) {
pos = Rect(outputPort->getAbsolutePos(), outputPort->box.size).getCenter();
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gRackWidget);
}
else if (hoveredOutputPort) {
pos = Rect(hoveredOutputPort->getAbsolutePos(), hoveredOutputPort->box.size).getCenter();
return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), gRackWidget);
}
else {
return gRackWidget->lastMousePos;
}
return pos.minus(getAbsolutePos().minus(box.pos));
}

Vec WireWidget::getInputPos() {
Vec pos;
if (inputPort) {
pos = Rect(inputPort->getAbsolutePos(), inputPort->box.size).getCenter();
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gRackWidget);
}
else if (hoveredInputPort) {
pos = Rect(hoveredInputPort->getAbsolutePos(), hoveredInputPort->box.size).getCenter();
return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), gRackWidget);
}
else {
return gRackWidget->lastMousePos;
}
return pos.minus(getAbsolutePos().minus(box.pos));
}

void WireWidget::draw(NVGcontext *vg) {


+ 3
- 3
src/core/AudioInterface.cpp View File

@@ -335,7 +335,7 @@ struct AudioChoice : ChoiceButton {
AudioInterface *audioInterface;
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

int deviceCount = audioInterface->getDeviceCount();
@@ -373,7 +373,7 @@ struct SampleRateChoice : ChoiceButton {
AudioInterface *audioInterface;
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

const float sampleRates[6] = {44100, 48000, 88200, 96000, 176400, 192000};
@@ -404,7 +404,7 @@ struct BlockSizeChoice : ChoiceButton {
AudioInterface *audioInterface;
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

const int blockSizes[] = {64, 128, 256, 512, 1024, 2048, 4096};


+ 1
- 1
src/core/MidiClockToCV.cpp View File

@@ -201,7 +201,7 @@ struct ClockRatioChoice : ChoiceButton {

void onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

for (unsigned long ratio = 0; ratio < ratioNames.size(); ratio++) {


+ 2
- 2
src/core/MidiIO.cpp View File

@@ -182,7 +182,7 @@ void MidiItem::onAction() {

void MidiChoice::onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

{
@@ -217,7 +217,7 @@ void ChannelItem::onAction() {

void ChannelChoice::onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

{


+ 1
- 1
src/core/QuadMidiToCV.cpp View File

@@ -259,7 +259,7 @@ struct ModeChoice : ChoiceButton {

void onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

for (unsigned long i = 0; i < modeNames.size(); i++) {


+ 1
- 1
src/widgets/Tooltip.cpp View File

@@ -6,7 +6,7 @@ namespace rack {

void Tooltip::step() {
// Follow the mouse
box.pos = gMousePos.minus(parent->getAbsolutePos());
box.pos = gMousePos;

// Wrap size to contents
// box.size = getChildrenBoundingBox().getBottomRight();


+ 17
- 17
src/widgets/Widget.cpp View File

@@ -16,28 +16,28 @@ Widget::~Widget() {
clearChildren();
}

Vec Widget::getAbsolutePos() {
// Recursively compute position offset from parents
if (!parent) {
return box.pos;
}
else {
return box.pos.plus(parent->getAbsolutePos());
Rect Widget::getChildrenBoundingBox() {
Rect bound;
for (Widget *child : children) {
if (child == children.front()) {
bound = child->box;
}
else {
bound = bound.expand(child->box);
}
}
return bound;
}

Rect Widget::getChildrenBoundingBox() {
if (children.empty()) {
return Rect();
Vec Widget::getRelativeOffset(Vec v, Widget *relative) {
if (this == relative) {
return v;
}

Vec topLeft = Vec(INFINITY, INFINITY);
Vec bottomRight = Vec(-INFINITY, -INFINITY);
for (Widget *child : children) {
topLeft = topLeft.min(child->box.pos);
bottomRight = bottomRight.max(child->box.getBottomRight());
v = v.plus(box.pos);
if (parent) {
v = parent->getRelativeOffset(v, relative);
}
return Rect(topLeft, bottomRight.minus(topLeft));
return v;
}

Rect Widget::getViewport(Rect r) {


+ 5
- 0
src/widgets/ZoomWidget.cpp View File

@@ -3,6 +3,11 @@

namespace rack {


Vec ZoomWidget::getRelativeOffset(Vec v, Widget *relative) {
return Widget::getRelativeOffset(v.mult(zoom), relative);
}

Rect ZoomWidget::getViewport(Rect r) {
r.pos = r.pos.mult(zoom);
r.size = r.size.mult(zoom);


Loading…
Cancel
Save