/* BasicWriter Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "GridTree.hpp" #include namespace uigrid { Splitter getSplitter(Orientation orientation, const Rect &r) { switch (orientation) { case Orientation::vert: return Splitter(this, Rect(r.x1, r.y2 - ss, r.x2, r.y2), orientation); case Orientation::horz: return Splitter(this, Rect(r.x1, r.y1, r.x2 - ss, r.y2 - ss), orientation); default: return Rect(0, 0, 0, 0); } } void GridTreeNode::gatherBoundingBoxes(std::vector *areas, std::vector *splitters, const Rect &r, int splitterSize) { const int ss = splitterSize; const int h = r.h(); const int w = r.w(); // If this node is a leaf, store the area of the frame and the splitter // positions in the given lists and abort. if (isLeaf()) { if (areas) { areas->push_back(FrameArea(this, r)); } if (splitters) { splitters->push_back(getSplitter(Orientation::vert, r)); splitters->push_back(getSplitter(Orientation::horz, r)); } return; } // Recursively descend into the child nodes. Calculate the area the // child nodes occupy. The last child should always occupy all remaining // space in order to avoid gaps caused by rounding errors. unsigned int i = 0; switch (orientation) { case Orientation::vert: { int offsY = r.y1; for (auto it = children.begin(); it != children.end(); it++, i++) { const int ch = (i == children.size() - 1) ? r.y2 - offsY : h * (*it)->relativeSize; (*it)->gatherBoundingBoxes(areas, splitters, Rect::bounds(r.x1, offsY, w, ch), splitterSize); offsY += ch; } } break; case Orientation::horz: { int offsX = r.x1; for (auto it = children.begin(); it != children.end(); it++, i++) { const int cw = (i == children.size() - 1) ? r.x2 - offsX : w * (*it)->relativeSize; (*it)->gatherBoundingBoxes(areas, splitters, Rect::bounds(offsX, r.y1, cw, h), splitterSize); offsX += cw; } } break; case Orientation::none: break; } } }