Browse Source

components cleanup, more css, texture select component

Nicolas Cannasse 8 years ago
parent
commit
c3f84ca028

+ 60 - 38
bin/style.css

@@ -3,6 +3,9 @@ body {
   padding: 0;
   padding: 0;
   background-color: black;
   background-color: black;
 }
 }
+a {
+  text-decoration: none;
+}
 ul,
 ul,
 li {
 li {
   margin: 0;
   margin: 0;
@@ -24,6 +27,28 @@ select {
 input {
 input {
   padding-left: 4px;
   padding-left: 4px;
 }
 }
+select:focus {
+  outline: none;
+}
+select:focus:hover {
+  border-color: #444;
+}
+select,
+input {
+  background-color: #222222;
+  border: 1px solid #444;
+}
+select:focus,
+input:focus {
+  background-color: #141414;
+}
+select:hover,
+input:hover {
+  border-color: #888;
+}
+input[type=texture] {
+  cursor: pointer;
+}
 input[type=button] {
 input[type=button] {
   background-color: #444;
   background-color: #444;
   cursor: pointer;
   cursor: pointer;
@@ -34,12 +59,13 @@ input[type=button]:hover {
 }
 }
 input[type=range] {
 input[type=range] {
   -webkit-appearance: none;
   -webkit-appearance: none;
-  /* Hides the slider so that custom slider can be made */
   background: transparent;
   background: transparent;
-  /* Otherwise white in Chrome */
   border: none;
   border: none;
   padding: 0;
   padding: 0;
 }
 }
+input[type=range]:focus {
+  outline: none;
+}
 input[type=range]::-webkit-slider-thumb {
 input[type=range]::-webkit-slider-thumb {
   -webkit-appearance: none;
   -webkit-appearance: none;
   outline: 1px solid #aaa;
   outline: 1px solid #aaa;
@@ -48,7 +74,6 @@ input[type=range]::-webkit-slider-thumb {
   background: #ccc;
   background: #ccc;
   cursor: pointer;
   cursor: pointer;
   margin-top: 0px;
   margin-top: 0px;
-  /* You need to specify a margin in Chrome, but in Firefox and IE it is automatic */
 }
 }
 input[type=range]::-webkit-slider-runnable-track {
 input[type=range]::-webkit-slider-runnable-track {
   width: 100%;
   width: 100%;
@@ -57,14 +82,7 @@ input[type=range]::-webkit-slider-runnable-track {
   background: #141414;
   background: #141414;
   border: 1px solid #444;
   border: 1px solid #444;
 }
 }
-input[type=range]:focus {
-  outline: none;
-  /* Removes the blue border. You should probably do some kind of focus styling for accessibility reasons though. */
-}
-.checkbox-wrapper {
-  display: inline-block;
-}
-input[type='checkbox'] {
+input[type=checkbox] {
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
   text-rendering: optimizeSpeed;
   text-rendering: optimizeSpeed;
   width: 13px;
   width: 13px;
@@ -77,7 +95,7 @@ input[type='checkbox'] {
   cursor: pointer;
   cursor: pointer;
   top: 1px;
   top: 1px;
 }
 }
-input[type='checkbox']:after {
+input[type=checkbox]:after {
   content: "";
   content: "";
   vertical-align: middle;
   vertical-align: middle;
   text-align: center;
   text-align: center;
@@ -93,25 +111,13 @@ input[type='checkbox']:after {
   background: #202020;
   background: #202020;
   color: #fff;
   color: #fff;
 }
 }
-input[type='checkbox']:checked:after {
+input[type=checkbox]:checked:after {
   content: '\2714';
   content: '\2714';
 }
 }
-a {
-  text-decoration: none;
-}
 #mainmenu {
 #mainmenu {
   display: none;
   display: none;
 }
 }
-select,
-input {
-  background-color: #222222;
-  border: 1px solid #444;
-}
-select:focus,
-input:focus {
-  background-color: #141414;
-}
-.hide-scrollzone {
+.hide-scroll {
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
   overflow: auto;
   overflow: auto;
@@ -126,16 +132,26 @@ input:focus {
 ::-webkit-scrollbar-thumb {
 ::-webkit-scrollbar-thumb {
   background: #ddd;
   background: #ddd;
 }
 }
+.checkbox-wrapper {
+  display: inline-block;
+}
 .hide-loading {
 .hide-loading {
   width: 16px;
   width: 16px;
   height: 16px;
   height: 16px;
   display: inline-block;
   display: inline-block;
   background: url('libs/jstree/default-dark/throbber.gif');
   background: url('libs/jstree/default-dark/throbber.gif');
 }
 }
+.hide-scene-container {
+  width: 100%;
+  height: 100%;
+  position: relative;
+}
 .hide-scene {
 .hide-scene {
+  position: absolute;
   cursor: default;
   cursor: default;
 }
 }
 .hide-scene-layer {
 .hide-scene-layer {
+  width: auto;
   position: absolute;
   position: absolute;
   z-index: 1;
   z-index: 1;
   height: 100%;
   height: 100%;
@@ -144,21 +160,19 @@ input:focus {
   background: transparent !important;
   background: transparent !important;
   user-select: none;
   user-select: none;
 }
 }
-.hide-toolbar {
-  display: flex;
-  flex-direction: column;
+.flex {
+  width: 100%;
   height: 100%;
   height: 100%;
+  display: flex;
 }
 }
-.hide-toolbar > .content {
+.flex > * {
   flex-grow: 100;
   flex-grow: 100;
-  position: relative;
 }
 }
-.hide-toolbar > .content > canvas {
-  position: absolute;
+.flex.vertical {
+  flex-direction: column;
 }
 }
-.hide-toolbar > .toolbar {
-  width: 100%;
-  height: 24px;
+.hide-toolbar {
+  flex: none;
   padding: 4px;
   padding: 4px;
   padding-top: 2px;
   padding-top: 2px;
   padding-bottom: 6px;
   padding-bottom: 6px;
@@ -226,7 +240,7 @@ input:focus {
   display: flex;
   display: flex;
 }
 }
 .hide-properties > .panel {
 .hide-properties > .panel {
-  width: 260px;
+  flex: 0 0 260px;
   padding: 10px;
   padding: 10px;
   overflow: auto;
   overflow: auto;
 }
 }
@@ -314,6 +328,14 @@ div.lm_close_tab:hover {
   background-color: #555 !important;
   background-color: #555 !important;
 }
 }
 /* JSTree fixes */
 /* JSTree fixes */
+.jstree {
+  background: transparent !important;
+}
+.jstree-icon.jstree-ocl {
+  opacity: 0.7;
+  width: 18px !important;
+  top: -1px;
+}
 .jstree-icon {
 .jstree-icon {
-  color: #888 !important;
+  color: #aaa !important;
 }
 }

+ 116 - 88
bin/style.less

@@ -4,6 +4,11 @@ body {
 	background-color : black;
 	background-color : black;
 }
 }
 
 
+
+a {
+	text-decoration : none;
+}
+
 ul, li {
 ul, li {
 	margin : 0;
 	margin : 0;
 	padding : 0;
 	padding : 0;
@@ -20,50 +25,67 @@ input {
 	padding-left : 4px;
 	padding-left : 4px;
 }
 }
 
 
-input[type=button] {
-	background-color : #444;
-	cursor : pointer;
-}
-
-input[type=button]:hover {
-	color : white;
-	background-color : #666;
+select {
+	&:focus {
+		outline: none;
+	}
+	&:focus:hover {
+		border-color : #444;
+	}
 }
 }
 
 
-input[type=range] {
-	-webkit-appearance: none; /* Hides the slider so that custom slider can be made */
-	background: transparent; /* Otherwise white in Chrome */
-	border:none;
-	padding:0;
+select, input {
+	background-color: rgb(34,34,34);
+	border : 1px solid #444;
+	&:focus {
+		background-color: rgb(20,20,20);
+	}
+	&:hover {
+		border-color : #888;
+	}
 }
 }
 
 
-input[type=range]::-webkit-slider-thumb {
-	-webkit-appearance: none;
-	outline: 1px solid #aaa;
-	height: 6px;
-	width: 6px;
-	background: #ccc;
-	cursor: pointer;
-	margin-top: 0px; /* You need to specify a margin in Chrome, but in Firefox and IE it is automatic */
+input[type=texture] {
+	cursor : pointer;
 }
 }
 
 
-input[type=range]::-webkit-slider-runnable-track {
-	width: 100%;
-	height: 8px;
-	cursor: pointer;
-	background: rgb(20,20,20);
-	border: 1px solid #444;
+input[type=button] {
+	background-color : #444;
+	cursor : pointer;
+	&:hover {
+		color : white;
+		background-color : #666;
+	}
 }
 }
 
 
-input[type=range]:focus {
-	outline: none; /* Removes the blue border. You should probably do some kind of focus styling for accessibility reasons though. */
-}
+input[type=range] {
+	-webkit-appearance: none;
+	background: transparent;
+	border:none;
+	padding:0;
+	&:focus {
+		outline: none;
+	}
+	&::-webkit-slider-thumb {
+		-webkit-appearance: none;
+		outline: 1px solid #aaa;
+		height: 6px;
+		width: 6px;
+		background: #ccc;
+		cursor: pointer;
+		margin-top: 0px;
+	}
 
 
-.checkbox-wrapper {
-	display:inline-block;
+	&::-webkit-slider-runnable-track {
+		width: 100%;
+		height: 8px;
+		cursor: pointer;
+		background: rgb(20,20,20);
+		border: 1px solid #444;
+	}
 }
 }
 
 
-input[type='checkbox'] {
+input[type=checkbox] {
     -webkit-font-smoothing: antialiased;
     -webkit-font-smoothing: antialiased;
     text-rendering: optimizeSpeed;
     text-rendering: optimizeSpeed;
     width: 13px;
     width: 13px;
@@ -75,44 +97,31 @@ input[type='checkbox'] {
     position: relative;
     position: relative;
     cursor:pointer;
     cursor:pointer;
 	top:1px;
 	top:1px;
-}
-
-input[type='checkbox']:after {
-    content:"";
-    vertical-align: middle;
-    text-align: center;
-    line-height: 13px;
-    position: absolute;
-    cursor: pointer;
-    height: 13px;
-    width: 13px;
-    left:0px;
-    top:0px;
-    font-size:10px;
-    box-shadow: inset 0px 1px 1px #000, 0px 1px 0px #444;
-    background: #202020;
-    color: #fff;
-}
-
-input[type='checkbox']:checked:after {
-    content:'\2714';
-}
+	&:after {
+		content:"";
+		vertical-align: middle;
+		text-align: center;
+		line-height: 13px;
+		position: absolute;
+		cursor: pointer;
+		height: 13px;
+		width: 13px;
+		left:0px;
+		top:0px;
+		font-size:10px;
+		box-shadow: inset 0px 1px 1px #000, 0px 1px 0px #444;
+		background: #202020;
+		color: #fff;
+	}
 
 
-a {
-	text-decoration : none;
+	&:checked:after {
+		content:'\2714';
+	}
 }
 }
 
 
 #mainmenu { display : none }
 #mainmenu { display : none }
 
 
-select, input {
-	background-color: rgb(34,34,34);
-	border : 1px solid #444;
-	&:focus {
-		background-color: rgb(20,20,20);
-	}
-}
-
-.hide-scrollzone {
+.hide-scroll {
 	width : 100%;
 	width : 100%;
 	height : 100%;
 	height : 100%;
 	overflow : auto;
 	overflow : auto;
@@ -131,6 +140,10 @@ select, input {
 	background: #ddd;
 	background: #ddd;
 }
 }
 
 
+.checkbox-wrapper {
+	display:inline-block;
+}
+
 .hide-loading {
 .hide-loading {
 	width : 16px;
 	width : 16px;
 	height : 16px;
 	height : 16px;
@@ -138,11 +151,19 @@ select, input {
 	background : url('libs/jstree/default-dark/throbber.gif');
 	background : url('libs/jstree/default-dark/throbber.gif');
 }
 }
 
 
+.hide-scene-container {
+	width:100%;
+	height:100%;
+	position:relative;
+}
+
 .hide-scene {
 .hide-scene {
+	position:absolute;
 	cursor: default;
 	cursor: default;
 }
 }
 
 
 .hide-scene-layer {
 .hide-scene-layer {
+	width:auto;
 	position: absolute;
 	position: absolute;
 	z-index: 1;
 	z-index: 1;
 	height: 100%;
 	height: 100%;
@@ -153,30 +174,27 @@ select, input {
 	}
 	}
 }
 }
 
 
-.hide-toolbar {
+.flex {
+	width:100%;
+	height:100%;
+	display:flex;
+	>* {
+		flex-grow : 100;
+	}
+}
 
 
-	display: flex;
+.flex.vertical {
 	flex-direction: column;
 	flex-direction: column;
-	height : 100%;
-
-	>.content {
-		flex-grow: 100;
-		position: relative;
-		>canvas {
-			position : absolute;
-		}
-	}
+}
 
 
-	>.toolbar {
-		width: 100%;
-		height : 24px;
-		padding : 4px;
-		padding-top: 2px;
-		padding-bottom: 6px;
-		background-color : rgb(34,34,34);
-		border-bottom : 1px solid #000;
-	}
+.hide-toolbar {
 
 
+	flex: none;
+	padding : 4px;
+	padding-top: 2px;
+	padding-bottom: 6px;
+	background-color : rgb(34,34,34);
+	border-bottom : 1px solid #000;
 
 
 	.button, .toggle {
 	.button, .toggle {
 		margin-right : 5px;
 		margin-right : 5px;
@@ -242,7 +260,7 @@ select, input {
 	display: flex;
 	display: flex;
 
 
 	>.panel {
 	>.panel {
-		width : 260px;
+		flex : 0 0 260px;
 		padding:10px;
 		padding:10px;
 		overflow:auto;
 		overflow:auto;
 	}
 	}
@@ -338,6 +356,16 @@ div.lm_close_tab:hover { background-color : #555 !important; }
 
 
 /* JSTree fixes */
 /* JSTree fixes */
 
 
+.jstree {
+	background:transparent !important;
+}
+
+.jstree-icon.jstree-ocl {
+	opacity: 0.7;
+	width:18px !important;
+	top:-1px;
+}
+
 .jstree-icon {
 .jstree-icon {
-	color : #888 !important;
+	color : #aaa !important;
 }
 }

+ 9 - 1
hide/comp/Properties.hx

@@ -47,13 +47,21 @@ class Properties extends Component {
 			var fname = f.attr("field");
 			var fname = f.attr("field");
 			var current : Dynamic = Reflect.field(context, fname);
 			var current : Dynamic = Reflect.field(context, fname);
 			var enumValue : Enum<Dynamic> = null;
 			var enumValue : Enum<Dynamic> = null;
-			if( f.attr("type") == "checkbox" ) {
+
+			switch( f.attr("type") ) {
+			case "checkbox":
 				f.prop("checked", current);
 				f.prop("checked", current);
 				f.change(function(_) {
 				f.change(function(_) {
 					beforeChange();
 					beforeChange();
 					Reflect.setProperty(context, fname, f.prop("checked"));
 					Reflect.setProperty(context, fname, f.prop("checked"));
 				});
 				});
 				continue;
 				continue;
+			case "texture":
+				var sel = new hide.comp.TextureSelect(f);
+				sel.value = current;
+				sel.onChange = function() Reflect.setProperty(context, fname, sel.value);
+				continue;
+			default:
 			}
 			}
 
 
 			if( f.is("select") ) {
 			if( f.is("select") ) {

+ 16 - 2
hide/comp/Scene.hx

@@ -57,6 +57,7 @@ class Scene extends Component implements h3d.IDrawable {
 
 
 	public function new(root) {
 	public function new(root) {
 		super(root);
 		super(root);
+		root.addClass("hide-scene-container");
 		canvas = cast new Element("<canvas class='hide-scene' style='width:100%;height:100%'/>").appendTo(root)[0];
 		canvas = cast new Element("<canvas class='hide-scene' style='width:100%;height:100%'/>").appendTo(root)[0];
 		canvas.addEventListener("mousemove",function(_) canvas.focus());
 		canvas.addEventListener("mousemove",function(_) canvas.focus());
 		canvas.addEventListener("mouseleave",function(_) canvas.blur());
 		canvas.addEventListener("mouseleave",function(_) canvas.blur());
@@ -65,6 +66,7 @@ class Scene extends Component implements h3d.IDrawable {
 			e.preventDefault();
 			e.preventDefault();
 			return false;
 			return false;
 		};
 		};
+		untyped canvas.__scene = this;
 		haxe.Timer.delay(delayedInit,0); // wait canvas added to window
 		haxe.Timer.delay(delayedInit,0); // wait canvas added to window
 	}
 	}
 
 
@@ -156,8 +158,9 @@ class Scene extends Component implements h3d.IDrawable {
 
 
 	function resolvePath( modelPath : String, filePath : String ) {
 	function resolvePath( modelPath : String, filePath : String ) {
 		inline function exists(path) return sys.FileSystem.exists(path);
 		inline function exists(path) return sys.FileSystem.exists(path);
-		if( exists(filePath) )
-			return filePath;
+		var fullPath = ide.getPath(filePath);
+		if( exists(fullPath) )
+			return fullPath;
 		filePath = filePath.split("\\").join("/");
 		filePath = filePath.split("\\").join("/");
 		modelPath = ide.getPath(modelPath);
 		modelPath = ide.getPath(modelPath);
 
 
@@ -175,6 +178,7 @@ class Scene extends Component implements h3d.IDrawable {
 		if( path != null ) {
 		if( path != null ) {
 			var t = new h3d.mat.Texture(1,1);
 			var t = new h3d.mat.Texture(1,1);
 			t.clear(0x102030);
 			t.clear(0x102030);
+			t.name = ide.makeRelative(path);
 			loadTexture(path, function(_) {}, t);
 			loadTexture(path, function(_) {}, t);
 			return t;
 			return t;
 		}
 		}
@@ -208,4 +212,14 @@ class Scene extends Component implements h3d.IDrawable {
 	public dynamic function onReady() {
 	public dynamic function onReady() {
 	}
 	}
 
 
+	public static function getNearest( e : Element ) : Scene {
+		while( e.length > 0 ) {
+			var c : Dynamic = e.find("canvas")[0];
+			if( c != null && c.__scene != null )
+				return c.__scene;
+			e = e.parent();
+		}
+		return null;
+	}
+
 }
 }

+ 0 - 12
hide/comp/ScrollZone.hx

@@ -1,12 +0,0 @@
-package hide.comp;
-
-class ScrollZone extends Component {
-
-	public var content : Element;
-
-	public function new(root) {
-		super(root);
-		content = new Element("<div class='hide-scrollzone'>").appendTo(root);
-	}
-
-}

+ 50 - 0
hide/comp/TextureSelect.hx

@@ -0,0 +1,50 @@
+package hide.comp;
+
+class TextureSelect extends Component {
+
+	var engine : h3d.Engine;
+	public var value(default, set) : h3d.mat.Texture;
+
+	public function new(root) {
+		super(root);
+		root.mousedown(function(e) {
+			e.preventDefault();
+			if( e.button == 0 ) {
+				ide.chooseFile(["jpg", "jpeg", "gif"], function(path) {
+					value = Scene.getNearest(root).loadTextureFile("", path);
+					onChange();
+				});
+			}
+		});
+		root.contextmenu(function(e) {
+			e.preventDefault();
+			var path = getPath();
+			new ContextMenu([
+				{ label : "View", enabled : path != null, click : function() ide.open("hide.view.Image", {path:path}) },
+				{ label : "Clear", enabled : value != null, click : function() { value = null; onChange(); } },
+			]);
+			return false;
+		});
+	}
+
+	public function getPath() {
+		var t = value;
+		if( t == null || t.name == null )
+			return null;
+		var path = ide.getPath(t.name);
+		if( sys.FileSystem.exists(path) )
+			return path;
+		return null;
+	}
+
+	function set_value(t:h3d.mat.Texture) {
+		var path = t == null ? "-- select --" : t.name == null ? "????" : (sys.FileSystem.exists(ide.getPath(t.name)) ? "" : "[NOT FOUND]") + t.name;
+		root.val(path);
+		root.attr("title", t == null ? "" : t.name);
+		return value = t;
+	}
+
+	public dynamic function onChange() {
+	}
+
+}

+ 4 - 9
hide/comp/Toolbar.hx

@@ -13,27 +13,22 @@ typedef ToolSelect<T> = {
 
 
 class Toolbar extends Component {
 class Toolbar extends Component {
 
 
-	public var bar : Element;
-	public var content : Element;
-
 	public function new(root) {
 	public function new(root) {
 		super(root);
 		super(root);
-		var e = new Element('<div class="hide-toolbar"><div class="toolbar"/><div class="content"/>').appendTo(root);
-		bar = e.find('.toolbar');
-		content = e.find(".content");
+		root.addClass("hide-toolbar");
 	}
 	}
 
 
 	public function addButton( icon : String, ?label : String, ?onClick : Void -> Void ) {
 	public function addButton( icon : String, ?label : String, ?onClick : Void -> Void ) {
 		var e = new Element('<div class="button" title="${label==null ? "" : label}"><div class="icon fa fa-$icon"/></div>');
 		var e = new Element('<div class="button" title="${label==null ? "" : label}"><div class="icon fa fa-$icon"/></div>');
 		if( onClick != null ) e.click(function(_) onClick());
 		if( onClick != null ) e.click(function(_) onClick());
-		e.appendTo(bar);
+		e.appendTo(root);
 		return e;
 		return e;
 	}
 	}
 
 
 	public function addToggle( icon : String, ?label : String, ?onToggle : Bool -> Void ) : ToolToggle {
 	public function addToggle( icon : String, ?label : String, ?onToggle : Bool -> Void ) : ToolToggle {
 		var e = new Element('<div class="toggle" title="${label==null ? "" : label}"><div class="icon fa fa-$icon"/></div>');
 		var e = new Element('<div class="toggle" title="${label==null ? "" : label}"><div class="icon fa fa-$icon"/></div>');
 		e.click(function(_) { e.toggleClass("toggled"); if( onToggle != null ) onToggle(e.hasClass("toggled")); });
 		e.click(function(_) { e.toggleClass("toggled"); if( onToggle != null ) onToggle(e.hasClass("toggled")); });
-		e.appendTo(bar);
+		e.appendTo(root);
 		return { element : e, toggle : function(b) e.toggleClass("toggled",b) };
 		return { element : e, toggle : function(b) e.toggleClass("toggled",b) };
 	}
 	}
 
 
@@ -52,7 +47,7 @@ class Toolbar extends Component {
 			onSelect : function(_) {},
 			onSelect : function(_) {},
 		};
 		};
 		select.change(function(_) tool.onSelect(content[Std.parseInt(select.val())].value));
 		select.change(function(_) tool.onSelect(content[Std.parseInt(select.val())].value));
-		e.appendTo(bar);
+		e.appendTo(root);
 		return tool;
 		return tool;
 	}
 	}
 
 

+ 25 - 4
hide/ui/Ide.hx

@@ -50,6 +50,9 @@ class Ide {
 					return;
 					return;
 			window.close(true);
 			window.close(true);
 		});
 		});
+
+		var body = window.window.document.body;
+		body.onfocus = function(_) haxe.Timer.delay(function() new Element(body).find("input[type=file]").change().remove(), 200);
 	}
 	}
 
 
 	function onWindowChange() {
 	function onWindowChange() {
@@ -179,11 +182,29 @@ class Ide {
 		initLayout();
 		initLayout();
 	}
 	}
 
 
+	public function makeRelative( path : String ) {
+		path = path.split("\\").join("/");
+		if( StringTools.startsWith(path.toLowerCase(), resourceDir.toLowerCase()+"/") )
+			return path.substr(resourceDir.length+1);
+		return path;
+	}
+
+	public function chooseFile( exts : Array<String>, onSelect : String -> Void ) {
+		var e = new Element('<input type="file" value="" accept="${[for( e in exts ) "."+e].join(",")}"/>');
+		e.change(function(_) {
+			var file = makeRelative(e.val());
+			e.remove();
+			onSelect(file == "" ? null : file);
+		}).appendTo(window.window.document.body).click();
+	}
+
 	public function chooseDirectory( onSelect : String -> Void ) {
 	public function chooseDirectory( onSelect : String -> Void ) {
-		new Element('<input type="file" nwdirectory/>').change(function(e) {
-			var dir = js.jquery.Helper.JTHIS.val();
-			onSelect(dir);
-		}).click();
+		var e = new Element('<input type="file" value="" nwdirectory/>');
+		e.change(function(_) {
+			var dir = makeRelative(js.jquery.Helper.JTHIS.val());
+			onSelect(dir == "" ? null : dir);
+			e.remove();
+		}).appendTo(window.window.document.body).click();
 	}
 	}
 
 
 	function initMenu() {
 	function initMenu() {

+ 6 - 2
hide/view/FileTree.hx

@@ -20,6 +20,10 @@ class FileTree extends hide.ui.View<{ root : String, opened : Array<String> }> {
 		super(state);
 		super(state);
 		if( state.root == null ) {
 		if( state.root == null ) {
 			ide.chooseDirectory(function(dir) {
 			ide.chooseDirectory(function(dir) {
+				if( dir == null ) {
+					close();
+					return;
+				}
 				state.root = dir.split("\\").join("/")+"/";
 				state.root = dir.split("\\").join("/")+"/";
 				saveState();
 				saveState();
 				rebuild();
 				rebuild();
@@ -58,8 +62,8 @@ class FileTree extends hide.ui.View<{ root : String, opened : Array<String> }> {
 
 
 		if( state.opened == null ) state.opened = [];
 		if( state.opened == null ) state.opened = [];
 
 
-		var panel = new hide.comp.ScrollZone(e);
-		tree = new hide.comp.IconTree(panel.content);
+		var panel = new Element("<div class='hide-scroll'>").appendTo(e);
+		tree = new hide.comp.IconTree(panel);
 		tree.get = function(path) {
 		tree.get = function(path) {
 			if( path == null ) path = "";
 			if( path == null ) path = "";
 			var basePath = ide.getPath(state.root) + path;
 			var basePath = ide.getPath(state.root) + path;

+ 13 - 6
hide/view/Model.hx

@@ -7,13 +7,20 @@ class Model extends FileView {
 	var scene : hide.comp.Scene;
 	var scene : hide.comp.Scene;
 	var control : h3d.scene.CameraController;
 	var control : h3d.scene.CameraController;
 	var tree : hide.comp.IconTree;
 	var tree : hide.comp.IconTree;
-	var scroll : hide.comp.ScrollZone;
+	var overlay : Element;
 
 
 	override function onDisplay( e : Element ) {
 	override function onDisplay( e : Element ) {
-		tools = new hide.comp.Toolbar(e);
-		var cont = new Element('<div class="hide-scene-layer">').appendTo(tools.content);
-		scroll = new hide.comp.ScrollZone(cont);
-		scene = new hide.comp.Scene(tools.content);
+		e.html('
+			<div class="flex vertical">
+				<div class="toolbar"></div>
+				<div class="scene">
+					<div class="hide-scene-layer hide-scroll"></div>
+				</div>
+			</div>
+		');
+		tools = new hide.comp.Toolbar(e.find(".toolbar"));
+		overlay = e.find(".hide-scene-layer");
+		scene = new hide.comp.Scene(e.find(".scene"));
 		scene.onReady = init;
 		scene.onReady = init;
 	}
 	}
 
 
@@ -31,7 +38,7 @@ class Model extends FileView {
 
 
 		new h3d.scene.Object(scene.s3d).addChild(obj);
 		new h3d.scene.Object(scene.s3d).addChild(obj);
 		control = new h3d.scene.CameraController(scene.s3d);
 		control = new h3d.scene.CameraController(scene.s3d);
-		tree = new hide.comp.SceneTree(obj,scroll.content, obj.name != null);
+		tree = new hide.comp.SceneTree(obj,overlay, obj.name != null);
 		resetCamera();
 		resetCamera();
 
 
 		var anims = listAnims();
 		var anims = listAnims();

+ 7 - 4
hide/view/Particles3D.hx

@@ -43,8 +43,8 @@ class Particles3D extends FileView {
 					<div class="group" name="Display">
 					<div class="group" name="Display">
 						<dl>
 						<dl>
 							<dt>Name</dt><dd><input field="name" onchange="$(this).closest(\'.section\').find(\'>h1 span\').text($(this).val())"/></dd>
 							<dt>Name</dt><dd><input field="name" onchange="$(this).closest(\'.section\').find(\'>h1 span\').text($(this).val())"/></dd>
-							<dt>Texture</dt><dd><input type="file" accept="image/*"/></dd>
-							<dt>Color Gradient</dt><dd><input type="file" accept="image/*"/></dd>
+							<dt>Texture</dt><dd><input type="texture" field="texture"/></dd>
+							<dt>Color Gradient</dt><dd><input type="texture" field="colorGradient"/></dd>
 							<dt>Sort</dt><dd><select field="sortMode"></select></dd>
 							<dt>Sort</dt><dd><select field="sortMode"></select></dd>
 							<dt>3D&nbsp;Transform</dt><dd><input type="checkbox" field="transform3D"/></dd>
 							<dt>3D&nbsp;Transform</dt><dd><input type="checkbox" field="transform3D"/></dd>
 						</dl>
 						</dl>
@@ -100,8 +100,11 @@ class Particles3D extends FileView {
 					<div class="group" name="Animation">
 					<div class="group" name="Animation">
 						<dl>
 						<dl>
 							<dt>Animation Repeat</dt><dd><input type="range" field="animationRepeat" min="0" max="10"/></dd>
 							<dt>Animation Repeat</dt><dd><input type="range" field="animationRepeat" min="0" max="10"/></dd>
-							<dt>Frame Division</dt><dd>X <input type="number" field="frameDivisionX" min="1" max="16"/> Y <input type="number" field="frameDivisionY" min="1" max="16"/></dd>
-							<dt>Frame Count</dt><dd><input type="number" field="frameCount" min="0" max="32"/></dd>
+							<dt>Frame Division</dt><dd>
+								X <input type="number" style="width:30px" field="frameDivisionX" min="1" max="16"/>
+								Y <input type="number" style="width:30px" field="frameDivisionY" min="1" max="16"/>
+								# <input type="number" style="width:30px" field="frameCount" min="0" max="32"/>
+							</dd>
 						</dl>
 						</dl>
 					</div>
 					</div>