void SetContainerPosition(float x, float y) { var stage = _targetElement.GetStage(); if (stage == null) { return; } _container.Pack(); float offsetX = _manager.OffsetX, offsetY = _manager.OffsetY, dist = _manager.EdgeDistance; var point = _targetElement.LocalToStageCoordinates(new Vector2(x + offsetX - _container.GetWidth() / 2, y - offsetY - _container.GetHeight())); if (point.Y < dist) { point = _targetElement.LocalToStageCoordinates(new Vector2(x + offsetX, y + offsetY)); } if (point.X < dist) { point.X = dist; } if (point.X + _container.GetWidth() > stage.GetWidth() - dist) { point.X = stage.GetWidth() - dist - _container.GetWidth(); } if (point.Y + _container.GetHeight() > stage.GetHeight() - dist) { point.Y = stage.GetHeight() - dist - _container.GetHeight(); } _container.SetPosition(point.X, point.Y); point = _targetElement.LocalToStageCoordinates(new Vector2(_targetElement.GetWidth() / 2, _targetElement.GetHeight() / 2)); point -= new Vector2(_container.GetX(), _container.GetY()); _container.SetOrigin(point.X, point.Y); }
public override void Layout() { var bg = _style.Background; var hScrollKnob = _style.HScrollKnob; var vScrollKnob = _style.VScrollKnob; float bgLeftWidth = 0, bgRightWidth = 0, bgTopHeight = 0, bgBottomHeight = 0; if (bg != null) { bgLeftWidth = bg.LeftWidth; bgRightWidth = bg.RightWidth; bgTopHeight = bg.TopHeight; bgBottomHeight = bg.BottomHeight; } var width = GetWidth(); var height = GetHeight(); var scrollbarHeight = 0f; if (hScrollKnob != null) { scrollbarHeight = hScrollKnob.MinHeight; } if (_style.HScroll != null) { scrollbarHeight = Math.Max(scrollbarHeight, _style.HScroll.MinHeight); } var scrollbarWidth = 0f; if (vScrollKnob != null) { scrollbarWidth = vScrollKnob.MinWidth; } if (_style.VScroll != null) { scrollbarWidth = Math.Max(scrollbarWidth, _style.VScroll.MinWidth); } // Get available space size by subtracting background's padded area. _areaWidth = width - bgLeftWidth - bgRightWidth; _areaHeight = height - bgTopHeight - bgBottomHeight; if (_widget == null) { return; } // Get widget's desired width. float widgetWidth, widgetHeight; if (_widget is ILayout) { var layout = _widget as ILayout; widgetWidth = layout.PreferredWidth; widgetHeight = layout.PreferredHeight; } else { widgetWidth = _widget.GetWidth(); widgetHeight = _widget.GetHeight(); } // Determine if horizontal/vertical scrollbars are needed. _scrollX = _forceScrollX || (widgetWidth > _areaWidth && !_disableX); _scrollY = _forceScrollY || (widgetHeight > _areaHeight && !_disableY); var fade = _fadeScrollBars; if (!fade) { // Check again, now taking into account the area that's taken up by any enabled scrollbars. if (_scrollY) { _areaWidth -= scrollbarWidth; if (!_scrollX && widgetWidth > _areaWidth && !_disableX) { _scrollX = true; } } if (_scrollX) { _areaHeight -= scrollbarHeight; if (!_scrollY && widgetHeight > _areaHeight && !_disableY) { _scrollY = true; _areaWidth -= scrollbarWidth; } } } // the bounds of the scrollable area for the widget. _widgetAreaBounds = RectangleExt.FromFloats(bgLeftWidth, bgBottomHeight, _areaWidth, _areaHeight); if (fade) { // Make sure widget is drawn under fading scrollbars. if (_scrollX && _scrollY) { _areaHeight -= scrollbarHeight; _areaWidth -= scrollbarWidth; } } else { if (_scrollbarsOnTop) { // Make sure widget is drawn under non-fading scrollbars. if (_scrollX) { _widgetAreaBounds.Height += (int)scrollbarHeight; } if (_scrollY) { _widgetAreaBounds.Width += (int)scrollbarWidth; } } else { // Offset widget area y for horizontal scrollbar at bottom. if (_scrollX && _hScrollOnBottom) { _widgetAreaBounds.Y += (int)scrollbarHeight; } // Offset widget area x for vertical scrollbar at left. if (_scrollY && !_vScrollOnRight) { _widgetAreaBounds.X += (int)scrollbarWidth; } } } // If the widget is smaller than the available space, make it take up the available space. widgetWidth = _disableX ? _areaWidth : Math.Max(_areaWidth, widgetWidth); widgetHeight = _disableY ? _areaHeight : Math.Max(_areaHeight, widgetHeight); _maxX = widgetWidth - _areaWidth; _maxY = widgetHeight - _areaHeight; if (fade) { // Make sure widget is drawn under fading scrollbars. if (_scrollX && _scrollY) { _maxY -= scrollbarHeight; _maxX -= scrollbarWidth; } } SetScrollX(Mathf.Clamp(_amountX, 0, _maxX)); SetScrollY(Mathf.Clamp(_amountY, 0, _maxY)); // Set the bounds and scroll knob sizes if scrollbars are needed. if (_scrollX) { if (hScrollKnob != null) { var hScrollHeight = _style.HScroll != null ? _style.HScroll.MinHeight : hScrollKnob.MinHeight; // The corner gap where the two scroll bars intersect might have to flip from right to left. var boundsX = _vScrollOnRight ? bgLeftWidth : bgLeftWidth + scrollbarWidth; // Scrollbar on the top or bottom. var boundsY = _hScrollOnBottom ? bgBottomHeight : height - bgTopHeight - hScrollHeight; _hScrollBounds = RectangleExt.FromFloats(boundsX, boundsY, _areaWidth, hScrollHeight); if (_variableSizeKnobs) { _hKnobBounds.Width = (int)Math.Max(hScrollKnob.MinWidth, (int)(_hScrollBounds.Width * _areaWidth / widgetWidth)); } else { _hKnobBounds.Width = (int)hScrollKnob.MinWidth; } _hKnobBounds.Height = (int)hScrollKnob.MinHeight; _hKnobBounds.X = _hScrollBounds.X + (int)((_hScrollBounds.Width - _hKnobBounds.Width) * GetScrollPercentX()); _hKnobBounds.Y = _hScrollBounds.Y; } else { _hScrollBounds = Rectangle.Empty; _hKnobBounds = Rectangle.Empty; } } if (_scrollY) { if (vScrollKnob != null) { var vScrollWidth = _style.VScroll != null ? _style.VScroll.MinWidth : vScrollKnob.MinWidth; // the small gap where the two scroll bars intersect might have to flip from bottom to top float boundsX, boundsY; if (_hScrollOnBottom) { boundsY = height - bgTopHeight - _areaHeight; } else { boundsY = bgBottomHeight; } // bar on the left or right if (_vScrollOnRight) { boundsX = width - bgRightWidth - vScrollWidth; } else { boundsX = bgLeftWidth; } _vScrollBounds = RectangleExt.FromFloats(boundsX, boundsY, vScrollWidth, _areaHeight); _vKnobBounds.Width = (int)vScrollKnob.MinWidth; if (_variableSizeKnobs) { _vKnobBounds.Height = (int)Math.Max(vScrollKnob.MinHeight, (int)(_vScrollBounds.Height * _areaHeight / widgetHeight)); } else { _vKnobBounds.Height = (int)vScrollKnob.MinHeight; } if (_vScrollOnRight) { _vKnobBounds.X = (int)(width - bgRightWidth - vScrollKnob.MinWidth); } else { _vKnobBounds.X = (int)bgLeftWidth; } _vKnobBounds.Y = _vScrollBounds.Y + (int)((_vScrollBounds.Height - _vKnobBounds.Height) * (1 - GetScrollPercentY())); } else { _vScrollBounds = Rectangle.Empty; _vKnobBounds = Rectangle.Empty; } } _widget.SetSize(widgetWidth, widgetHeight); if (_widget is ILayout) { ((ILayout)_widget).Validate(); } }