Jump to content

Smart Component Generator


Recommended Posts

  • 3 months later...

It looks interesting but I am not sure I fully understand the purpose. Are these then components on the IDE component ribbon? Are they components that you can access in code only? Just looking at some of the SMS code is interesting in itself.

 

Thanks for sharing

Link to post
Share on other sites

Look at this smart employee headBar component. This is a visual component. 

(* ╔═════════════════════════════╗
   ║  _______  _______  _______  ║
   ║ (  ____ (       )(  ____ /  ║
   ║ | (    /| () () || (    \/  ║
   ║ | (_____ | || || || (_____  ║
   ║ (_____  )| |(_)| |(_____  ) ║
   ║       ) || |   | |      ) | ║
   ║ /____) || )   ( |/____) |   ║
   ║ _______)|/     \|\_______)  ║
   ║ created by: warleyalex      ║
   ╚═════════════════════════════╝ *)
unit uHeaderBar;

{$R 'https://fonts.googleapis.com/icon?family=Material+Icons'}

interface

uses
  Smart.Core,
  SmartCL.System, System.Types,
  SmartCL.Components,
  ECMA.JSON, w3C.HTML5, W3C.Console, W3C.DOM;

type
  TSearchBar = class;
  TBackButton = class;
  TNextButton = class;
  TEventListener = procedure(eventObj : JKeyboardEvent);

type
  THeaderBar = class(TW3CustomControl{TW3Component})
  private
    (* Private declarations *)
    FTitle: string;
    FSearchBar : TSearchBar;
    FBackButton: TBackButton;
    FNextButton: TNextButton;
  protected
    (* Protected declarations *)
    function GetSearchBar: TSearchBar;
    procedure createINNERComponent;
    procedure InitializeObject; override;
    procedure FinalizeObject; override;
    (* procedure ObjectReady; override; *)
    procedure StyleTagObject; override; empty; (* comment this if you need style attribute in the parent *)
    procedure bindEvent(element: Variant; EventType: variant; handler: TEventListener);
    (* invoked events *)
    procedure DoClickBackButton(eventObj : JKeyboardEvent);
    procedure DoClickNextButton(eventObj : JKeyboardEvent);
    procedure DoKeyUpSearchBar(eventObj : JKeyboardEvent);
  public
    (* Public declarations *)
  published
    (* Published declarations *)
    //property SearchBar: TSearchBar read FSearchBar write FSearchBar;
    property SearchBar: TSearchBar read GetSearchBar;
    property BackButton: TBackButton read FBackButton write FBackButton;
    property NextButton: TNextButton read FNextButton write FNextButton;
    property Title: string read FTitle write FTitle;
  end;

  TBackButton = class(TObject)
  private
  { private declarations }
    FOnClick: TMouseClickEvent;
    FOnKeyUp: TKeyUpEvent;
    FVisible: boolean;
    FCaption: String = 'Back';
  public
  { public declarations }
  published
  { published declarations }
    property OnClick: TMouseClickEvent read FOnClick write FOnClick;
    property OnKeyUp: TKeyUpEvent read FOnKeyUp write FOnKeyUp;
    property Visible: Boolean read FVisible write FVisible;
    property Caption: String read FCaption write FCaption;
  end;

  TNextButton = class(TObject)
  private
  { private declarations }
    FOnClick: TMouseClickEvent;
    FOnKeyUp: TKeyUpEvent;
    FVisible: boolean;
    FCaption: String = 'Next';
  published
  { published declarations }
    property OnClick: TMouseClickEvent read FOnClick write FOnClick;
    property OnKeyUp: TKeyUpEvent read FOnKeyUp write FOnKeyUp;
    property Visible: Boolean read FVisible write FVisible;
    property Caption: String read FCaption write FCaption;
  end;

  TSearchBar = class(TW3OwnedObject)
  private
  { private declarations }
    Parent: THeaderBar;
    FOnKeyUp: TKeyUpEvent;
    FVisible: boolean;
  protected
  { protected declarations }
    function AcceptParent(aObject: TObject): Boolean; override;
    function  getText: String;
    procedure setText(aValue: String);
  public
  { public declarations }
  published
  { published declarations }
    property OnKeyUp: TKeyUpEvent read FOnKeyUp write FOnKeyUp;
    property Visible: Boolean read FVisible write FVisible;
    property Text: String read getText write setText;
  end;

