Просмотр исходного кода

IDE now displays saved/unsaved status of files, will prompt to save all on run, UIButton will now dispatch click event on Enter press, IDE text editor sets saved/unsaved flag

Ivan Safrin 13 лет назад
Родитель
Сommit
fcaa4baef6

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

@@ -56,11 +56,15 @@ public:
 	
 	
 	String getEditorType() { return editorType; }
 	String getEditorType() { return editorType; }
 	
 	
+	bool hasChanges() { return _hasChanges;}
+	
+	void setHasChanges(bool newVal);
+	
 	PolycodeProject *parentProject;
 	PolycodeProject *parentProject;
 		
 		
 protected:
 protected:
 
 
-	
+	bool _hasChanges;
 
 
 	String filePath;
 	String filePath;
 	bool _isReadOnly;
 	bool _isReadOnly;

+ 7 - 0
IDE/Contents/Include/PolycodeEditorManager.h

@@ -36,9 +36,16 @@ class PolycodeEditorManager : public EventDispatcher {
 		PolycodeEditor *createEditorForExtension(String extension);
 		PolycodeEditor *createEditorForExtension(String extension);
 		void registerEditorFactory(PolycodeEditorFactory *editorFactory);
 		void registerEditorFactory(PolycodeEditorFactory *editorFactory);
 	
 	
+		void handleEvent(Event *event);
+	
 		void setCurrentEditor(PolycodeEditor *editor, bool sendChangeEvent = true);
 		void setCurrentEditor(PolycodeEditor *editor, bool sendChangeEvent = true);
 		PolycodeEditor *getCurrentEditor() { return currentEditor; }
 		PolycodeEditor *getCurrentEditor() { return currentEditor; }
 		
 		
+		void saveAll();
+		
+		bool hasUnsavedFiles();
+		bool hasUnsavedFilesForProject(PolycodeProject *project);
+		
 	//	int close
 	//	int close
 	std::vector<PolycodeEditor*> openEditors;
 	std::vector<PolycodeEditor*> openEditors;
 		
 		

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

@@ -79,12 +79,13 @@ public:
 	
 	
 	void addFiles();
 	void addFiles();
 	
 	
-	void newGroup();
+	void newGroup();	
 	void openProject();
 	void openProject();
 	void closeProject();	
 	void closeProject();	
 	void saveFile();
 	void saveFile();
 	void findText();
 	void findText();
 	void runProject();
 	void runProject();
+	void doRunProject();
 	void exportProject();	
 	void exportProject();	
 	
 	
 	// system callbacks
 	// system callbacks
@@ -101,6 +102,8 @@ public:
 	Core *core;	
 	Core *core;	
 protected:
 protected:
 
 
+	bool runNextFrame;
+
 	bool willRunProject;
 	bool willRunProject;
 	PolycodeFrame *frame;
 	PolycodeFrame *frame;
 	
 	

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

@@ -95,7 +95,7 @@ public:
 protected:
 protected:
 
 
 	FindBar *findBar;
 	FindBar *findBar;
-	
+	bool isLoading;
 	String lastFindString;
 	String lastFindString;
 
 
 	PolycodeSyntaxHighlighter *syntaxHighligher;
 	PolycodeSyntaxHighlighter *syntaxHighligher;

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

@@ -58,8 +58,6 @@ class YesNoPopup : public UIWindow {
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		
 		
 		String action;
 		String action;
-		
-	protected:
 	
 	
 		ScreenLabel *captionLabel;
 		ScreenLabel *captionLabel;
 	
 	

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

@@ -48,6 +48,7 @@ PolycodeEditor::PolycodeEditor(bool _isReadOnly) : ScreenEntity(), ClipboardProv
 	this->_isReadOnly = _isReadOnly;
 	this->_isReadOnly = _isReadOnly;
 	enableScissor = true;	
 	enableScissor = true;	
 	processInputEvents = true;
 	processInputEvents = true;
+	_hasChanges = false;
 
 
 	Core *core = CoreServices::getInstance()->getCore();
 	Core *core = CoreServices::getInstance()->getCore();
 	
 	
@@ -55,6 +56,13 @@ PolycodeEditor::PolycodeEditor(bool _isReadOnly) : ScreenEntity(), ClipboardProv
 	core->addEventListener(this, Core::EVENT_PASTE);
 	core->addEventListener(this, Core::EVENT_PASTE);
 }
 }
 
 
