Browse Source

Merge branch 'master' of https://github.com/HeapsIO/hide

clementlandrin 3 years ago
parent
commit
1fcd3f45ea
7 changed files with 193 additions and 95 deletions
  1. 6 0
      bin/style.css
  2. 8 1
      bin/style.less
  3. 126 82
      hide/comp/TileSelector.hx
  4. 39 7
      hide/comp/cdb/Cell.hx
  5. 7 5
      hide/comp/cdb/Editor.hx
  6. 2 0
      hide/comp/cdb/Table.hx
  7. 5 0
      hide/ui/Keys.hx

+ 6 - 0
bin/style.css

@@ -332,6 +332,10 @@ input[type=checkbox]:checked:after {
   text-align: left;
   overflow: hidden;
 }
+.hide-tileselect .dim-edit {
+  margin-left: 2px;
+  margin-right: 2px;
+}
 .hide-tileselect .flex-scroll {
   height: 600px;
   width: 800px;
@@ -345,6 +349,8 @@ input[type=checkbox]:checked:after {
 .hide-tileselect .flex-scroll .scroll .tile {
   background-color: #202;
   position: relative;
+  margin-right: 1px;
+  margin-bottom: 1px;
 }
 .hide-tileselect .flex-scroll .scroll .tile .valueDisp {
   position: absolute;

+ 8 - 1
bin/style.less

@@ -364,12 +364,17 @@ input[type=checkbox] {
 	}
 }
 
+@tileselect-cursor-border: 1px;
 .hide-tileselect {
 	display: inline-block;
 	background-color : #111;
 	border : 1px solid #666;
 	text-align: left;
 	overflow: hidden;
+	.dim-edit {
+		margin-left: 2px;
+		margin-right: 2px;
+	}
 	.flex-scroll {
 		height: 600px;
 		width: 800px;
@@ -381,6 +386,8 @@ input[type=checkbox] {
 			.tile {
 				background-color: #202;
 				position: relative;
+				margin-right: @tileselect-cursor-border;
+				margin-bottom: @tileselect-cursor-border;
 				.valueDisp {
 					position: absolute;
 					background-color: rgba(0,80,128,0.3);
@@ -389,7 +396,7 @@ input[type=checkbox] {
 				}
 				.cursor {
 					position: absolute;
-					border : 1px solid #fff;
+					border : @tileselect-cursor-border solid #fff;
 					pointer-events:none;
 				}
 			}

+ 126 - 82
hide/comp/TileSelector.hx

@@ -3,27 +3,30 @@ package hide.comp;
 class TileSelector extends Component {
 
 	public var file(default,set) : String;
-	public var size(default,set) : Int;
+	public var size(default,set) : {width: Int, height: Int};
 	public var value(default,set) : Null<{ x : Int, y : Int, width : Int, height : Int }>;
+
 	public var allowRectSelect(default,set) : Bool;
 	public var allowSizeSelect(default,set) : Bool;
 	public var allowFileChange(default,set) : Bool;
 
-    var valueDisp : Element;
-    var cursor : Element;
-    var image : Element;
-	var movePos = { x : 0, y : 0, moving : false, moved : false };
-    var cursorPos : { x : Int, y : Int, x2 : Int, y2 : Int, select : Bool };
-    var width : Int;
-    var height : Int;
+	var cursorPos : { x : Int, y : Int, x2 : Int, y2 : Int, dragSelect : Bool };
+	var movePos = { x : 0, y : 0, dragScrolling : false };
+	var valueDisp : Element;
+	var cursor : Element;
+	var image : Element;
+	var imageWidth : Int;
+	var imageHeight : Int;
 	var zoom : Float;
 	var imageElt : js.html.ImageElement;
+	var modal : Element;
 
 	public function new(file,size,?parent,?el) {
 		super(parent,el);
 		element.addClass("hide-tileselect");
 		this.file = file;
 		this.size = size;
+		this.modal = parent.parent();
 	}
 
 	function set_file(file) {
@@ -34,8 +37,8 @@ class TileSelector extends Component {
 
 	function set_value(v) {
 		value = v;
-        if( cursorPos != null ) updateCursor();
-        return v;
+		if( cursorPos != null ) updateCursor();
+		return v;
 	}
 
 	function set_size(size) {
@@ -62,24 +65,34 @@ class TileSelector extends Component {
 		return b;
 	}
 
-    function updateCursor() {
-        var k = size * zoom;
-        var width = hxd.Math.abs(cursorPos.x2 - cursorPos.x) + 1;
-        var height = hxd.Math.abs(cursorPos.y2 - cursorPos.y) + 1;
-        cursor.css({left: hxd.Math.min(cursorPos.x,cursorPos.x2)*k,top:hxd.Math.min(cursorPos.y,cursorPos.y2)*k,width:width*k,height:height*k});
-        cursor.toggle(cursorPos.x >= 0);
-        if( value != null ) {
-            valueDisp.show();
-            valueDisp.css({left:value.x*k,top:value.y*k,width:value.width*k,height:value.height*k});
-        } else
-            valueDisp.hide();
-    }
-
-    function rescale() {
-        image.height(height*zoom).width(width*zoom);
-        image.css("background-size",(width*zoom)+"px "+(height*zoom)+"px");
-        updateCursor();
-    }
+	function updateCursor() {
+		var k = { w: size.width * zoom, h: size.height * zoom };
+		var width = hxd.Math.abs(cursorPos.x2 - cursorPos.x) + 1;
+		var height = hxd.Math.abs(cursorPos.y2 - cursorPos.y) + 1;
+		cursor.css({
+			left: hxd.Math.min(cursorPos.x,cursorPos.x2)*k.w,
+			top:hxd.Math.min(cursorPos.y,cursorPos.y2)*k.h,
+			width:width*k.w - 1,
+			height:height*k.h - 1,
+		});
+		cursor.toggle(cursorPos.x >= 0);
+		if( value != null ) {
+			valueDisp.show();
+			valueDisp.css({
+				left:value.x*k.w,
+				top:value.y*k.h,
+				width:value.width*k.w - 1,
+				height:value.height*k.h - 1,
+			});
+		} else
+			valueDisp.hide();
+	}
+
+	function rescale() {
+		image.height(imageHeight*zoom).width(imageWidth*zoom);
+		image.css("background-size",(imageWidth*zoom)+"px "+(imageHeight*zoom)+"px");
+		updateCursor();
+	}
 
 	function rebuild() {
 
@@ -101,14 +114,24 @@ class TileSelector extends Component {
 			tex.onChange = function() this.file = tex.path;
 		}
 		if( allowSizeSelect ) {
-			var size = new Element('<span><input type="number" value="$size">px</span>').appendTo(tool.element);
-			size.find("input").on("blur",function(e:js.jquery.Event) {
-                var nsize = Std.parseInt(e.getThis().val());
-                if( this.size != nsize && nsize != null && nsize > 0 )
-				    this.size = nsize;
+			var widthEdit = new Element('<span class="dim-edit">Width:<input type="number" value="${size.width}">px</span>').appendTo(tool.element);
+			widthEdit.find("input").on("blur",function(e:js.jquery.Event) {
+				var nsize = Std.parseInt(e.getThis().val());
+				if( this.size.width != nsize && nsize != null && nsize > 0 )
+					this.size.width = nsize;
 			}).on("keydown", function(e:js.jquery.Event) {
-				if( e.keyCode == 13 ) size.find("input").blur();
+				if( e.keyCode == 13 ) widthEdit.find("input").blur();
 			});
+			var heightEdit = new Element('<span class="dim-edit">Height:<input type="number" value="${size.height}">px</span>').appendTo(tool.element);
+			heightEdit.find("input").on("blur",function(e:js.jquery.Event) {
+				var nsize = Std.parseInt(e.getThis().val());
+				if( this.size.height != nsize && nsize != null && nsize > 0 )
+					this.size.height = nsize;
+			}).on("keydown", function(e:js.jquery.Event) {
+				if( e.keyCode == 13 ) heightEdit.find("input").blur();
+			});
+			widthEdit.find("input").on("blur", updateCursor);
+			heightEdit.find("input").on("blur", updateCursor);
 		}
 		if( tool.element.children().length == 0 )
 			tool.remove();
@@ -117,18 +140,19 @@ class TileSelector extends Component {
 		var scroll = new Element("<div class='flex-scroll'><div class='scroll'>").appendTo(element).find(".scroll");
 		image = new Element('<div class="tile" style="background-image:url(\'$url\')"></div>').appendTo(scroll);
 
-        valueDisp = new Element('<div class="valueDisp">').appendTo(image);
+		valueDisp = new Element('<div class="valueDisp">').appendTo(image);
 		cursor = new Element('<div class="cursor">').appendTo(image);
-        cursorPos = { x : -1, y : -1, x2 : -1, y2 : -1, select : false };
+		cursorPos = { x : -1, y : -1, x2 : -1, y2 : -1, dragSelect : false };
 		var i = js.Browser.document.createImageElement();
 		this.imageElt = i;
 
 		i.onload = function(_) {
 			if( imageElt != i ) return;
-            width = i.width;
-            height = i.height;
-			zoom = Math.floor(hxd.Math.min(800 / width, 580 / height));
+			imageWidth = i.width;
+			imageHeight = i.height;
+			zoom = Math.floor(hxd.Math.min(800 / imageWidth, 580 / imageHeight));
 			if( zoom <= 0 ) zoom = 1;
+
 			scroll.on("mousewheel", function(e:js.jquery.Event) {
 				if( untyped e.originalEvent.wheelDelta > 0 )
 					zoom++;
@@ -137,30 +161,36 @@ class TileSelector extends Component {
 				rescale();
 				e.preventDefault();
 			});
+
 			scroll.parent().on("mousedown", function(e) {
-				if( e.button == 0 ) {
-					movePos.moving = true;
-					movePos.x = e.offsetX;
-					movePos.y = e.offsetY;
+				if( e.button == 2 ) {
+					movePos.dragScrolling = true;
+					movePos.x = e.pageX;
+					movePos.y = e.pageY;
 				}
 			});
-			scroll.parent().on("mousemove", function(e) {
-				if( movePos.moving ) {
-					var dx = e.offsetX - movePos.x;
-					var dy = e.offsetY - movePos.y;
+
+			modal.on("mousemove", function(e) {
+				if( movePos.dragScrolling ) {
+					var dx = e.pageX - movePos.x;
+					var dy = e.pageY - movePos.y;
+
 					scroll[0].scrollBy(-dx,-dy);
-					movePos.moved = true;
+					movePos.x = e.pageX;
+					movePos.y = e.pageY;
 				}
 			});
+
 			image.on("mousemove", function(e:js.jquery.Event) {
-				if( movePos.moving )
+				if( movePos.dragScrolling )
 					return;
-				var k = zoom * size;
-				var x = Math.floor(e.offsetX / k);
-				var y = Math.floor(e.offsetY / k);
-				if( (x+1) * size > i.width ) x--;
-				if( (y+1) * size > i.height ) y--;
-				if( cursorPos.select ) {
+				var k = { w: size.width * zoom, h: size.height * zoom };
+				var x = Math.floor(e.offsetX / k.w);
+				var y = Math.floor(e.offsetY / k.h);
+				if( (x+1) * size.width > i.width ) x--;
+				if( (y+1) * size.height > i.height ) y--;
+
+				if( cursorPos.dragSelect ) {
 					cursorPos.x2 = x;
 					cursorPos.y2 = y;
 				} else {
@@ -169,36 +199,50 @@ class TileSelector extends Component {
 				}
 				updateCursor();
 			});
-            image.on("mousedown", function(e:js.jquery.Event) {
-				if( e.button == 2 && allowRectSelect )
-					cursorPos.select = true;
-            });
-            image.on("mouseup", function(e:js.jquery.Event) {
+			image.on("mousedown", function(e:js.jquery.Event) {
+				if( movePos.dragScrolling )
+					return;
+				var k = { w: size.width * zoom, h: size.height * zoom };
+				var x = Math.floor(e.offsetX / k.w);
+				var y = Math.floor(e.offsetY / k.h);
+				if( (x+1) * size.width > i.width ) x--;
+				if( (y+1) * size.height > i.height ) y--;
+				cursorPos.x = cursorPos.x2 = x;
+				cursorPos.y = cursorPos.y2 = y;
+
+				if( e.button == 0 && allowRectSelect )
+					cursorPos.dragSelect = true;
+			});
+			modal.on("mouseup", function(e) {
+				movePos.dragScrolling = false;
+				cursorPos.dragSelect = false;
+			});
+			image.on("mouseup", function(e:js.jquery.Event) {
 				e.preventDefault();
-				var moved = movePos.moved;
-				movePos.moved = false;
-				movePos.moving = false;
-                cursorPos.select = false;
-				if( e.button == 0 && moved )
+				movePos.dragScrolling = false;
+				cursorPos.dragSelect = false;
+				if( e.button != 0 )
 					return;
-                if( cursorPos.x2 >= cursorPos.x ) {
-                    value.x = cursorPos.x;
-                    value.width = cursorPos.x2 - cursorPos.x + 1;
-                } else {
-                    value.x = cursorPos.x2;
-                    value.width = cursorPos.x - cursorPos.x2 + 1;
-                }
-                if( cursorPos.y2 >= cursorPos.y ) {
-                    value.y = cursorPos.y;
-                    value.height = cursorPos.y2 - cursorPos.y + 1;
-                } else {
-                    value.y = cursorPos.y2;
-                    value.height = cursorPos.y - cursorPos.y2 + 1;
-                }
-                onChange(false);
-            });
-			image.on("contextmenu", function(e) {
+				if( cursorPos.x2 >= cursorPos.x ) {
+					value.x = cursorPos.x;
+					value.width = cursorPos.x2 - cursorPos.x + 1;
+				} else {
+					value.x = cursorPos.x2;
+					value.width = cursorPos.x - cursorPos.x2 + 1;
+				}
+				if( cursorPos.y2 >= cursorPos.y ) {
+					value.y = cursorPos.y;
+					value.height = cursorPos.y2 - cursorPos.y + 1;
+				} else {
+					value.y = cursorPos.y2;
+					value.height = cursorPos.y - cursorPos.y2 + 1;
+				}
+				onChange(false);
+				e.stopPropagation();
+			});
+			modal.on("contextmenu", function(e) {
 				e.preventDefault();
+				e.stopPropagation();
 			});
 			rescale();
 		};

+ 39 - 7
hide/comp/cdb/Cell.hx

@@ -155,6 +155,9 @@ class Cell extends Component {
 
 	public function refresh(withSubtable = false) {
 		currentValue = Reflect.field(line.obj, column.name);
+
+		blurOff = true;
+
 		var html = valueHtml(column, value, line.table.getRealSheet(), line.obj, []);
 		if( !R_HTML.match(html) )
 			element[0].textContent = html;
@@ -162,6 +165,8 @@ class Cell extends Component {
 			element.html(html);
 		else
 			element[0].innerHTML = html;
+		blurOff = false;
+
 		updateClasses();
 		var subTable = line.subTable;
 		if( withSubtable && subTable != null && subTable.cell == this) {
@@ -170,7 +175,6 @@ class Cell extends Component {
 			else
 				table.refreshList(this);
 		}
-		blurOff = false;
 	}
 
 	function watchFile( file : String ) {
@@ -579,7 +583,6 @@ class Cell extends Component {
 			i.keydown(function(e) {
 				switch( e.keyCode ) {
 				case K.ESCAPE:
-					blurOff = true;
 					refresh();
 					table.editor.element.focus();
 				case K.ENTER if( !e.shiftKey || !column.type.match(TString|TDynamic|TCustom(_)) ):
@@ -759,10 +762,30 @@ class Cell extends Component {
 			var modal = new hide.comp.Modal(element);
 			modal.modalClick = function(_) closeEdit();
 
+			function getDims(t : cdb.Types.TilePos) {
+				if (t == null)
+					return {width: 16, height: 16};
+				if (t.size == 1) {
+					return {
+						width: (t.width != null && t.width > 0) ? t.width : t.size,
+						height: (t.height != null && t.height > 0) ? t.height : t.size,
+					};
+				}
+				return {width: t.size, height: t.size};
+			}
+
 			var t : cdb.Types.TilePos = currentValue;
 			var file = t == null ? null : t.file;
-			var size = t == null ? 16 : t.size;
-			var pos = t == null ? { x : 0, y : 0, width : 1, height : 1 } : { x : t.x, y : t.y, width : t.width == null ? 1 : t.width, height : t.height == null ? 1 : t.height };
+			var dims = getDims(t);
+			var pos = { x : 0, y : 0, width : 1, height : 1 };
+			if (t != null) {
+				pos = {
+					x : Math.floor(t.x / ((t.size != 1) ? 1 : t.width)),
+					y : Math.floor(t.y / ((t.size != 1) ? 1 : t.height)),
+					width : (t.width == null || t.size == 1) ? 1 : t.width,
+					height : (t.height == null || t.size == 1) ? 1 : t.height,
+				};
+			}
 			if( file == null ) {
 				var y = line.index - 1;
 				while( y >= 0 ) {
@@ -770,16 +793,25 @@ class Cell extends Component {
 					var v2 = Reflect.field(o.obj, column.name);
 					if( v2 != null ) {
 						file = v2.file;
-						size = v2.size;
+						dims = getDims(v2);
 						break;
 					}
 				}
 			}
 
 			function setVal() {
+				var size = dims.width;
 				var v : Dynamic = { file : file, size : size, x : pos.x, y : pos.y };
 				if( pos.width != 1 ) v.width = pos.width;
 				if( pos.height != 1 ) v.height = pos.height;
+
+				if( dims.height != dims.width ) {
+					v.size = 1;
+					v.x = pos.x * dims.width;
+					v.y = pos.y * dims.height;
+					v.width = pos.width * dims.width;
+					v.height = pos.height * dims.height;
+				}
 				setRawValue(v);
 			}
 
@@ -797,7 +829,7 @@ class Cell extends Component {
 				return;
 			}
 
-			var ts = new hide.comp.TileSelector(file,size,modal.content);
+			var ts = new hide.comp.TileSelector(file,dims,modal.content);
 			ts.allowRectSelect = true;
 			ts.allowSizeSelect = true;
 			ts.allowFileChange = true;
@@ -805,7 +837,7 @@ class Cell extends Component {
 			ts.onChange = function(cancel) {
 				if( !cancel ) {
 					file = ts.file;
-					size = ts.size;
+					dims = ts.size;
 					pos = ts.value;
 					setVal();
 				}

+ 7 - 5
hide/comp/cdb/Editor.hx

@@ -95,14 +95,16 @@ class Editor extends Component {
 		});
 		element.contextmenu(function(e) e.preventDefault());
 
-		if( cdbTable == null )
+		if( cdbTable == null ) {
 			element.mousedown(onMouseDown);
-		else {
+			keys = new hide.ui.Keys(element);
+		} else {
 			cdbTable.element.off("mousedown", onMouseDown);
 			cdbTable.element.mousedown(onMouseDown);
+			keys = cdbTable.keys;
 		}
 
-		keys = new hide.ui.Keys(element);
+		keys.clear();
 		keys.addListener(onKey);
 		keys.register("search", function() {
 			searchBox.show();
@@ -188,8 +190,8 @@ class Editor extends Component {
 		case K.ESCAPE:
 			if( currentFilter != null ) {
 				searchFilter(null);
-				searchBox.hide();
 			}
+			searchBox.hide();
 		}
 		return false;
 	}
@@ -539,7 +541,7 @@ class Editor extends Component {
 			function openRec(s:UndoSheet) : Table {
 				if( s.parent != null ) {
 					var t = openRec(s.parent.sheet);
-					if( t != null ) {
+					if( t != null && s.parent.line < t.lines.length ) {
 						var cell = t.lines[s.parent.line].cells[t.displayMode == Properties || t.displayMode == AllProperties ? 0 : s.parent.column];
 						if( cell.line.subTable == null && (cell.column.type == TList || cell.column.type == TProperties) )
 							cell.open(true);

+ 2 - 0
hide/comp/cdb/Table.hx

@@ -229,6 +229,8 @@ class Table extends Component {
 		var content = sep.find("span");
 		var toggle = sep.find("a");
 		var title = if( sheet.props.separatorTitles != null ) sheet.props.separatorTitles[sindex] else null;
+		if( title != null )
+			sep.addClass('separator-$title');
 
 		function getLines() {
 			var snext = 0, sref = -1;

+ 5 - 0
hide/ui/Keys.hx

@@ -21,6 +21,11 @@ class Keys {
 		}
 	}
 
+	public function clear() {
+		listeners = [];
+		keys = [];
+	}
+
 	public function addListener( l ) {
 		listeners.push(l);
 	}