//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rendering::renderOverlayItems(OpenGLContext* oglContext, bool useSoftwareRendering) { OverlayItemRectMap itemRectMap; calculateOverlayItemLayout(&itemRectMap); // Must setup a scissor to limit the overlay items to the current viewport, as they might setup a local viewport (e.g. navigation cube) GLboolean scissorWasOn = glIsEnabled(GL_SCISSOR_TEST); int scissorBox[4] = {0, 0, -1, -1}; glGetIntegerv(GL_SCISSOR_BOX, scissorBox); glScissor(static_cast<GLsizei>(m_camera->viewport()->x()), static_cast<GLsizei>(m_camera->viewport()->y()), static_cast<GLsizei>(m_camera->viewport()->width()), static_cast<GLsizei>(m_camera->viewport()->height())); glEnable(GL_SCISSOR_TEST); OverlayItemRectMap::iterator it; for (it = itemRectMap.begin(); it != itemRectMap.end(); ++it) { OverlayItem* item = it->first; Recti rect = it->second; if (useSoftwareRendering) { item->renderSoftware(oglContext, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height()))); } else { item->render(oglContext, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height()))); } } // Restore scissor settings if (!scissorWasOn) glDisable(GL_SCISSOR_TEST); glScissor(scissorBox[0], scissorBox[1], scissorBox[2], scissorBox[3]); }
void Moveable::mousePressEvent( MousePressEvent& event ) { int gx, gy; Recti rcorner; raise(); event.position( _lx, _ly ); size( rcorner.x, rcorner.y ); rcorner.x -= 18; rcorner.y -= 18; rcorner.setSize( 18, 18 ); if( rcorner.contains( _lx, _ly ) && !_togglebutton.state() ) { _activeMode = 2; } else { event.position( gx, gy ); mapGlobal( gx, gy ); _activeWidget = childAt( gx, gy ); if( _activeWidget ) { mapGlobal( event.x, event.y ); _activeWidget->mapLocal( event.x, event.y ); _activeWidget->mousePressEvent( event ); } else { _activeMode = 1; } } }
void Widget::paintChild( Widget* w, GFX& gfx, const Recti& rect ) const { if( w->parent() != this ) return; /* get current cliprect and translation */ Recti cliprect = gfx.clipRect(); Vector2i gtransold; gfx.getTranslationGlobal( gtransold ); /* get child rectangle in global coords */ Recti newcliprect = w->rect(); Recti childrect = newcliprect; newcliprect.intersect( cliprect ); /* set new clipping */ gfx.setClipRect( newcliprect ); /* do painting with default GFX, only paint currently visible part */ newcliprect.intersect( rect ); PaintEvent pe( newcliprect ); gfx.setTranslationGlobal( Vector2i( childrect.x, childrect.y ) ); gfx.setDefault(); w->paintEvent( pe, gfx ); /* restore old viewport */ gfx.setTranslationGlobal( gtransold ); gfx.setDefault(); gfx.setClipRect( cliprect ); }
bool Recti::contains(const Recti &rect) const { return getLeft() < rect.getRight() && getRight() > rect.getLeft() && getTop() < rect.getTop() && getBottom() > rect.getBottom(); }
TYPED_TEST(BufferTest, ShouldReturnRect) { Buffer<TypeParam> buffer(50, 50); Recti rect = buffer.rect(); ASSERT_EQ(0, rect.x()); ASSERT_EQ(0, rect.y()); ASSERT_EQ(50, rect.width()); ASSERT_EQ(50, rect.height()); }
void RangeTest::subclassTypes() { const Vector2i a; CORRADE_VERIFY((std::is_same<decltype(Recti::fromSize(a, a)), Recti>::value)); const Recti r; CORRADE_VERIFY((std::is_same<decltype(r.translated(a)), Recti>::value)); CORRADE_VERIFY((std::is_same<decltype(r.padded(a)), Recti>::value)); CORRADE_VERIFY((std::is_same<decltype(r.scaled(a)), Recti>::value)); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rendering::renderOverlayItems(OpenGLContext* oglContext, bool useSoftwareRendering) { OverlayItemRectMap itemRectMap; calculateOverlayItemLayout(&itemRectMap); // Must setup a scissor to limit the overlay items to the current viewport, as they might setup a local viewport (e.g. navigation cube) GLboolean scissorWasOn = glIsEnabled(GL_SCISSOR_TEST); int scissorBox[4] = {0, 0, -1, -1}; glGetIntegerv(GL_SCISSOR_BOX, scissorBox); glScissor(static_cast<GLsizei>(m_camera->viewport()->x()), static_cast<GLsizei>(m_camera->viewport()->y()), static_cast<GLsizei>(m_camera->viewport()->width()), static_cast<GLsizei>(m_camera->viewport()->height())); glEnable(GL_SCISSOR_TEST); const size_t numOverlayItems = m_overlayItems.size(); for (size_t i = 0; i < numOverlayItems; i++) { OverlayItem* item = m_overlayItems.at(i); Vec2i pos(0, 0); Vec2ui size(0, 0); if (item->layoutScheme() == OverlayItem::FIXED_POSITION) { pos = item->fixedPosition(); size = item->sizeHint(); } else { // Item should be laid out already - grab its pos/size from the layout map OverlayItemRectMap::iterator it = itemRectMap.find(item); if (it != itemRectMap.end()) { Recti rect = it->second; pos = rect.min(); size.set(static_cast<uint>(rect.width()), static_cast<uint>(rect.height())); } } if (!size.isZero()) { if (useSoftwareRendering) { item->renderSoftware(oglContext, pos, size); } else { item->render(oglContext, pos, size); } } } // Restore scissor settings if (!scissorWasOn) glDisable(GL_SCISSOR_TEST); glScissor(scissorBox[0], scissorBox[1], scissorBox[2], scissorBox[3]); }
void Camera::plot(Buffer<unsigned int>& buffer, const Recti& rect, const ViewPlane::Iterator& pixel, const Colord& color) const { auto avergageColor = color / viewPlane()->sampler()->numSamples(); unsigned int rgb = avergageColor.rgb(); int size = pixel.pixelSize(); if (size == 1) { buffer[pixel.row()][pixel.column()] = rgb; } else { for (int x = pixel.column(); x != pixel.column() + size && x < rect.right(); ++x) for (int y = pixel.row(); y != pixel.row() + size && y < rect.bottom(); ++y) buffer[y][x] = rgb; } }
bool Recti::clipBy(const Recti& other) { int minX, minY, maxX, maxY; getBounds(minX, minY, maxX, maxY); int otherMinX, otherMinY, otherMaxX, otherMaxY; other.getBounds(otherMinX, otherMinY, otherMaxX, otherMaxY); if (minX > otherMaxX || maxX < otherMinX) return false; if (minY > otherMaxY || maxY < otherMinY) return false; if (minX < otherMinX) minX = otherMinX; if (minY < otherMinY) minY = otherMinY; if (maxX > otherMaxX) maxX = otherMaxX; if (maxY > otherMaxY) maxY = otherMaxY; setBounds(minX, minY, maxX, maxY); return true; }
void Viewport::setBounds(Recti bounds) { sprite->setBounds(bounds); if (target.isValid()) { target->setSize(bounds.getSize()); } }
//-------------------------------------------------------------------------------------------------- /// Get the the overlay item (if any) at the given cursor position //-------------------------------------------------------------------------------------------------- OverlayItem* Rendering::overlayItemFromWindowCoordinates(int x, int y) { OverlayItemRectMap itemRectMap; calculateOverlayItemLayout(&itemRectMap); OverlayItemRectMap::iterator it; for (it = itemRectMap.begin(); it != itemRectMap.end(); ++it) { OverlayItem* item = it->first; Recti rect = it->second; if (item->pick(x, y, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height())))) { return item; } } return NULL; }
void ContainerClip::Draw(Graphics &g) const { const Transform2d& tr = g.GetTransform(); Recti clip = g.GetClipRect(); Recti nclip = m_rect; Vector2f lt = tr.transform(nclip.GetTopLeft()); Vector2f rb = tr.transform(nclip.GetBottomRight()); nclip.x = std::max(0.0f,std::min(lt.x, rb.x)); nclip.y = std::max(0.0f,std::min(lt.y, rb.y)); nclip.w = std::max(lt.x, rb.x) - nclip.x; nclip.h = std::max(lt.y, rb.y) - nclip.y; if (nclip.w > 0 && nclip.h > 0) { nclip = nclip.GetIntersect(clip); if (nclip.w > 0 && nclip.h > 0) { g.SetClipRect(nclip); Container::Draw(g); g.SetClipRect(clip); } } }
void generate_cave(Location origin, const Recti& area) { set<Vec2i> dug; set<Vec2i> edge; Vec2i pos = area.min() + area.dim() / 2; const float floor_fraction = 0.5; size_t n = area.volume() * floor_fraction; dig(origin + pos); dug.insert(pos); for (auto a : hex_dirs) { if (dug.find(pos + a) == dug.end()) { edge.insert(pos + a); } } while (dug.size() < n && edge.size() > 0) { auto pick = rand_choice(edge); pos = *pick; int n_floor = 0; for (auto a : hex_dirs) if (dug.find(pos + a) != dug.end()) n_floor++; // Decide whether to dig here. Prefer to dig in closed quarters and // destroy singleton pillars. if (n_floor < 6 && rand_int(n_floor * n_floor) > 1) continue; edge.erase(pick); dig(origin + pos); dug.insert(pos); for (auto a : hex_dirs) { if (dug.find(pos + a) == dug.end() && area.contains(pos + a)) { edge.insert(pos + a); } } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool OverlayScalarMapperLegend::pick(int oglXCoord, int oglYCoord, const Vec2i& position, const Vec2ui& size) { Recti oglRect(position, size.x(), size.y()); OverlayColorLegendLayoutInfo layoutInViewPortCoords(oglRect.min(), Vec2ui(oglRect.width(), oglRect.height())); layoutInfo(&layoutInViewPortCoords); Vec2i legendBarOrigin = oglRect.min(); legendBarOrigin.x() += static_cast<uint>(layoutInViewPortCoords.legendRect.min().x()); legendBarOrigin.y() += static_cast<uint>(layoutInViewPortCoords.legendRect.min().y()); Recti legendBarRect = Recti(legendBarOrigin, static_cast<uint>(layoutInViewPortCoords.legendRect.width()), static_cast<uint>(layoutInViewPortCoords.legendRect.height())); if ((oglXCoord > legendBarRect.min().x()) && (oglXCoord < legendBarRect.max().x()) && (oglYCoord > legendBarRect.min().y()) && (oglYCoord < legendBarRect.max().y())) { return true; } return false; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rendering::renderOverlayItems(OpenGLContext* oglContext, bool useSoftwareRendering) { OverlayItemRectMap itemRectMap; calculateOverlayItemLayout(&itemRectMap); OverlayItemRectMap::iterator it; for (it = itemRectMap.begin(); it != itemRectMap.end(); ++it) { OverlayItem* item = it->first; Recti rect = it->second; if (useSoftwareRendering) { item->renderSoftware(oglContext, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height()))); } else { item->render(oglContext, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height()))); } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rendering::renderOverlayItems(OpenGLContext* oglContext, bool useSoftwareRendering) { OverlayItemRectMap itemRectMap; calculateOverlayItemLayout(&itemRectMap); OverlayItemRectMap::iterator it; for (it = itemRectMap.begin(); it != itemRectMap.end(); ++it) { OverlayItem* item = it->first; Recti rect = it->second; if (useSoftwareRendering) { item->renderSoftware(oglContext, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height()))); } else { item->render(oglContext, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height()))); } } for (size_t i = 0; i < m_overlayItems.size(); i++) { OverlayItemLayout item = m_overlayItems.at(i); if ((item.corner == OverlayItem::UNMANAGED) ) { Vec2ui size = item.overlayItem->sizeHint(); Vec2i pos = item.overlayItem->unmanagedPosition(); if (useSoftwareRendering) { item.overlayItem->renderSoftware(oglContext, pos, size); } else { item.overlayItem->render(oglContext, pos, size); } } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(RectTest, FromMinMax) { { Rectd rect = Rectd::fromMinMax(Vec2d(-1, 2), Vec2d(10, 12)); EXPECT_TRUE(rect.isValid()); EXPECT_DOUBLE_EQ(-1, rect.min().x()); EXPECT_DOUBLE_EQ(2, rect.min().y()); EXPECT_DOUBLE_EQ(10, rect.max().x()); EXPECT_DOUBLE_EQ(12, rect.max().y()); EXPECT_DOUBLE_EQ(11, rect.width()); EXPECT_DOUBLE_EQ(10, rect.height()); } { Recti rect = Recti::fromMinMax(Vec2i(-1, 2), Vec2i(10, 12)); EXPECT_TRUE(rect.isValid()); EXPECT_EQ(-1, rect.min().x()); EXPECT_EQ( 2, rect.min().y()); EXPECT_EQ(10, rect.max().x()); EXPECT_EQ(12, rect.max().y()); EXPECT_EQ(11, rect.width()); EXPECT_EQ(10, rect.height()); } { Rectui rect = Rectui::fromMinMax(Vec2ui(1, 2), Vec2ui(11, 22)); EXPECT_TRUE(rect.isValid()); EXPECT_EQ( 1, rect.min().x()); EXPECT_EQ( 2, rect.min().y()); EXPECT_EQ(11, rect.max().x()); EXPECT_EQ(22, rect.max().y()); EXPECT_EQ(10, rect.width()); EXPECT_EQ(20, rect.height()); } }
//-------------------------------------------------------------------------------------------------- /// Get the the overlay item (if any) at the given cursor position //-------------------------------------------------------------------------------------------------- OverlayItem* Rendering::overlayItemFromWindowCoordinates(int x, int y) { OverlayItemRectMap itemRectMap; calculateOverlayItemLayout(&itemRectMap); const size_t numOverlayItems = m_overlayItems.size(); for (size_t i = 0; i < numOverlayItems; i++) { OverlayItem* item = m_overlayItems.at(i); OverlayItemRectMap::iterator it = itemRectMap.find(item); if (it != itemRectMap.end()) { Recti rect = it->second; if (item->pick(x, y, rect.min(), Vec2ui(static_cast<cvf::uint>(rect.width()), static_cast<cvf::uint>(rect.height())))) { return item; } } } return NULL; }
bool Recti::intersects(const Recti& other) const { int minX, minY, maxX, maxY; getBounds(minX, minY, maxX, maxY); int otherMinX, otherMinY, otherMaxX, otherMaxY; other.getBounds(otherMinX, otherMinY, otherMaxX, otherMaxY); if (minX > otherMaxX || maxX < otherMinX) return false; if (minY > otherMaxY || maxY < otherMinY) return false; return true; }
void Recti::envelop(const Recti& other) { int minX, minY, maxX, maxY; getBounds(minX, minY, maxX, maxY); int otherMinX, otherMinY, otherMaxX, otherMaxY; other.getBounds(otherMinX, otherMinY, otherMaxX, otherMaxY); if (minX > otherMinX) minX = otherMinX; if (minY > otherMinY) minY = otherMinY; if (maxX < otherMaxX) maxX = otherMaxX; if (maxY < otherMaxY) maxY = otherMaxY; setBounds(minX, minY, maxX, maxY); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rendering::calculateOverlayItemLayout(OverlayItemRectMap* itemRectMap, OverlayItem::LayoutCorner corner, OverlayItem::LayoutDirection direction) { const int border = 3; const Vec2i vpSize = Vec2i(static_cast<int>(m_camera->viewport()->width()), static_cast<int>(m_camera->viewport()->height())); const Vec2i vpPos = Vec2i(m_camera->viewport()->x(), m_camera->viewport()->y()); Vec2i cursor(0,0); switch (corner) { case OverlayItem::TOP_LEFT: cursor.set(border, vpSize.y() - border); break; case OverlayItem::TOP_RIGHT: cursor.set(vpSize.x() - border, vpSize.y() - border); break; case OverlayItem::BOTTOM_LEFT: cursor.set(border, border); break; case OverlayItem::BOTTOM_RIGHT: cursor.set(vpSize.x() - border, border); break; default: cursor.set(border,border); } cursor += vpPos; // Adjust based on other already placed items OverlayItemRectMap::iterator it; for (it = itemRectMap->begin(); it != itemRectMap->end(); ++it) { Recti rect = it->second; if (rect.contains(cursor) && (direction == OverlayItem::VERTICAL)) { if (corner == OverlayItem::BOTTOM_LEFT || corner == OverlayItem::BOTTOM_RIGHT) { cursor.y() += rect.height() + border; } else { cursor.y() -= rect.height() + border; } } } size_t numOverlayItems = m_overlayItems.size(); size_t i; for (i = 0; i < numOverlayItems; i++) { OverlayItemLayout item = m_overlayItems.at(i); if ((item.corner == corner) && (item.direction == direction)) { CVF_ASSERT(item.overlayItem.notNull()); // Find this position and size Vec2i position = cursor; Vec2ui size = item.overlayItem->sizeHint(); if ((corner == OverlayItem::TOP_RIGHT) || (corner == OverlayItem::BOTTOM_RIGHT)) { position.x() -= size.x(); } if ((corner == OverlayItem::TOP_LEFT) || (corner == OverlayItem::TOP_RIGHT)) { position.y() -= size.y(); } // Store the position in the map Recti rect(position.x(), position.y(), static_cast<int>(size.x()), static_cast<int>(size.y())); (*itemRectMap)[item.overlayItem.p()] = rect; // Find next position, moving the cursor if (direction == OverlayItem::HORIZONTAL) { if ((corner == OverlayItem::TOP_LEFT) || (corner == OverlayItem::BOTTOM_LEFT)) { cursor.x() += (size.x() + border); } else { cursor.x() -= (size.x() + border); } } else if (direction == OverlayItem::VERTICAL) { if ((corner == OverlayItem::BOTTOM_LEFT) || (corner == OverlayItem::BOTTOM_RIGHT)) { cursor.y() += (size.y() + border); } else { cursor.y() -= (size.y() + border); } } else { CVF_FAIL_MSG("Unhandled OverlayItem::LayoutDirection"); } } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(RectTest, RectTypes) { // Rectf { Rectf rect; EXPECT_FLOAT_EQ(0.0f, rect.min().x()); EXPECT_FLOAT_EQ(0.0f, rect.min().y()); EXPECT_FLOAT_EQ(0.0f, rect.width()); EXPECT_FLOAT_EQ(0.0f, rect.height()); EXPECT_FALSE(rect.isValid()); } { Rectf rect(-1.0f, -2.0f, 5.0f, 10.0f); EXPECT_FLOAT_EQ(-1.0f, rect.min().x()); EXPECT_FLOAT_EQ(-2.0f, rect.min().y()); EXPECT_FLOAT_EQ(5.0f, rect.width()); EXPECT_FLOAT_EQ(10.0f, rect.height()); EXPECT_TRUE(rect.isValid()); } // Recti { Recti rect; EXPECT_EQ(0, rect.min().x()); EXPECT_EQ(0, rect.min().y()); EXPECT_EQ(0, rect.width()); EXPECT_EQ(0, rect.height()); EXPECT_FALSE(rect.isValid()); } { Recti rect(-1, -2, 5, 10); EXPECT_EQ(-1, rect.min().x()); EXPECT_EQ(-2, rect.min().y()); EXPECT_EQ(5, rect.width()); EXPECT_EQ(10, rect.height()); EXPECT_TRUE(rect.isValid()); } // Rectui { Rectui rect; EXPECT_EQ(0, rect.min().x()); EXPECT_EQ(0, rect.min().y()); EXPECT_EQ(0, rect.width()); EXPECT_EQ(0, rect.height()); EXPECT_FALSE(rect.isValid()); } { Rectui rect(1, 2, 5, 10); EXPECT_EQ(1, rect.min().x()); EXPECT_EQ(2, rect.min().y()); EXPECT_EQ(5, rect.width()); EXPECT_EQ(10, rect.height()); EXPECT_TRUE(rect.isValid()); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rendering::calculateOverlayItemLayoutForSchemeAndCorner(OverlayItemRectMap* itemRectMap, OverlayItem::LayoutScheme layoutScheme, OverlayItem::AnchorCorner anchorCorner) { CVF_ASSERT(layoutScheme == OverlayItem::HORIZONTAL || layoutScheme == OverlayItem::VERTICAL); const int border = 3; const Vec2i vpSize = Vec2i(static_cast<int>(m_camera->viewport()->width()), static_cast<int>(m_camera->viewport()->height())); const Vec2i vpPos = Vec2i(m_camera->viewport()->x(), m_camera->viewport()->y()); Vec2i cursor(0,0); switch (anchorCorner) { case OverlayItem::TOP_LEFT: cursor.set(border, vpSize.y() - border); break; case OverlayItem::TOP_RIGHT: cursor.set(vpSize.x() - border, vpSize.y() - border); break; case OverlayItem::BOTTOM_LEFT: cursor.set(border, border); break; case OverlayItem::BOTTOM_RIGHT: cursor.set(vpSize.x() - border, border); break; default: cursor.set(border,border); } cursor += vpPos; // Adjust starting cursor position based on other already placed items in this anchor corner // The assumption here is that for each corner, the horizontal layout has already been added to the map if (layoutScheme == OverlayItem::VERTICAL) { OverlayItemRectMap::iterator it; for (it = itemRectMap->begin(); it != itemRectMap->end(); ++it) { const OverlayItem* placedItem = it->first; const Recti placedItemRect = it->second; if (placedItem->anchorCorner() == anchorCorner && placedItemRect.contains(cursor)) { if (anchorCorner == OverlayItem::BOTTOM_LEFT || anchorCorner == OverlayItem::BOTTOM_RIGHT) { cursor.y() += placedItemRect.height() + border; } else { cursor.y() -= placedItemRect.height() + border; } } } } const size_t numOverlayItems = m_overlayItems.size(); for (size_t i = 0; i < numOverlayItems; i++) { OverlayItem* item = m_overlayItems.at(i); if ((item->anchorCorner() == anchorCorner) && (item->layoutScheme() == layoutScheme)) { // Find this position and size Vec2i position = cursor; Vec2ui size = item->sizeHint(); if ((anchorCorner == OverlayItem::TOP_RIGHT) || (anchorCorner == OverlayItem::BOTTOM_RIGHT)) { position.x() -= size.x(); } if ((anchorCorner == OverlayItem::TOP_LEFT) || (anchorCorner == OverlayItem::TOP_RIGHT)) { position.y() -= size.y(); } // Store the position in the map Recti rect(position.x(), position.y(), static_cast<int>(size.x()), static_cast<int>(size.y())); (*itemRectMap)[item] = rect; // Find next position, moving the cursor if (layoutScheme == OverlayItem::HORIZONTAL) { if ((anchorCorner == OverlayItem::TOP_LEFT) || (anchorCorner == OverlayItem::BOTTOM_LEFT)) { cursor.x() += (size.x() + border); } else { cursor.x() -= (size.x() + border); } } else if (layoutScheme == OverlayItem::VERTICAL) { if ((anchorCorner == OverlayItem::BOTTOM_LEFT) || (anchorCorner == OverlayItem::BOTTOM_RIGHT)) { cursor.y() += (size.y() + border); } else { cursor.y() -= (size.y() + border); } } else { CVF_FAIL_MSG("Unhandled OverlayItem::LayoutDirection"); } } } }
Rect::Rect(const Recti &r) : position(r.getPos()), size(r.getSize()) { }