فهرست منبع

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

Conflicts:
	IDE/Contents/Source/PolycodeIDEApp.cpp
Ethan M 12 سال پیش
والد
کامیت
513d2de1f1

+ 9 - 0
Bindings/Contents/LUA/API/defaults.lua

@@ -117,6 +117,15 @@ end
 function onMouseMove(x,y)
 end
 
+function onJoystickButtonDown(id, button)
+end
+
+function onJoystickButtonUp(id, button)
+end
+
+function onJoystickAxisMoved(id, axis, value)
+end
+
 function Update(e)
 end
 

+ 16 - 0
Core/Contents/Include/PolyCoreInput.h

@@ -97,6 +97,22 @@ namespace Polycode {
 		*/				
 		bool getKeyState(PolyKEY keyCode);		
 		
+		/** 
+		* Returns the state of the specified joystick button for the specified joystick index. If the joystick index is invalid, returns false
+		* @param joystickIndex Joystick index to check the state on
+		* @param button Joystick button to check the stat of.
+		* @return True if the button is pressed, false otherwise or if joystick index is invalid.
+		*/						
+		bool getJoystickButtonState(int joystickIndex, int button);
+		
+		/** 
+		* Returns the value of the specified joystick axis for the specified joystick index. If the joystick index is invalid, returns 0
+		* @param joystickIndex Joystick index to check the state on
+		* @param axis Joystick axis to get the value of.
+		* @return Value of the joystick axis (0 if joystickIndex is invalid)
+		*/						
+		Number getJoystickAxisValue(int joystickIndex, int axis);
+		
 		/** 
 		* Returns the current mouse position as delta from last frame.
 		* @return Mouse position as a 2d vector delta from last frame.

+ 18 - 0
Core/Contents/Source/PolyCoreInput.cpp

@@ -61,6 +61,24 @@ namespace Polycode {
 		return &joysticks[index];
 	}	
 	
+	bool CoreInput::getJoystickButtonState(int joystickIndex, int button) {
+		JoystickInfo *info = getJoystickInfoByIndex(joystickIndex);
+		if(info) {
+			return info->joystickButtonState[button];
+		} else {
+			return false;
+		}
+	}
+	
+	Number CoreInput::getJoystickAxisValue(int joystickIndex, int axis) {
+		JoystickInfo *info = getJoystickInfoByIndex(joystickIndex);
+		if(info) {
+			return info->joystickAxisState[axis];
+		} else {
+			return 0.0;
+		}	
+	}
+	
 	JoystickInfo *CoreInput::getJoystickInfoByID(unsigned int deviceID) {
 		for(int i=0;i<joysticks.size();i++) {
 			if(joysticks[i].deviceID == deviceID) {

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

@@ -75,7 +75,7 @@ SDLCore::SDLCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen, bool
 		setenv("SDL_VIDEO_CENTERED", "1", 1);
 	}
 
-	if(SDL_Init(SDL_INIT_VIDEO) < 0) {
+	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0) {
 	}
 	
 	eventMutex = createMutex();
@@ -88,6 +88,15 @@ SDLCore::SDLCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen, bool
 	SDL_EnableUNICODE(1);
 	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
 	
+	SDL_JoystickEventState(SDL_ENABLE);
+	
+	int numJoysticks = SDL_NumJoysticks();
+	
+	for(int i=0; i < numJoysticks; i++) {
+		SDL_JoystickOpen(i);
+		input->addJoystick(i);
+	}
+
 	((OpenGLRenderer*)renderer)->initOSSpecific();
 	CoreServices::getInstance()->installModule(new GLSLShaderModule());	
 }
@@ -113,8 +122,6 @@ void SDLCore::setVideoMode(int xRes, int yRes, bool fullScreen, bool vSync, int
 		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0);
 	}
 	
-	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
-	
 	flags = SDL_OPENGL;
 
 	if(fullScreen) {
@@ -124,6 +131,16 @@ void SDLCore::setVideoMode(int xRes, int yRes, bool fullScreen, bool vSync, int
 	if(resizableWindow) {
 		flags |= SDL_RESIZABLE;
 	}
+
+	if(vSync) {
+		flags |= SDL_DOUBLEBUF;
+		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+		SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
+	} else {
+		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
+		SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
+	}
+
 	SDL_SetVideoMode(xRes, yRes, 0, flags);
 	
 	renderer->Resize(xRes, yRes);
@@ -295,8 +312,14 @@ bool SDLCore::Update() {
 						}
 					}
 				break;
+				case SDL_JOYAXISMOTION:
+					input->joystickAxisMoved(event.jaxis.axis, ((Number)event.jaxis.value)/32767.0, event.jaxis.which);
+				break;
 				case SDL_JOYBUTTONDOWN:
-//					input->setKeyState((PolyKEY)(event.key.keysym.sym), true);
+					input->joystickButtonDown(event.jbutton.button, event.jbutton.which);
+				break;
+				case SDL_JOYBUTTONUP:
+					input->joystickButtonUp(event.jbutton.button, event.jbutton.which);
 				break;
 				case SDL_KEYDOWN:
 					if(!checkSpecialKeyEvents((PolyKEY)(event.key.keysym.sym))) {

+ 12 - 0
Core/Contents/Source/PolyScreenSprite.cpp

@@ -148,7 +148,13 @@ void ScreenSprite::recalculateSpriteDimensions() {
 	
 	for(int i =0 ; i < animations.size(); i++) {
 		animations[i]->numFramesX = texture->getWidth() / spriteWidth;	
+		if(animations[i]->numFramesX < 1) {
+			animations[i]->numFramesX = 1;
+		}
 		animations[i]->numFramesY = texture->getHeight() / spriteHeight;
+		if(animations[i]->numFramesY < 1) {
+			animations[i]->numFramesY = 1;
+		}		
 		animations[i]->spriteUVWidth = spriteUVWidth;
 		animations[i]->spriteUVHeight = spriteUVHeight;	
 		animations[i]->setOffsetsFromFrameString(animations[i]->frames);
@@ -211,7 +217,13 @@ SpriteAnimation *ScreenSprite::addAnimation(const String& name, const String& fr
 	
 	
 	newAnimation->numFramesX = texture->getWidth() / spriteWidth;	
+	if(newAnimation->numFramesX < 1) {
+		newAnimation->numFramesX = 1;
+	}
 	newAnimation->numFramesY = texture->getHeight() / spriteHeight;
+	if(newAnimation->numFramesY < 1) {
+		newAnimation->numFramesY = 1;
+	}	
 	newAnimation->spriteUVWidth = spriteUVWidth;
 	newAnimation->spriteUVHeight = spriteUVHeight;
 	

+ 6 - 9
IDE/Build/Mac OS X/English.lproj/MainMenu.xib

@@ -680,7 +680,7 @@
 				<string key="NSName">_NSMainMenu</string>
 			</object>
 			<object class="NSWindowTemplate" id="972006081">
-				<int key="NSWindowStyleMask">15</int>
+				<int key="NSWindowStyleMask">13</int>
 				<int key="NSWindowBacking">2</int>
 				<string key="NSWindowRect">{{335, 390}, {800, 600}}</string>
 				<int key="NSWTFlags">1954021376</int>
@@ -690,7 +690,7 @@
 				<nil key="NSUserInterfaceItemIdentifier"/>
 				<string key="NSWindowContentMinSize">{400, 200}</string>
 				<object class="NSView" key="NSWindowView" id="439893737">
-					<nil key="NSNextResponder"/>
+					<reference key="NSNextResponder"/>
 					<int key="NSvFlags">256</int>
 					<object class="NSMutableArray" key="NSSubviews">
 						<bool key="EncodedWithXMLCoder">YES</bool>
@@ -700,6 +700,8 @@
 							<object class="NSPSMatrix" key="NSDrawMatrix"/>
 							<string key="NSFrameSize">{800, 600}</string>
 							<reference key="NSSuperview" ref="439893737"/>
+							<reference key="NSWindow"/>
+							<reference key="NSNextKeyView"/>
 							<object class="NSOpenGLPixelFormat" key="NSPixelFormat">
 								<object class="NSMutableData" key="NSPixelAttributes">
 									<bytes key="NS.bytes">AAAAYAAAAAA</bytes>
@@ -708,6 +710,8 @@
 						</object>
 					</object>
 					<string key="NSFrameSize">{800, 600}</string>
+					<reference key="NSSuperview"/>
+					<reference key="NSWindow"/>
 					<reference key="NSNextKeyView" ref="633009941"/>
 				</object>
 				<string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
@@ -2122,14 +2126,12 @@
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>polycodeView</string>
 							<string>projectMenu</string>
-							<string>sdfsdf</string>
 							<string>window</string>
 						</object>
 						<object class="NSArray" key="dict.values">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>PolycodeView</string>
 							<string>NSMenu</string>
-							<string>NSMenuItem</string>
 							<string>NSWindow</string>
 						</object>
 					</object>
@@ -2139,7 +2141,6 @@
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>polycodeView</string>
 							<string>projectMenu</string>
-							<string>sdfsdf</string>
 							<string>window</string>
 						</object>
 						<object class="NSArray" key="dict.values">
@@ -2152,10 +2153,6 @@
 								<string key="name">projectMenu</string>
 								<string key="candidateClassName">NSMenu</string>
 							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">sdfsdf</string>
-								<string key="candidateClassName">NSMenuItem</string>
-							</object>
 							<object class="IBToOneOutletInfo">
 								<string key="name">window</string>
 								<string key="candidateClassName">NSWindow</string>

+ 12 - 4
IDE/Build/Mac OS X/PolycodeAppDelegate.m

@@ -42,7 +42,7 @@
 - (void)animationTimer:(NSTimer *)timer
 {
 	if(!app->Update()) {
-		[[NSApplication sharedApplication] stop:self];
+		[[NSApplication sharedApplication] terminate:self];
 	}
 	
 	if(mustShowProjectMenu) {
@@ -70,9 +70,17 @@
 }
 
 - (void)applicationWillTerminate:(NSNotification *)aNotification {
-	NSLog(@"STOPPING\n");
-	app->saveConfigFile();
-	app->core->Shutdown();
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)theApplication
+{
+	bool retVal = app->quitApp();
+	if(retVal) {
+		app->saveConfigFile();
+		app->core->Shutdown();
+		printf("STOPPING\n");
+	}
+	return retVal;
 }
 
 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication

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

@@ -98,6 +98,8 @@ public:
 	
 	void refreshProject();	
 	
+	bool quitApp();
+	
 	bool needsRedraw;
 	bool lastConnected;
 	
@@ -111,6 +113,7 @@ public:
 	
 protected:
 
+	bool quittingApp;
 	bool runNextFrame;
 
 	bool willRunProject;

+ 17 - 2
IDE/Contents/Include/PolycodeProps.h

@@ -30,6 +30,7 @@
 
 using namespace Polycode;
 
+#define PROP_PADDING	40
 
 class PolycodeEditorPropActionData;
 
@@ -40,6 +41,8 @@ class PropProp : public UIElement {
 
 		virtual void setPropData(PolycodeEditorPropActionData* data) {}
 		
+		virtual void setPropWidth(Number width) {}
+		
 		String propType;
 		ScreenLabel *label;
 		ScreenEntity *propContents;				
@@ -57,12 +60,17 @@ class Vector2Prop : public PropProp {
 		Vector2 get();
 		
 		void setPropData(PolycodeEditorPropActionData* data);
+		
+		void setPropWidth(Number width);		
 				
 		UITextInput *positionX;
 		UITextInput *positionY;	
 		
 		Vector2 lastData;
-		Vector2 currentData;		
+		Vector2 currentData;	
+		
+		ScreenLabel *labelX;
+		ScreenLabel *labelY;		
 };
 
 class SliderProp : public PropProp {
@@ -73,6 +81,7 @@ class SliderProp : public PropProp {
 		void set(Number number);
 		Number get();
 		
+		void setPropWidth(Number width);		
 		void setPropData(PolycodeEditorPropActionData* data);		
 				
 		UIHSlider *slider;
@@ -91,6 +100,8 @@ class NumberProp : public PropProp {
 		void set(Number number);
 		Number get();
 		
+		void setPropWidth(Number width);
+		
 		void setPropData(PolycodeEditorPropActionData* data);
 				
 		UITextInput *numberEntry;
@@ -122,6 +133,8 @@ class StringProp : public PropProp {
 		void set(String str);
 		String get();
 
+		void setPropWidth(Number width);
+
 		void setPropData(PolycodeEditorPropActionData* data);
 				
 		UITextInput *stringEntry;
@@ -154,7 +167,9 @@ class ComboProp : public PropProp {
 		void handleEvent(Event *event);
 		
 		void setPropData(PolycodeEditorPropActionData* data);
-			
+
+		void setPropWidth(Number width);
+
 		void set(unsigned int index);
 		unsigned int get();
 				

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

@@ -226,7 +226,8 @@ class PolycodeScreenEditorMain : public UIElement {
 		ScreenEntity *placingPreviewEntity;												
 		bool multiSelect;
 		
-		PolycodeEditor *editor;		
+		PolycodeEditor *editor;	
+		ScreenEntity *baseEntity;			
 	protected:
 	
 		PolycodeScreenEditorActionData *beforeData;
@@ -305,7 +306,6 @@ class PolycodeScreenEditorMain : public UIElement {
 		bool isDraggingEntity;
 		bool isScalingEntity;
 		
-		ScreenEntity *baseEntity;
 
 		
 		ScreenEntity *screenTransform;

BIN
IDE/Contents/Resources/UIThemes/default/textfield.png


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

@@ -185,6 +185,10 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	lastConnected = false;
 	
 	frame->closeFileButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	
+	quittingApp = false;
+	
+	CoreServices::getInstance()->getCore()->getInput()->addEventListener(this, InputEvent::EVENT_KEYDOWN);
 }
 
 void PolycodeIDEApp::renameFile() {
@@ -210,6 +214,19 @@ void PolycodeIDEApp::doRemoveFile() {
 		if(projectManager->getActiveProject()) {
 			frame->projectBrowser->refreshProject(projectManager->getActiveProject());
 		}
+		PolycodeEditor *editor;
+		for (int i=0; i < editorManager->openEditors.size(); i++) {
+			if (editorManager->openEditors[i]->getFilePath() == projectManager->selectedFile) {
+				editor = editorManager->openEditors[i];
+				break;
+			}
+		}
+		// have to set changes to false to avoid problems with saving and modal dialogs in removeEditor()
+		// besides, we're removing the file, so saving is not necessary
+		if (editor) {
+			editor->setHasChanges(false);
+			removeEditor(editor);
+		}
 	}
 }
 
@@ -385,6 +402,35 @@ void PolycodeIDEApp::doRunProject() {
 	PolycodeToolLauncher::runPolyapp(outPath);
 }
 
+bool PolycodeIDEApp::quitApp() {	
+
+	quittingApp = true;
+	
+	while(editorManager->getCurrentEditor()) {
+		PolycodeEditor *editor = editorManager->getCurrentEditor();
+		
+		if(editor->hasChanges()) {
+			OSFileEntry entry(editor->getFilePath(), OSFileEntry::TYPE_FILE);	
+			frame->yesNoCancelPopup->setCaption("The file \""+entry.name+"\" has unsaved changes. Save before quitting?");
+			frame->yesNoCancelPopup->action = "closeQuitFile";
+			frame->showModal(frame->yesNoCancelPopup);
+			return false;
+		} 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);
+			}
+		}
+		
+	}
+	
+	return true;
+}
+
 void PolycodeIDEApp::runProject() {
 	if(projectManager->getActiveProject()) {
 		if(editorManager->hasUnsavedFilesForProject(projectManager->getActiveProject())) {
@@ -622,7 +668,8 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 		}
 		
 		if(event->getEventCode() == Event::CHANGE_EVENT) {
-			BrowserUserData *selectedData = frame->getProjectBrowser()->getSelectedData();
+			PolycodeProjectBrowser *pb = frame->getProjectBrowser();
+			BrowserUserData *selectedData = pb->getSelectedData();
 						
 			if(selectedData->type == 3) {
 				projectManager->activeFolder = selectedData->parentProject->getRootFolder();
@@ -645,7 +692,8 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 			if(selectedData->type == 0)
 				return;			
 			
-			if(selectedData) {
+			// don't open the editor if the selection was made by UITreeContainer arrow-key navigation
+			if (selectedData && pb->treeContainer->getRootNode()->getSelectedNode()->isSelectedByKey() == false) {
 				openFile(selectedData->fileEntry);
 			}
 		}
@@ -691,9 +739,41 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 				case UIEvent::CANCEL_EVENT:
 				break;
 			}
-		}
-		
-		else if (frame->yesNoCancelPopup->action == "closeProject") {
+		} else if(frame->yesNoCancelPopup->action == "closeQuitFile") {
+			switch(event->getEventCode()) {
+				case UIEvent::YES_EVENT:
+				{
+					PolycodeEditor *editor = editorManager->getCurrentEditor();
+					if(editor) {
+						editor->saveFile();
+						closeFile();
+					}
+					frame->yesNoCancelPopup->action = "";
+					frame->hideModal();
+					if(quitApp()) {
+						core->Shutdown();
+					}
+				}
+				break;
+				case UIEvent::NO_EVENT:
+				{
+					PolycodeEditor *editor = editorManager->getCurrentEditor();
+					if(editor) {
+						editor->setHasChanges(false);
+						closeFile();
+					}
+					frame->yesNoCancelPopup->action = "";					
+					frame->hideModal();
+					if(quitApp()) {
+						core->Shutdown();
+					}					
+				}
+				break;
+				case UIEvent::CANCEL_EVENT:
+					quittingApp = false;
+				break;
+			}					
+		} else if (frame->yesNoCancelPopup->action == "closeProject") {
 			switch (event->getEventCode()) {
 				case UIEvent::YES_EVENT:
 					saveFiles(tempEditorStore);
@@ -825,6 +905,18 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 				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) {
+			InputEvent *inEvent = (InputEvent*)event;
+			if (inEvent->keyCode() == KEY_RETURN || inEvent->keyCode() == KEY_RIGHT) {
+				BrowserUserData *selectedData = frame->getProjectBrowser()->getSelectedData();
+				if (selectedData)
+					openFile(selectedData->fileEntry);
+			}
+		}
+	}
 }
 
 void PolycodeIDEApp::saveConfigFile() {

+ 39 - 13
IDE/Contents/Source/PolycodeProps.cpp

@@ -164,7 +164,7 @@ void PropList::updateSize() {
 void PropList::Resize(Number width, Number height) {
 	setWidth(width);
 	setHeight(height);
-	
+		
 	scrollContainer->Resize(width, height-30);
 	
 	bg->setShapeSize(width, height);
@@ -288,6 +288,7 @@ void PropSheet::Resize(Number width, Number height) {
 	
 	for(int i=0; i < props.size(); i++) {
 		props[i]->setPosition(0, yOffset);
+		props[i]->setPropWidth(width);
 		yOffset += props[i]->getHeight();
 	}
 }
@@ -329,15 +330,15 @@ PropProp::~PropProp() {
 
 Vector2Prop::Vector2Prop(String caption) : PropProp(caption, "Vector2") {
 
-	ScreenLabel *label = new ScreenLabel("X:", 11);
-	label->color.a = 0.4;
-	propContents->addChild(label);
-	label->setPosition(-20, 6);	
+	labelX = new ScreenLabel("X:", 11);
+	labelX->color.a = 0.4;
+	propContents->addChild(labelX);
+	labelX->setPosition(-20, 6);	
 
-	label = new ScreenLabel("Y:", 11);
-	label->color.a = 0.4;
-	propContents->addChild(label);
-	label->setPosition(60, 6);	
+	labelY = new ScreenLabel("Y:", 11);
+	labelY->color.a = 0.4;
+	propContents->addChild(labelY);
+	labelY->setPosition(60, 6);	
 	
 	positionX = NULL;
 	positionY = NULL;
@@ -360,6 +361,18 @@ Vector2Prop::Vector2Prop(String caption) : PropProp(caption, "Vector2") {
 
 }
 
+void Vector2Prop::setPropWidth(Number width) {
+	labelX->setPosition(0, 6);
+	labelY->setPosition(((width-propContents->position.x-PROP_PADDING)/2.0), 6);	
+	
+	positionX->position.x = labelX->position.x + 20;
+	positionX->Resize(floor(((width-propContents->position.x-PROP_PADDING)/2.0)-25), positionX->getHeight());
+
+	positionY->position.x = labelY->position.x + 20;
+	positionY->Resize(floor(((width-propContents->position.x-PROP_PADDING)/2.0)-25), positionY->getHeight());
+
+}
+
 void Vector2Prop::handleEvent(Event *event) {
 	if(event->getDispatcher() == positionX || event->getDispatcher() == positionY) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {
@@ -462,7 +475,10 @@ StringProp::StringProp(String caption) : PropProp(caption, "String") {
 	propContents->addChild(stringEntry);
 	stringEntry->setPosition(0, 0);
 	setHeight(30);
+}
 
+void StringProp::setPropWidth(Number width) {
+	stringEntry->Resize(width - propContents->position.x - PROP_PADDING, stringEntry->getHeight());
 }
 
 void StringProp::handleEvent(Event *event) {
@@ -485,7 +501,7 @@ void StringProp::setPropData(PolycodeEditorPropActionData* data) {
 
 void StringProp::set(String str) {
 	suppressChangeEvent = true;
-	stringEntry->setText(str, false);
+	stringEntry->setText(str);
 	suppressChangeEvent = false;	
 }
 
@@ -508,10 +524,13 @@ SliderProp::SliderProp(String caption, Number min, Number max) : PropProp(captio
 	valueLabel = new ScreenLabel("0.0", 10);
 	propContents->addChild(valueLabel);
 	valueLabel->setPosition(120, 5);
-	valueLabel->color.a = 0.5;
-	
+	valueLabel->color.a = 0.6;
 	setHeight(30);
+}
 
+void SliderProp::setPropWidth(Number width) {
+	slider->Resize(width - propContents->position.x - PROP_PADDING - 50, slider->getHeight());
+	valueLabel->setPosition(width - propContents->position.x - PROP_PADDING - 30, 5);	
 }
 
 void SliderProp::handleEvent(Event *event) {
@@ -566,6 +585,10 @@ NumberProp::NumberProp(String caption) : PropProp(caption, "Number") {
 
 }
 
+void NumberProp::setPropWidth(Number width) {
+	numberEntry->Resize(width - propContents->position.x - PROP_PADDING, numberEntry->getHeight());
+}
+
 void NumberProp::setPropData(PolycodeEditorPropActionData* data) {
 	set(data->numVal);
 	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
@@ -587,7 +610,7 @@ void NumberProp::handleEvent(Event *event) {
 
 void NumberProp::set(Number number) {
 	suppressChangeEvent = true;
-	numberEntry->setText(String::NumberToString(number), false);
+	numberEntry->setText(String::NumberToString(number));
 	suppressChangeEvent = false;	
 }
 
@@ -653,7 +676,10 @@ ComboProp::ComboProp(String caption) : PropProp(caption, "Combo") {
 	propContents->addChild(comboEntry);
 	comboEntry->setPosition(-3, 0);
 	setHeight(30);
+}
 
+void ComboProp::setPropWidth(Number width) {
+	comboEntry->Resize(width - propContents->position.x - PROP_PADDING, comboEntry->getHeight());
 }
 
 void ComboProp::setPropData(PolycodeEditorPropActionData* data) {

+ 9 - 3
IDE/Contents/Source/PolycodeScreenEditor.cpp

@@ -2526,7 +2526,7 @@ void PolycodeScreenEditorMain::handleDroppedFile(OSFileEntry file, Number x, Num
 
 PolycodeScreenEditor::PolycodeScreenEditor() : PolycodeEditor(true){
 
-	mainSizer = new UIHSizer(100,100,300,false);
+	mainSizer = new UIHSizer(100,100,340,false);
 	addChild(mainSizer);	
 
 	editorMain = new PolycodeScreenEditorMain(this);
@@ -2553,11 +2553,17 @@ PolycodeScreenEditor::PolycodeScreenEditor() : PolycodeEditor(true){
 }
 
 String PolycodeScreenEditor::Copy(void **data) {
-	return editorMain->Copy(data);
+	if(editorMain->baseEntity->hasFocus) {
+		return editorMain->Copy(data);
+	} else {
+		return "";
+	}
 }
 
 void PolycodeScreenEditor::Paste(void *data, String clipboardType) {
-	editorMain->Paste(data, clipboardType);
+	if(editorMain->baseEntity->hasFocus) {
+		editorMain->Paste(data, clipboardType);
+	}
 }
 
 void PolycodeScreenEditor::destroyClipboardData(void *data, String type) {

+ 5 - 1
Modules/Contents/UI/Include/PolyUIComboBox.h

@@ -60,6 +60,8 @@ namespace Polycode {
 			void setSelectedIndex(unsigned int newIndex);
 			void handleEvent(Event *event);
 			
+			void Resize(Number width, Number height);
+			
 			unsigned int getNumItems();
 			UIComboBoxItem *getItemAtIndex(unsigned int index);
 							
@@ -75,7 +77,9 @@ namespace Polycode {
 			ScreenLabel *selectedLabel;
 			Number comboHeight;
 			Number comboWidth;
-			
+			Number dropDownX;
+			Number dropDownY;
+						
 			int selectedOffset;
 						
 			Number nextItemHeight;

+ 4 - 0
Modules/Contents/UI/Include/PolyUIHSlider.h

@@ -40,6 +40,8 @@ namespace Polycode {
 			void handleEvent(Event *event);
 			void Update();
 			
+			void Resize(Number width, Number height);
+			
 			void setSliderValue(Number val);
 			Number getSliderValue();			
 			
@@ -49,6 +51,8 @@ namespace Polycode {
 			
 			bool dragging;
 			
+			Number bgHeight;
+			
 			Number labelXPos;
 			Number labelYPos;
 			UIBox *bgRect;

+ 5 - 1
Modules/Contents/UI/Include/PolyUITree.h

@@ -54,7 +54,7 @@ namespace Polycode {
 			void setUserData(void *data);
 			UITree *getSelectedNode();
 			void setIcon(String iconFile);
-			void setSelected();
+			void setSelected(bool byKey=false);
 			
 			void setLabelText(const String &text);
 			
@@ -74,6 +74,8 @@ namespace Polycode {
 			UITree *getPrevSibling();
 			UITree *getNextSibling();
 			Number getCellHeight() { return cellHeight; }
+
+			bool isSelectedByKey() { return selectedByKey; }
 		
 		private:
 
@@ -104,5 +106,7 @@ namespace Polycode {
 			int size;
 			Number cellHeight;
 			Number cellPadding;
+
+			bool selectedByKey;
 	};
 }

+ 1 - 2
Modules/Contents/UI/Include/PolyUITreeContainer.h

@@ -47,9 +47,8 @@ namespace Polycode {
 		 * Scrolls the container to show a specified node.
 		 * @param node The tree node to scroll to or show.
 		 * @param showAtTop If true, show the node at the top of the container. If false, show it at the bottom.
-		 * @param select If true (default), select the node. If false, don't.
 		 */
-		void scrollToNode(UITree *node, bool showAtTop, bool select=true);
+		void scrollToNode(UITree *node, bool showAtTop);
 		
 	protected:
 		bool keyNavigable;

+ 12 - 2
Modules/Contents/UI/Source/PolyUIComboBox.cpp

@@ -58,8 +58,8 @@ UIComboBox::UIComboBox(UIGlobalMenu *globalMenu, Number comboWidth) : UIElement(
 	Number paddingX = conf->getNumericValue("Polycode", "uiComboBoxTextOffsetX");	
 	Number paddingY = conf->getNumericValue("Polycode", "uiComboBoxTextOffsetY");	
 
-	Number dropDownX = conf->getNumericValue("Polycode", "uiComboBoxDropX");
-	Number dropDownY = conf->getNumericValue("Polycode", "uiComboBoxDropY");
+	dropDownX = conf->getNumericValue("Polycode", "uiComboBoxDropX");
+	dropDownY = conf->getNumericValue("Polycode", "uiComboBoxDropY");
 		
 	dropDownImage = new ScreenImage(dropDownImageFile);
 	dropDownImage->setPosition(comboWidth - dropDownImage->getWidth() - dropDownX,dropDownY);
@@ -100,6 +100,16 @@ UIComboBox::UIComboBox(UIGlobalMenu *globalMenu, Number comboWidth) : UIElement(
 	this->height = comboHeight;
 }
 
+void UIComboBox::Resize(Number width, Number height) {
+	this->comboWidth = width;
+	bgBox->resizeBox(width, comboHeight);
+	this->width = width;
+	this->height = height;	
+	matrixDirty = true;	
+	setHitbox(width,height);
+	dropDownImage->setPosition(comboWidth - dropDownImage->getWidth() - dropDownX,dropDownY);	
+}
+
 UIComboBox::~UIComboBox() {
 	for(int c = 0; c < items.size(); c++)
 		delete items[c];

+ 12 - 1
Modules/Contents/UI/Source/PolyUIHSlider.cpp

@@ -33,7 +33,7 @@ UIHSlider::UIHSlider(Number start, Number end, Number width) : UIElement() {
 	
 	String bgImage = conf->getStringValue("Polycode", "uiHSliderBg");
 	String gripImage = conf->getStringValue("Polycode", "uiHSliderGrip");	
-	Number bgHeight = conf->getNumericValue("Polycode", "uiHSliderBgHeight");
+	bgHeight = conf->getNumericValue("Polycode", "uiHSliderBgHeight");
 
 	Number st = conf->getNumericValue("Polycode", "uiHSliderBgT");
 	Number sr = conf->getNumericValue("Polycode", "uiHSliderBgR");
@@ -97,6 +97,17 @@ void UIHSlider::setSliderValue(Number val) {
 Number UIHSlider::getSliderValue() {
 	return sliderValue;
 }
+
+void UIHSlider::Resize(Number width, Number height) {
+	bgRect->resizeBox(width, bgHeight);
+	this->width = width;
+	this->height = height;	
+	matrixDirty = true;	
+	setHitbox(width,height);
+	sliderWidth = width;
+	gripRect->setDragLimits(Rectangle(0,floor(bgHeight/2.0),width,0));	
+	setSliderValue(sliderValue);
+}
 			
 void UIHSlider::handleEvent(Event *event) {
 

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

@@ -123,8 +123,8 @@ UITextInput::UITextInput(bool multiLine, Number width, Number height) : UIElemen
 		decoratorOffset = sl/2.0;
 	}
 
-	textContainer->setWidth(this->getWidth() - textContainer->getPosition2D().x - padding);
-	textContainer->setHeight(this->getHeight() - textContainer->getPosition2D().y);
+	textContainer->setWidth(fabs(this->getWidth() - textContainer->getPosition2D().x - padding));
+	textContainer->setHeight(fabs(this->getHeight() - textContainer->getPosition2D().y));
 	textContainer->setPosition(padding + decoratorOffset, padding);
 	
 	inputRect->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
@@ -487,6 +487,10 @@ void UITextInput::Resize(Number width, Number height) {
 	matrixDirty = true;	
 	setHitbox(width,height);
 	
+	textContainer->setWidth(fabs(this->getWidth() - textContainer->getPosition2D().x - padding));
+	textContainer->setHeight(fabs(this->getHeight() - textContainer->getPosition2D().y));
+	textContainer->setPosition(padding + decoratorOffset, padding);		
+	
 	if(multiLine) {
 		inputRect->setHitbox(width - scrollContainer->getVScrollWidth(), height);
 		
@@ -578,9 +582,9 @@ void UITextInput::renumberLines() {
 
 	// Update the position and width of the text accordingly.
 	textContainer->setPosition(decoratorOffset + padding, padding);
-	textContainer->setWidth(this->getWidth() - textContainer->getPosition2D().x - padding);
-	textContainer->setHeight(this->getHeight() - textContainer->getPosition2D().y - padding);
-	textContainer->scissorBox.setRect(textContainer->getPosition2D().x, textContainer->getPosition2D().y, textContainer->getWidth(), textContainer->getHeight());
+	textContainer->setWidth(fabs(this->getWidth() - textContainer->getPosition2D().x - padding));
+	textContainer->setHeight(fabs(this->getHeight() - textContainer->getPosition2D().y - padding));
+	textContainer->scissorBox.setRect(textContainer->getPosition2D().x, textContainer->getPosition2D().y, textContainer->getWidth(), textContainer->getHeight()+padding);
 }
 
 void UITextInput::restructLines() {
@@ -1457,7 +1461,7 @@ void UITextInput::Update() {
 	}
 	linesToDelete.clear();
 
-	textContainer->scissorBox.setRect(textContainer->getScreenPosition().x, textContainer->getScreenPosition().y, textContainer->getWidth(), textContainer->getHeight());
+	textContainer->scissorBox.setRect(textContainer->getScreenPosition().x, textContainer->getScreenPosition().y, textContainer->getWidth(), textContainer->getHeight() + padding);
 }
 
 UITextInput::~UITextInput() {

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

@@ -145,7 +145,8 @@ void UITree::removeTreeChild(UITree *child) {
 	}
 }
 
-void UITree::setSelected() {
+void UITree::setSelected(bool byKey) {
+	selectedByKey = byKey;
 	selected = true;
 	refreshTree();
 	if(parent == NULL) {

+ 8 - 15
Modules/Contents/UI/Source/PolyUITreeContainer.cpp

@@ -167,9 +167,9 @@ void UITreeContainer::onKeyDown(PolyKEY key, wchar_t charCode) {
 					for (int i=0; i < parent->getNumTreeChildren(); i++) {
 						if (parent->getTreeChild(i) == currentSelection) {
 							if (i == 0)
-								parent->setSelected();
+								parent->setSelected(true);
 							else
-								findLastOpenNode((parent->getTreeChild(i-1)))->setSelected();
+								findLastOpenNode((parent->getTreeChild(i-1)))->setSelected(true);
 							scrollDir = UP;
 							break;
 						}
@@ -185,7 +185,7 @@ void UITreeContainer::onKeyDown(PolyKEY key, wchar_t charCode) {
 					parent = getRootNode();
 
 				if (currentSelection->hasTreeChildren() && !currentSelection->isCollapsed()) {
-					currentSelection->getTreeChild(0)->setSelected();
+					currentSelection->getTreeChild(0)->setSelected(true);
 					scrollDir = DOWN;
 				}
 				else {
@@ -194,9 +194,9 @@ void UITreeContainer::onKeyDown(PolyKEY key, wchar_t charCode) {
 							if (i == parent->getNumTreeChildren()-1) {
 								UITree *psib = findNextParentSibling(parent);
 								if (psib)
-									psib->setSelected();
+									psib->setSelected(true);
 							} else {
-								parent->getTreeChild(i+1)->setSelected();
+								parent->getTreeChild(i+1)->setSelected(true);
 							}
 							scrollDir = DOWN;
 							break;
@@ -209,7 +209,7 @@ void UITreeContainer::onKeyDown(PolyKEY key, wchar_t charCode) {
 				if (currentSelection->hasTreeChildren() && !currentSelection->isCollapsed())
 					currentSelection->toggleCollapsed();
 				else if (parent) {
-					parent->setSelected();
+					parent->setSelected(true);
 					scrollDir = UP;
 				}
 			}
@@ -218,15 +218,11 @@ void UITreeContainer::onKeyDown(PolyKEY key, wchar_t charCode) {
 				if (currentSelection->hasTreeChildren()) {
 					if (currentSelection->isCollapsed())
 						currentSelection->toggleCollapsed();
-					else {
-						currentSelection->getTreeChild(0)->setSelected();
-						scrollDir = DOWN;
-					}
 				}
 			}
 			
 			if (scrollDir != NONE)
-				scrollToNode(getRootNode()->getSelectedNode(), (scrollDir == UP) ? true : false, false);
+				scrollToNode(getRootNode()->getSelectedNode(), (scrollDir == UP) ? true : false);
 		}
 		//
 		// END KEYBOARD NAV STUFF
@@ -234,7 +230,7 @@ void UITreeContainer::onKeyDown(PolyKEY key, wchar_t charCode) {
 	}
 }
 
-void UITreeContainer::scrollToNode(UITree *node, bool showAtTop, bool select) {
+void UITreeContainer::scrollToNode(UITree *node, bool showAtTop) {
 	
 	Number nodeY = node->getScreenPosition().y - getRootNode()->getScreenPosition().y;
 	Number contentHeight = mainContainer->getContentSize().y;
@@ -242,9 +238,6 @@ void UITreeContainer::scrollToNode(UITree *node, bool showAtTop, bool select) {
 	Number viewTop = (contentHeight - mainContainer->getHeight()) * mainContainer->getVScrollBar()->getScrollValue();
 	Number viewBottom = viewTop + mainContainer->getHeight();
 	
-	if (select)
-		node->setSelected();
-	
 	if (nodeY < viewTop || nodeY+node->getCellHeight() > viewBottom) {
 		if (showAtTop)
 			mainContainer->scrollVertical((nodeY-viewTop) / scrollHeight);

+ 43 - 0
Player/Contents/Source/PolycodePlayer.cpp

@@ -677,6 +677,9 @@ void PolycodePlayer::loadFile(const char *fileName) {
 	core->getInput()->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 	core->getInput()->addEventListener(this, InputEvent::EVENT_MOUSEMOVE);
 	core->getInput()->addEventListener(this, InputEvent::EVENT_MOUSEUP);
+	core->getInput()->addEventListener(this, InputEvent::EVENT_JOYBUTTON_DOWN);
+	core->getInput()->addEventListener(this, InputEvent::EVENT_JOYBUTTON_UP);
+	core->getInput()->addEventListener(this, InputEvent::EVENT_JOYAXIS_MOVED);
 					
 	if(nameString == "") {
 		return;
@@ -890,6 +893,46 @@ void PolycodePlayer::handleEvent(Event *event) {
 				}
 			}
 			break;																			
+			case InputEvent::EVENT_JOYBUTTON_DOWN:
+			{
+				if(L && !crashed) {
+					lua_getfield (L, LUA_GLOBALSINDEX, "__customError");
+					errH = lua_gettop(L);									
+					lua_getfield(L, LUA_GLOBALSINDEX, "onJoystickButtonDown");
+					lua_pushnumber(L, inputEvent->joystickIndex);
+					lua_pushnumber(L, inputEvent->joystickButton);
+					lua_pcall(L, 2,0,errH);	
+					lua_settop(L, 0);					
+				}
+			}
+			break;																			
+			case InputEvent::EVENT_JOYBUTTON_UP:
+			{
+				if(L && !crashed) {
+					lua_getfield (L, LUA_GLOBALSINDEX, "__customError");
+					errH = lua_gettop(L);									
+					lua_getfield(L, LUA_GLOBALSINDEX, "onJoystickButtonUp");
+					lua_pushnumber(L, inputEvent->joystickIndex);
+					lua_pushnumber(L, inputEvent->joystickButton);
+					lua_pcall(L, 2,0,errH);	
+					lua_settop(L, 0);
+				}
+			}
+			break;																			
+			case InputEvent::EVENT_JOYAXIS_MOVED:
+			{
+				if(L && !crashed) {
+					lua_getfield (L, LUA_GLOBALSINDEX, "__customError");
+					errH = lua_gettop(L);									
+					lua_getfield(L, LUA_GLOBALSINDEX, "onJoystickAxisMoved");
+					lua_pushnumber(L, inputEvent->joystickIndex);
+					lua_pushnumber(L, inputEvent->joystickAxis);
+					lua_pushnumber(L, inputEvent->joystickAxisValue);
+					lua_pcall(L, 3,0,errH);	
+					lua_settop(L, 0);
+				}
+			}
+			break;																			
 		}
 	}
 }