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

Polycode IDE will now save tabs, layout, open project browser nodes and open editors on exit (and load them on startup)

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

+ 1 - 1
IDE/Build/Mac OS X/PolycodeAppDelegate.m

@@ -82,9 +82,9 @@ void PolycodeAppEventHandler::handleEvent(Event *evt) {
 
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)theApplication
 {
+	app->saveConfigFile();
 	bool retVal = app->quitApp();
 	if(retVal) {
-		app->saveConfigFile();
 		app->core->Shutdown();
 		printf("STOPPING\n");
 	}

+ 6 - 1
IDE/Contents/Include/PolycodeEditorManager.h

@@ -24,6 +24,7 @@
 
 #include "Polycode.h"
 #include "PolycodeEditor.h"
+#include "PolycodeProjectManager.h"
 
 using namespace Polycode;
 
@@ -47,18 +48,22 @@ class PolycodeEditorManager : public EventDispatcher {
 		
 		std::vector<PolycodeEditor*> getOpenEditorsForProject(PolycodeProject *project);
 		
+		PolycodeEditor *openFile(OSFileEntry file);
+		
 		void saveAll();
 		
 		bool hasUnsavedFiles();
 		bool hasUnsavedFilesForProject(PolycodeProject *project);
 		void saveFilesForProject(PolycodeProject *project);
 		
+		void setProjectManager(PolycodeProjectManager *projectManager);
+		
 	//	int close
 	std::vector<PolycodeEditor*> openEditors;
 		
 protected:
 	
 	PolycodeEditor *currentEditor;
-	
+	PolycodeProjectManager *projectManager;
 	std::vector<PolycodeEditorFactory*> editorFactories;	
 };

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

@@ -145,9 +145,15 @@ class EditorHolder : public UIElement {
 		EditorHolder(PolycodeProject *project, PolycodeEditorManager *editorManager, EditorHolder *parentHolder);
 		~EditorHolder();
 		
+		ObjectEntry *getEditorHolderConfig();
+		void applyConfig(ObjectEntry *entry);
+		
 		void handleEvent(Event *event);
 		void Resize(Number width, Number height);		
 		
+		void makeVSplit();
+		void makeHSplit();
+				
 		void _mergeSides(EditorHolder *mainHolder);
 		void mergeSides(EditorHolder *mainHolder);
 		
@@ -202,6 +208,9 @@ class PolycodeProjectTab : public UIElement {
 		void Resize(Number width, Number height);				
 		void showEditor(PolycodeEditor *editor);
 		
+		ObjectEntry *getTabConfig();
+		void applyTabConfig(ObjectEntry *tabEntry);
+		
 		void setActive(bool val);
 		bool isActive();
 		
@@ -250,6 +259,8 @@ class PolycodeProjectFrame : public UIElement {
 		
 		PolycodeProjectTab *addNewTab(String caption = "New Tab");
 		
+		ObjectEntry *getFrameConfig();
+		
 		void showTab(PolycodeProjectTab *tab);
 		void closeTab(PolycodeProjectTab *tab);
 		
@@ -264,6 +275,9 @@ class PolycodeProjectFrame : public UIElement {
 		
 		EditorHolder *lastActiveEditorHolder;
 		
+		PolycodeProjectTab *getTabAtIndex(unsigned int index);
+		unsigned int getNumTabs();
+		
 	protected:
 	
 		PolycodeProject *project;
@@ -306,6 +320,8 @@ public:
 	
 	TextInputPopup *showTextInput(String caption, String action, String value);
 	
+	ObjectEntry *getFrameConfigForProject(PolycodeProject *project);
+	
 	void toggleConsole();
 	void showConsole();
 	void hideConsole();
@@ -348,6 +364,9 @@ public:
 	
 	void updateFileSelector();
 	
+	bool isShowingConsole();
+	Number getConsoleSize();
+	
 private:
 	
 	Number consoleSize;

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

@@ -116,6 +116,8 @@ protected:
 	bool quittingApp;
 	bool runNextFrame;
 
+	Object configFile;
+
 	bool willRunProject;
 	PolycodeFrame *frame;
 	
@@ -127,7 +129,9 @@ protected:
 	
 private:
 
-	std::vector<String> projectsToOpen;
+	void applyFinalConfig();
+
+	std::vector<ObjectEntry*> projectsToOpen;
 
 	void doCloseProject();
 	void doCloseFiles(std::vector<PolycodeEditor*> editors);

+ 25 - 24
IDE/Contents/Include/PolycodeProjectBrowser.h

@@ -50,32 +50,33 @@ class PolycodeProjectBrowserEvent : public Event {
 };
 
 class PolycodeProjectBrowser : public UIElement {
-public:
-	PolycodeProjectBrowser(PolycodeProject *project);
-	~PolycodeProjectBrowser();
-	
-	void Resize(Number width, Number height);
-	
-	UITree *nodeHasName(UITree *node, String name);
-	bool listHasFileEntry(vector<OSFileEntry> files, OSFileEntry fileEntry);
-	
-	void Refresh();
-	
-	void handleEvent(Event *event);
-	
-	void parseFolderIntoNode(UITree *node, String spath, PolycodeProject *parentProject);
-	
-	
-	
-	BrowserUserData *getSelectedData() { return selectedData; }
-	
-	UITreeContainer *treeContainer;
+	public:
+		PolycodeProjectBrowser(PolycodeProject *project);
+		~PolycodeProjectBrowser();
+		
+		void Resize(Number width, Number height);
+		
+		ObjectEntry *getBrowserConfig();
+		void applyBrowserConfig(ObjectEntry *entry);
+		
+		UITree *nodeHasName(UITree *node, String name);
+		bool listHasFileEntry(vector<OSFileEntry> files, OSFileEntry fileEntry);
+		
+		void Refresh();
+		
+		void handleEvent(Event *event);
+		
+		void parseFolderIntoNode(UITree *node, String spath, PolycodeProject *parentProject);
+		
+		BrowserUserData *getSelectedData() { return selectedData; }
+		
+		UITreeContainer *treeContainer;
 			
 protected:
 
-		UIRect *headerBg;
-	
-		UIMenu *contextMenu;
-	
+		void applyOpenNodeToTree(UITree* treeNode, ObjectEntry *nodeEntry);
+		
+		UIRect *headerBg;	
+		UIMenu *contextMenu;	
 		BrowserUserData *selectedData;
 };	

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

@@ -31,6 +31,10 @@ PolycodeEditorManager::~PolycodeEditorManager() {
 	
 }
 
+void PolycodeEditorManager::setProjectManager(PolycodeProjectManager *projectManager) {
+	this->projectManager = projectManager;
+}
+
 PolycodeEditorFactory *PolycodeEditorManager::getEditorFactoryForExtension(String extension) {
 	for(int i=0;i < editorFactories.size(); i++) {
 		PolycodeEditorFactory *factory = editorFactories[i];
@@ -65,6 +69,23 @@ void PolycodeEditorManager::destroyEditor(PolycodeEditor* editor) {
 	}
 }
 
+PolycodeEditor *PolycodeEditorManager::openFile(OSFileEntry file) {
+	PolycodeEditor *editor = getEditorForPath(file.fullPath);	
+	if(editor) {
+		return editor;
+	} else {
+		editor = createEditorForExtension(file.extension);
+		if(editor) {
+			editor->parentProject = projectManager->getActiveProject();
+			if(!editor->openFile(file)) {
+				delete editor;
+				editor = NULL;
+			}
+		}
+	}
+	return editor;
+}
+
 bool PolycodeEditorManager::hasUnsavedFiles() {
 	for(int i=0; i < openEditors.size();i++) {
 		PolycodeEditor *editor = openEditors[i];

+ 193 - 48
IDE/Contents/Source/PolycodeFrame.cpp

@@ -25,10 +25,9 @@
 
 UIColorPicker *globalColorPicker;
 PolycodeFrame *globalFrame;
-
 extern UIGlobalMenu *globalMenu;
-
 EditorHolder *activeEditorHolder = NULL;
+extern PolycodeEditorManager *globalEditorManager;
 
 EditPoint::EditPoint(BezierPoint *point, unsigned int type) : Entity() {
 	this->point = point;
@@ -537,8 +536,79 @@ EditorHolder::EditorHolder(PolycodeProject *project, PolycodeEditorManager *edit
 	isActive = false;
 }
 
+ObjectEntry *EditorHolder::getEditorHolderConfig() {
+	ObjectEntry *configEntry = new ObjectEntry();
+	configEntry->name = "editor_holder";
+	
+	if(vSizer) {	
+		configEntry->addChild("split", "vsplit");
+		ObjectEntry *childEditors = configEntry->addChild("child_editors");
+		childEditors->addChild(firstChildHolder->getEditorHolderConfig())->addChild("size", vSizer->getMainHeight());
+		childEditors->addChild(secondChildHolder->getEditorHolderConfig());				
+	} else if(hSizer) {
+		configEntry->addChild("split", "hsplit");
+		ObjectEntry *childEditors = configEntry->addChild("child_editors");
+		childEditors->addChild(firstChildHolder->getEditorHolderConfig())->addChild("size", hSizer->getMainWidth());
+		childEditors->addChild(secondChildHolder->getEditorHolderConfig());				
+	} else {
+		configEntry->addChild("split", "none");	
+		if(currentEditor) {
+			configEntry->addChild("file_name", 	currentEditor->getFilePath());
+		}
+
+	}
+	return configEntry;
+}
+
+void EditorHolder::applyConfig(ObjectEntry *entry) {
+	ObjectEntry *splitEntry = (*entry)["split"];
+	if(splitEntry) {
+		if(splitEntry->stringVal == "none") {
+			ObjectEntry *fileNameEntry = (*entry)["file_name"];
+			if(fileNameEntry) {
+				OSFileEntry file = OSFileEntry(fileNameEntry->stringVal, OSFileEntry::TYPE_FILE);
+				PolycodeEditor *editor = globalEditorManager->openFile(file);
+				if(editor) {
+					setEditor(editor);
+				}	
+			}
+		} else {
+			if(splitEntry->stringVal == "hsplit") {
+				makeHSplit();
+			} else {
+				makeVSplit();
+			}
+			
+			ObjectEntry *childEntries = (*entry)["child_editors"];
+			if(childEntries) {
+				ObjectEntry *firstChildEntry = (*childEntries)[0];
+				if(firstChildEntry) {
+					firstChildHolder->applyConfig(firstChildEntry);
+					if(vSizer) {
+						vSizer->setMainHeight((*firstChildEntry)["size"]->NumberVal);
+					} else if(hSizer) {
+						hSizer->setMainWidth((*firstChildEntry)["size"]->NumberVal);
+					}
+				}
+				ObjectEntry *secondChildEntry = (*childEntries)[1];
+				if(secondChildEntry) {
+					secondChildHolder->applyConfig(secondChildEntry);
+				}				
+			}
+			
+		}
+	}
+}
+
 void EditorHolder::setActive(bool val) {
+
 	isActive = val;
+	
+	if(vSizer || hSizer) {
+		firstChildHolder->setActive(val);
+		return;
+	}	
+	
 	if(val) {	
 		headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiAccentColor"));
 		if(activeEditorHolder && activeEditorHolder != this) {
@@ -631,6 +701,55 @@ PolycodeEditor *EditorHolder::getEditor() {
 	return currentEditor;
 }
 
+void EditorHolder::makeVSplit() {
+	holderBar->visible = false;
+	holderBar->enabled = false;
+
+	vSizer = new UIVSizer(getWidth(), getHeight(), getHeight()/2.0, true);
+	addChild(vSizer);
+	firstChildHolder = new EditorHolder(project, editorManager, this);
+	firstChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);
+	vSizer->addTopChild(firstChildHolder);		
+	if(isActive) {
+		firstChildHolder->setActive(true);
+	}		
+	secondChildHolder = new EditorHolder(project, editorManager, this);
+	secondChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);
+	vSizer->addBottomChild(secondChildHolder);
+
+
+	if(currentEditor) {
+		removeChild(currentEditor);
+		currentEditor->setEditorHolder(NULL);			
+		firstChildHolder->setEditor(currentEditor);
+		currentEditor = NULL;
+	}
+}
+
+void EditorHolder::makeHSplit() {
+	holderBar->visible = false;
+	holderBar->enabled = false;
+	
+	hSizer = new UIHSizer(getWidth(), getHeight(), getWidth()/2.0, true);
+	addChild(hSizer);
+	firstChildHolder = new EditorHolder(project, editorManager, this);
+	firstChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);		
+	hSizer->addLeftChild(firstChildHolder);
+	secondChildHolder = new EditorHolder(project, editorManager, this);
+	secondChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);		
+	hSizer->addRightChild(secondChildHolder);
+	if(isActive) {
+		firstChildHolder->setActive(true);
+	}		
+	
+	if(currentEditor) {
+		removeChild(currentEditor);
+		currentEditor->setEditorHolder(NULL);
+		firstChildHolder->setEditor(currentEditor);
+		currentEditor = NULL;
+	}
+}
+
 void EditorHolder::handleEvent(Event *event) {
 
 	if(event->getDispatcher() == this) {
@@ -638,53 +757,9 @@ void EditorHolder::handleEvent(Event *event) {
 			setActive(true);
 		}
 	} else if(event->getDispatcher() == vSplitButton) {
-		holderBar->visible = false;
-		holderBar->enabled = false;
-		
-		vSizer = new UIVSizer(getWidth(), getHeight(), getHeight()/2.0, true);
-		addChild(vSizer);
-		firstChildHolder = new EditorHolder(project, editorManager, this);
-		firstChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);
-		vSizer->addTopChild(firstChildHolder);		
-		if(isActive) {
-			firstChildHolder->setActive(true);
-		}		
-		secondChildHolder = new EditorHolder(project, editorManager, this);
-		secondChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);
-		vSizer->addBottomChild(secondChildHolder);
-		
-		
-		if(currentEditor) {
-			removeChild(currentEditor);
-			currentEditor->setEditorHolder(NULL);			
-			firstChildHolder->setEditor(currentEditor);
-			currentEditor = NULL;
-		}
-		
+		makeVSplit();
 	} else if(event->getDispatcher() == hSplitButton) {
-		holderBar->visible = false;
-		holderBar->enabled = false;
-		
-		hSizer = new UIHSizer(getWidth(), getHeight(), getWidth()/2.0, true);
-		addChild(hSizer);
-		firstChildHolder = new EditorHolder(project, editorManager, this);
-		firstChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);		
-		hSizer->addLeftChild(firstChildHolder);
-		secondChildHolder = new EditorHolder(project, editorManager, this);
-		secondChildHolder->addEventListener(this, UIEvent::CLOSE_EVENT);		
-		hSizer->addRightChild(secondChildHolder);
-		if(isActive) {
-			firstChildHolder->setActive(true);
-		}		
-		
-		if(currentEditor) {
-			removeChild(currentEditor);
-			currentEditor->setEditorHolder(NULL);
-			firstChildHolder->setEditor(currentEditor);
-			currentEditor = NULL;
-		}
-				
-								
+		makeHSplit();								
 	} else if(event->getDispatcher() == currentFileSelector) {
 		PolycodeEditor *editor = (PolycodeEditor*) currentFileSelector->getSelectedItem()->data;
 		if(currentEditor != editor) {
@@ -854,6 +929,35 @@ String PolycodeProjectTab::getTabName() {
 	return tabName;
 }
 
+ObjectEntry *PolycodeProjectTab::getTabConfig() {
+	ObjectEntry *configEntry = new ObjectEntry();
+	configEntry->name = "tab";
+	
+	configEntry->addChild(projectBrowser->getBrowserConfig());
+	
+	configEntry->addChild("tab_name", tabName);	
+	configEntry->addChild("tab_active", isActive());
+	
+	configEntry->addChild(editorHolder->getEditorHolderConfig());
+	return configEntry;
+}
+
+void PolycodeProjectTab::applyTabConfig(ObjectEntry *tabEntry) {
+	ObjectEntry *browserEntry = (*tabEntry)["project_browser"];
+	if(browserEntry) {
+		ObjectEntry *browserWidthEntry = (*browserEntry)["width"];
+		if(browserWidthEntry) {
+			mainSizer->setMainWidth(browserWidthEntry->NumberVal);
+		}
+		projectBrowser->applyBrowserConfig(browserEntry);
+	}
+	
+	ObjectEntry *editorHolderEntry = (*tabEntry)["editor_holder"];
+	if(editorHolderEntry) {
+		editorHolder->applyConfig(editorHolderEntry);
+	}
+}
+
 void PolycodeProjectTab::setTabName(String newName) {
 	tabName = newName;
 }
@@ -978,6 +1082,14 @@ PolycodeProjectFrame::PolycodeProjectFrame(PolycodeProject *project, PolycodeEdi
 	addNewTab("Default");
 }
 
+PolycodeProjectTab *PolycodeProjectFrame::getTabAtIndex(unsigned int index) {
+	return tabs[index];
+}
+
+unsigned int PolycodeProjectFrame::getNumTabs() {
+	return tabs.size();
+}
+
 PolycodeProjectTab *PolycodeProjectFrame::getActiveTab() {
 	return activeTab;
 }
@@ -1060,6 +1172,18 @@ void PolycodeProjectFrame::restructTabs() {
 	newTabButton->setPosition((i * 155), 0.0);
 }
 
+ObjectEntry *PolycodeProjectFrame::getFrameConfig() {
+	ObjectEntry *configEntry = new ObjectEntry();
+	configEntry->name = "frame";
+	
+	ObjectEntry *tabsEntry = configEntry->addChild("tabs");
+	
+	for(int i=0; i < tabs.size(); i++) {
+		tabsEntry->addChild(tabs[i]->getTabConfig());
+	}
+	return configEntry;
+}
+
 void PolycodeProjectFrame::handleEvent(Event *event) {
 	for(int i=0; i < tabs.size(); i++) {
 		if(event->getDispatcher() == tabs[i] && event->getEventCode() == UIEvent::CLOSE_EVENT) {
@@ -1313,6 +1437,10 @@ void PolycodeFrame::hideModal() {
 	modalBlocker->enabled = false;		
 }
 
+bool PolycodeFrame::isShowingConsole() {
+	return showingConsole;
+}
+	
 void PolycodeFrame::showConsole() {
 	if(!showingConsole)
 		toggleConsole();
@@ -1337,6 +1465,14 @@ void PolycodeFrame::toggleConsole() {
 	showingConsole = !showingConsole;
 }
 
+Number PolycodeFrame::getConsoleSize() {
+	if(showingConsole) {
+		return consoleSizer->getMainHeight();
+	} else {
+		return consoleSize;
+	}
+}
+
 void PolycodeFrame::Update() {
 	if(willHideModal) {
 		hideModal();
@@ -1524,6 +1660,15 @@ void PolycodeFrame::Resize(int x, int y) {
 	UIElement::Resize(x, y);
 }
 
+ObjectEntry *PolycodeFrame::getFrameConfigForProject(PolycodeProject *project) {
+	for(int i=0; i < projectFrames.size(); i++) {
+		if(projectFrames[i]->getProject() == project) {
+			return projectFrames[i]->getFrameConfig();
+		}
+	}
+	return NULL;
+}
+
 void PolycodeFrame::removeProjectFrame(PolycodeProject *project) {
 
 }

+ 97 - 33
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -28,7 +28,7 @@ using namespace Polycode;
 UIGlobalMenu *globalMenu;
 SyntaxHighlightTheme *globalSyntaxTheme;
 PolycodeClipboard *globalClipboard;
-
+PolycodeEditorManager *globalEditorManager;
 
 PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	core = new POLYCODE_CORE(view, 1100, 700,false,true, 0, 0,60, -1);	
@@ -89,6 +89,7 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 //	screen->rootEntity.setDefaultScreenOptions(true);
 	
 	editorManager = new PolycodeEditorManager();
+	globalEditorManager = editorManager;
 	
 	frame = new PolycodeFrame(editorManager);
 	frame->setAnchorPoint(-1.0, -1.0, 0.0);
@@ -120,20 +121,13 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	screen->addChild(frame);
 	
 	projectManager = new PolycodeProjectManager();
+	editorManager->setProjectManager(projectManager);
 		
 	frame->projectManager = projectManager;
 	projectManager->addEventListener(frame, Event::CHANGE_EVENT);
 	projectManager->addEventListener(this, Event::CHANGE_EVENT);
 			
 	frame->Resize(core->getXRes(), core->getYRes());	
-
-	for(int i=0; i < projectsToOpen.size(); i++) {
-		PolycodeProject* project = projectManager->openProject(projectsToOpen[i]);
-		if(project) {
-			OSFileEntry projectEntry =	OSFileEntry(project->getProjectFile(), OSFileEntry::TYPE_FILE);
-			projectManager->setActiveProject(project);
-		}
-	}
 	
 	debugger = new PolycodeRemoteDebugger(projectManager);
 	frame->console->setDebugger(debugger);
@@ -201,6 +195,8 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	quittingApp = false;
 	
 	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_KEYDOWN);
+	
+	applyFinalConfig();
 }
 
 void PolycodeIDEApp::renameFile() {
@@ -573,24 +569,10 @@ void PolycodeIDEApp::openFile(OSFileEntry file) {
 		}	
 	}
 
-	PolycodeEditor *editor = editorManager->getEditorForPath(file.fullPath);
+	PolycodeEditor *editor = editorManager->openFile(file);
 	
 	if(editor) {
 		frame->getActiveProjectFrame()->getActiveTab()->showEditor(editor);
-	} else {
-		editor = editorManager->createEditorForExtension(file.extension);
-		if(editor) {
-			editor->parentProject = projectManager->getActiveProject();
-			if(editor->openFile(file)) {
-				frame->getActiveProjectFrame()->getActiveTab()->showEditor(editor);
-			} else {
-				delete editor;
-				editor = NULL;
-			}
-		}
-	}
-							
-	if(editor) {
 		editorManager->setCurrentEditor(editor);
 	}
 }
@@ -1038,12 +1020,24 @@ void PolycodeIDEApp::saveConfigFile() {
 
 	configFile.root.addChild("app_width", String::IntToString(core->getXRes()));
 	configFile.root.addChild("app_height", String::IntToString(core->getYRes()));
-		
+	
+	ObjectEntry *consoleEntry = configFile.root.addChild("console");
+	consoleEntry->addChild("size", frame->getConsoleSize());
+	consoleEntry->addChild("showing", frame->isShowingConsole());
+	
 	for(int i=0; i < projectManager->getProjectCount(); i++) {
 		PolycodeProject *project = projectManager->getProjectByIndex(i);		
 		ObjectEntry *projectEntry = configFile.root["open_projects"]->addChild("project");
+
+		projectEntry->addChild("is_active", (project == projectManager->getActiveProject()));
+		
 		projectEntry->addChild("name", project->getProjectName());
 		projectEntry->addChild("path", project->getProjectFile());
+		
+		ObjectEntry *projectFrameConfig = frame->getFrameConfigForProject(project);
+		if(projectFrameConfig) {
+			projectEntry->addChild(projectFrameConfig);
+		}
 	}
 
 	configFile.root.addChild("settings");
@@ -1062,7 +1056,6 @@ void PolycodeIDEApp::saveConfigFile() {
 }
 
 void PolycodeIDEApp::loadConfigFile() {
-	Object configFile;
 	// TODO: Make a crossplatform core method to get application data path
 #if defined(__APPLE__) && defined(__MACH__)
 	configFile.loadFromXML(core->getUserHomeDirectory()+"/Library/Application Support/Polycode/config.xml");
@@ -1084,7 +1077,7 @@ void PolycodeIDEApp::loadConfigFile() {
 	
 	ObjectEntry *appWidth = configFile.root["app_width"];
 	ObjectEntry *appHeight = configFile.root["app_height"];
-	
+		
 	bool setResFromConfig = false;
 	if(appWidth && appHeight) {
 		int newXRes = appWidth->intVal;
@@ -1110,10 +1103,7 @@ void PolycodeIDEApp::loadConfigFile() {
 		ObjectEntry *projects = configFile.root["open_projects"];
 		if(projects) {
 			for(int i=0; i < projects->length; i++) {
-				ObjectEntry *entry = (*(*projects)[i])["path"];
-				if(entry) {
-					projectsToOpen.push_back(entry->stringVal);
-				}
+				projectsToOpen.push_back((*projects)[i]);
 			}
 		}
 	}
@@ -1140,11 +1130,85 @@ void PolycodeIDEApp::loadConfigFile() {
 	}
 }
 
+void PolycodeIDEApp::applyFinalConfig() {
 
-PolycodeIDEApp::~PolycodeIDEApp() {
+	PolycodeProject *activeConfigProject = NULL;
 	
-	saveConfigFile();
+	for(int i=0; i < projectsToOpen.size(); i++) {
+		ObjectEntry *projectPathEntry = ((*projectsToOpen[i])["path"]);		
+		if(projectPathEntry) {
+			String projectPath = projectPathEntry->stringVal;
+			PolycodeProject* project = projectManager->openProject(projectPath);
+			
+			ObjectEntry *projectActiveEntry = ((*projectsToOpen[i])["is_active"]);
+			if(projectActiveEntry) {
+				if(projectActiveEntry->boolVal) {
+					activeConfigProject = project;
+				}
+			}
+			
+			PolycodeProjectFrame *projectFrame = frame->getProjectFrame(project);
+			
+			PolycodeProjectTab *activeTab = NULL;
+			
+			if(project) {
+				OSFileEntry projectEntry =	OSFileEntry(project->getProjectFile(), OSFileEntry::TYPE_FILE);	
+				ObjectEntry *frameEntry = ((*projectsToOpen[i])["frame"]);
+				if(frameEntry) {
+					ObjectEntry *tabs = (*frameEntry)["tabs"];
+					if(tabs) {
+						for(int i=0; i < tabs->length; i++) {
+							ObjectEntry *tab = (*tabs)[i];
+							if(tab) {
+								ObjectEntry *tabName = (*tab)["tab_name"];
+								ObjectEntry *tabActive = (*tab)["tab_active"];
+								
+								if(i == 0) {
+									projectFrame->getTabAtIndex(0)->setTabName(tabName->stringVal);
+								} else {
+									projectFrame->addNewTab(tabName->stringVal);
+								}			
+													
+								projectFrame->getTabAtIndex(i)->applyTabConfig(tab);
+								
+								if(tabActive->boolVal) {
+									activeTab = projectFrame->getTabAtIndex(i);
+								}
+								
+							}
+						}
+						
+						if(activeTab) {
+							projectFrame->showTab(activeTab);
+						}
+					}
+				}
+			}
+		}				
+	}
 	
+	if(activeConfigProject) {
+		projectManager->setActiveProject(activeConfigProject);
+		frame->switchToProjectFrame(frame->getProjectFrame(activeConfigProject));
+	}
+
+	ObjectEntry *consoleEntry = configFile.root["console"];	
+	if(consoleEntry) {
+		if((*consoleEntry)["size"]) {
+			frame->getConsoleSizer()->setMainHeight((*consoleEntry)["size"]->NumberVal);
+		}
+		if((*consoleEntry)["showing"]) {
+			if((*consoleEntry)["showing"]->boolVal) {
+				frame->showConsole();
+			} else {
+				frame->hideConsole();			
+			}
+		}		
+	}
+}
+
+PolycodeIDEApp::~PolycodeIDEApp() {	
+	saveConfigFile();
 	delete core;
 }
 

+ 69 - 0
IDE/Contents/Source/PolycodeProjectBrowser.cpp

@@ -142,6 +142,74 @@ bool PolycodeProjectBrowser::listHasFileEntry(vector<OSFileEntry> files, OSFileE
 	return false;
 }
 
+void parseOpenNodesIntoEntry(ObjectEntry *entry, UITree *node, bool addNewNode) {
+
+	bool hasOpenNodes = false;
+	for(int i=0; i < node->getNumTreeChildren(); i++) {
+		UITree *child = node->getTreeChild(i);	
+		if(!child->isCollapsed()) {	
+			hasOpenNodes = true;
+		}
+	}
+
+	if(!hasOpenNodes) {
+		return;		
+	}
+
+	ObjectEntry *childNodes = entry;
+	if(addNewNode) {
+		childNodes = entry->addChild("child_nodes");
+	}
+	
+	for(int i=0; i < node->getNumTreeChildren(); i++) {
+		UITree *child = node->getTreeChild(i);
+		if(!child->isCollapsed()) {
+			ObjectEntry *newEntry = childNodes->addChild("open_node");
+			newEntry->addChild("name", child->getLabelText());			
+			parseOpenNodesIntoEntry(newEntry, child, true);
+		}
+	}
+}
+
+ObjectEntry *PolycodeProjectBrowser::getBrowserConfig() {
+	ObjectEntry *configEntry = new ObjectEntry();	
+	configEntry->name = "project_browser";
+	
+	configEntry->addChild("width", getWidth());	
+	ObjectEntry *openNodes = configEntry->addChild("open_nodes");
+	parseOpenNodesIntoEntry(openNodes, treeContainer->getRootNode(), false);
+	
+	return configEntry;
+}
+
+void PolycodeProjectBrowser::applyOpenNodeToTree(UITree* treeNode, ObjectEntry *nodeEntry) {
+	for(int i=0; i < treeNode->getNumTreeChildren(); i++) {
+		if(treeNode->getTreeChild(i)->getLabelText() == (*nodeEntry)["name"]->stringVal ){
+			if(treeNode->getTreeChild(i)->isCollapsed()) {
+				treeNode->getTreeChild(i)->toggleCollapsed();
+				ObjectEntry *childNodes = (*nodeEntry)["child_nodes"];
+				if(childNodes) {
+					for(int j=0; j < childNodes->length; j++) {
+						applyOpenNodeToTree(treeNode->getTreeChild(i), (*childNodes)[j]);
+					}
+				}
+			}
+		}
+	}
+}
+
+void PolycodeProjectBrowser::applyBrowserConfig(ObjectEntry *entry) {
+	ObjectEntry *openNodes = (*entry)["open_nodes"];
+	if(openNodes) {
+		for(int i=0; i < openNodes->length; i++) {
+			ObjectEntry *openNode = (*openNodes)[i];
+			if(openNode) {				
+				applyOpenNodeToTree(treeContainer->getRootNode(), openNode);
+			}
+		}
+	}
+}
+
 void PolycodeProjectBrowser::parseFolderIntoNode(UITree *node, String spath, PolycodeProject *parentProject) {
 	vector<OSFileEntry> files = OSBasics::parseFolder(spath, false);
 	
@@ -183,4 +251,5 @@ void PolycodeProjectBrowser::parseFolderIntoNode(UITree *node, String spath, Pol
 void PolycodeProjectBrowser::Resize(Number width, Number height) {
 	headerBg->Resize(width, 30);
 	treeContainer->Resize(width, height-30);
+	UIElement::Resize(width, height);
 }

+ 3 - 0
IDE/Contents/Source/PolycodeProjectManager.cpp

@@ -38,6 +38,7 @@ PolycodeProject* PolycodeProjectManager::openProject(String path) {
 
 	for(int i=0; i < projects.size(); i++) {
 		if(projects[i]->getProjectFile() == path) {
+			setActiveProject(projects[i]);
 			return projects[i];
 		}
 	}	
@@ -72,6 +73,8 @@ PolycodeProject* PolycodeProjectManager::openProject(String path) {
 		CoreServices::getInstance()->getFontManager()->registerFont(fontName, fontPath);		
 	}
 	
+	setActiveProject(newProject);
+	
 	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
 	return newProject;
 }