Improved View Cursor; now also displays context information around the

cursor during operation (e.g. grab)
This commit is contained in:
brunoherbelin
2020-06-07 12:45:28 +02:00
parent 04541f23ee
commit d0c31f0331
7 changed files with 97 additions and 32 deletions

View File

@@ -808,8 +808,8 @@ void ImGuiToolkit::ShowStats(bool *p_open, int* p_corner)
if (p_open && ImGui::MenuItem("Close")) *p_open = false; if (p_open && ImGui::MenuItem("Close")) *p_open = false;
ImGui::EndPopup(); ImGui::EndPopup();
} }
ImGui::End();
} }
ImGui::End();
} }
ImVec4 ImGuiToolkit::GetHighlightColor() ImVec4 ImGuiToolkit::GetHighlightColor()

View File

@@ -77,10 +77,10 @@ void ImGuiVisitor::visit(Group &n)
ImGui::SameLine(0, 10); ImGui::SameLine(0, 10);
float scale[2] = { n.scale_.x, n.scale_.y} ; float scale[2] = { n.scale_.x, n.scale_.y} ;
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if ( ImGui::SliderFloat2("Scale", scale, -5.0, 5.0, "%.2f") ) if ( ImGui::SliderFloat2("Scale", scale, -MAX_SCALE, MAX_SCALE, "%.2f") )
{ {
n.scale_.x = scale[0]; n.scale_.x = CLAMP_SCALE(scale[0]);
n.scale_.y = scale[1]; n.scale_.y = CLAMP_SCALE(scale[1]);
} }
// // loop over members of a group // // loop over members of a group

View File

@@ -205,8 +205,14 @@ void Source::update(float dt)
// MODIFY geometry based on GEOMETRY node // MODIFY geometry based on GEOMETRY node
groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_; groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_;
groups_[View::RENDERING]->scale_ = groups_[View::GEOMETRY]->scale_;
groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_; groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_;
// avoid any null scale
glm::vec3 s = groups_[View::GEOMETRY]->scale_;
s.x = CLAMP_SCALE(s.x);
s.y = CLAMP_SCALE(s.y);
s.z = 1.f;
groups_[View::GEOMETRY]->scale_ = s;
groups_[View::RENDERING]->scale_ = s;
// MODIFY depth based on LAYER node // MODIFY depth based on LAYER node
groups_[View::MIXING]->translation_.z = groups_[View::LAYER]->translation_.z; groups_[View::MIXING]->translation_.z = groups_[View::LAYER]->translation_.z;

View File

