Explorar o código

Checking in selection code before I redo it all

Marko Pintera %!s(int64=12) %!d(string=hai) anos
pai
achega
f61d880f0e
Modificáronse 2 ficheiros con 105 adicións e 39 borrados
  1. 8 0
      BansheeEngine/Include/BsGUIInputBox.h
  2. 97 39
      BansheeEngine/Source/BsGUIInputBox.cpp

+ 8 - 0
BansheeEngine/Include/BsGUIInputBox.h

@@ -8,6 +8,12 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	enum class SelectionDir
+	{
+		Left,
+		Right
+	};
+
 	class BS_EXPORT GUIInputBox : public GUIElement
 	class BS_EXPORT GUIInputBox : public GUIElement
 	{
 	{
 	public:
 	public:
@@ -84,6 +90,8 @@ namespace BansheeEngine
 
 
 		void showSelection(CM::UINT32 startChar);
 		void showSelection(CM::UINT32 startChar);
 		void clearSelection();
 		void clearSelection();
+		CM::UINT32 getCaretSelectionCharIdx(SelectionDir dir);
+		bool isNewlineChar(CM::UINT32 charIdx);
 		CM::Vector<CM::Rect>::type getSelectionRects() const;
 		CM::Vector<CM::Rect>::type getSelectionRects() const;
 
 
 		CM::Rect getTextBounds() const;
 		CM::Rect getTextBounds() const;

+ 97 - 39
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -437,23 +437,23 @@ namespace BansheeEngine
 				if(ev.isShiftDown())
 				if(ev.isShiftDown())
 				{
 				{
 					if(!mSelectionShown)
 					if(!mSelectionShown)
-						showSelection(mInputCaret->getCharIdxAtCaretPos());
+						showSelection(getCaretSelectionCharIdx(SelectionDir::Left));
 
 
-					bool isAtNewline = false;
+					mInputCaret->moveCaretLeft();
+					UINT32 charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
 
 
-					do 
+					if (isNewlineChar(charIdx) && mInputCaret->getCaretPos() > 0)
 					{
 					{
-						isAtNewline = mInputCaret->isCaretAtNewline();
 						mInputCaret->moveCaretLeft();
 						mInputCaret->moveCaretLeft();
-
-					} while (isAtNewline && mInputCaret->getCaretPos() > 0);
+						charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+					} 
 
 
 					scrollTextToCaret();
 					scrollTextToCaret();
 
 
 					if(mSelectionAnchor == mSelectionEnd)
 					if(mSelectionAnchor == mSelectionEnd)
-						mSelectionStart = std::max(0U, mInputCaret->getCharIdxAtCaretPos());
+						mSelectionStart = charIdx;
 					else
 					else
-						mSelectionEnd = std::max(0U, mInputCaret->getCharIdxAtCaretPos());
+						mSelectionEnd = charIdx;
 
 
 					markAsDirty();
 					markAsDirty();
 					return true;
 					return true;
@@ -474,23 +474,39 @@ namespace BansheeEngine
 				if(ev.isShiftDown())
 				if(ev.isShiftDown())
 				{
 				{
 					if(!mSelectionShown)
 					if(!mSelectionShown)
-						showSelection(mInputCaret->getCharIdxAtCaretPos());
-
-					mInputCaret->moveCaretRight();
+						showSelection(getCaretSelectionCharIdx(SelectionDir::Left));
 
 
-					UINT32 maxCaretPos = mInputCaret->getMaxCaretPos();
-					while (mInputCaret->isCaretAtNewline() && mInputCaret->getCaretPos() <= maxCaretPos)
+					if(mSelectionAnchor == mSelectionStart)
 					{
 					{
 						mInputCaret->moveCaretRight();
 						mInputCaret->moveCaretRight();
-					} 
+						UINT32 charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
 
 
-					scrollTextToCaret();
+						UINT32 maxCaretPos = mInputCaret->getMaxCaretPos();
+						if (isNewlineChar(getCaretSelectionCharIdx(SelectionDir::Right)) && mInputCaret->getCaretPos() <= maxCaretPos)
+						{
+							mInputCaret->moveCaretRight();
+							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+						} 
 
 
-					if(mSelectionAnchor == mSelectionStart)
-						mSelectionEnd = std::max(0U, mInputCaret->getCharIdxAtCaretPos());
+						mSelectionEnd = charIdx;
+					}
 					else
 					else
-						mSelectionStart = std::max(0U, mInputCaret->getCharIdxAtCaretPos());
+					{
+						mInputCaret->moveCaretRight();
+						UINT32 charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+
+						UINT32 maxCaretPos = mInputCaret->getMaxCaretPos();
+						if (isNewlineChar(charIdx) && mInputCaret->getCaretPos() <= maxCaretPos)
+						{
+							mInputCaret->moveCaretRight();
+							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+						} 
+
+						mSelectionStart = charIdx;
+					}
 						
 						
+					scrollTextToCaret();
+
 					markAsDirty();
 					markAsDirty();
 					return true;
 					return true;
 				}
 				}
@@ -689,6 +705,24 @@ namespace BansheeEngine
 		markAsDirty();
 		markAsDirty();
 	}
 	}
 
 
+	UINT32 GUIInputBox::getCaretSelectionCharIdx(SelectionDir dir)
+	{
+		UINT32 charIdx = mInputCaret->getCharIdxAtCaretPos();
+
+		if(dir == SelectionDir::Right)
+			charIdx = (UINT32)std::max(0, (INT32)(charIdx - 1));
+
+		return charIdx;
+	}
+
+	bool GUIInputBox::isNewlineChar(CM::UINT32 charIdx)
+	{
+		if(mText[charIdx] == '\n')
+			return true;
+
+		return false;
+	}
+
 	Vector<Rect>::type GUIInputBox::getSelectionRects() const
 	Vector<Rect>::type GUIInputBox::getSelectionRects() const
 	{
 	{
 		Vector<Rect>::type selectionRects;
 		Vector<Rect>::type selectionRects;
@@ -704,25 +738,38 @@ namespace BansheeEngine
 
 
 		{
 		{
 			const SpriteLineDesc& lineDesc = mTextSprite->getLineDesc(startLine);
 			const SpriteLineDesc& lineDesc = mTextSprite->getLineDesc(startLine);
-			Rect startChar = mTextSprite->getCharRect(mSelectionStart);
+			
+			UINT32 startCharIdx = mSelectionStart;
+
 			UINT32 endCharIdx = mSelectionEnd - 1;
 			UINT32 endCharIdx = mSelectionEnd - 1;
-			if(endCharIdx >= lineDesc.endChar && endCharIdx > 0)
-			{
+			if(startLine != endLine)
 				endCharIdx = lineDesc.endChar - 1;
 				endCharIdx = lineDesc.endChar - 1;
 
 
-				if(startLine != (mTextSprite->getNumLines() - 1) && endCharIdx > 0) // Ignore newline char
-					endCharIdx -= 1;
-			}
-			
-			Rect endChar = mTextSprite->getCharRect(endCharIdx);
+			if(startCharIdx != endCharIdx)
+			{
+				if(startCharIdx == (lineDesc.endChar - 1) && startCharIdx < ((UINT32)mText.size() - 1)) // Ignore newline char
+				{
+					if(startLine != (mTextSprite->getNumLines() - 1))
+						startCharIdx += 1;
+				}
 
 
-			Rect selectionRect;
-			selectionRect.x = startChar.x;
-			selectionRect.y = lineDesc.lineYStart;
-			selectionRect.height = lineDesc.lineHeight;
-			selectionRect.width = (endChar.x + endChar.width) - startChar.x;
+				if(endCharIdx == (lineDesc.endChar - 1) && endCharIdx > 0) // Ignore newline char
+				{
+					if(startLine != (mTextSprite->getNumLines() - 1))
+						endCharIdx -= 1;
+				}
 
 
-			selectionRects.push_back(selectionRect);
+				Rect startChar = mTextSprite->getCharRect(startCharIdx);
+				Rect endChar = mTextSprite->getCharRect(endCharIdx);
+
+				Rect selectionRect;
+				selectionRect.x = startChar.x;
+				selectionRect.y = lineDesc.lineYStart;
+				selectionRect.height = lineDesc.lineHeight;
+				selectionRect.width = (endChar.x + endChar.width) - startChar.x;
+
+				selectionRects.push_back(selectionRect);
+			}
 		}
 		}
 
 
 		for(UINT32 i = startLine + 1; i < endLine; i++)
 		for(UINT32 i = startLine + 1; i < endLine; i++)
@@ -731,12 +778,18 @@ namespace BansheeEngine
 			if(lineDesc.startChar == lineDesc.endChar)
 			if(lineDesc.startChar == lineDesc.endChar)
 				continue;
 				continue;
 
 
-			UINT32 endCharIdx = lineDesc.endChar;
+			UINT32 startCharIdx = lineDesc.startChar;
+			if(startCharIdx == (lineDesc.endChar - 1) && startCharIdx > 0) // Ignore newline char
+			{
+				startCharIdx -= 1;
+			}
+
+			UINT32 endCharIdx = lineDesc.endChar - 1;
 			if(endCharIdx > 0) // Ignore newline char
 			if(endCharIdx > 0) // Ignore newline char
 				endCharIdx -= 1;
 				endCharIdx -= 1;
 
 
 			Rect startChar = mTextSprite->getCharRect(lineDesc.startChar);
 			Rect startChar = mTextSprite->getCharRect(lineDesc.startChar);
-			Rect endChar = mTextSprite->getCharRect(lineDesc.endChar);
+			Rect endChar = mTextSprite->getCharRect(endCharIdx);
 
 
 			Rect selectionRect;
 			Rect selectionRect;
 			selectionRect.x = startChar.x;
 			selectionRect.x = startChar.x;
@@ -753,17 +806,22 @@ namespace BansheeEngine
 
 
 			if(lineDesc.startChar != lineDesc.endChar)
 			if(lineDesc.startChar != lineDesc.endChar)
 			{
 			{
-				UINT32 endCharIdx = mSelectionEnd - 1;
-				if(endCharIdx > 0) // Ignore newline char
+				UINT32 startCharIdx = lineDesc.startChar;
+				if(startCharIdx == (lineDesc.endChar - 1) && startCharIdx > 0) // Ignore newline char
 				{
 				{
-					endCharIdx -= 1;
+					if(startLine != (mTextSprite->getNumLines() - 1))
+						startCharIdx -= 1;
+				}
 
 
-					if(endLine != (mTextSprite->getNumLines() - 1) && endCharIdx > 0) // Ignore newline char
+				UINT32 endCharIdx = mSelectionEnd - 1;
+				if(endCharIdx == (lineDesc.endChar - 1) && endCharIdx > 0)
+				{
+					if(endLine != (mTextSprite->getNumLines() - 1)) // Ignore newline char
 						endCharIdx -= 1;
 						endCharIdx -= 1;
 				}
 				}
 
 
 				Rect startChar = mTextSprite->getCharRect(lineDesc.startChar);
 				Rect startChar = mTextSprite->getCharRect(lineDesc.startChar);
-				Rect endChar = mTextSprite->getCharRect(mSelectionEnd - 1);
+				Rect endChar = mTextSprite->getCharRect(endCharIdx);
 
 
 				Rect selectionRect;
 				Rect selectionRect;
 				selectionRect.x = startChar.x;
 				selectionRect.x = startChar.x;