فهرست منبع

Find support in UITextInput and IDE text editor

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

+ 1 - 0
Core/Contents/Include/PolyEvent.h

@@ -63,6 +63,7 @@ namespace Polycode {
 			
 			static const int COMPLETE_EVENT = 0;
 			static const int CHANGE_EVENT = 1;
+			static const int CANCEL_EVENT = 2;			
 			
 			bool deleteOnDispatch;
 						

+ 11 - 0
Core/Contents/Include/PolyString.h

@@ -123,6 +123,17 @@ namespace Polycode {
 			*/													
 			size_t find_last_of(const String& str, size_t pos = std::wstring::npos ) { return contents.find_last_of(str.contents, pos); }
 		
+			
+			/**
+			* 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.
+			*/			
+			size_t find_first_of(const String &str, size_t pos = 0) {
+				return contents.find_first_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; }		

+ 16 - 10
IDE/Build/Mac OS X/English.lproj/MainMenu.xib

@@ -678,7 +678,6 @@
 							<string key="NSFrameSize">{800, 600}</string>
 							<reference key="NSSuperview" ref="439893737"/>
 							<reference key="NSWindow"/>
-							<reference key="NSNextKeyView"/>
 							<object class="NSOpenGLPixelFormat" key="NSPixelFormat">
 								<object class="NSMutableData" key="NSPixelAttributes">
 									<bytes key="NS.bytes">AAAAYAAAAAA</bytes>
@@ -885,14 +884,6 @@
 					</object>
 					<int key="connectionID">240</int>
 				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBActionConnection" key="connection">
-						<string key="label">performFindPanelAction:</string>
-						<reference key="source" ref="1014"/>
-						<reference key="destination" ref="447796847"/>
-					</object>
-					<int key="connectionID">241</int>
-				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBActionConnection" key="connection">
 						<string key="label">centerSelectionInVisibleArea:</string>
@@ -1125,6 +1116,14 @@
 					</object>
 					<int key="connectionID">589</int>
 				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">findText:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="447796847"/>
+					</object>
+					<int key="connectionID">590</int>
+				</object>
 			</object>
 			<object class="IBMutableOrderedSet" key="objectRecords">
 				<object class="NSArray" key="orderedObjects">
@@ -1890,7 +1889,7 @@
 				<reference key="dict.values" ref="0"/>
 			</object>
 			<nil key="sourceID"/>
-			<int key="maxID">589</int>
+			<int key="maxID">590</int>
 		</object>
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1904,6 +1903,7 @@
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>browseExamples:</string>
 							<string>closeProject:</string>
+							<string>findText:</string>
 							<string>newFile:</string>
 							<string>newGroup:</string>
 							<string>newProject:</string>
@@ -1927,6 +1927,7 @@
 							<string>id</string>
 							<string>id</string>
 							<string>id</string>
+							<string>id</string>
 						</object>
 					</object>
 					<object class="NSMutableDictionary" key="actionInfosByName">
@@ -1935,6 +1936,7 @@
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>browseExamples:</string>
 							<string>closeProject:</string>
+							<string>findText:</string>
 							<string>newFile:</string>
 							<string>newGroup:</string>
 							<string>newProject:</string>
@@ -1955,6 +1957,10 @@
 								<string key="name">closeProject:</string>
 								<string key="candidateClassName">id</string>
 							</object>
+							<object class="IBActionInfo">
+								<string key="name">findText:</string>
+								<string key="candidateClassName">id</string>
+							</object>
 							<object class="IBActionInfo">
 								<string key="name">newFile:</string>
 								<string key="candidateClassName">id</string>

+ 1 - 0
IDE/Build/Mac OS X/PolycodeAppDelegate.h

@@ -63,5 +63,6 @@ public:
 -(IBAction) newFile: (id) sender;
 -(IBAction) openProject: (id) sender;
 -(IBAction) saveFile: (id) sender;
+-(IBAction) findText: (id) sender;
 
 @end

+ 5 - 0
IDE/Build/Mac OS X/PolycodeAppDelegate.m

@@ -115,4 +115,9 @@
 	app->saveFile();
 }
 
+-(IBAction) findText: (id) sender {
+	app->findText();
+}
+
+
 @end

+ 2 - 0
IDE/Contents/Include/PolycodeEditor.h

@@ -50,6 +50,8 @@ protected:
 	String filePath;
 	bool _isReadOnly;
 	
+	Vector2 editorSize;
+	
 	String editorType;
 };
 

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

