{********************************************************************}
{                                                                    }
{ written by TMS Software                                            }
{            copyright © 2013                                        }
{            Email : info@tmssoftware.com                            }
{            Web : http://www.tmssoftware.com                        }
{                                                                    }
{ The source code is given as is. The author is not responsible      }
{ for any possible damage done due to the use of this code.          }
{ The complete source code remains property of the author and may    }
{ not be distributed, published, given or sold in any form as such.  }
{ No parts of the source code can be included in any other component }
{ or application without written authorization of the author.        }
{********************************************************************}

unit FMX.TMSSearchEdit;

interface

{$I TMSDEFS.INC}

uses
  Classes, Types, SysUtils, FMX.Types, FMX.TMSBaseControl,
  FMX.Edit, FMX.Objects, FMX.Layouts, FMX.Controls, UIConsts, FMX.Styles
  {$IFDEF DELPHIXE5_LVL}
  , FMX.Graphics
  {$ENDIF}
  ;

const
  MAJ_VER = 1; // Major version nr.
  MIN_VER = 5; // Minor version nr.
  REL_VER = 0; // Release nr.
  BLD_VER = 0; // Build nr.

  // version history
  // v1.0.0.0 : First Release
  // v1.1.0.3 : Fixed : Small issue with loading styles
  //          : Reorganized packages
  // v1.1.1.0 : New : support for update 4
  // v1.1.1.1 : Improved : TMSIOS define
  // v1.1.1.2 : New : support for update 4 hotfix 1
  // v1.2.0.0 : New: Exposed OnClickClear, OnClickFind
  // v1.5.0.0 : New : support for XE4

type
  TTMSFMXSearchEditMode = (emCaption, emDescription);

  [ComponentPlatformsAttribute(TMSPlatforms)]
  TTMSFMXSearchEdit = class(TEdit)
  private
    FMode: TTMSFMXSearchEditMode;
    FShowFind: Boolean;
    FShowClear: Boolean;
    FBackGroundVisible: Boolean;
    FOnClickClear: TNotifyEvent;
    FOnClickFind: TNotifyEvent;
    procedure SetShowFind(const Value: Boolean);
    procedure SetShowClear(const Value: Boolean);
    procedure SetBackGroundVisible(const Value: Boolean);
    function GetVersion: String;
    function GetVersionNr: Integer;
    procedure SetVersion(const Value: String);
  protected
    procedure UpdateFind;
    procedure UpdateBackGround;
    procedure UpdateClear;
    procedure DoChangeTracking; override;
    procedure ApplyStyle; override;
    function GetClassName: String; virtual;
    function GetClassStyleName: String; virtual;
    function GetStyleObject: TFmxObject; override;
    function LoadFromResource: TFMXObject;
    procedure ClearButtonClicked(Sender: TObject);
    procedure FindButtonClicked(Sender: TObject);
    procedure DoClickClear; virtual;
    procedure DoClickFind; virtual;
  public
    property Mode: TTMSFMXSearchEditMode read FMode write FMode;
    constructor Create(AOwner: TComponent); override;
    function GetClearButton: TImage;
    function GetFindButton: TImage;
    function GetBackGround: TRoundRect;
    function GetContent: TLayout;
  published
    property BackGroundVisible: Boolean read FBackGroundVisible write SetBackGroundVisible default True;
    property ShowFind: Boolean read FShowFind write SetShowFind default True;
    property ShowClear: Boolean read FShowClear write SetShowClear default True;
    property Version: String read GetVersion write SetVersion;
    property OnClickClear: TNotifyEvent read FOnClickClear write FOnClickClear;
    property OnClickFind: TNotifyEvent read FOnClickFind write FOnClickFind;
  end;

implementation

{$R FMX.TMSSearchEdit.res}

{ TTMSFMXSearchEdit }

procedure TTMSFMXSearchEdit.ApplyStyle;
var
  c: TLayout;
begin
  inherited;
  UpdateClear;
  UpdateFind;
  UpdateBackGround;
  c := GetContent;
  if Assigned(c) then
    {$IFDEF DELPHIXE6_LVL}
    c.Align := TAlignLayout.Client;
    {$ELSE}
    c.Align := TAlignLayout.alClient;
    {$ENDIF}
end;

procedure TTMSFMXSearchEdit.ClearButtonClicked(Sender: TObject);
begin
  DoClickClear;
  Text := '';
  Change;
end;

constructor TTMSFMXSearchEdit.Create(AOwner: TComponent);
begin
  inherited;
  Width :=  120;
  Height := 30;
  FShowFind := True;
  FShowClear := True;
  FBackGroundVisible := True;
end;

procedure TTMSFMXSearchEdit.DoClickClear;
begin
  if Assigned(OnClickClear) then
    OnClickClear(Self);
end;

procedure TTMSFMXSearchEdit.DoClickFind;
begin
  if Assigned(OnClickFind) then
    OnClickFind(Self);
end;

procedure TTMSFMXSearchEdit.FindButtonClicked(Sender: TObject);
begin
  DoClickFind;
end;

function TTMSFMXSearchEdit.GetBackGround: TRoundRect;
begin
  Result := FindStyleResource('background') as TRoundRect;
end;

function TTMSFMXSearchEdit.GetClassName: String;
begin
  Result := ClassName;
end;

function TTMSFMXSearchEdit.GetClassStyleName: String;
begin
  Result := GetClassName + 'style';
  Delete(Result, 1, 1);
end;

function TTMSFMXSearchEdit.GetFindButton: TImage;
begin
  Result := FindStyleResource('findbutton') as TImage;
end;

function TTMSFMXSearchEdit.GetClearButton: TImage;
begin
  Result := FindStyleResource('clearbutton') as TImage;
end;

function TTMSFMXSearchEdit.GetContent: TLayout;
begin
  Result := FindStyleResource('content') as TLayout;
end;

function TTMSFMXSearchEdit.GetStyleObject: TFMXObject;
var
  obj: TFMXObject;
begin
  obj := inherited GetStyleObject;
  if Assigned(obj) and (obj.ClassType = TLayout) then
  begin
    obj.Free;
    obj := LoadFromResource;
  end;

  Result := obj;
end;

function TTMSFMXSearchEdit.GetVersion: string;
var
  vn: Integer;
begin
  vn := GetVersionNr;
  Result := IntToStr(Hi(Hiword(vn)))+'.'+IntToStr(Lo(Hiword(vn)))+'.'+IntToStr(Hi(Loword(vn)))+'.'+IntToStr(Lo(Loword(vn)));
end;

function TTMSFMXSearchEdit.GetVersionNr: integer;
begin
  Result := MakeLong(MakeWord(BLD_VER,REL_VER),MakeWord(MIN_VER,MAJ_VER));
end;

function TTMSFMXSearchEdit.LoadFromResource: TFMXObject;
var
  str: String;
begin
  Result := nil;
  // create resource class name
  str := GetClassStyleName;
  if FindRCData(HInstance, str) then
    {$IFDEF DELPHIXE6_LVL}
    Result := TStyleStreaming.LoadFromResource(Hinstance, str, RT_RCDATA);
    {$ELSE}
    Result := TStyleManager.LoadFromResource(Hinstance, str, RT_RCDATA);
    {$ENDIF}
end;

procedure TTMSFMXSearchEdit.SetBackGroundVisible(const Value: Boolean);
begin
  if FBackGroundVisible <> Value then
  begin
    FBackGroundVisible := Value;
    UpdateBackGround;
  end;
end;

procedure TTMSFMXSearchEdit.SetShowClear(const Value: Boolean);
begin
  if FShowClear <> Value then
  begin
    FShowClear := Value;
    UpdateClear;
  end;
end;

procedure TTMSFMXSearchEdit.SetShowFind(const Value: Boolean);
begin
  if FShowFind <> Value then
  begin
    FShowFind := Value;
    UpdateFind;
  end;
end;

procedure TTMSFMXSearchEdit.DoChangeTracking;
var
  btnClear: TImage;
begin
  inherited;
  btnClear := GetClearButton;
  if Assigned(btnClear) and ShowClear then
    btnClear.Visible := Text <> '';
end;

procedure TTMSFMXSearchEdit.SetVersion(const Value: String);
begin

end;

procedure TTMSFMXSearchEdit.UpdateBackGround;
var
  bkg: TRoundRect;
begin
  bkg := GetBackGround;
  if Assigned(bkg) then
  begin
    {$IFDEF DELPHIXE6_LVL}
    if BackGroundVisible then
    begin
      bkg.Fill.Kind := TBrushKind.Solid;
      bkg.Stroke.Kind := TBrushKind.Solid;
    end
    else
    begin
      bkg.Fill.Kind := TBrushKind.None;
      bkg.Stroke.Kind := TBrushKind.None;
    end;
    {$ELSE}
    if BackGroundVisible then
    begin
      bkg.Fill.Kind := TBrushKind.bkSolid;
      bkg.Stroke.Kind := TBrushKind.bkSolid;
    end
    else
    begin
      bkg.Fill.Kind := TBrushKind.bkNone;
      bkg.Stroke.Kind := TBrushKind.bkNone;
    end;
    {$ENDIF}
  end;
end;

procedure TTMSFMXSearchEdit.UpdateClear;
var
  btnClear: TImage;
begin
  btnClear := GetClearButton;
  if Assigned(btnClear) then
  begin
    btnClear.Visible := ShowClear and (Text <> '');
    btnClear.OnClick := ClearButtonClicked;
  end;
end;

procedure TTMSFMXSearchEdit.UpdateFind;
var
  btnFind: TImage;
begin
  btnFind := GetFindButton;
  if Assigned(btnFind) then
  begin
    btnFind.Visible := ShowFind;
    btnFind.OnClick := FindButtonClicked;
  end;
end;

initialization
  RegisterFmxClasses([TTMSFMXSearchEdit]);

end.
