Browse Source

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 12 years ago
parent
commit
f9eaf70190
3 changed files with 31 additions and 1 deletions
  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