|
|
@@ -8,6 +8,7 @@
|
|
|
#include "BsGUIScrollBarVert.h"
|
|
|
#include "BsGUIScrollBarHorz.h"
|
|
|
#include "BsGUIMouseEvent.h"
|
|
|
+#include "BsGUILayoutUtility.h"
|
|
|
#include "BsException.h"
|
|
|
|
|
|
using namespace std::placeholders;
|
|
|
@@ -21,10 +22,18 @@ namespace BansheeEngine
|
|
|
GUIScrollArea::GUIScrollArea(ScrollBarType vertBarType, ScrollBarType horzBarType,
|
|
|
const String& scrollBarStyle, const String& scrollAreaStyle, const GUILayoutOptions& layoutOptions)
|
|
|
:GUIElementContainer(layoutOptions), mVertScroll(nullptr), mHorzScroll(nullptr), mVertOffset(0), mHorzOffset(0),
|
|
|
- mContentWidth(0), mContentHeight(0), mClippedContentWidth(0), mClippedContentHeight(0), mVertBarType(vertBarType), mHorzBarType(horzBarType),
|
|
|
- mScrollBarStyle(scrollBarStyle)
|
|
|
+ mVertBarType(vertBarType), mHorzBarType(horzBarType), mScrollBarStyle(scrollBarStyle)
|
|
|
{
|
|
|
mContentLayout = &addLayoutYInternal(this);
|
|
|
+
|
|
|
+ mHorzScroll = GUIScrollBarHorz::create(mScrollBarStyle);
|
|
|
+ mVertScroll = GUIScrollBarVert::create(mScrollBarStyle);
|
|
|
+
|
|
|
+ _registerChildElement(mHorzScroll);
|
|
|
+ _registerChildElement(mVertScroll);
|
|
|
+
|
|
|
+ mHorzScroll->onScrollPositionChanged.connect(std::bind(&GUIScrollArea::horzScrollUpdate, this, _1));
|
|
|
+ mVertScroll->onScrollPositionChanged.connect(std::bind(&GUIScrollArea::vertScrollUpdate, this, _1));
|
|
|
}
|
|
|
|
|
|
GUIScrollArea::~GUIScrollArea()
|
|
|
@@ -42,136 +51,187 @@ namespace BansheeEngine
|
|
|
mClippedBounds = bounds;
|
|
|
}
|
|
|
|
|
|
- void GUIScrollArea::_updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height,
|
|
|
- Rect2I clipRect, UINT8 widgetDepth, UINT16 areaDepth)
|
|
|
+ void GUIScrollArea::_getElementAreas(INT32 x, INT32 y, UINT32 width, UINT32 height, Rect2I* elementAreas, UINT32 numElements, const Vector<Vector2I>& optimalSizes) const
|
|
|
+ {
|
|
|
+ Vector2I visibleSize, contentSize;
|
|
|
+ _getElementAreas(x, y, width, height, elementAreas, numElements, optimalSizes, visibleSize, contentSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ void GUIScrollArea::_getElementAreas(INT32 x, INT32 y, UINT32 width, UINT32 height, Rect2I* elementAreas, UINT32 numElements,
|
|
|
+ const Vector<Vector2I>& optimalSizes, Vector2I& visibleSize, Vector2I& contentSize) const
|
|
|
{
|
|
|
- // We want elements to use their optimal height, since scroll area
|
|
|
- // technically provides "infinite" space
|
|
|
- UINT32 contentLayoutWidth = width;
|
|
|
- if(mHorzBarType != ScrollBarType::NeverShow)
|
|
|
- contentLayoutWidth = mContentLayout->_getOptimalSize().x;
|
|
|
+ assert(mChildren.size() == numElements && numElements == 3);
|
|
|
+
|
|
|
+ UINT32 layoutIdx = 0;
|
|
|
+ UINT32 horzScrollIdx = 0;
|
|
|
+ UINT32 vertScrollIdx = 0;
|
|
|
+ UINT32 idx = 0;
|
|
|
+ for (auto& child : mChildren)
|
|
|
+ {
|
|
|
+ if (child == mContentLayout)
|
|
|
+ layoutIdx = idx;
|
|
|
|
|
|
- UINT32 contentLayoutHeight = height;
|
|
|
- if(mVertBarType != ScrollBarType::NeverShow)
|
|
|
- contentLayoutHeight = mContentLayout->_getOptimalSize().y;
|
|
|
+ if (child == mHorzScroll)
|
|
|
+ horzScrollIdx = idx;
|
|
|
|
|
|
- UINT32 maxedContentLayoutWidth = std::max(contentLayoutWidth, mWidth);
|
|
|
- UINT32 maxedContentLayoutHeight = std::max(contentLayoutHeight, mHeight);
|
|
|
+ if (child == mVertScroll)
|
|
|
+ vertScrollIdx = idx;
|
|
|
|
|
|
- mContentLayout->_updateLayoutInternal(x, y, maxedContentLayoutWidth, maxedContentLayoutHeight,
|
|
|
- clipRect, widgetDepth, areaDepth);
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
|
|
|
- mContentWidth = mContentLayout->_getActualWidth();
|
|
|
- mContentHeight = mContentLayout->_getActualHeight();
|
|
|
+ // Calculate content layout bounds
|
|
|
|
|
|
- mClippedContentWidth = width;
|
|
|
- mClippedContentHeight = height;
|
|
|
+ //// We want elements to use their optimal height, since scroll area
|
|
|
+ //// technically provides "infinite" space
|
|
|
+ UINT32 optimalContentWidth = width;
|
|
|
+ if (mHorzBarType != ScrollBarType::NeverShow)
|
|
|
+ optimalContentWidth = optimalSizes[layoutIdx].x;
|
|
|
|
|
|
- Rect2I layoutClipRect = clipRect;
|
|
|
- bool addHorzScrollbar = (mHorzBarType == ScrollBarType::ShowIfDoesntFit && mContentWidth > mWidth) ||
|
|
|
+ UINT32 optimalContentHeight = height;
|
|
|
+ if (mVertBarType != ScrollBarType::NeverShow)
|
|
|
+ optimalContentHeight = optimalSizes[layoutIdx].y;
|
|
|
+
|
|
|
+ UINT32 layoutWidth = std::max(optimalContentWidth, width);
|
|
|
+ UINT32 layoutHeight = std::max(optimalContentHeight, height);
|
|
|
+
|
|
|
+ contentSize = GUILayoutUtility::calcActualSize(layoutWidth, layoutHeight, mContentLayout);
|
|
|
+ visibleSize = Vector2I(width, height);
|
|
|
+
|
|
|
+ bool addHorzScrollbar = (mHorzBarType == ScrollBarType::ShowIfDoesntFit && contentSize.x > visibleSize.x) ||
|
|
|
mHorzBarType == ScrollBarType::AlwaysShow && mHorzBarType != ScrollBarType::NeverShow;
|
|
|
|
|
|
bool hasHorzScrollbar = false;
|
|
|
bool hasVertScrollbar = false;
|
|
|
- if(addHorzScrollbar)
|
|
|
- {
|
|
|
+ if (addHorzScrollbar)
|
|
|
+ {
|
|
|
// Make room for scrollbar
|
|
|
- mClippedContentHeight = (UINT32)std::max(0, (INT32)height - (INT32)ScrollBarWidth);
|
|
|
- layoutClipRect.height = mClippedContentHeight;
|
|
|
- hasHorzScrollbar = true;
|
|
|
+ visibleSize.y = (UINT32)std::max(0, (INT32)height - (INT32)ScrollBarWidth);
|
|
|
|
|
|
if (mVertBarType == ScrollBarType::NeverShow)
|
|
|
- maxedContentLayoutHeight = mClippedContentHeight;
|
|
|
+ layoutHeight = (UINT32)visibleSize.y;
|
|
|
else
|
|
|
- maxedContentLayoutHeight = std::max(contentLayoutHeight, mClippedContentHeight); // Never go below optimal size
|
|
|
-
|
|
|
- mContentLayout->_updateLayoutInternal(x - Math::floorToInt(mHorzOffset), y,
|
|
|
- maxedContentLayoutWidth, maxedContentLayoutHeight, layoutClipRect, widgetDepth, areaDepth);
|
|
|
+ layoutHeight = std::max(optimalContentHeight, (UINT32)visibleSize.y); // Never go below optimal size
|
|
|
|
|
|
- mContentWidth = mContentLayout->_getActualWidth();
|
|
|
- mContentHeight = mContentLayout->_getActualHeight();
|
|
|
+ contentSize = GUILayoutUtility::calcActualSize(layoutWidth, layoutHeight, mContentLayout);
|
|
|
+ hasHorzScrollbar = true;
|
|
|
}
|
|
|
|
|
|
- bool addVertScrollbar = (mVertBarType == ScrollBarType::ShowIfDoesntFit && mContentHeight > mClippedContentHeight) ||
|
|
|
+ bool addVertScrollbar = (mVertBarType == ScrollBarType::ShowIfDoesntFit && contentSize.y > visibleSize.y) ||
|
|
|
mVertBarType == ScrollBarType::AlwaysShow && mVertBarType != ScrollBarType::NeverShow;
|
|
|
|
|
|
- if(addVertScrollbar)
|
|
|
+ if (addVertScrollbar)
|
|
|
{
|
|
|
// Make room for scrollbar
|
|
|
- mClippedContentWidth = (UINT32)std::max(0, (INT32)width - (INT32)ScrollBarWidth);
|
|
|
- layoutClipRect.width = mClippedContentWidth;
|
|
|
- hasVertScrollbar = true;
|
|
|
-
|
|
|
+ visibleSize.x = (UINT32)std::max(0, (INT32)width - (INT32)ScrollBarWidth);
|
|
|
+
|
|
|
if (mHorzBarType == ScrollBarType::NeverShow)
|
|
|
- maxedContentLayoutWidth = mClippedContentWidth;
|
|
|
+ layoutWidth = (UINT32)visibleSize.x;
|
|
|
else
|
|
|
- maxedContentLayoutWidth = std::max(contentLayoutWidth, mClippedContentWidth); // Never go below optimal size
|
|
|
+ layoutWidth = std::max(optimalContentWidth, (UINT32)visibleSize.x); // Never go below optimal size
|
|
|
|
|
|
- if(hasHorzScrollbar)
|
|
|
- {
|
|
|
- mContentLayout->_updateLayoutInternal(x - Math::floorToInt(mHorzOffset), y - Math::floorToInt(mVertOffset),
|
|
|
- maxedContentLayoutWidth, maxedContentLayoutHeight,
|
|
|
- layoutClipRect, widgetDepth, areaDepth);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- mContentLayout->_updateLayoutInternal(x, y - Math::floorToInt(mVertOffset),
|
|
|
- maxedContentLayoutWidth, maxedContentLayoutHeight,
|
|
|
- layoutClipRect, widgetDepth, areaDepth);
|
|
|
- }
|
|
|
-
|
|
|
- mContentWidth = mContentLayout->_getActualWidth();
|
|
|
- mContentHeight = mContentLayout->_getActualHeight();
|
|
|
+ contentSize = GUILayoutUtility::calcActualSize(layoutWidth, layoutHeight, mContentLayout);
|
|
|
+ hasVertScrollbar = true;
|
|
|
|
|
|
- if(!hasHorzScrollbar) // Since width has been reduced, we need to check if we require the horizontal scrollbar
|
|
|
+ if (!hasHorzScrollbar) // Since width has been reduced, we need to check if we require the horizontal scrollbar
|
|
|
{
|
|
|
- addHorzScrollbar = (mHorzBarType == ScrollBarType::ShowIfDoesntFit && mContentWidth > mClippedContentWidth) && mHorzBarType != ScrollBarType::NeverShow;
|
|
|
+ addHorzScrollbar = (mHorzBarType == ScrollBarType::ShowIfDoesntFit && contentSize.x > visibleSize.x) && mHorzBarType != ScrollBarType::NeverShow;
|
|
|
|
|
|
- if(addHorzScrollbar)
|
|
|
+ if (addHorzScrollbar)
|
|
|
{
|
|
|
// Make room for scrollbar
|
|
|
- mClippedContentHeight = (UINT32)std::max(0, (INT32)height - (INT32)ScrollBarWidth);
|
|
|
- layoutClipRect.height = mClippedContentHeight;
|
|
|
+ visibleSize.y = (UINT32)std::max(0, (INT32)height - (INT32)ScrollBarWidth);
|
|
|
|
|
|
if (mVertBarType == ScrollBarType::NeverShow)
|
|
|
- maxedContentLayoutHeight = mClippedContentHeight;
|
|
|
+ layoutHeight = (UINT32)visibleSize.y;
|
|
|
else
|
|
|
- maxedContentLayoutHeight = std::max(contentLayoutHeight, mClippedContentHeight); // Never go below optimal size
|
|
|
-
|
|
|
- mContentLayout->_updateLayoutInternal(x - Math::floorToInt(mHorzOffset), y - Math::floorToInt(mVertOffset),
|
|
|
- maxedContentLayoutWidth, maxedContentLayoutHeight,
|
|
|
- layoutClipRect, widgetDepth, areaDepth);
|
|
|
-
|
|
|
- mContentWidth = mContentLayout->_getActualWidth();
|
|
|
- mContentHeight = mContentLayout->_getActualHeight();
|
|
|
+ layoutHeight = std::max(optimalContentHeight, (UINT32)visibleSize.y); // Never go below optimal size
|
|
|
|
|
|
+ contentSize = GUILayoutUtility::calcActualSize(layoutWidth, layoutHeight, mContentLayout);
|
|
|
hasHorzScrollbar = true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Add/remove/update vertical scrollbar as needed
|
|
|
- if((mVertBarType == ScrollBarType::ShowIfDoesntFit && mContentHeight > mClippedContentHeight) || mVertBarType == ScrollBarType::AlwaysShow &&
|
|
|
- mVertBarType != ScrollBarType::NeverShow)
|
|
|
- {
|
|
|
- if(mVertScroll == nullptr)
|
|
|
- {
|
|
|
- mVertScroll = GUIScrollBarVert::create(mScrollBarStyle);
|
|
|
-
|
|
|
- _registerChildElement(mVertScroll);
|
|
|
-
|
|
|
- mVertScroll->onScrollPositionChanged.connect(std::bind(&GUIScrollArea::vertScrollUpdate, this, _1));
|
|
|
- }
|
|
|
+ elementAreas[layoutIdx] = Rect2I(x - Math::floorToInt(mHorzOffset), y - Math::floorToInt(mVertOffset), layoutWidth, layoutHeight);
|
|
|
|
|
|
+ // Calculate vertical scrollbar bounds
|
|
|
+ if (hasVertScrollbar)
|
|
|
+ {
|
|
|
INT32 scrollBarOffset = (UINT32)std::max(0, (INT32)width - (INT32)ScrollBarWidth);
|
|
|
UINT32 scrollBarHeight = height;
|
|
|
- if(hasHorzScrollbar)
|
|
|
+ if (hasHorzScrollbar)
|
|
|
scrollBarHeight = (UINT32)std::max(0, (INT32)scrollBarHeight - (INT32)ScrollBarWidth);
|
|
|
|
|
|
- Vector2I offset(x + scrollBarOffset, y);
|
|
|
- mVertScroll->setOffset(offset);
|
|
|
- mVertScroll->setWidth(ScrollBarWidth);
|
|
|
- mVertScroll->setHeight(scrollBarHeight);
|
|
|
+ elementAreas[vertScrollIdx] = Rect2I(x + scrollBarOffset, y, ScrollBarWidth, scrollBarHeight);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ elementAreas[vertScrollIdx] = Rect2I(x + layoutWidth, y, 0, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Calculate horizontal scrollbar bounds
|
|
|
+ if (hasHorzScrollbar)
|
|
|
+ {
|
|
|
+ INT32 scrollBarOffset = (UINT32)std::max(0, (INT32)height - (INT32)ScrollBarWidth);
|
|
|
+ UINT32 scrollBarWidth = width;
|
|
|
+ if (hasVertScrollbar)
|
|
|
+ scrollBarWidth = (UINT32)std::max(0, (INT32)scrollBarWidth - (INT32)ScrollBarWidth);
|
|
|
+
|
|
|
+ elementAreas[horzScrollIdx] = Rect2I(x, y + scrollBarOffset, scrollBarWidth, ScrollBarWidth);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ elementAreas[horzScrollIdx] = Rect2I(x, y + layoutHeight, 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void GUIScrollArea::_updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height,
|
|
|
+ Rect2I clipRect, UINT8 widgetDepth, UINT16 areaDepth)
|
|
|
+ {
|
|
|
+ UINT32 numElements = (UINT32)mChildren.size();
|
|
|
+ Rect2I* elementAreas = nullptr;
|
|
|
+
|
|
|
+ if (numElements > 0)
|
|
|
+ elementAreas = stackConstructN<Rect2I>(numElements);
|
|
|
+
|
|
|
+ Vector<Vector2I> optimalSizes;
|
|
|
+ UINT32 layoutIdx = 0;
|
|
|
+ UINT32 horzScrollIdx = 0;
|
|
|
+ UINT32 vertScrollIdx = 0;
|
|
|
+ for (UINT32 i = 0; i < numElements; i++)
|
|
|
+ {
|
|
|
+ GUIElementBase* child = _getChild(i);
|
|
|
+ optimalSizes.push_back(GUILayoutUtility::calcOptimalSize(child));
|
|
|
+
|
|
|
+ if (child == mContentLayout)
|
|
|
+ layoutIdx = i;
|
|
|
+
|
|
|
+ if (child == mHorzScroll)
|
|
|
+ horzScrollIdx = i;
|
|
|
+
|
|
|
+ if (child == mVertScroll)
|
|
|
+ vertScrollIdx = i;
|
|
|
+ }
|
|
|
+
|
|
|
+ _getElementAreas(x, y, width, height, elementAreas, numElements, optimalSizes, mVisibleSize, mContentSize);
|
|
|
+
|
|
|
+ Rect2I& layoutBounds = elementAreas[layoutIdx];
|
|
|
+ Rect2I& horzScrollBounds = elementAreas[horzScrollIdx];
|
|
|
+ Rect2I& vertScrollBounds = elementAreas[vertScrollIdx];
|
|
|
+
|
|
|
+ // Layout
|
|
|
+ Rect2I layoutClipRect = clipRect;
|
|
|
+ layoutClipRect.width = (UINT32)mVisibleSize.x;
|
|
|
+ layoutClipRect.height = (UINT32)mVisibleSize.y;
|
|
|
+ mContentLayout->_updateLayoutInternal(layoutBounds.x, layoutBounds.y,
|
|
|
+ layoutBounds.width, layoutBounds.height, layoutClipRect, widgetDepth, areaDepth);
|
|
|
+
|
|
|
+ // Vertical scrollbar
|
|
|
+ {
|
|
|
+ mVertScroll->setOffset(Vector2I(vertScrollBounds.x, vertScrollBounds.y));
|
|
|
+ mVertScroll->setWidth(vertScrollBounds.width);
|
|
|
+ mVertScroll->setHeight(vertScrollBounds.height);
|
|
|
mVertScroll->_setAreaDepth(areaDepth);
|
|
|
mVertScroll->_setWidgetDepth(widgetDepth);
|
|
|
|
|
|
@@ -180,55 +240,28 @@ namespace BansheeEngine
|
|
|
mVertScroll->_setClipRect(elemClipRect);
|
|
|
|
|
|
// This element is not a child of any layout so we treat it as a root element
|
|
|
- Rect2I scrollBarLayoutClipRect(clipRect.x + scrollBarOffset, clipRect.y, clippedScrollbarWidth, clipRect.height);
|
|
|
- mVertScroll->_updateLayout(offset.x, offset.y, ScrollBarWidth, scrollBarHeight, scrollBarLayoutClipRect, widgetDepth, areaDepth);
|
|
|
+ Rect2I scrollBarLayoutClipRect(clipRect.x + (vertScrollBounds.x - x), clipRect.y + (vertScrollBounds.y - y), clippedScrollbarWidth, clipRect.height);
|
|
|
+ mVertScroll->_updateLayout(vertScrollBounds.x, vertScrollBounds.y, vertScrollBounds.width, vertScrollBounds.height, scrollBarLayoutClipRect, widgetDepth, areaDepth);
|
|
|
|
|
|
// Set new handle size and update position to match the new size
|
|
|
- UINT32 newHandleSize = (UINT32)Math::floorToInt(mVertScroll->getMaxHandleSize() * (scrollBarHeight / (float)mContentHeight));
|
|
|
+ UINT32 newHandleSize = (UINT32)Math::floorToInt(mVertScroll->getMaxHandleSize() * (vertScrollBounds.height / (float)mContentSize.y));
|
|
|
newHandleSize = std::max(newHandleSize, MinHandleSize);
|
|
|
|
|
|
- UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentHeight) - INT32(scrollBarHeight));
|
|
|
+ UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentSize.y) - INT32(vertScrollBounds.height));
|
|
|
float newScrollPct = 0.0f;
|
|
|
|
|
|
- if(scrollableHeight > 0)
|
|
|
+ if (scrollableHeight > 0)
|
|
|
newScrollPct = mVertOffset / scrollableHeight;
|
|
|
|
|
|
mVertScroll->setHandleSize(newHandleSize);
|
|
|
mVertScroll->setScrollPos(newScrollPct);
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- if(mVertScroll != nullptr)
|
|
|
- {
|
|
|
- GUIElement::destroy(mVertScroll);
|
|
|
- mVertScroll = nullptr;
|
|
|
- }
|
|
|
-
|
|
|
- mVertOffset = 0.0f;
|
|
|
- }
|
|
|
|
|
|
- // Add/remove/update horizontal scrollbar as needed
|
|
|
- if((mHorzBarType == ScrollBarType::ShowIfDoesntFit && mContentWidth > mClippedContentWidth) || mHorzBarType == ScrollBarType::AlwaysShow &&
|
|
|
- mHorzBarType != ScrollBarType::NeverShow)
|
|
|
- {
|
|
|
- if(mHorzScroll == nullptr)
|
|
|
- {
|
|
|
- mHorzScroll = GUIScrollBarHorz::create(mScrollBarStyle);
|
|
|
-
|
|
|
- _registerChildElement(mHorzScroll);
|
|
|
-
|
|
|
- mHorzScroll->onScrollPositionChanged.connect(std::bind(&GUIScrollArea::horzScrollUpdate, this, _1));
|
|
|
- }
|
|
|
-
|
|
|
- INT32 scrollBarOffset = (UINT32)std::max(0, (INT32)height - (INT32)ScrollBarWidth);
|
|
|
- UINT32 scrollBarWidth = width;
|
|
|
- if(hasVertScrollbar)
|
|
|
- scrollBarWidth = (UINT32)std::max(0, (INT32)scrollBarWidth - (INT32)ScrollBarWidth);
|
|
|
-
|
|
|
- Vector2I offset(x, y + scrollBarOffset);
|
|
|
- mHorzScroll->setOffset(offset);
|
|
|
- mHorzScroll->setWidth(scrollBarWidth);
|
|
|
- mHorzScroll->setHeight(ScrollBarWidth);
|
|
|
+ // Horizontal scrollbar
|
|
|
+ {
|
|
|
+ mHorzScroll->setOffset(Vector2I(horzScrollBounds.x, horzScrollBounds.y));
|
|
|
+ mHorzScroll->setWidth(horzScrollBounds.width);
|
|
|
+ mHorzScroll->setHeight(horzScrollBounds.height);
|
|
|
mHorzScroll->_setAreaDepth(areaDepth);
|
|
|
mHorzScroll->_setWidgetDepth(widgetDepth);
|
|
|
|
|
|
@@ -237,32 +270,25 @@ namespace BansheeEngine
|
|
|
mHorzScroll->_setClipRect(elemClipRect);
|
|
|
|
|
|
// This element is not a child of any layout so we treat it as a root element
|
|
|
- Rect2I scrollBarLayoutClipRect(clipRect.x, clipRect.y + scrollBarOffset, clipRect.width, clippedScrollbarHeight);
|
|
|
- mHorzScroll->_updateLayout(offset.x, offset.y, scrollBarWidth, ScrollBarWidth, scrollBarLayoutClipRect, widgetDepth, areaDepth);
|
|
|
+ Rect2I scrollBarLayoutClipRect(clipRect.x + (horzScrollBounds.x - x), clipRect.y + (horzScrollBounds.y - y), clipRect.width, clippedScrollbarHeight);
|
|
|
+ mHorzScroll->_updateLayout(horzScrollBounds.x, horzScrollBounds.y, horzScrollBounds.width, horzScrollBounds.height, scrollBarLayoutClipRect, widgetDepth, areaDepth);
|
|
|
|
|
|
// Set new handle size and update position to match the new size
|
|
|
- UINT32 newHandleSize = (UINT32)Math::floorToInt(mHorzScroll->getMaxHandleSize() * (scrollBarWidth / (float)mContentWidth));
|
|
|
+ UINT32 newHandleSize = (UINT32)Math::floorToInt(mHorzScroll->getMaxHandleSize() * (horzScrollBounds.width / (float)mContentSize.x));
|
|
|
newHandleSize = std::max(newHandleSize, MinHandleSize);
|
|
|
|
|
|
- UINT32 scrollableWidth = (UINT32)std::max(0, INT32(mContentWidth) - INT32(scrollBarWidth));
|
|
|
+ UINT32 scrollableWidth = (UINT32)std::max(0, INT32(mContentSize.x) - INT32(horzScrollBounds.width));
|
|
|
float newScrollPct = 0.0f;
|
|
|
-
|
|
|
- if(scrollableWidth > 0)
|
|
|
+
|
|
|
+ if (scrollableWidth > 0)
|
|
|
newScrollPct = mHorzOffset / scrollableWidth;
|
|
|
|
|
|
mHorzScroll->setHandleSize(newHandleSize);
|
|
|
mHorzScroll->setScrollPos(newScrollPct);
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- if(mHorzScroll != nullptr)
|
|
|
- {
|
|
|
- GUIElement::destroy(mHorzScroll);
|
|
|
- mHorzScroll = nullptr;
|
|
|
- }
|
|
|
|
|
|
- mHorzOffset = 0.0f;
|
|
|
- }
|
|
|
+ if (elementAreas != nullptr)
|
|
|
+ stackDeallocLast(elementAreas);
|
|
|
}
|
|
|
|
|
|
void GUIScrollArea::vertScrollUpdate(float scrollPos)
|
|
|
@@ -277,7 +303,7 @@ namespace BansheeEngine
|
|
|
|
|
|
void GUIScrollArea::scrollToVertical(float pct)
|
|
|
{
|
|
|
- UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentHeight) - INT32(mClippedContentHeight));
|
|
|
+ UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentSize.y) - INT32(mVisibleSize.y));
|
|
|
mVertOffset = scrollableHeight * Math::clamp01(pct);
|
|
|
|
|
|
markContentAsDirty();
|
|
|
@@ -285,7 +311,7 @@ namespace BansheeEngine
|
|
|
|
|
|
void GUIScrollArea::scrollToHorizontal(float pct)
|
|
|
{
|
|
|
- UINT32 scrollableWidth = (UINT32)std::max(0, INT32(mContentWidth) - INT32(mClippedContentWidth));
|
|
|
+ UINT32 scrollableWidth = (UINT32)std::max(0, INT32(mContentSize.x) - INT32(mVisibleSize.x));
|
|
|
mHorzOffset = scrollableWidth * Math::clamp01(pct);
|
|
|
|
|
|
markContentAsDirty();
|
|
|
@@ -295,7 +321,7 @@ namespace BansheeEngine
|
|
|
{
|
|
|
if(mVertScroll != nullptr)
|
|
|
{
|
|
|
- UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentHeight) - INT32(mClippedContentHeight));
|
|
|
+ UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentSize.y) - INT32(mVisibleSize.y));
|
|
|
|
|
|
float offset = 0.0f;
|
|
|
if(scrollableSize > 0)
|
|
|
@@ -309,7 +335,7 @@ namespace BansheeEngine
|
|
|
{
|
|
|
if(mVertScroll != nullptr)
|
|
|
{
|
|
|
- UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentHeight) - INT32(mClippedContentHeight));
|
|
|
+ UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentSize.y) - INT32(mVisibleSize.y));
|
|
|
|
|
|
float offset = 0.0f;
|
|
|
if(scrollableSize > 0)
|
|
|
@@ -323,7 +349,7 @@ namespace BansheeEngine
|
|
|
{
|
|
|
if(mHorzScroll != nullptr)
|
|
|
{
|
|
|
- UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentWidth) - INT32(mClippedContentWidth));
|
|
|
+ UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentSize.x) - INT32(mVisibleSize.x));
|
|
|
|
|
|
float offset = 0.0f;
|
|
|
if(scrollableSize > 0)
|
|
|
@@ -337,7 +363,7 @@ namespace BansheeEngine
|
|
|
{
|
|
|
if(mHorzScroll != nullptr)
|
|
|
{
|
|
|
- UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentWidth) - INT32(mClippedContentWidth));
|
|
|
+ UINT32 scrollableSize = (UINT32)std::max(0, INT32(mContentSize.x) - INT32(mVisibleSize.x));
|
|
|
|
|
|
float offset = 0.0f;
|
|
|
if(scrollableSize > 0)
|
|
|
@@ -378,7 +404,7 @@ namespace BansheeEngine
|
|
|
// Mouse wheel only scrolls on the Y axis
|
|
|
if(mVertScroll != nullptr)
|
|
|
{
|
|
|
- UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentWidth) - INT32(mClippedContentHeight));
|
|
|
+ UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentSize.y) - INT32(mVisibleSize.y));
|
|
|
float additionalScroll = (float)WheelScrollAmount / scrollableHeight;
|
|
|
|
|
|
mVertScroll->scroll(additionalScroll * ev.getWheelScrollAmount());
|