فهرست منبع

Multiple UITextInput fixes (crashing on deleting lines, mouse input while scrolling)

Ivan Safrin 13 سال پیش
والد
کامیت
f6dddc3e47

+ 0 - 2
Core/Contents/Include/PolyCocoaCore.h

@@ -153,8 +153,6 @@ namespace Polycode {
 		PolycodeView *glView;
 		uint64_t initTime;	
 		
-		PolycodeView *view;
-		
 		IOHIDManagerRef hidManager;
 	};
 }

+ 9 - 7
Core/Contents/Source/PolyCocoaCore.mm

@@ -48,8 +48,6 @@ CocoaCore::CocoaCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen,
 	hidManager = NULL;
 	initGamepad();
 
-	this->view = view;
-
 	eventMutex = createMutex();
 	
 //	NSLog(@"BUNDLE: %@", [[NSBundle mainBundle] bundlePath]);
@@ -174,21 +172,25 @@ CocoaCore::CocoaCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen,
 }
 
 void CocoaCore::copyStringToClipboard(const String& str) {
+
 	NSPasteboard *pb = [NSPasteboard generalPasteboard];
     NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];
-    [pb declareTypes:types owner:glView];
-	
-	//NSString *nsstr = [NSString stringWithCharacters: (unichar*) str.c_str() length: str.length()];
+    [pb declareTypes:types owner:nil];
 	
