//----------------------------------------------------------------------------// Rectf Element::getUnclippedOuterRect_impl(bool skipAllPixelAlignment) const { const Sizef pixel_size = skipAllPixelAlignment ? calculatePixelSize(true) : getPixelSize(); Rectf ret(Vector2f(0, 0), pixel_size); const Element* parent = getParentElement(); Rectf parent_rect; if (parent) { const CachedRectf& base = parent->getChildContentArea(isNonClient()); parent_rect = skipAllPixelAlignment ? base.getFresh(true) : base.get(); } else { parent_rect = Rectf(Vector2f(0, 0), getRootContainerSize()); } const Sizef parent_size = parent_rect.getSize(); Vector2f offset = parent_rect.d_min + CoordConverter::asAbsolute(getArea().d_min, parent_size, false); switch (getHorizontalAlignment()) { case HA_CENTRE: offset.d_x += (parent_size.d_width - pixel_size.d_width) * 0.5f; break; case HA_RIGHT: offset.d_x += parent_size.d_width - pixel_size.d_width; break; default: break; } switch (getVerticalAlignment()) { case VA_CENTRE: offset.d_y += (parent_size.d_height - pixel_size.d_height) * 0.5f; break; case VA_BOTTOM: offset.d_y += parent_size.d_height - pixel_size.d_height; break; default: break; } if (d_pixelAligned && !skipAllPixelAlignment) { offset = Vector2f(CoordConverter::alignToPixels(offset.d_x), CoordConverter::alignToPixels(offset.d_y)); } ret.offset(offset); return ret; }
//----------------------------------------------------------------------------// Sizef Element::getParentPixelSize(bool skipAllPixelAlignment) const { if (d_parent) { return skipAllPixelAlignment ? d_parent->calculatePixelSize(true) : d_parent->getPixelSize(); } else { return getRootContainerSize(); } }
/************************************************************************* move the window's bottom edge by 'delta'. The rest of the window does not move, thus this changes the size of the Window. *************************************************************************/ bool FrameWindow::moveBottomEdge(float delta, URect& out_area) { // store this so we can work out how much size actually changed float orgHeight = d_pixelSize.d_height; // ensure that we only size to the set constraints. // // NB: We are required to do this here due to our virtually unique sizing nature; the // normal system for limiting the window size is unable to supply the information we // require for updating our internal state used to manage the dragging, etc. float maxHeight(CoordConverter::asAbsolute(d_maxSize.d_height, getRootContainerSize().d_height)); float minHeight(CoordConverter::asAbsolute(d_minSize.d_height, getRootContainerSize().d_height)); float newHeight = orgHeight + delta; if (maxHeight != 0.0f && newHeight > maxHeight) delta = maxHeight - orgHeight; else if (newHeight < minHeight) delta = minHeight - orgHeight; // ensure adjustment will be whole pixel float adjustment = /*PixelAligned(*/delta/*)*/; out_area.d_max.d_y.d_offset += adjustment; if (d_verticalAlignment == VA_BOTTOM) { out_area.d_max.d_y.d_offset += adjustment; out_area.d_min.d_y.d_offset += adjustment; } else if (d_verticalAlignment == VA_CENTRE) { out_area.d_max.d_y.d_offset += adjustment * 0.5f; out_area.d_min.d_y.d_offset += adjustment * 0.5f; } // move the dragging point so mouse remains 'attached' to edge of window d_dragPoint.d_y += adjustment; return d_verticalAlignment == VA_BOTTOM; }
/************************************************************************* move the window's top edge by 'delta'. The rest of the window does not move, thus this changes the size of the Window. *************************************************************************/ bool FrameWindow::moveTopEdge(float delta, URect& out_area) { float orgHeight = d_pixelSize.d_height; // ensure that we only size to the set constraints. // // NB: We are required to do this here due to our virtually unique sizing nature; the // normal system for limiting the window size is unable to supply the information we // require for updating our internal state used to manage the dragging, etc. float maxHeight(CoordConverter::asAbsolute(d_maxSize.d_height, getRootContainerSize().d_height)); float minHeight(CoordConverter::asAbsolute(d_minSize.d_height, getRootContainerSize().d_height)); float newHeight = orgHeight - delta; if (maxHeight != 0.0f && newHeight > maxHeight) delta = orgHeight - maxHeight; else if (newHeight < minHeight) delta = orgHeight - minHeight; // ensure adjustment will be whole pixel float adjustment = /*PixelAligned(*/delta/*)*/; if (d_verticalAlignment == VA_BOTTOM) { out_area.d_max.d_y.d_offset -= adjustment; } else if (d_verticalAlignment == VA_CENTRE) { out_area.d_max.d_y.d_offset -= adjustment * 0.5f; out_area.d_min.d_y.d_offset += adjustment * 0.5f; } else { out_area.d_min.d_y.d_offset += adjustment; } return d_verticalAlignment == VA_TOP; }
/************************************************************************* move the window's left edge by 'delta'. The rest of the window does not move, thus this changes the size of the Window. *************************************************************************/ bool FrameWindow::moveLeftEdge(float delta, URect& out_area) { float orgWidth = d_pixelSize.d_width; // ensure that we only size to the set constraints. // // NB: We are required to do this here due to our virtually unique sizing nature; the // normal system for limiting the window size is unable to supply the information we // require for updating our internal state used to manage the dragging, etc. float maxWidth(CoordConverter::asAbsolute(d_maxSize.d_width, getRootContainerSize().d_width)); float minWidth(CoordConverter::asAbsolute(d_minSize.d_width, getRootContainerSize().d_width)); float newWidth = orgWidth - delta; if (maxWidth != 0.0f && newWidth > maxWidth) delta = orgWidth - maxWidth; else if (newWidth < minWidth) delta = orgWidth - minWidth; // ensure adjustment will be whole pixel float adjustment = /*PixelAligned(*/delta/*)*/; if (d_horizontalAlignment == HA_RIGHT) { out_area.d_max.d_x.d_offset -= adjustment; } else if (d_horizontalAlignment == HA_CENTRE) { out_area.d_max.d_x.d_offset -= adjustment * 0.5f; out_area.d_min.d_x.d_offset += adjustment * 0.5f; } else { out_area.d_min.d_x.d_offset += adjustment; } return d_horizontalAlignment == HA_LEFT; }
/************************************************************************* Handler for mouse button press events *************************************************************************/ void Titlebar::onMouseButtonDown(MouseEventArgs& e) { // Base class processing Window::onMouseButtonDown(e); if (e.button == LeftButton) { if ((d_parent != 0) && d_dragEnabled) { // we want all mouse inputs from now on if (captureInput()) { // initialise the dragging state d_dragging = true; d_dragPoint = CoordConverter::screenToWindow(*this, e.position); // store old constraint area d_oldCursorArea = getGUIContext(). getMouseCursor().getConstraintArea(); // setup new constraint area to be the intersection of the old area and our grand-parent's clipped inner-area Rectf constrainArea; if ((d_parent == 0) || (getParent()->getParent() == 0)) { Rectf screen(Vector2f(0, 0), getRootContainerSize()); constrainArea = screen.getIntersection(d_oldCursorArea); } else { constrainArea = getParent()->getParent()->getInnerRectClipper().getIntersection(d_oldCursorArea); } getGUIContext().getMouseCursor(). setConstraintArea(&constrainArea); } } ++e.handled; } }
//----------------------------------------------------------------------------// Sizef Element::calculatePixelSize(bool skipAllPixelAlignment) const { // calculate pixel sizes for everything, so we have a common format for // comparisons. Sizef absMin(CoordConverter::asAbsolute(d_minSize, getRootContainerSize(), false)); Sizef absMax(CoordConverter::asAbsolute(d_maxSize, getRootContainerSize(), false)); Sizef base_size; if (skipAllPixelAlignment) { base_size = Sizef((d_parent && !d_nonClient) ? d_parent->getUnclippedInnerRect().getFresh(true).getSize() : getParentPixelSize(true)); } else { base_size = Sizef((d_parent && !d_nonClient) ? d_parent->getUnclippedInnerRect().get().getSize() : getParentPixelSize()); } Sizef ret = CoordConverter::asAbsolute(d_area.getSize(), base_size, false); // in case absMin components are larger than absMax ones, // max size takes precedence if (absMax.d_width != 0.0f && absMin.d_width > absMax.d_width) { absMin.d_width = absMax.d_width; CEGUI_LOGINSANE("MinSize resulted in an absolute pixel size with " "width larger than what MaxSize resulted in"); } if (absMax.d_height != 0.0f && absMin.d_height > absMax.d_height) { absMin.d_height = absMax.d_height; CEGUI_LOGINSANE("MinSize resulted in an absolute pixel size with " "height larger than what MaxSize resulted in"); } // limit new pixel size to: minSize <= newSize <= maxSize if (ret.d_width < absMin.d_width) ret.d_width = absMin.d_width; else if (absMax.d_width != 0.0f && ret.d_width > absMax.d_width) ret.d_width = absMax.d_width; if (ret.d_height < absMin.d_height) ret.d_height = absMin.d_height; else if (absMax.d_height != 0.0f && ret.d_height > absMax.d_height) ret.d_height = absMax.d_height; if (d_aspectMode != AM_IGNORE) { // make sure we respect current aspect mode and ratio ret.scaleToAspect(d_aspectMode, d_aspectRatio); // make sure we haven't blown any of the hard limits // still maintain the aspect when we do this if (d_aspectMode == AM_SHRINK) { float ratio = 1.0f; // check that we haven't blown the min size if (ret.d_width < absMin.d_width) { ratio = absMin.d_width / ret.d_width; } if (ret.d_height < absMin.d_height) { const float newRatio = absMin.d_height / ret.d_height; if (newRatio > ratio) ratio = newRatio; } ret.d_width *= ratio; ret.d_height *= ratio; } else if (d_aspectMode == AM_EXPAND) { float ratio = 1.0f; // check that we haven't blown the min size if (absMax.d_width != 0.0f && ret.d_width > absMax.d_width) { ratio = absMax.d_width / ret.d_width; } if (absMax.d_height != 0.0f && ret.d_height > absMax.d_height) { const float newRatio = absMax.d_height / ret.d_height; if (newRatio > ratio) ratio = newRatio; } ret.d_width *= ratio; ret.d_height *= ratio; } // NOTE: When the hard min max limits are unsatisfiable with the aspect lock mode, // the result won't be limited by both limits! } if (d_pixelAligned) { ret.d_width = CoordConverter::alignToPixels(ret.d_width); ret.d_height = CoordConverter::alignToPixels(ret.d_height); } return ret; }