Skip to content

Commit

Permalink
Merge branch 'touch' for #3
Browse files Browse the repository at this point in the history
* touch:
  touch and hold to move modules when the're locked
  touch support: option to enlarge hit boxes for small controls, option to lock module positions
  just in case
  • Loading branch information
Vitaly Pronkin committed May 21, 2018
2 parents 35baea2 + 41383a4 commit ee4602e
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 3 deletions.
3 changes: 3 additions & 0 deletions include/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ void settingsLoad(std::string filename);

extern bool skipAutosaveOnLaunch;

extern bool largerHitBoxes;
extern bool lockModules;


} // namespace rack
2 changes: 2 additions & 0 deletions include/util/math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ struct Vec {
Vec() : x(0.0f), y(0.0f) {}
Vec(float x, float y) : x(x), y(y) {}

static const Vec zero;

Vec neg() {
return Vec(-x, -y);
}
Expand Down
3 changes: 3 additions & 0 deletions include/widgets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ struct Widget {
bool visible = true;
bool canSquash = false;
bool canCache = false;
bool canGrowHitBox = false;

NVGLUframebuffer *fb = NULL;
Vec fbSize;
Expand Down Expand Up @@ -249,6 +250,8 @@ struct Widget {
void drawCachedOrFresh(NVGcontext *vg);
void ensureCached(NVGcontext *vg);

Rect getHitBox();

// Events

/** Called when a mouse button is pressed over this widget
Expand Down
1 change: 1 addition & 0 deletions src/app/Knob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace rack {

Knob::Knob() {
smooth = true;
canGrowHitBox = true;
}

void Knob::onDragStart(EventDragStart &e) {
Expand Down
20 changes: 19 additions & 1 deletion src/app/ModuleWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
#include "engine.hpp"
#include "plugin.hpp"
#include "window.hpp"

#include "settings.hpp"

namespace rack {


static double dragStartTime;
static bool cancelDrag;

ModuleWidget::ModuleWidget(Module *module) {
this->module = module;
}
Expand Down Expand Up @@ -323,12 +326,27 @@ void ModuleWidget::onHoverKey(EventHoverKey &e) {

void ModuleWidget::onDragStart(EventDragStart &e) {
dragPos = gRackWidget->lastMousePos.minus(box.pos);

dragStartTime = glfwGetTime();
cancelDrag = false;
}

void ModuleWidget::onDragEnd(EventDragEnd &e) {
}

void ModuleWidget::onDragMove(EventDragMove &e) {
if (cancelDrag)
return;

if (lockModules) {
if (glfwGetTime() - dragStartTime < 1) {
if (e.mouseRel.norm() >= 3)
cancelDrag = true;

return;
}
}

Rect newBox = box;
newBox.pos = gRackWidget->lastMousePos.minus(dragPos);
gRackWidget->requestModuleBoxNearest(this, newBox);
Expand Down
1 change: 1 addition & 0 deletions src/app/Port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct PlugLight : MultiLightWidget {

Port::Port() {
plugLight = new PlugLight();
canGrowHitBox = true;
}

Port::~Port() {
Expand Down
2 changes: 2 additions & 0 deletions src/app/SVGButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace rack {

SVGButton::SVGButton() {
canSquash = true;
canGrowHitBox = true;

//XXX: We still inherit from FramebufferWidget to preserve class hierarchy but we don't really want this
canCache = false;

Expand Down
1 change: 1 addition & 0 deletions src/app/SVGSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace rack {

SVGSlider::SVGSlider() {
canSquash = true;
canGrowHitBox = true;

//XXX: We still inherit from FramebufferWidget to preserve class hierarchy but we don't really want this
canCache = false;
Expand Down
1 change: 1 addition & 0 deletions src/app/SVGSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace rack {

SVGSwitch::SVGSwitch() {
canSquash = true;
canGrowHitBox = true;

//XXX: We still inherit from FramebufferWidget to preserve class hierarchy but we don't really want this
canCache = false;
Expand Down
31 changes: 30 additions & 1 deletion src/app/Toolbar.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "app.hpp"
#include "window.hpp"
#include "engine.hpp"

#include "settings.hpp"

namespace rack {

Expand Down Expand Up @@ -64,6 +64,30 @@ struct FileChoice : ChoiceButton {
}
};

struct LargerHitBoxesItem : MenuItem {
void onAction(EventAction &e) override {
largerHitBoxes = !largerHitBoxes;
//TODO: save settings
}
};

struct LockModulesItem : MenuItem {
void onAction(EventAction &e) override {
lockModules = !lockModules;
//TODO: save settings
}
};

struct OptionsChoice : ChoiceButton {
void onAction(EventAction &e) override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;

menu->addChild(MenuItem::create<LargerHitBoxesItem>("Larger Hit Boxes", CHECKMARK(largerHitBoxes)));
menu->addChild(MenuItem::create<LockModulesItem>("Lock Modules", CHECKMARK(lockModules)));
}
};

struct EnginePauseItem : MenuItem {
void onAction(EventAction &e) override {
Expand Down Expand Up @@ -119,6 +143,11 @@ Toolbar::Toolbar() {
fileChoice->text = "File";
layout->addChild(fileChoice);

ChoiceButton *optionsChoice = new OptionsChoice();
optionsChoice->box.size.x = 100;
optionsChoice->text = "Options";
layout->addChild(optionsChoice);

// EngineSampleRateChoice *srChoice = new EngineSampleRateChoice();
// srChoice->box.size.x = 100;
// layout->addChild(srChoice);
Expand Down
21 changes: 21 additions & 0 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ namespace rack {

bool skipAutosaveOnLaunch = false;

bool largerHitBoxes = false;
bool lockModules = false;


static json_t *settingsToJson() {
// root
Expand Down Expand Up @@ -67,6 +70,14 @@ static json_t *settingsToJson() {
// moduleBrowser
json_object_set_new(rootJ, "moduleBrowser", appModuleBrowserToJson());

// largerHitBoxes
if (largerHitBoxes)
json_object_set_new(rootJ, "largerHitBoxes", json_true());

// lockModules
if (lockModules)
json_object_set_new(rootJ, "lockModules", json_true());

return rootJ;
}

Expand Down Expand Up @@ -135,6 +146,16 @@ static void settingsFromJson(json_t *rootJ) {
json_t * moduleBrowserJ = json_object_get(rootJ, "moduleBrowser");
if (moduleBrowserJ)
appModuleBrowserFromJson(moduleBrowserJ);

// largerHitBoxes
json_t *largerHitBoxesJ = json_object_get(rootJ, "largerHitBoxes");
if (largerHitBoxesJ)
largerHitBoxes = json_boolean_value(largerHitBoxesJ);

// lockModules
json_t *lockModulesJ = json_object_get(rootJ, "lockModules");
if (lockModulesJ)
lockModules = json_boolean_value(lockModulesJ);
}


Expand Down
52 changes: 51 additions & 1 deletion src/widgets/Widget.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "widgets.hpp"
#include "app.hpp"
#include "window.hpp"
#include "settings.hpp"
#include <algorithm>

#include "nanovg_gl.h"
Expand Down Expand Up @@ -269,6 +270,7 @@ void Widget::drawCachedOrFresh(NVGcontext *vg) {
nvgRestore(vg);
}


#define RECURSE_EVENT_POSITION(_method) { \
Vec pos = e.pos; \
for (auto it = children.rbegin(); it != children.rend(); it++) { \
Expand All @@ -285,9 +287,41 @@ void Widget::drawCachedOrFresh(NVGcontext *vg) {
e.pos = pos; \
}

// For simplification we assume that components with non-zero hitMargins will consume the event
#define RECURSE_EVENT_POSITION_WITH_MARGINS(_method) { \
Vec pos = e.pos; \
for (auto it = children.rbegin(); it != children.rend(); it++) { \
Widget *child = *it; \
if (!child->visible) \
continue; \
if (child->box.contains(pos)) { \
e.pos = pos.minus(child->box.pos); \
child->_method(e); \
if (e.consumed) \
break; \
} \
} \
if (largerHitBoxes && !e.consumed) { \
Widget* target = NULL; \
for (auto it = children.rbegin(); it != children.rend(); it++) { \
Widget *child = *it; \
if (!child->visible) \
continue; \
if (child->getHitBox().contains(pos)) { \
if (!target || child->box.getCenter().minus(pos).norm() < target->box.getCenter().minus(pos).norm()) \
target = child; \
} \
} \
if (target) { \
e.pos = pos.minus(target->box.pos); \
target->_method(e); \
} \
} \
e.pos = pos; \
}

void Widget::onMouseDown(EventMouseDown &e) {
RECURSE_EVENT_POSITION(onMouseDown);
RECURSE_EVENT_POSITION_WITH_MARGINS(onMouseDown);
}

void Widget::onMouseUp(EventMouseUp &e) {
Expand All @@ -310,6 +344,7 @@ void Widget::onPathDrop(EventPathDrop &e) {
RECURSE_EVENT_POSITION(onPathDrop);
}


void Widget::onZoom(EventZoom &e) {
for (auto it = children.rbegin(); it != children.rend(); it++) {
Widget *child = *it;
Expand All @@ -322,4 +357,19 @@ void Widget::onResize() {
dirty = true;
}

Rect Widget::getHitBox() {
if (!canGrowHitBox)
return box;

float min = 32.0f / gRackScene->zoomWidget->zoom;

Vec grow;
if (box.size.x < min)
grow.x = (min - box.size.x) * 0.5;
if (box.size.y < min)
grow.y = (min - box.size.y) * 0.5;

return box.grow(grow);
}

} // namespace rack
3 changes: 3 additions & 0 deletions src/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
namespace rack {


//TODO: where should this go?
const Vec Vec::zero = Vec(0, 0);

GLFWwindow *gWindow = NULL;
NVGcontext *gVg = NULL;
std::shared_ptr<Font> gGuiFont;
Expand Down

0 comments on commit ee4602e

Please sign in to comment.