浏览代码

Input caret now works fine with spaces

Marko Pintera 12 年之前
父节点
当前提交
ab0d77dfe6

+ 9 - 0
BansheeEngine/Include/BsGUIButtonEvent.h

@@ -17,10 +17,15 @@ namespace BansheeEngine
 	{
 	public:
 		GUIButtonEvent();
+		GUIButtonEvent(bool shift, bool ctrl, bool alt);
 
 		GUIKeyEventType getType() const { return mType; }
 		CM::ButtonCode getKey() const { return mKey; }
 		const CM::UINT32& getInputChar() const { return mInputChar; }
+
+		bool isShiftDown() const { return mShift; }
+		bool isCtrlDown() const { return mCtrl; }
+		bool isAltDown() const { return mAlt; }
 	private:
 		friend class GUIManager;
 
@@ -28,6 +33,10 @@ namespace BansheeEngine
 		CM::ButtonCode mKey;
 		CM::UINT32 mInputChar;
 
+		bool mShift;
+		bool mCtrl;
+		bool mAlt;
+
 		void setKeyDownData(CM::ButtonCode key);
 		void setKeyUpData(CM::ButtonCode key);
 		void setTextInputData(CM::UINT32 inputChar);

+ 7 - 1
BansheeEngine/Source/BsGUIButtonEvent.cpp

@@ -5,7 +5,13 @@ using namespace CamelotFramework;
 namespace BansheeEngine
 {
 	GUIButtonEvent::GUIButtonEvent()
-		:mType(GUIKeyEventType::KeyDown), mKey(BC_0)
+		:mType(GUIKeyEventType::KeyDown), mKey(BC_0), mShift(false), mCtrl(false), mAlt(false)
+	{
+
+	}
+
+	GUIButtonEvent::GUIButtonEvent(bool shift, bool ctrl, bool alt)
+		:mType(GUIKeyEventType::KeyDown), mKey(BC_0), mShift(shift), mCtrl(ctrl), mAlt(alt)
 	{
 
 	}

+ 21 - 15
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -383,26 +383,32 @@ namespace BansheeEngine
 			
 			if(ev.getKey() == BC_LEFT)
 			{
-				//if(gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT))
-				//{
-
-				//}
-				//else
-				//{
-
-				//}
-				mCaretPos = (UINT32)std::max(0, (INT32)mCaretPos - 1);
+				if(ev.isShiftDown())
+				{
+					// TODO
+				}
+				else
+				{
+					mCaretPos = (UINT32)std::max(0, (INT32)mCaretPos - 1);
 
-				markAsDirty();
-				return true;
+					markAsDirty();
+					return true;
+				}
 			}
 
 			if(ev.getKey() == BC_RIGHT)
 			{
-				mCaretPos = std::min((UINT32)mText.size(), mCaretPos + 1);
+				if(ev.isShiftDown())
+				{
+					// TODO
+				}
+				else
+				{
+					mCaretPos = std::min((UINT32)mText.size(), mCaretPos + 1);
 
-				markAsDirty();
-				return true;
+					markAsDirty();
+					return true;
+				}
 			}
 
 			if(ev.getKey() == BC_RETURN)
@@ -477,7 +483,7 @@ namespace BansheeEngine
 		}
 		else
 		{
-			Rect contentBounds = getContentBounds();
+			Rect contentBounds = getTextBounds();
 			return Int2(contentBounds.x, contentBounds.y);
 		}		
 	}

+ 10 - 2
BansheeEngine/Source/BsGUIManager.cpp

