#2657 Final cleanup and refactoring of legends size system

This commit is contained in:
Jacob Støren 2018-04-20 16:55:51 +02:00
parent 03ec76c20a
commit 3957027b4b
10 changed files with 49 additions and 141 deletions

View File

@ -43,7 +43,7 @@
RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font)
: TitledOverlayFrame(font, 120, 150)
{
this->computeLayoutAndExtents( this->sizeHint());
}
//--------------------------------------------------------------------------------------------------
@ -54,14 +54,6 @@ RivTernarySaturationOverlayItem::~RivTernarySaturationOverlayItem()
// Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::computeLayoutAndExtents(const cvf::Vec2ui& size)
{
this->setMinimumWidth(size.x());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -102,7 +94,6 @@ void RivTernarySaturationOverlayItem::renderGeneric(cvf::OpenGLContext* oglConte
float border = 0.0f;
cvf::Vec2ui sizeFrameBox = size;
sizeFrameBox.x() = this->matchedWidth(); // Match to other legends
cvf::Camera camera;
camera.setViewport(position.x(), position.y(), sizeFrameBox.x(), sizeFrameBox.y());

View File

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

View File

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

View File

@ -602,11 +602,11 @@ void RiuViewer::addColorLegendToBottomLeftCorner(caf::TitledOverlayFrame* legend
if (catLegend->categoryCount() > categoryThreshold)
{
catLegend->setSizeHint(cvf::Vec2ui(categoryWidth, height - 2 * border - axisCrossHeight - 2 * edgeAxisBorderHeight));
catLegend->setRenderSize(cvf::Vec2ui(categoryWidth, height - 3 * border - axisCrossHeight - 2 * edgeAxisBorderHeight));
}
else
{
catLegend->setSizeHint(cvf::Vec2ui(200, 200));
catLegend->setRenderSize(cvf::Vec2ui(categoryWidth, 200));
}
xPos += categoryWidth + border;
}
@ -615,20 +615,21 @@ void RiuViewer::addColorLegendToBottomLeftCorner(caf::TitledOverlayFrame* legend
{
item->setLayoutFixedPosition(cvf::Vec2i(xPos, yPos));
yPos += item->sizeHint().y() + border + edgeAxisBorderHeight;
yPos += item->renderSize().y() + border + edgeAxisBorderHeight;
}
}
unsigned int requiredLegendWidth = 0u;
for (auto legend : overlayItems)
{
legend->computeLayoutAndExtents(legend->sizeHint());
requiredLegendWidth = std::max(requiredLegendWidth, legend->minimumWidth());
requiredLegendWidth = std::max(requiredLegendWidth, legend->preferredSize().x());
}
for (auto legend : overlayItems)
{
legend->setMatchedWidth(requiredLegendWidth);
cvf::Vec2ui widthAdjustedSize = legend->renderSize();
widthAdjustedSize.x() = requiredLegendWidth;
legend->setRenderSize(widthAdjustedSize);
}
}
@ -890,7 +891,7 @@ cvf::OverlayItem* RiuViewer::pickFixedPositionedLegend(int winPosX, int winPosY)
for (auto overlayItem : m_visibleLegends)
{
if (overlayItem->layoutScheme() == cvf::OverlayItem::FIXED_POSITION &&
overlayItem->pick(translatedMousePosX, translatedMousePosY, overlayItem->fixedPosition(), overlayItem->sizeHint()))
overlayItem->pick(translatedMousePosX, translatedMousePosY, overlayItem->fixedPosition(), overlayItem->renderSize()))
{
return overlayItem.p();
}

View File

@ -29,6 +29,7 @@
#include "cvfScalarMapper.h"
#include "cafInternalLegendRenderTools.h"
#include <cmath>
using namespace cvf;
@ -129,9 +130,15 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext,
camera.applyOpenGL();
camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH);
this->computeLayoutAndExtents(size);
m_Layout = OverlayColorLegendLayoutInfo(size);
layoutInfo(&m_Layout);
m_textDrawer = new TextDrawer(this->font());
Vec2f backgroundSize(CVF_MIN((float)this->minimumWidth(), (float)size.x()), (float)size.y());
// Set up text drawer
float maxLegendRightPos = 0;
setupTextDrawer(m_textDrawer.p(), &m_Layout);
Vec2f backgroundSize(size);
// Do the actual rendering
if (software)
@ -162,8 +169,7 @@ void CategoryLegend::renderGeneric(OpenGLContext* oglContext,
///
//--------------------------------------------------------------------------------------------------
void CategoryLegend::setupTextDrawer(TextDrawer* textDrawer,
const OverlayColorLegendLayoutInfo* layout,
float* maxLegendRightPos)
const OverlayColorLegendLayoutInfo* layout)
{
if (m_categoryMapper.isNull())
{
@ -172,8 +178,6 @@ void CategoryLegend::setupTextDrawer(TextDrawer* textDrawer,
CVF_ASSERT(layout);
float legendRight = 0.0f;
textDrawer->setVerticalAlignment(TextDrawer::CENTER);
textDrawer->setTextColor(this->textColor());
@ -218,9 +222,6 @@ void CategoryLegend::setupTextDrawer(TextDrawer* textDrawer,
Vec2f pos(textX, textY);
textDrawer->addText(displayText, pos);
float neededRightPos = pos.x() + this->font()->textExtent(displayText).x();
legendRight = legendRight >= neededRightPos ? legendRight :neededRightPos;
lastVisibleTextY = textY;
m_visibleCategoryLabels.push_back(true);
}
@ -231,13 +232,9 @@ void CategoryLegend::setupTextDrawer(TextDrawer* textDrawer,
Vec2f pos(layout->margins.x(), titleY);
textDrawer->addText(this->titleStrings()[it], pos);
float neededRightPos = pos.x() + this->font()->textExtent(this->titleStrings()[it]).x();
legendRight = legendRight >= neededRightPos ? legendRight :neededRightPos;
titleY -= layout->lineSpacing;
}
*maxLegendRightPos = legendRight;
}
//--------------------------------------------------------------------------------------------------
@ -498,24 +495,6 @@ void CategoryLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout)
layout->tickEndX = layout->tickMidX + 5;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void CategoryLegend::computeLayoutAndExtents(const Vec2ui& size)
{
// Todo: Cache this between renderings. Update only when needed.
m_Layout = OverlayColorLegendLayoutInfo(size);
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>(cvf::Math::ceil(maxLegendRightPos + m_Layout.margins.x()));
this->setMinimumWidth(contentWidth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -524,7 +503,7 @@ cvf::Vec2ui CategoryLegend::preferredSize()
OverlayColorLegendLayoutInfo layout({200,200}); // Use default size
layoutInfo(&layout);
unsigned int prefferredYSize = 2*layout.margins.y() + (this->titleStrings().size() + m_categoryMapper->categoryCount() )* layout.lineSpacing ;
float prefferredYSize = 2*layout.margins.y() + (this->titleStrings().size() + m_categoryMapper->categoryCount() )* layout.lineSpacing ;
unsigned int maxTickTextWidth = 0;
for (size_t cIdx = 0; cIdx < m_categoryMapper->categoryCount(); ++cIdx )
@ -534,17 +513,17 @@ cvf::Vec2ui CategoryLegend::preferredSize()
maxTickTextWidth = maxTickTextWidth < textWidth ? textWidth : maxTickTextWidth;
}
unsigned int prefferredXSize = layout.tickEndX + layout.margins.x() + layout.tickTextLeadSpace + maxTickTextWidth;
float prefferredXSize = layout.tickEndX + layout.margins.x() + layout.tickTextLeadSpace + maxTickTextWidth;
for (const cvf::String& titleLine : titleStrings())
{
unsigned int titleWidth = this->font()->textExtent(titleLine).x() + 2*layout.margins.x();
float titleWidth = this->font()->textExtent(titleLine).x() + 2*layout.margins.x();
prefferredXSize = prefferredXSize < titleWidth ? titleWidth : prefferredXSize;
}
prefferredXSize = std::min(prefferredXSize, 400u);
prefferredXSize = std::min(prefferredXSize, 400.0f);
return { prefferredXSize, prefferredYSize };
return { (unsigned int)(std::ceil(prefferredXSize)), (unsigned int)(std::ceil(prefferredYSize)) };
}

View File

@ -31,7 +31,6 @@ public:
virtual ~CategoryLegend();
size_t categoryCount() const;
void computeLayoutAndExtents(const cvf::Vec2ui& size) override;
cvf::Vec2ui preferredSize() override;
@ -72,8 +71,7 @@ protected:
const cvf::Vec2ui& size,
bool software);
void setupTextDrawer(cvf::TextDrawer* textDrawer,
const OverlayColorLegendLayoutInfo* layout,
float* maxLegendRightPos);
const OverlayColorLegendLayoutInfo* layout);
void renderLegendUsingShaders(cvf::OpenGLContext* oglContext,
OverlayColorLegendLayoutInfo* layout,
const cvf::MatrixState& matrixState);

