Преглед изворни кода

Add a new InputEvent type: TextInput. This now is used for any text input - the character for keypress events is removed!

Also merges and closes #620.
Joachim Meyer пре 9 година
родитељ
комит
a700c59140

+ 1 - 1
build/linux/Makefile

@@ -128,4 +128,4 @@ studio_debug: core_debug ui_debug $(DOBJSTUDIO)
 	@cp $(ASSETDIR)/icons/sdl_icon.bmp Studio/icon.bmp
 
 clean:
-	rm -f $(OBJCORE) $(OBJUI) $(OBJTEMPLATE) $(OBJSTUDIO) $(DOBJCORE) $(DOBJUI) $(DOBJTEMPLATE) $(DOBJSTUDIO) $(LIBDIR)/libPolycore.a Studio/Polycode $(LIBDIR)/libPolycodeUI.a TemplateApp/PolycodeTemplate $(LIBDIR)/libPolycored.a Studio/Polycoded $(LIBDIR)/libPolycodeUId.a TemplateApp/PolycodeTemplated
+	rm -f $(OBJCORE) $(OBJUI) $(OBJTEMPLATE) $(OBJSTUDIO) $(DOBJCORE) $(DOBJUI) $(DOBJTEMPLATE) $(DOBJSTUDIO) $(OBJPHYSICS2D) $(DOBJPHYSICS2D) $(OBJPHYSICS3D) $(DOBJPHYSICS3D) $(LIBDIR)/libPolycore.a Studio/Polycode $(LIBDIR)/libPolycodeUI.a $(LIBDIR)/libPolycode3DPhysics.a $(LIBDIR)/libPolycode2DPhysics.a TemplateApp/PolycodeTemplate $(LIBDIR)/libPolycored.a Studio/Polycoded $(LIBDIR)/libPolycodeUId.a $(LIBDIR)/libPolycode3DPhysicsd.a $(LIBDIR)/libPolycode2DPhysicsd.a TemplateApp/PolycodeTemplated

+ 4 - 2
include/polycode/core/PolyCoreInput.h

