/* * LayoutAuto.hh * * Created on: Sep, 2, 2014 * Author: AKKA */ #include "LayoutAuto.hh" #include "PlotLogger.hh" #include "DecoratorPlot.hh" #include namespace plot { /** * @Brief Add a panel characterized by it's constraint to the LayoutAuto */ void LayoutAuto::addPanel (PanelConstraint panelConstraint, double /*preferedWidth=-1*/, double /*preferedHeight=-1*/) { switch (panelConstraint) { case PanelConstraint::MaxWidth: _nbMaxWidthPanel++; break; case PanelConstraint::Square: _nbSquarePanel++; break; default: // TODO lever exception ici ??? break; } } /** * @Brief Reset LayoutAuto internal parameters and compute optimized parameters * like _panelHeight, _panelWidth, _panelXSpacing, _panelYSpacing... */ void LayoutAuto::reset (void) { // Reset current panels _curMaxWidthPanel = 0; _curSquarePanel = 0; _curSquarePanelLine = 0; // Compute general data for the layout depending on // - the number of panel // - their constraint _panelHeight = _requestPanelHeight; _panelYSpacing = _requestPanelSpacing; double layoutHeight = computeLayoutHeight (); // Shrink _requestPanelHeight if necessary if (layoutHeight > 1) { shrink (0.01); expand (0.001); } // Expand _requestPanelHeight if necessary and asked else if ((layoutHeight < 1) && (_autoExpand == true)) { expand (0.01); expand (0.001); expand (0.0001); } } /** * @Brief Decrease panelHeight by step while layoutHeight is more than 1.0 */ void LayoutAuto::shrink (double step) { double layoutHeight; do { // Decrease panelHeight by step and keep the same ratio for panelSpacing _panelHeight -= step; _panelYSpacing = _requestPanelSpacing * (_panelHeight / _requestPanelHeight); layoutHeight = computeLayoutHeight (); } while (layoutHeight > 1.0); } /** * @Brief Increase panelHeight by step until layoutHeight reach (but not over step) 1.0 */ void LayoutAuto::expand (double step) { double layoutHeight; do { // Increase panelHeight by step and keep the same ratio for panelSpacing _panelHeight += step; _panelYSpacing = _requestPanelSpacing * (_panelHeight / _requestPanelHeight); layoutHeight = computeLayoutHeight (); } while (layoutHeight < 1.0); // Restore last valid value for panelHeight and panelSpacing _panelHeight -= step; _panelYSpacing = _requestPanelSpacing * (_panelHeight / _requestPanelHeight); computeLayoutHeight (); } double LayoutAuto::computeLayoutHeight (void) { double layoutHeight = 0; _nbLineForSquarePanel = 0; _firstPanelHeightDelta = 0; _panelWidth = _panelHeight / _xyRatio; _panelXSpacing = _panelYSpacing / _xyRatio; // Computes _nbMaxSquarePanelByLine and nbLineForSquarePanel for the layout // then computes panelHeight _nbMaxSquarePanelByLine = (int) ((1.0 + _panelXSpacing) / (_panelWidth + _panelXSpacing)); _nbLineForSquarePanel = _nbSquarePanel / _nbMaxSquarePanelByLine; if ((_nbSquarePanel % _nbMaxSquarePanelByLine) != 0) _nbLineForSquarePanel++; // Computes height for MaxWidth Panel if (_nbMaxWidthPanel > 0) { layoutHeight += _nbMaxWidthPanel * _panelHeight + (_nbMaxWidthPanel - 1) * _panelYSpacing; _firstPanelHeightDelta = (_firstPanelHeightFactor-1.0) * _panelHeight; layoutHeight += _firstPanelHeightDelta; } // Computes height for Square Panel if (_nbSquarePanel > 0) layoutHeight += _nbLineForSquarePanel * _panelHeight + (_nbLineForSquarePanel - 1) * _panelYSpacing; // Add space between MaxWidth and Square ? if ((_nbMaxWidthPanel > 0) && (_nbSquarePanel > 0)) layoutHeight += _panelYSpacing; // LOG4CXX_DEBUG(gLogger,"Layout::computeLayoutHeight _nbMaxPanelSquareByLine = " << _nbMaxSquarePanelByLine); // LOG4CXX_DEBUG(gLogger,"Layout::computeLayoutHeight _nbLineForSquarePanel = " << _nbLineForSquarePanel); // LOG4CXX_DEBUG(gLogger,"Layout::computeLayoutHeight layoutHeight = " << layoutHeight); return layoutHeight; } Bounds & LayoutAuto::getNextBounds (PanelConstraint panelConstraint) { int nbSquarePanelOnLine; double lastSquarePanelXPosition; // Computes panels position on the layout depending on their constraints switch (panelConstraint) { case PanelConstraint::MaxWidth: _computedPanelBounds._x = 0; _computedPanelBounds._y = _curMaxWidthPanel *(_panelHeight + _panelYSpacing); _computedPanelBounds._width = 1.0; _computedPanelBounds._height = _panelHeight; // The first MaxWidth panel can have an extra panel height if (_curMaxWidthPanel != 0) { _computedPanelBounds._y += _firstPanelHeightDelta; } if (_curMaxWidthPanel == 0) { _computedPanelBounds._height += _firstPanelHeightDelta; } _curMaxWidthPanel++; break; case PanelConstraint::Square: // Compute number of square panel on the current line // Are we on the last PanelSquareLine ? if (_curSquarePanelLine == (_nbLineForSquarePanel - 1)) nbSquarePanelOnLine = _nbSquarePanel - (_curSquarePanelLine * _nbMaxSquarePanelByLine); else nbSquarePanelOnLine = _nbMaxSquarePanelByLine; // Compute x position of the last SquarePanel on the line (centered) lastSquarePanelXPosition = 0.5 + ((((nbSquarePanelOnLine) * _panelWidth) + ((nbSquarePanelOnLine-1) * _panelXSpacing)) / 2.0) - _panelWidth; _computedPanelBounds._x = lastSquarePanelXPosition - (_curSquarePanel % _nbMaxSquarePanelByLine) * (_panelWidth + _panelXSpacing);; _computedPanelBounds._y = (_nbMaxWidthPanel + _curSquarePanelLine) *(_panelHeight + _panelYSpacing); if (_nbMaxWidthPanel != 0) { _computedPanelBounds._y += _firstPanelHeightDelta; } _computedPanelBounds._width = _panelWidth; _computedPanelBounds._height = _panelHeight; _curSquarePanel++; // Next line for square panel if ((_curSquarePanel % _nbMaxSquarePanelByLine) == 0) _curSquarePanelLine++; break; default: // TODO lever exception ici ??? break; } return _computedPanelBounds; } void LayoutAuto::computePanelsPosition (std::vector> _plots) { // Add panels constraint to the layout for (auto plot : boost::adaptors::reverse(_plots)) { DecoratorPlot *decoratorPlot = dynamic_cast< DecoratorPlot* >(plot.get()); if (decoratorPlot != NULL) if (!decoratorPlot->_isStandalone) continue; this->addPanel ( plot->getLayoutConstraint(), plot->_panel->_preferedWidth, plot->_panel->_preferedHeight); } // Reset layout this->reset(); for (auto plot : boost::adaptors::reverse(_plots)) { DecoratorPlot *decoratorPlot = dynamic_cast< DecoratorPlot* >(plot.get()); if (decoratorPlot != NULL) if (!decoratorPlot->_isStandalone) continue; plot->_panel->_bounds = this->getNextBounds (plot->getLayoutConstraint()); } } }