Ich entwickle eine TUI-Bibliothek in C# und ich benötige Ratschläge, wie man Farbthemen für Anzeigeobjekte erstellen kann. Objekte, die alle auf dem Bildschirm gezeichnet werden können erben von dieser Schnittstelle:Force-Klassen, die eine eigene spezifische Implementierung einer abstrakten Klasse enthalten/verwenden
public interface IDrawable
{
Area ScreenArea { get; }
List<char[]> DisplayChars { get; }
//some other properties...
}
Oder besser gesagt, genauer gesagt, die Schnittstellen für jedes ziehbar Objekt implementiert diese Schnittstelle (IWindow
ist ein IDrawable
). Jeder IDrawable
wird auf einen bestimmten Teil des Konsolenfensters von der Fläche Struktur dargestellt gezeichnet:
public struct Area
{
public readonly int EndX;
public readonly int EndY;
public readonly int Height;
public readonly int StartX;
public readonly int StartY;
public readonly int Width;
public Area(int startX, int endX, int startY, int endY)
{
StartX = startX;
EndX = endX;
StartY = startY;
EndY = endY;
Height = endY - startY;
Width = endX - startX;
}
/// <summary>
/// Get the overlapping area between this area and another.
/// </summary>
/// <param name="refArea"></param>
/// <returns>Overlap area relative to the upper left corner of the ref area.</returns>
public Area OverlapWith(Area refArea)
{
//....
}
}
Die eigentliche Zeichnung von Objekten wird durch Verfahren in einer statischen Display
Klasse behandelt, die Console.Write()
auf jedem Element in DisplayChars nennen. Ich möchte für jede Klasse, die von IDrawable
erbt, gezwungen werden, ihre eigenen Regeln zu implementieren, wie ihr Bereich in einzelne Farbbereiche unterteilt werden kann, zum Beispiel können Popup-Fenster separate färbbare Bereiche für ihre äußeren Rahmen haben, ihren Titel (innerhalb seine äußere Grenze) und sein innerer Bereich.
Ich habe schon eine Weile darüber nachgedacht, wie ich das in meinem Kopf machen kann. Ich muss einen Typ eingeben, ColorScheme
, um die Regeln für welche Zeichen in welcher Farbe zu schreiben enthalten. Ich entschied, dass der beste Weg dies zu tun wäre, es zu einer abstrakten Klasse zu machen, die eine Liste von "Unterbereichen" enthält, auf die Farben separat angewendet werden können.
Ich möchte für jedes nicht-abstrakte IDrawable
eine eigene Klasse implementieren müssen, die von ColorScheme
erbt. Zum Beispiel hätte die Klasse Window : IWindow
keine solche Implementierung, aber die Klasse PopupWindow : Window
müsste einen entsprechenden Typ von PopupWindowColorScheme : ColorScheme
haben, in dem der Autor von PopupWindow
definieren würde, wie die Klasse 'Area
in separate Bereiche aufgeteilt werden soll. Jede PopupWindow
würde eine eigene Instanz dieses Typs haben, um ihre spezifischen Farben zu enthalten.
Ist das möglich? Wenn nicht, gibt es eine andere Möglichkeit, Autoren von IDrawable
Typen zu zwingen, eine Methode anzugeben, um ihre Bereiche in färbbare Regionen aufzuteilen?
Dies sollte perfekt sein! Vielen Dank für die schnelle Antwort :) Jetzt muss ich nur noch die Innereien herausfinden, wie ein ColorScheme aussehen sollte, vorzugsweise so, dass die Draw-Methoden für jedes Zeichen, das sie auf den Bildschirm schreiben, keine Farbe überprüfen und einstellen müssen . – thetiniestmouse
Hmm, kleines Problem, wegen schlechter Vererbungshierarchie. Ich habe derzeit Schnittstellen für abstrakte Klassen, die von IDrawable erben, und spezifische Typen, die indirekt über ihre abstrakte Basis erben, mit der Idee, dass Klassen wie "WindowManager" und "ControlManager" ihre jeweiligen Typen über ihre Schnittstellen handhaben und trotzdem behandeln könnten sie als Zeichen. Wäre es zu schrecklich, Casting zu verwenden und sich auf diejenigen verlassen zu müssen, die benutzerdefinierte Typen erstellen, z. B. "IDrawable" und "IWindow" zu verwenden, wenn ein neuer Fenstertyp erstellt wird, wie sie sollen? – thetiniestmouse
@thetiniestmouse In diesem Fall würde ich empfehlen, eine nicht generische Schnittstelle 'IDrawable' zu behalten, die alle Kerneigenschaften und Methoden * anders * als' ColorScheme' und eine Unterschnittstelle 'IDrawable: IDrawable' spezifiziert, die' ColorScheme 'liefert '-spezifische Funktionalität. Sie können sogar eine Eigenschaft auf 'IDrawable' haben, die die Basis 'ColorScheme' freilegt und sie 'IDrawable 'mit' new T ColorScheme {get; } '. (Dies ist ähnlich wie "IEnumerable : IEnumerable" funktioniert) –