Explorar o código

When writing a very long line of text that causes the input box to scroll it, and then deleting the text, the text will now be properly scrolled back

Marko Pintera %!s(int64=12) %!d(string=hai) anos
pai
achega
f9eaf70190
Modificáronse 3 ficheiros con 31 adicións e 1 borrados
  1. 1 0
      BansheeEngine/Include/BsGUIInputBox.h
  2. 25 1
      BansheeEngine/Source/BsGUIInputBox.cpp
  3. 5 0
      TODO.txt

+ 1 - 0
BansheeEngine/Include/BsGUIInputBox.h

@@ -100,6 +100,7 @@ namespace BansheeEngine
 		void moveSelectionRight(bool skipNewline);
 
 		void scrollTextToCaret();
+		void clampScrollToBounds(CM::Rect unclippedTextBounds);
 
 		CM::Int2 getTextOffset() const;
 		CM::Rect getTextClipRect() const;

+ 25 - 1
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -136,6 +136,10 @@ namespace BansheeEngine
 			gGUIManager().getInputSelectionTool()->updateSprite();
 		}
 
+		// When text bounds are reduced the scroll needs to be adjusted so that
+		// input box isn't filled with mostly empty space.
+		clampScrollToBounds(mTextSprite->getBounds(mOffset, Rect()));
+
 		GUIElement::updateRenderElementsInternal();
 	}
 
@@ -787,13 +791,33 @@ namespace BansheeEngine
 
 		mTextOffset += offset;
 
-		Int2 newOffset = getTextOffset();
 		gGUIManager().getInputCaretTool()->updateText(this, textDesc);
 		gGUIManager().getInputSelectionTool()->updateText(this, textDesc);
 
 		markContentAsDirty();
 	}
 
+	void GUIInputBox::clampScrollToBounds(Rect unclippedTextBounds)
+	{
+		TEXT_SPRITE_DESC textDesc = getTextDesc();
+
+		Int2 newTextOffset;
+		INT32 maxScrollableWidth = std::max(0, (INT32)unclippedTextBounds.width - (INT32)textDesc.width);
+		INT32 maxScrollableHeight = std::max(0, (INT32)unclippedTextBounds.height - (INT32)textDesc.height);
+		newTextOffset.x = Math::Clamp(mTextOffset.x, -maxScrollableWidth, 0);
+		newTextOffset.y = Math::Clamp(mTextOffset.y, -maxScrollableHeight, 0);
+
+		if(newTextOffset != mTextOffset)
+		{
+			mTextOffset = newTextOffset;
+
+			gGUIManager().getInputCaretTool()->updateText(this, textDesc);
+			gGUIManager().getInputSelectionTool()->updateText(this, textDesc);
+
+			markContentAsDirty();
+		}
+	}
+
 	void GUIInputBox::insertString(CM::UINT32 charIdx, const WString& string)
 	{
 		mText.insert(mText.begin() + charIdx, string.begin(), string.end());

+ 5 - 0
TODO.txt

@@ -10,6 +10,11 @@ GUIWidget::updateMeshes leaks. If I leave the game running I can see memory cont
    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:
+ GUIManager drag events should only trigger after a mouse moves a few pixels
+  - Right now it is breaking double click as start/end drag events get sent out twice
+
+ Writing a long word so that text scrolls, then deleting it will not scroll back unless the cursor is out of view
+
  Key repeat
  Double click (Input box select all)
  Windows drag and drop detect