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.
This commit is contained in:
Gaute Lindkvist 2018-04-06 14:07:00 +02:00
parent 63ffade452
commit 38aa447dcd
10 changed files with 127 additions and 35 deletions

View File

@ -43,6 +43,7 @@
RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font) RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font)
: TitledOverlayFrame(font, 120, 150) : 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 // Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::computeLayoutAndExtents()
{
this->setMinimumWidth(this->sizeHint().x());
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -41,6 +41,7 @@ class RivTernarySaturationOverlayItem : public caf::TitledOverlayFrame
public: public:
explicit RivTernarySaturationOverlayItem(cvf::Font* font); explicit RivTernarySaturationOverlayItem(cvf::Font* font);
~RivTernarySaturationOverlayItem(); ~RivTernarySaturationOverlayItem();
virtual void computeLayoutAndExtents() override;
void setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange); void setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange);

View File

@ -370,6 +370,7 @@ void RimLegendConfig::updateLegend()
numDecimalDigits -= static_cast<int>(decadesInRange); numDecimalDigits -= static_cast<int>(decadesInRange);
} }
m_scalarMapperLegend->setTickPrecision(cvf::Math::clamp(numDecimalDigits, 0, 20)); m_scalarMapperLegend->setTickPrecision(cvf::Math::clamp(numDecimalDigits, 0, 20));
m_scalarMapperLegend->computeLayoutAndExtents();
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
RiaPreferences* preferences = app->preferences(); RiaPreferences* preferences = app->preferences();

View File

@ -614,6 +614,17 @@ void RiuViewer::addColorLegendToBottomLeftCorner(caf::TitledOverlayFrame* legend
yPos += item->sizeHint().y() + border + edgeAxisBorderHeight; 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);
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -41,6 +41,7 @@ namespace caf {
CategoryLegend::CategoryLegend(Font* font, const CategoryMapper* categoryMapper) CategoryLegend::CategoryLegend(Font* font, const CategoryMapper* categoryMapper)
: TitledOverlayFrame(font, 200, 200) : TitledOverlayFrame(font, 200, 200)
, m_categoryMapper(categoryMapper) , m_categoryMapper(categoryMapper)
, m_Layout(Vec2i(0, 0), Vec2ui(200u, 200u))
{ {
CVF_ASSERT(font); CVF_ASSERT(font);
CVF_ASSERT(!font->isEmpty()); CVF_ASSERT(!font->isEmpty());
@ -128,17 +129,9 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext,
camera.applyOpenGL(); camera.applyOpenGL();
camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH);
// Get layout information this->computeLayoutAndExtents();
// Todo: Cache this between renderings. Update only when needed.
OverlayColorLegendLayoutInfo layout(position, size);
layoutInfo(&layout);
// Set up text drawer Vec2f backgroundSize(CVF_MIN((float) this->width(), (float)size.x()), (float)size.y());
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());
// Do the actual rendering // Do the actual rendering
if (software) if (software)
@ -147,8 +140,8 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext,
backgroundSize, backgroundSize,
this->backgroundColor(), this->backgroundColor(),
this->backgroundFrameColor()); this->backgroundFrameColor());
renderLegendImmediateMode(oglContext, &layout); renderLegendImmediateMode(oglContext, &m_Layout);
textDrawer.renderSoftware(oglContext, camera); m_textDrawer->renderSoftware(oglContext, camera);
} }
else else
{ {
@ -158,8 +151,8 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext,
backgroundSize, backgroundSize,
this->backgroundColor(), this->backgroundColor(),
this->backgroundFrameColor()); this->backgroundFrameColor());
renderLegendUsingShaders(oglContext, &layout, matrixState); renderLegendUsingShaders(oglContext, &m_Layout, matrixState);
textDrawer.render(oglContext, camera); m_textDrawer->render(oglContext, camera);
} }
CVF_CHECK_OGL(oglContext); CVF_CHECK_OGL(oglContext);
@ -498,6 +491,22 @@ void CategoryLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout)
layout->tickX = layout->x1 + 5; 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<unsigned int>(std::ceil(maxLegendRightPos + m_Layout.margins.x()));
this->setMinimumWidth(contentWidth);
}