@@ -69,6 +69,7 @@ public:
 	void openProject();
 	void closeProject();	
 	void saveFile();
+	void findText();
 	
 	void refreshProject();
 	

+ 22 - 0
IDE/Contents/Include/PolycodeTextEditor.h

@@ -28,6 +28,19 @@
 
 using namespace Polycode;
 
+class FindBar : public UIElement {
+	public:
+		FindBar();
+		~FindBar();
+		
+		void setBarWidth(int width);
+		
+		UITextInput *findInput;
+	protected:
+		ScreenShape *barBg;
+		
+};
+
 class PolycodeSyntaxHighlighter : public UITextInputSyntaxHighlighter {
 	public:
 		PolycodeSyntaxHighlighter(String extension);
@@ -56,10 +69,19 @@ public:
 	void Resize(int x, int y);
 	void saveFile();
 	
+	void handleEvent(Event *event);
+	
+	void hideFindBar();
+	void showFindBar();
+	
 	void highlightLine(unsigned int lineNumber);
 	
 protected:
 
+	FindBar *findBar;
+	
+	String lastFindString;
+
 	PolycodeSyntaxHighlighter *syntaxHighligher;
 	UITextInput *textInput;
 };

+ 1 - 0
IDE/Contents/Source/PolycodeEditor.cpp

@@ -49,6 +49,7 @@ PolycodeEditor::PolycodeEditor(bool _isReadOnly) : ScreenEntity() {
 }
 
 void PolycodeEditor::Resize(int x, int y) {
+	editorSize = Vector2(x,y);
 	Vector2 pos = getScreenPosition();
 	scissorBox.setRect(pos.x,pos.y, x, y);	
 }

+ 9 - 0
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -186,6 +186,15 @@ void PolycodeIDEApp::runProject() {
 	}
 }
 
