Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Korrekter Umgang mit Delphi Styles und eigenen Komponenten (https://www.delphipraxis.net/181343-korrekter-umgang-mit-delphi-styles-und-eigenen-komponenten.html)

Whookie 7. Aug 2014 15:13

Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Seit einiger Zeit habe ich mit den Delphi Styles einwenig experimentiert. Da ich eine Menge eigener (visueller) Komponenten habe stellt sich mir aber nun die Frage, wie man am besten deren Style integriert, sodass sie bei einem Stylewechsel passend angezeigt werden.

Für ein paar ganz einfach Komponenten reicht es natürlich im Paint() die StyleServices zu verwenden und eventuell auch System oder Stylefarben für eigene Zusätze zu "missbrauchen".

Mitunter gibt es aber komplexere Komponenten, die mehrere zum Style passende Elemente benötigen würden (in der Regel eigene Farben wie zum Beispiel bei einer "Log"-Komponente die für Fehler, Warnungen und normalen Text unterschiedliche Farben benötigt - und das eben abhängig vom durch einen Style gegebenen Hintergrund).
Hin und wieder wären aber auch ein paar Grafiken von Vorteil die auch, abhängig vom Style, mal heller mal dunkler daherkommen sollten.

Irgend etwas zu den original Styles hinzuzufügen ist ja wohl verboten und auch Kopien davon, dafür zu verwenden erscheint mir nicht gerade vernünftig.

Man könnte natürlich für jede Komponente die entsprechenden Ressourcen für alle momentan bekannten Styles speichern und bei einem Stylewechsel nachsehen ob Einstellungen dafür vorhanden sind (über den Stylenamen?) und diese dann verwenden. Ist aber mühsam und bei einer Lib mit 50+ Komponenten ganz schön aufwendig und dann auch über die ganze Lib. verstreut!

Schön wäre es etwa, wenn ich für alle Komponenten ein gemeinsames Style-File haben könnte indem nur meine Einstellungen enthalten sind (scheitert schon mal daran, dass im Bitmap-Stil-Designer ein "Neu"es Projekt komplett mit einer vollen Konfiguration bestückt ist und leider Löschen auch verboten ist).
Theoretisch könnte ich dann für jeden Delphi Style eine eigene .vsf haben und diese müsste mit ausgeliefert werden (ob als eigenständige Datei oder auch als Ressource) und dann müsste es auch noch eine Methode geben, die meine Zusätze mit denen der dazugehörenden Styles verbindet....

Letzteres wäre dann auch noch ein zweites Mal von Vorteil, weil auch die eigentliche Applikation noch styleabhängige Komponenten mitbringen kann (z.B.: einen umfangreichen Satz an Icons die zumindestens für "helle" und "dunkle" Styles andere Farben haben müssen)...

Also eine Menge Fragen, ich hoffe, dass es - wie immer - ein paar Spezialisten gibt, die sich damit auskennen...

TiGü 7. Aug 2014 16:59

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Zitat:

Zitat von Whookie (Beitrag 1267911)
Also eine Menge Fragen, ich hoffe, dass es - wie immer - ein paar Spezialisten gibt, die sich damit auskennen...

Im gesamten Beitrag gibt es nur ein Fragezeichen (und das steht in Klammern).

Wenn du in deinen Komponenten viel selber auf den Canvas zeichnest, bieten sich die Methoden von StyleServices an. Beispielsweise GetSystemColor und GetStyleColor.
Welche Farben das für die einzelnen Styles sind, kann man sich im Bitmap Style Designer unter "Colors" und "SysColors" anschauen.

Eine weitere Möglichkeit wäre das Schreiben eigener StyleHooks für deine Komponenten.
Somit wäre zumindest das Zeichen im Styling-Fall von den bisherigen Code entkoppelt.

Das VCL Styles Project ist dir ein Begriff?
http://theroadtodelphi.wordpress.com...ry/vcl-styles/

Whookie 8. Aug 2014 13:20

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Ja kenn ich, hab auch selber ein paar fixes für Delphi XE5 an den StyleHooks gemacht... ist aber ein Beispiel dafür, wie man es eben nicht machen sollte die eigenen Erweiterungen in den Originalstyle zu integrieren ist - aus meiner Sicht - ein "no go".

Vielleicht waren meine Fragen aber wirklich nicht klar genug definiert. Die Hauptfrage ergibt sich aber aus dem Titel des Threads:

1. Korrekter Umgang mit Delphi Styles und eigenen Komponenten?
1.1. Eigene Farben für jeden Stil definieren (wo am besten)?
1.2. Eigene Graphiken für jeden Stil definieren (wo/wie)?

2. Korrektes Management für die einzelnen Zusätze
2.1. Wo hin mit den eigenen Definitionen (siehe 1.1, 1.2)?
2.2. Wie linken mit den bestehenden Styles (so dass, die Umschaltung eines Styles auch die eigenen Komponenten betrifft)?

Alles andere sind Gedanken die ich mir zu diesem Thema gemacht habe und sollte nur zeigen in welche Richtungen meine Überlegungen bisher gegangen sind.

Insider2004 8. Aug 2014 15:54

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Ich habe die VCL.Styles aufgegeben. Was nützt es, wenn die 3 Standard-Komponenten unterstützt werden, aber die 20 anderen Fremdkomponenten nicht. Ich hab keine Zeit mich darum auch noch zu kümmern. Das ganze Konzept des skinning taugt nicht in Delphi, weil es nicht adaptiv ist. Ausserdem sollte das immer die Aufgabe des nativen Betriebssystems sein.

Whookie 8. Aug 2014 16:17

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Zitat:

Zitat von Insider2004 (Beitrag 1268045)
Ich habe die VCL.Styles aufgegeben.

Ja, ich sehe das auch eher als mittelfristiges Ziel, eher aber wegen der unendlichen Anzahl an Bugs.

Zitat:

Zitat von Insider2004 (Beitrag 1268045)
...aber die 20 anderen Fremdkomponenten nicht

Zugegeben ein Problem, das aber in vielen Fällen einfach in der Applikation gelöst werden kann (wie eingangs erwähnt hat man ja auch selber zB. Icons die sich dem Style entspr. ändern müssen).
Zumindestens von Steema weis ich, dass mit dem nächsten Release Style Support kommen wird (habe aber keine Ahnung wann konkret <Kristallkugel> wohl spätestens irgendwann im Herbst </Kristallkugel> und wie das Ganze dann aussehen wird).

Zitat:

Zitat von Insider2004 (Beitrag 1268045)
Das ganze Konzept des skinning taugt nicht in Delphi, weil es nicht adaptiv ist.

Damit meinst Du, dass es überhaupt keine Möglichkeit gibt, eigene Erweiterungen an eine bestehende Skin zu hängen???

Zitat:

Zitat von Insider2004 (Beitrag 1268045)
Ausserdem sollte das immer die Aufgabe des nativen Betriebssystems sein.

Ich weis, dass sowas schnell in metaphorische Betrachtungen über das "Soll" und "Haben" und insbesondere über Gott und dessen Bereitschaft aus seinem Garten Eden ein Laserdrom zu machen ausarten kann ... aber (ja es gibt immer ein "aber") manchmal neigt der Mensch dazu gottgewolltes einfach so zu nehmen und nach seinem eigenen belieben zu verändern... ;)

