Skip to content

Commit

Permalink
Add CustomCell.BeginEdit/CommitEdit/CancelEdit events
Browse files Browse the repository at this point in the history
- WPF: Make Grid.BeginEdit/CommitEdit/CancelEdit work better by default with a CustomCell
  • Loading branch information
cwensley committed Jul 9, 2020
1 parent c30c6ce commit 86340a4
Show file tree
Hide file tree
Showing 12 changed files with 555 additions and 42 deletions.
36 changes: 30 additions & 6 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"clear": true
}
},
{
Expand All @@ -23,41 +26,59 @@
"type": "shell",
"problemMatcher": "$msCompile",
"group": "build",
"presentation": {
"clear": true
}
},
{
"label": "build-gtk",
"command": "dotnet build ${config:var.buildProperties} /p:Configuration=${config:var.configuration} ${workspaceFolder}/test/Eto.Test.Gtk/Eto.Test.Gtk.csproj",
"type": "shell",
"group": "build",
"problemMatcher": "$msCompile"
"problemMatcher": "$msCompile",
"presentation": {
"clear": true
}
},
{
"label": "build-mac64",
"command": "dotnet build ${config:var.buildProperties} /p:Configuration=${config:var.configuration} ${workspaceFolder}/test/Eto.Test.Mac/Eto.Test.Mac64.csproj",
"type": "shell",
"group": "build",
"problemMatcher": "$msCompile"
"problemMatcher": "$msCompile",
"presentation": {
"clear": true
}
},
{
"label": "build-xammac2",
"command": "msbuild /restore ${config:var.buildProperties} /p:Configuration=${config:var.configuration} ${workspaceFolder}/test/Eto.Test.Mac/Eto.Test.XamMac2.csproj",
"type": "shell",
"group": "build",
"problemMatcher": "$msCompile"
"problemMatcher": "$msCompile",
"presentation": {
"clear": true
}
},
{
"label": "build-wpf",
"command": "dotnet build ${config:var.buildProperties} /p:Configuration=${config:var.configuration} ${workspaceFolder}/test/Eto.Test.Wpf/Eto.Test.Wpf.csproj",
"type": "shell",
"group": "build",
"problemMatcher": "$msCompile"
"problemMatcher": "$msCompile",
"presentation": {
"clear": true
}
},
{
"label": "build-winforms",
"command": "dotnet build ${config:var.buildProperties} /p:Configuration=${config:var.configuration} ${workspaceFolder}/test/Eto.Test.WinForms/Eto.Test.WinForms.csproj",
"type": "shell",
"group": "build",
"problemMatcher": "$msCompile"
"problemMatcher": "$msCompile",
"presentation": {
"clear": true
}
},
{
"label": "restore",
Expand All @@ -72,7 +93,10 @@
"windows": {
"command": "IF ('${input:confirm}' -ne 'Yes') { exit 1 }; git clean -dxff ; git submodule foreach git clean -dxff ; git submodule update --init --recursive"
},
"problemMatcher": []
"problemMatcher": [],
"presentation": {
"clear": true
}
},
],
"inputs": [
Expand Down
2 changes: 1 addition & 1 deletion build/Build.proj
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
</ItemGroup>

<!-- Build all source code -->
<Target Name="Build" DependsOnTargets="UpdateVersion">
<Target Name="Build" DependsOnTargets="UpdateVersion;PrintInfo">

<PropertyGroup>
<BuildProperties>Configuration=$(Configuration);Platform=$(OSPlatform)</BuildProperties>
Expand Down
34 changes: 29 additions & 5 deletions src/Eto.Gtk/Forms/Cells/CustomCellHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ public int Row
IGtkCellEditable CreateEditable(Gdk.Rectangle cellArea)
{
var item = Handler.Source.GetItem(Row);
var args = new CellEventArgs(null, Handler.Widget, Row, item, CellStates.Editing);
int column = -1;
var args = new CellEventArgs(null, Handler.Widget, Row, column, item, CellStates.Editing, null);

var ed = new EtoCellEditable();
ed.Content = Handler.Callback.OnCreateCell(Handler.Widget, args);
Expand All @@ -125,7 +126,10 @@ IGtkCellEditable CreateEditable(Gdk.Rectangle cellArea)
public override void GetSize(Gtk.Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
{
base.GetSize(widget, ref cell_area, out x_offset, out y_offset, out width, out height);
height = Math.Max(height, Handler.Source.RowHeight);
var h = Handler;
if (h == null)
return;
height = Math.Max(height, h.Source.RowHeight);
}

public override Gtk.CellEditable StartEditing(Gdk.Event evnt, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags)
Expand All @@ -135,22 +139,42 @@ public override Gtk.CellEditable StartEditing(Gdk.Event evnt, Gtk.Widget widget,

protected override void Render(Gdk.Drawable window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags)
{
var h = Handler;
if (h == null)
return;

if (editingRow == row)
{
return;
}
using (var graphics = new Graphics(new GraphicsHandler(widget, window)))
{
var item = Handler.Source.GetItem(Row);
var item = h.Source.GetItem(Row);
var args = new CellPaintEventArgs(graphics, cell_area.ToEto(), flags.ToEto(), item);
Handler.Callback.OnPaint(Handler.Widget, args);
h.Callback.OnPaint(h.Widget, args);
}
}
#else
protected override void OnGetPreferredHeight(Gtk.Widget widget, out int minimum_size, out int natural_size)
{
base.OnGetPreferredHeight(widget, out minimum_size, out natural_size);
natural_size = Handler.Source.RowHeight;
var h = Handler;
if (h == null)
return;
natural_size = h.Source.RowHeight;
}

protected override void OnGetPreferredWidth(Gtk.Widget widget, out int minimum_size, out int natural_size)
{
base.OnGetPreferredWidth(widget, out minimum_size, out natural_size);
var h = Handler;
if (h == null)
return;
var item = h.Source?.GetItem(Row);
int column = -1;
var args = new CellEventArgs(null, h.Widget, Row, column, item, CellStates.Editing, null);

natural_size = (int)h.Callback.OnGetPreferredWidth(h.Widget, args);
}

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
Expand Down
48 changes: 46 additions & 2 deletions src/Eto.Mac/Forms/Cells/CustomCellHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public override NSObject GetObjectValue(object dataItem)

public override nfloat GetPreferredWidth(object value, CGSize cellSize, int row, object dataItem)
{
var args = new CellEventArgs(ColumnHandler?.DataViewHandler as Grid, Widget, row, dataItem, CellStates.None);
var column = -1;// TODO: lookup!
var args = new MutableCellEventArgs(ColumnHandler?.DataViewHandler as Grid, Widget, row, column, dataItem, CellStates.None, null);
var identifier = Callback.OnGetIdentifier(Widget, args) ?? string.Empty;
Control widthCell;
if (!widthCells.TryGetValue(identifier, out widthCell))
Expand All @@ -63,6 +64,7 @@ public override nfloat GetPreferredWidth(object value, CGSize cellSize, int row,
widthCell.AttachNative();
widthCells.Add(identifier, widthCell);
}
args.SetControl(widthCell);
Callback.OnConfigureCell(Widget, args, widthCell);
widthCell.GetMacControl()?.InvalidateMeasure();

Expand All @@ -76,6 +78,7 @@ public override nfloat GetPreferredWidth(object value, CGSize cellSize, int row,

public class EtoCustomCellView : NSTableCellView
{
public CustomCellHandler Handler { get; set;}
public MutableCellEventArgs Args { get; set; }

public Control EtoControl { get; set; }
Expand Down Expand Up @@ -109,6 +112,43 @@ public override NSBackgroundStyle BackgroundStyle
Args.SetTextColor(ControlText);
}
}

public void Setup()
{
EtoControl.GotFocus += ControlGotFocus;
EtoControl.LostFocus += ControlLostFocus;
}

bool losingFocus;

private void ControlLostFocus(object sender, EventArgs e)
{
if (losingFocus)
return;

losingFocus = true;
var h = Handler;
var ee = MacConversions.CreateCellEventArgs(h.ColumnHandler.Widget, null, Args.Row, Args.Column, Args.Item);
if (!h.ColumnHandler.DataViewHandler.IsCancellingEdit)
{
h.Callback.OnCommitEdit(h.Widget, Args);
h.ColumnHandler.DataViewHandler.OnCellEdited(ee);
}
else
{
h.Callback.OnCancelEdit(h.Widget, Args);
}
losingFocus = false;
}

private void ControlGotFocus(object sender, EventArgs e)
{
var h = Handler;
h.Callback.OnBeginEdit(h.Widget, Args);
var ee = MacConversions.CreateCellEventArgs(h.ColumnHandler.Widget, null, Args.Row, Args.Column, Args.Item);
h.ColumnHandler.DataViewHandler.OnCellEditing(ee);
}

}

public override Color GetBackgroundColor(NSView view)
Expand All @@ -131,7 +171,8 @@ public override NSView GetViewForItem(NSTableView tableView, NSTableColumn table
state |= CellStates.Selected;
if (tableColumn.Editable)
state |= CellStates.Editing;
var args = new MutableCellEventArgs(ColumnHandler.DataViewHandler as Grid, Widget, row, item, state);
var column = -1; // TODO: get index or lookup when needed.
var args = new MutableCellEventArgs(ColumnHandler.DataViewHandler as Grid, Widget, row, column, item, state, null);
var identifier = tableColumn.Identifier;
var id = Callback.OnGetIdentifier(Widget, args);
if (!string.IsNullOrEmpty(id))
Expand All @@ -141,9 +182,11 @@ public override NSView GetViewForItem(NSTableView tableView, NSTableColumn table
if (view == null)
{
var control = Callback.OnCreateCell(Widget, args);
args.SetControl(control);

view = new EtoCustomCellView
{
Handler = this,
Args = args,
EtoControl = control,
Identifier = identifier,
Expand All @@ -156,6 +199,7 @@ public override NSView GetViewForItem(NSTableView tableView, NSTableColumn table
childView.AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable;
childView.Frame = view.Frame;
view.AddSubview(childView);
view.Setup();
}
}
else
Expand Down
2 changes: 2 additions & 0 deletions src/Eto.Mac/Forms/Controls/GridColumnHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public interface IDataViewHandler
Grid Widget { get; }

bool SuppressUpdate { get; }

bool IsCancellingEdit { get; }
}

public interface IDataColumnHandler
Expand Down
28 changes: 22 additions & 6 deletions src/Eto.Mac/Forms/Controls/GridHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ static class GridHandler
public static readonly object IsEditing_Key = new object();
public static readonly object IsMouseDragging_Key = new object();
public static readonly object ContextMenu_Key = new object();
public static readonly object IsCancelEdit_Key = new object();
}

class EtoTableHeaderView : NSTableHeaderView
Expand Down Expand Up @@ -474,18 +475,27 @@ public void UnselectAll()

public void BeginEdit(int row, int column)
{
Control.SelectRow((nnint)row, false);
if (!Control.IsRowSelected(row))
{
Control.SelectRow((nnint)row, false);
}
Control.EditColumn((nint)column, (nint)row, new NSEvent(), true);
}

public bool CommitEdit() => SetFocusToControl();

public bool CancelEdit()
{
SuppressUpdate++;
var ret = SetFocusToControl();
SuppressUpdate--;
return ret;
if (IsEditing)
{
SuppressUpdate++;
IsCancellingEdit = true;
var ret = SetFocusToControl();
IsCancellingEdit = false;
SuppressUpdate--;
return ret;
}
return true;
}

bool SetFocusToControl()
Expand Down Expand Up @@ -588,10 +598,16 @@ void IDataViewHandler.OnCellEditing(GridViewCellEventArgs e)
SetIsEditing(true);
}

public bool IsCancellingEdit
{
get => Widget.Properties.Get<bool>(GridHandler.IsCancelEdit_Key);
set => Widget.Properties.Set(GridHandler.IsCancelEdit_Key, value);
}

void IDataViewHandler.OnCellEdited(GridViewCellEventArgs e)
{
SetIsEditing(false);
if (e.Item != null)
if (e.Item != null && !IsCancellingEdit)
Callback.OnCellEdited(Widget, e);

// reload this entire row
Expand Down
Loading

0 comments on commit 86340a4

Please sign in to comment.