unit Vis2D_ElementSettings;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VisCtl2D,
  TextEditor, ColorContainer, Vcl.StdCtrls, ScrollBoxEx, UxPanel;

type
  TVis2D_ElementSettingsFrm = class(TDrawableOptionsFrm)
    btnApply: TUxButton;
    ScrollBox1: TScrollBoxEx;
    Label2: TLabel;
    lblAreaColor: TLabel;
    lblOpacity: TLabel;
    lblElementName: TLabel;
    ccArea: TColorContainer;
    eOpacity: TTextEditor;
    Label1: TLabel;
    lblBorderColor: TLabel;
    lblBorderWidth: TLabel;
    ccBorder: TColorContainer;
    eBorderWidth: TTextEditor;
    Label6: TLabel;
    Label7: TLabel;
    lblDisplacement: TLabel;
    eDisplacement: TTextEditor;
    procedure ScrollBox1Enter(Sender: TObject);
    procedure ScrollBox1Exit(Sender: TObject);
    procedure btnApplyClick(Sender: TObject);
    procedure CallUpdateDrawable(Sender: TObject);
  strict protected
    procedure Initialize; override;
    procedure UpdateDrawable; override;
  public

  end;

implementation

uses
  Math, RTTI;

{$R *.dfm}

{ TVis2D_ElementSettingsFrm }

procedure TVis2D_ElementSettingsFrm.btnApplyClick(Sender: TObject);
begin
  UpdateDrawable;
end;

procedure TVis2D_ElementSettingsFrm.CallUpdateDrawable(Sender: TObject);
begin
  UpdateDrawable;
end;

procedure TVis2D_ElementSettingsFrm.Initialize;
var
  Element: TElementStyle;
begin

  inherited;

  // If FDrawable isn't a TElementStyle, try to find a property named Style.
  if not (FDrawable is TElementStyle) then
  begin
    var &Type := TRttiContext.Create.GetType(FDrawable.ClassType);
    if &Type is TRttiInstanceType then
    begin
      var StyleProp := TRttiInstanceType(&Type).GetProperty('Style');
      if StyleProp.IsReadable and (StyleProp.PropertyType is TRttiInstanceType) then
      begin
        if TRttiInstanceType(StyleProp.PropertyType).MetaclassType = TElementStyle then
        begin
          with StyleProp.GetValue(FDrawable) do
            if IsObjectInstance and (AsObject is TElementStyle) then
              FDrawable := AsObject as TElementStyle;
        end;
      end;
    end;
  end;

  Element := FDrawable as TElementStyle;

  lblElementName.Caption := Element.Name;

  lblAreaColor.Enabled := espColor in Element.Parts;
  ccArea.Enabled := espColor in Element.Parts;
  ccArea.Color := Element.Color;

  eOpacity.PlainText := Round(100 * Element.Opacity / Element.Opacity.MaxValue).ToString;
  eOpacity.Enabled := espOpacity in Element.Parts;
  lblOpacity.Enabled := espOpacity in Element.Parts;

  ccBorder.Color := Element.BorderColor;
  ccBorder.Enabled := espBorderColor in Element.Parts;
  lblBorderColor.Enabled := espBorderColor in Element.Parts;

  eBorderWidth.PlainText := Element.BorderWidth.ToString;
  eBorderWidth.Enabled := espBorderWidth in Element.Parts;
  lblBorderWidth.Enabled := espBorderWidth in Element.Parts;

  eDisplacement.PlainText := Element.Displacement.ToString;
  eDisplacement.Enabled := espDisplacement in Element.Parts;
  lblDisplacement.Enabled := espDisplacement in Element.Parts;

end;

procedure TVis2D_ElementSettingsFrm.ScrollBox1Enter(Sender: TObject);
begin
  btnApply.Default := True;
end;

procedure TVis2D_ElementSettingsFrm.ScrollBox1Exit(Sender: TObject);
begin
  btnApply.Default := False;
end;

procedure TVis2D_ElementSettingsFrm.UpdateDrawable;
var
  Element: TElementStyle;
begin

  if not Initialized then
    Exit;

  Element := FDrawable as TElementStyle;

  Element.Color := ccArea.Color;
  Element.Opacity := EnsureRange(Round(Element.Opacity.MaxValue * StrToFloat(eOpacity.PlainText) / 100), 0, Element.Opacity.MaxValue);
  Element.BorderColor := ccBorder.Color;
  Element.BorderWidth := StrToInt(eBorderWidth.PlainText);
  Element.Displacement := StrToFloat(eDisplacement.PlainText);

  inherited;

end;

end.