@@ -330,9 +330,9 @@ void UserInterface::handleMouse()
if ( ImGui::IsMouseDragging(ImGuiMouseButton_Right, 10.0f) ) if ( ImGui::IsMouseDragging(ImGuiMouseButton_Right, 10.0f) )
{ {
// right mouse drag => drag current view // right mouse drag => drag current view
int c = Mixer::manager().currentView()->drag( mouseclic[ImGuiMouseButton_Right], mousepos); View::Cursor c = Mixer::manager().currentView()->drag( mouseclic[ImGuiMouseButton_Right], mousepos);
ImGui::SetMouseCursor(c); ImGui::SetMouseCursor(c.type);
} }
else { else {
ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow); ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
@@ -355,8 +355,21 @@ void UserInterface::handleMouse()
if (current) if (current)
{ {
// grab current source // grab current source
int c = Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, current, picked); View::Cursor c = Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, current, picked);
ImGui::SetMouseCursor(c);
ImGui::SetMouseCursor(c.type);
float d = 0.5f * ImGui::GetFrameHeight() ;
ImVec2 window_pos = ImVec2( mousepos.x - d, mousepos.y - d );
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always);
ImGui::SetNextWindowBgAlpha(0.45f); // Transparent background
if (ImGui::Begin("MouseInfoContext", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
{
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_MONO);
ImGui::Text(" %s", c.info.c_str());
ImGui::PopFont();
ImGui::End();
}
} }
else { else {
// Log::Info("Mouse drag (%.1f,%.1f)(%.1f,%.1f)", io.MouseClickedPos[0].x, io.MouseClickedPos[0].y, io.MousePos.x, io.MousePos.y); // Log::Info("Mouse drag (%.1f,%.1f)(%.1f,%.1f)", io.MouseClickedPos[0].x, io.MouseClickedPos[0].y, io.MousePos.x, io.MousePos.y);

View File

@@ -6,6 +6,8 @@
// memmove // memmove
#include <string.h> #include <string.h>
#include <sstream>
#include <iomanip>
#include "defines.h" #include "defines.h"
#include "Settings.h" #include "Settings.h"
@@ -76,7 +78,7 @@ View::Cursor View::drag (glm::vec2 from, glm::vec2 to)
// compute delta translation // compute delta translation
scene.root()->translation_ = start_translation + gl_Position_to - gl_Position_from; scene.root()->translation_ = start_translation + gl_Position_to - gl_Position_from;
return Cursor_ResizeAll; return Cursor(Cursor_ResizeAll);
} }
std::pair<Node *, glm::vec2> View::pick(glm::vec3 point) std::pair<Node *, glm::vec2> View::pick(glm::vec3 point)
@@ -133,7 +135,7 @@ void MixingView::zoom( float factor )
View::Cursor MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2>) View::Cursor MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2>)
{ {
if (!s) if (!s)
return Cursor_Arrow; return Cursor();
Group *sourceNode = s->group(mode_); Group *sourceNode = s->group(mode_);
@@ -155,7 +157,9 @@ View::Cursor MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pai
// request update // request update
s->touch(); s->touch();
return Cursor_ResizeAll; std::ostringstream info;
info << "Alpha " << std::fixed << std::setprecision(3) << s->blendingShader()->color.a;
return Cursor(Cursor_ResizeAll, info.str() );
} }
uint MixingView::textureMixingQuadratic() uint MixingView::textureMixingQuadratic()
@@ -344,7 +348,9 @@ std::pair<Node *, glm::vec2> GeometryView::pick(glm::vec3 point)
View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick)
{ {
View::Cursor ret = Cursor_Arrow; View::Cursor ret = Cursor();
std::ostringstream info;
// work on the given source // work on the given source
if (!s) if (!s)
@@ -396,42 +402,70 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
// select cursor depending on diagonal // select cursor depending on diagonal
glm::vec2 axis = glm::sign(pick.second); glm::vec2 axis = glm::sign(pick.second);
ret = axis.x * axis.y > 0.f ? Cursor_ResizeNESW : Cursor_ResizeNWSE; ret.type = axis.x * axis.y > 0.f ? Cursor_ResizeNESW : Cursor_ResizeNWSE;
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
info << " x " << sourceNode->scale_.y;
} }
// picking on the resizing handles left or right // picking on the resizing handles left or right
else if ( pick.first == s->resize_H_handle_ ) { else if ( pick.first == s->resize_H_handle_ ) {
sourceNode->scale_ = start_scale * glm::vec3(S_resize.x, 1.f, 1.f); sourceNode->scale_ = start_scale * glm::vec3(S_resize.x, 1.f, 1.f);
ret = Cursor_ResizeEW; if (UserInterface::manager().keyboardModifier())
sourceNode->scale_.x = float( int( sourceNode->scale_.x * 10.f ) ) / 10.f;
ret.type = Cursor_ResizeEW;
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
info << " x " << sourceNode->scale_.y;
} }
// picking on the resizing handles top or bottom // picking on the resizing handles top or bottom
else if ( pick.first == s->resize_V_handle_ ) { else if ( pick.first == s->resize_V_handle_ ) {
sourceNode->scale_ = start_scale * glm::vec3(1.f, S_resize.y, 1.f); sourceNode->scale_ = start_scale * glm::vec3(1.f, S_resize.y, 1.f);
ret = Cursor_ResizeNS; if (UserInterface::manager().keyboardModifier())
sourceNode->scale_.y = float( int( sourceNode->scale_.y * 10.f ) ) / 10.f;
ret.type = Cursor_ResizeNS;
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
info << " x " << sourceNode->scale_.y;
} }
// picking on the rotating handle // picking on the rotating handle
else if ( pick.first == s->rotate_handle_ ) { else if ( pick.first == s->rotate_handle_ ) {
float angle = glm::orientedAngle( glm::normalize(glm::vec2(S_from)), glm::normalize(glm::vec2(S_to))); float angle = glm::orientedAngle( glm::normalize(glm::vec2(S_from)), glm::normalize(glm::vec2(S_to)));
if (UserInterface::manager().keyboardModifier())
angle = float ( int(angle * 30.f) ) / 30.f;
sourceNode->rotation_ = start_rotation + glm::vec3(0.f, 0.f, angle); sourceNode->rotation_ = start_rotation + glm::vec3(0.f, 0.f, angle);
ret = Cursor_Hand;
int degrees = int( glm::degrees(sourceNode->rotation_.z) );
if (UserInterface::manager().keyboardModifier()) {
degrees = (degrees / 10) * 10;
sourceNode->rotation_.z = glm::radians( float(degrees) );
}
ret.type = Cursor_Hand;
info << "Angle " << degrees << "\u00b0"; // degree symbol
} }
// picking anywhere but on a handle: user wants to move the source // picking anywhere but on a handle: user wants to move the source
else { else {
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
ret = Cursor_ResizeAll;
if (UserInterface::manager().keyboardModifier()) {
sourceNode->translation_.x = float( int( sourceNode->translation_.x * 10.f ) ) / 10.f;
sourceNode->translation_.y = float( int( sourceNode->translation_.y * 10.f ) ) / 10.f;
}
ret.type = Cursor_ResizeAll;
info << "Position (" << std::fixed << std::setprecision(3) << sourceNode->translation_.x;
info << ", " << sourceNode->translation_.y << ")";
} }
} }
// don't have a handle, we can only move the source // don't have a handle, we can only move the source
else { else {
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
ret = Cursor_ResizeAll; ret.type = Cursor_ResizeAll;
info << "Position (" << std::fixed << std::setprecision(3) << sourceNode->translation_.x;
info << ", " << sourceNode->translation_.y << ")";
} }
// request update // request update
s->touch(); s->touch();
ret.info = info.str();
return ret; return ret;
} }
@@ -497,10 +531,10 @@ void LayerView::zoom (float factor)
} }
void LayerView::setDepth (Source *s, float d) float LayerView::setDepth(Source *s, float d)
{ {
if (!s) if (!s)
return; return -1.f;
float depth = d; float depth = d;
@@ -528,12 +562,14 @@ void LayerView::setDepth (Source *s, float d)
// request reordering // request reordering
View::need_deep_update_ = true; View::need_deep_update_ = true;
return sourceNode->translation_.z;
} }
View::Cursor LayerView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) View::Cursor LayerView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick)
{ {
if (!s) if (!s)
return Cursor_Arrow; return Cursor();
static glm::vec3 start_translation = glm::vec3(0.f); static glm::vec3 start_translation = glm::vec3(0.f);
static glm::vec2 start_position = glm::vec2(0.f); static glm::vec2 start_position = glm::vec2(0.f);
@@ -551,8 +587,10 @@ View::Cursor LayerView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair
glm::vec3 dest_translation = start_translation + gl_Position_to - gl_Position_from; glm::vec3 dest_translation = start_translation + gl_Position_to - gl_Position_from;
// apply change // apply change
setDepth( s, MAX( -dest_translation.x, 0.f) ); float d = setDepth( s, MAX( -dest_translation.x, 0.f) );
return Cursor_ResizeAll; std::ostringstream info;
info << "Depth " << std::fixed << std::setprecision(2) << d;
return Cursor(Cursor_ResizeAll, info.str() );
} }

