New Double clic action in Player window, Display window or background

This commit is contained in:
Bruno Herbelin
2024-01-07 23:39:58 +01:00
parent a913cee7a4
commit 9d27335d7d
4 changed files with 131 additions and 77 deletions

View File

@@ -471,17 +471,29 @@ void OutputPreviewWindow::Render()
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.f); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.f);
ImGui::Image((void*)(intptr_t)output->texture(), imagesize); ImGui::Image((void*)(intptr_t)output->texture(), imagesize);
ImGui::PopStyleVar(); ImGui::PopStyleVar();
// mouse over the image
if ( ImGui::IsItemHovered() ) {
// show magnifying glass if active
if (magnifying_glass)
DrawInspector(output->texture(), imagesize, imagesize, draw_pos);
}
// disable magnifying glass if window is deactivated // disable magnifying glass if window is deactivated
if (g.NavWindow != g.CurrentWindow) if (g.NavWindow != g.CurrentWindow)
magnifying_glass = false; magnifying_glass = false;
// handle mouse clic and hovering on image
const ImRect bb(draw_pos, draw_pos + imagesize);
const ImGuiID id = ImGui::GetCurrentWindow()->GetID("##output-texture");
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held,
ImGuiButtonFlags_PressedOnClick);
// toggle preview on double clic
if (pressed) {
// trigger to show preview (will be ignored if not double clic)
UserInterface::manager().show_preview = UserInterface::PREVIEW_OUTPUT;
// cancel the button behavior to let window move on drag
ImGui::SetActiveID(0, ImGui::GetCurrentWindow());
ImGui::SetHoveredID(0);
}
// show magnifying glass if active and mouse hovering
else if (hovered && magnifying_glass)
DrawInspector(output->texture(), imagesize, imagesize, draw_pos);
/// ///
/// Icons overlays /// Icons overlays
/// ///

View File

