/* * Panel.cc * * Created on: 28 oct. 2013 * Author: CS */ #include "Panel.hh" #include "DefaultPlotConfiguration.hh" #include "ColormapManager.hh" #include "Label.hh" #include "PlotLogger.hh" #include "PlPlotUtil.hh" namespace plot { //Auto id set to a negative number to preserve id defined in request int Panel::PANEL_COUNTER = -1; Panel::Panel() : _id(--PANEL_COUNTER), _index(-1), _resolution(0), _updateTitleOnNextInterval(false), _bounds(Bounds()), _backgroundColor(Color()), _plotAreaBackgroundColor(Color()), _titleAlign(PlotCommon::Align::CENTER), _titlePosition(PlotCommon::Position::POS_TOP), _drawn(false), _page(), _preferedWidth(-1), _preferedHeight(-1), _leftMargin(-1), _rightMargin(-1), _topMargin(-1), _bottomMargin(-1), _paramsLegendProperties(), _textLegendPropertiesList(), _font(Font("", 0)), _title(Font("", 0)) { } Panel::Panel(DefaultPlotConfiguration &defaults) : _id(--PANEL_COUNTER), _index(defaults._defaultPanel._index), _resolution(defaults._defaultPanel._resolution), _updateTitleOnNextInterval(false), _bounds(Bounds()), _backgroundColor(defaults._defaultPanel._backgroundColor), _plotAreaBackgroundColor(defaults._defaultPanel._backgroundColor), _titleAlign(defaults._defaultPanel._titleAlign), _titlePosition(defaults._defaultPanel._titlePosition), _drawn(false), _page(), _preferedWidth(defaults._defaultPanel._preferedWidth), _preferedHeight(defaults._defaultPanel._preferedHeight), _leftMargin(defaults._defaultPanel._leftMargin), _rightMargin(defaults._defaultPanel._rightMargin), _topMargin(defaults._defaultPanel._topMargin), _bottomMargin(defaults._defaultPanel._bottomMargin), _textLegendPropertiesList(defaults._defaultPanel._textLegendPropertiesList), _font(defaults._defaultPanel.getFont()), _title(defaults._defaultPanel.getFont()) { } Panel::Panel(Page *page) : _id(--PANEL_COUNTER), _index(-1), _resolution(DefaultPlotConfiguration::getInstance()._defaultPanel._resolution), _updateTitleOnNextInterval(false), _bounds(Bounds()), _backgroundColor(DefaultPlotConfiguration::getInstance()._defaultPanel._backgroundColor), _plotAreaBackgroundColor(DefaultPlotConfiguration::getInstance()._defaultPanel._backgroundColor), _titleAlign(DefaultPlotConfiguration::getInstance()._defaultPanel._titleAlign), _titlePosition(DefaultPlotConfiguration::getInstance()._defaultPanel._titlePosition), _drawn(false), _page(page), _preferedWidth(DefaultPlotConfiguration::getInstance()._defaultPanel._preferedWidth), _preferedHeight(DefaultPlotConfiguration::getInstance()._defaultPanel._preferedHeight), _leftMargin(DefaultPlotConfiguration::getInstance()._defaultPanel._leftMargin), _rightMargin(DefaultPlotConfiguration::getInstance()._defaultPanel._rightMargin), _topMargin(DefaultPlotConfiguration::getInstance()._defaultPanel._topMargin), _bottomMargin(DefaultPlotConfiguration::getInstance()._defaultPanel._bottomMargin), _textLegendPropertiesList(DefaultPlotConfiguration::getInstance()._defaultPanel._textLegendPropertiesList), _font(Font( DefaultPlotConfiguration::getInstance()._defaultPanel.getFont().getName().empty() ? page->getFont().getName() : DefaultPlotConfiguration::getInstance()._defaultPanel.getFont().getName(), DefaultPlotConfiguration::getInstance()._defaultPanel.getFont().getSize() != 0 ? DefaultPlotConfiguration::getInstance()._defaultPanel.getFont().getSize() : page->getFont().getSize())), _title(_font) { } Panel::~Panel() { } Font Panel::getTitleFont() { Font titleFont(_title.getFont()); if (titleFont.getName() == "") titleFont.setName(_font.getName()); if (titleFont.getSize() == 0) titleFont.setSize(_font.getSize()); return titleFont; } void Panel::reserveSpaceForTitle(double& topSpace, double& bottomSpace, double& titleHeight) { LabelRowInfo titleRows(Label::getRowNumber(_title)); if (titleRows.empty()) return; CharSize lCharSizeTitle; Font titleFont(getTitleFont()); PlPlotUtil::setPlFont(titleFont); lCharSizeTitle = PlPlotUtil::getCharacterSizeInPlPage(_page); titleHeight = (titleRows.size() + PlPlotUtil::LINE_SPACE_TITLE * (titleRows.size() + 1)) * lCharSizeTitle.second; switch (_titlePosition) { case PlotCommon::Position::POS_TOP : topSpace += titleHeight; break; case PlotCommon::Position::POS_BOTTOM : bottomSpace += titleHeight; break; default : //Not possible - Nothing to do ; } } void Panel::drawTitle(std::shared_ptr& pls) { LabelRowInfo titleRows(Label::getRowNumber(_title)); if (titleRows.empty()) return; if ((_titlePosition != PlotCommon::Position::POS_TOP) && (_titlePosition != PlotCommon::Position::POS_BOTTOM)) return; // Compute panel coordinate in the page Bounds lBounds = getBoundsInPlPage(); Color lInitialColor = changeColor(pls, _title._color, _page->_mode); Font titleFont(getTitleFont()); PlPlotUtil::setPlFont(titleFont); // Specify viewport for the panel pls->vpor(lBounds._x, lBounds._x + lBounds._width, lBounds._y, lBounds._y + lBounds._height); float lRowDisp = -0.5 - PlPlotUtil::LINE_SPACE_TITLE; // Draw each line of title for (auto row : titleRows) { pls->mtex( getPlSide(_titlePosition).c_str(), lRowDisp, getPlPos(_titleAlign), getPlJust(_titleAlign), row.c_str() ); // 1 is for full character and then let space between two line. lRowDisp -= (1 + PlPlotUtil::LINE_SPACE_TITLE); } // Restore initial color. restoreColor(pls, lInitialColor, _page->_mode); } void Panel::draw(std::shared_ptr& pls) { if (_drawn) //panel is already drawn => no draw background and title return; // Draw background fillBackground(pls); // write title with dedicated position and align drawTitle(pls); _drawn = true; } /** * @brief Write panel context */ void Panel::writeContext(std::shared_ptr& /*pls*/, ContextFileWriter& writer) { Bounds lBounds = getBoundsInPlPage(); writer.addAttribute("id", std::to_string(_id).c_str()); if (_page->_orientation == PlotCommon::Orientation::PORTRAIT) { writer.addAttribute("x", std::to_string(lBounds._y*std::get<0>(_page->getSize())).c_str()); writer.addAttribute("y", std::to_string(lBounds._x*std::get<1>(_page->getSize())).c_str()); writer.addAttribute("width", std::to_string(lBounds._height*std::get<0>(_page->getSize())).c_str()); writer.addAttribute("height", std::to_string(lBounds._width*std::get<1>(_page->getSize())).c_str()); } else { writer.addAttribute("x", std::to_string(lBounds._x*std::get<0>(_page->getSize())).c_str()); writer.addAttribute("y", std::to_string(lBounds._y*std::get<1>(_page->getSize())).c_str()); writer.addAttribute("width", std::to_string(lBounds._width*std::get<0>(_page->getSize())).c_str()); writer.addAttribute("height", std::to_string(lBounds._height*std::get<1>(_page->getSize())).c_str()); } } void Panel::fillBackground(std::shared_ptr& pls) { // If color map index is not equal to 0, need to change cmap0. if (_backgroundColor._colorMapIndex != -1) { std::string lFilePath = ColormapManager::getInstance().get(_page->_mode, _backgroundColor._colorMapIndex); pls->spal0(lFilePath.c_str()); } PLINT lInitialRed = -1, lInitialGreen = -1, lInitialBlue = -1; // if color index is equal to 0 choose the first color in cmap 0 if (_backgroundColor._colorIndex != -1) { pls->col0(_backgroundColor._colorIndex); } else if (_backgroundColor._red != -1 && _backgroundColor._green != -1 && _backgroundColor._blue != -1) { // Store initial color in first index. pls->gcol0(0, lInitialRed, lInitialGreen, lInitialBlue); pls->scol0(0, _backgroundColor._red, _backgroundColor._green, _backgroundColor._blue); pls->col0(0); } else { // chose first color in cmap0. pls->col0(0); } // Compute panel coordinate in the page Bounds lBounds = getBoundsInPlPage(); // Specify viewport for the panel pls->vpor(lBounds._x, lBounds._x + lBounds._width, lBounds._y, lBounds._y + lBounds._height); // Set window size. pls->wind(0, 1, 0, 1); // Fill background. PLFLT px[] = { 0, 0, 1, 1 }; PLFLT py[] = { 0, 1, 1, 0 }; pls->fill(4, px, py); // Restore initial color in first index. if (lInitialRed != -1 && lInitialGreen != -1 && lInitialBlue != -1) { pls->scol0(0, lInitialRed, lInitialGreen, lInitialBlue); } else if (_backgroundColor._colorMapIndex != -1) { // Restore default cmap0 (default colormap for cmap0 is the first index). std::string lFilePath = ColormapManager::getInstance().get(_page->_mode, 0); pls->spal0(lFilePath.c_str()); } pls->col0(0); } void Panel::drawMessage(std::shared_ptr& pls, std::string& message) { Bounds lBounds = getBoundsInPlPage(); // Specify viewport for the panel pls->vpor(lBounds._x, lBounds._x + lBounds._width, lBounds._y, lBounds._y + lBounds._height); // Set window size. pls->wind(0, 1, 0, 1); pls->col0(0); PlPlotUtil::setPlFont(_font); pls->ptex (0.5, 0.5, 0.5, 0, 0.5, message.c_str()); // Set window size. pls->wind(lBounds._x, lBounds._x + lBounds._width, lBounds._y, lBounds._y + lBounds._height); } void Panel::drawEmptyPanel(std::shared_ptr& pls) { Bounds lBounds = getBoundsInPlPage(); // Specify viewport for the panel pls->vpor(lBounds._x, lBounds._x + lBounds._width, lBounds._y, lBounds._y + lBounds._height); // Set window size. pls->wind(0, 1, 0, 1); pls->col0(0); //Draw panel border PLFLT xBorder[5] = {0,0,1,1,0}; PLFLT yBorder[5] = {0,1,1,0,0}; pls->lsty(static_cast(getPlLineStyle(LineStyle::LONG_SPACED_DOT))); pls->width(1); pls->line(5,xBorder,yBorder); // Set window size. pls->wind(lBounds._x, lBounds._x + lBounds._width, lBounds._y, lBounds._y + lBounds._height); //Draw text PlPlotUtil::setPlFont(_font); std::string emptyText = "Empty panel "; if (_index > -1) { emptyText += "#"; emptyText += std::to_string(_index); } else { emptyText += "(Id : "; emptyText += std::to_string(_id); emptyText += ")"; } drawMessage(pls, emptyText); } void Panel::drawNoData(std::shared_ptr& pls) { std::string noDataText = "NO DATA"; drawMessage(pls, noDataText); } Bounds Panel::getBoundsInPlPage() { Bounds drawableBounds; //Drawable bounds in PlPlot page _page->getDrawableBoundsInPlPage(drawableBounds); //Panel bounds is relative to the drawable bounds => rewrite it relative to the PlPlot page Bounds panelBounds; panelBounds._x = drawableBounds._x + drawableBounds._width * _bounds._x; panelBounds._y = drawableBounds._y + drawableBounds._height * _bounds._y; panelBounds._width = drawableBounds._width * _bounds._width; panelBounds._height = drawableBounds._height * _bounds._height; return panelBounds; } std::ostream& operator <<(std::ostream& out, Bounds& bounds) { out << "[BOUNDS]" << std::endl; out << "bounds.x=" << bounds._x << std::endl; out << "bounds.y=" << bounds._y << std::endl; out << "bounds.width=" << bounds._width << std::endl; out << "bounds.height=" << bounds._height << std::endl; return out; } std::ostream& operator <<(std::ostream& out, Panel& panel) { out << "[PANEL]" << std::endl; out << "panel.resolution=" << panel._resolution << std::endl; out << "panel.title=" << panel.getTitle()->_text << std::endl; out << "panel.title.align=" << panel._titleAlign << std::endl; out << "panel.title.position=" << panel._titlePosition << std::endl; out << panel._bounds << panel._backgroundColor << panel.getFont(); for (auto axe : panel._axes) { if (axe.second != nullptr) axe.second.get()->dump(out); } return out; } } /* namespace plot */