View File

@ -186,9 +186,15 @@ void OverlayScalarMapperLegend::renderGeneric(OpenGLContext* oglContext, const V
camera.applyOpenGL();
camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH);
this->computeLayoutAndExtents( size);
m_Layout = OverlayColorLegendLayoutInfo(size);
layoutInfo(&m_Layout);
m_textDrawer = new TextDrawer(this->font());
Vec2f backgroundSize((float)this->matchedWidth(), (float)size.y());
// Set up text drawer
float maxLegendRightPos = 0;
setupTextDrawer(m_textDrawer.p(), &m_Layout );
Vec2f backgroundSize(size);
// Do the actual rendering
if (software)
@ -225,12 +231,10 @@ void OverlayScalarMapperLegend::renderGeneric(OpenGLContext* oglContext, const V
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setupTextDrawer(TextDrawer* textDrawer, const OverlayColorLegendLayoutInfo* layout, float* maxLegendRightPos)
void OverlayScalarMapperLegend::setupTextDrawer(TextDrawer* textDrawer, const OverlayColorLegendLayoutInfo* layout)
{
CVF_ASSERT(layout);
float legendRight = 0.0f;
textDrawer->setVerticalAlignment(TextDrawer::CENTER);
textDrawer->setTextColor(this->textColor());
@ -285,9 +289,6 @@ void OverlayScalarMapperLegend::setupTextDrawer(TextDrawer* textDrawer, const Ov
Vec2f pos(textX, textY);
textDrawer->addText(valueString, pos);
float neededRightPos = pos.x() + this->font()->textExtent(valueString).x();
legendRight = legendRight >= neededRightPos ? legendRight :neededRightPos;
lastVisibleTextY = textY;
m_visibleTickLabels.push_back(true);
}
@ -298,14 +299,9 @@ void OverlayScalarMapperLegend::setupTextDrawer(TextDrawer* textDrawer, const Ov
Vec2f pos(layout->margins.x(), titleY);
textDrawer->addText(this->titleStrings()[it], pos);
float neededRightPos = pos.x() + this->font()->textExtent(this->titleStrings()[it]).x();
legendRight = legendRight >= neededRightPos ? legendRight :neededRightPos;
titleY -= layout->lineSpacing;
}
*maxLegendRightPos = legendRight;
}
@ -682,25 +678,6 @@ void OverlayScalarMapperLegend::setTickFormat(NumberFormat format)
m_numberFormat = format;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::computeLayoutAndExtents( const Vec2ui& size)
{
// Todo: Cache this between renderings. Update only when needed.
//m_Layout = OverlayColorLegendLayoutInfo( size );
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>(cvf::Math::ceil(maxLegendRightPos + m_Layout.margins.x()));
this->setMinimumWidth(contentWidth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -709,7 +686,7 @@ cvf::Vec2ui OverlayScalarMapperLegend::preferredSize()
OverlayColorLegendLayoutInfo layout({200,200}); // Use default size
layoutInfo(&layout);
unsigned int prefferredYSize = 2*layout.margins.y() + (this->titleStrings().size() + m_tickValues.size() )* layout.lineSpacing ;
float prefferredYSize = 2*layout.margins.y() + (this->titleStrings().size() + m_tickValues.size() )* layout.lineSpacing ;
unsigned int maxTickTextWidth = 0;
for (double tickValue : m_tickValues )
@ -731,17 +708,17 @@ cvf::Vec2ui OverlayScalarMapperLegend::preferredSize()
maxTickTextWidth = maxTickTextWidth < textWidth ? textWidth : maxTickTextWidth;
}
unsigned int prefferredXSize = layout.tickEndX + layout.margins.x() + layout.tickTextLeadSpace + maxTickTextWidth;
float prefferredXSize = layout.tickEndX + layout.margins.x() + layout.tickTextLeadSpace + maxTickTextWidth;
for (const cvf::String& titleLine : titleStrings())
{
unsigned int titleWidth = this->font()->textExtent(titleLine).x() + 2*layout.margins.x();
float titleWidth = this->font()->textExtent(titleLine).x() + 2*layout.margins.x();
prefferredXSize = prefferredXSize < titleWidth ? titleWidth : prefferredXSize;
}
prefferredXSize = std::min(prefferredXSize, 400u);
prefferredXSize = std::min(prefferredXSize, 400.0f);
return { prefferredXSize, prefferredYSize };
return { (unsigned int)(std::ceil(prefferredXSize)), (unsigned int)(std::ceil(prefferredYSize)) };
}

View File

@ -85,7 +85,6 @@ public:
void setTickPrecision(int precision);
enum NumberFormat { AUTO, SCIENTIFIC, FIXED};
void setTickFormat(NumberFormat format);
void computeLayoutAndExtents(const cvf::Vec2ui& size) override;
virtual cvf::Vec2ui preferredSize() override;
@ -126,8 +125,7 @@ protected:
void renderLegendImmediateMode(OpenGLContext* oglContext,
OverlayColorLegendLayoutInfo* layout);
void setupTextDrawer(TextDrawer* textDrawer,
const OverlayColorLegendLayoutInfo* layout,
float* maxLegendRightPos);
const OverlayColorLegendLayoutInfo* layout);
protected:
DoubleArray m_tickValues; // Ticks between each level + top and bottom of legend (n+1 entries)

