Просмотр исходного кода

Working scroll view (only vertical)

Marko Pintera 12 лет назад
Родитель
Сommit
c477bb4e76

+ 2 - 1
BansheeEngine/Include/BsGUIScrollBarHandle.h

@@ -51,6 +51,8 @@ namespace BansheeEngine
 
 		virtual CM::UINT32 _getOptimalWidth() const;
 		virtual CM::UINT32 _getOptimalHeight() const;
+
+		CM::UINT32 getMaxSize() const;
 	private:
 		ImageSprite* mImageSprite;
 		CM::UINT32 mHandleSize;
@@ -65,6 +67,5 @@ namespace BansheeEngine
 
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
 		bool isOnHandle(const CM::Int2& pos) const;
-		CM::UINT32 getMaxSize() const;
 	};
 }

+ 2 - 0
BansheeEngine/Include/BsGUIScrollBarVert.h

@@ -19,6 +19,8 @@ namespace BansheeEngine
 
 		void setHandleSize(CM::UINT32 size);
 		void setScrollPos(float pct);
+
+		CM::UINT32 getMaxHandleSize() const;
 	protected:
 		~GUIScrollBarVert();
 

+ 1 - 0
BansheeEngine/Include/BsPrerequisites.h

@@ -39,6 +39,7 @@ namespace BansheeEngine
 	class GUIScrollBarHandle;
 	class GUIScrollBarVert;
 	class GUIScrollBarHorz;
+	class GUIScrollArea;
 	class GUISkin;
 	struct GUIElementStyle;
 	class GUIMouseEvent;

+ 1 - 1
BansheeEngine/Source/BsGUILayoutX.cpp

@@ -354,7 +354,7 @@ namespace BansheeEngine
 
 				element->_setHeight(elemHeight);
 
-				UINT32 yOffset = (UINT32)Math::CeilToInt((height - element->_getHeight()) * 0.5f);
+				INT32 yOffset = Math::CeilToInt(((INT32)height - (INT32)element->_getHeight()) * 0.5f);
 
 				Int2 offset(x + xOffset, y + yOffset);
 				element->_setOffset(offset);

+ 1 - 1
BansheeEngine/Source/BsGUILayoutY.cpp

@@ -354,7 +354,7 @@ namespace BansheeEngine
 				element->_setWidth(elemWidth);
 				element->_setHeight(elemHeight);
 
-				UINT32 xOffset = (UINT32)Math::CeilToInt((width - element->_getWidth()) * 0.5f);
+				INT32 xOffset = Math::CeilToInt((INT32)(width - (INT32)element->_getWidth()) * 0.5f);
 
 				Int2 offset(x + xOffset, y + yOffset);
 				element->_setOffset(offset);

+ 19 - 11
BansheeEngine/Source/BsGUIScrollArea.cpp

@@ -20,12 +20,6 @@ namespace BansheeEngine
 		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()
@@ -82,8 +76,11 @@ namespace BansheeEngine
 			contentWidth = mContentLayout->_getActualWidth();
 			contentHeight = mContentLayout->_getActualHeight();
 
-			mVertScroll = GUIScrollBarVert::create(_getParentWidget());
-			mVertScroll->scrollPositionChanged.connect(boost::bind(&GUIScrollArea::vertScrollUpdate, this, _1));
+			if(mVertScroll == nullptr)
+			{
+				mVertScroll = GUIScrollBarVert::create(_getParentWidget());
+				mVertScroll->scrollPositionChanged.connect(boost::bind(&GUIScrollArea::vertScrollUpdate, this, _1));
+			}
 
 			Int2 offset(x + contentWidth, y);
 			mVertScroll->_setOffset(offset);
@@ -92,9 +89,14 @@ namespace BansheeEngine
 			mVertScroll->_setAreaDepth(areaDepth);
 			mVertScroll->_setWidgetDepth(widgetDepth);
 
-			Rect elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+			UINT32 clippedScrollbarWidth = std::min(width, ScrollBarWidth);
+			Rect elemClipRect(0, 0, clippedScrollbarWidth, clipRect.height);
 			mVertScroll->_setClipRect(elemClipRect);
 
+			// This element is not a child of any layout so we treat it as a root element
+			Rect scrollBarLayoutClipRect(clipRect.x + contentWidth, clipRect.y, clippedScrollbarWidth, clipRect.height);
+			mVertScroll->_updateLayout(offset.x, offset.y, ScrollBarWidth, height, scrollBarLayoutClipRect, widgetDepth, areaDepth);
+
 			// TODO - Update scroll handle size and update position to match
 		}
 		else
@@ -114,12 +116,18 @@ namespace BansheeEngine
 
 	void GUIScrollArea::vertScrollUpdate(float scrollPos)
 	{
-		mVertOffset = Math::FloorToInt(mContentHeight * scrollPos);
+		UINT32 scrollableHeight = (UINT32)std::max(0, INT32(mContentHeight) - INT32(mHeight));
+		mVertOffset = Math::FloorToInt(scrollableHeight * scrollPos);
+
+		markContentAsDirty();
 	}
 
 	void GUIScrollArea::horzScrollUpdate(float scrollPos)
 	{
-		mHorzOffset = Math::FloorToInt(mContentWidth * scrollPos);
+		UINT32 scrollableWidth = (UINT32)std::max(0, INT32(mContentWidth) - INT32(mWidth));
+		mHorzOffset = Math::FloorToInt(scrollableWidth * scrollPos);
+
+		markContentAsDirty();
 	}
 
 	GUIScrollArea* GUIScrollArea::create(GUIWidget& parent, const GUIElementStyle* style)

