//
// Core.cs: The core engine for gui.cs
//
// Authors:
// Miguel de Icaza (miguel@gnome.org)
//
// Pending:
// - Check for NeedDisplay on the hierarchy and repaint
// - Layout support
// - "Colors" type or "Attributes" type?
// - What to surface as "BackgroundCOlor" when clearing a window, an attribute or colors?
//
// Optimziations
// - Add rendering limitation to the exposed area
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
namespace Terminal.Gui {
///
/// Responder base class implemented by objects that want to participate on keyboard and mouse input.
///
public class Responder : IDisposable {
bool disposedValue;
#if DEBUG_IDISPOSABLE
///
/// For debug purposes to verify objects are being disposed properly
///
public bool WasDisposed = false;
///
/// For debug purposes to verify objects are being disposed properly
///
public int DisposedCount = 0;
///
/// For debug purposes
///
public static List Instances = new List ();
///
/// For debug purposes
///
public Responder ()
{
Instances.Add (this);
}
#endif
///
/// Gets or sets a value indicating whether this can focus.
///
/// true if can focus; otherwise, false.
public virtual bool CanFocus { get; set; }
///
/// Gets or sets a value indicating whether this has focus.
///
/// true if has focus; otherwise, false.
public virtual bool HasFocus { get; }
///
/// Gets or sets a value indicating whether this can respond to user interaction.
///
public virtual bool Enabled { get; set; } = true;
///
/// Gets or sets a value indicating whether this and all its child controls are displayed.
///
public virtual bool Visible { get; set; } = true;
// Key handling
///
/// This method can be overwritten by view that
/// want to provide accelerator functionality
/// (Alt-key for example).
///
///
///
/// Before keys are sent to the subview on the
/// current view, all the views are
/// processed and the key is passed to the widgets
/// to allow some of them to process the keystroke
/// as a hot-key.
///
/// For example, if you implement a button that
/// has a hotkey ok "o", you would catch the
/// combination Alt-o here. If the event is
/// caught, you must return true to stop the
/// keystroke from being dispatched to other
/// views.
///
///
public virtual bool ProcessHotKey (KeyEvent kb)
{
return false;
}
///
/// If the view is focused, gives the view a
/// chance to process the keystroke.
///
///
///
/// Views can override this method if they are
/// interested in processing the given keystroke.
/// If they consume the keystroke, they must
/// return true to stop the keystroke from being
/// processed by other widgets or consumed by the
/// widget engine. If they return false, the
/// keystroke will be passed using the ProcessColdKey
/// method to other views to process.
///
///
/// The View implementation does nothing but return false,
/// so it is not necessary to call base.ProcessKey if you
/// derive directly from View, but you should if you derive
/// other View subclasses.
///
///
/// Contains the details about the key that produced the event.
public virtual bool ProcessKey (KeyEvent keyEvent)
{
return false;
}
///
/// This method can be overwritten by views that
/// want to provide accelerator functionality
/// (Alt-key for example), but without
/// interefering with normal ProcessKey behavior.
///
///
///
/// After keys are sent to the subviews on the
/// current view, all the view are
/// processed and the key is passed to the views
/// to allow some of them to process the keystroke
/// as a cold-key.
///
/// This functionality is used, for example, by
/// default buttons to act on the enter key.
/// Processing this as a hot-key would prevent
/// non-default buttons from consuming the enter
/// keypress when they have the focus.
///
///
/// Contains the details about the key that produced the event.
public virtual bool ProcessColdKey (KeyEvent keyEvent)
{
return false;
}
///
/// Method invoked when a key is pressed.
///
/// Contains the details about the key that produced the event.
/// true if the event was handled
public virtual bool OnKeyDown (KeyEvent keyEvent)
{
return false;
}
///
/// Method invoked when a key is released.
///
/// Contains the details about the key that produced the event.
/// true if the event was handled
public virtual bool OnKeyUp (KeyEvent keyEvent)
{
return false;
}
///
/// Method invoked when a mouse event is generated
///
/// true, if the event was handled, false otherwise.
/// Contains the details about the mouse event.
public virtual bool MouseEvent (MouseEvent mouseEvent)
{
return false;
}
///
/// Method invoked when a mouse event is generated for the first time.
///
///
/// true, if the event was handled, false otherwise.
public virtual bool OnMouseEnter (MouseEvent mouseEvent)
{
return false;
}
///
/// Method invoked when a mouse event is generated for the last time.
///
///
/// true, if the event was handled, false otherwise.
public virtual bool OnMouseLeave (MouseEvent mouseEvent)
{
return false;
}
///
/// Method invoked when a view gets focus.
///
/// The view that is losing focus.
/// true, if the event was handled, false otherwise.
public virtual bool OnEnter (View view)
{
return false;
}
///
/// Method invoked when a view loses focus.
///
/// The view that is getting focus.
/// true, if the event was handled, false otherwise.
public virtual bool OnLeave (View view)
{
return false;
}
///
/// Method invoked when the property from a view is changed.
///
public virtual void OnCanFocusChanged () { }
///
/// Method invoked when the property from a view is changed.
///
public virtual void OnEnabledChanged () { }
///
/// Method invoked when the property from a view is changed.
///
public virtual void OnVisibleChanged () { }
// TODO: v2 - nuke this
///
/// Utilty function to determine is overridden in the .
///
/// The view.
/// The method name.
/// if it's overridden, otherwise.
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;
}
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
///
/// If disposing equals true, the method has been called directly
/// or indirectly by a user's code. Managed and unmanaged resources
/// can be disposed.
/// If disposing equals false, the method has been called by the
/// runtime from inside the finalizer and you should not reference
/// other objects. Only unmanaged resources can be disposed.
///
///
protected virtual void Dispose (bool disposing)
{
if (!disposedValue) {
if (disposing) {
// TODO: dispose managed state (managed objects)
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource.
///
public void Dispose ()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose (disposing: true);
GC.SuppressFinalize (this);
#if DEBUG_IDISPOSABLE
WasDisposed = true;
#endif
}
}
}