예제 #1
0
	void GUIPanel::_updateLayoutInternal(const GUILayoutData& data)
	{
		GUILayoutData childData = data;
		_updateDepthRange(childData);

		UINT32 numElements = (UINT32)mChildren.size();
		Rect2I* elementAreas = nullptr;

		if (numElements > 0)
			elementAreas = bs_stack_new<Rect2I>(numElements);

		_getElementAreas(data.area, elementAreas, numElements, mChildSizeRanges, mSizeRange);

		UINT32 childIdx = 0;

		for (auto& child : mChildren)
		{
			if (child->_isActive())
			{
				childData.area = elementAreas[childIdx];

				_updateChildLayout(child, childData);
			}

			childIdx++;
		}

		if (elementAreas != nullptr)
			bs_stack_free(elementAreas);
	}
예제 #2
0
	void GUILayoutX::_updateLayoutInternal(const GUILayoutData& data)
	{
		UINT32 numElements = (UINT32)mChildren.size();
		Rect2I* elementAreas = nullptr;

		if (numElements > 0)
			elementAreas = bs_stack_new<Rect2I>(numElements);

		_getElementAreas(data.area, elementAreas, numElements, mChildSizeRanges, mSizeRange);

		// Now that we have all the areas, actually assign them
		UINT32 childIdx = 0;

		GUILayoutData childData = data;
		for(auto& child : mChildren)
		{
			if (child->_isActive())
			{
				childData.area = elementAreas[childIdx];
				childData.clipRect = childData.area;
				childData.clipRect.clip(data.clipRect);

				child->_setLayoutData(childData);
				child->_updateLayoutInternal(childData);
			}

			childIdx++;
		}

		if(elementAreas != nullptr)
			bs_stack_free(elementAreas);
	}
예제 #3
0
	void GUIScrollArea::_getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements,
		const Vector<LayoutSizeRange>& sizeRanges, const LayoutSizeRange& mySizeRange) const
	{
		Vector2I visibleSize, contentSize;
		_getElementAreas(layoutArea, elementAreas, numElements, sizeRanges, visibleSize, contentSize);
	}
예제 #4
0
	void GUIScrollArea::_updateLayoutInternal(const GUILayoutData& data)
	{
		UINT32 numElements = (UINT32)mChildren.size();
		Rect2I* elementAreas = nullptr;

		if (numElements > 0)
			elementAreas = bs_stack_new<Rect2I>(numElements);

		UINT32 layoutIdx = 0;
		UINT32 horzScrollIdx = 0;
		UINT32 vertScrollIdx = 0;
		for (UINT32 i = 0; i < numElements; i++)
		{
			GUIElementBase* child = _getChild(i);

			if (child == mContentLayout)
				layoutIdx = i;

			if (child == mHorzScroll)
				horzScrollIdx = i;

			if (child == mVertScroll)
				vertScrollIdx = i;
		}

		_getElementAreas(data.area, elementAreas, numElements, mChildSizeRanges, mVisibleSize, mContentSize);

		Rect2I& layoutBounds = elementAreas[layoutIdx];
		Rect2I& horzScrollBounds = elementAreas[horzScrollIdx];
		Rect2I& vertScrollBounds = elementAreas[vertScrollIdx];

		// Recalculate offsets in case scroll percent got updated externally (this needs to be delayed to this point because
		// at the time of the update content and visible sizes might be out of date).
		UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentSize.y) - INT32(mVisibleSize.y));
		if (mRecalculateVertOffset)
		{
			mVertOffset = scrollableHeight * Math::clamp01(mVertScroll->getScrollPos());

			mRecalculateVertOffset = false;
		}

		UINT32 scrollableWidth = (UINT32)std::max(0, INT32(mContentSize.x) - INT32(mVisibleSize.x));
		if (mRecalculateHorzOffset)
		{
			mHorzOffset = scrollableWidth * Math::clamp01(mHorzScroll->getScrollPos());

			mRecalculateHorzOffset = false;
		}

		// Reset offset in case layout size changed so everything fits
		mVertOffset = Math::clamp(mVertOffset, 0.0f, (float)scrollableHeight);
		mHorzOffset = Math::clamp(mHorzOffset, 0.0f, (float)scrollableWidth);

		// Layout
		if (mContentLayout->_isActive())
		{
			layoutBounds.x -= Math::floorToInt(mHorzOffset);
			layoutBounds.y -= Math::floorToInt(mVertOffset);

			Rect2I layoutClipRect = data.clipRect;
			layoutClipRect.width = (UINT32)mVisibleSize.x;
			layoutClipRect.height = (UINT32)mVisibleSize.y;
			layoutClipRect.clip(data.clipRect);

			GUILayoutData layoutData = data;
			layoutData.area = layoutBounds;
			layoutData.clipRect = layoutClipRect;

			mContentLayout->_setLayoutData(layoutData);
			mContentLayout->_updateLayoutInternal(layoutData);
		}

		// Vertical scrollbar
		{
			GUILayoutData vertScrollData = data;
			vertScrollData.area = vertScrollBounds;

			vertScrollData.clipRect = vertScrollBounds;
			vertScrollData.clipRect.clip(data.clipRect);

			mVertScroll->_setLayoutData(vertScrollData);
			mVertScroll->_updateLayoutInternal(vertScrollData);

			// Set new handle size and update position to match the new size
			UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentSize.y) - INT32(vertScrollBounds.height));
			float newScrollPct = 0.0f;

			if (scrollableHeight > 0)
				newScrollPct = mVertOffset / scrollableHeight;	

			mVertScroll->_setHandleSize(vertScrollBounds.height / (float)mContentSize.y);
			mVertScroll->_setScrollPos(newScrollPct);
		}

		// Horizontal scrollbar
		{
			GUILayoutData horzScrollData = data;
			horzScrollData.area = horzScrollBounds;

			horzScrollData.clipRect = horzScrollBounds;
			horzScrollData.clipRect.clip(data.clipRect);

			mHorzScroll->_setLayoutData(horzScrollData);
			mHorzScroll->_updateLayoutInternal(horzScrollData);

			// Set new handle size and update position to match the new size
			UINT32 scrollableWidth = (UINT32)std::max(0, INT32(mContentSize.x) - INT32(horzScrollBounds.width));
			float newScrollPct = 0.0f;

			if (scrollableWidth > 0)
				newScrollPct = mHorzOffset / scrollableWidth;

			mHorzScroll->_setHandleSize(horzScrollBounds.width / (float)mContentSize.x);
			mHorzScroll->_setScrollPos(newScrollPct);
		}

		if (elementAreas != nullptr)
			bs_stack_free(elementAreas);
	}