Procházet zdrojové kódy

Fixed drop down scroll up and down button graphic
Fixed invalid drop down sub-menu width
Added depth to submenus
Fixed an issue where scroll down button was appearing when not needed

Marko Pintera před 12 roky
rodič
revize
9ac4938fd7

+ 0 - 1
BansheeEngine.sln

@@ -46,7 +46,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 		Notes.txt = Notes.txt
 		Notes.txt = Notes.txt
 		RenderOperation.txt = RenderOperation.txt
 		RenderOperation.txt = RenderOperation.txt
 		TODO.txt = TODO.txt
 		TODO.txt = TODO.txt
-		TODO_2D_GUI.txt = TODO_2D_GUI.txt
 		TODODoc.txt = TODODoc.txt
 		TODODoc.txt = TODODoc.txt
 		TODOEditor.txt = TODOEditor.txt
 		TODOEditor.txt = TODOEditor.txt
 	EndProjectSection
 	EndProjectSection

+ 3 - 0
BansheeEngine/Include/BsEngineGUI.h

@@ -80,7 +80,10 @@ namespace BansheeEngine
 		static const CM::String DropDownBoxEntryHoverTex;
 		static const CM::String DropDownBoxEntryHoverTex;
 
 
 		static const CM::String DropDownBoxBtnUpNormalTex;
 		static const CM::String DropDownBoxBtnUpNormalTex;
+		static const CM::String DropDownBoxBtnUpHoverTex;
+
 		static const CM::String DropDownBoxBtnDownNormalTex;
 		static const CM::String DropDownBoxBtnDownNormalTex;
+		static const CM::String DropDownBoxBtnDownHoverTex;
 
 
 		static const CM::String DropDownBoxEntryExpNormalTex;
 		static const CM::String DropDownBoxEntryExpNormalTex;
 		static const CM::String DropDownBoxEntryExpHoverTex;
 		static const CM::String DropDownBoxEntryExpHoverTex;

+ 2 - 1
BansheeEngine/Include/BsGUIDropDownBox.h

@@ -116,6 +116,7 @@ namespace BansheeEngine
 			CM::INT32 x, y;
 			CM::INT32 x, y;
 			CM::UINT32 width, height;
 			CM::UINT32 width, height;
 			CM::Rect mAvailableBounds;
 			CM::Rect mAvailableBounds;
+			CM::UINT32 mDepthOffset;
 			bool mOpenedUpward;
 			bool mOpenedUpward;
 
 
 			CM::Vector<GUITexture*>::type mCachedSeparators;
 			CM::Vector<GUITexture*>::type mCachedSeparators;
@@ -132,7 +133,7 @@ namespace BansheeEngine
 			DropDownSubMenu* mSubMenu;
 			DropDownSubMenu* mSubMenu;
 
 
 			DropDownSubMenu(GUIDropDownBox* owner, const GUIDropDownAreaPlacement& placement, 
 			DropDownSubMenu(GUIDropDownBox* owner, const GUIDropDownAreaPlacement& placement, 
-				const CM::Rect& availableBounds, const CM::Vector<GUIDropDownData>::type& elements, GUIDropDownType type);
+				const CM::Rect& availableBounds, const CM::Vector<GUIDropDownData>::type& elements, GUIDropDownType type, CM::UINT32 depthOffset);
 			~DropDownSubMenu();
 			~DropDownSubMenu();
 
 
 			void updateGUIElements();
 			void updateGUIElements();

+ 7 - 2
BansheeEngine/Source/BsEngineGUI.cpp

@@ -78,7 +78,10 @@ namespace BansheeEngine
 	const String EngineGUI::DropDownBoxEntryHoverTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownButtonHover.psd";
 	const String EngineGUI::DropDownBoxEntryHoverTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownButtonHover.psd";
 
 
 	const String EngineGUI::DropDownBoxBtnUpNormalTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownBoxBtnUpNormal.psd";
 	const String EngineGUI::DropDownBoxBtnUpNormalTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownBoxBtnUpNormal.psd";
+	const String EngineGUI::DropDownBoxBtnUpHoverTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownBoxBtnUpHover.psd";
+
 	const String EngineGUI::DropDownBoxBtnDownNormalTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownBoxBtnDownNormal.psd";
 	const String EngineGUI::DropDownBoxBtnDownNormalTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownBoxBtnDownNormal.psd";
