Răsfoiți Sursa

Just checking in because I'm about to delete some stuff

Marko Pintera 12 ani în urmă
părinte
comite
64b69f1fde

+ 10 - 3
BansheeEngine/Include/BsGUIInputBox.h

@@ -48,23 +48,29 @@ namespace BansheeEngine
 		virtual CM::UINT32 _getRenderElementDepth(CM::UINT32 renderElementIdx) const;
 		virtual void _setFocus(bool focus);
 	private:
+		// Sprites
 		ImageSprite* mImageSprite;
 		ImageSprite* mCaretSprite;
 		TextSprite* mTextSprite;
 		CM::Vector<ImageSprite*>::type mSelectionSprites;
-		CM::UINT32 mNumImageRenderElements;
 		bool mInputCursorSet;
 		bool mDragInProgress;
 		bool mIsMultiline;
 
+		IMAGE_SPRITE_DESC mImageDesc;
+		CM::WString mText;
+
+		// Selection & input caret
 		CM::UINT32 mSelectionStart;
 		CM::UINT32 mSelectionEnd;
 		CM::UINT32 mCaretPos;
 		bool mCaretShown;
 		bool mSelectionShown;
 
-		IMAGE_SPRITE_DESC mImageDesc;
-		CM::WString mText;
+		// Used for caret/selection and in general hit detection with specific chars
+		CM::Vector2* mTextVertices;
+		UINT32 mNumTextVertices;
+		UINT32 mTextLineHeight;
 
 		GUIInputBox(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions);
 
@@ -85,5 +91,6 @@ namespace BansheeEngine
 
 		CM::UINT32 getCharAtPosition(const CM::Int2& pos) const;
 		CM::Rect getTextBounds() const;
+		TEXT_SPRITE_DESC getTextDesc() const;
 	};
 }

+ 15 - 1
BansheeEngine/Include/BsTextSprite.h

@@ -43,6 +43,20 @@ namespace BansheeEngine
 
 		void update(const TEXT_SPRITE_DESC& desc);
 
-		static void getTextVertices(const TEXT_SPRITE_DESC& desc, CM::Vector2* vertices, CM::Vector2* uv = nullptr);
+		/**
+		 * @brief	Populates the provided buffer with vertices for the individual characters described
+		 * 			by the descriptor structure. Characters will be in the same position as if they were being drawn on
+		 * 			the screen using TextSprite directly.
+		 *
+		 * @param	desc				What text to get vertices for, what font, what size, etc.
+		 * @param   [out]	vertices	Pre-allocated array with enough space to hold all vertices.						
+		 *
+		 * @return	Number of text quads. (1 quad per character)
+		 * 			
+		 * @note	This method should be called twice. Once with "vertices" as nullptr to receive number
+		 * 			of quads you will need, then you should allocate the vertex array of enough size and
+		 * 			send it to the second call. (4 * numQuads)
+		 */
+		static UINT32 getTextVertices(const TEXT_SPRITE_DESC& desc, CM::Vector2* vertices);
 	};
 }

+ 47 - 24
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -24,9 +24,9 @@ namespace BansheeEngine
 	}
 
 	GUIInputBox::GUIInputBox(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions)
-		:GUIElement(parent, style, layoutOptions), mNumImageRenderElements(0), mInputCursorSet(false), mDragInProgress(false),
+		:GUIElement(parent, style, layoutOptions), mInputCursorSet(false), mDragInProgress(false),
 		mSelectionStart(0), mSelectionEnd(0), mCaretSprite(nullptr), mCaretShown(false), mSelectionShown(false), mCaretPos(0),
