Browse Source

Add menu scrolling, refactor OpaqueWidget events

tags/v0.4.0
Andrew Belt 7 years ago
parent
commit
4fc5f17cfc
7 changed files with 43 additions and 26 deletions
  1. +8
    -3
      include/math.hpp
  2. +12
    -6
      include/widgets.hpp
  3. +1
    -1
      src/gui.cpp
  4. +9
    -0
      src/widgets/Menu.cpp
  5. +1
    -0
      src/widgets/MenuOverlay.cpp
  6. +8
    -9
      src/widgets/ScrollBar.cpp
  7. +4
    -7
      src/widgets/ScrollWidget.cpp

+ 8
- 3
include/math.hpp View File

@@ -62,10 +62,10 @@ inline float eucmodf(float a, float base) {
}

/** Limits a value between a minimum and maximum
If min < max, returns max
If min > max, the limits are switched
*/
inline float clampf(float x, float min, float max) {
return fmaxf(fminf(x, max), min);
return fmaxf(fminf(x, fmaxf(min, max)), fminf(min, max));
}

/** If the magnitude of x if less than eps, return 0 */
@@ -199,11 +199,16 @@ struct Rect {
return Rect(min, max.minus(min));
}

/** Returns whether this Rect contains another Rect, inclusive on the top/left, non-inclusive on the bottom/right */
/** Returns whether this Rect contains an entire point, inclusive on the top/left, non-inclusive on the bottom/right */
bool contains(Vec v) {
return pos.x <= v.x && v.x < pos.x + size.x
&& pos.y <= v.y && v.y < pos.y + size.y;
}
/** Returns whether this Rect contains an entire Rect */
bool contains(Rect r) {
return pos.x <= r.pos.x && r.pos.x + r.size.x <= pos.x + size.x
&& pos.y <= r.pos.y && r.pos.y + r.size.y <= pos.y + size.y;
}
/** Returns whether this Rect overlaps with another Rect */
bool intersects(Rect r) {
return (pos.x + size.x > r.pos.x && r.pos.x + r.size.x > pos.x)


+ 12
- 6
include/widgets.hpp View File

@@ -145,7 +145,7 @@ struct TransparentWidget : virtual Widget {
Widget *onScroll(Vec pos, Vec scrollRel) {return NULL;}
};

/** Widget that itself responds to mouse events */
/** Widget that automatically responds to all mouse events but gives a chance for children to respond instead */
struct OpaqueWidget : virtual Widget {
Widget *onMouseDown(Vec pos, int button) {
Widget *w = Widget::onMouseDown(pos, button);
@@ -165,6 +165,13 @@ struct OpaqueWidget : virtual Widget {
onMouseMoveOpaque(mouseRel);
return this;
}
Widget *onScroll(Vec pos, Vec scrollRel) {
Widget *w = Widget::onScroll(pos, scrollRel);
if (w) return w;
if (onScrollOpaque(scrollRel))
return this;
return NULL;
}

/** "High level" events called by the above lower level events.
Use these if you don't care about the clicked position.
@@ -172,6 +179,7 @@ struct OpaqueWidget : virtual Widget {
virtual void onMouseDownOpaque(int button) {}
virtual void onMouseUpOpaque(int button) {}
virtual void onMouseMoveOpaque(Vec mouseRel) {}
virtual bool onScrollOpaque(Vec scrollRel) {return false;}
};

struct SpriteWidget : virtual Widget {
@@ -249,9 +257,6 @@ struct Label : Widget {
// Deletes itself from parent when clicked
struct MenuOverlay : OpaqueWidget {
void step();
Widget *onScroll(Vec pos, Vec scrollRel) {
return this;
}
void onDragDrop(Widget *origin);
};

@@ -262,6 +267,7 @@ struct Menu : OpaqueWidget {
// Resizes menu and calls addChild()
void pushChild(Widget *child);
void draw(NVGcontext *vg);
bool onScrollOpaque(Vec scrollRel);
};

struct MenuEntry : OpaqueWidget {
@@ -340,8 +346,8 @@ struct ScrollBar : OpaqueWidget {
ScrollBar() {
box.size = Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT);
}
void step();
void draw(NVGcontext *vg);
void move(float delta);
void onDragStart();
void onDragMove(Vec mouseRel);
void onDragEnd();
@@ -356,7 +362,7 @@ struct ScrollWidget : OpaqueWidget {
ScrollWidget();
void step();
void draw(NVGcontext *vg);
Widget *onScroll(Vec pos, Vec scrollRel);
bool onScrollOpaque(Vec scrollRel);
};

struct TextField : OpaqueWidget {


+ 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(-95));
gScene->onScroll(gMousePos, scrollRel.mult(-38.0));
}

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


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

@@ -29,4 +29,13 @@ void Menu::draw(NVGcontext *vg) {
}


bool Menu::onScrollOpaque(Vec scrollRel) {
if (!parent)
return true;
if (!parent->box.contains(box))
box.pos = box.pos.plus(scrollRel.neg());
return true;
}


} // namespace rack

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

@@ -8,6 +8,7 @@ void MenuOverlay::step() {
for (Widget *child : children) {
child->box = child->box.clamp(Rect(Vec(0, 0), box.size));
}

Widget::step();
}



+ 8
- 9
src/widgets/ScrollBar.cpp View File

@@ -4,6 +4,13 @@

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;
@@ -13,21 +20,13 @@ void ScrollBar::draw(NVGcontext *vg) {
bndScrollBar(vg, 0.0, 0.0, box.size.x, box.size.y, state, offset, size);
}

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

void ScrollBar::onDragStart() {
state = BND_ACTIVE;
guiCursorLock();
}

void ScrollBar::onDragMove(Vec mouseRel) {
float delta = (orientation == VERTICAL ? mouseRel.y : mouseRel.x);
move(delta);
containerOffset += (orientation == VERTICAL ? mouseRel.y : mouseRel.x);
}

void ScrollBar::onDragEnd() {


+ 4
- 7
src/widgets/ScrollWidget.cpp View File

@@ -40,13 +40,10 @@ void ScrollWidget::draw(NVGcontext *vg) {
Widget::draw(vg);
}

Widget *ScrollWidget::onScroll(Vec pos, Vec scrollRel) {
Widget *w = Widget::onScroll(pos, scrollRel);
if (w) return w;

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




Loading…
Cancel
Save