Der schöne Günther 8. Aug 2014 16:44

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Von XE5 auf XE6 wurde die unermüdliche Arbeit von Rodrigo Ruz eingebaut. Hast du dir das angesehen?

(Soll nur ein Hinweis sein, deine eigentlichen Fragen beantwortet das nicht)

Insider2004 8. Aug 2014 17:19

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1268051)
Von XE5 auf XE6 wurde die unermüdliche Arbeit von Rodrigo Ruz eingebaut. Hast du dir das angesehen?

(Soll nur ein Hinweis sein, deine eigentlichen Fragen beantwortet das nicht)

Darüber reden wir ja. EMBA hat mal wieder kostenlos eine 50%-Lösung "zugekauft", anstatt selbst das Hirn einzuschalten und eine wasserdichte Lösung anzubieten.

Whookie 8. Aug 2014 17:36

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1268051)
Von XE5 auf XE6 wurde die unermüdliche Arbeit von Rodrigo Ruz eingebaut. Hast du dir das angesehen?

(Soll nur ein Hinweis sein, deine eigentlichen Fragen beantwortet das nicht)

Ja, leider haben sie auch ein paar kapitale Bugs zugekauft (oder selber gemacht :D ) und daher muss ich XE6 ganz auslassen (Stichwort: MDI Crash)

TiGü 11. Aug 2014 10:38

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mich in meiner eigenen Anwendung auf einen einzigen selbst erstellten Style konzentriert.
Jeden Style abdecken zu wollen ist eine Mammutaufgabe.
Fraglich auch, ob das sinnvoll ist.
Ich würde den Anwender die Wahl lassen zwischen den normalen Windows-Style und einen anderen.

Dementsprechend muss man ggf. alles doppelt haben: Imagelisten, Image-Ressourcen usw. und zur Laufzeit beim Programmstart austauschen.
Die Farben müssen dann entsprechend aus den Style extrahiert werden (GetSystemColor/GetStyleColor).

Hier mal so ein Minimalbeispiel:

Delphi-Quellcode:
unit StylesTestFrm;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls,
  Vcl.ExtCtrls,
  System.Generics.Collections,
  Vcl.Themes,
  Vcl.ImgList;