-		mIsMultiline(false)
+		mIsMultiline(false), mTextVertices(nullptr), mNumTextVertices(0), mTextLineHeight(0)
 	{
 		mImageSprite = cm_new<ImageSprite, PoolAlloc>();
 		mCaretSprite = cm_new<ImageSprite, PoolAlloc>();
@@ -122,21 +122,8 @@ namespace BansheeEngine
 
 		mImageSprite->update(mImageDesc);
 		mBounds = mImageSprite->getBounds();
-		mNumImageRenderElements = mImageSprite->getNumRenderElements();
-
-		TEXT_SPRITE_DESC textDesc;
-		textDesc.text = mText;
-		textDesc.font = mStyle->font;
-		textDesc.fontSize = mStyle->fontSize;
-
-		Rect textBounds = getTextBounds();
-		textDesc.offset = Int2(textBounds.x, textBounds.y);
-		textDesc.width = textBounds.width;
-		textDesc.height = textBounds.height;
-		textDesc.clipRect = Rect(0, 0, textDesc.width, textDesc.height);
-		textDesc.horzAlign = mStyle->textHorzAlign;
-		textDesc.vertAlign = mStyle->textVertAlign;
 
+		TEXT_SPRITE_DESC textDesc = getTextDesc();
 		mTextSprite->update(textDesc);
 
 		if(mCaretShown && GUIManager::instance().getCaretBlinkState())
@@ -467,16 +454,37 @@ namespace BansheeEngine
 
 	UINT32 GUIInputBox::getCharAtPosition(const Int2& pos) const
 	{
-		Rect textBounds = getTextBounds();
+		TEXT_SPRITE_DESC textDesc = getTextDesc();
+		UINT32 numQuads = TextSprite::getTextVertices(textDesc, nullptr);
 
-		//std::shared_ptr<TextUtility::TextData> textData = 
-		//	TextUtility::getTextData(mText, mStyle->font, mStyle->fontSize, 
-		//	textBounds.width, textBounds.height, mIsMultiline);
+		if(numQuads == 0)
+			return 0;
 
-		//textData->getLines()
+		Vector2* vertices = (Vector2*)cm_alloc(numQuads * 4 * sizeof(Vector2));
+		TextSprite::getTextVertices(textDesc, vertices);
 
-		// TODO
-		return 0;
+		Vector2 vecPos((float)pos.x, (float)pos.y);
+
+		float nearestDist = std::numeric_limits<float>::max();
+		UINT32 nearestChar = 0;
+		for(UINT32 i = 0; i < numQuads; i++)
+		{
+			UINT32 curVert = i * 4;
+
+			Vector2 center = vertices[curVert + 0] + vertices[curVert + 1] + vertices[curVert + 2] + vertices[curVert + 3];
+			center /= 4;
+
+			float dist = center.squaredDistance(vecPos);
+			if(dist < nearestDist)
+			{
+				nearestChar = i;
+				nearestDist = dist;
+			}
+		}
+
+		cm_free(vertices);
+
+		return nearestChar;
 	}
 
 	CM::Rect GUIInputBox::getTextBounds() const
@@ -490,10 +498,25 @@ namespace BansheeEngine
 		textBounds.height = (UINT32)std::max(0, (INT32)textBounds.height - 
 			(INT32)(mStyle->margins.top + mStyle->margins.bottom + mStyle->contentOffset.top + mStyle->contentOffset.bottom));
 
-
 		return textBounds;
 	}
 