View File

@ -31,6 +31,7 @@ public:
virtual ~CategoryLegend(); virtual ~CategoryLegend();
size_t categoryCount() const; size_t categoryCount() const;
void computeLayoutAndExtents() override;
protected: protected:
void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) override; void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) override;
@ -81,7 +82,8 @@ protected:
protected: protected:
std::vector<bool> m_visibleCategoryLabels; // Skip labels ending up on top of previous visible label std::vector<bool> m_visibleCategoryLabels; // Skip labels ending up on top of previous visible label
OverlayColorLegendLayoutInfo m_Layout;
cvf::ref<cvf::TextDrawer> m_textDrawer;
cvf::cref<CategoryMapper> m_categoryMapper; cvf::cref<CategoryMapper> m_categoryMapper;
}; };

View File

@ -86,6 +86,7 @@ OverlayScalarMapperLegend::OverlayScalarMapperLegend(Font* font)
: TitledOverlayFrame(font, 200, 200) : TitledOverlayFrame(font, 200, 200)
, m_tickNumberPrecision(4) , m_tickNumberPrecision(4)
, m_numberFormat(AUTO) , m_numberFormat(AUTO)
, m_Layout(Vec2i(0, 0), Vec2ui(200u, 200u))
{ {
CVF_ASSERT(font); CVF_ASSERT(font);
CVF_ASSERT(!font->isEmpty()); CVF_ASSERT(!font->isEmpty());
@ -182,31 +183,26 @@ void OverlayScalarMapperLegend::renderGeneric(OpenGLContext* oglContext, const V
camera.applyOpenGL(); camera.applyOpenGL();
camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH);
// Get layout information m_Layout.position = position;
// Todo: Cache this between renderings. Update only when needed. m_Layout.size = size;
OverlayColorLegendLayoutInfo layout(position, size);
layoutInfo(&layout);
// Set up text drawer this->computeLayoutAndExtents();
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 // Do the actual rendering
if (software) if (software)
{ {
if (this->backgroundEnabled()) InternalLegendRenderTools::renderBackgroundImmediateMode(oglContext, backgroundSize, this->backgroundColor(), this->backgroundFrameColor()); if (this->backgroundEnabled()) InternalLegendRenderTools::renderBackgroundImmediateMode(oglContext, backgroundSize, this->backgroundColor(), this->backgroundFrameColor());
renderLegendImmediateMode(oglContext, &layout); renderLegendImmediateMode(oglContext, &m_Layout);
textDrawer.renderSoftware(oglContext, camera); m_textDrawer->renderSoftware(oglContext, camera);
} }
else else
{ {
const MatrixState matrixState(camera); const MatrixState matrixState(camera);
if (this->backgroundEnabled()) InternalLegendRenderTools::renderBackgroundUsingShaders(oglContext, matrixState, backgroundSize, this->backgroundColor(), this->backgroundFrameColor()); if (this->backgroundEnabled()) InternalLegendRenderTools::renderBackgroundUsingShaders(oglContext, matrixState, backgroundSize, this->backgroundColor(), this->backgroundFrameColor());
renderLegendUsingShaders(oglContext, &layout, matrixState); renderLegendUsingShaders(oglContext, &m_Layout, matrixState);
textDrawer.render(oglContext, camera); m_textDrawer->render(oglContext, camera);
} }
CVF_CHECK_OGL(oglContext); CVF_CHECK_OGL(oglContext);
@ -666,6 +662,22 @@ void OverlayScalarMapperLegend::setTickFormat(NumberFormat format)
m_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<unsigned int>(std::ceil(maxLegendRightPos + m_Layout.margins.x()));
this->setMinimumWidth(contentWidth);
}
} // namespace cvf } // namespace cvf