13
View.h
View File

@@ -32,15 +32,22 @@ public:
Cursor_ResizeNWSE, Cursor_ResizeNWSE,
Cursor_Hand, Cursor_Hand,
Cursor_NotAllowed Cursor_NotAllowed
} CursorType;
typedef struct Cursor {
CursorType type;
std::string info;
Cursor() { type = Cursor_Arrow; info = "";}
Cursor(CursorType t, std::string i = "") { type = t; info = i;}
} Cursor; } Cursor;
virtual std::pair<Node *, glm::vec2> pick(glm::vec3 point); virtual std::pair<Node *, glm::vec2> pick(glm::vec3 point);
virtual Cursor drag (glm::vec2, glm::vec2); virtual Cursor drag (glm::vec2, glm::vec2);
virtual Cursor grab (glm::vec2, glm::vec2, Source*, std::pair<Node *, glm::vec2>) { virtual Cursor grab (glm::vec2, glm::vec2, Source*, std::pair<Node *, glm::vec2>) {
return Cursor_Arrow; return Cursor();
} }
virtual Cursor over (glm::vec2, Source*, std::pair<Node *, glm::vec2>) { virtual Cursor over (glm::vec2, Source*, std::pair<Node *, glm::vec2>) {
return Cursor_Arrow; return Cursor();
} }
virtual void restoreSettings(); virtual void restoreSettings();
@@ -107,7 +114,7 @@ public:
void zoom (float factor) override; void zoom (float factor) override;
Cursor grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) override; Cursor grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) override;
void setDepth (Source *, float d = -1.f); float setDepth (Source *, float d = -1.f);
private: private:
float aspect_ratio; float aspect_ratio;

