Browse Source

refactor hide/cdb

Nicolas Cannasse 7 years ago
parent
commit
001b20ec0f
9 changed files with 394 additions and 299 deletions
  1. 2 2
      bin/cdb.css
  2. 2 2
      bin/cdb.less
  3. 0 281
      hide/comp/CdbEditor.hx
  4. 13 12
      hide/comp/cdb/Cell.hx
  5. 130 0
      hide/comp/cdb/Cursor.hx
  6. 85 0
      hide/comp/cdb/Editor.hx
  7. 19 0
      hide/comp/cdb/Line.hx
  8. 141 0
      hide/comp/cdb/Table.hx
  9. 2 2
      hide/view/CdbTable.hx

+ 2 - 2
bin/cdb.css

@@ -67,7 +67,7 @@
 }
 .cdb .cdb-sheet tr.selected,
 .cdb .cdb-sheet td.selected {
-  background-color: #EEE;
+  background-color: #353535;
 }
 .cdb .cdb-sheet td {
   user-select: none;
@@ -96,7 +96,7 @@
 }
 .cdb .cdb-sheet tr.list tr.selected,
 .cdb .cdb-sheet tr.list td.selected {
-  background-color: #DDD;
+  background-color: #353535;
 }
 .cdb .cdb-sheet tr.list > td {
   padding: 0;

+ 2 - 2
bin/cdb.less

@@ -81,7 +81,7 @@
 		}
 
 		tr.selected, td.selected {
-			background-color : #EEE;
+			background-color : #353535;
 		}
 
 		td {
@@ -113,7 +113,7 @@
 			}
 
 			tr.selected, td.selected {
-				background-color : #DDD;
+				background-color : #353535;
 			}
 
 			& > td {

+ 0 - 281
hide/comp/CdbEditor.hx

@@ -1,281 +0,0 @@
-package hide.comp;
-import js.jquery.Helper.*;
-
-private typedef Cursor = {
-	s : cdb.Sheet,
-	x : Int,
-	y : Int,
-	?select : { x : Int, y : Int },
-	?onchange : Void -> Void,
-}
-
-@:allow(hide.comp.CdbCell)
-class CdbEditor extends Component {
-
-	var base : cdb.Database;
-	var sheet : cdb.Sheet;
-	var cursor : Cursor;
-	var existsCache : Map<String,{ t : Float, r : Bool }> = new Map();
-
-	public function new(root, sheet) {
-		super(root);
-		this.sheet = sheet;
-		base = sheet.base;
-		cursor = {
-			s : null,
-			x : 0,
-			y : 0,
-		};
-		refresh();
-	}
-
-	function refresh() {
-
-		root.html('');
-		root.addClass('cdb');
-
-		if( sheet.columns.length == 0 ) {
-			J("<a>Add a column</a>").appendTo(root).click(function(_) {
-				newColumn(sheet);
-			});
-			return;
-		}
-
-		var content = J("<table>");
-		content.addClass("cdb-sheet");
-		fillTable(content, sheet);
-		content.appendTo(root);
-	}
-
-	function fillTable( content : Element, sheet : cdb.Sheet ) {
-
-		content.attr("sheet", sheet.getPath());
-
-		var cols = J("<tr>").addClass("head");
-		J("<th>").addClass("start").appendTo(cols);
-		var lines = [for( i in 0...sheet.lines.length ) {
-			var l = J("<tr>");
-			l.data("index", i);
-			var head = J("<td>").addClass("start").text("" + i);
-			l.mousedown(function(e) {
-				if( e.which == 3 ) {
-					head.click();
-					//haxe.Timer.delay(popupLine.bind(sheet,i),1);
-					e.preventDefault();
-					return;
-				}
-			}).click(function(e) {
-				if( e.shiftKey && cursor.s == sheet && cursor.x < 0 ) {
-					cursor.select = { x : -1, y : i };
-					updateCursor();
-				} else
-					setCursor(sheet, -1, i);
-			});
-			head.appendTo(l);
-			l;
-		}];
-
-
-		var colCount = sheet.columns.length;
-		var todo = [];
-		var inTodo = false;
-		for( cindex in 0...sheet.columns.length ) {
-			var c = sheet.columns[cindex];
-			var col = J("<th>");
-			col.text(c.name);
-			col.addClass( "t_"+c.type.getName().substr(1).toLowerCase() );
-			if( sheet.props.displayColumn == c.name )
-				col.addClass("display");
-			col.mousedown(function(e) {
-				if( e.which == 3 ) {
-					//haxe.Timer.delay(popupColumn.bind(sheet,c),1);
-					e.preventDefault();
-					return;
-				}
-			});
-			col.dblclick(function(_) {
-				newColumn(sheet, c);
-			});
-			cols.append(col);
-
-			for( index in 0...sheet.lines.length ) {
-				var v = J("<td>").addClass("c");
-				var l = lines[index];
-				v.appendTo(l);
-				var cell = new CdbCell(v, this, c, sheet.lines[index]);
-				switch( c.type ) {
-				case TList:
-					var key = sheet.getPath() + "@" + c.name + ":" + index;
-					cell.root.click(function(e) {
-						e.stopPropagation();
-						toggleList(cell);
-					});
-				default:
-				}
-			}
-		}
-
-		if( sheet.lines.length == 0 ) {
-			var l = J('<tr><td colspan="${sheet.columns.length + 1}"><a href="javascript:_.insertLine()">Insert Line</a></td></tr>');
-			l.find("a").click(function(_) setCursor(sheet));
-			lines.push(l);
-		}
-
-		content.empty();
-		content.append(cols);
-
-		var snext = 0;
-		for( i in 0...lines.length ) {
-			while( sheet.separators[snext] == i ) {
-				var sep = J("<tr>").addClass("separator").append('<td colspan="${colCount+1}">').appendTo(content);
-				var content = sep.find("td");
-				var title = if( sheet.props.separatorTitles != null ) sheet.props.separatorTitles[snext] else null;
-				if( title != null ) content.text(title);
-				var pos = snext;
-				sep.dblclick(function(e) {
-					content.empty();
-					J("<input>").appendTo(content).focus().val(title == null ? "" : title).blur(function(_) {
-						/*title = JTHIS.val();
-						JTHIS.remove();
-						content.text(title);
-						var titles = sheet.props.separatorTitles;
-						if( titles == null ) titles = [];
-						while( titles.length < pos )
-							titles.push(null);
-						titles[pos] = title == "" ? null : title;
-						while( titles[titles.length - 1] == null && titles.length > 0 )
-							titles.pop();
-						if( titles.length == 0 ) titles = null;
-						sheet.props.separatorTitles = titles;
-						save();*/
-					}).keypress(function(e) {
-						e.stopPropagation();
-					}).keydown(function(e) {
-						if( e.keyCode == 13 ) { JTHIS.blur(); e.preventDefault(); } else if( e.keyCode == 27 ) content.text(title);
-						e.stopPropagation();
-					});
-				});
-				snext++;
-			}
-			content.append(lines[i]);
-		}
-
-		inTodo = true;
-		for( t in todo ) t();
-		inTodo = false;
-	}
-
-	function toggleList( cell : CdbCell ) {
-	}
-
-	function quickExists(path) {
-		var c = existsCache.get(path);
-		if( c == null ) {
-			c = { t : -1e9, r : false };
-			existsCache.set(path, c);
-		}
-		var t = haxe.Timer.stamp();
-		if( c.t < t - 10 ) { // cache result for 10s
-			c.r = sys.FileSystem.exists(path);
-			c.t = t;
-		}
-		return c.r;
-	}
-
-	function setCursor( ?s, ?x=0, ?y=0, ?sel, update = true ) {
-		cursor.s = s;
-		cursor.x = x;
-		cursor.y = y;
-		cursor.select = sel;
-		var ch = cursor.onchange;
-		if( ch != null ) {
-			cursor.onchange = null;
-			ch();
-		}
-		if( update ) updateCursor();
-	}
-
-	function getLine( sheet : cdb.Sheet, index : Int ) {
-		return J("table[sheet='"+sheet.getPath()+"'] > tbody > tr").not(".head,.separator,.list").eq(index);
-	}
-
-	function updateCursor() {
-		J(".selected").removeClass("selected");
-		J(".cursor").removeClass("cursor");
-		J(".cursorLine").removeClass("cursorLine");
-		if( cursor.s == null )
-			return;
-		if( cursor.y < 0 ) {
-			cursor.y = 0;
-			cursor.select = null;
-		}
-		if( cursor.y >= cursor.s.lines.length ) {
-			cursor.y = cursor.s.lines.length - 1;
-			cursor.select = null;
-		}
-		var max = cursor.s.props.isProps ? 1 : cursor.s.columns.length;
-		if( cursor.x >= max ) {
-			cursor.x = max - 1;
-			cursor.select = null;
-		}
-		var l = getLine(cursor.s, cursor.y);
-		if( cursor.x < 0 ) {
-			l.addClass("selected");
-			if( cursor.select != null ) {
-				var y = cursor.y;
-				while( cursor.select.y != y ) {
-					if( cursor.select.y > y ) y++ else y--;
-					getLine(cursor.s, y).addClass("selected");
-				}
-			}
-		} else {
-			l.find("td.c").eq(cursor.x).addClass("cursor").closest("tr").addClass("cursorLine");
-			if( cursor.select != null ) {
-				var s = getSelection();
-				for( y in s.y1...s.y2 + 1 )
-					getLine(cursor.s, y).find("td.c").slice(s.x1, s.x2+1).addClass("selected");
-			}
-		}
-		var e = l[0];
-		if( e != null ) untyped e.scrollIntoViewIfNeeded();
-	}
-
-	function getSelection() {
-		if( cursor.s == null )
-			return null;
-		var x1 = if( cursor.x < 0 ) 0 else cursor.x;
-		var x2 = if( cursor.x < 0 ) cursor.s.columns.length-1 else if( cursor.select != null ) cursor.select.x else x1;
-		var y1 = cursor.y;
-		var y2 = if( cursor.select != null ) cursor.select.y else y1;
-		if( x2 < x1 ) {
-			var tmp = x2;
-			x2 = x1;
-			x1 = tmp;
-		}
-		if( y2 < y1 ) {
-			var tmp = y2;
-			y2 = y1;
-			y1 = tmp;
-		}
-		return { x1 : x1, x2 : x2, y1 : y1, y2 : y2 };
-	}
-
-	function updateClasses(v:Element, c:cdb.Data.Column, val:Dynamic) {
-		switch( c.type ) {
-		case TBool :
-			v.removeClass("true, false").addClass( val==true ? "true" : "false" );
-		case TInt, TFloat :
-			v.removeClass("zero");
-			if( val==0 )
-				v.addClass("zero");
-		default:
-		}
-	}
-
-	function newColumn( sheet : cdb.Sheet, ?after ) {
-	}
-
-	public dynamic function save() {
-	}
-
-}

+ 13 - 12
hide/comp/CdbCell.hx → hide/comp/cdb/Cell.hx

@@ -1,22 +1,23 @@
-package hide.comp;
+package hide.comp.cdb;
 
-class CdbCell extends Component {
+class Cell extends Component {
 
 	static var UID = 0;
 	static var typeNames = [for( t in Type.getEnumConstructs(cdb.Data.ColumnType) ) t.substr(1).toLowerCase()];
 
-	var editor : CdbEditor;
+	var editor : Editor;
+	var line : Line;
 	var col : cdb.Data.Column;
-	var obj : Dynamic;
 	var currentValue : Dynamic;
 	public var value(get, set) : Dynamic;
 
-	public function new( root : Element, editor : CdbEditor, col : cdb.Data.Column, obj : Dynamic ) {
+	public function new( root : Element, line : Line, col : cdb.Data.Column ) {
 		super(root);
-		this.editor = editor;
+		this.line = line;
+		this.editor = line.table.editor;
 		this.col = col;
-		this.obj = obj;
-		currentValue = Reflect.field(obj, col.name);
+		@:privateAccess line.cells.push(this);
+		currentValue = Reflect.field(line.obj, col.name);
 		root.addClass("t_" + typeNames[col.type.getIndex()]);
 		refresh();
 	}
@@ -24,11 +25,11 @@ class CdbCell extends Component {
 	function set_value( v : Dynamic ) {
 		var old = currentValue;
 		currentValue = v;
-		if( obj == null && v != currentValue ) {
+		if( v != currentValue ) {
 			if( v == null )
-				Reflect.deleteField(obj, col.name);
+				Reflect.deleteField(line.obj, col.name);
 			else
-				Reflect.setField(obj, col.name, v);
+				Reflect.setField(line.obj, col.name, v);
 			// TODO : history
 		}
 		refresh();
@@ -38,7 +39,7 @@ class CdbCell extends Component {
 	inline function get_value() return currentValue;
 
 	function refresh() {
-		var html = valueHtml(col, value, editor.sheet, obj);
+		var html = valueHtml(col, value, editor.sheet, line.obj);
 		if( html == "&nbsp;" ) root.text(" ") else if( html.indexOf('<') < 0 && html.indexOf('&') < 0 ) root.text(html) else root.html(html);
 		updateClasses();
 	}

+ 130 - 0
hide/comp/cdb/Cursor.hx

@@ -0,0 +1,130 @@
+package hide.comp.cdb;
+
+class Cursor {
+
+	var editor : Editor;
+	public var sheet : cdb.Sheet;
+	public var x : Int;
+	public var y : Int;
+	public var select : Null<{ x : Int, y : Int }>;
+	public var onchange : Void -> Void;
+
+	public function new(editor) {
+		this.editor = editor;
+	}
+
+	public function set( ?s, ?x=0, ?y=0, ?sel, update = true ) {
+		this.sheet = s;
+		this.x = x;
+		this.y = y;
+		this.select = sel;
+		var ch = onchange;
+		if( ch != null ) {
+			onchange = null;
+			ch();
+		}
+		if( update ) this.update();
+	}
+
+	public function getLine() {
+		if( sheet == null ) return null;
+		return editor.getLine(sheet, y);
+	}
+
+	public function move( dx : Int, dy : Int, shift : Bool, ctrl : Bool ) {
+		if( sheet == null )
+			return;
+		if( x == -1 && ctrl ) {
+			if( dy != 0 )
+				editor.moveLine(getLine(), dy);
+			update();
+			return;
+		}
+		if( dx < 0 && x >= 0 )
+			x--;
+		if( dy < 0 && y > 0 )
+			y--;
+		if( dx > 0 && x < sheet.columns.length - 1 )
+			x++;
+		if( dy > 0 && y < sheet.lines.length - 1 )
+			y++;
+		select = null;
+		update();
+	}
+
+	public function update() {
+		var root = editor.root;
+		root.find(".selected").removeClass("selected");
+		root.find(".cursor").removeClass("cursor");
+		root.find(".cursorLine").removeClass("cursorLine");
+		if( sheet == null )
+			return;
+		if( y < 0 ) {
+			y = 0;
+			select = null;
+		}
+		if( y >= sheet.lines.length ) {
+			y = sheet.lines.length - 1;
+			select = null;
+		}
+		var max = sheet.props.isProps ? 1 : sheet.columns.length;
+		if( x >= max ) {
+			x = max - 1;
+			select = null;
+		}
+		var line = getLine();
+		if( x < 0 ) {
+			line.root.addClass("selected");
+			if( select != null ) {
+				var cy = y;
+				while( select.y != cy ) {
+					if( select.y > cy ) cy++ else cy--;
+					editor.getLine(sheet, cy).root.addClass("selected");
+				}
+			}
+		} else {
+			line.cells[x].root.addClass("cursor").closest("tr").addClass("cursorLine");
+			if( select != null ) {
+				var s = getSelection();
+				for( y in s.y1...s.y2 + 1 ) {
+					var l = editor.getLine(sheet, y);
+					for( x in s.x1...s.x2+1)
+						l.cells[x].root.addClass("selected");
+				}
+			}
+		}
+		var e = line.root[0];
+		if( e != null ) untyped e.scrollIntoViewIfNeeded();
+	}
+
+	function getSelection() {
+		if( sheet == null )
+			return null;
+		var x1 = if( x < 0 ) 0 else x;
+		var x2 = if( x < 0 ) sheet.columns.length-1 else if( select != null ) select.x else x1;
+		var y1 = y;
+		var y2 = if( select != null ) select.y else y1;
+		if( x2 < x1 ) {
+			var tmp = x2;
+			x2 = x1;
+			x1 = tmp;
+		}
+		if( y2 < y1 ) {
+			var tmp = y2;
+			y2 = y1;
+			y1 = tmp;
+		}
+		return { x1 : x1, x2 : x2, y1 : y1, y2 : y2 };
+	}
+
+
+	public function clickLine( line : Line, shiftKey = false ) {
+		var sheet = line.table.sheet;
+		if( shiftKey && this.sheet == sheet && x < 0 ) {
+			select = { x : -1, y : line.index };
+			update();
+		} else
+			set(sheet, -1, line.index);
+	}
+
+}

+ 85 - 0
hide/comp/cdb/Editor.hx

@@ -0,0 +1,85 @@
+package hide.comp.cdb;
+
+@:allow(hide.comp.cdb)
+class Editor extends Component {
+
+	var base : cdb.Database;
+	var sheet : cdb.Sheet;
+	var existsCache : Map<String,{ t : Float, r : Bool }> = new Map();
+	var tables : Array<Table> = [];
+	public var cursor : Cursor;
+
+	public function new(root, sheet) {
+		super(root);
+		this.sheet = sheet;
+		base = sheet.base;
+		cursor = new Cursor(this);
+		refresh();
+	}
+
+	function refresh() {
+
+		root.html('');
+		root.addClass('cdb');
+
+		if( sheet.columns.length == 0 ) {
+			new Element("<a>Add a column</a>").appendTo(root).click(function(_) {
+				newColumn(sheet);
+			});
+			return;
+		}
+
+		var content = new Element("<table>");
+		tables = [];
+		new Table(this, sheet, content);
+		content.appendTo(root);
+	}
+
+	function quickExists(path) {
+		var c = existsCache.get(path);
+		if( c == null ) {
+			c = { t : -1e9, r : false };
+			existsCache.set(path, c);
+		}
+		var t = haxe.Timer.stamp();
+		if( c.t < t - 10 ) { // cache result for 10s
+			c.r = sys.FileSystem.exists(path);
+			c.t = t;
+		}
+		return c.r;
+	}
+
+	function getLine( sheet : cdb.Sheet, index : Int ) {
+		for( t in tables )
+			if( t.sheet == sheet )
+				return t.lines[index];
+		return null;
+	}
+
+	public function newColumn( sheet : cdb.Sheet, ?after ) {
+	}
+
+	public function insertLine( table : Table, index = 0 ) {
+	}
+
+	function moveLine( line : Line, delta : Int ) {
+		/*
+		// remove opened list
+		getLine(sheet, index).next("tr.list").change();
+		var index = sheet.moveLine(index, delta);
+		if( index != null ) {
+			setCursor(sheet, -1, index, false);
+			refresh();
+			save();
+		}
+		*/
+	}
+
+	public function popupLine( line : Line ) {
+	}
+
+	public dynamic function save() {
+	}
+
+}
+

+ 19 - 0
hide/comp/cdb/Line.hx

@@ -0,0 +1,19 @@
+package hide.comp.cdb;
+
+class Line extends Component {
+
+	public var index : Int;
+	public var table : Table;
+	public var obj(get, never) : Dynamic;
+	public var cells : Array<Cell>;
+
+	public function new(table, index, root) {
+		super(root);
+		this.table = table;
+		this.index = index;
+		cells = [];
+	}
+
+	inline function get_obj() return table.sheet.lines[index];
+
+}

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

@@ -0,0 +1,141 @@
+package hide.comp.cdb;
+import js.jquery.Helper.*;
+
+class Table extends Component {
+
+	public var editor : Editor;
+	public var sheet : cdb.Sheet;
+	public var lines : Array<Line>;
+
+	public function new(editor, sheet, root) {
+		super(root);
+		this.editor = editor;
+		this.sheet = sheet;
+		@:privateAccess editor.tables.push(this);
+		root.addClass("cdb-sheet");
+		refresh();
+	}
+
+	public function dispose() {
+		@:privateAccess editor.tables.remove(this);
+	}
+
+	public function refresh() {
+
+		var cols = J("<tr>").addClass("head");
+		J("<th>").addClass("start").appendTo(cols);
+		lines = [for( index in 0...sheet.lines.length ) {
+			var l = J("<tr>");
+			var head = J("<td>").addClass("start").text("" + index);
+			head.appendTo(l);
+			var line = new Line(this, index, l);
+			l.mousedown(function(e) {
+				if( e.which == 3 ) {
+					head.click();
+					editor.popupLine(line);
+					e.preventDefault();
+					return;
+				}
+			}).click(function(e) {
+				editor.cursor.clickLine(line, e.shiftKey);
+			});
+			line;
+		}];
+
+
+		var colCount = sheet.columns.length;
+		var todo = [];
+		var inTodo = false;
+		for( cindex in 0...sheet.columns.length ) {
+			var c = sheet.columns[cindex];
+			var col = J("<th>");
+			col.text(c.name);
+			col.addClass( "t_"+c.type.getName().substr(1).toLowerCase() );
+			if( sheet.props.displayColumn == c.name )
+				col.addClass("display");
+			col.mousedown(function(e) {
+				if( e.which == 3 ) {
+					//haxe.Timer.delay(popupColumn.bind(sheet,c),1);
+					e.preventDefault();
+					return;
+				}
+			});
+			col.dblclick(function(_) {
+				editor.newColumn(sheet, c);
+			});
+			cols.append(col);
+
+			for( index in 0...sheet.lines.length ) {
+				var v = J("<td>").addClass("c");
+				var line = lines[index];
+				v.appendTo(line.root);
+				var cell = new Cell(v, line, c);
+				switch( c.type ) {
+				case TList:
+					var key = sheet.getPath() + "@" + c.name + ":" + index;
+					cell.root.click(function(e) {
+						e.stopPropagation();
+						toggleList(cell);
+					});
+				default:
+				}
+			}
+		}
+
+		root.empty();
+		root.append(cols);
+
+		var snext = 0;
+		for( i in 0...lines.length ) {
+			while( sheet.separators[snext] == i ) {
+				var sep = J("<tr>").addClass("separator").append('<td colspan="${colCount+1}">').appendTo(root);
+				var content = sep.find("td");
+				var title = if( sheet.props.separatorTitles != null ) sheet.props.separatorTitles[snext] else null;
+				if( title != null ) content.text(title);
+				var pos = snext;
+				sep.dblclick(function(e) {
+					content.empty();
+					J("<input>").appendTo(content).focus().val(title == null ? "" : title).blur(function(_) {
+						/*title = JTHIS.val();
+						JTHIS.remove();
+						content.text(title);
+						var titles = sheet.props.separatorTitles;
+						if( titles == null ) titles = [];
+						while( titles.length < pos )
+							titles.push(null);
+						titles[pos] = title == "" ? null : title;
+						while( titles[titles.length - 1] == null && titles.length > 0 )
+							titles.pop();
+						if( titles.length == 0 ) titles = null;
+						sheet.props.separatorTitles = titles;
+						save();*/
+					}).keypress(function(e) {
+						e.stopPropagation();
+					}).keydown(function(e) {
+						if( e.keyCode == 13 ) { JTHIS.blur(); e.preventDefault(); } else if( e.keyCode == 27 ) content.text(title);
+						e.stopPropagation();
+					});
+				});
+				snext++;
+			}
+			root.append(lines[i].root);
+		}
+
+		if( sheet.lines.length == 0 ) {
+			var l = J('<tr><td colspan="${sheet.columns.length + 1}"><a href="javascript:_.insertLine()">Insert Line</a></td></tr>');
+			l.find("a").click(function(_) {
+				editor.insertLine(this);
+				editor.cursor.set(sheet);
+			});
+			root.append(l);
+		}
+
+		inTodo = true;
+		for( t in todo ) t();
+		inTodo = false;
+	}
+
+	function toggleList( cell : Cell ) {
+	}
+
+}

+ 2 - 2
hide/view/CdbTable.hx

@@ -3,7 +3,7 @@ package hide.view;
 class CdbTable extends hide.ui.View<{ path : String }> {
 
 	var sheet : cdb.Sheet;
-	var editor : hide.comp.CdbEditor;
+	var editor : hide.comp.cdb.Editor;
 
 	public function new(state) {
 		super(state);
@@ -20,7 +20,7 @@ class CdbTable extends hide.ui.View<{ path : String }> {
 			return;
 		}
 		root.addClass("hide-scroll");
-		editor = new hide.comp.CdbEditor(root, sheet);
+		editor = new hide.comp.cdb.Editor(root, sheet);
 	}
 
 	override function getTitle() {