Browse Source

[filebrowser] Fix fileTree not redrawing on layout changes

Clément Espeute 2 months ago
parent
commit
f1af8b8595
4 changed files with 112 additions and 0 deletions
  1. 9 0
      bin/style.css
  2. 11 0
      bin/style.less
  3. 87 0
      hide/comp/FancyGallery.hx
  4. 5 0
      hide/comp/FancyTree.hx

+ 9 - 0
bin/style.css

@@ -5366,6 +5366,15 @@ fancy-gallery fancy-scroll fancy-item-container fancy-item {
 fancy-gallery fancy-scroll fancy-item-container fancy-item:hover {
 fancy-gallery fancy-scroll fancy-item-container fancy-item:hover {
   background-color: var(--hover);
   background-color: var(--hover);
 }
 }
+fancy-gallery fancy-scroll fancy-item-container fancy-item.selected {
+  color: white;
+  background-color: var(--selection);
+}
+fancy-gallery fancy-scroll fancy-item-container fancy-item.current {
+  outline: dashed 1px #AAA;
+  z-index: 10;
+  outline-offset: -1px;
+}
 fancy-gallery fancy-scroll fancy-item-container fancy-item.details {
 fancy-gallery fancy-scroll fancy-item-container fancy-item.details {
   padding: 0;
   padding: 0;
   display: flex;
   display: flex;

+ 11 - 0
bin/style.less

@@ -6450,6 +6450,17 @@ fancy-gallery {
 					background-color: var(--hover);
 					background-color: var(--hover);
 				}
 				}
 
 
+				&.selected {
+					color: white;
+					background-color: var(--selection);
+				}
+
+				&.current {
+					outline: dashed 1px #AAA;
+					z-index: 10;
+					outline-offset: -1px;
+				}
+
 				box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.4);
 				box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.4);
 
 
 				&.details {
 				&.details {

+ 87 - 0
hide/comp/FancyGallery.hx

@@ -4,6 +4,7 @@ enum GalleryRefreshFlag {
 	Search;
 	Search;
 	Items;
 	Items;
 	RegenHeader;
 	RegenHeader;
+	FocusCurrent;
 }
 }
 
 
 typedef GalleryRefreshFlags = haxe.EnumFlags<GalleryRefreshFlag>;
 typedef GalleryRefreshFlags = haxe.EnumFlags<GalleryRefreshFlag>;
@@ -16,6 +17,7 @@ class FancyGallery<GalleryItem> extends hide.comp.Component {
 	var itemMap : Map<{}, GalleryItemData<GalleryItem>> = [];
 	var itemMap : Map<{}, GalleryItemData<GalleryItem>> = [];
 	var itemContainer : js.html.Element;
 	var itemContainer : js.html.Element;
 	var scroll : js.html.Element;
 	var scroll : js.html.Element;
+	var selection : Map<{}, Bool> = [];
 
 
 	var lastHeight : Float = 0;
 	var lastHeight : Float = 0;
 
 
@@ -27,6 +29,24 @@ class FancyGallery<GalleryItem> extends hide.comp.Component {
 
 
 	var details = false;
 	var details = false;
 
 
+	var currentItem(default, set) : GalleryItemData<GalleryItem>;
+	function set_currentItem(v) {
+		currentItem = v;
+		queueRefresh(FocusCurrent);
+		return currentItem;
+	}
+
+	var currentVisible(default, set) : Bool = false;
+
+	function set_currentVisible(v) {
+		currentVisible = v;
+		if (currentVisible)
+			queueRefresh(FocusCurrent);
+		else
+			queueRefresh();
+		return currentVisible;
+	}
+
 	public function new(parent: Element, el: Element) {
 	public function new(parent: Element, el: Element) {
 		saveDisplayKey = "fancyGallery";
 		saveDisplayKey = "fancyGallery";
 		if (el != null) {
 		if (el != null) {
@@ -73,6 +93,17 @@ class FancyGallery<GalleryItem> extends hide.comp.Component {
 			}
 			}
 		}
 		}
 
 
+		itemContainer.onblur = (e: js.html.FocusEvent) -> {
+			if (itemContainer.contains(cast e.relatedTarget)) {
+				currentVisible = false;
+				currentItem = null;
+			};
+		}
+
+		itemContainer.onclick = (e) -> {
+			currentVisible = false;
+		}
+
 		itemContainer.oncontextmenu = contextMenuHandler.bind(null);
 		itemContainer.oncontextmenu = contextMenuHandler.bind(null);
 		scroll = el.find("fancy-scroll").get(0);
 		scroll = el.find("fancy-scroll").get(0);
 
 
@@ -173,6 +204,45 @@ class FancyGallery<GalleryItem> extends hide.comp.Component {
 		queueRefresh(RegenHeader);
 		queueRefresh(RegenHeader);
 	}
 	}
 
 
+	public function clearSelection() {
+		selection.clear();
+		queueRefresh();
+	}
+
+	function setSelection(data: GalleryItemData<GalleryItem>, select: Bool) {
+		if (select) {
+			selection.set(cast data, true);
+		} else {
+			selection.remove(cast data);
+		}
+	}
+
+	function dataClickHandler(data: GalleryItemData<GalleryItem>, event: js.html.MouseEvent) : Void {
+		if (!event.ctrlKey) {
+			clearSelection();
+		}
+
+		var currentIndex = currentData.indexOf(currentItem);
+		if (event.shiftKey && currentIndex >= 0) {
+			var newIndex = currentData.indexOf(data);
+
+			var min = hxd.Math.imin(currentIndex, newIndex);
+			var max = hxd.Math.imax(currentIndex, newIndex);
+
+			for (i in min...max + 1) {
+				setSelection(currentData[i], true);
+			}
+		} else {
+			setSelection(data, !selection.exists(cast data));
+		}
+
+		if (!(event.shiftKey && !event.ctrlKey) || currentItem == null)
+			currentItem = data;
+		//onSelectionChanged();
+
+		queueRefresh();
+	}
+
 	public function rename(item: GalleryItem, onFinished : (newName:String) -> Void) {
 	public function rename(item: GalleryItem, onFinished : (newName:String) -> Void) {
 		var data = itemMap.get(cast item);
 		var data = itemMap.get(cast item);
 		var name = data.element.querySelector("fancy-name");
 		var name = data.element.querySelector("fancy-name");
@@ -231,7 +301,20 @@ class FancyGallery<GalleryItem> extends hide.comp.Component {
 		// We might need to recompute the scroll height so we call getBoundingClientRect again
 		// We might need to recompute the scroll height so we call getBoundingClientRect again
 		var scrollHeight = scroll.getBoundingClientRect().height;
 		var scrollHeight = scroll.getBoundingClientRect().height;
 
 
+		if (currentRefreshFlags.has(FocusCurrent)) {
+			var currentIndex = currentData.indexOf(currentItem);
+
+			if (currentIndex >= 0) {
+				var currentHeight = (hxd.Math.floor(currentIndex / itemsPerRow)) * (itemHeightPx + margin);
+				if (currentHeight < scroll.scrollTop) {
+					scroll.scrollTo(scroll.scrollLeft, currentHeight);
+				}
 
 
+				if (currentHeight + itemHeightPx - scrollHeight > scroll.scrollTop) {
+					scroll.scrollTo(scroll.scrollLeft, currentHeight + itemHeightPx - scrollHeight);
+				}
+			}
+		}
 
 
 		var clipStart = scroll.scrollTop;
 		var clipStart = scroll.scrollTop;
 		var clipEnd = scrollHeight + clipStart;
 		var clipEnd = scrollHeight + clipStart;
@@ -306,6 +389,8 @@ class FancyGallery<GalleryItem> extends hide.comp.Component {
 				onDoubleClick(data.item);
 				onDoubleClick(data.item);
 			}
 			}
 
 
+			data.element.onclick = dataClickHandler.bind(data);
+
 			data.element.oncontextmenu = contextMenuHandler.bind(data.item);
 			data.element.oncontextmenu = contextMenuHandler.bind(data.item);
 
 
 			setupDragAndDrop(data);
 			setupDragAndDrop(data);
@@ -320,6 +405,8 @@ class FancyGallery<GalleryItem> extends hide.comp.Component {
 
 
 		data.element.style.height = '${itemHeightPx}px';
 		data.element.style.height = '${itemHeightPx}px';
 		data.element.classList.toggle("details", details);
 		data.element.classList.toggle("details", details);
+		data.element.classList.toggle("selected", selection.exists(cast data));
+		data.element.classList.toggle("current", currentVisible && currentItem == data);
 
 
 		var name = data.element.querySelector("fancy-name");
 		var name = data.element.querySelector("fancy-name");
 		if (name.title != data.name) {
 		if (name.title != data.name) {

+ 5 - 0
hide/comp/FancyTree.hx

@@ -119,6 +119,11 @@ class FancyTree<TreeItem> extends hide.comp.Component {
 			currentVisible = false;
 			currentVisible = false;
 		}
 		}
 
 
+		var resizeObserver = new hide.comp.ResizeObserver((_, _) -> {
+			queueRefresh();
+		});
+		resizeObserver.observe(element.get(0));
+
  	}
  	}
 
 
 	/**
 	/**