Browse Source

Add RackScrollWidget::getZoom/setZoom/getGridOffset/setGridOffset(). Serialize zoom in patch instead of settings.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
10067ceadc
7 changed files with 75 additions and 49 deletions
  1. +11
    -0
      include/app/RackScrollWidget.hpp
  2. +0
    -4
      include/settings.hpp
  3. +4
    -4
      src/app/MenuBar.cpp
  4. +39
    -26
      src/app/RackScrollWidget.cpp
  5. +5
    -7
      src/app/Scene.cpp
  6. +16
    -1
      src/patch.cpp
  7. +0
    -7
      src/settings.cpp

+ 11
- 0
include/app/RackScrollWidget.hpp View File

@@ -18,7 +18,18 @@ struct RackScrollWidget : ui::ScrollWidget {

RackScrollWidget();
~RackScrollWidget();

void reset();
/** Gets the top-left scroll offset in grid coordinates.
*/
math::Vec getGridOffset();
void setGridOffset(math::Vec gridOffset);
float getZoom();
/** Sets the zoom level, with a pivot at the center of the scroll viewport.
*/
void setZoom(float zoom);
void setZoom(float zoom, math::Vec pivot);

void step() override;
void draw(const DrawArgs& args) override;
void onHoverKey(const HoverKeyEvent& e) override;


+ 0
- 4
include/settings.hpp View File

@@ -35,10 +35,6 @@ extern bool windowMaximized;
extern math::Vec windowSize;
/** Position in window in pixels */
extern math::Vec windowPos;
/** Rack zoom level, log2. E.g. 100% = 0, 200% = 1, 50% = -1. */
extern float zoom;
static const float zoomMax = 2.f;
static const float zoomMin = -2.f;
/** Reverse the zoom scroll direction */
extern bool invertZoom;
/** Ratio between UI pixel and physical screen pixel.


+ 4
- 4
src/app/MenuBar.cpp View File

@@ -168,16 +168,16 @@ struct EditButton : MenuButton {

struct ZoomQuantity : Quantity {
void setValue(float value) override {
settings::zoom = math::clamp(value, getMinValue(), getMaxValue());
APP->scene->rackScroll->setZoom(std::pow(2.f, value));
}
float getValue() override {
return settings::zoom;
return std::log2(APP->scene->rackScroll->getZoom());
}
float getMinValue() override {
return settings::zoomMin;
return -2.f;
}
float getMaxValue() override {
return settings::zoomMax;
return 2.f;
}
float getDefaultValue() override {
return 0.0;


+ 39
- 26
src/app/RackScrollWidget.cpp View File

@@ -10,8 +10,6 @@ namespace app {


struct RackScrollWidget::Internal {
/** The pivot point for zooming */
math::Vec zoomPos;
/** For viewport expanding */
float oldZoom = 0.f;
math::Vec oldOffset;
@@ -43,28 +41,47 @@ void RackScrollWidget::reset() {
}


void RackScrollWidget::step() {
// Compute zoom from exponential zoom
float zoom = std::pow(2.f, settings::zoom);
if (zoom != zoomWidget->zoom) {
// Set offset based on zoomPos
offset = offset.plus(internal->zoomPos).div(zoomWidget->zoom).mult(zoom).minus(internal->zoomPos);
// Set zoom
zoomWidget->setZoom(zoom);
}
math::Vec RackScrollWidget::getGridOffset() {
return offset.minus(RACK_OFFSET).div(RACK_GRID_SIZE);
}
void RackScrollWidget::setGridOffset(math::Vec gridOffset) {
offset = gridOffset.mult(RACK_GRID_SIZE).plus(RACK_OFFSET);
}

internal->zoomPos = box.size.div(2);
float RackScrollWidget::getZoom() {
return zoomWidget->getZoom();
}


void RackScrollWidget::setZoom(float zoom) {
setZoom(zoom, getSize().div(2));
}


void RackScrollWidget::setZoom(float zoom, math::Vec pivot) {
zoom = math::clamp(zoom, std::pow(2.f, -2), std::pow(2.f, 2));

offset = offset.plus(pivot).mult(zoom / zoomWidget->getZoom()).minus(pivot);
zoomWidget->setZoom(zoom);
}


void RackScrollWidget::step() {
float zoom = getZoom();

// Compute module bounding box
math::Rect moduleBox = rackWidget->getModuleContainer()->getChildrenBoundingBox();
if (!moduleBox.size.isFinite())
moduleBox = math::Rect(RACK_OFFSET, math::Vec(0, 0));

// Expand moduleBox by half a screen size
// Expand moduleBox by a screen size
math::Rect scrollBox = moduleBox;
scrollBox.pos = scrollBox.pos.mult(zoom);
scrollBox.size = scrollBox.size.mult(zoom);
scrollBox = scrollBox.grow(box.size.mult(0.6666));
scrollBox = scrollBox.grow(box.size.mult(0.9));

// Expand to the current viewport box so that moving modules (and thus changing the module bounding box) doesn't clamp the scroll offset.
if (zoom == internal->oldZoom) {
@@ -81,7 +98,7 @@ void RackScrollWidget::step() {
// Scroll rack if dragging cable near the edge of the screen
math::Vec pos = APP->scene->mousePos;
math::Rect viewport = getViewport(box.zeroPos());
if (rackWidget->incompleteCable) {
if (APP->event->getDraggedWidget()) {
float margin = 20.0;
float speed = 15.0;
if (pos.x <= viewport.pos.x + margin)
@@ -98,6 +115,7 @@ void RackScrollWidget::step() {
hideScrollbars = APP->window->isFullScreen();

ScrollWidget::step();

internal->oldOffset = offset;
internal->oldZoom = zoom;
}
@@ -119,13 +137,8 @@ void RackScrollWidget::onHoverScroll(const HoverScrollEvent& e) {
float zoomDelta = e.scrollDelta.y / 50 / 4;
if (settings::invertZoom)
zoomDelta *= -1;
settings::zoom += zoomDelta;
// Limit min/max depending on the direction of zooming
if (zoomDelta > 0.f)
settings::zoom = std::fmin(settings::zoom, settings::zoomMax);
else
settings::zoom = std::fmax(settings::zoom, settings::zoomMin);
internal->zoomPos = e.pos;
float zoom = getZoom() * std::pow(2.f, zoomDelta);
setZoom(zoom, e.pos);
e.consume(this);
}

@@ -153,13 +166,13 @@ void RackScrollWidget::onButton(const ButtonEvent& e) {
// Zoom in/out with extra mouse buttons
if (e.action == GLFW_PRESS) {
if (e.button == GLFW_MOUSE_BUTTON_4) {
settings::zoom -= 0.5f;
settings::zoom = std::fmax(settings::zoom, settings::zoomMin);
float zoom = getZoom() * std::pow(2.f, -0.5f);
setZoom(zoom, e.pos);
e.consume(this);
}
if (e.button == GLFW_MOUSE_BUTTON_5) {
settings::zoom += 0.5f;
settings::zoom = std::fmin(settings::zoom, settings::zoomMax);
float zoom = getZoom() * std::pow(2.f, 0.5f);
setZoom(zoom, e.pos);
e.consume(this);
}
}


+ 5
- 7
src/app/Scene.cpp View File

@@ -202,26 +202,24 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
e.consume(this);
}
if (e.keyName == "-" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
float zoom = settings::zoom;
float zoom = std::log2(APP->scene->rackScroll->getZoom());
zoom *= 2;
zoom = std::ceil(zoom - 0.01f) - 1;
zoom /= 2;
settings::zoom = zoom;
settings::zoom = std::fmax(settings::zoom, settings::zoomMin);
APP->scene->rackScroll->setZoom(std::pow(2.f, zoom));
e.consume(this);
}
// Numpad has a "+" key, but the main keyboard section hides it under "="
if ((e.keyName == "=" || e.keyName == "+") && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
float zoom = settings::zoom;
float zoom = std::log2(APP->scene->rackScroll->getZoom());
zoom *= 2;
zoom = std::floor(zoom + 0.01f) + 1;
zoom /= 2;
settings::zoom = zoom;
settings::zoom = std::fmin(settings::zoom, settings::zoomMax);
APP->scene->rackScroll->setZoom(std::pow(2.f, zoom));
e.consume(this);
}
if ((e.keyName == "0") && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
settings::zoom = 0.f;
APP->scene->rackScroll->setZoom(1.f);
e.consume(this);
}
if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) {


+ 16
- 1
src/patch.cpp View File

@@ -416,11 +416,18 @@ json_t* Manager::toJson() {
if (!APP->history->isSaved())
json_object_set_new(rootJ, "unsaved", json_boolean(true));

// Merge with rootJ
// zoom
if (APP->scene) {
float zoom = APP->scene->rackScroll->getZoom();
json_object_set_new(rootJ, "zoom", json_real(zoom));
}

// Merge with Engine JSON
json_t* engineJ = APP->engine->toJson();
json_object_update(rootJ, engineJ);
json_decref(engineJ);

// Merge with RackWidget JSON
if (APP->scene) {
APP->scene->rack->mergeJson(rootJ);
}
@@ -453,6 +460,14 @@ void Manager::fromJson(json_t* rootJ) {
if (!unsavedJ)
APP->history->setSaved();

// zoom
if (APP->scene) {
json_t* zoomJ = json_object_get(rootJ, "zoom");
if (zoomJ)
APP->scene->rackScroll->setZoom(json_number_value(zoomJ));
}

// Pass JSON to Engine and RackWidget
try {
APP->engine->fromJson(rootJ);
if (APP->scene) {


+ 0
- 7
src/settings.cpp View File

@@ -23,7 +23,6 @@ std::string token;
bool windowMaximized = false;
math::Vec windowSize = math::Vec(1024, 768);
math::Vec windowPos = math::Vec(NAN, NAN);
float zoom = 0.0;
bool invertZoom = false;
float pixelRatio = 0.0;
float cableOpacity = 0.5;
@@ -95,8 +94,6 @@ json_t* toJson() {
json_t* windowPosJ = json_pack("[f, f]", windowPos.x, windowPos.y);
json_object_set_new(rootJ, "windowPos", windowPosJ);

json_object_set_new(rootJ, "zoom", json_real(zoom));

json_object_set_new(rootJ, "invertZoom", json_boolean(invertZoom));

json_object_set_new(rootJ, "pixelRatio", json_real(pixelRatio));
@@ -217,10 +214,6 @@ void fromJson(json_t* rootJ) {
windowPos = math::Vec(x, y);
}

json_t* zoomJ = json_object_get(rootJ, "zoom");
if (zoomJ)
zoom = json_number_value(zoomJ);

json_t* invertZoomJ = json_object_get(rootJ, "invertZoom");
if (invertZoomJ)
invertZoom = json_boolean_value(invertZoomJ);


Loading…
Cancel
Save