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

Merge branch 'file-selector-2' of https://github.com/TheCosmotect/Polycode into pullreq_testing

Ivan Safrin 12 лет назад
Родитель
Сommit
de08d2035e

+ 9 - 0
IDE/Contents/Include/PolycodeFrame.h

@@ -214,6 +214,13 @@ public:
 	
 	UIWindow *aboutWindow;
 	UIButton *aboutOKButton;
+	
+	UIImageButton *closeFileButton;
+	
+	void updateFileSelector();
+	void showNextEditor();
+	void showPreviousEditor();
+	
 private:
 	
 	int frameSizeX;
@@ -254,4 +261,6 @@ private:
 	UIButton *newProjectButton;
 	UIButton *examplesButton;
 	
+	bool displayFilePathInSelector;
+
 };

+ 12 - 3
IDE/Contents/Include/PolycodeIDEApp.h

@@ -90,7 +90,7 @@ public:
 	void exportProject();
 	void toggleConsole();
 	
-	bool removeEditor(PolycodeEditor *editor);
+	void removeEditor(PolycodeEditor *editor);
 	
 	// system callbacks
 	
@@ -105,7 +105,12 @@ public:
 	
 	const static int EVENT_SHOW_MENU = 1;
 	
-	Core *core;	
+	Core *core;
+	
+	void saveFiles(std::vector<PolycodeEditor*> editors);
+	void closeFiles(std::vector<PolycodeEditor*> editors, String saveMsg="");
+	bool filesHaveChanges(std::vector<PolycodeEditor*> editors);
+	
 protected:
 
 	bool quittingApp;
@@ -122,5 +127,9 @@ protected:
 	UIMenuBar *menuBar;
 	
 private:
-	void cleanupProjectOnClose(bool save);
+	void doCloseProject();
+	void doCloseFiles(std::vector<PolycodeEditor*> editors);
+	
+	// used in saving/closing files via popup dialog prompts
+	std::vector<PolycodeEditor*> tempEditorStore;
 };

+ 77 - 21
IDE/Contents/Source/PolycodeFrame.cpp

@@ -564,11 +564,12 @@ PolycodeFrame::PolycodeFrame() : ScreenEntity() {
 	currentProjectTitle->color.a = 0.4;
 	currentProjectTitle->setPosition(70, 0);
 
-	currentFileSelector = new UIComboBox(globalMenu, 300);
+	currentFileSelector = new UIComboBox(globalMenu, 350);
 	currentFileSelector->addEventListener(this, UIEvent::CHANGE_EVENT);
-	
 	addChild(currentFileSelector);
 
+	closeFileButton = new UIImageButton("Images/remove_icon.png");
+	addChild(closeFileButton);
 	
 	resizer = new ScreenImage("Images/corner_resize.png");	
 	addChild(resizer);
@@ -635,6 +636,7 @@ PolycodeFrame::PolycodeFrame() : ScreenEntity() {
 		
 	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_MOUSEUP);
 	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_MOUSEMOVE);
+	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_KEYDOWN);
 	
 	curveEditor = new CurveEditor();
 	addChild(curveEditor);