implementation

function document: variant; external "document" property;
function &typeof: variant; overload; external "typeof" property;

{ ╔═══════════════════════════════════════════════════════════════════════╗
  ║ ### TSearchBar widget ###                                             ║
  ╚═══════════════════════════════════════════════════════════════════════╝ }

function TSearchBar.AcceptParent(aObject: TObject): Boolean;
begin
  result:=(aObject<>NIL) and (aObject is TW3CustomControl);
  if result then
    Parent:= THeaderBar(aObject);
end;

function TSearchBar.getText: String;
begin
  Result := document.querySelector('.main--input').value
end;

procedure TSearchBar.setText(aValue: String);
begin
If visible then
  Parent.Handle.ReadyExecute( procedure ()
  begin
    document.querySelector('.main--input').value := aValue;
  end);
end;

{ ╔═══════════════════════════════════════════════════════════════════════╗
  ║ ### THeaderBar widget ###                                             ║
  ╚═══════════════════════════════════════════════════════════════════════╝ }
procedure THeaderBar.bindEvent(element: Variant; EventType: variant; handler: TEventListener);
begin
  if (element.addEventListener) then
    element.addEventListener(EventType, @handler, false)
  else
    element.attachEvent("on"+EventType, @handler);
end;

(* initializate the SearchBar widget on-the-fly *)
function THeaderBar.GetSearchBar: TSearchBar;
begin
  if FSearchBar = nil then
    FSearchBar := TSearchBar.Create(Self);
  Result := FSearchBar;
end;

procedure THeaderBar.FinalizeObject;
begin
  FBackButton.Free;
  FNextButton.Free;

  if Assigned(FSearchBar) then
    FSearchBar.Free;
  inherited;
end;

(* to perform onclick event on the BackButton widget *)
procedure THeaderBar.DoClickBackButton(eventObj : JKeyboardEvent);
begin
  if Assigned(BackButton.FOnClick) then
    BackButton.FOnClick(self);
end;

(* to perform onclick event on the NextButton widget *)
procedure THeaderBar.DoClickNextButton(eventObj : JKeyboardEvent);
begin
  if Assigned(NextButton.FOnClick) then
    NextButton.FOnClick(self);
end;

(* to perform onkeyup event on the SearchBar widget *)
procedure THeaderBar.DoKeyUpSearchBar(eventObj : JKeyboardEvent);
begin 
  if Assigned(SearchBar.FOnKeyUp) then
    SearchBar.FOnKeyUp(Self,eventObj.keyCode);
end;

{ ╔══════════════════════════════════════════════════╗
  ║ Insert here the innerComponent (generated code)  ║
  ╚══════════════════════════════════════════════════╝ }

procedure THeaderBar.createINNERComponent;
begin
{ ╔═══════════════════════════════════════════════════════════════════════════╗
  ║ Since the document fragment is in memory and not part of the main DOM     ║
  ║ tree, appending children to it does not cause page reflow (computation    ║
  ║ of elements position and geometry). Consequently, using documentfragments ║
  ║ often results in better performance.                                      ║
  ╚═══════════════════════════════════════════════════════════════════════════╝ }

var docFragment := JDocumentFragment( document.createDocumentFragment() ); // contains all gathered nodes

var header_ := JHTMLElement( document.createElement('HEADER') );
header_.setAttribute("class", "bar-title");
docFragment.appendChild(header_);

var div_ := JHTMLDivElement( document.createElement('DIV') );
div_.setAttribute("class", "header-animated");
header_.appendChild(div_);

if BackButton.visible then begin
  var BackButton := JHTMLDivElement( document.createElement('DIV') );
  BackButton.setAttribute("class", "button-prev");
  div_.appendChild(BackButton);
  if Self.NextButton.caption <> '' then begin
    var text_ := JText( document.createTextNode(Self.BackButton.Caption) );
    BackButton.appendChild(text_);
  end;
  bindEvent(BackButton, "click", @DoClickBackButton);
end;

