Bläddra i källkod

Selection working without empty lines

Marko Pintera 12 år sedan
förälder
incheckning
993ba17623
3 ändrade filer med 77 tillägg och 60 borttagningar
  1. 2 2
      BansheeEngine/Include/BsGUIInputBox.h
  2. 75 57
      BansheeEngine/Source/BsGUIInputBox.cpp
  3. 0 1
      TODO.txt

+ 2 - 2
BansheeEngine/Include/BsGUIInputBox.h

@@ -90,8 +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::UINT32 getCaretSelectionCharIdx(SelectionDir dir) const;
+		bool isNewlineChar(CM::UINT32 charIdx) const;
 		CM::Vector<CM::Rect>::type getSelectionRects() const;
 		CM::Vector<CM::Rect>::type getSelectionRects() const;
 
 
 		CM::Rect getTextBounds() const;
 		CM::Rect getTextBounds() const;

+ 75 - 57
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -437,23 +437,46 @@ namespace BansheeEngine
 				if(ev.isShiftDown())
 				if(ev.isShiftDown())
 				{
 				{
 					if(!mSelectionShown)
 					if(!mSelectionShown)
-						showSelection(getCaretSelectionCharIdx(SelectionDir::Left));
+					{
+						if(isNewlineChar(getCaretSelectionCharIdx(SelectionDir::Right)))
+						{
+							mInputCaret->moveCaretLeft();
+						}
 
 
-					mInputCaret->moveCaretLeft();
-					UINT32 charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+						showSelection(getCaretSelectionCharIdx(SelectionDir::Left));
+					}
 
 
-					if (isNewlineChar(charIdx) && mInputCaret->getCaretPos() > 0)
+					if(mSelectionAnchor == mSelectionEnd)
 					{
 					{
 						mInputCaret->moveCaretLeft();
 						mInputCaret->moveCaretLeft();
-						charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
-					} 
+						UINT32 charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
 
 
-					scrollTextToCaret();
+						if (isNewlineChar(charIdx) && mInputCaret->getCaretPos() > 0)
+						{
+							mInputCaret->moveCaretLeft();
+							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+						} 
 
 
-					if(mSelectionAnchor == mSelectionEnd)
-						mSelectionStart = charIdx;
+						mSelectionStart = std::min(mSelectionEnd, charIdx);
+					}
 					else
 					else
-						mSelectionEnd = charIdx;
+					{
+						mInputCaret->moveCaretLeft();
+						UINT32 charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+
+						if (isNewlineChar(getCaretSelectionCharIdx(SelectionDir::Right)) && mInputCaret->getCaretPos() > 0)
+						{
+							mInputCaret->moveCaretLeft();
+							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
+						} 
+
+						mSelectionEnd = std::max(mSelectionStart, charIdx);
+					}
+
+					if(mSelectionStart == mSelectionEnd)
+						clearSelection();
+
+					scrollTextToCaret();
 
 
 					markAsDirty();
 					markAsDirty();
 					return true;
 					return true;
@@ -474,8 +497,15 @@ namespace BansheeEngine
 				if(ev.isShiftDown())
 				if(ev.isShiftDown())
 				{
 				{
 					if(!mSelectionShown)
 					if(!mSelectionShown)
-						showSelection(getCaretSelectionCharIdx(SelectionDir::Left));
+					{
+						if(isNewlineChar(getCaretSelectionCharIdx(SelectionDir::Left)))
+						{
+							mInputCaret->moveCaretRight();
+						}
 
 
+						showSelection(getCaretSelectionCharIdx(SelectionDir::Left));
+					}
+						
 					if(mSelectionAnchor == mSelectionStart)
 					if(mSelectionAnchor == mSelectionStart)
 					{
 					{
 						mInputCaret->moveCaretRight();
 						mInputCaret->moveCaretRight();
@@ -488,7 +518,7 @@ namespace BansheeEngine
 							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
 							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
 						} 
 						} 
 
 
-						mSelectionEnd = charIdx;
+						mSelectionEnd = std::max(mSelectionStart, charIdx);
 					}
 					}
 					else
 					else
 					{
 					{
@@ -502,9 +532,13 @@ namespace BansheeEngine
 							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
 							charIdx = getCaretSelectionCharIdx(SelectionDir::Left);
 						} 
 						} 
 
 
-						mSelectionStart = charIdx;
+
+						mSelectionStart = std::min(mSelectionEnd, charIdx);
 					}
 					}
-						
+
+					if(mSelectionStart == mSelectionEnd)
+						clearSelection();
+
 					scrollTextToCaret();
 					scrollTextToCaret();
 
 
 					markAsDirty();
 					markAsDirty();
@@ -705,7 +739,7 @@ namespace BansheeEngine
 		markAsDirty();
 		markAsDirty();
 	}
 	}
 
 
-	UINT32 GUIInputBox::getCaretSelectionCharIdx(SelectionDir dir)
+	UINT32 GUIInputBox::getCaretSelectionCharIdx(SelectionDir dir) const
 	{
 	{
 		UINT32 charIdx = mInputCaret->getCharIdxAtCaretPos();
 		UINT32 charIdx = mInputCaret->getCharIdxAtCaretPos();
 
 
@@ -715,7 +749,7 @@ namespace BansheeEngine
 		return charIdx;
 		return charIdx;
 	}
 	}
 
 
