Improved keyboard manipulation of selection of sources in Views.

This commit is contained in:
brunoherbelin
2021-03-17 05:12:00 +01:00
parent 77764248b5
commit 41efc572e0
5 changed files with 198 additions and 109 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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);