mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Improved View Cursor; now also displays context information around the
cursor during operation (e.g. grab)
This commit is contained in:
@@ -808,9 +808,9 @@ 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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
74
View.cpp
74
View.cpp
@@ -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
13
View.h
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user