var h1_ := JHTMLHeadingElement( document.createElement('H1') );
h1_.setAttribute("class", "title");
div_.appendChild(h1_);
If (Self.Title <> '') then begin
  var text_0 := JText( document.createTextNode(Self.Title) );
  h1_.appendChild(text_0);
end;

if NextButton.visible then begin
  var NextButton := JHTMLDivElement( document.createElement('DIV') );
  NextButton.setAttribute("class", "button-next");
  div_.appendChild(NextButton);
  if Self.NextButton.Caption <> '' then begin
    var text_1 := JText( document.createTextNode(Self.NextButton.Caption) );
    NextButton.appendChild(text_1);
  end;
  bindEvent(NextButton, "click", @DoClickNextButton);
end;
//------------------------
if SearchBar.visible then begin
  var d = JHTMLDivElement( document.createElement('DIV') );
  d.setAttribute("class", "main--input_container");
  div_.appendChild(d);

  var Edit1 := JHTMLInputElement( document.createElement('INPUT') );
  Edit1.setAttribute("type", "search");
  Edit1.setAttribute("class", "main--input");
  Edit1.setAttribute("value", "");
  d.appendChild(Edit1);
  bindEvent(Edit1, "keyup", @DoKeyUpSearchBar);

  var i1 = JHTMLElement( document.createElement('I') );
  i1.setAttribute("class", "material-icons");
  var t = JText( document.createTextNode("search") );
  i1.appendChild(t);
  d.appendChild(i1);
end;

Self.Handle.appendChild( docFragment );
//====================================================
	// Focus input when click on container
	SMS('.main--input_container').click(procedure()
  begin
    SMS(".main--input").focus()
	end);
	// Focus input
	SMS(".main--input").focus(procedure ()
  begin
		SMS(this).addClass("main--input--focus");
		SMS(".search--button").addClass("search--button--visible");
	end);
	// Unfocus input if it's empty
  SMS('.main--input').blur(procedure()
  begin
    if(SMS(this).val() = '') then begin
      SMS(this).removeClass('main--input--focus');
			SMS(".search--button").removeClass("search--button--visible");
    end;
  end);

End;

procedure THeaderBar.InitializeObject;
begin
  inherited;
{ ╔══════════════════════════════════════════════════╗
  ║ this is a good place to initialize the component ║
  ╚══════════════════════════════════════════════════╝ }
  FBackButton := TBackButton.Create;
  FNextButton := TNextButton.Create;

{ ╔═════════════════════════════════════════════════════════════════════╗
  ║ make the control display itself correctly when its ready in the DOM ║
  ╚═════════════════════════════════════════════════════════════════════╝ }
  Handle.ReadyExecute(procedure()
  begin
    (* call createInnerComponent *)
    createInnerComponent;
{ ╔══════════════════════════════════════════════════╗
  ║ some basic style attributes after render         ║
  ╚══════════════════════════════════════════════════╝ }
    Self.Handle.style["left"] := null;
    Self.Handle.style["width"] := null;
    Self.Handle.style["height"] := null;
  end);

end;

End.

This is a visual component, just drag'n drop into designer or create manually.

var
  HeaderBar1: THeaderBar;

  HeaderBar1 := THeaderBar.Create(Self);
  HeaderBar1.Width := 320;
  HeaderBar1.Height := 44;
  HeaderBar1.Name := 'HeaderBar1';
  HeaderBar1.Title := 'Smart Employees';
  HeaderBar1.NextButton.Visible := true;
  HeaderBar1.NextButton.Caption := '?';
  HeaderBar1.NextButton.OnClick := procedure(Sender: TObject)
  begin
    WriteLn('About clicked');
  end;

  HeaderBar1.SearchBar.Visible := true;
  HeaderBar1.SearchBar.OnKeyUp := procedure(Sender: TObject; aKeyCode: Integer)
  begin
    WriteLn( HeaderBar1.SearchBar.text );
  end;

Link to post
Share on other sites

it don't work for you perhaps I'm using totaly modified RTL version to bypass the whole SmartCL* framework, this experimental component inherits from the TW3CustomControl but it would also work with TW3Component/TW3MovableControl base class which provides a lightweight infrainstructure.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...