Browse Source

Added key commands to ModuleWidget, removed CPU usage meter (misleads

way too many people, should not have added in the first place)
tags/v0.3.2
Andrew Belt 7 years ago
parent
commit
728afc763a
9 changed files with 111 additions and 61 deletions
  1. +8
    -1
      include/app.hpp
  2. +1
    -8
      include/gui.hpp
  3. +6
    -4
      include/widgets.hpp
  4. +33
    -11
      src/app/ModuleWidget.cpp
  5. +29
    -9
      src/app/RackWidget.cpp
  6. +2
    -0
      src/app/Toolbar.cpp
  7. +16
    -26
      src/gui.cpp
  8. +2
    -2
      src/widgets/TextField.cpp
  9. +14
    -0
      src/widgets/Widget.cpp

+ 8
- 1
include/app.hpp View File

@@ -57,6 +57,8 @@ struct ModuleWidget : OpaqueWidget {
bool requested = false;
Vec requestedPos;
Vec dragPos;
Widget *onMouseMove(Vec pos, Vec mouseRel);
Widget *onHoverKey(Vec pos, int key);
void onDragStart();
void onDragMove(Vec mouseRel);
void onDragEnd();
@@ -97,7 +99,12 @@ struct RackWidget : OpaqueWidget {
json_t *toJson();
void fromJson(json_t *root);

void repositionModule(ModuleWidget *module);
void addModule(ModuleWidget *m);
/** Transfers ownership to the caller so they must `delete` it if that is the intension */
void deleteModule(ModuleWidget *m);
void cloneModule(ModuleWidget *m);
/** Moves a module to the closest non-colliding position */
void repositionModule(ModuleWidget *m);
void step();
void draw(NVGcontext *vg);



+ 1
- 8
include/gui.hpp View File

@@ -18,13 +18,6 @@ void guiDestroy();
void guiRun();
void guiCursorLock();
void guiCursorUnlock();

inline bool guiIsModPressed() {
#ifdef ARCH_MAC
return glfwGetKey(gWindow, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS;
#else
return glfwGetKey(gWindow, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS;
#endif
}
bool guiIsModPressed();

} // namespace rack

+ 6
- 4
include/widgets.hpp View File

@@ -91,15 +91,17 @@ struct Widget {
*/
virtual Widget *onMouseDown(Vec pos, int button);
virtual Widget *onMouseUp(Vec pos, int button);
/** Called on every frame, even if mouseRel = Vec(0, 0) */
virtual Widget *onMouseMove(Vec pos, Vec mouseRel);
virtual Widget *onHoverKey(Vec pos, int key);
/** Called when this widget begins responding to `onMouseMove` events */
virtual void onMouseEnter() {}
/** Called when another widget begins responding to `onMouseMove` events */
virtual void onMouseLeave() {}
virtual void onSelect() {}
virtual void onDeselect() {}
virtual void onText(int codepoint) {}
virtual void onKey(int key) {}
virtual bool onText(int codepoint) {return false;}
virtual bool onKey(int key) {return false;}
virtual Widget *onScroll(Vec pos, Vec scrollRel);

/** Called when a widget responds to `onMouseDown` for a left button press */
@@ -364,8 +366,8 @@ struct TextField : OpaqueWidget {
}
void draw(NVGcontext *vg);
Widget *onMouseDown(Vec pos, int button);
void onText(int codepoint);
void onKey(int scancode);
bool onText(int codepoint);
bool onKey(int scancode);
void onSelect();
void insertText(std::string newText);
};


+ 33
- 11
src/app/ModuleWidget.cpp View File

@@ -1,6 +1,7 @@
#include "app.hpp"
#include "engine.hpp"
#include "plugin.hpp"
#include "gui.hpp"


namespace rack {
@@ -125,6 +126,7 @@ void ModuleWidget::draw(NVGcontext *vg) {

Widget::draw(vg);

/*
// CPU usage text
if (dynamic_cast<RackScene*>(gScene)->toolbar->cpuUsageButton->value > 0.0) {
float cpuTime = module ? module->cpuTime : 0.0;
@@ -145,10 +147,38 @@ void ModuleWidget::draw(NVGcontext *vg) {
bndMenuItem(vg, 0.0, 0.0, box.size.x, BND_WIDGET_HEIGHT, BND_DEFAULT, -1, text.c_str());
nvgRestore(vg);
}
*/

nvgResetScissor(vg);
}

Widget *ModuleWidget::onMouseMove(Vec pos, Vec mouseRel) {
return OpaqueWidget::onMouseMove(pos, mouseRel);
}

Widget *ModuleWidget::onHoverKey(Vec pos, int key) {
switch (key) {
case GLFW_KEY_DELETE:
case GLFW_KEY_BACKSPACE:
gRackWidget->deleteModule(this);
delete this;
break;
case GLFW_KEY_I:
if (guiIsModPressed())
initialize();
break;
case GLFW_KEY_R:
if (guiIsModPressed())
randomize();
break;
case GLFW_KEY_D:
if (guiIsModPressed())
gRackWidget->cloneModule(this);
break;
}
return NULL;
}

void ModuleWidget::onDragStart() {
dragPos = gMousePos.minus(getAbsolutePos());
}
@@ -185,22 +215,14 @@ struct RandomizeMenuItem : MenuItem {
struct CloneMenuItem : MenuItem {
ModuleWidget *moduleWidget;
void onAction() {
// Create new module from model
ModuleWidget *clonedModuleWidget = moduleWidget->model->createModuleWidget();
// JSON serialization is the most straightforward way to do this
json_t *moduleJ = moduleWidget->toJson();
clonedModuleWidget->fromJson(moduleJ);
json_decref(moduleJ);
clonedModuleWidget->requestedPos = moduleWidget->box.pos;
clonedModuleWidget->requested = true;
gRackWidget->moduleContainer->addChild(clonedModuleWidget);
gRackWidget->cloneModule(moduleWidget);
}
};

struct DeleteMenuItem : MenuItem {
ModuleWidget *moduleWidget;
void onAction() {
gRackWidget->moduleContainer->removeChild(moduleWidget);
gRackWidget->deleteModule(moduleWidget);
delete moduleWidget;
}
};
@@ -229,7 +251,7 @@ void ModuleWidget::onMouseDown(int button) {
menu->pushChild(disconnectItem);

CloneMenuItem *cloneItem = new CloneMenuItem();
cloneItem->text = "Clone";
cloneItem->text = "Duplicate";
cloneItem->moduleWidget = this;
menu->pushChild(cloneItem);



+ 29
- 9
src/app/RackWidget.cpp View File

@@ -226,29 +226,49 @@ void RackWidget::fromJson(json_t *rootJ) {
}
}

void RackWidget::repositionModule(ModuleWidget *module) {
void RackWidget::addModule(ModuleWidget *m) {
moduleContainer->addChild(m);
}

void RackWidget::deleteModule(ModuleWidget *m) {
moduleContainer->removeChild(m);
}

void RackWidget::cloneModule(ModuleWidget *m) {
// Create new module from model
ModuleWidget *clonedModuleWidget = m->model->createModuleWidget();
// JSON serialization is the most straightforward way to do this
json_t *moduleJ = m->toJson();
clonedModuleWidget->fromJson(moduleJ);
json_decref(moduleJ);
clonedModuleWidget->requestedPos = m->box.pos;
clonedModuleWidget->requested = true;
addModule(clonedModuleWidget);
}

void RackWidget::repositionModule(ModuleWidget *m) {
// Create possible positions
int x0 = roundf(module->requestedPos.x / RACK_GRID_WIDTH);
int y0 = roundf(module->requestedPos.y / RACK_GRID_HEIGHT);
int x0 = roundf(m->requestedPos.x / RACK_GRID_WIDTH);
int y0 = roundf(m->requestedPos.y / RACK_GRID_HEIGHT);
std::vector<Vec> positions;
for (int y = maxi(0, y0 - 2); y < y0 + 2; y++) {
for (int x = maxi(0, x0 - 40); x < x0 + 40; x++) {
for (int y = maxi(0, y0 - 4); y < y0 + 4; y++) {
for (int x = maxi(0, x0 - 200); x < x0 + 200; x++) {
positions.push_back(Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT));
}
}

// Sort possible positions by distance to the requested position
Vec requestedPos = module->requestedPos;
Vec requestedPos = m->requestedPos;
std::sort(positions.begin(), positions.end(), [requestedPos](Vec a, Vec b) {
return a.minus(requestedPos).norm() < b.minus(requestedPos).norm();
});

// Find a position that does not collide
for (Vec pos : positions) {
Rect newBox = Rect(pos, module->box.size);
Rect newBox = Rect(pos, m->box.size);
bool collides = false;
for (Widget *child2 : moduleContainer->children) {
if (module == child2) continue;
if (m == child2) continue;
if (newBox.intersects(child2->box)) {
collides = true;
break;
@@ -256,7 +276,7 @@ void RackWidget::repositionModule(ModuleWidget *module) {
}
if (collides) continue;

module->box.pos = pos;
m->box.pos = pos;
break;
}
}


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

@@ -139,6 +139,7 @@ Toolbar::Toolbar() {
xPos += wireTensionSlider->box.size.x;
}

/*
xPos += margin;
{
cpuUsageButton = new RadioButton();
@@ -148,6 +149,7 @@ Toolbar::Toolbar() {
addChild(cpuUsageButton);
xPos += cpuUsageButton->box.size.x;
}
*/

xPos += margin;
{


+ 16
- 26
src/gui.cpp View File

@@ -157,34 +157,13 @@ void charCallback(GLFWwindow *window, unsigned int codepoint) {
}
}

// static int lastWindowX, lastWindowY, lastWindowWidth, lastWindowHeight;

void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
if (key == GLFW_KEY_F11 || key == GLFW_KEY_ESCAPE) {
/*
// Toggle fullscreen
GLFWmonitor *monitor = glfwGetWindowMonitor(gWindow);
if (monitor) {
// Window mode
glfwSetWindowMonitor(gWindow, NULL, lastWindowX, lastWindowY, lastWindowWidth, lastWindowHeight, 0);
}
else {
// Fullscreen
glfwGetWindowPos(gWindow, &lastWindowX, &lastWindowY);
glfwGetWindowSize(gWindow, &lastWindowWidth, &lastWindowHeight);
monitor = glfwGetPrimaryMonitor();
assert(monitor);
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(gWindow, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
}
*/
}
else {
if (gSelectedWidget) {
gSelectedWidget->onKey(key);
}
}
// onKey
if (gSelectedWidget && gSelectedWidget->onKey(key))
return;
// onHoverKey
gScene->onHoverKey(gMousePos, key);
}
}

@@ -228,6 +207,9 @@ void guiInit() {
err = glfwInit();
assert(err);

const char *glVersion = (const char *)glGetString(GL_VERSION);
printf("OpenGL version %s\n", glVersion);

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@@ -329,6 +311,14 @@ void guiCursorUnlock() {
glfwSetInputMode(gWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}

bool guiIsModPressed() {
#ifdef ARCH_MAC
return glfwGetKey(gWindow, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS;
#else
return glfwGetKey(gWindow, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS;
#endif
}


////////////////////
// resources


+ 2
- 2
src/widgets/TextField.cpp View File

@@ -29,13 +29,13 @@ Widget *TextField::onMouseDown(Vec pos, int button) {
}


void TextField::onText(int codepoint) {
bool TextField::onText(int codepoint) {
char c = codepoint;
std::string newText(1, c);
insertText(newText);
}

void TextField::onKey(int key) {
bool TextField::onKey(int key) {
switch (key) {
case GLFW_KEY_BACKSPACE:
if (begin < end) {


+ 14
- 0
src/widgets/Widget.cpp View File

@@ -121,6 +121,20 @@ Widget *Widget::onMouseMove(Vec pos, Vec mouseRel) {
return NULL;
}

Widget *Widget::onHoverKey(Vec pos, int key) {
for (auto it = children.rbegin(); it != children.rend(); it++) {
Widget *child = *it;
if (!child->visible)
continue;
if (child->box.contains(pos)) {
Widget *w = child->onHoverKey(pos.minus(child->box.pos), key);
if (w)
return w;
}
}
return NULL;
}

Widget *Widget::onScroll(Vec pos, Vec scrollRel) {
for (auto it = children.rbegin(); it != children.rend(); it++) {
Widget *child = *it;


Loading…
Cancel
Save