+	const String EngineGUI::DropDownBoxBtnDownHoverTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownBoxBtnDownHover.psd";
 
 
 	const String EngineGUI::DropDownBoxEntryExpNormalTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownExpNormal.psd";
 	const String EngineGUI::DropDownBoxEntryExpNormalTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownExpNormal.psd";
 	const String EngineGUI::DropDownBoxEntryExpHoverTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownExpHover.psd";
 	const String EngineGUI::DropDownBoxEntryExpHoverTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\DropDownExpHover.psd";
@@ -478,10 +481,11 @@ namespace BansheeEngine
 
 
 		// DropDown scroll up button
 		// DropDown scroll up button
 		HTexture dropDownBtnScrollUpNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnUpNormalTex));
 		HTexture dropDownBtnScrollUpNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnUpNormalTex));
+		HTexture dropDownBtnScrollUpHover = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnUpHoverTex));
 
 
 		GUIElementStyle dropDownScrollUpBtnStyle;
 		GUIElementStyle dropDownScrollUpBtnStyle;
 		dropDownScrollUpBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownBtnScrollUpNormal));
 		dropDownScrollUpBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownBtnScrollUpNormal));
-		dropDownScrollUpBtnStyle.hover.texture = dropDownScrollUpBtnStyle.normal.texture;
+		dropDownScrollUpBtnStyle.hover.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownBtnScrollUpHover));
 		dropDownScrollUpBtnStyle.active.texture = dropDownScrollUpBtnStyle.hover.texture;
 		dropDownScrollUpBtnStyle.active.texture = dropDownScrollUpBtnStyle.hover.texture;
 		dropDownScrollUpBtnStyle.fixedHeight = true;
 		dropDownScrollUpBtnStyle.fixedHeight = true;
 		dropDownScrollUpBtnStyle.fixedWidth = false;
 		dropDownScrollUpBtnStyle.fixedWidth = false;
@@ -518,10 +522,11 @@ namespace BansheeEngine
 
 
 		// DropDown scroll down button
 		// DropDown scroll down button
 		HTexture dropDownBtnScrollDownNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnDownNormalTex));
 		HTexture dropDownBtnScrollDownNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnDownNormalTex));
+		HTexture dropDownBtnScrollDownHover = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnDownHoverTex));
 
 
 		GUIElementStyle dropDownScrollDownBtnStyle;
 		GUIElementStyle dropDownScrollDownBtnStyle;
 		dropDownScrollDownBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownBtnScrollDownNormal));
 		dropDownScrollDownBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownBtnScrollDownNormal));
-		dropDownScrollDownBtnStyle.hover.texture = dropDownScrollDownBtnStyle.normal.texture;
+		dropDownScrollDownBtnStyle.hover.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownBtnScrollDownHover));
 		dropDownScrollDownBtnStyle.active.texture = dropDownScrollDownBtnStyle.hover.texture;
 		dropDownScrollDownBtnStyle.active.texture = dropDownScrollDownBtnStyle.hover.texture;
 		dropDownScrollDownBtnStyle.fixedHeight = true;
 		dropDownScrollDownBtnStyle.fixedHeight = true;
 		dropDownScrollDownBtnStyle.fixedWidth = false;
 		dropDownScrollDownBtnStyle.fixedWidth = false;

+ 23 - 12
BansheeEngine/Source/BsGUIDropDownBox.cpp

@@ -98,14 +98,14 @@ namespace BansheeEngine
 		mSeparatorStyle = skin.getStyle(stylePrefix + "Separator");
 		mSeparatorStyle = skin.getStyle(stylePrefix + "Separator");
 		mBackgroundStyle = skin.getStyle(stylePrefix + "Frame");
 		mBackgroundStyle = skin.getStyle(stylePrefix + "Frame");
 
 
-		mScrollUpBtnArrow = skin.getStyle("ScrollUpBtnArrow")->normal.texture;
-		mScrollDownBtnArrow = skin.getStyle("ScrollDownBtnArrow")->normal.texture;
+		mScrollUpBtnArrow = skin.getStyle(stylePrefix + "ScrollUpBtnArrow")->normal.texture;
+		mScrollDownBtnArrow = skin.getStyle(stylePrefix + "ScrollDownBtnArrow")->normal.texture;
 
 
 		setDepth(0); // Needs to be in front of everything
 		setDepth(0); // Needs to be in front of everything
 		setSkin(skin);
 		setSkin(skin);
 
 
 		Rect availableBounds(target->getLeft(), target->getTop(), target->getWidth(), target->getHeight());
 		Rect availableBounds(target->getLeft(), target->getTop(), target->getWidth(), target->getHeight());
