From 27135cd724baed3a499a7c51dc6b20d466bc846f Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Sat, 13 Apr 2024 12:52:04 +0100 Subject: [PATCH] WIP selection consistency --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 86 +++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index 0c20c6db6..a4c66a68c 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -1,5 +1,9 @@ using Eto.GtkSharp.Forms.Cells; using Eto.GtkSharp.Forms.Menu; +using Gtk; +using Grid = Eto.Forms.Grid; +using GridLines = Eto.Forms.GridLines; + namespace Eto.GtkSharp.Forms.Controls { class GridHandler @@ -89,6 +93,26 @@ protected GridHandler() // ScrolledWindow.Add(Box); } + /*protected override TreeView CreateControl() + { + var control = base.CreateControl(); + control.Selection.SelectFunction = SelectFunction; + return control; + }*/ + + + private bool SelectFunction(Gtk.TreeSelection selection, Gtk.ITreeModel model, Gtk.TreePath path, bool pathCurrentlySelected) + { + // Cancel removing last selected item + var rows = selection.GetSelectedRows().Select(r => r.Indices[0]); + if (!AllowEmptySelection && AllowMultipleSelection && pathCurrentlySelected && selection.CountSelectedRows() == 1) + { + return false; + } + + return true; + } + protected abstract ITreeModelImplementor CreateModelImplementor(); protected void UpdateModel() @@ -138,12 +162,23 @@ protected override void Initialize() columns.Register(Widget.Columns); base.Initialize(); - Widget.MouseDown += Widget_MouseDown; + //Widget.MouseDown += Widget_MouseDown; Control.QueryTooltip += Control_QueryTooltip; Control.HasTooltip = true; - + //Control.Selection.SelectFunction = SelectFunction; + Control.Selection.Changed += (sender, args) => + { + //if (!AllowEmptySelection && AllowMultipleSelection) + { + if (!AllowEmptySelection && Control.Selection.CountSelectedRows() == 0) + { + Control.GetCursor(out var cursorRow, out _); + Control.Selection.SelectPath(cursorRow); + } + } + }; } private void Control_QueryTooltip(object o, Gtk.QueryTooltipArgs args) @@ -536,17 +571,20 @@ public bool AllowMultipleSelection get { return Control.Selection.Mode == Gtk.SelectionMode.Multiple; } set { - if (value) + SetSelectionMode(AllowEmptySelection, value); + /*if (value) { Control.Selection.Mode = Gtk.SelectionMode.Multiple; } else { + // Workaround to not lose the ability to select after switching to Multi then back to Single. Control.GetCursor(out var cursorRow, out _); Control.Selection.Mode = Gtk.SelectionMode.None; Control.Selection.Mode = Gtk.SelectionMode.Single; Control.Selection.SelectPath(cursorRow); } + SetSelectionMode();*/ } } @@ -716,7 +754,47 @@ public bool IsEditing public bool AllowEmptySelection { get => Widget.Properties.Get(GridHandler.AllowEmptySelection_Key, true); - set => Widget.Properties.TrySet(GridHandler.AllowEmptySelection_Key, value, true); + set + { + Widget.Properties.TrySet(GridHandler.AllowEmptySelection_Key, value, true); + SetSelectionMode(value, AllowMultipleSelection); + } + } + + private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelection) + { + var currentMode = Control.Selection.Mode; + var newMode = + (allowEmptySelection, allowMultipleSelection) switch + { + (true, true) => SelectionMode.Multiple, + (true, false) => SelectionMode.Single, + (false, true) => SelectionMode.Multiple, // Handled by SelectFunction + (false, false) => SelectionMode.Browse + }; + + if (newMode != currentMode) + { + if (currentMode == SelectionMode.Multiple && newMode != SelectionMode.Multiple) + { + // Workaround to not lose the ability to select after switching to Multi then back to Single or Browse. + Control.Selection.Mode = Gtk.SelectionMode.None; + Control.Selection.Mode = newMode; + //if (Control.Selection.CountSelectedRows() == 0) + { + Control.GetCursor(out var cursorRow, out _); + Control.Selection.SelectPath(cursorRow); + } + } + Control.Selection.Mode = newMode; + } + if (!allowEmptySelection && Control.Selection.CountSelectedRows() == 0) + { + Control.GetCursor(out var cursorRow, out _); + Control.Selection.SelectPath(cursorRow); + } + + //EnsureSelection(); } #if !GTK2