View File

@ -13,8 +13,7 @@ namespace caf {
//--------------------------------------------------------------------------------------------------
TitledOverlayFrame::TitledOverlayFrame(Font* font, unsigned int width, unsigned int height)
: m_font(font)
, m_sizeHint(width, height)
, m_minimumWidth(0u)
, m_renderSize(width, height)
, m_textColor(Color3::BLACK)
, m_lineColor(Color3::BLACK)
, m_lineWidth(1)
@ -31,26 +30,17 @@ namespace caf {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TitledOverlayFrame::setSizeHint(const Vec2ui& size)
void TitledOverlayFrame::setRenderSize(const Vec2ui& size)
{
m_sizeHint = size;
}
//--------------------------------------------------------------------------------------------------
/// Will also update the matched width since this should always be >= minimum width
//--------------------------------------------------------------------------------------------------
void TitledOverlayFrame::setMinimumWidth(unsigned int width)
{
m_minimumWidth = width;
m_matchedWidth = std::max(m_minimumWidth, m_matchedWidth);
m_renderSize = size;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TitledOverlayFrame::setMatchedWidth(unsigned int width)
cvf::Vec2ui TitledOverlayFrame::renderSize() const
{
m_matchedWidth = width;
return m_renderSize;
}
//--------------------------------------------------------------------------------------------------
@ -124,23 +114,7 @@ namespace caf {
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui TitledOverlayFrame::sizeHint()
{
return m_sizeHint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
unsigned int TitledOverlayFrame::minimumWidth()
{
return m_minimumWidth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
unsigned int TitledOverlayFrame::matchedWidth()
{
return m_matchedWidth;
return m_renderSize;
}
//--------------------------------------------------------------------------------------------------

View File

@ -21,9 +21,8 @@ namespace caf {
TitledOverlayFrame(cvf::Font* font, unsigned int width = 100, unsigned int height = 200);
virtual ~TitledOverlayFrame();
virtual void setSizeHint(const cvf::Vec2ui& size);
void setMinimumWidth(unsigned int width);
void setMatchedWidth(unsigned int width);
void setRenderSize(const cvf::Vec2ui& size);
cvf::Vec2ui renderSize() const;
void setTextColor(const cvf::Color3f& color);
void setLineColor(const cvf::Color3f& lineColor);
@ -35,12 +34,7 @@ namespace caf {
void setBackgroundColor(const cvf::Color4f& backgroundColor);
void setBackgroundFrameColor(const cvf::Color4f& backgroundFrameColor);
virtual void computeLayoutAndExtents(const cvf::Vec2ui& size) = 0;
virtual cvf::Vec2ui preferredSize() = 0;
unsigned int minimumWidth();
unsigned int matchedWidth();
protected:
cvf::Color3f textColor() const;
@ -55,9 +49,7 @@ namespace caf {
private:
cvf::Vec2ui sizeHint() override final; // Will return the size to use for rendering, and is really not a hint.
cvf::Vec2ui m_sizeHint; // The desired pixel size of the color legend area
unsigned int m_minimumWidth; // Minimum width required to fit content
unsigned int m_matchedWidth; // Width matched to other legends (>= minimumWidth)
cvf::Vec2ui m_renderSize; // The rendered size of the color legend area in pixels
cvf::Color3f m_textColor;
cvf::Color3f m_lineColor;