|
|
@@ -0,0 +1,152 @@
|
|
|
+#include "BsGUIScrollArea.h"
|
|
|
+#include "BsGUIElementStyle.h"
|
|
|
+#include "BsGUISkin.h"
|
|
|
+#include "BsGUIWidget.h"
|
|
|
+#include "BsGUILayoutOptions.h"
|
|
|
+#include "BsGUILayout.h"
|
|
|
+#include "BsGUISkin.h"
|
|
|
+#include "BsGUIScrollBarVert.h"
|
|
|
+#include "BsGUIScrollBarHorz.h"
|
|
|
+#include "CmException.h"
|
|
|
+
|
|
|
+using namespace CamelotFramework;
|
|
|
+
|
|
|
+namespace BansheeEngine
|
|
|
+{
|
|
|
+ const UINT32 GUIScrollArea::ScrollBarWidth = 6;
|
|
|
+
|
|
|
+ GUIScrollArea::GUIScrollArea(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions)
|
|
|
+ :GUIElement(parent, style, layoutOptions), mVertScroll(nullptr), mHorzScroll(nullptr), mVertOffset(0), mHorzOffset(0),
|
|
|
+ mContentWidth(0), mContentHeight(0)
|
|
|
+ {
|
|
|
+ mContentLayout = &addLayoutYInternal();
|
|
|
+ mVertScroll = GUIScrollBarVert::create(parent);
|
|
|
+
|
|
|
+ mVertScroll->scrollPositionChanged.connect(boost::bind(&GUIScrollArea::vertScrollUpdate, this, _1));
|
|
|
+
|
|
|
+ mHorzScroll = GUIScrollBarHorz::create(parent);
|
|
|
+ // mHorzScroll->scrollPositionChanged.connect(boost::bind(&GUIScrollArea::horzScrollUpdate, this, _1)); // TODO - Enable
|
|
|
+ }
|
|
|
+
|
|
|
+ GUIScrollArea::~GUIScrollArea()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ UINT32 GUIScrollArea::getNumRenderElements() const
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ const HMaterial& GUIScrollArea::getMaterial(UINT32 renderElementIdx) const
|
|
|
+ {
|
|
|
+ CM_EXCEPT(InternalErrorException, "Trying to retrieve a material from an element with no render elements.");
|
|
|
+ }
|
|
|
+
|
|
|
+ UINT32 GUIScrollArea::getNumQuads(UINT32 renderElementIdx) const
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ void GUIScrollArea::updateRenderElementsInternal()
|
|
|
+ { }
|
|
|
+
|
|
|
+ UINT32 GUIScrollArea::_getOptimalWidth() const
|
|
|
+ {
|
|
|
+ return mContentLayout->_getOptimalWidth();
|
|
|
+ }
|
|
|
+
|
|
|
+ UINT32 GUIScrollArea::_getOptimalHeight() const
|
|
|
+ {
|
|
|
+ return mContentLayout->_getOptimalHeight();
|
|
|
+ }
|
|
|
+
|
|
|
+ void GUIScrollArea::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads,
|
|
|
+ UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const
|
|
|
+ { }
|
|
|
+
|
|
|
+ void GUIScrollArea::_updateLayoutInternal(UINT32 x, UINT32 y, UINT32 width, UINT32 height,
|
|
|
+ Rect clipRect, UINT8 widgetDepth, UINT16 areaDepth)
|
|
|
+ {
|
|
|
+ mContentLayout->_updateLayoutInternal(x, y, width, height, clipRect, widgetDepth, areaDepth);
|
|
|
+ UINT32 contentWidth = mContentLayout->_getActualWidth();
|
|
|
+ UINT32 contentHeight = mContentLayout->_getActualHeight();
|
|
|
+
|
|
|
+ if(contentHeight > mHeight)
|
|
|
+ {
|
|
|
+ // Make room for scrollbar
|
|
|
+ UINT32 contentWidth = (UINT32)std::max(0, (INT32)width - (INT32)ScrollBarWidth);
|
|
|
+
|
|
|
+ Rect layoutClipRect(clipRect.x, clipRect.y, contentWidth, clipRect.height);
|
|
|
+ mContentLayout->_updateLayoutInternal(x, y - mVertOffset, contentWidth, height, layoutClipRect, widgetDepth, areaDepth);
|
|
|
+ contentWidth = mContentLayout->_getActualWidth();
|
|
|
+ contentHeight = mContentLayout->_getActualHeight();
|
|
|
+
|
|
|
+ mVertScroll = GUIScrollBarVert::create(_getParentWidget());
|
|
|
+ mVertScroll->scrollPositionChanged.connect(boost::bind(&GUIScrollArea::vertScrollUpdate, this, _1));
|
|
|
+
|
|
|
+ Int2 offset(x + contentWidth, y);
|
|
|
+ mVertScroll->_setOffset(offset);
|
|
|
+ mVertScroll->_setWidth(ScrollBarWidth);
|
|
|
+ mVertScroll->_setHeight(height);
|
|
|
+ mVertScroll->_setAreaDepth(areaDepth);
|
|
|
+ mVertScroll->_setWidgetDepth(widgetDepth);
|
|
|
+
|
|
|
+ Rect elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
|
|
|
+ mVertScroll->_setClipRect(elemClipRect);
|
|
|
+
|
|
|
+ // TODO - Update scroll handle size and update position to match
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(mVertScroll != nullptr)
|
|
|
+ {
|
|
|
+ GUIElement::destroy(mVertScroll);
|
|
|
+ mVertScroll = nullptr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO - Add horizontal scroll bar
|
|
|
+
|
|
|
+ mContentWidth = contentWidth;
|
|
|
+ mContentHeight = contentHeight;
|
|
|
+ }
|
|
|
+
|
|
|
+ void GUIScrollArea::vertScrollUpdate(float scrollPos)
|
|
|
+ {
|
|
|
+ mVertOffset = Math::FloorToInt(mContentHeight * scrollPos);
|
|
|
+ }
|
|
|
+
|
|
|
+ void GUIScrollArea::horzScrollUpdate(float scrollPos)
|
|
|
+ {
|
|
|
+ mHorzOffset = Math::FloorToInt(mContentWidth * scrollPos);
|
|
|
+ }
|
|
|
+
|
|
|
+ GUIScrollArea* GUIScrollArea::create(GUIWidget& parent, const GUIElementStyle* style)
|
|
|
+ {
|
|
|
+ if(style == nullptr)
|
|
|
+ {
|
|
|
+ const GUISkin* skin = parent.getSkin();
|
|
|
+ style = skin->getStyle(getGUITypeName());
|
|
|
+ }
|
|
|
+
|
|
|
+ return new (cm_alloc<GUIScrollArea, PoolAlloc>()) GUIScrollArea(parent, style, getDefaultLayoutOptions(style));
|
|
|
+ }
|
|
|
+
|
|
|
+ GUIScrollArea* GUIScrollArea::create(GUIWidget& parent, const GUILayoutOptions& layoutOptions, const GUIElementStyle* style)
|
|
|
+ {
|
|
|
+ if(style == nullptr)
|
|
|
+ {
|
|
|
+ const GUISkin* skin = parent.getSkin();
|
|
|
+ style = skin->getStyle(getGUITypeName());
|
|
|
+ }
|
|
|
+
|
|
|
+ return new (cm_alloc<GUIScrollArea, PoolAlloc>()) GUIScrollArea(parent, style, layoutOptions);
|
|
|
+ }
|
|
|
+
|
|
|
+ const String& GUIScrollArea::getGUITypeName()
|
|
|
+ {
|
|
|
+ static String typeName = "ScrollArea";
|
|
|
+ return typeName;
|
|
|
+ }
|
|
|
+}
|