Pārlūkot izejas kodu

cdb: cleanup undo/redo, fixed tabs sync

Nicolas Cannasse 5 gadi atpakaļ
vecāks
revīzija
92cf5cbaa6

+ 0 - 1
bin/app.html

@@ -66,7 +66,6 @@
 	</menu>
 	<menu label="Database" class="database">
 		<menu label="View" class="dbview"></menu>
-		<menu label="New Sheet" class="dbnew"></menu>
 		<menu label="Export Localized Texts" class="dbexport"></menu>
 		<separator></separator>
 		<menu label="Enable Compression" class="dbcompress" type="checkbox"></menu>

+ 2 - 19
hide/Ide.hx

@@ -17,7 +17,6 @@ class Ide {
 	public var isFocused(get, never) : Bool;
 
 	public var database : cdb.Database;
-	public var databaseApi : hide.comp.cdb.Editor.EditorApi;
 	public var shaderLoader : hide.tools.ShaderLoader;
 	public var fileWatcher : hide.tools.FileWatcher;
 	public var typesCache : hide.tools.TypesCache;
@@ -502,20 +501,9 @@ class Ide {
 
 		databaseFile = config.project.get("cdb.databaseFile");
 		loadDatabase();
-		databaseApi = {
-			copy : () -> (database.save() : Any),
-			load : (v:Any) -> database.load((v:String)),
-			save : saveDatabase,
-			undo : new hide.ui.UndoHistory(),
-			undoState : [], // common
-		};
-		databaseApi.editor = new hide.comp.cdb.AllEditors();
 		fileWatcher.register(databaseFile,function() {
 			loadDatabase(true);
-			databaseApi.editor.refresh();
-			// reset undo (prevent undoing external changes)
-			databaseApi.undo.clear();
-			databaseApi.undoState = [];
+			hide.comp.cdb.Editor.refreshAll(true);
 		});
 
 		if( config.project.get("debug.displayErrors")  ) {
@@ -662,7 +650,7 @@ class Ide {
 			return null;
 		}
 		saveDatabase();
-		databaseApi.editor.refresh();
+		hide.comp.cdb.Editor.refreshAll();
 		return s;
 	}
 
@@ -860,11 +848,6 @@ class Ide {
 		db.find(".dbview").click(function(_) {
 			open("hide.view.CdbTable",{});
 		});
-		db.find(".dbnew").click(function(_) {
-			var sheet = createDBSheet();
-			if( sheet == null ) return;
-			open("hide.view.CdbTable",{});
-		});
 		db.find(".dbcompress").prop("checked",database.compress).click(function(_) {
 			database.compress = !database.compress;
 			saveDatabase();

+ 0 - 23
hide/comp/cdb/AllEditors.hx

@@ -1,23 +0,0 @@
-package hide.comp.cdb;
-
-class AllEditors extends Editor {
-
-	public function new() {
-		super(null,null,hide.Ide.inst.databaseApi);
-	}
-
-	override function init() {
-	}
-
-	function getEditors() : Array<Editor> {
-		return [for( e in new Element(".is-cdb-editor").elements() ) e.data("cdb")];
-	}
-
-	override function refresh( ?state : Editor.UndoState ) {
-		for( e in getEditors() ) {
-			e.syncSheet();
-			e.refresh(state);
-		}
-	}
-
-}

+ 1 - 1
hide/comp/cdb/Cell.hx

@@ -551,7 +551,7 @@ class Cell extends Component {
 			}
 			setValue(newValue);
 			editor.endChanges();
-			editor.refreshAll();
+			Editor.refreshAll();
 			focus();
 			/*
 			// creates or remove a #DUP : need to refresh the whole table

+ 62 - 49
hide/comp/cdb/Editor.hx

@@ -8,6 +8,7 @@ typedef UndoSheet = {
 
 typedef UndoState = {
 	var data : Any;
+	var sheet : String;
 	var cursor : { sheet : String, x : Int, y : Int, select : Null<{ x : Int, y : Int }> };
 	var tables : Array<UndoSheet>;
 }
@@ -16,17 +17,12 @@ typedef EditorApi = {
 	function load( data : Any ) : Void;
 	function copy() : Any;
 	function save() : Void;
-	var ?currentValue : Any;
-	var ?undo : hide.ui.UndoHistory;
-	var ?undoState : Array<UndoState>;
-	var ?editor : Editor;
 }
 
 @:allow(hide.comp.cdb)
 class Editor extends Component {
 
 	var base : cdb.Database;
-	var sheetName : String;
 	var sheet : cdb.Sheet;
 	var existsCache : Map<String,{ t : Float, r : Bool }> = new Map();
 	var tables : Array<Table> = [];
@@ -40,26 +36,31 @@ class Editor extends Component {
 	var changesDepth : Int = 0;
 	var currentFilter : String;
 	var api : EditorApi;
+	var undoState : Array<UndoState> = [];
+	var currentValue : Any;
 	public var config : hide.Config;
 	public var cursor : Cursor;
 	public var keys : hide.ui.Keys;
 	public var undo : hide.ui.UndoHistory;
 
-	public function new(sheet,config,api,?parent) {
-		super(parent,null);
+	public function new(config,api) {
+		super(null,null);
 		this.api = api;
 		this.config = config;
-		this.sheet = sheet;
-		sheetName = sheet == null ? null : sheet.name;
-		if( api.undoState == null ) api.undoState = [];
-		if( api.editor == null ) api.editor = this;
-		if( api.currentValue == null ) api.currentValue = api.copy();
-		this.undo = api.undo == null ? new hide.ui.UndoHistory() : api.undo;
-		api.undo = undo;
-		init();
+		currentValue = api.copy();
+		undo = new hide.ui.UndoHistory();
 	}
 
-	function init() {
+	public function getCurrentSheet() {
+		return sheet == null ? null : sheet.name;
+	}
+
+	public function show( sheet, ?parent : Element ) {
+		if( element != null ) element.remove();
+		element = new Element('<div>');
+		if( parent != null )
+			parent.append(element);
+		this.sheet = sheet;
 		element.attr("tabindex", 0);
 		element.addClass("is-cdb-editor");
 		element.data("cdb", this);
@@ -318,13 +319,14 @@ class Editor extends Component {
 	**/
 	public function beginChanges() {
 		if( changesDepth == 0 )
-			api.undoState.unshift(getState());
+			undoState.unshift(getState());
 		changesDepth++;
 	}
 
 	function getState() : UndoState {
 		return {
-			data : api.currentValue,
+			data : currentValue,
+			sheet : getCurrentSheet(),
 			cursor : cursor.table == null ? null : {
 				sheet : cursor.table.sheet.name,
 				x : cursor.x,
@@ -387,34 +389,48 @@ class Editor extends Component {
 	**/
 	public function endChanges() {
 		changesDepth--;
-		if( changesDepth == 0 ) {
-			var f = makeCustom(api);
-			if( f != null ) undo.change(Custom(f));
-		}
-	}
+		if( changesDepth != 0 ) return;
 
-	// do not reference "this" editor in undo state !
-	static function makeCustom( api : EditorApi ) {
 		var newValue = api.copy();
-		if( newValue == api.currentValue )
-			return null;
-		var state = api.undoState[0];
-		api.currentValue = newValue;
+		if( newValue == currentValue )
+			return;
+		var state = undoState[0];
+		var newSheet = getCurrentSheet();
+		currentValue = newValue;
 		api.save();
-		return function(undo) api.editor.handleUndo(state, newValue, undo);
-	}
-
-	function handleUndo( state : UndoState, newValue : Any, undo : Bool ) {
-		if( undo ) {
-			api.undoState.shift();
-			api.currentValue = state.data;
-		} else {
-			api.undoState.unshift(state);
-			api.currentValue = newValue;
+		undo.change(Custom(function(undo) {
+			var currentSheet;
+			if( undo ) {
+				undoState.shift();
+				currentValue = state.data;
+				currentSheet = state.sheet;
+			} else {
+				undoState.unshift(state);
+				currentValue = newValue;
+				currentSheet = newSheet;
+			}
+			api.load(currentValue);
+			element.removeClass("is-cdb-editor");
+			refreshAll();
+			element.addClass("is-cdb-editor");
+			syncSheet(currentSheet);
+			refresh(state);
+			api.save();
+		}));
+	}
+
+	public static function refreshAll( eraseUndo = false ) {
+		var editors : Array<Editor> = [for( e in new Element(".is-cdb-editor").elements() ) e.data("cdb")];
+		for( e in editors ) {
+			e.syncSheet(Ide.inst.database);
+			e.refresh();
+			// prevent undo over input changes
+			if( eraseUndo ) {
+				e.currentValue = e.api.copy();
+				e.undo.clear();
+				e.undoState = [];
+			}
 		}
-		api.load(api.currentValue);
-		refreshAll(state);
-		api.save();
 	}
 
 	function showReferences() {
@@ -441,22 +457,19 @@ class Editor extends Component {
 		ide.open("hide.view.CdbTable", { path : s.name }, function(view) @:privateAccess Std.downcast(view,hide.view.CdbTable).editor.cursor.setDefault(line,column));
 	}
 
-	public function syncSheet( ?base ) {
+	public function syncSheet( ?base, ?name ) {
 		if( base == null ) base = this.base;
 		this.base = base;
-
+		if( name == null ) name = getCurrentSheet();
 		// swap sheet if it was modified
+		this.sheet = null;
 		for( s in base.sheets )
-			if( s.name == sheetName ) {
+			if( s.name == name ) {
 				this.sheet = s;
 				break;
 			}
 	}
 
-	final function refreshAll( ?state : UndoState ) {
-		api.editor.refresh(state);
-	}
-
 	public function refresh( ?state : UndoState ) {
 
 		if( state == null )

+ 2 - 1
hide/comp/cdb/ObjEditor.hx

@@ -20,7 +20,8 @@ class ObjEditor extends Editor {
             copy : function() return (haxe.Json.stringify(obj) : Any),
             save : function() {},
         };
-        super(pseudoSheet, props, api, parent);
+		super(props, api);
+		show(pseudoSheet, parent);
     }
 
 	override function changeObject(line:Line, column:cdb.Data.Column, value:Dynamic) {

+ 57 - 50
hide/view/CdbTable.hx

@@ -1,72 +1,71 @@
 package hide.view;
 
-class CdbTable extends hide.ui.View<{ path : String }> {
+class CdbTable extends hide.ui.View<{}> {
 
-	var sheets : Array<cdb.Sheet>;
 	var tabContents : Array<Element>;
 	var editor : hide.comp.cdb.Editor;
-	var currentSheet : Int = 0;
+	var currentSheet : String;
+	var tabCache : String;
 
 	public function new( ?state ) {
 		super(state);
-		syncSheets();
-		var name = this.config.get("cdb.currentSheet");
-		if( name != null )
-			for( s in sheets )
-				if( s.name == name ) {
-					currentSheet = sheets.indexOf(s);
-					break;
-				}
+		editor = new hide.comp.cdb.Editor(config,{
+			copy : () -> (ide.database.save() : Any),
+			load : (v:Any) -> ide.database.load((v:String)),
+			save : function() {
+				ide.saveDatabase();
+				haxe.Timer.delay(syncTabs,0);
+			}
+		});
+		undo = editor.undo;
+		currentSheet = this.config.get("cdb.currentSheet");
 	}
 
-	function syncSheets() {
-		if( state.path == null )
-			sheets = [for( s in ide.database.sheets ) if( !s.props.hide ) s];
-		else {
-			for( s in ide.database.sheets )
-				if( s.name == state.path ) {
-					sheets = [s];
-					break;
-				}
+	function syncTabs() {
+		if( getTabCache() != tabCache || editor.getCurrentSheet() != currentSheet ) {
+			currentSheet = editor.getCurrentSheet();
+			rebuild();
 		}
 	}
 
+	function getSheets() {
+		return [for( s in ide.database.sheets ) if( !s.props.hide ) s];
+	}
+
+	function getTabCache() {
+		return [for( s in getSheets() ) s.name].join("|");
+	}
+
 	override function onActivate() {
 		if( editor != null ) editor.focus();
 	}
 
 	function setEditor(index:Int) {
-		syncSheets();
-		if( editor != null )
-			editor.remove();
-		editor = new hide.comp.cdb.Editor(sheets[index],config,ide.databaseApi,tabContents[index]);
+		var sheets = getSheets();
+		editor.show(sheets[index],tabContents[index]);
 		haxe.Timer.delay(function() {
 			// delay
 			editor.focus();
 			editor.onFocus = activate;
 		},0);
-		undo = ide.databaseApi.undo;
-		currentSheet = index;
+		currentSheet = editor.getCurrentSheet();
 		ide.currentConfig.set("cdb.currentSheet", sheets[index].name);
 	}
 
 	override function onDisplay() {
-		if( sheets == null ) {
-			element.text("CDB sheet not found '" + state.path + "'");
-			return;
-		}
+		var sheets = getSheets();
 		if( sheets.length == 0 ) {
 			element.html("No CDB sheet created, <a href='#'>create one</a>");
 			element.find("a").click(function(_) {
 				var sheet = ide.createDBSheet();
 				if( sheet == null ) return;
-				syncSheets();
 				rebuild();
 			});
 			return;
 		}
 		element.addClass("cdb-view");
-		var tabs = state.path != null ? null : new hide.comp.Tabs(element, true);
+		var tabs = new hide.comp.Tabs(element, true);
+		tabCache = getTabCache();
 		tabContents = [];
 		for( sheet in sheets ) {
 			var tab = tabs == null ? element : tabs.createTab(sheet.name);
@@ -76,31 +75,39 @@ class CdbTable extends hide.ui.View<{ path : String }> {
 		if( tabs != null ) {
 			tabs.onTabChange = setEditor;
 			tabs.onTabRightClick = function(index) {
-				syncSheets();
-				var sheetCount = sheets.length;
-				editor.popupSheet(sheets[index], function() {
-					syncSheets();
-					if( sheets.length > sheetCount )
-						currentSheet = index + 1;
-					else if( sheets.length < sheetCount )
-						currentSheet = index == 0 ? 0 : index - 1;
-					rebuild();
+				editor.popupSheet(getSheets()[index], function() {
+					var newSheets = getSheets();
+					var delta = newSheets.length - sheets.length;
+					var sshow = null;
+					if( delta > 0 )
+						sshow = newSheets[index+1];
+					else if( delta < 0 )
+						sshow = newSheets[index-1];
+					else
+						sshow = newSheets[index]; // rename
+					if( sshow != null )
+						currentSheet = sshow.name;
+					if( getTabCache() != tabCache )
+						rebuild();
 				});
 			};
 		}
-		if( sheets.length > 0 )
-			tabs.currentTab = tabContents[currentSheet].parent();
 
-		watch(@:privateAccess ide.databaseFile, () -> {
-			syncSheets();
-			rebuild();
-		});
+		if( sheets.length > 0 ) {
+			var idx = 0;
+			for( i in 0...sheets.length )
+				if( sheets[i].name == currentSheet ) {
+					idx = i;
+					break;
+				}
+			tabs.currentTab = tabContents[idx].parent();
+		}
+
+		watch(@:privateAccess ide.databaseFile, () -> rebuild());
 	}
 
 	override function getTitle() {
-		if( state.path == null )
-			return "CDB";
-		return state.path.charAt(0).toUpperCase() + state.path.substr(1);
+		return "CDB";
 	}
 
 	static var _ = hide.ui.View.register(CdbTable);