From 38aa447dcd1ce8395776462eddb4d217f07ad7e5 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Fri, 6 Apr 2018 14:07:00 +0200 Subject: [PATCH] Unify the width of all visible legends. * Calculate the minimum width to fit the content before the render pass. * Set the actual width of all the legends to the largest of the minimum widths. * This resizes the legends to always be the same size and reduces the size of you remove the widest legend. --- .../RivTernarySaturationOverlayItem.cpp | 9 ++++ .../RivTernarySaturationOverlayItem.h | 1 + .../ProjectDataModel/RimLegendConfig.cpp | 1 + ApplicationCode/UserInterface/RiuViewer.cpp | 11 +++++ .../cafVizExtensions/cafCategoryLegend.cpp | 37 +++++++++------- .../cafVizExtensions/cafCategoryLegend.h | 8 ++-- .../cafOverlayScalarMapperLegend.cpp | 42 ++++++++++++------- .../cafOverlayScalarMapperLegend.h | 6 ++- .../cafTitledOverlayFrame.cpp | 36 ++++++++++++++++ .../cafVizExtensions/cafTitledOverlayFrame.h | 11 ++++- 10 files changed, 127 insertions(+), 35 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp index 70a96c9a80..78695e899e 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp @@ -43,6 +43,7 @@ RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font) : TitledOverlayFrame(font, 120, 150) { + this->computeLayoutAndExtents(); } //-------------------------------------------------------------------------------------------------- @@ -53,6 +54,14 @@ RivTernarySaturationOverlayItem::~RivTernarySaturationOverlayItem() // Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::computeLayoutAndExtents() +{ + this->setMinimumWidth(this->sizeHint().x()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h index ff3fffd0b3..34ee1d58ac 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h @@ -41,6 +41,7 @@ class RivTernarySaturationOverlayItem : public caf::TitledOverlayFrame public: explicit RivTernarySaturationOverlayItem(cvf::Font* font); ~RivTernarySaturationOverlayItem(); + virtual void computeLayoutAndExtents() override; void setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange); diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index 3b8fc83bce..819cc1c8eb 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -370,6 +370,7 @@ void RimLegendConfig::updateLegend() numDecimalDigits -= static_cast(decadesInRange); } m_scalarMapperLegend->setTickPrecision(cvf::Math::clamp(numDecimalDigits, 0, 20)); + m_scalarMapperLegend->computeLayoutAndExtents(); RiaApplication* app = RiaApplication::instance(); RiaPreferences* preferences = app->preferences(); diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index eb2408ba62..4bc5008681 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -614,6 +614,17 @@ void RiuViewer::addColorLegendToBottomLeftCorner(caf::TitledOverlayFrame* legend yPos += item->sizeHint().y() + border + edgeAxisBorderHeight; } } + + unsigned int requiredLegendWidth = 0u; + for (auto legend : m_visibleLegends) + { + requiredLegendWidth = std::max(requiredLegendWidth, legend->minimumWidth()); + } + + for (auto legend : m_visibleLegends) + { + legend->setWidth(requiredLegendWidth); + } } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.cpp b/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.cpp index 1da1fd6221..58e9797481 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.cpp +++ b/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.cpp @@ -41,6 +41,7 @@ namespace caf { CategoryLegend::CategoryLegend(Font* font, const CategoryMapper* categoryMapper) : TitledOverlayFrame(font, 200, 200) , m_categoryMapper(categoryMapper) + , m_Layout(Vec2i(0, 0), Vec2ui(200u, 200u)) { CVF_ASSERT(font); CVF_ASSERT(!font->isEmpty()); @@ -128,17 +129,9 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext, camera.applyOpenGL(); camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); - // Get layout information - // Todo: Cache this between renderings. Update only when needed. - OverlayColorLegendLayoutInfo layout(position, size); - layoutInfo(&layout); + this->computeLayoutAndExtents(); - // Set up text drawer - float maxLegendRightPos = 0; - TextDrawer textDrawer(this->font()); - setupTextDrawer(&textDrawer, &layout, &maxLegendRightPos); - - Vec2f backgroundSize(CVF_MIN(maxLegendRightPos + layout.margins.x(), (float)size.x()), (float)size.y()); + Vec2f backgroundSize(CVF_MIN((float) this->width(), (float)size.x()), (float)size.y()); // Do the actual rendering if (software) @@ -147,8 +140,8 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext, backgroundSize, this->backgroundColor(), this->backgroundFrameColor()); - renderLegendImmediateMode(oglContext, &layout); - textDrawer.renderSoftware(oglContext, camera); + renderLegendImmediateMode(oglContext, &m_Layout); + m_textDrawer->renderSoftware(oglContext, camera); } else { @@ -158,8 +151,8 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext, backgroundSize, this->backgroundColor(), this->backgroundFrameColor()); - renderLegendUsingShaders(oglContext, &layout, matrixState); - textDrawer.render(oglContext, camera); + renderLegendUsingShaders(oglContext, &m_Layout, matrixState); + m_textDrawer->render(oglContext, camera); } CVF_CHECK_OGL(oglContext); @@ -498,6 +491,22 @@ void CategoryLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout) layout->tickX = layout->x1 + 5; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CategoryLegend::computeLayoutAndExtents() +{ + // Todo: Cache this between renderings. Update only when needed. + layoutInfo(&m_Layout); + m_textDrawer = new TextDrawer(this->font()); + + // Set up text drawer + float maxLegendRightPos = 0; + setupTextDrawer(m_textDrawer.p(), &m_Layout, &maxLegendRightPos); + + unsigned int contentWidth = static_cast(std::ceil(maxLegendRightPos + m_Layout.margins.x())); + this->setMinimumWidth(contentWidth); +} diff --git a/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h b/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h index 0e5e6cdf29..a78eb9d726 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h +++ b/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h @@ -31,6 +31,7 @@ public: virtual ~CategoryLegend(); size_t categoryCount() const; + void computeLayoutAndExtents() override; protected: void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) override; @@ -80,9 +81,10 @@ protected: OverlayColorLegendLayoutInfo* layout); protected: - std::vector m_visibleCategoryLabels; // Skip labels ending up on top of previous visible label - - cvf::cref m_categoryMapper; + std::vector m_visibleCategoryLabels; // Skip labels ending up on top of previous visible label + OverlayColorLegendLayoutInfo m_Layout; + cvf::ref m_textDrawer; + cvf::cref m_categoryMapper; }; } diff --git a/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.cpp b/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.cpp index ad1fee92aa..0abf0c9b79 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.cpp +++ b/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.cpp @@ -86,6 +86,7 @@ OverlayScalarMapperLegend::OverlayScalarMapperLegend(Font* font) : TitledOverlayFrame(font, 200, 200) , m_tickNumberPrecision(4) , m_numberFormat(AUTO) + , m_Layout(Vec2i(0, 0), Vec2ui(200u, 200u)) { CVF_ASSERT(font); CVF_ASSERT(!font->isEmpty()); @@ -182,31 +183,26 @@ void OverlayScalarMapperLegend::renderGeneric(OpenGLContext* oglContext, const V camera.applyOpenGL(); camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); - // Get layout information - // Todo: Cache this between renderings. Update only when needed. - OverlayColorLegendLayoutInfo layout(position, size); - layoutInfo(&layout); + m_Layout.position = position; + m_Layout.size = size; + + this->computeLayoutAndExtents(); - // Set up text drawer - float maxLegendRightPos = 0; - TextDrawer textDrawer(this->font()); - setupTextDrawer(&textDrawer, &layout, &maxLegendRightPos); - - Vec2f backgroundSize(CVF_MIN(maxLegendRightPos + layout.margins.x(), (float)size.x()), (float)size.y()); + Vec2f backgroundSize(CVF_MIN((float)this->width(), (float)size.x()), (float)size.y()); // Do the actual rendering if (software) { if (this->backgroundEnabled()) InternalLegendRenderTools::renderBackgroundImmediateMode(oglContext, backgroundSize, this->backgroundColor(), this->backgroundFrameColor()); - renderLegendImmediateMode(oglContext, &layout); - textDrawer.renderSoftware(oglContext, camera); + renderLegendImmediateMode(oglContext, &m_Layout); + m_textDrawer->renderSoftware(oglContext, camera); } else { const MatrixState matrixState(camera); if (this->backgroundEnabled()) InternalLegendRenderTools::renderBackgroundUsingShaders(oglContext, matrixState, backgroundSize, this->backgroundColor(), this->backgroundFrameColor()); - renderLegendUsingShaders(oglContext, &layout, matrixState); - textDrawer.render(oglContext, camera); + renderLegendUsingShaders(oglContext, &m_Layout, matrixState); + m_textDrawer->render(oglContext, camera); } CVF_CHECK_OGL(oglContext); @@ -221,7 +217,7 @@ void OverlayScalarMapperLegend::setupTextDrawer(TextDrawer* textDrawer, const Ov CVF_ASSERT(layout); float legendRight = 0.0f; - + textDrawer->setVerticalAlignment(TextDrawer::CENTER); textDrawer->setTextColor(this->textColor()); @@ -666,6 +662,22 @@ void OverlayScalarMapperLegend::setTickFormat(NumberFormat format) m_numberFormat = format; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayScalarMapperLegend::computeLayoutAndExtents() +{ + layoutInfo(&m_Layout); + + m_textDrawer = new TextDrawer(this->font()); + + // Set up text drawer + float maxLegendRightPos = 0; + setupTextDrawer(m_textDrawer.p(), &m_Layout, &maxLegendRightPos); + + unsigned int contentWidth = static_cast(std::ceil(maxLegendRightPos + m_Layout.margins.x())); + this->setMinimumWidth(contentWidth); +} } // namespace cvf diff --git a/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h b/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h index 11a2f2c7cc..6a2c2fffd0 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h +++ b/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h @@ -85,7 +85,7 @@ public: void setTickPrecision(int precision); enum NumberFormat { AUTO, SCIENTIFIC, FIXED}; void setTickFormat(NumberFormat format); - + void computeLayoutAndExtents() override; protected: void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override; void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override; @@ -134,7 +134,9 @@ protected: int m_tickNumberPrecision; NumberFormat m_numberFormat; - cvf::cref m_scalarMapper; + OverlayColorLegendLayoutInfo m_Layout; + cvf::ref m_textDrawer; + cvf::cref m_scalarMapper; }; } diff --git a/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.cpp b/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.cpp index 4660733875..10f35d6832 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.cpp +++ b/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.cpp @@ -2,6 +2,8 @@ #include "cafCategoryMapper.h" #include "cvfFont.h" +#include + using namespace cvf; namespace caf { @@ -12,6 +14,7 @@ namespace caf { TitledOverlayFrame::TitledOverlayFrame(Font* font, unsigned int width, unsigned int height) : m_font(font) , m_sizeHint(width, height) + , m_minimumWidth(0u) , m_textColor(Color3::BLACK) , m_lineColor(Color3::BLACK) , m_lineWidth(1) @@ -33,6 +36,23 @@ namespace caf { m_sizeHint = size; } + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void TitledOverlayFrame::setMinimumWidth(unsigned int width) + { + m_minimumWidth = width; + m_actualWidth = std::max(m_minimumWidth, m_actualWidth); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void TitledOverlayFrame::setWidth(unsigned int width) + { + m_actualWidth = width; + } + //-------------------------------------------------------------------------------------------------- /// Set color of the text //-------------------------------------------------------------------------------------------------- @@ -107,6 +127,22 @@ namespace caf { return m_sizeHint; } + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + unsigned int TitledOverlayFrame::minimumWidth() + { + return m_minimumWidth; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + unsigned int TitledOverlayFrame::width() + { + return m_actualWidth; + } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.h b/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.h index 384aff7c8e..8c211253f8 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.h +++ b/Fwk/AppFwk/cafVizExtensions/cafTitledOverlayFrame.h @@ -22,6 +22,8 @@ namespace caf { virtual ~TitledOverlayFrame(); virtual void setSizeHint(const cvf::Vec2ui& size); + void setMinimumWidth(unsigned int width); + void setWidth(unsigned int width); void setTextColor(const cvf::Color3f& color); void setLineColor(const cvf::Color3f& lineColor); @@ -33,8 +35,12 @@ namespace caf { void setBackgroundColor(const cvf::Color4f& backgroundColor); void setBackgroundFrameColor(const cvf::Color4f& backgroundFrameColor); - virtual cvf::Vec2ui sizeHint() override; + virtual void computeLayoutAndExtents() = 0; + virtual cvf::Vec2ui sizeHint() override; + unsigned int minimumWidth(); + unsigned int width(); + protected: cvf::Color3f textColor() const; cvf::Color3f lineColor() const; @@ -48,6 +54,9 @@ namespace caf { private: cvf::Vec2ui m_sizeHint; // The desired pixel size of the color legend area + unsigned int m_minimumWidth; + unsigned int m_actualWidth; + cvf::Color3f m_textColor; cvf::Color3f m_lineColor; int m_lineWidth;