+void PolycodeEditor::setHasChanges(bool newVal) {
+	if(_hasChanges != newVal) {
+		_hasChanges = newVal;	
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+	}
+}
+
 void PolycodeEditor::handleEvent(Event *event) {
 void PolycodeEditor::handleEvent(Event *event) {
 	if(event->getDispatcher() == CoreServices::getInstance()->getCore()) {
 	if(event->getDispatcher() == CoreServices::getInstance()->getCore()) {
 		switch(event->getEventCode()) {
 		switch(event->getEventCode()) {

+ 30 - 0
IDE/Contents/Source/PolycodeEditorManager.cpp

@@ -37,12 +37,42 @@ PolycodeEditor *PolycodeEditorManager::createEditorForExtension(String extension
 		if(factory->canHandleExtension(extension)) {
 		if(factory->canHandleExtension(extension)) {
 			PolycodeEditor *editor = factory->createEditor();
 			PolycodeEditor *editor = factory->createEditor();
 			openEditors.push_back(editor);
 			openEditors.push_back(editor);
+			editor->addEventListener(this, Event::CHANGE_EVENT);
 			return editor;
 			return editor;
 		}
 		}
 	}
 	}
 	return NULL;
 	return NULL;
 }
 }
 
 
+bool PolycodeEditorManager::hasUnsavedFiles() {
+	for(int i=0; i < openEditors.size();i++) {
+		PolycodeEditor *editor = openEditors[i];
+		if(editor->hasChanges())
+			return true;
+	}
+	return false;
+}
+
+void PolycodeEditorManager::saveAll() {
+	for(int i=0; i < openEditors.size();i++) {
+		PolycodeEditor *editor = openEditors[i];
+		editor->saveFile();
+	}
+}
+
+bool PolycodeEditorManager::hasUnsavedFilesForProject(PolycodeProject *project) {
+	for(int i=0; i < openEditors.size();i++) {
+		PolycodeEditor *editor = openEditors[i];
+		if(editor->hasChanges() && editor->parentProject == project)
+			return true;
+	}
+	return false;
+}
+
+void PolycodeEditorManager::handleEvent(Event *event) {
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);
+}
+
 void PolycodeEditorManager::setCurrentEditor(PolycodeEditor *editor, bool sendChangeEvent) {
 void PolycodeEditorManager::setCurrentEditor(PolycodeEditor *editor, bool sendChangeEvent) {
 	currentEditor = editor;
 	currentEditor = editor;
 	if(sendChangeEvent){
 	if(sendChangeEvent){

+ 11 - 1
IDE/Contents/Source/PolycodeFrame.cpp

@@ -685,6 +685,10 @@ void PolycodeFrame::showModal(UIWindow *modalChild) {
 	modalChild->showWindow();
 	modalChild->showWindow();
 	modalChild->addEventListener(this, UIEvent::CLOSE_EVENT);
 	modalChild->addEventListener(this, UIEvent::CLOSE_EVENT);
 	Resize(frameSizeX, frameSizeY);
 	Resize(frameSizeX, frameSizeY);
+	
+	if(modalChild == yesNoPopup) {
+		yesNoPopup->focusChild(yesNoPopup->okButton);
+	}
 }
 }
 
 
 PolycodeProjectBrowser *PolycodeFrame::getProjectBrowser() {
 PolycodeProjectBrowser *PolycodeFrame::getProjectBrowser() {
@@ -749,7 +753,13 @@ void PolycodeFrame::handleEvent(Event *event) {
 		
 		
 		for(int i=0; i < editorManager->openEditors.size(); i++) {
 		for(int i=0; i < editorManager->openEditors.size(); i++) {
 			OSFileEntry entry(editorManager->openEditors[i]->getFilePath(), OSFileEntry::TYPE_FILE);
 			OSFileEntry entry(editorManager->openEditors[i]->getFilePath(), OSFileEntry::TYPE_FILE);
-			currentFileSelector->addComboItem(entry.name);
+			
+			if(editorManager->openEditors[i]->hasChanges()) {
+				currentFileSelector->addComboItem("* " +entry.name);			
+			} else {
+				currentFileSelector->addComboItem(entry.name);
+			}
+			
 			if(editorManager->getCurrentEditor() == editorManager->openEditors[i]) {
 			if(editorManager->getCurrentEditor() == editorManager->openEditors[i]) {
 				currentFileSelector->setSelectedIndex(i);
 				currentFileSelector->setSelectedIndex(i);
 			}
 			}

+ 39 - 5
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -34,6 +34,8 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	core = new POLYCODE_CORE(view, 900,700,false,true, 0, 0,30, -1);	
 	core = new POLYCODE_CORE(view, 900,700,false,true, 0, 0,30, -1);	
 //	core->pauseOnLoseFocus = true;
 //	core->pauseOnLoseFocus = true;
 	
 	
+	runNextFrame = false;
+	
 	core->addEventListener(this, Core::EVENT_CORE_RESIZE);
 	core->addEventListener(this, Core::EVENT_CORE_RESIZE);
 	core->addEventListener(this, Core::EVENT_LOST_FOCUS);
 	core->addEventListener(this, Core::EVENT_LOST_FOCUS);
 	core->addEventListener(this, Core::EVENT_GAINED_FOCUS);
 	core->addEventListener(this, Core::EVENT_GAINED_FOCUS);
@@ -86,6 +88,7 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 
 
 	frame->textInputPopup->addEventListener(this, UIEvent::OK_EVENT);	
 	frame->textInputPopup->addEventListener(this, UIEvent::OK_EVENT);	
 	frame->yesNoPopup->addEventListener(this, UIEvent::OK_EVENT);
 	frame->yesNoPopup->addEventListener(this, UIEvent::OK_EVENT);
+	frame->yesNoPopup->addEventListener(this, UIEvent::CANCEL_EVENT);
 	
 	
 	frame->newProjectWindow->addEventListener(this, UIEvent::OK_EVENT);
 	frame->newProjectWindow->addEventListener(this, UIEvent::OK_EVENT);
 	frame->exportProjectWindow->addEventListener(this, UIEvent::OK_EVENT);
 	frame->exportProjectWindow->addEventListener(this, UIEvent::OK_EVENT);
@@ -285,16 +288,26 @@ void PolycodeIDEApp::exportProject() {
 	}	
 	}	
 }
 }
 
 
-void PolycodeIDEApp::runProject() {
+void PolycodeIDEApp::doRunProject() {
 	printf("Running project...\n");
 	printf("Running project...\n");
 	stopProject();
 	stopProject();
 
 
+	String outPath = PolycodeToolLauncher::generateTempPath(projectManager->getActiveProject()) + ".polyapp";
+	PolycodeToolLauncher::buildProject(projectManager->getActiveProject(), outPath);
+	PolycodeToolLauncher::runPolyapp(outPath);
+}
+
+void PolycodeIDEApp::runProject() {
 	if(projectManager->getActiveProject()) {
 	if(projectManager->getActiveProject()) {
-		String outPath = PolycodeToolLauncher::generateTempPath(projectManager->getActiveProject()) + ".polyapp";
-		PolycodeToolLauncher::buildProject(projectManager->getActiveProject(), outPath);
-		PolycodeToolLauncher::runPolyapp(outPath);
+		if(editorManager->hasUnsavedFilesForProject(projectManager->getActiveProject())) {
+			frame->yesNoPopup->setCaption("This project has unsaved files. Save before building?");
+			frame->yesNoPopup->action = "saveAndRun";
+			frame->showModal(frame->yesNoPopup);		
+		} else {
+			doRunProject();	
+		}
 	} else {
 	} else {
-		PolycodeConsole::print("No active project!\n");
+		PolycodeConsole::print("No active project!\n");	
 	}
 	}
 }
 }
 
 
@@ -544,10 +557,26 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 	}
 	}
 
 
 	if(event->getDispatcher() == frame->yesNoPopup) {
 	if(event->getDispatcher() == frame->yesNoPopup) {
+
+		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CANCEL_EVENT) {
+			if(frame->yesNoPopup->action == "saveAndRun") {
+				runNextFrame = true;			
+			}
+			
+			frame->hideModal();
+			frame->yesNoPopup->action = "";		
+		}
+	
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
 			if(frame->yesNoPopup->action == "removeFile") {
 			if(frame->yesNoPopup->action == "removeFile") {
 				doRemoveFile();
 				doRemoveFile();
 			}
 			}
+			
+			if(frame->yesNoPopup->action == "saveAndRun") {
+				editorManager->saveAll();
+				runNextFrame = true;
+			}
+			
 			frame->hideModal();
 			frame->hideModal();
 			frame->yesNoPopup->action = "";
 			frame->yesNoPopup->action = "";
 		}
 		}
@@ -693,6 +722,11 @@ bool PolycodeIDEApp::Update() {
 		runProject();
 		runProject();
 	}
 	}
 
 
+	if(runNextFrame) {
+		runNextFrame = false;
+		doRunProject();
+	}
+
 	if(lastConnected != debugger->isConnected()) {
 	if(lastConnected != debugger->isConnected()) {
 		needsRedraw = true;
 		needsRedraw = true;
 		lastConnected = debugger->isConnected();
 		lastConnected = debugger->isConnected();

+ 13 - 0
IDE/Contents/Source/PolycodeTextEditor.cpp

@@ -283,6 +283,9 @@ PolycodeTextEditor::~PolycodeTextEditor() {
 
 
 bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 	
 	
+	
+	isLoading = true;
+	
 	textInput = new UITextInput(true, 100, 100);
 	textInput = new UITextInput(true, 100, 100);
 	addChild(textInput);
 	addChild(textInput);
 	textInput->setBackgroundColor(globalSyntaxTheme->bgColor);
 	textInput->setBackgroundColor(globalSyntaxTheme->bgColor);
@@ -292,6 +295,7 @@ bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 	textInput->setLineNumberColor(globalSyntaxTheme->lineNumberColor);
 	textInput->setLineNumberColor(globalSyntaxTheme->lineNumberColor);
 	textInput->enableLineNumbers(true);
 	textInput->enableLineNumbers(true);
 	
 	
+	textInput->addEventListener(this, UIEvent::CHANGE_EVENT);
 	
 	
 	findBar = new FindBar();
 	findBar = new FindBar();
 	findBar->visible = false;
 	findBar->visible = false;
@@ -319,11 +323,19 @@ bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 	delete data;
 	delete data;
 	
 	
 	PolycodeEditor::openFile(filePath);
 	PolycodeEditor::openFile(filePath);
+	
+	isLoading = false;	
 	return true;
 	return true;
 }
 }
 
 
 void PolycodeTextEditor::handleEvent(Event *event) {
 void PolycodeTextEditor::handleEvent(Event *event) {
 
 
+	if(event->getDispatcher() == textInput) {
+		if(!isLoading) {
+			setHasChanges(true);
+		}
+	}
+
 	if(event->getDispatcher() == findBar->replaceAllButton) {
 	if(event->getDispatcher() == findBar->replaceAllButton) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
 			textInput->replaceAll(findBar->findInput->getText(), findBar->replaceInput->getText());
 			textInput->replaceAll(findBar->findInput->getText(), findBar->replaceInput->getText());
@@ -399,6 +411,7 @@ void PolycodeTextEditor::saveFile() {
 	data->setFromString(textInput->getText(), String::ENCODING_UTF8);
 	data->setFromString(textInput->getText(), String::ENCODING_UTF8);
 	data->saveToFile(filePath);
 	data->saveToFile(filePath);
 	delete data;
 	delete data;
+	setHasChanges(false);
 }
 }
 
 
 void PolycodeTextEditor::Resize(int x, int y) {
 void PolycodeTextEditor::Resize(int x, int y) {

+ 2 - 1
IDE/Contents/Source/ToolWindows.cpp

@@ -114,7 +114,8 @@ void YesNoPopup::handleEvent(Event *event) {
 			}
 			}
 			
 			
 			if(event->getDispatcher() == cancelButton) {
 			if(event->getDispatcher() == cancelButton) {
-				dispatchEvent(new UIEvent(), UIEvent::CLOSE_EVENT);				
+				dispatchEvent(new UIEvent(), UIEvent::CLOSE_EVENT);
+				dispatchEvent(new UIEvent(), UIEvent::CANCEL_EVENT);				
 			}									
 			}									
 		}
 		}
 	}
 	}

+ 3 - 0
Modules/Contents/UI/Include/PolyUIButton.h

@@ -28,6 +28,7 @@
 #include "PolyUIEvent.h"
 #include "PolyUIEvent.h"
 #include "PolyUIBox.h"
 #include "PolyUIBox.h"
 #include "PolyUIElement.h"
 #include "PolyUIElement.h"
+#include "PolyCoreInput.h"
 
 
 namespace Polycode {
 namespace Polycode {
 
 
@@ -40,6 +41,8 @@ namespace Polycode {
 			void Update();
 			void Update();
 				
 				
 		private:
 		private:
+		
+			CoreInput *coreInput;
 			
 			
 			Number labelXPos;
 			Number labelXPos;
 			Number labelYPos;
 			Number labelYPos;

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

@@ -26,6 +26,7 @@
 #include "PolyInputEvent.h"
 #include "PolyInputEvent.h"
 #include "PolyLabel.h"
 #include "PolyLabel.h"
 #include "PolyCoreServices.h"
 #include "PolyCoreServices.h"
+#include "PolyCore.h"
 
 
 using namespace Polycode;
 using namespace Polycode;
 
 
@@ -63,6 +64,10 @@ UIButton::UIButton(String text, Number width, Number height) : UIElement() {
 	buttonRect->addEventListener(this, InputEvent::EVENT_MOUSEUP);
 	buttonRect->addEventListener(this, InputEvent::EVENT_MOUSEUP);
 	buttonRect->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);	
 	buttonRect->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);	
 	buttonRect->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 	buttonRect->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
+	
+	coreInput = CoreServices::getInstance()->getCore()->getInput();
+	coreInput->addEventListener(this, InputEvent::EVENT_KEYDOWN);
+		
 	pressedDown = false;
 	pressedDown = false;
 	
 	
 	buttonLabel = new ScreenLabel(text, fontSize, fontName, Label::ANTIALIAS_FULL);
 	buttonLabel = new ScreenLabel(text, fontSize, fontName, Label::ANTIALIAS_FULL);
@@ -97,6 +102,17 @@ UIButton::~UIButton() {
 }
 }
 		
 		
 void UIButton::handleEvent(Event *event) {
 void UIButton::handleEvent(Event *event) {
+
+	if(event->getDispatcher() == coreInput) {
+		switch(event->getEventCode()) {
+			case InputEvent::EVENT_KEYDOWN:
+				if(hasFocus) {
+					dispatchEvent(new UIEvent(), UIEvent::CLICK_EVENT);					
+				}
+			break;
+		}
+	}
+	
 	if(event->getDispatcher() == buttonRect) {
 	if(event->getDispatcher() == buttonRect) {
 		switch(event->getEventCode()) {
 		switch(event->getEventCode()) {
 			case InputEvent::EVENT_MOUSEOVER:
 			case InputEvent::EVENT_MOUSEOVER:

+ 10 - 2
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -1252,6 +1252,8 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 	}	
 	}	
 	
 	
 	String ctext = lines[lineOffset];
 	String ctext = lines[lineOffset];
+	
+	bool _changedText = false;
 		
 		
 	if((charCode > 31 && charCode < 127) || charCode > 127) {	
 	if((charCode > 31 && charCode < 127) || charCode > 127) {	
 		if(!isNumberOnly || (isNumberOnly && ((charCode > 47 && charCode < 58) || (charCode == '.' || charCode == '-')))) {
 		if(!isNumberOnly || (isNumberOnly && ((charCode > 47 && charCode < 58) || (charCode == '.' || charCode == '-')))) {
@@ -1265,6 +1267,7 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 			ctext = ctext.substr(0,caretPosition);
 			ctext = ctext.substr(0,caretPosition);
 			ctext += charCode + text2;
 			ctext += charCode + text2;
 			caretPosition++;
 			caretPosition++;
+			_changedText = true;
 		}
 		}
 	}
 	}
 	
 	
@@ -1276,7 +1279,8 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 		String text2 = ctext.substr(caretPosition, ctext.length()-caretPosition);
 		String text2 = ctext.substr(caretPosition, ctext.length()-caretPosition);
 		ctext = ctext.substr(0,caretPosition);
 		ctext = ctext.substr(0,caretPosition);
 		ctext += (wchar_t)'\t' + text2;
 		ctext += (wchar_t)'\t' + text2;
-		caretPosition++;		
+		caretPosition++;
+		_changedText = true;		
 	}
 	}
 	
 	
 	if(key == KEY_BACKSPACE) {
 	if(key == KEY_BACKSPACE) {
@@ -1293,6 +1297,7 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 				ctext = ctext.substr(0,caretPosition-1);
 				ctext = ctext.substr(0,caretPosition-1);
 				ctext += text2;
 				ctext += text2;
 				caretPosition--;
 				caretPosition--;
+				_changedText = true;				
 			}
 			}
 		} else {
 		} else {
 			if(lineOffset > 0) {
 			if(lineOffset > 0) {
@@ -1310,7 +1315,10 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 	}
 	}
 	
 	
 	lines[lineOffset] = ctext;
 	lines[lineOffset] = ctext;
-	changedText();
+	
+	if(_changedText) {
+		changedText();
+	}
 	updateCaretPosition();
 	updateCaretPosition();
 }
 }