View File

@ -85,7 +85,7 @@ public:
void setTickPrecision(int precision); void setTickPrecision(int precision);
enum NumberFormat { AUTO, SCIENTIFIC, FIXED}; enum NumberFormat { AUTO, SCIENTIFIC, FIXED};
void setTickFormat(NumberFormat format); void setTickFormat(NumberFormat format);
void computeLayoutAndExtents() override;
protected: protected:
void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override; void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override;
void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override; void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override;
@ -134,6 +134,8 @@ protected:
int m_tickNumberPrecision; int m_tickNumberPrecision;
NumberFormat m_numberFormat; NumberFormat m_numberFormat;
OverlayColorLegendLayoutInfo m_Layout;
cvf::ref<TextDrawer> m_textDrawer;
cvf::cref<ScalarMapper> m_scalarMapper; cvf::cref<ScalarMapper> m_scalarMapper;
}; };

View File

@ -2,6 +2,8 @@
#include "cafCategoryMapper.h" #include "cafCategoryMapper.h"
#include "cvfFont.h" #include "cvfFont.h"
#include <algorithm>
using namespace cvf; using namespace cvf;
namespace caf { namespace caf {
@ -12,6 +14,7 @@ namespace caf {
TitledOverlayFrame::TitledOverlayFrame(Font* font, unsigned int width, unsigned int height) TitledOverlayFrame::TitledOverlayFrame(Font* font, unsigned int width, unsigned int height)
: m_font(font) : m_font(font)
, m_sizeHint(width, height) , m_sizeHint(width, height)
, m_minimumWidth(0u)
, m_textColor(Color3::BLACK) , m_textColor(Color3::BLACK)
, m_lineColor(Color3::BLACK) , m_lineColor(Color3::BLACK)
, m_lineWidth(1) , m_lineWidth(1)
@ -33,6 +36,23 @@ namespace caf {
m_sizeHint = size; 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 /// Set color of the text
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -107,6 +127,22 @@ namespace caf {
return m_sizeHint; return m_sizeHint;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
unsigned int TitledOverlayFrame::minimumWidth()
{
return m_minimumWidth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
unsigned int TitledOverlayFrame::width()
{
return m_actualWidth;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -22,6 +22,8 @@ namespace caf {
virtual ~TitledOverlayFrame(); virtual ~TitledOverlayFrame();
virtual void setSizeHint(const cvf::Vec2ui& size); virtual void setSizeHint(const cvf::Vec2ui& size);
void setMinimumWidth(unsigned int width);
void setWidth(unsigned int width);
void setTextColor(const cvf::Color3f& color); void setTextColor(const cvf::Color3f& color);
void setLineColor(const cvf::Color3f& lineColor); void setLineColor(const cvf::Color3f& lineColor);
@ -33,7 +35,11 @@ namespace caf {
void setBackgroundColor(const cvf::Color4f& backgroundColor); void setBackgroundColor(const cvf::Color4f& backgroundColor);
void setBackgroundFrameColor(const cvf::Color4f& backgroundFrameColor); void setBackgroundFrameColor(const cvf::Color4f& backgroundFrameColor);
virtual void computeLayoutAndExtents() = 0;
virtual cvf::Vec2ui sizeHint() override; virtual cvf::Vec2ui sizeHint() override;
unsigned int minimumWidth();
unsigned int width();
protected: protected:
cvf::Color3f textColor() const; cvf::Color3f textColor() const;
@ -48,6 +54,9 @@ namespace caf {
private: private:
cvf::Vec2ui m_sizeHint; // The desired pixel size of the color legend area 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_textColor;
cvf::Color3f m_lineColor; cvf::Color3f m_lineColor;
int m_lineWidth; int m_lineWidth;