瀏覽代碼

CDB: Fix go forward / backward

lviguier 6 月之前
父節點
當前提交
94f28bbb41
共有 3 個文件被更改,包括 114 次插入171 次删除
  1. 88 27
      hide/comp/cdb/Cursor.hx
  2. 25 117
      hide/comp/cdb/Editor.hx
  3. 1 27
      hide/view/CdbTable.hx

+ 88 - 27
hide/comp/cdb/Cursor.hx

@@ -22,13 +22,21 @@ class Cursor {
 	public var y : Int;
 	public var selection : Array<Selection>;
 
+	// Jump to last / next cursor position with alt keys
+	public var stateIdx : Int = -1;
+	public var states : Array<CursorState> = [];
+
 	public function new(editor) {
 		this.editor = editor;
 		set();
 	}
 
 
-	public function set( ?t : Table, ?x : Int = 0, ?y : Int = 0, ?sel : Array<Selection>, update : Bool = true, scrollIntoView : Bool = false ) {
+	public function setDefault(table : Table, x : Int, y : Int) {
+		set(table == null ? editor.tables[0] : table, x, y, null, true, true, true);
+	}
+
+	public function set( ?t : Table, ?x : Int = 0, ?y : Int = 0, ?sel : Array<Selection>, update : Bool = true, scrollIntoView : Bool = false, saveCursorState : Bool = false ) {
 		if( t != null ) {
 			for( t2 in editor.tables ) {
 				if( t.sheet.getPath() == t2.sheet.getPath() ) {
@@ -56,23 +64,12 @@ class Cursor {
 
 		if( update ) this.update();
 
-		var line = getLine();
-		if (scrollIntoView && line != null) {
-			var e = line.element.get(0);
-			if( e != null ) untyped e.scrollIntoViewIfNeeded();
-		}
-
-		// Manage scroll if cursor is outside of the view
-		var c = getCell();
-		var l = getLine();
-		if (c != null)
-			untyped c.elementHtml.scrollIntoViewIfNeeded();
-		else if (l != null)
-			untyped l.element.get(0).scrollIntoViewIfNeeded();
-	}
+		// Save state allowing jump to with alt keys
+		if (saveCursorState)
+			saveState();
 
-	public function setDefault(line, column) {
-		set(editor.tables[0], column, line);
+		if (scrollIntoView)
+			this.scrollIntoView();
 	}
 
 	public function move( dx : Int, dy : Int, shift : Bool, ctrl : Bool, alt : Bool, ?overflow : Bool = false ) {
@@ -176,17 +173,56 @@ class Cursor {
 		else
 			addElementToSelection(line.table, line, x, y);
 
-		// Manage scroll if cursor is outside of the view
-		var c = getCell();
-		var l = getLine();
-		if (c != null)
-			untyped c.elementHtml.scrollIntoViewIfNeeded();
-		else if (l != null)
-			untyped l.element.get(0).scrollIntoViewIfNeeded();
-
+		this.scrollIntoView();
 		update();
 	}
 
+	public function jump(backward : Bool = true) {
+		stateIdx = Std.int(hxd.Math.clamp(backward ? stateIdx - 1 : stateIdx + 1, 0, states.length - 1));
+		var state = states[stateIdx];
+
+		// Open root sheet
+		var rootSheet = state.sheet.split('@')[0];
+		if (editor.currentSheet.name != rootSheet) {
+			editor.syncSheet(null, rootSheet);
+			 editor.refresh();
+		}
+
+		var curTable = editor.tables[0];
+		function getTable(path : String) : Table {
+			var targetCol = path.split('@')[0].split(':')[0];
+			var targetLineIdx = Std.parseInt(path.split('@')[0].split(':')[1]);
+			for (cIdx => c in curTable.columns) {
+				if (c.name == targetCol) {
+					var cell = curTable.lines[targetLineIdx].cells[ curTable.displayMode == Properties || curTable.displayMode == AllProperties ? 0 : cIdx];
+					if( cell.line.subTable == null && (cell.column.type == TList || cell.column.type == TProperties) )
+						cell.open(true);
+
+					curTable = cell.line.subTable;
+					var newPath = path.split('@');
+					newPath.shift();
+
+					if (newPath.length <= 0)
+						return cell.line.subTable;
+					return getTable(newPath.join("@"));
+				}
+			}
+
+			return null;
+		}
+
+		var newPath = state.sheet.split('@');
+		newPath.shift();
+		var t = newPath.length > 0 ? getTable(newPath.join("@")) : null;
+		if (t == null) {
+			for (table in editor.tables)
+				if (table.sheet.name == rootSheet)
+					t = table;
+		}
+		set(t, state.x, state.y, null, true, true, false);
+	}
+
+
 	public function update() {
 		hide();
 
@@ -254,6 +290,22 @@ class Cursor {
 		};
 	}
 
+	public function saveState() {
+		var state = getState();
+		if (state == null)
+			return;
+
+		if (states.length > 0) {
+			var prevState = states[states.length - 1];
+
+			if (state.sheet == prevState.sheet && state.x == prevState.x && state.y == prevState.y)
+				return;
+		}
+
+		stateIdx++;
+		states[stateIdx] = state;
+	}
+
 
 	public function save() {
 		if( table == null ) return null;
@@ -383,18 +435,27 @@ class Cursor {
 		return line.cells[x];
 	}
 
+	public function scrollIntoView() {
+		var c = getCell();
+		var l = getLine();
+		if (c != null)
+			untyped c.elementHtml.scrollIntoViewIfNeeded();
+		else if (l != null)
+			untyped l.element.get(0).scrollIntoViewIfNeeded();
+	}
+
 
 	public function clickLine( line : Line, shiftKey = false, ctrlKey = false ) {
 		this.table = line.table;
 		addElementToSelection(line.table, line, -1, line.index, shiftKey, ctrlKey);
-		set(line.table, -1, line.index, this.selection);
+		set(line.table, -1, line.index, this.selection, true, false, true);
 	}
 
 	public function clickCell( cell : Cell, shiftKey = false, ctrlKey = false ) {
 		this.table = cell.table;
 		var xIndex = cell.table.displayMode == Table ? cell.columnIndex : 0;
 		addElementToSelection(cell.table, cell.line, xIndex, cell.line.index, shiftKey, ctrlKey);
-		set(cell.table, xIndex, cell.line.index, this.selection);
+		set(cell.table, xIndex, cell.line.index, this.selection, true, false, true);
 	}
 
 	public function addElementToSelection(table: Table, line: Line, xIndex : Int, yIndex: Int, shift: Bool = false, ctrl: Bool = false) {

+ 25 - 117
hide/comp/cdb/Editor.hx

@@ -76,8 +76,6 @@ class Editor extends Component {
 	public var cursor : Cursor;
 	public var keys : hide.ui.Keys;
 	public var undo : hide.ui.UndoHistory;
-	public var cursorStates : Array<UndoState> = [];
-	public var cursorIndex : Int = 0;
 	public var formulas : Formulas;
 	public var showGUIDs = false;
 
@@ -136,8 +134,8 @@ class Editor extends Component {
 		keys.register("cdb.showReferences", () -> showReferences());
 		keys.register("undo", function() undo.undo());
 		keys.register("redo", function() undo.redo());
-		keys.register("cdb.moveBack", () -> cursorJump(true));
-		keys.register("cdb.moveAhead", () -> cursorJump(false));
+		keys.register("cdb.moveBack", () -> cursor.jump(true));
+		keys.register("cdb.moveAhead", () -> cursor.jump(false));
 		keys.register("cdb.insertLine", function() { insertLine(cursor.table,cursor.y); cursor.move(0,1,false,false,false); });
 		keys.register("duplicate", function() { duplicateLine(cursor.table,cursor.y); cursor.move(0,1,false,false,false); });
 		for( k in ["cdb.editCell","rename"] )
@@ -165,8 +163,8 @@ class Editor extends Component {
 		base = sheet.base;
 		if( cursor == null )
 			cursor = new Cursor(this);
-		else if ( !tables.contains(cursor.table) )
-			cursor.set();
+		// else if ( !tables.contains(cursor.table) ) //TODO(lv): needed ?
+		// 	cursor.set();
 		if( displayMode == null ) displayMode = Table;
 		DataFiles.load();
 		if( currentValue == null ) currentValue = api.copy();
@@ -176,10 +174,10 @@ class Editor extends Component {
 	function onMouseDown( e : hide.Element.Event ) {
 		switch ( e.which ) {
 		case 4:
-			cursorJump(true);
+			cursor.jump(true);
 			return false;
 		case 5:
-			cursorJump(false);
+			cursor.jump(false);
 			return false;
 		}
 		return true;
@@ -189,9 +187,17 @@ class Editor extends Component {
 		var isRepeat: Bool = untyped e.originalEvent.repeat;
 		switch( e.keyCode ) {
 		case K.LEFT:
+			if (e.altKey) {
+				cursor.jump(true);
+				return true;
+			}
 			cursor.move( -1, 0, e.shiftKey, e.ctrlKey, e.altKey);
 			return true;
 		case K.RIGHT:
+			if (e.altKey) {
+				cursor.jump(false);
+				return true;
+			}
 			cursor.move( 1, 0, e.shiftKey, e.ctrlKey, e.altKey);
 			return true;
 		case K.UP:
@@ -220,14 +226,13 @@ class Editor extends Component {
 				idx--;
 			}
 
-			cursor.set(cursor.table, cursor.x, idx);
+			cursor.setDefault(cursor.table, cursor.x, idx);
 			lines.get(idx).scrollIntoView({ block: js.html.ScrollLogicalPosition.END });
 
 			// Handle sticky elements
 			scrollView.scrollTop(scrollView.scrollTop() + scrollView.parent().siblings(".tabs-header").outerHeight());
 
 			return true;
-
 		case K.PGDOWN:
 			var scrollView = element.parent(".hide-scroll");
 			var height = scrollView.outerHeight() - (scrollView.find("thead").outerHeight() + scrollView.parent().siblings(".tabs-header").outerHeight());
@@ -243,7 +248,7 @@ class Editor extends Component {
 			if (idx > lines.length - 1)
 				idx = lines.length - 1;
 			lines.get(idx).scrollIntoView(true);
-			cursor.set(cursor.table, cursor.x, idx);
+			cursor.setDefault(cursor.table, cursor.x, idx);
 
 			// Handle sticky elements
 			var sepHeight = scrollView.find(".separator").height();
@@ -255,15 +260,9 @@ class Editor extends Component {
 		case K.SPACE:
 			e.preventDefault(); // prevent scroll
 		case K.ESCAPE:
-			if (!isRepeat) {
-				if( filters.length > 0 ) {
-					searchFilter([]);
-				}
-
-				if (searchBox != null && searchBox.is(":visible")) {
-					searchBox.hide();
-					refresh();
-				}
+			if (!isRepeat && searchBox != null && searchBox.is(":visible")) {
+				searchBox.find(".close-search").click();
+				return true;
 			}
 		}
 		return false;
@@ -854,7 +853,7 @@ class Editor extends Component {
 				y--;
 			}
 
-			cursor.set(cursor.table, -1, y1, null, true);
+			cursor.set(cursor.table, -1, y1, null, true, true, false);
 		}
 		else {
 			// delete cells
@@ -989,7 +988,6 @@ class Editor extends Component {
 				currentValue = newValue;
 				currentSheet = newSheet;
 			}
-			pushCursorState();
 			api.load(currentValue);
 			DataFiles.save(true); // save reloaded data
 			element.removeClass("is-cdb-editor");
@@ -1043,97 +1041,6 @@ class Editor extends Component {
 		}
 	}
 
-
-	function undoStatesEqual( s1 : UndoState, s2 : UndoState, cmpCursors = true ) {
-		function cursorEqual(c1 : Cursor.CursorState, c2 : Cursor.CursorState) {
-			if( c1 == c2 )
-				return true;
-			if( c1 == null || c2 == null )
-				return false;
-			return c1.sheet == c2.sheet && c1.x == c2.x && c1.y == c2.y;
-		}
-		function undoSheetEqual(s1 : UndoSheet, s2 : UndoSheet) {
-			if( s1.parent == null && s2.parent == null )
-				return s1.sheet == s2.sheet;
-			if( s1.parent == null || s2.parent == null )
-				return false;
-			if ( s1.sheet != s2.sheet || s1.parent.column != s2.parent.column || s1.parent.line != s2.parent.line )
-				return false;
-			return undoSheetEqual(s1.parent.sheet, s2.parent.sheet);
-		}
-		if ( s1.sheet != s2.sheet )
-			return false;
-		if( s1.tables.length != s2.tables.length )
-			return false;
-		for( i in 0...s1.tables.length ) {
-			if( !undoSheetEqual(s1.tables[i], s2.tables[i]) )
-				return false;
-		}
-		if( !cmpCursors )
-			return true;
-		if( cursorEqual(s1.cursor, s2.cursor) )
-			return true;
-		if( s1.cursor == null || s2.cursor == null )
-			return false;
-		return s1.cursor.y == -1 && s2.cursor.y == -1;
-	}
-
-	public function pushCursorState() {
-		if ( cursor == null )
-			return;
-		var state = getState();
-		state.data = null;
-
-		var stateBehind = (cursorStates.length <= 0) ? null : cursorStates[cursorIndex];
-		if( stateBehind != null && undoStatesEqual(state, stateBehind) )
-			return;
-		var stateAhead = (cursorStates.length <= 0 || cursorIndex >= cursorStates.length - 1) ? null : cursorStates[cursorIndex + 1];
-		if ( stateAhead != null && undoStatesEqual(state, stateAhead) ) {
-			cursorIndex++;
-			return;
-		}
-
-		if( cursorIndex < cursorStates.length - 1 && cursorIndex >= 0 ) {
-			cursorStates.splice(cursorIndex + 1, cursorStates.length);
-		}
-
-		cursorStates.push(state);
-		if( cursorIndex < cursorStates.length - 1 )
-			cursorIndex++;
-	}
-
-	function cursorJump(back = true) {
-		focus();
-
-		if( (back && cursorIndex <= 0) || (!back && cursorIndex >= cursorStates.length - 1) )
-			return;
-		if( back && cursorIndex == cursorStates.length - 1)
-			pushCursorState();
-
-		if(back)
-			cursorIndex--;
-		else
-			cursorIndex++;
-
-		var state = cursorStates[cursorIndex];
-		syncSheet(null, state.sheet);
-
-		if( undoStatesEqual(state, getState(), false) ) {
-			setState(state, true);
-			if( cursor.table != null ) {
-				for( t in tables ) {
-					if( t.sheet.getPath() == cursor.table.sheet.getPath() )
-						cursor.table = t;
-				}
-			}
-		} else
-			refresh(state);
-
-		if( cdbTable != null )
-			@:privateAccess cdbTable.syncTabs();
-		haxe.Timer.delay(() -> cursor.update(), 1); // scroll
-	}
-
 	public static var inRefreshAll(default,null) : Bool;
 	public static function refreshAll( eraseUndo = false, loadDataFiles = true) {
 		var editors : Array<Editor> = [for( e in new Element(".is-cdb-editor").elements() ) e.data("cdb")];
@@ -1685,6 +1592,7 @@ class Editor extends Component {
 			cursor.load(c);
 			var hiddenSeps = element.find("table.cdb-sheet > tbody > tr").not(".head").filter(".separator").filter(".sep-hidden").find("a.toggle");
 			hiddenSeps.click();
+			cursor.scrollIntoView();
 		});
 
 		searchBox.find(".search-type").click(function(_) {
@@ -2078,9 +1986,9 @@ class Editor extends Component {
 				sheet.columns.remove(col);
 				sheet.columns.insert(nextIndex, col);
 				if (cursor.x == indexColumn)
-					cursor.set(cursor.table, nextIndex, cursor.y);
+					cursor.setDefault(cursor.table, nextIndex, cursor.y);
 				else if (cursor.x == nextIndex)
-					cursor.set(cursor.table, nextIndex + 1, cursor.y);
+					cursor.setDefault(cursor.table, nextIndex + 1, cursor.y);
 				endChanges();
 				refresh();
 			}},
@@ -2091,9 +1999,9 @@ class Editor extends Component {
 				sheet.columns.remove(col);
 				sheet.columns.insert(nextIndex, col);
 				if (cursor.x == indexColumn)
-					cursor.set(cursor.table, nextIndex, cursor.y);
+					cursor.setDefault(cursor.table, nextIndex, cursor.y);
 				else if (cursor.x == nextIndex)
-					cursor.set(cursor.table, nextIndex - 1, cursor.y);
+					cursor.setDefault(cursor.table, nextIndex - 1, cursor.y);
 				endChanges();
 				refresh();
 			}},

+ 1 - 27
hide/view/CdbTable.hx

@@ -111,10 +111,6 @@ class CdbTable extends hide.ui.View<{}> {
 					lineNo = -1;
 			}
 
-			if (i == path.length-1) {
-				editor.pushCursorState();
-			}
-			trace(i, colNo, lineNo);
 			if (colNo >= 0 && lineNo >= 0) {
 				editor.cursor.set(curTable, colNo, lineNo, i == path.length-1, true);
 				lastCell = editor.cursor.getCell();
@@ -139,27 +135,6 @@ class CdbTable extends hide.ui.View<{}> {
 			editor.focus();
 			editor.cursor.update();
 		}, 1);
-		/*for (i in 0...coords.length) {
-			var c = coords[i];
-			editor.cursor.set(curTable, c.column, c.line);
-			if( editor.cursor.table != null && c.line != null ) {
-				editor.cursor.table.expandLine(c.line);
-				if (i < coords.length - 1) {
-					var sub = editor.cursor.getLine().subTable;
-					var cell = editor.cursor.getCell();
-					if (sub != null && sub.cell == cell) {
-						curTable = sub;
-					}
-					else {
-						cell.open(false);
-						curTable = editor.cursor.table;
-					}
-				}
-			}
-			else
-				break;
-		}*/
-
 	}
 
 	public function goto( s : cdb.Sheet, ?line : Int, ?column : Int, ?scriptLine : Int ) {
@@ -178,7 +153,7 @@ class CdbTable extends hide.ui.View<{}> {
 		@:privateAccess editor.updateFilters();
 		if( line != null ) {
 			if( column != null )
-				editor.cursor.setDefault(line, column);
+				editor.cursor.setDefault(@:privateAccess editor.tables[0], column, line);
 			if( editor.cursor.table != null )
 				editor.cursor.table.revealLine(line);
 			if (scriptLine != null) {
@@ -221,7 +196,6 @@ class CdbTable extends hide.ui.View<{}> {
 
 	function setEditor(index:Int) {
 		var sheets = getSheets();
-		editor.pushCursorState();
 		editor.show(sheets[index],tabContents[index]);
 		currentSheet = editor.getCurrentSheet();
 		ide.currentConfig.set("cdb.currentSheet", sheets[index].name);