diff --git a/source/MRCommonPlugins/ViewerButtons/MRViewerSettingsPlugin.cpp b/source/MRCommonPlugins/ViewerButtons/MRViewerSettingsPlugin.cpp index 36b2f1c61efb..bb12c3b93d1a 100644 --- a/source/MRCommonPlugins/ViewerButtons/MRViewerSettingsPlugin.cpp +++ b/source/MRCommonPlugins/ViewerButtons/MRViewerSettingsPlugin.cpp @@ -176,9 +176,13 @@ void ViewerSettingsPlugin::drawDialog( float menuScaling, ImGuiContext* ) } ImGui::ColorEdit4( "Color", &shadowGl_->shadowColor.x, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_PickerHueWheel ); - ImGui::DragFloat2( "Shift", &shadowGl_->shadowShift.x, 0.4f, -200.0f, 200.0f ); - ImGui::SetTooltipIfHovered( "X, Y shift in screen coordinates:\nX going right\nY going up", menuScaling ); - ImGui::DragFloatValid( "Blur radius", &shadowGl_->blurRadius, 0.2f, 0, 200 ); + + const char* tooltipsShift[2] = { + "Shift along Ox-axis to the left", + "Shift along Oy-axis to the top" + }; + ImGui::DragFloatValid2( "Shift", &shadowGl_->shadowShift.x, 0.4f, -200.0f, 200.0f, "%.3f px", 0, &tooltipsShift ); + ImGui::DragFloatValid( "Blur radius", &shadowGl_->blurRadius, 0.2f, 0, 200, "%.3f px" ); float quality = shadowGl_->getQuality(); ImGui::DragFloatValid( "Quality", &quality, 0.001f, 0.0625f, 1.0f ); ImGui::SetTooltipIfHovered( "Blur texture downscaling coefficient", menuScaling ); diff --git a/source/MRViewer/ImGuiHelpers.cpp b/source/MRViewer/ImGuiHelpers.cpp index da3c8fab791c..46e1cfca8294 100644 --- a/source/MRViewer/ImGuiHelpers.cpp +++ b/source/MRViewer/ImGuiHelpers.cpp @@ -307,6 +307,44 @@ bool InputIntValid( const char* label, int* v, int v_min, int v_max, return res; } +MultiDragRes DragFloatValid2( const char* label, float* valueArr, float step, float valueMin, float valueMax, const char* format, ImGuiSliderFlags flags, const char* ( *tooltips )[2] ) +{ + MultiDragRes res; + + ImGuiContext& g = *ImGui::GetCurrentContext(); + ImGuiWindow* window = g.CurrentWindow; + if ( window->SkipItems ) + return res; + + BeginGroup(); + PushID( label ); + constexpr int components = 2; + PushMultiItemsWidths( components, CalcItemWidth() ); + for ( int i = 0; i < components; i++ ) + { + PushID( i ); + if ( i > 0 ) + SameLine( 0, g.Style.ItemInnerSpacing.x ); + res.valueChanged = DragFloatValid( "", valueArr + i, step, valueMin, valueMax, format, flags ) || res.valueChanged; + if ( tooltips && IsItemHovered() && !IsItemActive() ) + SetTooltip( "%s", ( *tooltips )[i] ); + res.itemDeactivatedAfterEdit = res.itemDeactivatedAfterEdit || IsItemDeactivatedAfterEdit(); + PopID(); + PopItemWidth(); + } + PopID(); + + const char* label_end = FindRenderedTextEnd( label ); + if ( label != label_end ) + { + SameLine( 0, g.Style.ItemInnerSpacing.x ); + TextEx( label, label_end ); + } + + EndGroup(); + return res; +} + MultiDragRes DragFloatValid3( const char * label, float* valueArr, float step, float valueMin, float valueMax, const char* format, ImGuiSliderFlags flags, const char* (*tooltips)[3] ) { MultiDragRes res; diff --git a/source/MRViewer/ImGuiHelpers.h b/source/MRViewer/ImGuiHelpers.h index 0f52af536a89..7f8ff3da64d1 100644 --- a/source/MRViewer/ImGuiHelpers.h +++ b/source/MRViewer/ImGuiHelpers.h @@ -100,6 +100,16 @@ struct MultiDragRes explicit operator bool() const { return valueChanged; } }; +/// similar to ImGui::DragFloat2 - two drag-float controls in a row, but +/// 1) returns information whether an item was deactivated; +/// 2) calls DragFloatValid inside instead of DragFloat; +/// 3) permits showing tooltip for each item +MRVIEWER_API MultiDragRes DragFloatValid2( const char* label, float v[2], float v_speed = 1.0f, + float min = std::numeric_limits::lowest(), + float max = std::numeric_limits::max(), + const char* format = "%.3f", ImGuiSliderFlags flags = 0, + const char* ( *tooltips )[2] = nullptr ); + /// similar to ImGui::DragFloat3 - three drag-float controls in a row, but /// 1) returns information whether an item was deactivated; /// 2) calls DragFloatValid inside instead of DragFloat; diff --git a/source/MRViewer/MRGLStaticHolder.cpp b/source/MRViewer/MRGLStaticHolder.cpp index 53b6efed17a9..df58f907ffb7 100644 --- a/source/MRViewer/MRGLStaticHolder.cpp +++ b/source/MRViewer/MRGLStaticHolder.cpp @@ -1247,7 +1247,13 @@ void main(void) out vec4 outColor; // (out to render) fragment color const float gaussWeights[] = float[7] (0.161046, 0.148645, 0.116919, 0.078381, 0.044771, 0.021742, 0.009019); - + + float getValue( vec2 pos ) + { + if ( pos.x < 0.0 || pos.x > 1.0 || pos.y < 0.0 || pos.y > 1.0 ) + return 0.0; + return texture(pixels,pos).a; + } void main() { gl_FragDepth = 0.9999; @@ -1262,12 +1268,12 @@ void main(void) else posShift = vec2(0.0,blurRadius /(6.0* float(texSize.y))); - float convSum = gaussWeights[0]*texture(pixels, pos).a; + float convSum = gaussWeights[0]*getValue(pos); for ( int i=1; i<=6; ++i ) { vec2 fullShift = float(i)*posShift; - convSum = convSum + gaussWeights[i]*texture(pixels, pos+fullShift).a; - convSum = convSum + gaussWeights[i]*texture(pixels, pos-fullShift).a; + convSum = convSum + gaussWeights[i]*getValue(pos+fullShift); + convSum = convSum + gaussWeights[i]*getValue(pos-fullShift); } outColor = vec4(color.rgb,convSum); if ( !convX )