#2657 Add a preferredSize method to the legends

This commit is contained in:
Jacob Støren 2018-04-20 13:33:44 +02:00
parent 0192f66a4d
commit 03ec76c20a
8 changed files with 116 additions and 13 deletions

View File

@ -177,7 +177,7 @@ void RivTernarySaturationOverlayItem::renderGeneric(cvf::OpenGLContext* oglConte
textDrawer.renderSoftware(oglContext, camera);
textPosY -= 3;
renderAxisImmediateMode(textPosY, 2*lineHeightInPixels + border, border, oglContext);
renderAxisImmediateMode(textPosY, 2*lineHeightInPixels + border, border, sizeFrameBox.x(), oglContext);
CVF_CHECK_OGL(oglContext);
}
@ -187,7 +187,11 @@ void RivTernarySaturationOverlayItem::renderGeneric(cvf::OpenGLContext* oglConte
//--------------------------------------------------------------------------------------------------
/// Draw the axis using immediate mode OpenGL
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::renderAxisImmediateMode(float upperBoundY, float lowerBoundY, float border, cvf::OpenGLContext* oglContext)
void RivTernarySaturationOverlayItem::renderAxisImmediateMode(float upperBoundY,
float lowerBoundY,
float border,
unsigned int totalWidth,
cvf::OpenGLContext* oglContext)
{
#ifdef CVF_OPENGL_ES
CVF_UNUSED(layout);
@ -207,8 +211,8 @@ void RivTernarySaturationOverlayItem::renderAxisImmediateMode(float upperBoundY,
//float upperBoundY = static_cast<float>(this->sizeHint().y() - 20);
cvf::Vec3f a(float(border), lowerBoundY, 0);
cvf::Vec3f b(static_cast<float>(this->sizeHint().x() - border), lowerBoundY, 0);
cvf::Vec3f c(static_cast<float>(this->sizeHint().x() / 2), upperBoundY, 0);
cvf::Vec3f b(static_cast<float>(totalWidth - border), lowerBoundY, 0);
cvf::Vec3f c(static_cast<float>(totalWidth / 2), upperBoundY, 0);
// Draw filled rectangle elements
@ -256,3 +260,11 @@ void RivTernarySaturationOverlayItem::setRangeText(const cvf::String& soilRange,
m_sgasRange = sgasRange;
m_swatRange = swatRange;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui RivTernarySaturationOverlayItem::preferredSize()
{
return {120, 150}; // Could do more elaborate text width checks.
}

View File

@ -46,6 +46,7 @@ public:
void setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange);
void setAxisLabelsColor(const cvf::Color3f& color);
cvf::Vec2ui preferredSize() override;
private:
void render(cvf::OpenGLContext* oglContext,
@ -59,7 +60,11 @@ private:
const cvf::Vec2i& position,
const cvf::Vec2ui& size,
bool software);
void renderAxisImmediateMode(float upperY, float lowerBoundY, float border, cvf::OpenGLContext* oglContext);
void renderAxisImmediateMode(float upperY,
float lowerBoundY,
float border,
unsigned int totalWidth,
cvf::OpenGLContext* oglContext);
private:
cvf::String m_soilRange;

View File

@ -61,11 +61,10 @@ RiuCvfOverlayItemWidget::~RiuCvfOverlayItemWidget()
//--------------------------------------------------------------------------------------------------
void RiuCvfOverlayItemWidget::updateFromOverlyItem( cvf::OverlayItem * item)
{
//m_scalarMapperLegend->setTitle("Hei og hopp");
//m_scalarMapperLegend->computeLayoutAndExtents({0,0}, {100, 400});
//unsigned int width = m_scalarMapperLegend->minimumWidth() + 100;
unsigned int width = item->sizeHint().x();
unsigned int height = item->sizeHint().y();
// Use the render size of the overlayItem (sizeHint should be renamed)
unsigned int width = item->sizeHint().x();
unsigned int height = item->sizeHint().y();
QGLFormat glFormat;
glFormat.setDirectRendering(RiaApplication::instance()->useShaders());

View File

@ -179,7 +179,7 @@ void CategoryLegend::setupTextDrawer(TextDrawer* textDrawer,
m_visibleCategoryLabels.clear();
const float textX = layout->tickEndX + 5;
const float textX = layout->tickEndX + layout->tickTextLeadSpace;
const float overlapTolerance = 1.2f * layout->charHeight;
float lastVisibleTextY = 0.0;
@ -476,6 +476,7 @@ void CategoryLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout)
layout->charHeight = static_cast<float>(glyph->height());
layout->lineSpacing = layout->charHeight*1.5f;
layout->margins = Vec2f(8.0f, 8.0f);
layout->tickTextLeadSpace = 5.0f;
float colorBarWidth = 25.0f;
float colorBarHeight = static_cast<float>(layout->overallLegendSize.y())
@ -515,6 +516,37 @@ void CategoryLegend::computeLayoutAndExtents(const Vec2ui& size)
this->setMinimumWidth(contentWidth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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 ;
unsigned int maxTickTextWidth = 0;
for (size_t cIdx = 0; cIdx < m_categoryMapper->categoryCount(); ++cIdx )
{
cvf::String cathegoryText = m_categoryMapper->textForCategoryIndex(cIdx);
unsigned int textWidth = this->font()->textExtent(cathegoryText).x();
maxTickTextWidth = maxTickTextWidth < textWidth ? textWidth : maxTickTextWidth;
}
unsigned int 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();
prefferredXSize = prefferredXSize < titleWidth ? titleWidth : prefferredXSize;
}
prefferredXSize = std::min(prefferredXSize, 400u);
return { prefferredXSize, prefferredYSize };
}
} // namespace cvf

View File

@ -33,6 +33,8 @@ public:
size_t categoryCount() const;
void computeLayoutAndExtents(const cvf::Vec2ui& size) override;
cvf::Vec2ui preferredSize() override;
protected:
void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) override;
void renderSoftware(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) override;
@ -56,6 +58,7 @@ protected:
float lineSpacing;
cvf::Vec2f margins;
float tickStartX, tickMidX, tickEndX;
float tickTextLeadSpace;
cvf::Rectf colorBarRect;

View File

@ -65,6 +65,7 @@
#include "cvfScalarMapper.h"
#include <array>
#include "cvfRenderStateBlending.h"
#include <algorithm>
namespace caf {
@ -235,7 +236,7 @@ void OverlayScalarMapperLegend::setupTextDrawer(TextDrawer* textDrawer, const Ov
m_visibleTickLabels.clear();
const float textX = layout->tickEndX + 5;
const float textX = layout->tickEndX + layout->tickTextLeadSpace;
const float overlapTolerance = 1.2f * layout->charHeight;
float lastVisibleTextY = 0.0;
@ -622,6 +623,7 @@ void OverlayScalarMapperLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout)
layout->charHeight = static_cast<float>(glyph->height());
layout->lineSpacing = layout->charHeight*1.5f;
layout->margins = Vec2f(8.0f, 8.0f);
layout->tickTextLeadSpace = 5.0f;
float colorBarWidth = 25.0f;
float colorBarHeight = static_cast<float>(layout->overallLegendSize.y())
@ -699,5 +701,49 @@ void OverlayScalarMapperLegend::computeLayoutAndExtents( const Vec2ui& size)
this->setMinimumWidth(contentWidth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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 ;
unsigned int maxTickTextWidth = 0;
for (double tickValue : m_tickValues )
{
String valueString;
switch ( m_numberFormat )
{
case FIXED:
valueString = String::number(tickValue, 'f', m_tickNumberPrecision);
break;
case SCIENTIFIC:
valueString = String::number(tickValue, 'e', m_tickNumberPrecision);
break;
default:
valueString = String::number(tickValue);
break;
}
unsigned int textWidth = this->font()->textExtent(valueString).x();
maxTickTextWidth = maxTickTextWidth < textWidth ? textWidth : maxTickTextWidth;
}
unsigned int 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();
prefferredXSize = prefferredXSize < titleWidth ? titleWidth : prefferredXSize;
}
prefferredXSize = std::min(prefferredXSize, 400u);
return { prefferredXSize, prefferredYSize };
}
} // namespace cvf

View File

@ -86,6 +86,9 @@ public:
enum NumberFormat { AUTO, SCIENTIFIC, FIXED};
void setTickFormat(NumberFormat format);
void computeLayoutAndExtents(const cvf::Vec2ui& size) override;
virtual cvf::Vec2ui preferredSize() override;
protected:
void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override;
void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override;
@ -102,6 +105,7 @@ protected:
float lineSpacing;
Vec2f margins;
float tickStartX, tickMidX, tickEndX;
float tickTextLeadSpace;
Rectf colorBarRect;

View File

@ -37,7 +37,8 @@ namespace caf {
virtual void computeLayoutAndExtents(const cvf::Vec2ui& size) = 0;
virtual cvf::Vec2ui sizeHint() override;
virtual cvf::Vec2ui preferredSize() = 0;
unsigned int minimumWidth();
unsigned int matchedWidth();
@ -53,6 +54,7 @@ namespace caf {
cvf::Font* font();
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)