#2822, #2731, #2730 Rewrote the legend layout completely.

Now using preferred size unless it is higher than 0.7 viewer height.
If higher,  then use viewer height.
Stacks legend in columns not higher then the viewer.
Update layout on resize without triggering recreation of legends.
Place axiscross in right bottom corner.
This commit is contained in:
Jacob Støren 2018-05-04 13:32:41 +02:00
parent 4713700c24
commit 1fe4f67a8e
2 changed files with 66 additions and 72 deletions

View File

@ -63,6 +63,7 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QProgressBar> #include <QProgressBar>
#include "WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h" #include "WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h"
#include <algorithm>
using cvf::ManipulatorTrackball; using cvf::ManipulatorTrackball;
@ -88,7 +89,7 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent)
cvf::Font* standardFont = RiaApplication::instance()->standardFont(); cvf::Font* standardFont = RiaApplication::instance()->standardFont();
m_axisCross = new cvf::OverlayAxisCross(m_mainCamera.p(), standardFont); m_axisCross = new cvf::OverlayAxisCross(m_mainCamera.p(), standardFont);
m_axisCross->setAxisLabels("X", "Y", "Z"); m_axisCross->setAxisLabels("X", "Y", "Z");
m_axisCross->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT); m_axisCross->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_RIGHT);
m_mainRendering->addOverlayItem(m_axisCross.p()); m_mainRendering->addOverlayItem(m_axisCross.p());
m_showAxisCross = true; m_showAxisCross = true;
@ -536,7 +537,7 @@ void RiuViewer::removeAllColorLegends()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RiuViewer::addColorLegendToBottomLeftCorner(caf::TitledOverlayFrame* legend) void RiuViewer::addColorLegendToBottomLeftCorner(caf::TitledOverlayFrame* addedLegend)
{ {
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
CVF_ASSERT(app); CVF_ASSERT(app);
@ -545,91 +546,97 @@ void RiuViewer::addColorLegendToBottomLeftCorner(caf::TitledOverlayFrame* legend
CVF_ASSERT(preferences); CVF_ASSERT(preferences);
CVF_ASSERT(firstRendering); CVF_ASSERT(firstRendering);
if (legend) if (addedLegend)
{ {
cvf::Color4f backgroundColor = mainCamera()->viewport()->clearColor(); cvf::Color4f backgroundColor = mainCamera()->viewport()->clearColor();
backgroundColor.a() = 0.8f; backgroundColor.a() = 0.8f;
cvf::Color3f frameColor(backgroundColor.r(), backgroundColor.g(), backgroundColor.b()); cvf::Color3f frameColor(backgroundColor.r(), backgroundColor.g(), backgroundColor.b());
updateLegendTextAndTickMarkColor(legend); updateLegendTextAndTickMarkColor(addedLegend);
firstRendering->addOverlayItem(legend); firstRendering->addOverlayItem(addedLegend);
legend->enableBackground(preferences->showLegendBackground()); addedLegend->enableBackground(preferences->showLegendBackground());
legend->setBackgroundColor(backgroundColor); addedLegend->setBackgroundColor(backgroundColor);
legend->setBackgroundFrameColor(cvf::Color4f(RiaColorTools::computeOffsetColor(frameColor, 0.3f), 0.9f)); addedLegend->setBackgroundFrameColor(cvf::Color4f(RiaColorTools::computeOffsetColor(frameColor, 0.3f), 0.9f));
m_visibleLegends.push_back(legend); m_visibleLegends.push_back(addedLegend);
} }
// Category count used to switch between standard height and full height of legend updateLegendLayout();
const size_t categoryThreshold = 13;
std::vector<caf::CategoryLegend*> categoryLegends; }
std::vector<caf::TitledOverlayFrame*> overlayItems;
for (auto legend : m_visibleLegends)
{
legend->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT);
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuViewer::updateLegendLayout()
{
int viewPortHeight = static_cast<int>(m_mainCamera->viewport()->height());
caf::CategoryLegend* catLegend = dynamic_cast<caf::CategoryLegend*>(legend.p()); const float maxFreeLegendHeight = 0.7f*viewPortHeight;
if (catLegend)
{
categoryLegends.push_back(catLegend);
}
else
{
overlayItems.push_back(legend.p());
}
}
if (categoryLegends.size() > 0 || m_showWindowEdgeAxes)
{
const int border = 3; const int border = 3;
const int categoryWidth = 150;
int edgeAxisBorderWidth = m_showWindowEdgeAxes ? m_windowEdgeAxisOverlay->frameBorderWidth(): 0; int edgeAxisBorderWidth = m_showWindowEdgeAxes ? m_windowEdgeAxisOverlay->frameBorderWidth(): 0;
int edgeAxisBorderHeight = m_showWindowEdgeAxes ? m_windowEdgeAxisOverlay->frameBorderHeight(): 0; int edgeAxisBorderHeight = m_showWindowEdgeAxes ? m_windowEdgeAxisOverlay->frameBorderHeight(): 0;
// This value is taken from OverlayAxisCross, as the axis cross is always shown in the lower left corner
const int axisCrossHeight = m_showAxisCross? 120 : 0;
int height = static_cast<int>(m_mainCamera->viewport()->height());
int xPos = border + edgeAxisBorderWidth; int xPos = border + edgeAxisBorderWidth;
int yPos = border + edgeAxisBorderHeight;
int yPos = axisCrossHeight + 2*border + edgeAxisBorderHeight; std::vector<caf::TitledOverlayFrame*> standardHeightLegends;
for (auto catLegend : categoryLegends) // Place the legends needing the full height, and sort out the standard height legends
for ( cvf::ref<caf::TitledOverlayFrame> legend : m_visibleLegends )
{ {
catLegend->setLayoutFixedPosition(cvf::Vec2i(xPos, yPos)); cvf::Vec2ui prefSize = legend->preferredSize();
if (prefSize.y() > maxFreeLegendHeight)
if (catLegend->categoryCount() > categoryThreshold)
{ {
catLegend->setRenderSize(cvf::Vec2ui(categoryWidth, height - 3 * border - axisCrossHeight - 2 * edgeAxisBorderHeight)); int legendWidth = prefSize.x();
legend->setLayoutFixedPosition(cvf::Vec2i(xPos, yPos));
legend->setRenderSize(cvf::Vec2ui(legendWidth, viewPortHeight - 2 * border - 2 * edgeAxisBorderHeight));
xPos += legendWidth + border;
} }
else else
{ {
catLegend->setRenderSize(cvf::Vec2ui(categoryWidth, 200)); standardHeightLegends.push_back(legend.p());
} }
xPos += categoryWidth + border;
} }
for (auto item : overlayItems) // Place the rest of the legends in columns that fits within the screen height
int maxColumnWidht = 0;
std::vector<caf::TitledOverlayFrame*> columnLegends;
for ( caf::TitledOverlayFrame* legend : standardHeightLegends )
{ {
item->setLayoutFixedPosition(cvf::Vec2i(xPos, yPos)); cvf::Vec2ui prefSize = legend->preferredSize();
yPos += item->renderSize().y() + border + edgeAxisBorderHeight; // Check if we need a new column
} if ((yPos + (int)prefSize.y() + border) > viewPortHeight)
}
unsigned int requiredLegendWidth = 0u;
for (auto legend : overlayItems)
{ {
requiredLegendWidth = std::max(requiredLegendWidth, legend->preferredSize().x()); xPos += border + maxColumnWidht;
yPos = border + edgeAxisBorderHeight;
// Set same width to all legends in the column
for (caf::TitledOverlayFrame* legend : columnLegends )
{
legend->setRenderSize(cvf::Vec2ui(maxColumnWidht, legend->renderSize().y()));
}
maxColumnWidht = 0;
columnLegends.clear();
} }
for (auto legend : overlayItems) legend->setLayoutFixedPosition(cvf::Vec2i(xPos, yPos));
legend->setRenderSize(cvf::Vec2ui(prefSize.x(), prefSize.y()));
columnLegends.push_back(legend);
yPos += legend->renderSize().y() + border;
maxColumnWidht = std::max(maxColumnWidht, (int)prefSize.x());
}
// Set same width to all legends in the last column
for (caf::TitledOverlayFrame* legend : columnLegends )
{ {
cvf::Vec2ui widthAdjustedSize = legend->renderSize(); legend->setRenderSize(cvf::Vec2ui(maxColumnWidht, legend->renderSize().y()));
widthAdjustedSize.x() = requiredLegendWidth;
legend->setRenderSize(widthAdjustedSize);
} }
} }
@ -758,21 +765,7 @@ void RiuViewer::optimizeClippingPlanes()
void RiuViewer::resizeGL(int width, int height) void RiuViewer::resizeGL(int width, int height)
{ {
caf::Viewer::resizeGL(width, height); caf::Viewer::resizeGL(width, height);
this->updateLegendLayout();
bool hasCategoryLegend = false;
for (size_t i = 0; i < m_visibleLegends.size(); i++)
{
caf::CategoryLegend* categoryLegend = dynamic_cast<caf::CategoryLegend*>(m_visibleLegends.at(i));
if (categoryLegend)
{
hasCategoryLegend = true;
}
}
if (hasCategoryLegend)
{
m_rimView->updateCurrentTimeStepAndRedraw();
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -127,6 +127,7 @@ protected:
virtual void leaveEvent(QEvent *) override; virtual void leaveEvent(QEvent *) override;
private: private:
void updateLegendLayout();
void updateTextAndTickMarkColorForOverlayItems(); void updateTextAndTickMarkColorForOverlayItems();
void updateLegendTextAndTickMarkColor(cvf::OverlayItem* legend); void updateLegendTextAndTickMarkColor(cvf::OverlayItem* legend);