From 41efc572e09e2baca3064a95fbf428aa06eddc9b Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Wed, 17 Mar 2021 05:12:00 +0100 Subject: [PATCH] Improved keyboard manipulation of selection of sources in Views. --- GeometryView.cpp | 105 +++++++++++++++++++++++++-------------- LayerView.cpp | 79 +++++++++++++++++++---------- MixingView.cpp | 81 ++++++++++++++++++++---------- TextureView.cpp | 31 ++++++------ UserInterfaceManager.cpp | 11 ++-- 5 files changed, 198 insertions(+), 109 deletions(-) diff --git a/GeometryView.cpp b/GeometryView.cpp index d918349..1b56739 100644 --- a/GeometryView.cpp +++ b/GeometryView.cpp @@ -954,23 +954,23 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p if (UserInterface::manager().altModifier()) { sourceNode->translation_.x = ROUND(sourceNode->translation_.x, 10.f); sourceNode->translation_.y = ROUND(sourceNode->translation_.y, 10.f); - } - // ALT: single axis movement - overlay_position_cross_->visible_ = false; - if (UserInterface::manager().shiftModifier()) { - overlay_position_cross_->visible_ = true; - overlay_position_cross_->translation_.x = s->stored_status_->translation_.x; - overlay_position_cross_->translation_.y = s->stored_status_->translation_.y; - overlay_position_cross_->update(0); +// // + SHIFT: single axis movement +// overlay_position_cross_->visible_ = false; +// if (UserInterface::manager().shiftModifier()) { +// overlay_position_cross_->visible_ = true; +// overlay_position_cross_->translation_.x = s->stored_status_->translation_.x; +// overlay_position_cross_->translation_.y = s->stored_status_->translation_.y; +// overlay_position_cross_->update(0); - glm::vec3 dif = s->stored_status_->translation_ - sourceNode->translation_; - if (ABS(dif.x) > ABS(dif.y) ) { - sourceNode->translation_.y = s->stored_status_->translation_.y; - ret.type = Cursor_ResizeEW; - } else { - sourceNode->translation_.x = s->stored_status_->translation_.x; - ret.type = Cursor_ResizeNS; - } +// glm::vec3 dif = s->stored_status_->translation_ - sourceNode->translation_; +// if (ABS(dif.x) > ABS(dif.y) ) { +// sourceNode->translation_.y = s->stored_status_->translation_.y; +// ret.type = Cursor_ResizeEW; +// } else { +// sourceNode->translation_.x = s->stored_status_->translation_.x; +// ret.type = Cursor_ResizeNS; +// } +// } } // Show center overlay for POSITION overlay_position_->visible_ = true; @@ -1011,6 +1011,7 @@ void GeometryView::terminate() overlay_scaling_->visible_ = false; overlay_crop_->visible_ = false; + // restore possible color change after selection operation overlay_rotation_->color = glm::vec4(1.f, 1.f, 1.f, 0.8f); overlay_rotation_fix_->color = glm::vec4(1.f, 1.f, 1.f, 0.8f); overlay_rotation_clock_tic_->color = glm::vec4(1.f, 1.f, 1.f, 0.8f); @@ -1039,34 +1040,64 @@ void GeometryView::terminate() void GeometryView::arrow (glm::vec2 movement) { - Source *s = Mixer::manager().currentSource(); - if (s) { + static int accumulator = 0; + accumulator++; - glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); - glm::vec3 gl_Position_to = Rendering::manager().unProject(movement, scene.root()->transform_); - glm::vec3 gl_delta = gl_Position_to - gl_Position_from; + glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); + glm::vec3 gl_Position_to = Rendering::manager().unProject(movement, scene.root()->transform_); + glm::vec3 gl_delta = gl_Position_to - gl_Position_from; - Group *sourceNode = s->group(mode_); - static glm::vec3 alt_move_ = sourceNode->translation_; - if (UserInterface::manager().altModifier()) { - alt_move_ += gl_delta * ARROWS_MOVEMENT_FACTOR; - sourceNode->translation_.x = ROUND(alt_move_.x, 10.f); - sourceNode->translation_.y = ROUND(alt_move_.y, 10.f); + bool first = true; + glm::vec3 delta_translation(0.f); + for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++) { + + // individual move with SHIFT + if ( !Source::isCurrent(*it) && UserInterface::manager().shiftModifier() ) + continue; + + Group *sourceNode = (*it)->group(mode_); + glm::vec3 dest_translation(0.f); + + if (first) { + // dest starts at current + dest_translation = sourceNode->translation_; + + // + ALT : discrete displacement + if (UserInterface::manager().altModifier()) { + if (accumulator > 10) { + dest_translation += glm::sign(gl_delta) * 0.11f; + dest_translation.x = ROUND(dest_translation.x, 10.f); + dest_translation.y = ROUND(dest_translation.y, 10.f); + accumulator = 0; + } + else + break; + } + else { + // normal case: dest += delta + dest_translation += gl_delta * ARROWS_MOVEMENT_FACTOR; + } + + // store action in history + std::ostringstream info; + info << "Position " << std::fixed << std::setprecision(3) << sourceNode->translation_.x; + info << ", " << sourceNode->translation_.y ; + current_action_ = (*it)->name() + ": " + info.str(); + current_id_ = (*it)->id(); + + // delta for others to follow + delta_translation = dest_translation - sourceNode->translation_; } else { - sourceNode->translation_ += gl_delta * ARROWS_MOVEMENT_FACTOR; - alt_move_ = sourceNode->translation_; + // dest = current + delta from first + dest_translation = sourceNode->translation_ + delta_translation; } - // store action in history - std::ostringstream info; - info << "Position " << std::fixed << std::setprecision(3) << sourceNode->translation_.x; - info << ", " << sourceNode->translation_.y ; - current_action_ = s->name() + ": " + info.str(); - current_id_ = s->id(); + // apply & request update + sourceNode->translation_ = dest_translation; + (*it)->touch(); - // request update - s->touch(); + first = false; } } diff --git a/LayerView.cpp b/LayerView.cpp index a827a57..f94413d 100644 --- a/LayerView.cpp +++ b/LayerView.cpp @@ -269,10 +269,6 @@ float LayerView::setDepth(Source *s, float d) // change depth sourceNode->translation_.z = CLAMP( depth, MIN_DEPTH, MAX_DEPTH); - // discretized translation with ALT - if (UserInterface::manager().altModifier()) - sourceNode->translation_.z = ROUND(sourceNode->translation_.z, 5.f); - // request reordering of scene at next update View::need_deep_update_++; @@ -294,6 +290,10 @@ View::Cursor LayerView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair // compute delta translation glm::vec3 dest_translation = s->stored_status_->translation_ + gl_Position_to - gl_Position_from; + // discretized translation with ALT + if (UserInterface::manager().altModifier()) + dest_translation.x = ROUND(dest_translation.x, 5.f); + // apply change float d = setDepth( s, MAX( -dest_translation.x, 0.f) ); @@ -310,36 +310,61 @@ View::Cursor LayerView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair void LayerView::arrow (glm::vec2 movement) { - Source *s = Mixer::manager().currentSource(); - if (s) { + static int accumulator = 0; + accumulator++; - glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); - glm::vec3 gl_Position_to = Rendering::manager().unProject(glm::vec2(movement.x-movement.y, 0.f), scene.root()->transform_); - glm::vec3 gl_delta = gl_Position_to - gl_Position_from; + glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); + glm::vec3 gl_Position_to = Rendering::manager().unProject(glm::vec2(movement.x-movement.y, 0.f), scene.root()->transform_); + glm::vec3 gl_delta = gl_Position_to - gl_Position_from; - Group *sourceNode = s->group(mode_); - glm::vec3 dest_translation = sourceNode->translation_; - static glm::vec3 alt_move_ = sourceNode->translation_; - if (UserInterface::manager().altModifier()) { - alt_move_ += gl_delta * ARROWS_MOVEMENT_FACTOR; - dest_translation.x = ROUND(alt_move_.x, 10.f); - dest_translation.y = ROUND(alt_move_.y, 10.f); + bool first = true; + glm::vec3 delta_translation(0.f); + for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++) { + + // individual move with SHIFT + if ( !Source::isCurrent(*it) && UserInterface::manager().shiftModifier() ) + continue; + + Group *sourceNode = (*it)->group(mode_); + glm::vec3 dest_translation(0.f); + + if (first) { + // dest starts at current + dest_translation = sourceNode->translation_; + + // + ALT : discrete displacement + if (UserInterface::manager().altModifier()) { + if (accumulator > 10) { + dest_translation += glm::sign(gl_delta) * 0.21f; + dest_translation.x = ROUND(dest_translation.x, 10.f); + accumulator = 0; + } + else + break; + } + else { + // normal case: dest += delta + dest_translation += gl_delta * ARROWS_MOVEMENT_FACTOR; + } + + // store action in history + std::ostringstream info; + info << "Depth " << std::fixed << std::setprecision(2) << (*it)->depth() << " "; + current_action_ = (*it)->name() + ": " + info.str(); + current_id_ = (*it)->id(); + + // delta for others to follow + delta_translation = dest_translation - sourceNode->translation_; } else { - dest_translation += gl_delta * ARROWS_MOVEMENT_FACTOR; - alt_move_ = dest_translation; + // dest = current + delta from first + dest_translation = sourceNode->translation_ + delta_translation; } - setDepth( s, MAX( -dest_translation.x, 0.f) ); + // apply & request update + setDepth( *it, MAX( -dest_translation.x, 0.f) ); - // store action in history - std::ostringstream info; - info << "Depth " << std::fixed << std::setprecision(2) << s->depth() << " "; - current_action_ = s->name() + ": " + info.str(); - current_id_ = s->id(); - - // request update - s->touch(); + first = false; } } diff --git a/MixingView.cpp b/MixingView.cpp index 86d02ad..aefce4b 100644 --- a/MixingView.cpp +++ b/MixingView.cpp @@ -465,39 +465,70 @@ void MixingView::terminate() void MixingView::arrow (glm::vec2 movement) { - Source *s = Mixer::manager().currentSource(); - if (s) { + static int accumulator = 0; + accumulator++; - glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); - glm::vec3 gl_Position_to = Rendering::manager().unProject(movement, scene.root()->transform_); - glm::vec3 gl_delta = gl_Position_to - gl_Position_from; + glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); + glm::vec3 gl_Position_to = Rendering::manager().unProject(movement, scene.root()->transform_); + glm::vec3 gl_delta = gl_Position_to - gl_Position_from; - Group *sourceNode = s->group(mode_); - static glm::vec3 alt_move_ = sourceNode->translation_; - if (UserInterface::manager().altModifier()) { - alt_move_ += gl_delta * ARROWS_MOVEMENT_FACTOR; - sourceNode->translation_.x = ROUND(alt_move_.x, 10.f); - sourceNode->translation_.y = ROUND(alt_move_.y, 10.f); + bool first = true; + glm::vec3 delta_translation(0.f); + for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++) { + + // individual move with SHIFT + if ( !Source::isCurrent(*it) && UserInterface::manager().shiftModifier() ) + continue; + + Group *sourceNode = (*it)->group(mode_); + glm::vec3 dest_translation(0.f); + + if (first) { + // dest starts at current + dest_translation = sourceNode->translation_; + + // + ALT : discrete displacement + if (UserInterface::manager().altModifier()) { + if (accumulator > 10) { + dest_translation += glm::sign(gl_delta) * 0.11f; + dest_translation.x = ROUND(dest_translation.x, 10.f); + dest_translation.y = ROUND(dest_translation.y, 10.f); + accumulator = 0; + } + else + break; + } + else { + // normal case: dest += delta + dest_translation += gl_delta * ARROWS_MOVEMENT_FACTOR; + } + + // store action in history + std::ostringstream info; + if ((*it)->active()) { + info << "Alpha " << std::fixed << std::setprecision(3) << (*it)->blendingShader()->color.a << " "; + info << ( ((*it)->blendingShader()->color.a > 0.f) ? ICON_FA_EYE : ICON_FA_EYE_SLASH); + } + else + info << "Inactive " << ICON_FA_SNOWFLAKE; + current_action_ = (*it)->name() + ": " + info.str(); + current_id_ = (*it)->id(); + + // delta for others to follow + delta_translation = dest_translation - sourceNode->translation_; } else { - sourceNode->translation_ += gl_delta * ARROWS_MOVEMENT_FACTOR; - alt_move_ = sourceNode->translation_; + // dest = current + delta from first + dest_translation = sourceNode->translation_ + delta_translation; } - // store action in history - std::ostringstream info; - if (s->active()) { - info << "Alpha " << std::fixed << std::setprecision(3) << s->blendingShader()->color.a << " "; - info << ( (s->blendingShader()->color.a > 0.f) ? ICON_FA_EYE : ICON_FA_EYE_SLASH); - } - else - info << "Inactive " << ICON_FA_SNOWFLAKE; - current_action_ = s->name() + ": " + info.str(); - current_id_ = s->id(); + // apply & request update + sourceNode->translation_ = dest_translation; + (*it)->touch(); - // request update - s->touch(); + first = false; } + } void MixingView::setAlpha(Source *s) diff --git a/TextureView.cpp b/TextureView.cpp index 39d9e48..82dc35b 100644 --- a/TextureView.cpp +++ b/TextureView.cpp @@ -158,6 +158,7 @@ TextureView::TextureView() : View(TEXTURE), edit_source_(nullptr), need_edit_upd // with dark background g = new Group; s = new Symbol(Symbol::CLOCK); + s->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f ); g->attach(s); s = new Symbol(Symbol::CIRCLE_POINT); s->color = glm::vec4(0.f, 0.f, 0.f, 0.25f); @@ -1210,22 +1211,22 @@ View::Cursor TextureView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pa if (UserInterface::manager().altModifier()) { sourceNode->translation_.x = ROUND(sourceNode->translation_.x, 10.f); sourceNode->translation_.y = ROUND(sourceNode->translation_.y, 10.f); - } - // ALT: single axis movement - overlay_position_cross_->visible_ = false; - if (UserInterface::manager().shiftModifier()) { - overlay_position_cross_->visible_ = true; - overlay_position_cross_->translation_.x = s->stored_status_->translation_.x; - overlay_position_cross_->translation_.y = s->stored_status_->translation_.y; - overlay_position_cross_->update(0); + // + SHIFT: single axis movement + overlay_position_cross_->visible_ = false; + if (UserInterface::manager().shiftModifier()) { + overlay_position_cross_->visible_ = true; + overlay_position_cross_->translation_.x = s->stored_status_->translation_.x; + overlay_position_cross_->translation_.y = s->stored_status_->translation_.y; + overlay_position_cross_->update(0); - glm::vec3 dif = s->stored_status_->translation_ - sourceNode->translation_; - if (ABS(dif.x) > ABS(dif.y) ) { - sourceNode->translation_.y = s->stored_status_->translation_.y; - ret.type = Cursor_ResizeEW; - } else { - sourceNode->translation_.x = s->stored_status_->translation_.x; - ret.type = Cursor_ResizeNS; + glm::vec3 dif = s->stored_status_->translation_ - sourceNode->translation_; + if (ABS(dif.x) > ABS(dif.y) ) { + sourceNode->translation_.y = s->stored_status_->translation_.y; + ret.type = Cursor_ResizeEW; + } else { + sourceNode->translation_.x = s->stored_status_->translation_.x; + ret.type = Cursor_ResizeNS; + } } } // Show center overlay for POSITION diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 6779f5a..ba12376 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -422,7 +422,6 @@ void UserInterface::handleKeyboard() Mixer::manager().setView((View::Mode) target_view_navigator); } - // confirmation for leaving vimix: prevent un-wanted Ctrl+Q, but make it easy to confirm if (ImGui::BeginPopup("confirm_quit_popup")) { @@ -633,10 +632,12 @@ void UserInterface::handleMouse() Source *current = Mixer::manager().currentSource(); if (current) { - // grab others from selection - for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++) { - if ( *it != current ) - Mixer::manager().view()->grab(*it, mouseclic[ImGuiMouseButton_Left], mouse_smooth, picked); + if (!shift_modifier_active) { + // grab others from selection + for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++) { + if ( *it != current ) + Mixer::manager().view()->grab(*it, mouseclic[ImGuiMouseButton_Left], mouse_smooth, picked); + } } // grab current sources View::Cursor c = Mixer::manager().view()->grab(current, mouseclic[ImGuiMouseButton_Left], mouse_smooth, picked);