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)
: 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());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -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);

View File

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

View File

@ -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);
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -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<unsigned int>(std::ceil(maxLegendRightPos + m_Layout.margins.x()));
this->setMinimumWidth(contentWidth);
}

View File

@ -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<bool> m_visibleCategoryLabels; // Skip labels ending up on top of previous visible label
cvf::cref<CategoryMapper> m_categoryMapper;
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;
};
}

View File

@ -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;
// Set up text drawer
float maxLegendRightPos = 0;
TextDrawer textDrawer(this->font());
setupTextDrawer(&textDrawer, &layout, &maxLegendRightPos);
this->computeLayoutAndExtents();
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);
@ -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<unsigned int>(std::ceil(maxLegendRightPos + m_Layout.margins.x()));
this->setMinimumWidth(contentWidth);
}
} // namespace cvf

View File

@ -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<ScalarMapper> m_scalarMapper;
OverlayColorLegendLayoutInfo m_Layout;
cvf::ref<TextDrawer> m_textDrawer;
cvf::cref<ScalarMapper> m_scalarMapper;
};
}

View File

@ -2,6 +2,8 @@
#include "cafCategoryMapper.h"
#include "cvfFont.h"
#include <algorithm>
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -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,7 +35,11 @@ namespace caf {
void setBackgroundColor(const cvf::Color4f& backgroundColor);
void setBackgroundFrameColor(const cvf::Color4f& backgroundFrameColor);
virtual void computeLayoutAndExtents() = 0;
virtual cvf::Vec2ui sizeHint() override;
unsigned int minimumWidth();
unsigned int width();
protected:
cvf::Color3f textColor() 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;