diff options
Diffstat (limited to 'Xwt.Gtk/Xwt.GtkBackend/TableViewBackend.cs')
-rw-r--r-- | Xwt.Gtk/Xwt.GtkBackend/TableViewBackend.cs | 82 |
1 files changed, 74 insertions, 8 deletions
diff --git a/Xwt.Gtk/Xwt.GtkBackend/TableViewBackend.cs b/Xwt.Gtk/Xwt.GtkBackend/TableViewBackend.cs index 72de4f73..3e16979e 100644 --- a/Xwt.Gtk/Xwt.GtkBackend/TableViewBackend.cs +++ b/Xwt.Gtk/Xwt.GtkBackend/TableViewBackend.cs @@ -29,6 +29,7 @@ using Xwt.Backends; using Gtk; using System.Collections.Generic; using System.Linq; +using Gdk; #if XWT_GTK3 using TreeModel = Gtk.ITreeModel; #endif @@ -238,6 +239,7 @@ namespace Xwt.GtkBackend public void SetSelectionMode (SelectionMode mode) { switch (mode) { + case SelectionMode.None: Widget.Selection.Mode = Gtk.SelectionMode.None; break; case SelectionMode.Single: Widget.Selection.Mode = Gtk.SelectionMode.Single; break; case SelectionMode.Multiple: Widget.Selection.Mode = Gtk.SelectionMode.Multiple; break; } @@ -463,19 +465,36 @@ namespace Xwt.GtkBackend { Gtk.TreeViewColumn col; Gtk.TreePath path; - int cellx, celly; + int _cellx, _celly; cx = cy = 0; it = Gtk.TreeIter.Zero; - if (!Widget.GetPathAtPos (ex, ey, out path, out col, out cellx, out celly)) + if (!Widget.GetPathAtPos (ex, ey, out path, out col, out _cellx, out _celly)) return false; - if (!Widget.Model.GetIterFromString (out it, path.ToString ())) + if (!Widget.Model.GetIter (out it, path)) return false; - int sp, w; - if (col.CellGetPosition (r, out sp, out w)) { - if (cellx >= sp && cellx < sp + w) { + var cellArea = Widget.GetCellArea (path, col); + var cellx = ex - cellArea.X; + + var renderers = col.GetCellRenderers (); + int i = Array.IndexOf (renderers, r); + + int rendererX, rendererWidth; + if (col.CellGetPosition (r, out rendererX, out rendererWidth)) { + if (i < renderers.Length - 1) { + int nextX, _w; + // The width returned by CellGetPosition is not reliable. Calculate the width + // by getting the position of the next renderer. + if (col.CellGetPosition (renderers [i + 1], out nextX, out _w)) + rendererWidth = nextX - rendererX; + } else { + // Last renderer of the column. Its width is what's left in the cell area. + rendererWidth = cellArea.Width - rendererX; + } + + if (cellx >= rendererX && cellx < rendererX + rendererWidth) { Widget.ConvertBinWindowToWidgetCoords (ex, ey, out cx, out cy); return true; } @@ -492,16 +511,26 @@ namespace Xwt.GtkBackend Widget.QueueDrawArea (x, y, r.Width, r.Height); } + public void QueueResize (object target, Gtk.TreeIter iter) + { + var path = Widget.Model.GetPath (iter); + Widget.Model.EmitRowChanged (path, iter); + } + #endregion } class CustomTreeView: Gtk.TreeView { WidgetBackend backend; - + TreePath delayedSelection; + TreeViewColumn delayedSelectionColumn; + public CustomTreeView (WidgetBackend b) { backend = b; + base.DragBegin += (_, __) => + delayedSelection = null; } static CustomTreeView () @@ -514,6 +543,44 @@ namespace Xwt.GtkBackend GtkWorkarounds.RemoveKeyBindingFromClass (Gtk.TreeView.GType, Gdk.Key.BackSpace, Gdk.ModifierType.None); } + protected override bool OnButtonPressEvent (EventButton evnt) + { + if (Selection.Mode == Gtk.SelectionMode.Multiple) { + // If we are clicking on already selected row, delay the selection until we are certain that + // the user is not starting a DragDrop operation. + // This is needed to allow user to drag multiple selected rows. + TreePath treePath; + TreeViewColumn column; + GetPathAtPos ((int)evnt.X, (int)evnt.Y, out treePath, out column); + + var ctrlShiftMask = (evnt.State & (Gdk.ModifierType.ShiftMask | Gdk.ModifierType.ControlMask | Gdk.ModifierType.Mod2Mask)); + if (treePath != null && evnt.Button == 1 && this.Selection.PathIsSelected (treePath) && this.Selection.CountSelectedRows() > 1 && ctrlShiftMask == 0) { + delayedSelection = treePath; + delayedSelectionColumn = column; + Selection.SelectFunction = (_, __, ___, ____) => false; + var result = false; + try { + result = base.OnButtonPressEvent (evnt); + } finally { + Selection.SelectFunction = (_, __, ___, ____) => true; + } + return result; + } + } + return base.OnButtonPressEvent (evnt); + } + + protected override bool OnButtonReleaseEvent (EventButton evnt) + { + // Now, if mouse hadn't moved, we are certain that this was just a click. Proceed as usual. + if (delayedSelection != null) { + SetCursor (delayedSelection, delayedSelectionColumn, false); + delayedSelection = null; + delayedSelectionColumn = null; + } + return base.OnButtonReleaseEvent (evnt); + } + protected override void OnDragDataDelete (Gdk.DragContext context) { // This method is override to avoid the default implementation @@ -523,4 +590,3 @@ namespace Xwt.GtkBackend } } } - |