Browse Source

Shift clicking moves the text selection

Marko Pintera 12 years ago
parent
commit
ba04fd11a6

+ 9 - 1
BansheeEngine/Include/BsGUIMouseEvent.h

@@ -26,7 +26,7 @@ namespace BansheeEngine
 	{
 	{
 	public:
 	public:
 		GUIMouseEvent();
 		GUIMouseEvent();
-		GUIMouseEvent(bool buttonStates[GUIMouseButton::Count]);
+		GUIMouseEvent(bool buttonStates[GUIMouseButton::Count], bool shift, bool ctrl, bool alt);
 
 
 		const CM::Int2& getPosition() const { return mPosition; }
 		const CM::Int2& getPosition() const { return mPosition; }
 		GUIMouseEventType getType() const { return mType; }
 		GUIMouseEventType getType() const { return mType; }
@@ -34,6 +34,10 @@ namespace BansheeEngine
 		CM::Int2 getDragAmount() const { return mDragAmount; }
 		CM::Int2 getDragAmount() const { return mDragAmount; }
 		bool isButtonDown(GUIMouseButton button) const { return mButtonStates[(int)button]; }
 		bool isButtonDown(GUIMouseButton button) const { return mButtonStates[(int)button]; }
 		GUIElement* getMouseOverElement() const { return mMouseOverElement; }
 		GUIElement* getMouseOverElement() const { return mMouseOverElement; }
+
+		bool isShiftDown() const { return mShift; }
+		bool isCtrlDown() const { return mCtrl; }
+		bool isAltDown() const { return mAlt; }
 	private:
 	private:
 		friend class GUIManager;
 		friend class GUIManager;
 
 
@@ -44,6 +48,10 @@ namespace BansheeEngine
 		GUIMouseButton mButton;
 		GUIMouseButton mButton;
 		GUIElement* mMouseOverElement;
 		GUIElement* mMouseOverElement;
 
 
+		bool mShift;
+		bool mCtrl;
+		bool mAlt;
+
 		void setMouseOverData(GUIElement* mouseOverElement, const CM::Int2& position);
 		void setMouseOverData(GUIElement* mouseOverElement, const CM::Int2& position);
 		void setMouseOutData(GUIElement* mouseOverElement, const CM::Int2& position);
 		void setMouseOutData(GUIElement* mouseOverElement, const CM::Int2& position);
 		void setMouseMoveData(GUIElement* mouseOverElement, const CM::Int2& position);
 		void setMouseMoveData(GUIElement* mouseOverElement, const CM::Int2& position);

+ 62 - 26
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -354,16 +354,39 @@ namespace BansheeEngine
 		{
 		{
 			mImageDesc.texture = mStyle->active.texture;
 			mImageDesc.texture = mStyle->active.texture;
 
 
-			showCaret();
+			bool isElemInFocus = mCaretShown; // HACK - I need a proper way of determining if element is in focus, or is it just now getting focus
 
 
-			if(mText.size() > 0)
-				gGUIManager().getInputCaretTool()->moveCaretToPos(ev.getPosition());
+			if(isElemInFocus)
+			{
+				if(ev.isShiftDown())
+				{
+					if(!mSelectionShown)
+						showSelection(gGUIManager().getInputCaretTool()->getCaretPos());
+				}
+				else
+					clearSelection();
+
+				if(mText.size() > 0)
+					gGUIManager().getInputCaretTool()->moveCaretToPos(ev.getPosition());
+				else
+					gGUIManager().getInputCaretTool()->moveCaretToStart();
+
+				if(ev.isShiftDown())
+					gGUIManager().getInputSelectionTool()->moveSelectionToCaret(gGUIManager().getInputCaretTool()->getCaretPos());
+			}
 			else
 			else
-				gGUIManager().getInputCaretTool()->moveCaretToStart();
+			{
+				clearSelection();
+				showCaret();
+
+				if(mText.size() > 0)
+					gGUIManager().getInputCaretTool()->moveCaretToPos(ev.getPosition());
+				else
+					gGUIManager().getInputCaretTool()->moveCaretToStart();
+			}
 
 
 			scrollTextToCaret();
 			scrollTextToCaret();
 
 
-			clearSelection();
 			markContentAsDirty();
 			markContentAsDirty();
 
 
 			return true;
 			return true;
@@ -378,41 +401,50 @@ namespace BansheeEngine
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseDragStart)
 		else if(ev.getType() == GUIMouseEventType::MouseDragStart)
 		{
 		{
-			mDragInProgress = true;
+			if(!ev.isShiftDown())
+			{
+				mDragInProgress = true;
 
 
-			UINT32 caretPos = gGUIManager().getInputCaretTool()->getCaretPos();
-			showSelection(caretPos);
-			gGUIManager().getInputSelectionTool()->selectionDragStart(caretPos);
+				UINT32 caretPos = gGUIManager().getInputCaretTool()->getCaretPos();
+				showSelection(caretPos);
+				gGUIManager().getInputSelectionTool()->selectionDragStart(caretPos);
 
 
-			return true;
+				return true;
+			}
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseDragEnd)
 		else if(ev.getType() == GUIMouseEventType::MouseDragEnd)
 		{
 		{
-			mDragInProgress = false;
-
-			if(ev.getMouseOverElement() != this && mInputCursorSet)
+			if(!ev.isShiftDown())
 			{
 			{
-				Cursor::setCursor(CursorType::Arrow);
-				mInputCursorSet = false;
-			}
+				mDragInProgress = false;
 
 
-			gGUIManager().getInputSelectionTool()->selectionDragEnd();
+				if(ev.getMouseOverElement() != this && mInputCursorSet)
+				{
+					Cursor::setCursor(CursorType::Arrow);
+					mInputCursorSet = false;
+				}
 
 
-			return true;
+				gGUIManager().getInputSelectionTool()->selectionDragEnd();
+
+				return true;
+			}
 		}
 		}
 		else if(ev.getType() == GUIMouseEventType::MouseDrag)
 		else if(ev.getType() == GUIMouseEventType::MouseDrag)
 		{
 		{
-			if(mText.size() > 0)
-				gGUIManager().getInputCaretTool()->moveCaretToPos(ev.getPosition());
-			else
-				gGUIManager().getInputCaretTool()->moveCaretToStart();
+			if(!ev.isShiftDown())
+			{
+				if(mText.size() > 0)
+					gGUIManager().getInputCaretTool()->moveCaretToPos(ev.getPosition());
+				else
+					gGUIManager().getInputCaretTool()->moveCaretToStart();
 
 
-			gGUIManager().getInputSelectionTool()->selectionDragUpdate(gGUIManager().getInputCaretTool()->getCaretPos());
+				gGUIManager().getInputSelectionTool()->selectionDragUpdate(gGUIManager().getInputCaretTool()->getCaretPos());
 
 
-			scrollTextToCaret();
+				scrollTextToCaret();
 
 
-			markContentAsDirty();
-			return true;
+				markContentAsDirty();
+				return true;
+			}
 		}
 		}
 
 
 		return false;
 		return false;
@@ -639,6 +671,10 @@ namespace BansheeEngine
 
 
 	void GUIInputBox::showSelection(CM::UINT32 anchorCaretPos)
 	void GUIInputBox::showSelection(CM::UINT32 anchorCaretPos)
 	{
 	{
+		TEXT_SPRITE_DESC textDesc = getTextDesc();
+		Int2 offset = getTextOffset();
+		gGUIManager().getInputSelectionTool()->updateText(textDesc, offset, mTextOffset);
+
 		gGUIManager().getInputSelectionTool()->showSelection(anchorCaretPos);
 		gGUIManager().getInputSelectionTool()->showSelection(anchorCaretPos);
 		mSelectionShown = true;
 		mSelectionShown = true;
 		markContentAsDirty();
 		markContentAsDirty();

+ 15 - 11
BansheeEngine/Source/BsGUIManager.cpp

@@ -497,14 +497,14 @@ namespace BansheeEngine
 		if(event.isUsed())
 		if(event.isUsed())
 			return;
 			return;
 
 
+		bool shiftDown = gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT);
+		bool ctrlDown = gInput().isButtonDown(BC_LCONTROL) || gInput().isButtonDown(BC_RCONTROL);
+		bool altDown = gInput().isButtonDown(BC_LMENU) || gInput().isButtonDown(BC_RMENU);
+
 		if(event.isKeyboard())
 		if(event.isKeyboard())
 		{
 		{
 			if(mKeyboardFocusElement != nullptr)
 			if(mKeyboardFocusElement != nullptr)
 			{
 			{
-				bool shiftDown = gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT);
-				bool ctrlDown = gInput().isButtonDown(BC_LCONTROL) || gInput().isButtonDown(BC_RCONTROL);
-				bool altDown = gInput().isButtonDown(BC_LMENU) || gInput().isButtonDown(BC_RMENU);
-
 				mKeyEvent = GUIKeyEvent(shiftDown, ctrlDown, altDown);
 				mKeyEvent = GUIKeyEvent(shiftDown, ctrlDown, altDown);
 
 
 				mKeyEvent.setKeyDownData(event.buttonCode);
 				mKeyEvent.setKeyDownData(event.buttonCode);
@@ -519,7 +519,7 @@ namespace BansheeEngine
 			buttonStates[1] = gInput().isButtonDown(BC_MOUSE_MIDDLE);
 			buttonStates[1] = gInput().isButtonDown(BC_MOUSE_MIDDLE);
 			buttonStates[2] = gInput().isButtonDown(BC_MOUSE_RIGHT);
 			buttonStates[2] = gInput().isButtonDown(BC_MOUSE_RIGHT);
 
 
-			mMouseEvent = GUIMouseEvent(buttonStates);
+			mMouseEvent = GUIMouseEvent(buttonStates, shiftDown, ctrlDown, altDown);
 
 
 			GUIMouseButton guiButton = buttonToMouseButton(event.buttonCode);
 			GUIMouseButton guiButton = buttonToMouseButton(event.buttonCode);
 
 
@@ -572,14 +572,14 @@ namespace BansheeEngine
 		if(event.isUsed())
 		if(event.isUsed())
 			return;
 			return;
 
 
+		bool shiftDown = gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT);
+		bool ctrlDown = gInput().isButtonDown(BC_LCONTROL) || gInput().isButtonDown(BC_RCONTROL);
+		bool altDown = gInput().isButtonDown(BC_LMENU) || gInput().isButtonDown(BC_RMENU);
+
 		if(event.isKeyboard())
 		if(event.isKeyboard())
 		{
 		{
 			if(mKeyboardFocusElement != nullptr)
 			if(mKeyboardFocusElement != nullptr)
 			{
 			{
-				bool shiftDown = gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT);
-				bool ctrlDown = gInput().isButtonDown(BC_LCONTROL) || gInput().isButtonDown(BC_RCONTROL);
-				bool altDown = gInput().isButtonDown(BC_LMENU) || gInput().isButtonDown(BC_RMENU);
-
 				mKeyEvent = GUIKeyEvent(shiftDown, ctrlDown, altDown);
 				mKeyEvent = GUIKeyEvent(shiftDown, ctrlDown, altDown);
 
 
 				mKeyEvent.setKeyUpData(event.buttonCode);
 				mKeyEvent.setKeyUpData(event.buttonCode);
@@ -594,7 +594,7 @@ namespace BansheeEngine
 			buttonStates[1] = gInput().isButtonDown(BC_MOUSE_MIDDLE);
 			buttonStates[1] = gInput().isButtonDown(BC_MOUSE_MIDDLE);
 			buttonStates[2] = gInput().isButtonDown(BC_MOUSE_RIGHT);
 			buttonStates[2] = gInput().isButtonDown(BC_MOUSE_RIGHT);
 
 
-			mMouseEvent = GUIMouseEvent(buttonStates);
+			mMouseEvent = GUIMouseEvent(buttonStates, shiftDown, ctrlDown, altDown);
 
 
 			Int2 localPos;
 			Int2 localPos;
 			if(mMouseOverWidget != nullptr)
 			if(mMouseOverWidget != nullptr)
@@ -649,13 +649,17 @@ namespace BansheeEngine
 		}
 		}
 #endif
 #endif
 
 
+		bool shiftDown = gInput().isButtonDown(BC_LSHIFT) || gInput().isButtonDown(BC_RSHIFT);
+		bool ctrlDown = gInput().isButtonDown(BC_LCONTROL) || gInput().isButtonDown(BC_RCONTROL);
+		bool altDown = gInput().isButtonDown(BC_LMENU) || gInput().isButtonDown(BC_RMENU);
+
 		// TODO - Maybe avoid querying these for every event separately?
 		// TODO - Maybe avoid querying these for every event separately?
 		bool buttonStates[(int)GUIMouseButton::Count];
 		bool buttonStates[(int)GUIMouseButton::Count];
 		buttonStates[0] = gInput().isButtonDown(BC_MOUSE_LEFT);
 		buttonStates[0] = gInput().isButtonDown(BC_MOUSE_LEFT);
 		buttonStates[1] = gInput().isButtonDown(BC_MOUSE_MIDDLE);
 		buttonStates[1] = gInput().isButtonDown(BC_MOUSE_MIDDLE);
 		buttonStates[2] = gInput().isButtonDown(BC_MOUSE_RIGHT);
 		buttonStates[2] = gInput().isButtonDown(BC_MOUSE_RIGHT);
 
 
-		mMouseEvent = GUIMouseEvent(buttonStates);
+		mMouseEvent = GUIMouseEvent(buttonStates, shiftDown, ctrlDown, altDown);
 
 
 		GUIWidget* widgetInFocus = nullptr;
 		GUIWidget* widgetInFocus = nullptr;
 		GUIElement* topMostElement = nullptr;
 		GUIElement* topMostElement = nullptr;

+ 5 - 3
BansheeEngine/Source/BsGUIMouseEvent.cpp

@@ -5,13 +5,15 @@ using namespace CamelotFramework;
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	GUIMouseEvent::GUIMouseEvent()
 	GUIMouseEvent::GUIMouseEvent()
-		:mType(GUIMouseEventType::MouseMove), mButton(GUIMouseButton::Left), mMouseOverElement(nullptr)
+		:mType(GUIMouseEventType::MouseMove), mButton(GUIMouseButton::Left), mMouseOverElement(nullptr),
+		mShift(false), mCtrl(false), mAlt(false)
 	{
 	{
 
 
 	}
 	}
 
 
-	GUIMouseEvent::GUIMouseEvent(bool buttonStates[GUIMouseButton::Count])
-		:mType(GUIMouseEventType::MouseMove), mButton(GUIMouseButton::Left), mMouseOverElement(nullptr)
+	GUIMouseEvent::GUIMouseEvent(bool buttonStates[GUIMouseButton::Count], bool shift, bool ctrl, bool alt)
+		:mType(GUIMouseEventType::MouseMove), mButton(GUIMouseButton::Left), mMouseOverElement(nullptr),
+		mShift(shift), mCtrl(ctrl), mAlt(alt)
 	{
 	{
 		memcpy(mButtonStates, buttonStates, sizeof(mButtonStates));
 		memcpy(mButtonStates, buttonStates, sizeof(mButtonStates));
 	}
 	}