Răsfoiți Sursa

Beginnings of a syntax highlight engine

Ivan Safrin 13 ani în urmă
părinte
comite
5f8cc87ab9

+ 2 - 2
Core/Contents/Include/PolyString.h

@@ -103,7 +103,7 @@ namespace Polycode {
 			* Find last occurrence of content in string. 
 			* @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
+			* @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); }
 			
@@ -111,7 +111,7 @@ namespace Polycode {
 			* Find content in string. 
 			* @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
+			* @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); }
 			

+ 1 - 1
IDE/Contents/Include/PolycodeEditor.h

@@ -32,7 +32,7 @@ public:
 	PolycodeEditor(bool _isReadOnly);
 	virtual ~PolycodeEditor();
 	
-	virtual bool openFile(String filePath){ this->filePath = filePath; }
+	virtual bool openFile(OSFileEntry filePath){ this->filePath = filePath.fullPath; }
 	virtual void Resize(int x, int y);
 	
 	virtual void saveFile(){};

+ 1 - 1
IDE/Contents/Include/PolycodeFontEditor.h

@@ -33,7 +33,7 @@ public:
 	PolycodeFontEditor();
 	virtual ~PolycodeFontEditor();
 	
-	bool openFile(String filePath);
+	bool openFile(OSFileEntry filePath);
 	void Resize(int x, int y);
 	
 protected:

+ 1 - 1
IDE/Contents/Include/PolycodeImageEditor.h