-		mRootMenu = cm_new<DropDownSubMenu>(this, placement, availableBounds, elements, type);
+		mRootMenu = cm_new<DropDownSubMenu>(this, placement, availableBounds, elements, type, 0);
 	}
 	}
 
 
 	GUIDropDownBox::~GUIDropDownBox()
 	GUIDropDownBox::~GUIDropDownBox()
@@ -114,10 +114,10 @@ namespace BansheeEngine
 	}
 	}
 
 
 	GUIDropDownBox::DropDownSubMenu::DropDownSubMenu(GUIDropDownBox* owner, const GUIDropDownAreaPlacement& placement, 
 	GUIDropDownBox::DropDownSubMenu::DropDownSubMenu(GUIDropDownBox* owner, const GUIDropDownAreaPlacement& placement, 
-		const Rect& availableBounds, const CM::Vector<GUIDropDownData>::type& elements, GUIDropDownType type)
+		const Rect& availableBounds, const CM::Vector<GUIDropDownData>::type& elements, GUIDropDownType type, UINT32 depthOffset)
 		:mOwner(owner), mPage(0), mBackgroundFrame(nullptr), mBackgroundArea(nullptr), mContentArea(nullptr), 
 		:mOwner(owner), mPage(0), mBackgroundFrame(nullptr), mBackgroundArea(nullptr), mContentArea(nullptr), 
 		mContentLayout(nullptr), mScrollUpBtn(nullptr), mScrollDownBtn(nullptr), x(0), y(0), width(0), height(0), 
 		mContentLayout(nullptr), mScrollUpBtn(nullptr), mScrollDownBtn(nullptr), x(0), y(0), width(0), height(0), 
-		mType(type), mSubMenu(nullptr), mElements(elements), mOpenedUpward(false)
+		mType(type), mSubMenu(nullptr), mElements(elements), mOpenedUpward(false), mDepthOffset(depthOffset)
 	{
 	{
 		mAvailableBounds = availableBounds;
 		mAvailableBounds = availableBounds;
 
 
@@ -153,19 +153,24 @@ namespace BansheeEngine
 
 
 		//// Prefer right if possible
 		//// Prefer right if possible
 		if(DROP_DOWN_BOX_WIDTH <= availableRightwardWidth)
 		if(DROP_DOWN_BOX_WIDTH <= availableRightwardWidth)
+		{
 			x = potentialRightStart;
 			x = potentialRightStart;
+			width = DROP_DOWN_BOX_WIDTH;
+		}
 		else
 		else
 		{
 		{
 			if(availableRightwardWidth >= availableLeftwardWidth)
 			if(availableRightwardWidth >= availableLeftwardWidth)
+			{
 				x = potentialRightStart;
 				x = potentialRightStart;
+				width = std::min(DROP_DOWN_BOX_WIDTH, availableRightwardWidth);
+			}
 			else
 			else
+			{
 				x = potentialLeftStart - std::min(DROP_DOWN_BOX_WIDTH, availableLeftwardWidth);
 				x = potentialLeftStart - std::min(DROP_DOWN_BOX_WIDTH, availableLeftwardWidth);
+				width = std::min(DROP_DOWN_BOX_WIDTH, availableLeftwardWidth);
+			}
 		}
 		}
 
 
-		// Determine maximum width
-		UINT32 maxPossibleWidth = (UINT32)std::max(0, (availableBounds.x + availableBounds.width) - x);
-		width = std::min(DROP_DOWN_BOX_WIDTH, maxPossibleWidth);
-
 		// Determine y position and whether to open upward or downward
 		// Determine y position and whether to open upward or downward
 		UINT32 availableDownwardHeight = (UINT32)std::max(0, (availableBounds.y + availableBounds.height) - potentialBottomStart);
 		UINT32 availableDownwardHeight = (UINT32)std::max(0, (availableBounds.y + availableBounds.height) - potentialBottomStart);
 		UINT32 availableUpwardHeight = (UINT32)std::max(0, potentialTopStart - availableBounds.y);
 		UINT32 availableUpwardHeight = (UINT32)std::max(0, potentialTopStart - availableBounds.y);
@@ -209,11 +214,12 @@ namespace BansheeEngine
 
 
 		// Content area
 		// Content area
 		mContentArea = GUIArea::create(*mOwner, x, actualY, width, height);
 		mContentArea = GUIArea::create(*mOwner, x, actualY, width, height);
+		mContentArea->setDepth(10000 - depthOffset * 2 - 1);
 		mContentLayout = &mContentArea->getLayout().addLayoutY();
 		mContentLayout = &mContentArea->getLayout().addLayoutY();
 
 
 		// Background frame
 		// Background frame
 		mBackgroundArea = GUIArea::create(*mOwner, x, actualY, width, height);
 		mBackgroundArea = GUIArea::create(*mOwner, x, actualY, width, height);
-		mBackgroundArea->setDepth(102);
+		mBackgroundArea->setDepth(10000 - depthOffset * 2);
 
 
 		mBackgroundFrame = GUITexture::create(*mOwner, GUIImageScaleMode::StretchToFit, mOwner->mBackgroundStyle);
 		mBackgroundFrame = GUITexture::create(*mOwner, GUIImageScaleMode::StretchToFit, mOwner->mBackgroundStyle);
 		mBackgroundArea->getLayout().addElement(mBackgroundFrame);
 		mBackgroundArea->getLayout().addElement(mBackgroundFrame);
@@ -269,7 +275,6 @@ namespace BansheeEngine
 			if(usedHeight > height)
 			if(usedHeight > height)
 			{
 			{
 				usedHeight += mOwner->mScrollDownStyle->height;
 				usedHeight += mOwner->mScrollDownStyle->height;
-				needsScrollDown = true;
 
 
 				// Remove last few elements until we fit again
 				// Remove last few elements until we fit again
 				while(usedHeight > height && i >= 0)
 				while(usedHeight > height && i >= 0)
@@ -282,11 +287,17 @@ namespace BansheeEngine
 
 
 				// We found our page and are done
 				// We found our page and are done
 				if(curPage == mPage)
 				if(curPage == mPage)
+				{
+					needsScrollDown = i != (numElements - 1);
 					break;
 					break;
+				}
 
 
 				// Nothing fits, break out of infinite loop
 				// Nothing fits, break out of infinite loop
 				if(pageStart == pageEnd)
 				if(pageStart == pageEnd)
+				{
+					needsScrollDown = i != (numElements - 1);
 					break;
 					break;
+				}
 
 
 				pageStart = pageEnd;
 				pageStart = pageEnd;
 				usedHeight = mOwner->mBackgroundStyle->margins.top + mOwner->mBackgroundStyle->margins.bottom;
 				usedHeight = mOwner->mBackgroundStyle->margins.top + mOwner->mBackgroundStyle->margins.bottom;
@@ -475,6 +486,6 @@ namespace BansheeEngine
 		closeSubMenu();
 		closeSubMenu();
 
 
 		mSubMenu = cm_new<DropDownSubMenu>(mOwner, GUIDropDownAreaPlacement::aroundBoundsVert(source->getBounds()), 
 		mSubMenu = cm_new<DropDownSubMenu>(mOwner, GUIDropDownAreaPlacement::aroundBoundsVert(source->getBounds()), 
-			mAvailableBounds, mElements[idx].getSubMenuEntries(), mType);
+			mAvailableBounds, mElements[idx].getSubMenuEntries(), mType, mDepthOffset + 1);
 	}
 	}
 }
 }