+	TEXT_SPRITE_DESC GUIInputBox::getTextDesc() const
+	{
+		TEXT_SPRITE_DESC textDesc;
+		textDesc.text = mText;
+		textDesc.font = mStyle->font;
+		textDesc.fontSize = mStyle->fontSize;
+
+		Rect textBounds = getTextBounds();
+		textDesc.offset = Int2(textBounds.x, textBounds.y);
+		textDesc.width = textBounds.width;
+		textDesc.height = textBounds.height;
+		textDesc.clipRect = Rect(0, 0, textDesc.width, textDesc.height);
+		textDesc.horzAlign = mStyle->textHorzAlign;
+		textDesc.vertAlign = mStyle->textVertAlign;
+	}
+
 	void GUIInputBox::_setFocus(bool focus)
 	{
 		if(focus)

+ 18 - 17
BansheeEngine/Source/BsSprite.cpp

@@ -180,37 +180,38 @@ namespace BansheeEngine
 			float newLeft = Math::Clamp(vertices[vertIdx + 0].x, left, right);
 			float uvLeftOffset = (newLeft - vertices[vertIdx + 0].x) * du;
 
-			vertices[vertIdx + 0].x = newLeft;
-			vertices[vertIdx + 2].x = newLeft;
-			uv[vertIdx + 0].x += uvLeftOffset;
-			uv[vertIdx + 2].x += uvLeftOffset;
-
 			// Clip right
 			float newRight = Math::Clamp(vertices[vertIdx + 1].x, left, right);
 			float uvRightOffset = (vertices[vertIdx + 1].x - newRight) * du;
 
-			vertices[vertIdx + 1].x = newRight;
-			vertices[vertIdx + 3].x = newRight;
-			uv[vertIdx + 1].x -= uvRightOffset;
-			uv[vertIdx + 3].x -= uvRightOffset;
-
 			// Clip top
 			float newTop = Math::Clamp(vertices[vertIdx + 0].y, top, bottom);
 			float uvTopOffset = (newTop - vertices[vertIdx + 0].y) * dv;
 
-			vertices[vertIdx + 0].y = newTop;
-			vertices[vertIdx + 1].y = newTop;
-			uv[vertIdx + 0].y += uvTopOffset;
-			uv[vertIdx + 1].y += uvTopOffset;
-
 			// Clip bottom
 			float newBottom = Math::Clamp(vertices[vertIdx + 2].y, top, bottom);
 			float uvBottomOffset = (vertices[vertIdx + 2].y - newBottom) * dv;
 
+			vertices[vertIdx + 0].x = newLeft;
+			vertices[vertIdx + 2].x = newLeft;
+			vertices[vertIdx + 1].x = newRight;
+			vertices[vertIdx + 3].x = newRight;
+			vertices[vertIdx + 0].y = newTop;
+			vertices[vertIdx + 1].y = newTop;
 			vertices[vertIdx + 2].y = newBottom;
 			vertices[vertIdx + 3].y = newBottom;
-			uv[vertIdx + 2].y -= uvBottomOffset;
-			uv[vertIdx + 3].y -= uvBottomOffset;
+			
+			if(uv != nullptr)
+			{
+				uv[vertIdx + 0].x += uvLeftOffset;
+				uv[vertIdx + 2].x += uvLeftOffset;
+				uv[vertIdx + 1].x -= uvRightOffset;
+				uv[vertIdx + 3].x -= uvRightOffset;
+				uv[vertIdx + 0].y += uvTopOffset;
+				uv[vertIdx + 1].y += uvTopOffset;
+				uv[vertIdx + 2].y -= uvBottomOffset;
+				uv[vertIdx + 3].y -= uvBottomOffset;
+			}
 		}
 	}
 }

+ 9 - 4
BansheeEngine/Source/BsTextSprite.cpp

@@ -164,12 +164,12 @@ namespace BansheeEngine
 		updateBounds();
 	}
 
-	void TextSprite::getTextVertices(const TEXT_SPRITE_DESC& desc, CM::Vector2* vertices, CM::Vector2* uvs)
+	UINT32 TextSprite::getTextVertices(const TEXT_SPRITE_DESC& desc, CM::Vector2* vertices)
 	{
 		std::shared_ptr<TextUtility::TextData> textData = TextUtility::getTextData(desc.text, desc.font, desc.fontSize, desc.width, desc.height, desc.wordWrap);
 
 		if(textData == nullptr)
-			return;
+			return 0;
 
 		const CM::Vector<TextUtility::TextLine>::type& lines = textData->getLines();
 		const CM::Vector<UINT32>::type& quadsPerPage = textData->getNumQuadsPerPage();
@@ -178,6 +178,9 @@ namespace BansheeEngine
 		for(auto& quads : quadsPerPage)
 			numQuads += quads;
 
+		if(vertices == nullptr)
+			return numQuads;
+
 		UINT32 curHeight = 0;
 		for(auto& line : lines)
 			curHeight += line.getYOffset();
@@ -225,7 +228,7 @@ namespace BansheeEngine
 			for(size_t j = 0; j < numPages; j++)
 			{
 				// TODO - fillBuffer won't accept null uv or indexes
-				UINT32 writtenQuads = lines[i].fillBuffer((UINT32)j, vertices, uvs, nullptr, quadOffset, numQuads);
+				UINT32 writtenQuads = lines[i].fillBuffer((UINT32)j, vertices, nullptr, nullptr, quadOffset, numQuads);
 
 				UINT32 numVertices = writtenQuads * 4;
 				for(size_t i = 0; i < numVertices; i++)
@@ -240,7 +243,7 @@ namespace BansheeEngine
 
 		if(desc.clipRect.width > 0 && desc.clipRect.height > 0)
 		{
-			clipToRect(vertices, uvs, numQuads, desc.clipRect);
+			clipToRect(vertices, nullptr, numQuads, desc.clipRect);
 		}
 
 		// Apply offset
@@ -252,5 +255,7 @@ namespace BansheeEngine
 				vertices[i].y += (float)desc.offset.y;
 			}
 		}
+
+		return numQuads;
 	}
 }