+	NSString *nsstr = [NSString stringWithCString: str.c_str()];
+	/*
 	char* data = (char*)str.c_str();
 	unsigned size = str.size() * sizeof(char);
 	
 	NSString* nsstr = [[[NSString alloc] initWithBytes:data length:size encoding:NSUTF32LittleEndianStringEncoding] autorelease];
+	*/
     [pb setString: nsstr forType:NSStringPboardType];	
 }
 
 String CocoaCore::getClipboardString() {
-	
+	NSPasteboard *pb = [NSPasteboard generalPasteboard];		
+	NSString* retString = [pb stringForType:NSStringPboardType];
+	return [retString UTF8String];
 }
 
 void CocoaCore::setVideoMode(int xRes, int yRes, bool fullScreen, bool vSync, int aaLeve, int anisotropyLevel) {
@@ -294,7 +296,7 @@ vector<Polycode::Rectangle> CocoaCore::getVideoModes() {
 
 CocoaCore::~CocoaCore() {
 	printf("Shutting down cocoa core\n");
-	[view setCore:nil];	
+	[glView setCore:nil];	
 	shutdownGamepad();
 	if(fullScreen) {
 		[glView exitFullScreenModeWithOptions:nil];

+ 1 - 0
IDE/Contents/Include/PolycodeRemoteDebugger.h

@@ -41,6 +41,7 @@ class PolycodeRemoteDebugger : EventHandler {
 		
 		void handleEvent(Event *event);
 			
+		bool isConnected();
 			
 		static const int EVENT_DEBUG_ERROR = 32;
 		static const int EVENT_DEBUG_PRINT = 33;

+ 5 - 1
IDE/Contents/Source/PolycodeConsole.cpp

@@ -56,7 +56,11 @@ void PolycodeConsole::handleEvent(Event *event) {
 			_print(">"+consoleTextInput->getText());
 			_print("\n");
 			if(debugger) {
-				debugger->injectCode(consoleTextInput->getText());
+				if(!debugger->isConnected()) {
+					_print("Unable to inject code. No debugger clients connected.\n");
+				} else {
+					debugger->injectCode(consoleTextInput->getText());
+				}
 			}	
 
 			consoleTextInput->setText("");

+ 4 - 0
IDE/Contents/Source/PolycodeRemoteDebugger.cpp

@@ -35,6 +35,10 @@ PolycodeRemoteDebugger::~PolycodeRemoteDebugger() {
 
 }
 
+bool PolycodeRemoteDebugger::isConnected() {
+	return (debuggerClients.size() > 0);
+}
+
 void PolycodeRemoteDebugger::injectCode(String code) {
 	server->sendReliableDataToAllClients((char*)code.c_str(), code.length()+1, EVENT_INJECT_CODE);
 }

+ 14 - 0
Modules/Contents/UI/Include/PolyUITextInput.h

@@ -38,6 +38,8 @@
 
 using namespace std;
 
+#define MAX_TEXTINPUT_UNDO_STATES 30
+
 namespace Polycode {
 
 	class _PolyExport UITextInput : public UIElement {
@@ -63,6 +65,12 @@ namespace Polycode {
 			void deleteSelection();		
 			void selectAll();
 		
+			void Undo();
+			void Redo();
+			void Cut();
+			void Copy();
+			void Paste();
+					
 			void Resize(Number width, Number height);
 			
 			void setNumberOnly(bool val);
@@ -113,6 +121,12 @@ namespace Polycode {
 			bool doSelectToCaret;
 		
 			ScreenEntity *linesContainer;
+			
+			vector<ScreenLabel*> linesToDelete;		
+			
+			String undoStates[MAX_TEXTINPUT_UNDO_STATES];
+			int undoStateIndex;
+			int maxRedoIndex;
 		
 			bool multiLine;
 			Timer *blinkTimer;

+ 85 - 25
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -66,6 +66,8 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 		rectHeight = fontSize+12;
 	} 
 	
+	linesContainer = new ScreenEntity();	
+	
 	lineSpacing = conf->getNumericValue("Polycode", "textEditLineSpacing");
 	
 	Number st = conf->getNumericValue("Polycode", "textBgSkinT");
@@ -81,6 +83,7 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 	
 	addChild(inputRect);
 	
+
 	
 	
 	inputRect->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
@@ -96,25 +99,25 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 	selectorRectTop->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 	selectorRectTop->setColor(181.0f/255.0f, 213.0f/255.0f, 255.0f/255.0f, 1);
 	selectorRectTop->visible = false;
-	addChild(selectorRectTop);
+	linesContainer->addChild(selectorRectTop);
 
 	selectorRectMiddle = new ScreenShape(ScreenShape::SHAPE_RECT, 1,1);
 	selectorRectMiddle->setPositionMode(ScreenEntity::POSITION_TOPLEFT);	
 	selectorRectMiddle->setColor(181.0f/255.0f, 213.0f/255.0f, 255.0f/255.0f, 1);
 	selectorRectMiddle->visible = false;
-	addChild(selectorRectMiddle);
+	linesContainer->addChild(selectorRectMiddle);
 
 	selectorRectBottom = new ScreenShape(ScreenShape::SHAPE_RECT, 1,1);
 	selectorRectBottom->setPositionMode(ScreenEntity::POSITION_TOPLEFT);	
 	selectorRectBottom->setColor(181.0f/255.0f, 213.0f/255.0f, 255.0f/255.0f, 1);
 	selectorRectBottom->visible = false;
-	addChild(selectorRectBottom);
+	linesContainer->addChild(selectorRectBottom);
 		
 	
 	blinkerRect = new ScreenShape(ScreenShape::SHAPE_RECT, 1, fontSize+4,0,0);
 	blinkerRect->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 	blinkerRect->setColor(0,0,0,1);
-	addChild(blinkerRect);
+	linesContainer->addChild(blinkerRect);
 	blinkerRect->visible = false;
 	blinkerRect->setPosition(0,3);
 	
@@ -128,7 +131,6 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 	
 	updateCaretPosition();
 		
-	linesContainer = new ScreenEntity();
 	
 	scrollContainer = NULL;
 	
@@ -543,8 +545,8 @@ void UITextInput::removeLine(ScreenLabel *line) {
 			lines.erase(lines.begin()+i);
 		}
 	}
-	removeChild(line);
-	delete line;
+	linesContainer->removeChild(line);
+	linesToDelete.push_back(line);
 	restructLines();
 }
 
@@ -552,21 +554,43 @@ void UITextInput::selectAll() {
 	setSelection(0, lines.size()-1, 0, lines[lines.size()-1]->getText().length());
 }
 
-void UITextInput::insertText(String text) {
+void UITextInput::insertText(String text) {	
 	vector<String> strings = text.split("\n");
-	int numLines = lines.size();
-	for(int i=0; i < strings.size(); i++) {
-		if(i < numLines) {
-			lines[i]->setText(strings[i]);
-		} else {
-			numLines++;		
-			ScreenLabel *newLine = new ScreenLabel(L"", fontSize, fontName, Label::ANTIALIAS_FULL);
-			newLine->setColor(0,0,0,1);
-			linesContainer->addChild(newLine);			
-			lines.push_back(newLine);
-			newLine->setText(strings[i]);
+
+	if(hasSelection)
+		deleteSelection();
+
+	if(strings.size() > 1) {
+		String ctext = currentLine->getText();		
+		String text2 = ctext.substr(caretPosition, ctext.length()-caretPosition);
+		ctext = ctext.substr(0,caretPosition);
+		ctext += strings[0];
+		currentLine->setText(ctext);		
+		caretPosition = ctext.length();
+		
+		for(int i=1; i < strings.size()-1; i++) {
+			insertLine(true);
+			ctext = strings[i];
+			currentLine->setText(ctext);
+			caretPosition = ctext.length();			
 		}
+		
+		insertLine(true);
+		ctext = strings[strings.size()-1] + text2;
+		caretPosition = ctext.length();
+		currentLine->setText(ctext);		
+		
+	} else {
+		String ctext = currentLine->getText();		
+		String text2 = ctext.substr(caretPosition, ctext.length()-caretPosition);
+		ctext = ctext.substr(0,caretPosition);
+		ctext += text + text2;
+		caretPosition += text.length();
+		currentLine->setText(ctext);			
 	}
+	
+	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);	
+	updateCaretPosition();		
 	restructLines();	
 }
 
@@ -596,12 +620,34 @@ UIScrollContainer *UITextInput::getScrollContainer() {
 	return scrollContainer;
 }
 
+void UITextInput::Undo() {
+
+}
+
+void UITextInput::Redo() {
+
+}
+
+void UITextInput::Cut() {
+	Copy();
+	if(hasSelection) {
+		deleteSelection();
+	}	
+}
+
+void UITextInput::Copy() {
+	CoreServices::getInstance()->getCore()->copyStringToClipboard(getSelectionText());	
+}
+
+void UITextInput::Paste() {
+	insertText(CoreServices::getInstance()->getCore()->getClipboardString());
+}
+
 void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 	
 	if(!hasFocus)
 		return;
-	
-	
+		
 //	Logger::log("UCHAR: %d\n", charCode);	
 	
 	CoreInput *input = CoreServices::getInstance()->getCore()->getInput();	
@@ -612,16 +658,25 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 	}
 
 	if(key == KEY_c && (input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER))) {
-		CoreServices::getInstance()->getCore()->copyStringToClipboard(getSelectionText());
+		Copy();
 		return;
 	}
 
 	if(key == KEY_x && (input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER))) {
+		Cut();
+		return;
+	}
+	
+	if(key == KEY_z  && (input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER))) {
+		return;
+	}
+
+	if(key == KEY_y  && (input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER))) {
 		return;
 	}
 
 	if(key == KEY_v && (input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER))) {
-		insertText(CoreServices::getInstance()->getCore()->getClipboardString());
+		Paste();
 		return;
 	}	
 	
@@ -842,6 +897,10 @@ void UITextInput::Update() {
 //		inputRect->setStrokeColor(1.0f, 1.0f, 1.0f, 0.1f);
 	}
 	
+	for(int i=0; i < linesToDelete.size(); i++) {
+		delete linesToDelete[i];
+	}
+	linesToDelete.clear();
 }
 
 UITextInput::~UITextInput() {
@@ -857,7 +916,7 @@ void UITextInput::handleEvent(Event *event) {
 				} else {
 					hasFocus = true;
 				}
-				setCaretToMouse(((InputEvent*)event)->mousePosition.x, ((InputEvent*)event)->mousePosition.y);
+				setCaretToMouse(((InputEvent*)event)->mousePosition.x, ((InputEvent*)event)->mousePosition.y - linesContainer->getPosition().y);
 				draggingSelection = true;
 			break;
 			case InputEvent::EVENT_MOUSEUP:
@@ -867,8 +926,9 @@ void UITextInput::handleEvent(Event *event) {
 				selectWordAtCaret();
 			break;
 			case InputEvent::EVENT_MOUSEMOVE:
+				CoreServices::getInstance()->getCore()->setCursor(CURSOR_TEXT);			
 				if(draggingSelection) {
-					dragSelectionTo(((InputEvent*)event)->mousePosition.x, ((InputEvent*)event)->mousePosition.y);		
+					dragSelectionTo(((InputEvent*)event)->mousePosition.x, ((InputEvent*)event)->mousePosition.y - linesContainer->getPosition().y);		
 				}
 			break;
 			case InputEvent::EVENT_MOUSEOVER: