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

Added UIMenuBar, fixed UI destructor crashes, fixed Linux disk operations, added openURL on Linux, Linux IDE now uses a custom menu bar, more IDE fixes

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

+ 11 - 4
Core/Contents/Source/PolySDLCore.cpp

@@ -151,6 +151,13 @@ SDLCore::~SDLCore() {
 }
 
 void SDLCore::openURL(String url) {
+    int childExitStatus;
+    pid_t pid = fork();
+    if (pid == 0) {
+	execl("/usr/bin/xdg-open", "/usr/bin/xdg-open", url.c_str(), (char *)0);
+    } else {
+        pid_t ws = waitpid( pid, &childExitStatus, WNOHANG);
+    }
 }
 
 String SDLCore::executeExternalCommand(String command) {
@@ -301,9 +308,9 @@ void SDLCore::copyDiskItem(const String& itemPath, const String& destItemPath) {
     int childExitStatus;
     pid_t pid = fork();
     if (pid == 0) {
-        execl("/bin/cp", "/bin/cp", itemPath.c_str(), destItemPath.c_str(), (char *)0);
+        execl("/bin/cp", "/bin/cp", "-R", itemPath.c_str(), destItemPath.c_str(), (char *)0);
     } else {
-        pid_t ws = waitpid( pid, &childExitStatus, WNOHANG);
+        pid_t ws = waitpid( pid, &childExitStatus, 0);
     }
 }
 
@@ -313,7 +320,7 @@ void SDLCore::moveDiskItem(const String& itemPath, const String& destItemPath) {
     if (pid == 0) {
         execl("/bin/mv", "/bin/mv", itemPath.c_str(), destItemPath.c_str(), (char *)0);
     } else {
-        pid_t ws = waitpid( pid, &childExitStatus, WNOHANG);
+        pid_t ws = waitpid( pid, &childExitStatus, 0);
     }
 }
 
@@ -323,7 +330,7 @@ void SDLCore::removeDiskItem(const String& itemPath) {
     if (pid == 0) {
         execl("/bin/rm", "/bin/rm", "-rf", itemPath.c_str(), (char *)0);
     } else {
-        pid_t ws = waitpid( pid, &childExitStatus, WNOHANG);
+        pid_t ws = waitpid( pid, &childExitStatus, 0);
     }
 }
 

+ 9 - 2
IDE/Build/Linux/Makefile

@@ -1,13 +1,20 @@
 CC=g++
-CFLAGS=-I../../Contents/Include -I../../../Release/Linux/Framework/Core/Dependencies/include -I../../../Release/Linux/Framework/Core/Dependencies/include/AL -I../../../Release/Linux/Framework/Core/include -I../../../Release/Linux/Framework/Modules/include -I../../../Release/Linux/Framework/Modules/Dependencies/include -I../../../Release/Linux/Framework/Modules/Dependencies/include/bullet -DUSE_POLYCODEUI_FILE_DIALOGS
+CFLAGS=-I../../Contents/Include -I../../../Release/Linux/Framework/Core/Dependencies/include -I../../../Release/Linux/Framework/Core/Dependencies/include/AL -I../../../Release/Linux/Framework/Core/include -I../../../Release/Linux/Framework/Modules/include -I../../../Release/Linux/Framework/Modules/Dependencies/include -I../../../Release/Linux/Framework/Modules/Dependencies/include/bullet -DUSE_POLYCODEUI_FILE_DIALOGS -DUSE_POLYCODEUI_MENUBAR
 LDFLAGS=-lrt -ldl -lpthread ../../../Release/Linux/Framework/Core/lib/libPolycore.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libfreetype.a ../../../Release/Linux/Framework/Core/Dependencies/lib/liblibvorbisfile.a ../../../Release/Linux/Framework/Core/Dependencies/lib/liblibvorbis.a ../../../Release/Linux/Framework/Core/Dependencies/lib/liblibogg.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libopenal.so ../../../Release/Linux/Framework/Core/Dependencies/lib/libphysfs.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libpng15.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libz.a -lGL -lGLU -lSDL ../../../Release/Linux/Framework/Modules/lib/libPolycode2DPhysics.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libBox2D.a ../../../Release/Linux/Framework/Modules/lib/libPolycode3DPhysics.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libBulletDynamics.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libBulletCollision.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libLinearMath.a ../../../Release/Linux/Framework/Modules/lib/libPolycodeUI.a
+LDFLAGS_DEBUG=-lrt -ldl -lpthread ../../../Release/Linux/Framework/Core/lib/libPolycore_d.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libfreetype_d.a ../../../Release/Linux/Framework/Core/Dependencies/lib/liblibvorbisfiled.a ../../../Release/Linux/Framework/Core/Dependencies/lib/liblibvorbisd.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libliboggd.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libopenal.so ../../../Release/Linux/Framework/Core/Dependencies/lib/libphysfsd.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libpng15d.a ../../../Release/Linux/Framework/Core/Dependencies/lib/libz.a -lGL -lGLU -lSDL ../../../Release/Linux/Framework/Modules/lib/libPolycode2DPhysics_d.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libBox2D_d.a ../../../Release/Linux/Framework/Modules/lib/libPolycode3DPhysics_d.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libBulletDynamics_d.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libBulletCollision_d.a ../../../Release/Linux/Framework/Modules/Dependencies/lib/libLinearMath_d.a ../../../Release/Linux/Framework/Modules/lib/libPolycodeUI_d.a
 SRCS=../../Contents/Source/ExampleBrowserWindow.cpp ../../Contents/Source/PolycodeEditorManager.cpp  ../../Contents/Source/PolycodeProject.cpp        ../../Contents/Source/PolycodeScreenEditor.cpp ../../Contents/Source/ExportProjectWindow.cpp  ../../Contents/Source/PolycodeFontEditor.cpp     ../../Contents/Source/PolycodeProjectBrowser.cpp ../../Contents/Source/PolycodeSpriteEditor.cpp ../../Contents/Source/NewFileWindow.cpp        ../../Contents/Source/PolycodeFrame.cpp          ../../Contents/Source/PolycodeProjectEditor.cpp  ../../Contents/Source/PolycodeTextEditor.cpp ../../Contents/Source/NewProjectWindow.cpp     ../../Contents/Source/PolycodeIDEApp.cpp         ../../Contents/Source/PolycodeProjectManager.cpp ../../Contents/Source/PolycodeToolLauncher.cpp ../../Contents/Source/PolycodeConsole.cpp      ../../Contents/Source/PolycodeImageEditor.cpp    ../../Contents/Source/PolycodeProps.cpp          ../../Contents/Source/TextureBrowser.cpp ../../Contents/Source/PolycodeEditor.cpp       ../../Contents/Source/PolycodeMaterialEditor.cpp ../../Contents/Source/PolycodeRemoteDebugger.cpp ../../Contents/Source/ToolWindows.cpp
 
 default:
-	$(CC) $(CFLAGS) -g main.cpp $(SRCS) -o ./Build/Polycode $(LDFLAGS)
+	$(CC) $(CFLAGS) main.cpp $(SRCS) -o ./Build/Polycode $(LDFLAGS)
 	cp -R ../../Contents/Resources/* Build/
 	cp ../../../Release/Linux/Framework/Core/Assets/default.pak Build/
 	cp -R ../../../Release/Linux/Standalone Build
+debug:
+	$(CC) $(CFLAGS) -g main.cpp $(SRCS) -o ./Build/Polycode $(LDFLAGS_DEBUG)
+	cp -R ../../Contents/Resources/* Build/
+	cp ../../../Release/Linux/Framework/Core/Assets/default.pak Build/
+	cp -R ../../../Release/Linux/Standalone Build
+
 clean:
 	rm ./Build/Polycode
 	

+ 1 - 0
IDE/Build/Linux/main.cpp

@@ -6,5 +6,6 @@ int main(int argc, char *argv[]) {
 	PolycodeView *view = new PolycodeView("Hello Polycode!");
 	PolycodeIDEApp *app = new PolycodeIDEApp(view);
 	while(app->Update()) {}
+	app->saveConfigFile();
 	return 0;
 }

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

@@ -99,5 +99,7 @@ protected:
 	PolycodeProjectManager *projectManager;
 	
 	PolycodeRemoteDebugger *debugger;
+
+	UIMenuBar *menuBar;
 	
 };

+ 116 - 3
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -96,7 +96,7 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	frame->getProjectBrowser()->addEventListener(this, PolycodeProjectBrowserEvent::HANDLE_MENU_COMMAND);
 	
 	frame->Resize(core->getXRes(), core->getYRes());	
-	core->setVideoMode(1100, 700, false, false, 0, 0);
+
 	
 	debugger = new PolycodeRemoteDebugger(projectManager);
 	frame->console->setDebugger(debugger);
@@ -115,6 +115,46 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 				
 	loadConfigFile();
 	frame->console->applyTheme();
+
+#ifdef USE_POLYCODEUI_MENUBAR
+	menuBar = new UIMenuBar(100, globalMenu);
+
+	UIMenuBarEntry *fileEntry = menuBar->addMenuBarEntry("File");
+	fileEntry->addItem("New File", "new_file");
+	fileEntry->addItem("New Project", "new_project");
+	fileEntry->addItem("New Folder", "new_folder");
+	fileEntry->addItem("Open Project", "open_project");
+	fileEntry->addItem("Close Project", "close_project");
+	fileEntry->addItem("Remove File", "remove_file");
+	fileEntry->addItem("Refresh Project", "refresh_project");
+	fileEntry->addItem("Save File", "save_file");
+	fileEntry->addItem("Browse Examples", "browse_examples");
+	fileEntry->addItem("Quit", "quit");
+
+	UIMenuBarEntry *editEntry = menuBar->addMenuBarEntry("Edit");
+	editEntry->addItem("Undo", "undo");
+	editEntry->addItem("Redo", "redo");
+	editEntry->addItem("Cut", "cut");
+	editEntry->addItem("Copy", "copy");
+
+	UIMenuBarEntry *projectEntry = menuBar->addMenuBarEntry("Project");
+	projectEntry->addItem("Run Project", "run_project");
+	projectEntry->addItem("Publish Project", "export_project");
+
+	UIMenuBarEntry *helpEntry = menuBar->addMenuBarEntry("Help");
+	helpEntry->addItem("API Reference", "show_api");
+
+
+	menuBar->addEventListener(this, UIEvent::OK_EVENT);
+
+	screen->addChild(menuBar);
+	frame->position.y = 25;
+#else
+	menuBar = NULL;
+#endif
+	core->setVideoMode(1100, 700, false, false, 0, 0);
+
+
 }
 
 void PolycodeIDEApp::renameFile() {
@@ -180,6 +220,12 @@ void PolycodeIDEApp::newGroup() {
 
 void PolycodeIDEApp::openProject() {
 	
+#ifdef USE_POLYCODEUI_FILE_DIALOGS
+	std::vector<String> exts;
+	exts.push_back("polyproject");
+	frame->showFileBrowser(CoreServices::getInstance()->getCore()->getUserHomeDirectory(),  false, exts, false);
+	frame->fileDialog->addEventListener(this, UIEvent::OK_EVENT);
+#else
 	vector<CoreFileExtension> extensions;
 	CoreFileExtension ext;
 	ext.extension = "polyproject";
@@ -195,7 +241,8 @@ void PolycodeIDEApp::openProject() {
 			OSFileEntry projectEntry =  OSFileEntry(project->getProjectFile(), OSFileEntry::TYPE_FILE);
 			openFile(projectEntry);			
 		}
-	}		
+	}
+#endif
 }
 
 void PolycodeIDEApp::browseExamples() {
@@ -267,8 +314,14 @@ void PolycodeIDEApp::openProject(String projectFile) {
 void PolycodeIDEApp::openDocs() {
 
 	String polycodeBasePath = CoreServices::getInstance()->getCore()->getDefaultWorkingDirectory();
+#if defined(__APPLE__) && defined(__MACH__)
 	String docsURL = "file://localhost"+polycodeBasePath+"/Standalone/Docs/html/index.html";
 	core->openURL(docsURL);
+#else
+	String docsURL = polycodeBasePath+"/Standalone/Docs/html/index.html";
+	printf("Opening %s\n", docsURL.c_str());
+	core->openURL(docsURL);
+#endif
 }
 
 void PolycodeIDEApp::openFileInProject(PolycodeProject *project, String filePath) {
@@ -318,6 +371,53 @@ void PolycodeIDEApp::openFile(OSFileEntry file) {
 
 void PolycodeIDEApp::handleEvent(Event *event) {
 
+	if(event->getDispatcher() == frame->fileDialog) {
+		if(event->getEventCode() == UIEvent::OK_EVENT && event->getEventType() == "UIEvent") {
+			String path = frame->fileDialog->getSelection();
+			if(path != "") {
+				PolycodeProject *project = projectManager->openProject(path);
+				if(project) {
+					projectManager->setActiveProject(project);
+					OSFileEntry projectEntry =  OSFileEntry(project->getProjectFile(), OSFileEntry::TYPE_FILE);
+					openFile(projectEntry);			
+				}
+				
+			}
+		}
+	}
+
+	if(event->getDispatcher() == menuBar) {
+		String action = menuBar->getSelectedItem();
+	
+		if(action == "new_file") {
+			newFile();
+		} else if(action == "new_project") {
+			newProject();
+		} else if(action == "new_folder") {
+			newGroup();
+		} else if(action == "open_project") {
+			openProject();
+		} else if(action == "close_project") {
+			closeProject();
+		} else if(action == "remove_file") {
+			removeFile();
+		} else if(action == "refresh_project") {
+			refreshProject();
+		} else if(action == "save_file") {
+			saveFile();
+		} else if(action == "browse_examples") {
+			browseExamples();
+		} else if(action == "quit") {
+			core->Shutdown();
+		} else if(action == "run_project") {
+			runProject();
+		} else if(action == "export_project") {
+			exportProject();
+		} else if(action == "show_api") {
+			openDocs();
+		}
+	}
+
 	if(event->getDispatcher() == frame->console->backtraceWindow) {
 		if(event->getEventType() == "BackTraceEvent" && event->getEventCode() == BackTraceEvent::EVENT_BACKTRACE_SELECTED) {
 			BackTraceEvent *btEvent = (BackTraceEvent*) event;
@@ -338,6 +438,9 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 		switch(event->getEventCode()) {
 			case Core::EVENT_CORE_RESIZE:
 				frame->Resize(core->getXRes(), core->getYRes());
+				if(menuBar) {
+					menuBar->Resize(core->getXRes(), 25);
+				}
 			break;
 		}
 	}
@@ -499,15 +602,25 @@ void PolycodeIDEApp::saveConfigFile() {
 		projectEntry->addChild("name", project->getProjectName());
 		projectEntry->addChild("path", project->getProjectFile());
 	}
+
+#if defined(__APPLE__) && defined(__MACH__)
 	core->createFolder(core->getUserHomeDirectory()+"/Library/Application Support/Polycode");
 	configFile.saveToXML(core->getUserHomeDirectory()+"/Library/Application Support/Polycode/config.xml");	
+#else
+	core->createFolder(core->getUserHomeDirectory()+"/.polycode");
+	configFile.saveToXML(core->getUserHomeDirectory()+"/.polycode/config.xml");	
+
+#endif
 }
 
 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");
-		
+#else
+	configFile.loadFromXML(core->getUserHomeDirectory()+"/.polycode/config.xml");
+#endif	
 	globalSyntaxTheme = new SyntaxHighlightTheme();
 	String themeName = "default";
 	ObjectEntry *syntaxTheme = configFile.root["syntax_theme"];

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

@@ -41,7 +41,7 @@ void PolycodeRunner::runThread() {
 
 #endif
 	String ret = CoreServices::getInstance()->getCore()->executeExternalCommand(command);
-	core->removeDiskItem(polyappPath);	
+	CoreServices::getInstance()->getCore()->removeDiskItem(polyappPath);	
 }
 
 PolycodeToolLauncher::PolycodeToolLauncher() {

+ 2 - 0
Modules/Contents/UI/CMakeLists.txt

@@ -22,6 +22,7 @@ SET(polycodeUI_SRCS
     Source/PolyUIVScrollBar.cpp
     Source/PolyUIWindow.cpp
     Source/PolyUIFileDialog.cpp
+    Source/PolyUIMenuBar.cpp
 )
 
 SET(polycodeUI_HDRS
@@ -47,6 +48,7 @@ SET(polycodeUI_HDRS
     Include/PolyUIVScrollBar.h
     Include/PolyUIWindow.h
     Include/PolyUIFileDialog.h
+    Include/PolyUIMenuBar.h
 )
 
 INCLUDE_DIRECTORIES(

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

@@ -67,6 +67,8 @@ namespace Polycode {
 			void clearEntries();
 			void showFolder(String folderPath);
 	
+			bool canOpen(String extension);
+
 			void addToSidebar(String path, String name);
 
 			void Update();
@@ -94,6 +96,7 @@ namespace Polycode {
 
 			UIScrollContainer *scrollContainer;
 
+			std::vector<String> extensions;
 			std::vector<UIFileDialogEntry*> entries;
 			std::vector<UIFileDialogEntry*> sideBarEntries;
 			UIElement *entryHolder;		

+ 1 - 1
Modules/Contents/UI/Include/PolyUIMenu.h

@@ -102,4 +102,4 @@ namespace Polycode {
 	
 
 	
-}
+}

+ 83 - 0
Modules/Contents/UI/Include/PolyUIMenuBar.h

@@ -0,0 +1,83 @@
+/*
+ Copyright (C) 2012 by Ivan Safrin
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ 
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+#pragma once
+#include "PolyGlobals.h"
+#include "PolyScreenLabel.h"
+#include "PolyScreenShape.h"
+#include "PolyScreenEntity.h"
+#include "PolyUIEvent.h"
+#include "PolyUIBox.h"
+#include "PolyUIMenu.h"
+#include "PolyUIElement.h"
+#include "PolyInputEvent.h"
+
+namespace Polycode {
+
+	class UIMenuBarEntryItem {
+		public:
+			UIMenuBarEntryItem(String name, String code) { this->name = name; this->code = code; }
+			String name;	
+			String code;
+	};
+
+	class _PolyExport UIMenuBarEntry : public UIElement {
+		public:
+			UIMenuBarEntry(String name);
+			~UIMenuBarEntry();		
+			void addItem(String name, String code);
+
+			void Select();
+			void Deselect();
+
+			ScreenShape *bg;
+			ScreenLabel *label;
+
+			std::vector<UIMenuBarEntryItem> items;
+
+	};
+	
+	class _PolyExport UIMenuBar : public UIElement {
+		public:
+			UIMenuBar(int width, UIGlobalMenu *globalMenu);
+			~UIMenuBar();
+
+			void handleEvent(Event *event);	
+
+			void showMenuForEntry(UIMenuBarEntry *entry);
+			void Resize(Number width, Number height);
+			UIMenuBarEntry *addMenuBarEntry(String name);
+			
+			String getSelectedItem();
+		protected:
+			UIMenu *dropMenu;
+			UIGlobalMenu *globalMenu;
+			int entryOffset;
+			
+			bool holdingMouse;
+
+			String selectedItem;
+			ScreenShape *bgShape;
+			std::vector<UIMenuBarEntry*> entries;
+			UIMenuBarEntry *currentEntry;
+	};
+}

+ 1 - 0
Modules/Contents/UI/Include/PolycodeUI.h

@@ -41,3 +41,4 @@
 #include "PolyUIWindow.h"
 #include "PolyUIMenu.h"
 #include "PolyUIFileDialog.h"
+#include "PolyUIMenuBar.h"

+ 35 - 10
Modules/Contents/UI/Source/PolyUIFileDialog.cpp

@@ -60,8 +60,8 @@ UIFileDialog::UIFileDialog(String baseDir, bool foldersOnly, std::vector<String>
 	this->foldersOnly = foldersOnly;
 	this->allowMultiple = allowMultiple;
 
-	ownsChildren = true;
-	
+	this->extensions = extensions;
+
 	closeOnEscape = true;
 
 	if(foldersOnly) {
@@ -115,6 +115,15 @@ UIFileDialog::UIFileDialog(String baseDir, bool foldersOnly, std::vector<String>
 	addToSidebar(CoreServices::getInstance()->getCore()->getUserHomeDirectory(), "Home");
 }
 
+bool UIFileDialog::canOpen(String extension) {
+	for(int i=0; i < extensions.size(); i++) {
+		if(extensions[i] == extension) {
+			return true;
+		}
+	}
+	return false;
+}
+
 void UIFileDialog::addToSidebar(String path, String name) {
 	OSFileEntry backEntry;
 	backEntry.type = OSFileEntry::TYPE_FOLDER;
@@ -151,6 +160,8 @@ void UIFileDialog::showFolder(String folderPath) {
 
 	if(foldersOnly) {
 		selection = folderPath;
+	} else {
+		selection = "";
 	}
 
 
@@ -182,12 +193,16 @@ void UIFileDialog::showFolder(String folderPath) {
 	int i;
 	for(i=0; i < _entries.size(); i++) {
 		bool canSelect = false;
+
+		if(_entries[i].type == OSFileEntry::TYPE_FOLDER) {
+			canSelect = true;
+		}
+
 		if(foldersOnly) {
-			if(_entries[i].type == OSFileEntry::TYPE_FOLDER) {
+		} else {
+			if(canOpen(_entries[i].extension)) {
 				canSelect = true;
 			}
-		} else {
-
 		}
 		UIFileDialogEntry *newEntry = new UIFileDialogEntry(_entries[i], canSelect);
 		entryHolder->addChild(newEntry);
@@ -243,7 +258,9 @@ void UIFileDialog::handleEvent(Event *event) {
 							currentEntry->Deselect();
 						entries[i]->Select();
 						currentEntry = entries[i];
-						if(foldersOnly) {
+
+						if((foldersOnly &&  entries[i]->fileEntry.type == OSFileEntry::TYPE_FOLDER) 
+							|| (!foldersOnly &&  entries[i]->fileEntry.type == OSFileEntry::TYPE_FILE)) {
 							selection = entries[i]->fileEntry.fullPath;
 						}
 					}
@@ -284,12 +301,18 @@ void UIFileDialog::handleEvent(Event *event) {
 }
 
 UIFileDialog::~UIFileDialog() {
-
+	delete okButton;
+	delete cancelButton;
+	delete newFolderButton;
+	delete scrollContainer;
+	delete createFolderWindow;
+	delete entryHolder;
+	for(int i=0; i < sideBarEntries.size(); i++) {
+		delete sideBarEntries[i];
+	}
 }
 
 CreateFolderWindow::CreateFolderWindow() : UIWindow("New folder name", 290, 80) {
-	ownsChildren = true;
-	
 	closeBtn->visible = false;
 	closeBtn->enabled = false;
 
@@ -307,5 +330,7 @@ CreateFolderWindow::CreateFolderWindow() : UIWindow("New folder name", 290, 80)
 }
 
 CreateFolderWindow::~CreateFolderWindow() {
-	
+	delete cancelButton;
+	delete okButton;
+	delete nameInput;
 }

+ 3 - 2
Modules/Contents/UI/Source/PolyUIMenu.cpp

@@ -99,6 +99,7 @@ UIMenu::UIMenu(Number menuWidth) : UIElement() {
 	dropDownBox->processInputEvents = true;
 	
 	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);			
+	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_MOUSEUP);			
 
 	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_KEYDOWN);			
 
@@ -141,7 +142,7 @@ void UIMenu::handleEvent(Event *event) {
 				dispatchEvent(new UIEvent(), UIEvent::CANCEL_EVENT);							
 			}
 		}
-		if(event->getEventCode() == InputEvent::EVENT_MOUSEDOWN && !ignoreMouse) {
+		if((event->getEventCode() == InputEvent::EVENT_MOUSEDOWN || event->getEventCode() == InputEvent::EVENT_MOUSEUP) && !ignoreMouse) {
 			if(selectorBox->visible) {
 				dispatchEvent(new UIEvent(), UIEvent::OK_EVENT);
 			} else {
@@ -254,4 +255,4 @@ UIMenu *UIGlobalMenu::showMenu(Number x, Number y, Number width) {
 	currentMenu->setPosition(x,y);
 	return currentMenu;
 	
-}
+}

+ 130 - 0
Modules/Contents/UI/Source/PolyUIMenuBar.cpp

@@ -0,0 +1,130 @@
+
+#include "PolyUIMenuBar.h"
+#include "PolyLabel.h"
+
+using namespace Polycode;
+
+UIMenuBarEntry::UIMenuBarEntry(String name): UIElement() {
+	
+	label = new ScreenLabel(name, 14, "sans");
+	setWidth(label->getLabel()->getTextWidth() + 20);
+	bg = new ScreenShape(ScreenShape::SHAPE_RECT, width, 25);
+	bg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+	addChild(bg);
+	bg->color.setColorHex(0xce5a1600);
+	bg->processInputEvents = true;
+	addChild(label);
+	label->setPosition(10, 5);
+}
+
+void UIMenuBarEntry::Select() {
+	bg->color.setColorHex(0xce5a16ff);
+}
+
+void UIMenuBarEntry::Deselect() {
+	bg->color.setColorHex(0xce5a1600);
+}
+
+void UIMenuBarEntry::addItem(String name, String code) {
+	items.push_back(UIMenuBarEntryItem(name,code));
+}
+
+UIMenuBarEntry::~UIMenuBarEntry() {
+	delete bg;
+	delete label;
+}
+
+UIMenuBar::UIMenuBar(int width, UIGlobalMenu *globalMenu) : UIElement() {
+
+	this->globalMenu = globalMenu;
+
+	bgShape = new ScreenShape(ScreenShape::SHAPE_RECT, width, 25);
+	addChild(bgShape);
+	bgShape->setColor(0.0, 0.0, 0.0, 1.0);
+	bgShape->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+	entryOffset = 0;
+
+	currentEntry = NULL;
+	dropMenu = NULL;
+
+	holdingMouse = false;
+}
+
+UIMenuBarEntry *UIMenuBar::addMenuBarEntry(String name) {
+	UIMenuBarEntry *newEntry = new UIMenuBarEntry(name);
+	entries.push_back(newEntry);
+	addChild(newEntry);
+	newEntry->setPosition(entryOffset, 0);
+	entryOffset += newEntry->width;
+
+	newEntry->bg->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
+	newEntry->bg->addEventListener(this, InputEvent::EVENT_MOUSEUP);
+	newEntry->bg->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);
+	newEntry->bg->addEventListener(this, InputEvent::EVENT_MOUSEMOVE);
+
+	return newEntry;
+}
+
+void UIMenuBar::showMenuForEntry(UIMenuBarEntry *entry) {
+	dropMenu = globalMenu->showMenu(entry->position.x, 25, 130);
+	
+	dropMenu->addEventListener(this, UIEvent::OK_EVENT);
+	dropMenu->addEventListener(this, UIEvent::CANCEL_EVENT);
+
+	for(int i=0; i < entry->items.size(); i++) {
+		dropMenu->addOption(entry->items[i].name, entry->items[i].code);
+	}
+
+	if(currentEntry) {
+		currentEntry->Deselect();
+	}
+	entry->Select();
+	currentEntry = entry;
+}
+
+String UIMenuBar::getSelectedItem() {
+	return selectedItem;
+}
+
+void UIMenuBar::handleEvent(Event *event) {
+	if(event->getDispatcher() == dropMenu) {
+		if(event->getEventCode() == UIEvent::OK_EVENT) {
+			selectedItem = dropMenu->getSelectedItem()->_id;
+			dispatchEvent(new UIEvent(), UIEvent::OK_EVENT);
+		}
+
+		if(currentEntry) {
+			currentEntry->Deselect();
+			currentEntry = NULL;
+			dropMenu = NULL;
+		}
+	}
+
+	for(int i=0; i < entries.size(); i++) {
+		if(event->getDispatcher() == entries[i]->bg) {
+			switch(event->getEventCode()) {
+				case InputEvent::EVENT_MOUSEMOVE:
+					if(entries[i] != currentEntry && dropMenu) {
+						showMenuForEntry(entries[i]);
+					}
+				break;
+				case InputEvent::EVENT_MOUSEUP:
+				case InputEvent::EVENT_MOUSEUP_OUTSIDE:
+					holdingMouse = false;
+				break;
+				case InputEvent::EVENT_MOUSEDOWN:
+					holdingMouse = true;
+					showMenuForEntry(entries[i]);
+				break;
+			}
+		}
+	}
+}
+
+UIMenuBar::~UIMenuBar() {
+	delete bgShape;
+}
+
+void UIMenuBar::Resize(Number width, Number height) {
+	bgShape->setShapeSize(width, 25);
+}

+ 1 - 2
Modules/Contents/UI/Source/PolyUITree.cpp

@@ -108,7 +108,6 @@ UITree::UITree(String icon, String text, Number treeWidth, Number treeOffset) :
 	setPositionMode(ScreenEntity::POSITION_CENTER);
 	
 	refreshTree();
-	ownsChildren = true;
 }
 
 void UITree::Resize(Number width) {
@@ -338,4 +337,4 @@ UITree *UITree::addTreeChild(String icon, String text, void *userData) {
 	treeChildren.push_back(newTree);
 	refreshTree();
 	return newTree;
-}
+}