Skip to content
Merged
20 changes: 20 additions & 0 deletions Terminal.Gui/Core/Responder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;

namespace Terminal.Gui {
/// <summary>
Expand Down Expand Up @@ -236,6 +237,25 @@ public virtual void OnEnabledChanged () { }
/// </summary>
public virtual void OnVisibleChanged () { }

/// <summary>
/// Utilty function to determine <paramref name="method"/> is overridden in the <paramref name="subclass"/>.
/// </summary>
/// <param name="subclass">The view.</param>
/// <param name="method">The method name.</param>
/// <returns><see langword="true"/> if it's overridden, <see langword="false"/> otherwise.</returns>
internal static bool IsOverridden (Responder subclass, string method)
{
MethodInfo m = subclass.GetType ().GetMethod (method,
BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.DeclaredOnly);
if (m == null) {
return false;
}
return m.GetBaseDefinition ().DeclaringType != m.DeclaringType;
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
Expand Down
14 changes: 0 additions & 14 deletions Terminal.Gui/Core/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3073,19 +3073,5 @@ public View GetTopSuperView ()

return top;
}

/// <summary>
/// Check if the <paramref name="method"/> is overridden in the <paramref name="view"/>.
/// </summary>
/// <param name="view">The view.</param>
/// <param name="method">The method name.</param>
/// <returns><see langword="true"/> if it's overridden, <see langword="false"/> otherwise.</returns>
public bool IsOverridden (View view, string method)
{
Type t = view.GetType ();
MethodInfo m = t.GetMethod (method);

return (m.DeclaringType == t || m.ReflectedType == t) && m.GetBaseDefinition ().DeclaringType == typeof (Responder);
}
}
}
48 changes: 48 additions & 0 deletions UnitTests/ResponderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using Terminal.Gui;
using Xunit;
using static Terminal.Gui.Core.ViewTests;

// Alias Console to MockConsole so we don't accidentally use Console
using Console = Terminal.Gui.FakeConsole;
Expand Down Expand Up @@ -44,5 +45,52 @@ public void Dispose_Works ()
{

}

public class DerivedView : View {
public DerivedView ()
{
}

public override bool OnKeyDown (KeyEvent keyEvent)
{
return true;
}
}

[Fact]
public void IsOverridden_False_IfNotOverridden ()
{
// MouseEvent IS defined on Responder but NOT overridden
Assert.False (Responder.IsOverridden (new Responder () { }, "MouseEvent"));

// MouseEvent is defined on Responder and NOT overrident on View
Assert.False (Responder.IsOverridden (new View () { Text = "View does not override MouseEvent" }, "MouseEvent"));
Assert.False (Responder.IsOverridden (new DerivedView () { Text = "DerivedView does not override MouseEvent" }, "MouseEvent"));

// MouseEvent is NOT defined on DerivedView
Assert.False (Responder.IsOverridden (new DerivedView () { Text = "DerivedView does not override MouseEvent" }, "MouseEvent"));

// OnKeyDown is defined on View and NOT overrident on Button
Assert.False (Responder.IsOverridden (new Button () { Text = "Button does not override OnKeyDown" }, "OnKeyDown"));
}

[Fact]
public void IsOverridden_True_IfOverridden ()
{
// MouseEvent is defined on Responder IS overriden on ScrollBarView (but not View)
Assert.True (Responder.IsOverridden (new ScrollBarView () { Text = "ScrollBarView overrides MouseEvent" }, "MouseEvent"));

// OnKeyDown is defined on View
Assert.True (Responder.IsOverridden (new View () { Text = "View overrides OnKeyDown" }, "OnKeyDown"));

// OnKeyDown is defined on DerivedView
Assert.True (Responder.IsOverridden (new DerivedView () { Text = "DerivedView overrides OnKeyDown" }, "OnKeyDown"));

// ScrollBarView overrides both MouseEvent (from Responder) and Redraw (from View)
Assert.True (Responder.IsOverridden (new ScrollBarView () { Text = "ScrollBarView overrides MouseEvent" }, "MouseEvent"));
Assert.True (Responder.IsOverridden (new ScrollBarView () { Text = "ScrollBarView overrides Redraw" }, "Redraw"));

Assert.True (Responder.IsOverridden (new Button () { Text = "Button overrides MouseEvent" }, "MouseEvent"));
}
}
}