+ 1 - 1
BansheeEngine/Source/BsGUIScrollBarHandle.cpp

@@ -210,7 +210,7 @@ namespace BansheeEngine
 
 			if(!handleMoved.empty())
 			{
-				float pct = maxScrollAmount / (float)mHandlePos;
+				float pct = (float)mHandlePos / maxScrollAmount;
 				handleMoved(pct);
 			}
 

+ 5 - 0
BansheeEngine/Source/BsGUIScrollBarVert.cpp

@@ -107,6 +107,11 @@ namespace BansheeEngine
 		mHandleBtn->setHandlePos(pct);
 	}
 
+	CM::UINT32 GUIScrollBarVert::getMaxHandleSize() const
+	{
+		return mHandleBtn->getMaxSize();
+	}
+
 	GUIScrollBarVert* GUIScrollBarVert::create(GUIWidget& parent, const GUIElementStyle* style)
 	{
 		if(style == nullptr)

+ 19 - 3
CamelotClient/CmEditorWindow.cpp

@@ -18,7 +18,7 @@
 #include "BsEngineGUI.h"
 #include "BsGUIArea.h"
 #include "BsGUITabbedTitleBar.h"
-#include "BsGUIScrollBarVert.h"
+#include "BsGUIScrollArea.h"
 
 using namespace CamelotFramework;
 using namespace BansheeEngine;
@@ -74,8 +74,24 @@ namespace BansheeEditor
 
 		layout.addElement(GUIInputBox::create(*mGUI));
 		layout.addElement(GUIInputBox::create(*mGUI, GUILayoutOptions::fixed(100, 100), true));
-		layout.addElement(GUIScrollBarVert::create(*mGUI));
-		
+
+		GUIScrollArea* scrollArea = GUIScrollArea::create(*mGUI);
+		layout.addElement(scrollArea);
+
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test A"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test B"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test C"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test D"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test E"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test F"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test G"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test H"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test I"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test J"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test K"));
+		scrollArea->getLayout().addElement(GUIButton::create(*mGUI, L"Test L"));
+
+
 		//GUIFlexibleSpace& space4 = otherLayout.addFlexibleSpace();
 		//otherLayout.addElement(mDbgLabel);
 

+ 0 - 3
Notes.txt

@@ -15,9 +15,6 @@ Reminders:
 	components. Therefore is there any purpose of having C++ only inspector parsing code?
   - When I'll be doing SRGB write make sure GUI textures are handled properly. Right now they are read in gamma space, and displayed
     as normal, but if I switch to SRGB write then gamma would be applied twice to those textures.
-  - Make editor background have a tileable pattern (see Mini paper app on my cell). Since tileable images wouldn't work with scale9grid, it should be an overlay over the solid background.
-    - Maybe use the background type I used for website in WebDIP?
-    - Use black with yellow-orange highlights (highlight = selected button, selected frame border, selected entry box, etc.)
   - Async callbacks. I'd like to be able to assign a callback to an async method, that will execute on the calling thread once the async operation is complete.
      - For example when setting PixelData for a cursor I need to get PixelData from a texture, which is an async operation, in which case I need to block the calling thread
 	   until I get the result. But I'd rather apply the result once render thread is finished.

+ 10 - 7
TODO.txt

@@ -14,6 +14,11 @@ GUIWidget::updateMeshes leaks. If I leave the game running I can see memory cont
  - Resizing from the left actually resizes the right side
  - Clipping areas outside of a widget (or GUIArea for that matter) are not set up at all
 
+Over the holidays:
+ - Get release mode working
+ - Profile code to see why it runs to slow in debug (AQTime probably)
+ - Window docking/undocking
+
 IMMEDIATE:
  - Clicking on a window to focus and immediately trying to drag/resize it, doesn't work. I first need to click, then click again to drag/resize.
  - OpenGL rendering slows to extremely with time (seems to be related to rendering, possibly GUI, possibly in general Pass/Material/Shader/PassParams)
@@ -25,16 +30,14 @@ IMMEDIATE:
     - Make sure GUI system uses a dummy texture if one isn't available
 	- SpriteTexture keeps a static reference to DUmmyTexture which I need to release before shutdown
 
+- Seems the mouse-over bounds aren't right on the Tab button (I can't select it if I mouse over the bottom part)
+- When clipping scrolled GUIButton the text doesn't seem to get clipped properly
+- Clicking on the scroll buttons does nothing
+- Clicking on the empty scroll area doesn't do anything
+- Handle size is not dynamic
 - Hover colors of the scroll bar are wrong
 - Add horizontal scrollbar
 
-For tomorrow:
-Add another "content" layout to GUIScrollBarVert
-OVerride updateLayoutElements
- - apply scroll offset(s) (both horz and vertical)
- - remember last update layout width/height and adjust scroll handle size/position if it changed
-Ensure clip rects work as intended.
-
 TextBox needed elements:
  - Key-repeat? Pressing left/right/up/down arrows doesn't repeat the keys (also delete/backspace)
   - Add special text input commands, which will get repeatedly sent as long as their corresponding key is set in GUIManager