@@ -32,7 +32,7 @@ class PolycodeImageEditor : public PolycodeEditor {
 	PolycodeImageEditor();
 	virtual ~PolycodeImageEditor();
 	
-	bool openFile(String filePath);
+	bool openFile(OSFileEntry filePath);
 	void Resize(int x, int y);
 	
 	protected:

+ 1 - 1
IDE/Contents/Include/PolycodeProjectEditor.h

@@ -34,7 +34,7 @@ class PolycodeProjectEditor : public PolycodeEditor {
 	PolycodeProjectEditor();
 	virtual ~PolycodeProjectEditor();
 	
-	bool openFile(String filePath);
+	bool openFile(OSFileEntry filePath);
 	void Resize(int x, int y);
 	void saveFile();
 	

+ 1 - 1
IDE/Contents/Include/PolycodeScreenEditor.h

@@ -33,7 +33,7 @@ class PolycodeScreenEditor : public PolycodeEditor {
 	PolycodeScreenEditor();
 	virtual ~PolycodeScreenEditor();
 	
-	bool openFile(String filePath);
+	bool openFile(OSFileEntry filePath);
 	void Resize(int x, int y);
 	
 	void syncTransformToSelected();

+ 21 - 1
IDE/Contents/Include/PolycodeTextEditor.h

@@ -28,17 +28,37 @@
 
 using namespace Polycode;
 
+class PolycodeSyntaxHighlighter : public UITextInputSyntaxHighlighter {
+	public:
+		PolycodeSyntaxHighlighter(String extension);
+		~PolycodeSyntaxHighlighter();
+	
+		bool contains(String part, std::vector<String> list);
+	
+		std::vector<SyntaxHighlightToken> parseText(String text);		
+		std::vector<SyntaxHighlightToken> parseLua(String text);
+		
+		Color colorScheme[16];
+				
+		
+	protected:
+	
+		std::vector<String> separators;
+		std::vector<String> keywords;		
+};
+
 class PolycodeTextEditor : public PolycodeEditor {
 public:
 	PolycodeTextEditor();
 	virtual ~PolycodeTextEditor();
 	
-	bool openFile(String filePath);
+	bool openFile(OSFileEntry filePath);
 	void Resize(int x, int y);
 	void saveFile();
 	
 protected:
 
+	PolycodeSyntaxHighlighter *syntaxHighligher;
 	UITextInput *textInput;
 };
 

+ 7 - 7
IDE/Contents/Source/PolycodeFontEditor.cpp

@@ -30,9 +30,9 @@ PolycodeFontEditor::~PolycodeFontEditor() {
 	
 }
 
-bool PolycodeFontEditor::openFile(String filePath) {
+bool PolycodeFontEditor::openFile(OSFileEntry filePath) {
 	
-	CoreServices::getInstance()->getFontManager()->registerFont(filePath, filePath);
+	CoreServices::getInstance()->getFontManager()->registerFont(filePath.fullPath, filePath.fullPath);
 	
 	
 	
@@ -55,19 +55,19 @@ bool PolycodeFontEditor::openFile(String filePath) {
 	anchor->addChild(bg);
 	anchor->snapToPixels = true;
 	
-	editorLabel = new ScreenLabel(L"ABCDEFGHIJKLM", 48, filePath, Label::ANTIALIAS_FULL);
+	editorLabel = new ScreenLabel(L"ABCDEFGHIJKLM", 48, filePath.fullPath, Label::ANTIALIAS_FULL);
 	anchor->addChild(editorLabel);
-	editorLabel2 = new ScreenLabel(L"NOPQRSTUVWXYZ", 48, filePath, Label::ANTIALIAS_FULL);
+	editorLabel2 = new ScreenLabel(L"NOPQRSTUVWXYZ", 48, filePath.fullPath, Label::ANTIALIAS_FULL);
 	editorLabel2->setPosition(0, 48);
 	editorLabel->setPosition((editorLabel2->getWidth()-editorLabel->getWidth())/2, 0);
 	anchor->addChild(editorLabel2);
-	editorLabel3 = new ScreenLabel(L"abcdefghijklm", 48, filePath, Label::ANTIALIAS_FULL);
+	editorLabel3 = new ScreenLabel(L"abcdefghijklm", 48, filePath.fullPath, Label::ANTIALIAS_FULL);
 	editorLabel3->setPosition((editorLabel2->getWidth()-editorLabel3->getWidth())/2, 96);	
 	anchor->addChild(editorLabel3);
-	editorLabel4 = new ScreenLabel(L"nopqrstuvwxyz", 48, filePath, Label::ANTIALIAS_FULL);
+	editorLabel4 = new ScreenLabel(L"nopqrstuvwxyz", 48, filePath.fullPath, Label::ANTIALIAS_FULL);
 	editorLabel4->setPosition((editorLabel2->getWidth()-editorLabel4->getWidth())/2, 144);		
 	anchor->addChild(editorLabel4);
-	editorLabel5 = new ScreenLabel(L"1234567890", 48, filePath, Label::ANTIALIAS_FULL);
+	editorLabel5 = new ScreenLabel(L"1234567890", 48, filePath.fullPath, Label::ANTIALIAS_FULL);
 	editorLabel5->setPosition((editorLabel2->getWidth()-editorLabel5->getWidth())/2, 192);			
 	anchor->addChild(editorLabel5);
 

+ 1 - 1
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -224,7 +224,7 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 			} else {
 				editor = editorManager->createEditorForExtension(selectedData->fileEntry.extension);
 				if(editor) {
-					if(editor->openFile(selectedData->fileEntry.fullPath)) {
+					if(editor->openFile(selectedData->fileEntry)) {
 						frame->addEditor(editor);					
 						frame->showEditor(editor);
 					} else {

+ 2 - 2
IDE/Contents/Source/PolycodeImageEditor.cpp

@@ -30,7 +30,7 @@ PolycodeImageEditor::~PolycodeImageEditor() {
 	
 }
 
-bool PolycodeImageEditor::openFile(String filePath) {
+bool PolycodeImageEditor::openFile(OSFileEntry filePath) {
 	
 	grid = new ScreenImage("editorGrid.png");
 	
@@ -41,7 +41,7 @@ bool PolycodeImageEditor::openFile(String filePath) {
 	grid->getTexture()->recreateFromImageData();	
 	
 	
-	editorImage = new ScreenImage(filePath);
+	editorImage = new ScreenImage(filePath.fullPath);
 	addChild(editorImage);
 	
 	PolycodeEditor::openFile(filePath);

+ 2 - 2
IDE/Contents/Source/PolycodeProjectEditor.cpp

@@ -158,10 +158,10 @@ PolycodeProjectEditor::~PolycodeProjectEditor() {
 	
 }
 
-bool PolycodeProjectEditor::openFile(String filePath) {
+bool PolycodeProjectEditor::openFile(OSFileEntry filePath) {
 
 
-	if(!configFile.loadFromXML(filePath)) {
+	if(!configFile.loadFromXML(filePath.fullPath)) {
 		return false;
 	}
 	

+ 1 - 1
IDE/Contents/Source/PolycodeScreenEditor.cpp

@@ -86,7 +86,7 @@ PolycodeScreenEditor::~PolycodeScreenEditor() {
 	
 }
 
-bool PolycodeScreenEditor::openFile(String filePath) {
+bool PolycodeScreenEditor::openFile(OSFileEntry filePath) {
 	
 	PolycodeEditor::openFile(filePath);	
 	return true;

+ 142 - 3
IDE/Contents/Source/PolycodeTextEditor.cpp

@@ -22,20 +22,159 @@
 
 #include "PolycodeTextEditor.h"
 
+PolycodeSyntaxHighlighter::PolycodeSyntaxHighlighter(String extension) {
+
+	colorScheme[0] = Color(0.0, 0.0, 0.0, 1.0);
+	colorScheme[1] = Color(0.0, 0.53, 0.0, 1.0);
+	colorScheme[2] = Color(0.79, 0.0, 0.63, 1.0);
+	colorScheme[3] = Color(126.0/255.0, 73.0/255.0, 42.0/255.0, 1.0);
+	colorScheme[4] = Color(227.0/255.0, 11.0/255.0, 0.0/255.0, 1.0);
+	colorScheme[5] = Color(39.0/255.0, 90.0/255.0, 94.0/255.0, 1.0);	
+	colorScheme[6] = Color(56.0/255.0, 0.0/255.0, 218.0/255.0, 1.0);
+	
+//	String separators = " ;()\t\n=+-/\\'\"";	
+//	String keywords = "true,false,";
+	
+	separators = String(" ; ( ) \t \n = + - / \\ ' \"").split(" ");
+	separators.push_back(" ");
+	
+	keywords = String("true false class self break do end else elseif function if local nil not or repeat return then until while").split(" ");
+}
+
+PolycodeSyntaxHighlighter::~PolycodeSyntaxHighlighter() {
+
+}
+
+bool PolycodeSyntaxHighlighter::contains(String part, std::vector<String> list) {
+	for(int i=0; i < list.size(); i++) {
+		if(list[i] == part)
+			return true;
+	}
+	return false;
+}
+
+std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseText(String text) {
+	return parseLua(text);
+}
+	
+std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseLua(String text) {
+	std::vector<SyntaxHighlightToken> tokens;
+	
+	const int MODE_GENERAL = 0;
+	const int MODE_COMMENT = 1;
+	const int MODE_STRING = 2;
+	const int MODE_METHOD = 3;
+	const int MODE_KEYWORD = 4;
+					
+	int mode = MODE_GENERAL;
+	
+	bool isComment = false;
+	
+	String line = "";
+	
+	char lastSeparator = ' ';
+	
+	for(int i=0; i < text.length(); i++) {
+		char ch = text[i];				
+		if(contains(String(ch), separators)) {			
+
+			unsigned int type = mode;
+			unsigned int ch_type = mode;
+
+	
+			if(ch == '\"')
+				ch_type = MODE_STRING;
+	
+			if(mode != MODE_STRING && ch == '(') {
+				type = MODE_METHOD;
+			}
+
+			if(mode != MODE_STRING) {
+				if(contains(line, keywords)) {
+					type = MODE_KEYWORD;
+				}
+			}
+	
+			if(isComment) {
+				type = MODE_COMMENT;
+				ch_type = MODE_COMMENT;
+			}
+	
+			if(line != "")
+				tokens.push_back(SyntaxHighlightToken(line, type));
+			tokens.push_back(SyntaxHighlightToken(String(ch), ch_type));
+
+			if(ch == '-' && lastSeparator == '-' && mode != MODE_STRING) {
+				isComment = true;
+				tokens[tokens.size()-1].type = MODE_COMMENT;
+				tokens[tokens.size()-2].type = MODE_COMMENT;				
+			}
+			
+			if(ch == '\n' )
+				isComment = false;
+				
+
+			if(ch == '\"') {
+				if(mode == MODE_STRING) {
+					mode = MODE_GENERAL;	
+				} else {
+					mode = MODE_STRING;
+				}
+			}	
+						
+			line = "";
+			lastSeparator = ch;			
+		} else {
+			line += String(ch);
+		}
+	}
+	
+	for(int i=0; i < tokens.size(); i++) {
+		switch(tokens[i].type) {
+			case MODE_STRING:
+				tokens[i].color = colorScheme[4];			
+			break;
+			case MODE_COMMENT:
+				tokens[i].color = colorScheme[1];			
+			break;			
+			case MODE_METHOD:
+				tokens[i].color = colorScheme[3];			
+			break;			
+			case MODE_KEYWORD:
+				tokens[i].color = colorScheme[2];
+			break;												
+			default:
+				tokens[i].color = colorScheme[0];
+			break;
+		}
+//		printf("%s(%d)", tokens[i].text.c_str(), tokens[i].type);		
+	}
+	
+	return tokens;
+}
+
 PolycodeTextEditor::PolycodeTextEditor() : PolycodeEditor(true){
 }
 
 PolycodeTextEditor::~PolycodeTextEditor() {
-	
+	if(syntaxHighligher)
+		delete syntaxHighligher;
 }
 
-bool PolycodeTextEditor::openFile(String filePath) {
+bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 	
 	textInput = new UITextInput(true, 100, 100);
 	addChild(textInput);	
 	
+	syntaxHighligher = NULL;
+	
+	if(filePath.extension == "lua") {
+		syntaxHighligher = new PolycodeSyntaxHighlighter(filePath.extension);
+		textInput->setSyntaxHighlighter(syntaxHighligher);
+	}
+	
 	Data *data = new Data();
-	data->loadFromFile(filePath);	
+	data->loadFromFile(filePath.fullPath);	
 	textInput->insertText(data->getAsString(String::ENCODING_UTF8));
 	delete data;
 	

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

@@ -51,6 +51,19 @@ namespace Polycode {
 			int selectionLine;
 			int selectionCaretPosition;
 	};
+	
+	class _PolyExport SyntaxHighlightToken {
+		public:
+			SyntaxHighlightToken(String text, int type) { this->text = text; this->type = type; }
+			Color color;
+			String text;
+			unsigned int type;
+	};
+	
+	class _PolyExport UITextInputSyntaxHighlighter {
+		public:		
+			virtual std::vector<SyntaxHighlightToken> parseText(String text) = 0;
+	};
 
 	class _PolyExport UITextInput : public UIElement {
 		public:
@@ -66,6 +79,7 @@ namespace Polycode {
 		
 			int insertLine(bool after);
 		
+			void changedText();
 			
 			void onKeyDown(PolyKEY key, wchar_t charCode);
 		
@@ -83,6 +97,7 @@ namespace Polycode {
 			
 			void showLine(unsigned int lineNumber, bool top);
 
+			void setSyntaxHighlighter(UITextInputSyntaxHighlighter *syntaxHighliter);
 					
 			void Resize(Number width, Number height);
 			
@@ -135,6 +150,8 @@ namespace Polycode {
 		
 			int caretPosition;
 			bool doSelectToCaret;
+			
+			UITextInputSyntaxHighlighter *syntaxHighliter;
 		
 			ScreenEntity *linesContainer;
 			

+ 18 - 3
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -142,6 +142,8 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 	undoStateIndex = 0;
 	maxRedoIndex = 0;
 	
+	syntaxHighliter = NULL;
+	
 	insertLine(true);		
 }
 
@@ -301,9 +303,22 @@ void UITextInput::deleteSelection() {
 	clearSelection();
 	caretPosition = selectionL;
 	updateCaretPosition();
+	changedText();
+}
+
+void UITextInput::changedText() {
+
+	if(syntaxHighliter) {
+		std::vector<SyntaxHighlightToken> tokens = syntaxHighliter->parseText(getText());
+	}
+
 	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);	
 }
 
+void UITextInput::setSyntaxHighlighter(UITextInputSyntaxHighlighter *syntaxHighliter) {
+	this->syntaxHighliter = syntaxHighliter;
+}
+
 void UITextInput::Resize(Number width, Number height) {
 	inputRect->resizeBox(width, height);
 	this->width = width;
@@ -357,7 +372,7 @@ int UITextInput::insertLine(bool after) {
 		// do we even need that? I don't think so.
 	}	
 		
-	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);
+	changedText();
 	return 1;	
 }
 
@@ -610,7 +625,7 @@ void UITextInput::insertText(String text) {
 		currentLine->setText(ctext);			
 	}
 	
-	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);	
+	changedText();
 	updateCaretPosition();		
 	restructLines();	
 }
@@ -981,7 +996,7 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 	}
 	
 	currentLine->setText(ctext);	
-	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);	
+	changedText();
 	updateCaretPosition();
 }