+void PolycodeIDEApp::findText() {
+	if(editorManager->getCurrentEditor()) {
+		if(editorManager->getCurrentEditor()->getEditorType() == "PolycodeTextEditor") {
+			PolycodeTextEditor *textEditor = (PolycodeTextEditor*) editorManager->getCurrentEditor();
+			textEditor->showFindBar();
+		}
+	}
+}
+
 void PolycodeIDEApp::saveFile() {
 	if(editorManager->getCurrentEditor()) {
 		editorManager->getCurrentEditor()->saveFile();

+ 77 - 2
IDE/Contents/Source/PolycodeTextEditor.cpp

@@ -211,6 +211,13 @@ bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 	textInput = new UITextInput(true, 100, 100);
 	addChild(textInput);	
 	
+	findBar = new FindBar();
+	findBar->visible = false;
+	addChild(findBar);
+	
+	findBar->findInput->addEventListener(this, Event::COMPLETE_EVENT);
+	findBar->findInput->addEventListener(this, Event::CANCEL_EVENT);
+		
 	syntaxHighligher = NULL;
 	
 	if(filePath.extension == "lua") {
@@ -228,6 +235,42 @@ bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 	return true;
 }
 
+void PolycodeTextEditor::handleEvent(Event *event) {
+	if(event->getDispatcher() == findBar->findInput) {
+		if(event->getEventType() == "Event") {
+		
+			if(event->getEventCode() == Event::CANCEL_EVENT) {
+				hideFindBar();
+			}
+					
+			if(event->getEventCode() == Event::COMPLETE_EVENT) {
+				if(findBar->findInput->getText() != "") {
+				if(findBar->findInput->getText() != lastFindString) {
+					lastFindString = findBar->findInput->getText();
+					textInput->findString(lastFindString);
+				} else {
+					textInput->findNext();
+				}
+				}
+			}
+			
+		}
+	}	
+	PolycodeEditor::handleEvent(event);
+}
+
+void PolycodeTextEditor::showFindBar() {
+	findBar->visible = true;
+	findBar->focusChild(findBar->findInput);
+	Resize(editorSize.x, editorSize.y);
+}
+
+void PolycodeTextEditor::hideFindBar() {
+	findBar->visible = false;
+	focusChild(textInput);
+	Resize(editorSize.x, editorSize.y);
+}
+	
 void PolycodeTextEditor::highlightLine(unsigned int lineNumber) {
 	int lineSize = textInput->getLineText(lineNumber-1).length();
 	textInput->setSelection(lineNumber-1, lineNumber-1, 0, lineSize);
@@ -242,7 +285,39 @@ void PolycodeTextEditor::saveFile() {
 }
 
 void PolycodeTextEditor::Resize(int x, int y) {
-	textInput->Resize(x,y);
-	PolycodeEditor::Resize(x,y);	
+	findBar->setBarWidth(x);	
+	
+	if(findBar->visible) {
+		textInput->Resize(x,y-findBar->getHeight());
+		textInput->setPosition(0,findBar->getHeight());
+	} else {
+		textInput->Resize(x,y);
+		textInput->setPosition(0,0);
+	}
+	PolycodeEditor::Resize(x,y);
+}
+
+FindBar::FindBar() : UIElement() {
+	barBg = new ScreenShape(ScreenShape::SHAPE_RECT, 30,30);
+	barBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+	barBg->setColorInt(255, 222, 0, 255);
+	addChild(barBg);
+	this->height = 30;
+	
+	ScreenLabel *findLabel = new ScreenLabel("Find:", 16);
+	addChild(findLabel);
+	findLabel->setColor(0.0, 0.0, 0.0, 0.3);
+	findLabel->setPosition(10,4);
+	
+	findInput = new UITextInput(false, 100, 12);
+	addChild(findInput);
+	findInput->setPosition(60, 4);
+}
+
+FindBar::~FindBar(){
+
 }
 
+void FindBar::setBarWidth(int width) {
+	barBg->setShapeSize(width, 30);
+}

+ 16 - 1
Modules/Contents/UI/Include/PolyUITextInput.h

@@ -65,6 +65,13 @@ namespace Polycode {
 			virtual std::vector<SyntaxHighlightToken> parseText(String text) = 0;
 	};
 
+	class _PolyExport FindMatch {
+		public:
+			unsigned int lineNumber;
+			unsigned int caretStart;
+			unsigned int caretEnd;							
+	};
+
 	class _PolyExport UITextInput : public UIElement {
 		public:
 			UITextInput(bool multiLine, Number width, Number height);
@@ -95,6 +102,11 @@ namespace Polycode {
 			void Copy();
 			void Paste();
 			
+			void findString(String stringToFind);
+			void findNext();
+			void findPrevious();
+			void findCurrent();
+						
 			void showLine(unsigned int lineNumber, bool top);
 
 			void setSyntaxHighlighter(UITextInputSyntaxHighlighter *syntaxHighliter);
@@ -161,7 +173,10 @@ namespace Polycode {
 		
 			ScreenEntity *linesContainer;
 			
-			vector<ScreenLabel*> linesToDelete;		
+			vector<ScreenLabel*> linesToDelete;	
+			
+			std::vector<FindMatch> findMatches;
+			int findIndex;
 			
 			UITextInputUndoState undoStates[MAX_TEXTINPUT_UNDO_STATES];
 			int undoStateIndex;

+ 16 - 0
Modules/Contents/UI/Source/PolyUIScrollContainer.cpp

@@ -140,6 +140,17 @@ void UIScrollContainer::setContentSize(Number newContentWidth, Number newContent
 }
 
 void UIScrollContainer::setScrollValue(Number xScroll, Number yScroll) {
+	if(xScroll < 0)
+		xScroll = 0;
+	if(xScroll > 1)
+		xScroll = 1;
+		
+	if(yScroll < 0)
+		yScroll = 0;
+	if(yScroll > 1)
+		yScroll = 1;
+
+		
 	hScrollBar->scrollTo(xScroll);
 	vScrollBar->scrollTo(yScroll);	
 }
@@ -162,12 +173,17 @@ void UIScrollContainer::handleEvent(Event *event) {
 	if(event->getDispatcher() == vScrollBar) {
 		if(event->getEventCode() == Event::CHANGE_EVENT) {
 			scrollChild->setPositionY(floor(((-contentHeight+height) )*vScrollBar->getScrollValue()));
+			if(scrollChild->getPosition().y > 0)
+				scrollChild->setPositionY(0);
 		}
 	}
 	
 	if(event->getDispatcher() == hScrollBar) {
 		if(event->getEventCode() == Event::CHANGE_EVENT) {
 			scrollChild->setPositionX(floor(((-contentWidth+width) )*hScrollBar->getScrollValue()));
+			if(scrollChild->getPosition().x > 0)
+				scrollChild->setPositionX(0);
+			
 		}
 	}
 	

+ 73 - 0
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -598,6 +598,74 @@ void UITextInput::selectWordAtCaret() {
 	updateCaretPosition();	
 }
 
+void UITextInput::findString(String stringToFind) {
+	clearSelection();
+	findMatches.clear();
+	
+	for(int i=0; i < lines.size(); i++) {
+
+
+		String lineText = lines[i]->getText();
+		
+		int offset = 0;				
+		int retVal = -1;
+		do {
+			retVal = lineText.find(stringToFind, offset);
+			if(retVal != -1) {
+				FindMatch match;
+				match.lineNumber = i;
+				match.caretStart = retVal;
+				match.caretEnd = retVal + stringToFind.length();
+				findMatches.push_back(match);		
+				offset = retVal + stringToFind.length();
+			}			
+		} while(retVal != -1);
+		
+	}
+	
+	if(findMatches.size() > 0) {
+		findIndex = 0;
+		findCurrent();
+	}
+}
+
+void UITextInput::findNext() {
+	if(findMatches.size() == 0)
+		return;
+	findIndex++;
+	if(findIndex == findMatches.size()) {
+		findIndex = 0;
+	}
+	findCurrent();
+}
+
+void UITextInput::findPrevious() {
+	if(findMatches.size() == 0)
+		return;
+
+	findIndex--;
+	if(findIndex < 0) {
+		findIndex = findMatches.size()-1;
+	}
+	findCurrent();		
+}
+
+void UITextInput::findCurrent() {
+	if(findMatches.size() == 0)
+		return;
+
+	FindMatch match = findMatches[findIndex];
+
+	currentLine = lines[match.lineNumber];
+	caretPosition = match.caretStart;
+	lineOffset = match.lineNumber;
+	updateCaretPosition();
+
+	showLine(findMatches[findIndex].lineNumber, false);	
+	
+	setSelection(match.lineNumber, match.lineNumber, match.caretStart, match.caretEnd);
+}
+
 void UITextInput::setCaretToMouse(Number x, Number y) {
 	clearSelection();
 	x -= padding;
@@ -990,6 +1058,11 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 		return;
 	}
 	
+	if(key == KEY_ESCAPE) {
+		if(!multiLine) {
+			dispatchEvent(new Event(), Event::CANCEL_EVENT);		
+		}
+	}
 	
 	if(key == KEY_RETURN) {
 		if(multiLine) {