-	bool GUIInputBox::isNewlineChar(CM::UINT32 charIdx)
+	bool GUIInputBox::isNewlineChar(CM::UINT32 charIdx) const
 	{
 	{
 		if(mText[charIdx] == '\n')
 		if(mText[charIdx] == '\n')
 			return true;
 			return true;
@@ -743,47 +777,39 @@ namespace BansheeEngine
 
 
 			UINT32 endCharIdx = mSelectionEnd - 1;
 			UINT32 endCharIdx = mSelectionEnd - 1;
 			if(startLine != endLine)
 			if(startLine != endLine)
+			{
 				endCharIdx = lineDesc.endChar - 1;
 				endCharIdx = lineDesc.endChar - 1;
 
 
-			if(startCharIdx != endCharIdx)
-			{
-				if(startCharIdx == (lineDesc.endChar - 1) && startCharIdx < ((UINT32)mText.size() - 1)) // Ignore newline char
-				{
-					if(startLine != (mTextSprite->getNumLines() - 1))
-						startCharIdx += 1;
-				}
+				if(startLine != (mTextSprite->getNumLines() - 1) && endCharIdx > 0) // Ignore newline char
+					endCharIdx -= 1;
+			}
 
 
-				if(endCharIdx == (lineDesc.endChar - 1) && endCharIdx > 0) // Ignore newline char
-				{
-					if(startLine != (mTextSprite->getNumLines() - 1))
-						endCharIdx -= 1;
-				}
+#ifdef CM_DEBUG_MODE
+			if(isNewlineChar(startCharIdx))
+				CM_EXCEPT(InternalErrorException, "Selection marker placed on newline. That's not allowed");
 
 
-				Rect startChar = mTextSprite->getCharRect(startCharIdx);
-				Rect endChar = mTextSprite->getCharRect(endCharIdx);
+			if(isNewlineChar(endCharIdx))
+				CM_EXCEPT(InternalErrorException, "Selection marker placed on newline. That's not allowed");
+#endif
 
 
-				Rect selectionRect;
-				selectionRect.x = startChar.x;
-				selectionRect.y = lineDesc.lineYStart;
-				selectionRect.height = lineDesc.lineHeight;
-				selectionRect.width = (endChar.x + endChar.width) - startChar.x;
+			Rect startChar = mTextSprite->getCharRect(startCharIdx);
+			Rect endChar = mTextSprite->getCharRect(endCharIdx);
 
 
-				selectionRects.push_back(selectionRect);
-			}
+			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++)
 		{
 		{
 			const SpriteLineDesc& lineDesc = mTextSprite->getLineDesc(i);
 			const SpriteLineDesc& lineDesc = mTextSprite->getLineDesc(i);
-			if(lineDesc.startChar == lineDesc.endChar)
+			if(lineDesc.startChar == lineDesc.endChar || isNewlineChar(lineDesc.startChar))
 				continue;
 				continue;
 
 
-			UINT32 startCharIdx = lineDesc.startChar;
-			if(startCharIdx == (lineDesc.endChar - 1) && startCharIdx > 0) // Ignore newline char
-			{
-				startCharIdx -= 1;
-			}
-
 			UINT32 endCharIdx = lineDesc.endChar - 1;
 			UINT32 endCharIdx = lineDesc.endChar - 1;
 			if(endCharIdx > 0) // Ignore newline char
 			if(endCharIdx > 0) // Ignore newline char
 				endCharIdx -= 1;
 				endCharIdx -= 1;
@@ -804,21 +830,13 @@ namespace BansheeEngine
 		{
 		{
 			const SpriteLineDesc& lineDesc = mTextSprite->getLineDesc(endLine);
 			const SpriteLineDesc& lineDesc = mTextSprite->getLineDesc(endLine);
 
 
-			if(lineDesc.startChar != lineDesc.endChar)
+			if(lineDesc.startChar != lineDesc.endChar && !isNewlineChar(lineDesc.startChar))
 			{
 			{
-				UINT32 startCharIdx = lineDesc.startChar;
-				if(startCharIdx == (lineDesc.endChar - 1) && startCharIdx > 0) // Ignore newline char
-				{
-					if(startLine != (mTextSprite->getNumLines() - 1))
-						startCharIdx -= 1;
-				}
-
 				UINT32 endCharIdx = mSelectionEnd - 1;
 				UINT32 endCharIdx = mSelectionEnd - 1;
-				if(endCharIdx == (lineDesc.endChar - 1) && endCharIdx > 0)
-				{
-					if(endLine != (mTextSprite->getNumLines() - 1)) // Ignore newline char
-						endCharIdx -= 1;
-				}
+#ifdef CM_DEBUG_MODE
+				if(isNewlineChar(endCharIdx))
+					CM_EXCEPT(InternalErrorException, "Selection marker placed on newline. That's not allowed");
+#endif
 
 
 				Rect startChar = mTextSprite->getCharRect(lineDesc.startChar);
 				Rect startChar = mTextSprite->getCharRect(lineDesc.startChar);
 				Rect endChar = mTextSprite->getCharRect(endCharIdx);
 				Rect endChar = mTextSprite->getCharRect(endCharIdx);

+ 0 - 1
TODO.txt

@@ -29,7 +29,6 @@ TextBox needed elements:
      - I really need to update InputCaret so it holds its own sprite data
      - I really need to update InputCaret so it holds its own sprite data
  - Add a way to move selection up/down
  - Add a way to move selection up/down
  - Update selection move right so it correctly moves to next line. Currently I fixed some issues but there are still problems.
  - Update selection move right so it correctly moves to next line. Currently I fixed some issues but there are still problems.
- - There's an issue when selecting an empty line.
  - Get DebugCamera to ignore input if GUI has already processed it
  - Get DebugCamera to ignore input if GUI has already processed it
  - Cut/Copy/Paste
  - Cut/Copy/Paste
  - LATER
  - LATER