@@ -157,13 +157,15 @@ namespace Polycode {
 		void mouseWheelDown(int ticks);
 		void setMouseButtonState(int mouseButton, bool state, int ticks);
 		void setMousePosition(int x, int y, int ticks);
-		void setKeyState(PolyKEY keyCode, wchar_t code, bool newState, int ticks);
+		void setKeyState(PolyKEY keyCode, bool newState, int ticks);
 		void setDeltaPosition(int x, int y);
 		
 		void touchesBegan(TouchInfo touch, std::vector<TouchInfo> touches, int ticks);
 		void touchesMoved(TouchInfo touch, std::vector<TouchInfo> touches, int ticks);
 		void touchesEnded(TouchInfo touch, std::vector<TouchInfo> touches, int ticks);
-				
+		
+		void textInput(String text);
+		
 		static InputEvent *createEvent(Event *event){ return (InputEvent*)event; }
 		
 		/**

+ 8 - 8
include/polycode/core/PolyInputEvent.h

@@ -57,8 +57,7 @@ namespace Polycode {
 		public:
 			InputEvent();
 			InputEvent(Vector2 mousePosition,int timestamp);
-//			InputEvent(PolyKEY key, int timestamp);
-			InputEvent(PolyKEY key, wchar_t charCode, int timestamp);			
+			InputEvent(PolyKEY key, int timestamp);			
 			virtual ~InputEvent();
 		
 			// ----------------------------------------------------------------------------------------------------------------
@@ -89,6 +88,8 @@ namespace Polycode {
 		static const int EVENT_TOUCHES_BEGAN = EVENTBASE_INPUTEVENT+20;
 		static const int EVENT_TOUCHES_MOVED = EVENTBASE_INPUTEVENT+21;
 		static const int EVENT_TOUCHES_ENDED = EVENTBASE_INPUTEVENT+22;
+		
+		static const int EVENT_TEXTINPUT = EVENTBASE_INPUTEVENT+23;
 
 		//@}
 		// ----------------------------------------------------------------------------------------------------------------
@@ -112,16 +113,15 @@ namespace Polycode {
 		*/		
 		PolyKEY key;
 		
-		wchar_t getCharCode();
-		
 		int keyCode() { return key; }
 		
-		/**
-		* If this is a key press event, this will contain the unicode character that's being typed.
-		*/
-		wchar_t charCode;
 		int timestamp;
 		
+		/**
+		 * If this is a text input event, this will contain the text with all modifiers applied. (will usually be only 1 character)
+		 */
+		String text;
+		
 		std::vector<TouchInfo> touches;
 		TouchInfo touch;
 		int touchType;

+ 57 - 44
include/polycode/core/PolyString.h

@@ -44,32 +44,32 @@ namespace Polycode {
 		
 			/**
 			* Default constructor
-			*/			
+			*/
 			String();
 			
 			/**
 			* Initializes the string from a pointer to wide character buffer.
-			*/			
+			*/
 			String(const wchar_t *str);
 			
 			/**
 			* Initializes the string from a pointer to regular character buffer of a certain size.
-			*/						
+			*/
 			String(const char *str, size_t n);
 			
 			/**
 			* Initializes the string from a regular character buffer.
-			*/									
+			*/
 			String(const char *str);
 			
 			/**
 			* Initializes the string from an STL string.
-			*/												
+			*/
 			String(const std::string& str);
 			
 			/**
 			* Initializes the string from an STL wstring.
-			*/															
+			*/
 			String(const std::wstring& str);
 			
 			String(const wchar_t wchar);
@@ -78,25 +78,25 @@ namespace Polycode {
 		
 			/**
 			* Return the length of the string.
-			*/														
+			*/
 			size_t size() const { return contents.size(); }
 			
 			/**
 			* Return the length of the string.
-			*/			
+			*/
 			size_t length() const { return contents.size(); }
 		
 			/**
 			* Return the string and an STL string.
-			*/		
+			*/
 			const std::string& getSTLString() const;
-					
+			
 			/**
 			* Returns the substring of the string.
 			* @param pos Position of a character in the current string object to be used as starting character for the substring.
 			* @param n Length of the substring.
 			* @return A string object containing a substring of the current object.
-			*/					
+			*/
 			String substr(size_t pos = 0, size_t n = std::wstring::npos) const { return String(contents.substr(pos,n)); }
 
 			/**
@@ -104,7 +104,7 @@ namespace Polycode {
 			* @param str String to be searched for in the object.
 			* @param pos Position of the last character in the string to be taken into consideration for possible matches. The default value indicates that the entire string is searched.
 			* @return The position of the last occurrence in the string of the searched content or -1 if not found
-			*/							
+			*/
 			size_t rfind ( const String &str, size_t pos = std::wstring::npos ) const { return contents.rfind(str.contents, pos); }
 			
 			/**
@@ -112,7 +112,7 @@ namespace Polycode {
 			* @param str String to be searched for in the object.
 			* @param pos Position of the first character in the string to be taken into consideration for possible matches. The default value indicates that the entire string is searched.
 			* @return The position of the first occurrence in the string of the searched content or -1 if not found.
-			*/										
+			*/
 			size_t find ( const String &str, size_t pos = 0 ) const { return contents.find(str.contents, pos); }
 			
 			/**
@@ -120,7 +120,7 @@ namespace Polycode {
 			* @param str String containing the characters to search for.
 			* @param pos Position of the last character in the string to be taken into consideration for possible matches. The default value indicates that the entire string is searched.
 			* @return The position of the last occurrence in the string of any of the characters searched for.
-			*/													
+			*/
 			size_t find_last_of(const String& str, size_t pos = std::wstring::npos ) { return contents.find_last_of(str.contents, pos); }
 		
 			
@@ -128,37 +128,47 @@ namespace Polycode {
 			* Find character in string from the beginning. Searches the string from the beginnign for any of the characters that are part of the passed string.
 			* @param str String containing the characters to search for.
 			* @param pos Position of the first character in the string to be taken into consideration for possible matches. The default value indicates that the entire string is searched.
-			* @return The position of the last occurrence in the string of any of the characters searched for.
-			*/			
+			* @return The position of the first occurrence in the string of any of the characters searched for.
+			*/
 			size_t find_first_of(const String &str, size_t pos = 0) {
-				return contents.find_first_of(str.contents, pos); 
+				return contents.find_first_of(str.contents, pos);
+			}
+			
+			/**
+			* Find character in string from the beginning. Searches the string from the beginning for any other than the characters that are part of the passed string.
+			* @param str String containing the characters to not search for.
+			* @param pos Position of the first character in the string to be taken into consideration for possible matches. The default value indicates that the entire string is searched.
+			* @return The position of the first occurrence in the string of any of the characters searched for.
+			*/
+			size_t find_first_not_of(const String &str, size_t pos = 0) {
+				return contents.find_first_not_of(str.contents, pos);
 			}
 		
-			inline String operator + (const char *str) const { return String(contents + String(str).contents); }		
-			inline String operator + (const String &str) const { return String(contents + str.contents); }		
-			String operator += (const String &str) { contents = contents + str.contents; return *this; }		
+			inline String operator + (const char *str) const { return String(contents + String(str).contents); }
+			inline String operator + (const String &str) const { return String(contents + str.contents); }
+			String operator += (const String &str) { contents = contents + str.contents; return *this; }
 			String operator = (const String &str) {	 contents = str.contents; return *this;}
-			inline bool operator == (const String &str) const {	 return (str.contents == contents); }		
-			inline bool operator != (const String &str) const {	 return (str.contents != contents); }		
+			inline bool operator == (const String &str) const {	 return (str.contents == contents); }
+			inline bool operator != (const String &str) const {	 return (str.contents != contents); }
 			inline wchar_t operator [] ( const size_t i ) const { return contents[i]; }
 
 			/**
 			* Returns the lowercase version of the string.
 			* @return Lowercase version of the stirng.
-			*/															
+			*/
 			String toLowerCase() const;
 			
 			/**
 			* Returns the uppercase version of the string.
 			* @return Uppercase version of the stirng.
-			*/																		
+			*/
 			String toUpperCase() const;
-					
+			
 			/**
 			* Splits the string by the specified delimeter
 			* @param delim The delimeter to split by.
 			* @return An STL vector of the split parts of the string. 
-			*/																				
+			*/
 			std::vector<String> split(const String &delim) const;
 
 			/**
@@ -166,14 +176,14 @@ namespace Polycode {
 			* @param what Ocurrences of which string to replace in this string.
 			* @param withWhat What to replace them with.
 			* @return A new string with the specified matches replaced with the specified string.
-			*/																							
+			*/
 			String replace(const String &what, const String &withWhat) const;
 			
 			/**
 			* Convert a Number to a String.
 			* @param value Number to convert.
 			* @return A string converted from the Number.
-			*/																										
+			*/
 			static String NumberToString(Number value, int precision = 2);
 		
 		
@@ -184,13 +194,13 @@ namespace Polycode {
 			* Convert an integer to a String.
 			* @param value Integer to convert.
 			* @return A string converted from the integer.
-			*/																												
+			*/
 			static String IntToString(int value);
 		
 			/**
 			* Pointer to char data.
 			* @return A pointer to char data.
-			*/																												
+			*/
 			const char *c_str() const;
 			
 			/**
@@ -198,7 +208,7 @@ namespace Polycode {
 			* @param encoding The encoding to use.
 			* @return A pointer to the data using specified encoding.
 			* @see getDataSizeWithEncoding()
-			*/																															
+			*/
 			const char *getDataWithEncoding(int encoding) const;
 			
 			/**
@@ -206,48 +216,51 @@ namespace Polycode {
 			* @param encoding The encoding to use.
 			* @return A pointer to the data using specified encoding.
 			* @see getDataSizeWithEncoding()
-			*/																															
+			*/
 			wchar_t *getWDataWithEncoding(int encoding);
 
+			void append(const char c);
 
 			/**
 			* Returns the size of the data with the specified encoding. Currently the only supported encoding is String::ENCODING_UTF8
 			* @param encoding The encoding to use.
 			* @return The size the data would take up if returned with this encoding.
-			* @see getDataWithEncoding()
-			*/																		
-			
-
-			void append(const char c);
-
-			size_t getDataSizeWithEncoding(int encoding) const;					
+			* @see getDataSizeWithEncoding()
+			*/
+			size_t getDataSizeWithEncoding(int encoding) const;
 			
 			/**
 			* Sets the data for the string using specified encoding.
 			* @param data Data to set the string with.
 			* @param encoding The encoding to use.
-			*/																																		
+			*/
 			void setDataWithEncoding(char *data, int encoding);
 			
 			/**
 			* Checks if the string is a number
 			* @return true if the string is a number
-			*/			
+			*/
 			bool isNumber();
 
+			/**
+			* Checks if the string is an integer
+			* @return true if the string is an integer
+			*/
+			bool isInteger();
+ 
 			/**
 			* STL string version of the string.
-			*/																																					
+			*/
 			std::string contents;
 
 			/**
 			* STL string version of the string.
-			*/																																					
+			*/
 			std::wstring w_contents;
 
 			/**
 			* UTF-8 encoding.
-			*/																																							
+			*/
 			static const int ENCODING_UTF8 = 0; 
 			
 		

+ 4 - 2
include/polycode/modules/ui/PolyUITextInput.h

@@ -183,8 +183,10 @@ namespace Polycode {
 			 */
 			int insertLine(String lineText = "");
 
-			void onKeyDown(PolyKEY key, wchar_t charCode);
-		
+			void onKeyDown(PolyKEY key);
+			
+			void onTextInput(String newText);
+			
 			/**
 			 * Clear the current selection.
 			 */

+ 11 - 8
src/core/PolyCoreInput.cpp

@@ -242,7 +242,7 @@ namespace Polycode {
 			return false;
 	}
 	
-	void CoreInput::setKeyState(PolyKEY keyCode, wchar_t code, bool newState, int ticks) {
+	void CoreInput::setKeyState(PolyKEY keyCode, bool newState, int ticks) {
 		
 		if(newState && !keyRepeat) {
 			if(keyboardState[keyCode]) {
@@ -250,7 +250,7 @@ namespace Polycode {
 			}
 		}
 		
-		InputEvent *evt = new InputEvent(keyCode, code, ticks);
+		InputEvent *evt = new InputEvent(keyCode, ticks);
 		if(keyCode < 512)
 			keyboardState[keyCode] = newState;
 		if(newState) {
@@ -260,6 +260,15 @@ namespace Polycode {
 		}
 	}
 	
+	void CoreInput::textInput(String text){
+		InputEvent* iev = new InputEvent();
+		iev->text = "";
+		iev->text = text;
+		
+		dispatchEvent(iev, InputEvent::EVENT_TEXTINPUT);
+	}
+
+	
 	void CoreInput::touchesBegan(TouchInfo touch, std::vector<TouchInfo> touches, int ticks) {
 		if(ignoreOffScreenTouch) {
 			Core *core = CoreServices::getInstance()->getCore();
@@ -295,12 +304,6 @@ namespace Polycode {
 		}
 	}
 
-
-
-
-
-
-	
 	void CoreInput::touchesEnded(TouchInfo touch, std::vector<TouchInfo> touches, int ticks) {
 		if(ignoreOffScreenTouch) {
 			Core *core = CoreServices::getInstance()->getCore();

+ 1 - 13
src/core/PolyInputEvent.cpp

@@ -37,23 +37,11 @@ InputEvent::InputEvent(Vector2 mousePosition, int timestamp) : Event() {
 	eventType = "InputEvent";
 }
 
-InputEvent::InputEvent(PolyKEY key, wchar_t charCode, int timestamp) : Event() {
+InputEvent::InputEvent(PolyKEY key, int timestamp) : Event() {
 	this->key = key;
-	this->charCode = charCode;
 	this->timestamp = timestamp;
 	eventType = "InputEvent";	
 }
-	
-wchar_t InputEvent::getCharCode() {
-	return charCode;
-}
-
-/*
-InputEvent::InputEvent(PolyKEY key, int timestamp)	: Event() {
-	this->key = key;
-	this->timestamp = timestamp;	
-}
-*/
 
 InputEvent::~InputEvent() {
 

+ 7 - 4
src/core/PolySDLCore.cpp

@@ -247,7 +247,7 @@ vector<Polycode::Rectangle> SDLCore::getVideoModes() {
 		res.w = modes.w;
 		res.h = modes.h;
 		retVector.push_back(res);
-	}	
+	}
 	
 	return retVector;
 }
@@ -502,7 +502,7 @@ void SDLCore::flushRenderContext(){
 bool SDLCore::systemUpdate() {
 	if(!running)
 		return false;
-	doSleep();	
+	doSleep();
 	
 	updateCore();
 	
@@ -558,11 +558,11 @@ bool SDLCore::systemUpdate() {
 				break;
 				case SDL_KEYDOWN:
 					if(!checkSpecialKeyEvents(mapKey(event.key.keysym.scancode))) {
-						input->setKeyState(mapKey(event.key.keysym.scancode), event.key.keysym.sym, true, getTicks());
+						input->setKeyState(mapKey(event.key.keysym.scancode), true, getTicks());
 					}
 				break;
 				case SDL_KEYUP:
-					input->setKeyState(mapKey(event.key.keysym.scancode), event.key.keysym.sym, false, getTicks());
+					input->setKeyState(mapKey(event.key.keysym.scancode), false, getTicks());
 				break;
 				case SDL_MOUSEWHEEL:
 					if(event.wheel.y > 0) {
@@ -603,6 +603,9 @@ bool SDLCore::systemUpdate() {
 					lastMouseY = event.motion.y;
 					lastMouseX = event.motion.x;
 				break;
+				case SDL_TEXTINPUT:
+					input->textInput(String(event.text.text));
+				break;
 				default:
 					break;
 			}

+ 11 - 6
src/core/PolyString.cpp

@@ -24,6 +24,9 @@
 #include "polycode/core/PolyGlobals.h"
 #include <iomanip>
 #include <sstream>
+#ifdef _WINDOWS
+	#include <ctype.h>
+#endif
 
 using namespace Polycode;
 using namespace std;
@@ -113,15 +116,17 @@ void String::setDataWithEncoding(char *data, int encoding) {
 	}
 }
 
-bool String::isNumber() {
-#if PLATFORM == PLATFORM_WINDOWS
+bool String::isNumber(){
+	if (contents.find_first_not_of("0123456789.+-") == string::npos)
+		return true;
 	return false;
-#else
+}
+
+bool String::isInteger() {
 	std::string::const_iterator it = contents.begin();
-	while (it != contents.end() && std::isdigit(*it)) ++it;
+	while (it != contents.end() && (isdigit(*it) || *it == '+' || *it == '-')) ++it;
 	return !contents.empty() && it == contents.end();
-#endif
-}				
+}
 
 
 

+ 39 - 24
src/modules/ui/PolyUITextInput.cpp

@@ -237,6 +237,7 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height, int custom
 	indentSpacing = 4;
 	indentType = INDENT_TAB;
 	
+	core->getInput()->addEventListenerUnique(this, InputEvent::EVENT_TEXTINPUT);
 	core->getInput()->addEventListenerUnique(this, InputEvent::EVENT_KEYDOWN);
 	core->getInput()->addEventListenerUnique(this, InputEvent::EVENT_MOUSEUP);
 }
@@ -1717,7 +1718,7 @@ bool UITextInput::isNumberOrCharacter(wchar_t charCode) {
 	return false;
 }
 
-void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
+void UITextInput::onKeyDown(PolyKEY key) {
 	
 	if(!hasFocus)
 		return;
@@ -2059,28 +2060,6 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 	String ctext = lines[actualLineOffset].text;
 	
 	bool _changedText = false;
-		
-	if(((charCode > 31 && charCode < 127) || charCode > 127) && key != KEY_DELETE && key != KEY_HOME && key != KEY_END) {
-		
-		if(!isNumberOnly || (isNumberOnly && ((charCode > 47 && charCode < 58) || (charCode == '.' || charCode == '-')))) {
-			if(!isNumberOrCharacter(charCode)) { 
-				saveUndoState();
-			} else if (!isTypingWord) {
-				saveUndoState();
-				isTypingWord = 1;
-			}
-			if(hasSelection)
-				deleteSelection();
-			ctext = lines[actualLineOffset].text;
-			String text2 = ctext.substr(actualCaretPosition, ctext.length()-actualCaretPosition);
-			ctext = ctext.substr(0,actualCaretPosition);
-			ctext += charCode + text2;
-			actualCaretPosition++;
-			_changedText = true;
-			
-			showCurrentLineIfOffscreen();
-		}
-	}
 	
 	if(key == KEY_TAB && multiLine) {
 		saveUndoState();
@@ -2176,6 +2155,38 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 	updateCaretPosition();
 }
 
+void UITextInput::onTextInput(String newText){
+	if(!hasFocus)
+		return;
+	
+	if(!isNumberOnly || (isNumberOnly && newText.isNumber())) {
+		String ctext = lines[actualLineOffset].text;
+		//if(!isNumberOrCharacter(charCode)) { 
+			/*saveUndoState();
+		} else */
+		if (!isTypingWord) {
+			saveUndoState();
+			isTypingWord = 1;
+		}
+		
+		if(hasSelection)
+			deleteSelection();
+		
+		ctext = lines[actualLineOffset].text;
+		String text2 = ctext.substr(actualCaretPosition, ctext.length()-actualCaretPosition);
+		ctext = ctext.substr(0,actualCaretPosition);
+		ctext += newText + text2;
+		actualCaretPosition+=newText.length();
+		
+		showCurrentLineIfOffscreen();
+		
+		lines[actualLineOffset].text = ctext;
+		changedText(actualLineOffset, actualLineOffset);
+		updateCaretPosition();
+	}
+	
+}
+
 void UITextInput::Update() {
 	resizeTimer += core->getElapsed();
 	
@@ -2518,9 +2529,13 @@ void UITextInput::readjustBuffer(int lineStart, int lineEnd) {
 void UITextInput::handleEvent(Event *event) {
 
 	if(event->getDispatcher() == core->getInput()) {
+		if(event->getEventCode() == InputEvent::EVENT_TEXTINPUT){
+			InputEvent *inputEvent = (InputEvent*) event;
+			onTextInput(inputEvent->text);
+		}
 		if(event->getEventCode() == InputEvent::EVENT_KEYDOWN) {
 			InputEvent *inputEvent = (InputEvent*) event;
-			onKeyDown(inputEvent->key, inputEvent->charCode);
+			onKeyDown(inputEvent->key);
 		}
 		if (event->getEventCode() == InputEvent::EVENT_MOUSEUP) {
 			draggingSelection = false;

+ 2 - 2
src/modules/ui/PolyUITreeContainer.cpp

@@ -91,7 +91,7 @@ void UITreeContainer::handleEvent(Event *event) {
 	if(event->getDispatcher() == CoreServices::getInstance()->getCore()->getInput()) {
 		InputEvent *inputEvent = (InputEvent*) event;
 		if(event->getEventCode() == InputEvent::EVENT_KEYDOWN) {
-			onKeyDown(inputEvent->key, inputEvent->charCode);
+			onKeyDown(inputEvent->key);
 		}
 	}
 
@@ -164,7 +164,7 @@ UITree *UITreeContainer::findNextParentSibling(UITree *parent) {
 //
 // END RECURSIVE HELPER FUNCTIONS
 
-void UITreeContainer::onKeyDown(PolyKEY key, wchar_t charCode) {
+void UITreeContainer::onKeyDown(PolyKEY key) {
 	if (hasFocus) {
 		
 		// KEYBOARD NAV STUFF

+ 2 - 2
src/modules/ui/PolyUIWindow.cpp

@@ -131,7 +131,7 @@ UIWindow::~UIWindow() {
 	CoreServices::getInstance()->getCore()->getInput()->removeAllHandlersForListener(this);
 }
 
-void UIWindow::onKeyDown(PolyKEY key, wchar_t charCode) {	
+void UIWindow::onKeyDown(PolyKEY key) {	
 	if(key == KEY_ESCAPE && closeOnEscape) {
 		onClose();
 		dispatchEvent(new UIEvent(), UIEvent::CLOSE_EVENT);		
@@ -177,7 +177,7 @@ void UIWindow::handleEvent(Event *event) {
 	if(event->getDispatcher() == CoreServices::getInstance()->getCore()->getInput()) {
 		InputEvent *inputEvent = (InputEvent*)event;
 		if(event->getEventCode() == InputEvent::EVENT_KEYDOWN) {
-			onKeyDown(inputEvent->key, inputEvent->charCode);
+			onKeyDown(inputEvent->key);
 		}
 	}