+ 3 - 1
DropDown.txt

@@ -1,6 +1,8 @@
 GUI ignores image in GUIContent for most elements.
 GUI ignores image in GUIContent for most elements.
 
 
-Context menu appears at the wrong coordinates
+When opening a sub-menu it might overlap its parent menu. e.g. opening a sub-menu to the left of the parent menu. 
+ - Sub-menu bounds should be limited so that they can't overlap.
+   - Nested overlap should be allowed to happen as long as the last menu is visible. This is why menus will also need proper depth.
 
 
 Test scrollUp/scrollDown
 Test scrollUp/scrollDown
  - Scroll up/down button arrows seem to be missing
  - Scroll up/down button arrows seem to be missing

+ 9 - 0
TODO.txt

@@ -9,6 +9,15 @@ GUIWidget::updateMeshes leaks. If I leave the game running I can see memory cont
  - BansheeApplication should probably derive from Camlelot application. Right now user needs to know the difference between 
  - BansheeApplication should probably derive from Camlelot application. Right now user needs to know the difference between 
    gApplication and gBansheeApp, which is non-intuitive (e.g. retrieving a window can be done on gApplication, but running main loop can happen on both
    gApplication and gBansheeApp, which is non-intuitive (e.g. retrieving a window can be done on gApplication, but running main loop can happen on both
 
 
+GUI SYSTEM WRAP UP:
+ Key repeat
+ Double click (Input box select all)
+ Copy/Cut/Paste shortcut keys
+ Copy/Cut/Past context menu
+ Clipboard
+ Windows drag and drop detect
+ Click when unfocused actually effects the elements in that window/widget
+
 IMMEDIATE:
 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.
  - 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)
  - OpenGL rendering slows to extremely with time (seems to be related to rendering, possibly GUI, possibly in general Pass/Material/Shader/PassParams)