type

  TLineState = (Start, Move, Stop);

  TPainter = class
  strict private
    FIsLineStarted : Boolean;
    FCanvas : TCanvas;
    FImageIndex : Integer;
    FImageList : TImageList;
    FPoints : TList<TPoint>;
  public
    procedure Clear;
    function PaintLine(LineState : TLineState; X, Y : Integer) : Boolean;
    procedure Paint;

    constructor Create(ACanvas : TCanvas; AImageList : TImageList);
    destructor Destroy; override;

    property IsLineStarted : Boolean read FIsLineStarted write FIsLineStarted;
  end;

  TForm2 = class(TForm)
    PaintBox1 : TPaintBox;
    ilSystem : TImageList;
    ilStyle : TImageList;
    procedure FormCreate(Sender : TObject);
    procedure PaintBox1MouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
    procedure PaintBox1MouseMove(Sender : TObject; Shift : TShiftState; X, Y : Integer);
    procedure PaintBox1Paint(Sender : TObject);
    procedure PaintBox1MouseUp(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
    procedure FormDestroy(Sender: TObject);
  private
    FPainter : TPainter;
  public
  end;

var
  Form2 : TForm2;

implementation

uses
  System.Math;

{$R *.dfm}

procedure TForm2.FormCreate(Sender : TObject);
var
  LCurrentImageList : TImageList;
begin
  LCurrentImageList := ilStyle;
  if StyleServices.IsSystemStyle then
  begin
    LCurrentImageList := ilSystem;
  end;

  FPainter := TPainter.Create(PaintBox1.Canvas, LCurrentImageList);
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  FPainter.Free;
end;

procedure TForm2.PaintBox1MouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
begin
  case Button of
    TMouseButton.mbLeft :
    begin
      if FPainter.PaintLine(TLineState.Start, X, Y) then
        PaintBox1.Repaint;
    end;
  end;
end;

procedure TForm2.PaintBox1MouseMove(Sender : TObject; Shift : TShiftState; X, Y : Integer);
begin
  if FPainter.PaintLine(TLineState.Move, X, Y) then
    PaintBox1.Repaint;
end;

procedure TForm2.PaintBox1MouseUp(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
begin
  case Button of
    TMouseButton.mbLeft :
    begin
      if FPainter.PaintLine(TLineState.Stop, X, Y) then
        PaintBox1.Repaint;
    end;
    TMouseButton.mbRight :
    begin
      FPainter.Clear;
      PaintBox1.Repaint;
    end;
  end;
end;

procedure TForm2.PaintBox1Paint(Sender : TObject);
begin
  if Assigned(FPainter) then
  begin
    FPainter.Paint;
  end;
end;

procedure TPainter.Clear;
begin
  FCanvas.FillRect(FCanvas.ClipRect);
  FPoints.Clear;
  FImageIndex := 0;
end;

constructor TPainter.Create(ACanvas : TCanvas; AImageList : TImageList);
begin
  FCanvas := ACanvas;
  FImageList := AImageList;
  FPoints := TList<TPoint>.Create;
  FCanvas.Pen.Width := 5;
  FCanvas.Pen.Color := StyleServices.GetSystemColor(clHighlight);
  FCanvas.Brush.Color := StyleServices.GetSystemColor(clBackground);
end;

destructor TPainter.Destroy;
begin
  FPoints.Free;
  inherited;
end;

procedure TPainter.Paint;
var
  LPoints : TArray<TPoint>;
  LLastPosition : TPoint;
begin
  LPoints := FPoints.ToArray;
  FCanvas.Polyline(LPoints);

  if InRange(FImageIndex, 0, FImageList.Count - 1) then
  begin
    Inc(FImageIndex)
  end
  else
  begin
    FImageIndex := 0;
  end;

  if FPoints.Count > 0 then
  begin
    LLastPosition := FPoints.Last;
    FImageList.Draw(FCanvas, LLastPosition.X + 3, LLastPosition.Y + 3, FImageIndex);
  end;
end;

function TPainter.PaintLine(LineState : TLineState; X, Y : Integer) : Boolean;
var
  LPosition : TPoint;
begin
  LPosition := TPoint.Create(X, Y);
  case LineState of
    Start :
    begin
      FPoints.Add(LPosition);
      IsLineStarted := True;
    end;
    Move :
    begin
      if IsLineStarted then
      begin
        if LPosition <> FPoints.Last then
        begin
          FPoints.Add(LPosition);
        end;
      end;
    end;
    Stop :
    begin
      if IsLineStarted then
      begin
        FPoints.Clear;
        IsLineStarted := False;
      end;
    end;
  end;
  Result := IsLineStarted;
end;

end.

Whookie 11. Aug 2014 10:59

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
 
Für eigene Applikationen mache ich das in geeignetem Rahmen auch so ähnlich und da kann man sich sicher auch auf ein paar wenige Styles beschränken.

Mir geht es aber eher um (m)eine Komponenten Library die ja dann für anderen Entwickler und deren Projekte verwendet werden und damit wird es schon schwieriger einen Style vorzuschreiben!


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:12 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz