// // 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 } } }