@@ -663,6 +665,8 @@ PolycodeFrame::PolycodeFrame() : ScreenEntity() {
 	addChild(fileBrowserRoot);
 
 	fileDialog = NULL;
+	
+	displayFilePathInSelector = false;
 }
 
 void PolycodeFrame::showFileBrowser(String baseDir, bool foldersOnly, std::vector<String> extensions, bool allowMultiple) {
@@ -793,22 +797,8 @@ void PolycodeFrame::handleEvent(Event *event) {
 		showEditor(editor);
 	}
 	
-	if(event->getDispatcher() == editorManager) {	
-		currentFileSelector->clearItems();
-		
-		for(int i=0; i < editorManager->openEditors.size(); i++) {
-			OSFileEntry entry(editorManager->openEditors[i]->getFilePath(), OSFileEntry::TYPE_FILE);
-			
-			if(editorManager->openEditors[i]->hasChanges()) {
-				currentFileSelector->addComboItem("* " +entry.name);			
-			} else {
-				currentFileSelector->addComboItem(entry.name);
-			}
-			
-			if(editorManager->getCurrentEditor() == editorManager->openEditors[i]) {
-				currentFileSelector->setSelectedIndex(i);
-			}			
-		}
+	if(event->getDispatcher() == editorManager) {
+		updateFileSelector();
 	}
 	
 	if(event->getDispatcher() == projectManager) {
@@ -847,7 +837,32 @@ void PolycodeFrame::handleEvent(Event *event) {
 				if(isDragging) {
 					dragEntity->setPosition(((InputEvent*)event)->mousePosition);
 				}
-			break;	
+			break;
+			// TODO: add in key combos to switch editors in reverse order
+			case InputEvent::EVENT_KEYDOWN:
+				CoreInput *input = CoreServices::getInstance()->getCore()->getInput();
+				
+				if (input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER)) {
+					InputEvent *inEv = (InputEvent*)event;
+					// commenting this out for now until issue with KEY_BACKQUOTE is figured out
+					/*if (inEv->getKey() == KEY_BACKQUOTE) {
+						showNextEditor();
+					}*/
+					if (inEv->getKey() == KEY_SLASH) {
+						displayFilePathInSelector = (displayFilePathInSelector ? false : true);
+						updateFileSelector();
+					}
+				} else if (input->getKeyState(KEY_LCTRL) || input->getKeyState(KEY_RCTRL)) {
+					InputEvent *inEv = (InputEvent*)event;
+					if (inEv->getKey() == KEY_TAB) {
+						showNextEditor();
+					} else if (inEv->getKey() == KEY_SLASH) {
+						displayFilePathInSelector = (displayFilePathInSelector ? false : true);
+						updateFileSelector();
+					}
+				}
+			break;
+				
 		}
 	}
 
@@ -905,8 +920,8 @@ void PolycodeFrame::Resize(int x, int y) {
 	modalBlocker->setShapeSize(x, y);
 	fileDialogBlocker->setShapeSize(x, y);
 		
-	currentFileSelector->setPosition(x-350, 11);
-	
+	currentFileSelector->setPosition(x-400, 11);
+	closeFileButton->setPosition(currentFileSelector->getPosition().x-20, currentFileSelector->getPosition().y+6);
 	
 	if(this->modalChild) {
 		modalChild->setPosition((x-modalChild->getWidth())/2.0f, (y-modalChild->getHeight())/2.0f);
@@ -917,3 +932,44 @@ PolycodeFrame::~PolycodeFrame() {
 	
 }
 
+void PolycodeFrame::showNextEditor() {
+	if (currentFileSelector->getSelectedIndex() == currentFileSelector->getNumItems()-1)
+		currentFileSelector->setSelectedIndex(0);
+	else
+		currentFileSelector->setSelectedIndex(currentFileSelector->getSelectedIndex()+1);
+}
+void PolycodeFrame::showPreviousEditor() {
+	if (currentFileSelector->getSelectedIndex() == 0)
+		currentFileSelector->setSelectedIndex(currentFileSelector->getNumItems()-1);
+	else
+		currentFileSelector->setSelectedIndex(currentFileSelector->getSelectedIndex()-1);
+}
+
+void PolycodeFrame::updateFileSelector() {
+	currentFileSelector->clearItems();
+	
+	for(int i=0; i < editorManager->openEditors.size(); i++) {
+		OSFileEntry entry(editorManager->openEditors[i]->getFilePath(), OSFileEntry::TYPE_FILE);
+		
+		String projName = editorManager->openEditors[i]->parentProject->getProjectName();
+		String rootFolder = editorManager->openEditors[i]->parentProject->getRootFolder();
+		String filePath = editorManager->openEditors[i]->getFilePath();
+		String fullEntry = projName + filePath.substr(rootFolder.size(), filePath.size()-1);
+		
+		if(editorManager->openEditors[i]->hasChanges()) {
+			if (displayFilePathInSelector)
+				currentFileSelector->addComboItem("* "+fullEntry);
+			else
+				currentFileSelector->addComboItem("* "+entry.name);
+		} else {
+			if (displayFilePathInSelector)
+				currentFileSelector->addComboItem(fullEntry);
+			else
+				currentFileSelector->addComboItem(entry.name);
+		}
+		
+		if(editorManager->getCurrentEditor() == editorManager->openEditors[i]) {
+			currentFileSelector->setSelectedIndex(i);
+		}
+	}
+}

+ 100 - 44
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -184,6 +184,8 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	needsRedraw = false;
 	lastConnected = false;
 	
+	frame->closeFileButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	
 	quittingApp = false;
 	
 	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_KEYDOWN);
@@ -255,66 +257,78 @@ void PolycodeIDEApp::refreshProject() {
 	}
 }
 
-bool PolycodeIDEApp::removeEditor(PolycodeEditor *editor) {
-	if(!editor)
-		return false;
-		
-	if(editor->hasChanges()) {
-		OSFileEntry entry(editor->getFilePath(), OSFileEntry::TYPE_FILE);	
-		frame->yesNoCancelPopup->setCaption("The file \""+entry.name+"\" has unsaved changes. Save before closing?");
-		frame->yesNoCancelPopup->action = "closeFile";
-		frame->showModal(frame->yesNoCancelPopup);
-		return true;
-	} else {	
-		frame->removeEditor(editor);
-		editorManager->destroyEditor(editor);
-		if(editorManager->openEditors.size() > 0) {
-			editorManager->setCurrentEditor(editorManager->openEditors[0]);
-			frame->showEditor(editorManager->openEditors[0]);
-		} else {
-			editorManager->setCurrentEditor(NULL);
-		}
+// check if associated file has changes before invoking this
+void PolycodeIDEApp::removeEditor(PolycodeEditor *editor) {
+	if (!editor)
+		return;
+	
+	frame->removeEditor(editor);
+	editorManager->destroyEditor(editor);
+	if(editorManager->openEditors.size() > 0) {
+		editorManager->setCurrentEditor(editorManager->openEditors[0]);
+		frame->showEditor(editorManager->openEditors[0]);
+	} else {
+		editorManager->setCurrentEditor(NULL);
 	}
-	return false;
 }
 
 void PolycodeIDEApp::closeFile() {
+	// this will save the file if it has changes and/or close it (in closeFiles())
 	PolycodeEditor *editor = editorManager->getCurrentEditor();
-	if(editor) {
-		removeEditor(editor);
+	if (editor) {
+		std::vector<PolycodeEditor*> editorToSave;
+		editorToSave.push_back(editor);
+		OSFileEntry entry(editor->getFilePath(), OSFileEntry::TYPE_FILE);
+		closeFiles(editorToSave, "'"+entry.name+"' has unsaved changes. Save?");
+	}
+}
+
+void PolycodeIDEApp::closeFiles(std::vector<PolycodeEditor*> editors, String saveMsg) {
+	if (filesHaveChanges(editors)) {
+		if (saveMsg == "")
+			saveMsg = "File(s) have unsaved changes. Save all?";
+		tempEditorStore = editors;
+		frame->yesNoCancelPopup->setCaption(saveMsg);
+		frame->yesNoCancelPopup->action = "closeFiles";
+		frame->showModal(frame->yesNoCancelPopup);
+	} else
+		doCloseFiles(editors);
+}
+
+void PolycodeIDEApp::doCloseFiles(std::vector<PolycodeEditor*> editors) {
+	for (int i=0; i < editors.size(); i++) {
+		if (editors[i])
+			removeEditor(editors[i]);
 	}
 }
 
 void PolycodeIDEApp::closeProject() {
 	if(projectManager->getActiveProject()) {
-		if (editorManager->hasUnsavedFilesForProject(projectManager->getActiveProject())) {
+		std::vector<PolycodeEditor*> editors;
+		PolycodeEditor *editor;
+		bool hasChanges = false;
+		for (int i=0; i < editorManager->openEditors.size(); i++) {
+			editor = editorManager->openEditors[i];
+			if (editor->hasChanges())
+				hasChanges = true;
+			if (editor->parentProject == projectManager->getActiveProject())
+				editors.push_back(editor);
+		}
+		tempEditorStore = editors; // current project files
+		if (hasChanges) {
 			String name = projectManager->getActiveProject()->getProjectName();
 			frame->yesNoCancelPopup->setCaption("Project '" + name + "' has unsaved changes. Save all?");
 			frame->yesNoCancelPopup->action = "closeProject";
 			frame->showModal(frame->yesNoCancelPopup);
 		} else
-			cleanupProjectOnClose(false);
+			doCloseProject();
 	} else
-		PolycodeConsole::print("There are no active projects to close.");
+		PolycodeConsole::print("There are no active projects to close.\n");
 }
 
-// private function that removes editors and projects on project close
-void PolycodeIDEApp::cleanupProjectOnClose(bool save) {
-	PolycodeEditor *editor;
-	int i = 0;
-	while (i < editorManager->openEditors.size()) {
-		editor = editorManager->openEditors[i];
-		if(editor->parentProject == projectManager->getActiveProject()) {
-			if (save && editor->hasChanges())
-				editor->saveFile();
-			else
-				editor->setHasChanges(false);
-			
-			removeEditor(editor);
-			i--; // adjust for reduction in openEditors.size()
-		}
-		i++;
-	}
+// private helper function that removes editors and project on project close.
+void PolycodeIDEApp::doCloseProject() {
+	doCloseFiles(tempEditorStore);
 	frame->getProjectBrowser()->removeProject(projectManager->getActiveProject());
 	projectManager->removeProject(projectManager->getActiveProject());
 }
@@ -460,6 +474,21 @@ void PolycodeIDEApp::saveFile() {
 	}
 }
 
+void PolycodeIDEApp::saveFiles(std::vector<PolycodeEditor*> editors) {
+	for (int i=0; i < editors.size(); i++) {
+		if (editors[i]->hasChanges())
+			editors[i]->saveFile();
+	}
+}
+
+bool PolycodeIDEApp::filesHaveChanges(std::vector<PolycodeEditor*> editors) {
+	for (int i=0; i < editors.size(); i++) {
+		if (editors[i]->hasChanges())
+			return true;
+	}
+	return false;
+}
+
 void PolycodeIDEApp::openProject(String projectFile) {
 	projectManager->openProject(projectFile);
 }
@@ -747,10 +776,27 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 		} else if (frame->yesNoCancelPopup->action == "closeProject") {
 			switch (event->getEventCode()) {
 				case UIEvent::YES_EVENT:
-					cleanupProjectOnClose(true);
+					saveFiles(tempEditorStore);
+					doCloseProject();
+					break;
+				case UIEvent::NO_EVENT:
+					doCloseProject();
+					break;
+				case UIEvent::CANCEL_EVENT:
+					break;
+			}
+			frame->yesNoCancelPopup->action = "";
+			frame->hideModal();
+		}
+		
+		else if (frame->yesNoCancelPopup->action == "closeFiles") {
+			switch (event->getEventCode()) {
+				case UIEvent::YES_EVENT:
+					saveFiles(tempEditorStore);
+					doCloseFiles(tempEditorStore);
 					break;
 				case UIEvent::NO_EVENT:
-					cleanupProjectOnClose(false);
+					doCloseFiles(tempEditorStore);
 					break;
 				case UIEvent::CANCEL_EVENT:
 					break;
@@ -850,6 +896,16 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 		}
 	}
 	
+	// close files and editors after the close file button is pressed
+	if (event->getDispatcher() == frame->closeFileButton) {
+		if (event->getEventCode() == UIEvent::CLICK_EVENT) {
+			if (core->getInput()->getKeyState(KEY_RSHIFT) || core->getInput()->getKeyState(KEY_LSHIFT))
+				closeFiles(editorManager->openEditors);
+			else
+				closeFile();
+		}
+	}
+	
 	// open an editor/file if project browser has focus and user hits enter or right-arrow key
 	if (event->getDispatcher() == CoreServices::getInstance()->getCore()->getInput()) {
 		if (event->getEventCode() == InputEvent::EVENT_KEYDOWN && frame->getProjectBrowser()->treeContainer->hasFocus) {

+ 28 - 27
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -1347,7 +1347,20 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 			dispatchEvent(new Event(), Event::COMPLETE_EVENT);
 		}
 		return;
-	}	
+	}
+
+	// indent/shift text
+	if (multiLine && (key == KEY_LEFTBRACKET || key == KEY_RIGHTBRACKET) &&
+		(input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER) ||
+			input->getKeyState(KEY_LCTRL) || input->getKeyState(KEY_RCTRL))) {
+				shiftText( (key == KEY_RIGHTBRACKET) ? false : true );
+				return;
+	}
+
+	// at this point, return if certain modifier keys are held down so as not to potentially add any unwanted text
+	if (input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER) || input->getKeyState(KEY_LCTRL) ||
+		input->getKeyState(KEY_RCTRL) || input->getKeyState(KEY_LALT) || input->getKeyState(KEY_RALT))
+			return;
 	
 	String ctext = lines[lineOffset];
 	
@@ -1355,33 +1368,21 @@ void UITextInput::onKeyDown(PolyKEY key, wchar_t charCode) {
 		
 	if((charCode > 31 && charCode < 127) || charCode > 127) {
 		
-		// indent/shift text
-		if (multiLine && (key == KEY_LEFTBRACKET || key == KEY_RIGHTBRACKET) &&
-			(input->getKeyState(KEY_LSUPER) || input->getKeyState(KEY_RSUPER) ||
-				input->getKeyState(KEY_LCTRL) || input->getKeyState(KEY_RCTRL))) {
-					shiftText( (key == KEY_RIGHTBRACKET) ? false : true );
-					return;
-		}
-		
-		else {
-		
-			if(!isNumberOnly || (isNumberOnly && ((charCode > 47 && charCode < 58) || (charCode == '.' || charCode == '-')))) {
-				if(!isNumberOrCharacter(charCode)) { 
-					saveUndoState();
-				} else if (!isTypingWord) {
-					saveUndoState();
-					isTypingWord = 1;
-				}
-				if(hasSelection)
-					deleteSelection();
-				ctext = lines[lineOffset];
-				String text2 = ctext.substr(caretPosition, ctext.length()-caretPosition);
-				ctext = ctext.substr(0,caretPosition);
-				ctext += charCode + text2;
-				caretPosition++;
-				_changedText = true;
+		if(!isNumberOnly || (isNumberOnly && ((charCode > 47 && charCode < 58) || (charCode == '.' || charCode == '-')))) {
+			if(!isNumberOrCharacter(charCode)) { 
+				saveUndoState();
+			} else if (!isTypingWord) {
+				saveUndoState();
+				isTypingWord = 1;
 			}
-			
+			if(hasSelection)
+				deleteSelection();
+			ctext = lines[lineOffset];
+			String text2 = ctext.substr(caretPosition, ctext.length()-caretPosition);
+			ctext = ctext.substr(0,caretPosition);
+			ctext += charCode + text2;
+			caretPosition++;
+			_changedText = true;
 		}
 	}