فهرست منبع

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 سال پیش
والد
کامیت
f9eaf70190
3فایلهای تغییر یافته به همراه31 افزوده شده و 1 حذف شده
  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 moveSelectionRight(bool skipNewline);
 
 
 		void scrollTextToCaret();
 		void scrollTextToCaret();
+		void clampScrollToBounds(CM::Rect unclippedTextBounds);
 
 
 		CM::Int2 getTextOffset() const;
 		CM::Int2 getTextOffset() const;
 		CM::Rect getTextClipRect() const;
 		CM::Rect getTextClipRect() const;

+ 25 - 1
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -136,6 +136,10 @@ namespace BansheeEngine
 			gGUIManager().getInputSelectionTool()->updateSprite();
 			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();
 		GUIElement::updateRenderElementsInternal();
 	}
 	}
 
 
@@ -787,13 +791,33 @@ namespace BansheeEngine
 
 
 		mTextOffset += offset;
 		mTextOffset += offset;
 
 
-		Int2 newOffset = getTextOffset();
 		gGUIManager().getInputCaretTool()->updateText(this, textDesc);
 		gGUIManager().getInputCaretTool()->updateText(this, textDesc);
 		gGUIManager().getInputSelectionTool()->updateText(this, textDesc);
 		gGUIManager().getInputSelectionTool()->updateText(this, textDesc);
 
 
 		markContentAsDirty();
 		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)
 	void GUIInputBox::insertString(CM::UINT32 charIdx, const WString& string)
 	{
 	{
 		mText.insert(mText.begin() + charIdx, string.begin(), string.end());
 		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
    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:
 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
  Key repeat
  Double click (Input box select all)
  Double click (Input box select all)
  Windows drag and drop detect
  Windows drag and drop detect