View File

@@ -25,6 +25,9 @@
#define SCENE_UNIT 5.f #define SCENE_UNIT 5.f
#define SCENE_DEPTH 12.f #define SCENE_DEPTH 12.f
#define CIRCLE_SQUARE_DIST(x,y) ( (x*x + y*y) / (SCENE_UNIT * SCENE_UNIT * SCENE_UNIT * SCENE_UNIT) ) #define CIRCLE_SQUARE_DIST(x,y) ( (x*x + y*y) / (SCENE_UNIT * SCENE_UNIT * SCENE_UNIT * SCENE_UNIT) )
#define MIN_SCALE 0.01f
#define MAX_SCALE 10.f
#define CLAMP_SCALE(x) SIGN(x) * CLAMP( ABS(x), MIN_SCALE, MAX_SCALE)
#define IMGUI_TITLE_MAINWINDOW ICON_FA_CIRCLE_NOTCH " vimix" #define IMGUI_TITLE_MAINWINDOW ICON_FA_CIRCLE_NOTCH " vimix"
#define IMGUI_TITLE_MEDIAPLAYER ICON_FA_FILM " Media Player" #define IMGUI_TITLE_MEDIAPLAYER ICON_FA_FILM " Media Player"
@@ -58,8 +61,6 @@
#define MAX_ICON_SIZE 2.5 #define MAX_ICON_SIZE 2.5
#define MIN_DEPTH_LAYER 0.0 #define MIN_DEPTH_LAYER 0.0
#define MAX_DEPTH_LAYER 40.0 #define MAX_DEPTH_LAYER 40.0
#define MIN_SCALE 0.1
#define MAX_SCALE 200.0
#define DEPTH_EPSILON 0.1 #define DEPTH_EPSILON 0.1
#define DEPTH_DEFAULT_SPACING 1.0 #define DEPTH_DEFAULT_SPACING 1.0
#define BORDER_SIZE 0.4 #define BORDER_SIZE 0.4