Browse Source

Middle-click drag to move rack view, other needless refactoring

tags/v0.4.0
Andrew Belt 7 years ago
parent
commit
5163a7aba1
7 changed files with 74 additions and 51 deletions
  1. +10
    -0
      include/math.hpp
  2. +9
    -8
      include/widgets.hpp
  3. +1
    -1
      src/gui.cpp
  4. +13
    -1
      src/widgets/Menu.cpp
  5. +0
    -9
      src/widgets/MenuOverlay.cpp
  6. +14
    -10
      src/widgets/ScrollBar.cpp
  7. +27
    -22
      src/widgets/ScrollWidget.cpp

+ 10
- 0
include/math.hpp View File

@@ -147,6 +147,8 @@ inline void cmultf(float *cr, float *ci, float ar, float ai, float br, float bi)
// 2D float vector
////////////////////

struct Rect;

struct Vec {
float x, y;

@@ -186,6 +188,7 @@ struct Vec {
bool isZero() {
return x == 0.0 && y == 0.0;
}
Vec clamp(Rect bound);
};


@@ -237,4 +240,11 @@ struct Rect {
};


inline Vec Vec::clamp(Rect bound) {
return Vec(
clampf(x, bound.pos.x, bound.pos.x + bound.size.x),
clampf(y, bound.pos.y, bound.pos.y + bound.size.y));
}


} // namespace rack

+ 9
- 8
include/widgets.hpp View File

@@ -256,8 +256,8 @@ struct Label : Widget {

// Deletes itself from parent when clicked
struct MenuOverlay : OpaqueWidget {
void step();
void onDragDrop(Widget *origin);
bool onScrollOpaque(Vec scrollRel) {return true;}
};

struct Menu : OpaqueWidget {
@@ -266,6 +266,8 @@ struct Menu : OpaqueWidget {
}
// Resizes menu and calls addChild()
void pushChild(Widget *child);
void fit();
void step();
void draw(NVGcontext *vg);
bool onScrollOpaque(Vec scrollRel);
};
@@ -337,31 +339,30 @@ struct Slider : OpaqueWidget, QuantityWidget {
void onDragEnd();
};

/** Parent must be a ScrollWidget */
struct ScrollBar : OpaqueWidget {
enum { VERTICAL, HORIZONTAL } orientation;
float containerOffset = 0.0;
float containerSize = 0.0;
BNDwidgetState state = BND_DEFAULT;

ScrollBar() {
box.size = Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT);
}
void step();
void draw(NVGcontext *vg);
void onDragStart();
void onDragMove(Vec mouseRel);
void onDragEnd();
};

// Handles a container with scrollbars
/** Handles a container with ScrollBar */
struct ScrollWidget : OpaqueWidget {
Widget *container;
ScrollBar *hScrollBar;
ScrollBar *vScrollBar;
ScrollBar *horizontalScrollBar;
ScrollBar *verticalScrollBar;
Vec offset;

ScrollWidget();
void step();
void draw(NVGcontext *vg);
Widget *onMouseMove(Vec pos, Vec mouseRel);
bool onScrollOpaque(Vec scrollRel);
};



+ 1
- 1
src/gui.cpp View File