@@ -47,8 +47,6 @@
#define CHECKER_RESOLUTION 6000 #define CHECKER_RESOLUTION 6000
class Stream *checker_background_ = new Stream; class Stream *checker_background_ = new Stream;
void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider = false, bool withinspector = false);
ImRect DrawSourceWithSlider(Source *s, ImVec2 top, ImVec2 rendersize, bool with_inspector);
SourceControlWindow::SourceControlWindow() : WorkspaceWindow("SourceController"), SourceControlWindow::SourceControlWindow() : WorkspaceWindow("SourceController"),
@@ -1043,72 +1041,67 @@ void DrawInspector(uint texture, ImVec2 texturesize, ImVec2 cropsize, ImVec2 ori
} }
} }
void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider, bool withinspector) void SourceControlWindow::DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider, bool withinspector)
{ {
ImDrawList* draw_list = ImGui::GetWindowDrawList(); if (!s)
return;
// pre-draw background with checkerboard pattern
ImGui::Image((void*)(uintptr_t) checker_background_->texture(), framesize,
ImVec2(0,0), ImVec2(framesize.x/CHECKER_RESOLUTION, framesize.y/CHECKER_RESOLUTION));
// get back to top image corner to draw
ImGui::SetCursorScreenPos(top_image);
// info on source
CloneSource *cloned = dynamic_cast<CloneSource *>(s);
// 100% opacity for the image (ensure true colors) // 100% opacity for the image (ensure true colors)
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.f); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.f);
// draw pre and post-processed parts if necessary // pre-draw background with checkerboard pattern
if (s->imageProcessingEnabled() || s->textureTransformed() || cloned != nullptr) { ImGui::Image((void*)(uintptr_t) checker_background_->texture(), framesize,
ImVec2(0,0), ImVec2(framesize.x/CHECKER_RESOLUTION, framesize.y/CHECKER_RESOLUTION));
// get back to top image corner after draw
ImGui::SetCursorScreenPos(top_image);
// pre-calculate cropping areas of source and cropped rendering area
const glm::vec4 _crop = s->frame()->projectionArea();
const ImVec2 _cropsize = framesize * ImVec2(0.5f * (_crop[1] - _crop[0]),
0.5f * (_crop[2] - _crop[3]));
const ImVec2 _croptop = framesize * ImVec2(0.5f * (1.f + _crop[0]),
0.5f * (1.f - _crop[2]) );
// pre-calculate slider coordinates in rendering area
ImVec2 slider = framesize * ImVec2(Settings::application.widget.media_player_slider,1.f);
// draw pre and post-processed parts if necessary
if (s->imageProcessingEnabled() ||
s->textureTransformed() ||
s->icon() == glm::ivec2(ICON_SOURCE_CLONE))
{
// //
// LEFT of slider : original texture // LEFT of slider : original texture
// //
ImVec2 slider = framesize * ImVec2(Settings::application.widget.media_player_slider,1.f);
ImGui::Image((void*)(uintptr_t) s->texture(), slider, ImVec2(0.f,0.f), ImVec2(Settings::application.widget.media_player_slider,1.f)); ImGui::Image((void*)(uintptr_t) s->texture(), slider, ImVec2(0.f,0.f), ImVec2(Settings::application.widget.media_player_slider,1.f));
if ( withinspector && ImGui::IsItemHovered() )
DrawInspector(s->texture(), framesize, framesize, top_image);
// //
// RIGHT of slider : post-processed image (after crop and color correction) // RIGHT of slider : post-processed image (after crop and color correction)
// //
glm::vec4 _crop = s->frame()->projectionArea();
ImVec2 cropsize = ImVec2(0.5f * (_crop[1] - _crop[0]),
0.5f * (_crop[2] - _crop[3]));
ImVec2 croptop = ImVec2(0.5f * (1.f + _crop[0]),
0.5f * (1.f - _crop[2]) );
cropsize = framesize * cropsize;
croptop = framesize * croptop;
// no overlap of slider with cropped area // no overlap of slider with cropped area
if (slider.x < croptop.x) { if (slider.x < _croptop.x) {
// draw cropped area // draw cropped area
ImGui::SetCursorScreenPos( top_image + croptop ); ImGui::SetCursorScreenPos( top_image + _croptop );
ImGui::Image((void*)(uintptr_t) s->frame()->texture(), cropsize, ImVec2(0.f, 0.f), ImVec2(1.f,1.f)); ImGui::Image((void*)(uintptr_t) s->frame()->texture(), _cropsize, ImVec2(0.f, 0.f), ImVec2(1.f,1.f));
if ( withinspector && ImGui::IsItemHovered() )
DrawInspector(s->frame()->texture(), framesize, cropsize, top_image + croptop);
} }
// overlap of slider with cropped area (horizontally) // overlap of slider with cropped area (horizontally)
else if (slider.x < croptop.x + cropsize.x ) { else if (slider.x < _croptop.x + _cropsize.x ) {
// compute slider ratio of cropped area // compute slider ratio of cropped area
float cropped_slider = (slider.x - croptop.x) / cropsize.x; float cropped_slider = (slider.x - _croptop.x) / _cropsize.x;
// top x moves with slider // top x moves with slider
ImGui::SetCursorScreenPos( top_image + ImVec2(slider.x, croptop.y) ); ImGui::SetCursorScreenPos( top_image + ImVec2(slider.x, _croptop.y) );
// size is reduced by slider // size is reduced by slider
ImGui::Image((void*)(uintptr_t) s->frame()->texture(), cropsize * ImVec2(1.f -cropped_slider, 1.f), ImVec2(cropped_slider, 0.f), ImVec2(1.f,1.f)); ImGui::Image((void*)(uintptr_t) s->frame()->texture(), _cropsize * ImVec2(1.f -cropped_slider, 1.f), ImVec2(cropped_slider, 0.f), ImVec2(1.f,1.f));
if ( withinspector && ImGui::IsItemHovered() )
DrawInspector(s->frame()->texture(), framesize, cropsize, top_image + croptop);
} }
// else : no render of cropped area // else : no render of cropped area
ImU32 slider_color = ImGui::GetColorU32(ImGuiCol_NavWindowingHighlight);
if (withslider)
{
// //
// SLIDER // SLIDER
// //
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImU32 slider_color = ImGui::GetColorU32(ImGuiCol_NavWindowingHighlight);
if (withslider && !withinspector)
{
// user input : move slider horizontally // user input : move slider horizontally
ImGui::SetCursorScreenPos(top_image + ImVec2(- 20.f, 0.5f * framesize.y - 20.0f)); ImGui::SetCursorScreenPos(top_image + ImVec2(- 20.f, 0.5f * framesize.y - 20.0f));
ImGuiToolkit::InvisibleSliderFloat("#media_player_slider2", &Settings::application.widget.media_player_slider, 0.f, 1.f, ImVec2(framesize.x + 40.f, 40.0f) ); ImGuiToolkit::InvisibleSliderFloat("#media_player_slider2", &Settings::application.widget.media_player_slider, 0.f, 1.f, ImVec2(framesize.x + 40.f, 40.0f) );
@@ -1126,14 +1119,40 @@ void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider,
// no post-processed to show: draw simple texture // no post-processed to show: draw simple texture
else { else {
ImGui::Image((void *) (uintptr_t) s->texture(), framesize); ImGui::Image((void *) (uintptr_t) s->texture(), framesize);
if ( withinspector && ImGui::IsItemHovered() ) slider = framesize;
DrawInspector(s->texture(), framesize, framesize, top_image);
} }
//
// Handle mouse clic and hovering on image
//
const ImRect bb(top_image, top_image + framesize);
const ImGuiID id = ImGui::GetCurrentWindow()->GetID("##source-texture");
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_PressedOnClick);
// toggle preview on double clic
if (pressed) {
// trigger to show preview (will be ignored if not double clic)
UserInterface::manager().show_preview = UserInterface::PREVIEW_SOURCE;
// cancel the button behavior to let window move on drag
ImGui::SetActiveID(0, ImGui::GetCurrentWindow());
ImGui::SetHoveredID(0);
}
// show magnifying glass if hovering and inspector is active
else if (hovered && withinspector) {
// different texture to show depending on mouse position of slider
if (ImGui::IsMouseHoveringRect(top_image, top_image + slider))
// inspector over left side of slider
DrawInspector(s->texture(), framesize, framesize, top_image);
else
// inspector over right side of slider
DrawInspector(s->frame()->texture(), framesize, _cropsize, top_image + _croptop);
}
// pop ImGuiStyleVar_Alpha
ImGui::PopStyleVar(); ImGui::PopStyleVar();
} }
ImRect DrawSourceWithSlider(Source *s, ImVec2 top, ImVec2 rendersize, bool with_inspector) ImRect SourceControlWindow::DrawSourceWithSlider(Source *s, ImVec2 top, ImVec2 rendersize, bool with_inspector)
{ {
/// ///
/// Centered frame /// Centered frame

View File

@@ -2,6 +2,7 @@
#define SOURCECONTROLWINDOW_H #define SOURCECONTROLWINDOW_H
struct ImVec2; struct ImVec2;
struct ImRect;
#include "SourceList.h" #include "SourceList.h"
#include "InfoVisitor.h" #include "InfoVisitor.h"
@@ -55,6 +56,10 @@ class SourceControlWindow : public WorkspaceWindow
float mediaplayer_timeline_zoom_; float mediaplayer_timeline_zoom_;
void RenderMediaPlayer(MediaSource *ms); void RenderMediaPlayer(MediaSource *ms);
// draw methods
void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider = false, bool withinspector = false);
ImRect DrawSourceWithSlider(Source *s, ImVec2 top, ImVec2 rendersize, bool with_inspector);
// magnifying glass // magnifying glass
bool magnifying_glass; bool magnifying_glass;

View File

@@ -640,8 +640,16 @@ void UserInterface::handleMouse()
if ( ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) ) if ( ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) )
{ {
// if double clic action of view didn't succeed // if double clic event was not used in view
if ( !Mixer::manager().view()->doubleclic(mousepos) ) { if ( !Mixer::manager().view()->doubleclic(mousepos) ) {
int i = Mixer::manager().indexCurrentSource();
// if no current source
if (i<0){
// hide left pannel & toggle clear workspace
navigator.discardPannel();
WorkspaceWindow::toggleClearRestoreWorkspace();
}
else
// display current source in left panel /or/ hide left panel if no current source // display current source in left panel /or/ hide left panel if no current source
navigator.showPannelSource( Mixer::manager().indexCurrentSource() ); navigator.showPannelSource( Mixer::manager().indexCurrentSource() );
} }
@@ -1326,8 +1334,7 @@ void UserInterface::RenderPreview()
ImGui::OpenPopup("##RENDERPREVIEW"); ImGui::OpenPopup("##RENDERPREVIEW");
_inspector = false; _inspector = false;
_sustain = false; _sustain = false;
} } else
else
show_preview = PREVIEW_NONE; show_preview = PREVIEW_NONE;
} }
@@ -1351,26 +1358,37 @@ void UserInterface::RenderPreview()
ImGui::Image((void*)(intptr_t)_framebuffer->texture(), imagesize); ImGui::Image((void*)(intptr_t)_framebuffer->texture(), imagesize);
ImGui::PopStyleVar(); ImGui::PopStyleVar();
if ( ImGui::IsMouseClicked(ImGuiMouseButton_Left) ) { // closing icon in top left corner
// show inspector on mouse clic in
if ( ImGui::IsItemHovered() )
_inspector = !_inspector;
// close view on mouse clic outside
else if (!_sustain)
show_preview = PREVIEW_NONE;
}
// draw inspector (magnifying glass)
if ( _inspector && ImGui::IsItemHovered() )
DrawInspector(_framebuffer->texture(), imagesize, imagesize, draw_pos);
// closing icon
ImGui::SetCursorScreenPos(draw_pos + ImVec2(IMGUI_SAME_LINE, IMGUI_SAME_LINE));
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE); ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
ImGui::SetCursorScreenPos(draw_pos + ImVec2(IMGUI_SAME_LINE, IMGUI_SAME_LINE));
if (ImGuiToolkit::IconButton(ICON_FA_TIMES, "Close preview")) if (ImGuiToolkit::IconButton(ICON_FA_TIMES, "Close preview"))
show_preview = PREVIEW_NONE; show_preview = PREVIEW_NONE;
if ( ImGui::IsItemHovered() )
_inspector = false;
ImGui::PopFont(); ImGui::PopFont();
// handle mouse clic and hovering on image
const ImRect bb(draw_pos, draw_pos + imagesize);
const ImGuiID id = ImGui::GetCurrentWindow()->GetID("##preview-texture");
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb,
id,
&hovered,
&held,
ImGuiButtonFlags_PressedOnClick);
// toggle inspector on mouse clic
if (pressed)
_inspector = !_inspector;
// draw inspector (magnifying glass) on mouse hovering
if (hovered & _inspector)
DrawInspector(_framebuffer->texture(), imagesize, imagesize, draw_pos);
// close view on mouse clic outside
// and ignore show_preview on single clic
if (!hovered
&& !_sustain
&& !ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)
&& ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
show_preview = PREVIEW_NONE;
}
} }
// local keyboard handler (because focus is captured by modal dialog) // local keyboard handler (because focus is captured by modal dialog)