@@ -493,7 +493,11 @@ namespace BansheeEngine
 		{
 			if(mKeyboardFocusElement != nullptr)
 			{
-				mKeyEvent = GUIButtonEvent();
+				bool shiftDown = gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT);
+				bool ctrlDown = gInput().isButtonDown(BC_LCONTROL) || gInput().isButtonDown(BC_RCONTROL);
+				bool altDown = gInput().isButtonDown(BC_LMENU) || gInput().isButtonDown(BC_RMENU);
+
+				mKeyEvent = GUIButtonEvent(shiftDown, ctrlDown, altDown);
 
 				mKeyEvent.setKeyDownData(event.buttonCode);
 				mKeyboardFocusWidget->_keyEvent(mKeyboardFocusElement, mKeyEvent);
@@ -757,7 +761,11 @@ namespace BansheeEngine
 	{
 		if(mKeyboardFocusElement != nullptr)
 		{
-			mKeyEvent = GUIButtonEvent();
+			bool shiftDown = gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT);
+			bool ctrlDown = gInput().isButtonDown(BC_LCONTROL) || gInput().isButtonDown(BC_RCONTROL);
+			bool altDown = gInput().isButtonDown(BC_LMENU) || gInput().isButtonDown(BC_RMENU);
+
+			mKeyEvent = GUIButtonEvent(shiftDown, ctrlDown, altDown);
 
 			mKeyEvent.setTextInputData(event.textChar);
 			mKeyboardFocusWidget->_keyEvent(mKeyboardFocusElement, mKeyEvent);

+ 61 - 4
CamelotCore/Source/CmTextUtility.cpp

@@ -168,6 +168,8 @@ namespace CamelotFramework
 					quadsPerPage[charIter->page]++;
 				}
 			}
+			else
+				quadsPerPage[0]++;
 		}
 
 		return quadsPerPage;
@@ -182,6 +184,48 @@ namespace CamelotFramework
 		{
 			if(wordIter->isSpacer())
 			{
+				// We store invisible space quads in the first page. Even though they aren't needed
+				// for rendering and we could just leave an empty space, they are needed for intersection tests
+				// for things like determining caret placement and selection areas
+				if(page == 0) 
+				{
+					INT32 curX = penX;
+					INT32 curY = 0;
+
+					UINT32 curVert = offset * 4;
+					UINT32 curIndex = offset * 6;
+
+					vertices[curVert + 0] = Vector2((float)curX, (float)curY);
+					vertices[curVert + 1] = Vector2((float)(curX + mSpaceWidth), (float)curY);
+					vertices[curVert + 2] = Vector2((float)curX, (float)curY + (float)mLineHeight);
+					vertices[curVert + 3] = Vector2((float)(curX + mSpaceWidth), (float)curY + (float)mLineHeight);
+
+					if(uvs != nullptr)
+					{
+						uvs[curVert + 0] = Vector2(0.0f, 0.0f);
+						uvs[curVert + 1] = Vector2(0.0f, 0.0f);
+						uvs[curVert + 2] = Vector2(0.0f, 0.0f);
+						uvs[curVert + 3] = Vector2(0.0f, 0.0f);
+					}
+
+					// Triangles are back-facing which makes them invisible
+					if(indexes != nullptr)
+					{
+						indexes[curIndex + 0] = curVert + 0;
+						indexes[curIndex + 1] = curVert + 2;
+						indexes[curIndex + 2] = curVert + 1;
+						indexes[curIndex + 3] = curVert + 1;
+						indexes[curIndex + 4] = curVert + 2;
+						indexes[curIndex + 5] = curVert + 3;
+					}
+
+					offset++;
+					numQuads++;
+
+					if(offset > size)
+						CM_EXCEPT(InternalErrorException, "Out of buffer bounds. Buffer size: " + toString(size));
+				}
+
 				penX += mSpaceWidth;
 			}
 			else
@@ -255,9 +299,9 @@ namespace CamelotFramework
 		for(auto& word : mWords)
 		{
 			if(word.isSpacer())
-				continue;
-
-			numChars += (UINT32)word.getChars().size();
+				numChars++;
+			else
+				numChars += (UINT32)word.getChars().size();
 		}
 
 		return numChars;
@@ -287,7 +331,7 @@ namespace CamelotFramework
 			fontData = font->getFontDataForSize(nearestSize);
 		}
 
-		if(fontData == nullptr)
+		if(fontData == nullptr || fontData->texturePages.size() == 0)
 			return nullptr;
 
 		if(fontData->size != fontSize)
@@ -343,8 +387,21 @@ namespace CamelotFramework
 					textData->mTexturePages[charDesc.page] = fontData->texturePages[charDesc.page];
 			}
 			else
+			{
 				curLine->addSpace();
 
+				if((UINT32)textData->mQuadsPerPage.size() == 0)
+				{
+					textData->mQuadsPerPage.resize(1);
+					textData->mTexturePages.resize(1);
+				}
+
+				textData->mQuadsPerPage[0]++;
+
+				if(textData->mTexturePages[0] == nullptr)
+					textData->mTexturePages[0] = fontData->texturePages[0];
+			}
+
 			if(widthIsLimited && curLine->getWidth() > width)
 			{
 				if(wordWrap)