@@ -151,7 +151,7 @@ void cursorEnterCallback(GLFWwindow* window, int entered) {
void scrollCallback(GLFWwindow *window, double x, double y) {
Vec scrollRel = Vec(x, y);
// onScroll
gScene->onScroll(gMousePos, scrollRel.mult(-38.0));
gScene->onScroll(gMousePos, scrollRel.mult(50.0));
}

void charCallback(GLFWwindow *window, unsigned int codepoint) {


+ 13
- 1
src/widgets/Menu.cpp View File

@@ -9,6 +9,17 @@ void Menu::pushChild(Widget *child) {
box.size.y += child->box.size.y;
}

void Menu::fit() {
// Try to fit into the parent's box
if (parent)
box = box.clamp(Rect(Vec(0, 0), parent->box.size));
}

void Menu::step() {
fit();
Widget::step();
}

void Menu::draw(NVGcontext *vg) {
// Resize the width to the widest child
for (Widget *child : children) {
@@ -33,7 +44,8 @@ bool Menu::onScrollOpaque(Vec scrollRel) {
if (!parent)
return true;
if (!parent->box.contains(box))
box.pos = box.pos.plus(scrollRel.neg());
box.pos = box.pos.plus(scrollRel);
fit();
return true;
}



+ 0
- 9
src/widgets/MenuOverlay.cpp View File

@@ -3,15 +3,6 @@

namespace rack {

void MenuOverlay::step() {
// Try to fit all children into the overlay's box
for (Widget *child : children) {
child->box = child->box.clamp(Rect(Vec(0, 0), box.size));
}

Widget::step();
}

void MenuOverlay::onDragDrop(Widget *origin) {
if (origin == this) {
// deletes `this`


+ 14
- 10
src/widgets/ScrollBar.cpp View File

@@ -4,17 +4,16 @@

namespace rack {

void ScrollBar::step() {
float boxSize = (orientation == VERTICAL ? box.size.y : box.size.x);
float maxOffset = containerSize - boxSize;
containerOffset = clampf(containerOffset, 0.0, maxOffset);
Widget::step();
}

void ScrollBar::draw(NVGcontext *vg) {
float boxSize = (orientation == VERTICAL ? box.size.y : box.size.x);
float maxOffset = containerSize - boxSize;
float offset = containerOffset / maxOffset;
ScrollWidget *scrollWidget = dynamic_cast<ScrollWidget*>(parent);
assert(scrollWidget);
Vec containerCorner = scrollWidget->container->getChildrenBoundingBox().getBottomRight();

float containerSize = (orientation == HORIZONTAL) ? containerCorner.x : containerCorner.y;
float boxSize = (orientation == HORIZONTAL) ? box.size.x : box.size.y;
float offset = (orientation == HORIZONTAL) ? scrollWidget->offset.x : scrollWidget->offset.y;
offset = offset / (containerSize - boxSize);
float size = boxSize / containerSize;
size = clampf(size, 0.0, 1.0);
bndScrollBar(vg, 0.0, 0.0, box.size.x, box.size.y, state, offset, size);
@@ -26,7 +25,12 @@ void ScrollBar::onDragStart() {
}

void ScrollBar::onDragMove(Vec mouseRel) {
containerOffset += (orientation == VERTICAL ? mouseRel.y : mouseRel.x);
ScrollWidget *scrollWidget = dynamic_cast<ScrollWidget*>(parent);
assert(scrollWidget);
if (orientation == HORIZONTAL)
scrollWidget->offset.x += mouseRel.x;
else
scrollWidget->offset.y += mouseRel.y;
}

void ScrollBar::onDragEnd() {


+ 27
- 22
src/widgets/ScrollWidget.cpp View File

@@ -1,4 +1,5 @@
#include "widgets.hpp"
#include "gui.hpp"


namespace rack {
@@ -7,42 +8,46 @@ ScrollWidget::ScrollWidget() {
container = new Widget();
addChild(container);

hScrollBar = new ScrollBar();
hScrollBar->orientation = ScrollBar::HORIZONTAL;
addChild(hScrollBar);
horizontalScrollBar = new ScrollBar();
horizontalScrollBar->orientation = ScrollBar::HORIZONTAL;
addChild(horizontalScrollBar);

vScrollBar = new ScrollBar();
vScrollBar->orientation = ScrollBar::VERTICAL;
addChild(vScrollBar);
verticalScrollBar = new ScrollBar();
verticalScrollBar->orientation = ScrollBar::VERTICAL;
addChild(verticalScrollBar);
}

void ScrollWidget::step() {
Vec b = Vec(box.size.x - vScrollBar->box.size.x, box.size.y - hScrollBar->box.size.y);
// Clamp scroll offset
Vec containerCorner = container->getChildrenBoundingBox().getBottomRight();
offset = offset.clamp(Rect(Vec(0, 0), containerCorner.minus(box.size)));

hScrollBar->box.pos.y = b.y;
hScrollBar->box.size.x = b.x;
// Resize scroll bars
Vec inner = Vec(box.size.x - verticalScrollBar->box.size.x, box.size.y - horizontalScrollBar->box.size.y);
horizontalScrollBar->box.pos.y = inner.y;
horizontalScrollBar->box.size.x = inner.x;
verticalScrollBar->box.pos.x = inner.x;
verticalScrollBar->box.size.y = inner.y;

vScrollBar->box.pos.x = b.x;
vScrollBar->box.size.y = b.y;
// Update the container's positions from the offset
container->box.pos = offset.neg().round();

Widget::step();
}

void ScrollWidget::draw(NVGcontext *vg) {
// Update the scrollbar sizes
Vec c = container->getChildrenBoundingBox().getBottomRight();
hScrollBar->containerSize = c.x;
vScrollBar->containerSize = c.y;
Widget *ScrollWidget::onMouseMove(Vec pos, Vec mouseRel) {
Widget *w = Widget::onMouseMove(pos, mouseRel);
if (w) return w;

// Update the container's positions from the scrollbar offsets
container->box.pos = Vec(-hScrollBar->containerOffset, -vScrollBar->containerOffset).round();

Widget::draw(vg);
if (glfwGetMouseButton(gWindow, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS) {
offset = offset.minus(mouseRel);
return this;
}
return NULL;
}

bool ScrollWidget::onScrollOpaque(Vec scrollRel) {
hScrollBar->containerOffset += scrollRel.x;
vScrollBar->containerOffset += scrollRel.y;
offset = offset.minus(scrollRel);
return true;
}



Loading…
Cancel
Save