Advertisement
Guest User

pas2js component design

a guest
Jun 4th, 2018
390
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Hi there, In my experimental Pas2JS project, I've created a visual lazarus component and its pas2js
  2. corresponding version. When designing forms, you often use container type controls to hold others controls.
  3. In complex form designs, where containers are used within others containers. For instance, I dropped onto
  4. the form 5 components:
  5.  
  6. //+++++ Unit1.pas ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7. unit Unit1;
  8.  
  9. {$mode objfpc}{$H+}
  10.  
  11. interface
  12.  
  13. uses
  14.  SysUtils, Classes, JS, Web,
  15.  WEBLib.Graphics, WEBLIB.Controls, WEBLib.StdCtrls, WEBLib.ExtCtrls, WEBLib.Forms,
  16.  WEBLib.Dialogs, System.Color, MyCustomControl;
  17.  
  18. type
  19.  
  20.  { TForm1 }
  21.  
  22.  TForm1 = class(TWebForm)
  23.    MyCustomControl1: TMyCustomControl;
  24.    MyCustomControl2: TMyCustomControl;
  25.    MyCustomControl3: TMyCustomControl;
  26.    MyCustomControl4: TMyCustomControl;
  27.    MyCustomControl5: TMyCustomControl;
  28.    procedure MyCustomControl1Click(Sender: TObject);
  29.  private
  30.    { Private declarations }
  31.  public
  32.    { Public declarations }
  33.    procedure LoadDFMValues; override;
  34.    procedure WebButton1Click(Sender: TObject);
  35.  end;
  36.  
  37. var
  38.  Form1: TForm1;
  39.  
  40. implementation
  41.  
  42. {$R *.lfm}
  43.  
  44. { TForm1 }
  45.  
  46. procedure TForm1.MyCustomControl1Click(Sender: TObject);
  47. begin
  48.  console.log('teste');
  49. end;
  50.  
  51. procedure TForm1.LoadDFMValues;
  52. begin
  53.  inherited;
  54.  {$I 'Form1.lfm.inc'}
  55. end;
  56.  
  57. procedure TForm1.WebButton1Click(Sender: TObject);
  58. begin
  59.  console.log('button clicked');
  60. end;
  61.  
  62.  
  63. end.
  64.  
  65. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  66.  
  67. //// Form1.lfm //-----------------------------------------------------------------------
  68. object Form1: TForm1
  69.  Left = 289
  70.  Height = 480
  71.  Hint = 'Form1'
  72.  Top = 141
  73.  Width = 640
  74.  Caption = 'Form1'
  75.  ClientHeight = 480
  76.  ClientWidth = 640
  77.  LCLVersion = '1.9.0.0'
  78.  object MyCustomControl5: TMyCustomControl
  79.    Left = 30
  80.    Height = 248
  81.    Top = 11
  82.    Width = 460
  83.    BGColor = 16771033
  84.    Text = 'MyCustomControl'
  85.    object MyCustomControl1: TMyCustomControl
  86.      Left = 32
  87.      Height = 168
  88.      Top = 16
  89.      Width = 404
  90.      BGColor = clGreen
  91.      Text = 'MyCustomControl'
  92.      object MyCustomControl2: TMyCustomControl
  93.        Left = 14
  94.        Height = 135
  95.        Top = 14
  96.        Width = 376
  97.        BGColor = clMaroon
  98.        Text = 'MyCustomControl'
  99.        object MyCustomControl3: TMyCustomControl
  100.          Left = 13
  101.          Height = 99
  102.          Top = 21
  103.          Width = 347
  104.          BGColor = clBlue
  105.          Text = 'MyCustomControl'
  106.        end
  107.      end
  108.    end
  109.    object MyCustomControl4: TMyCustomControl
  110.      Left = 32
  111.      Height = 35
  112.      Top = 200
  113.      Width = 404
  114.      BGColor = clYellow
  115.      Text = 'MyCustomControl'
  116.    end
  117.  end
  118. end
  119. //_____________________________________________________________________________________
  120.  
  121. i modified the CompWriterPas, when we serialize as Pascal, we have this expected output:   
  122. ----------------------------------------------------------------------------------------   
  123.  
  124. MyCustomControl5:=TMyCustomControl.Create(Self);
  125. MyCustomControl1:=TMyCustomControl.Create(Self);
  126. MyCustomControl2:=TMyCustomControl.Create(Self);
  127. MyCustomControl3:=TMyCustomControl.Create(Self);
  128. MyCustomControl4:=TMyCustomControl.Create(Self);
  129. MyCustomControl5.BeginUpdate;
  130. MyCustomControl1.BeginUpdate;
  131. MyCustomControl2.BeginUpdate;
  132. MyCustomControl3.BeginUpdate;
  133. MyCustomControl4.BeginUpdate;
  134. try
  135.  Name:='Form1';
  136.  Left:=289;
  137.  Height:=480;
  138.  Hint:='Form1';
  139.  Top:=141;
  140.  Width:=640;
  141.  Caption:='Form1';
  142.  ClientHeight:=480;
  143.  ClientWidth:=640;
  144.  LCLVersion:='1.9.0.0';
  145.  with MyCustomControl5 do begin
  146.    Name:='MyCustomControl5';
  147.    Parent:=Self;
  148.    Left:=30;
  149.    Height:=248;
  150.    Top:=11;
  151.    Width:=460;
  152.    BGColor:=16771033;
  153.    Text:='MyCustomControl';
  154.    with MyCustomControl1 do begin
  155.      Name:='MyCustomControl1';
  156.      Parent:=MyCustomControl5;
  157.      Left:=32;
  158.      Height:=168;
  159.      Top:=16;
  160.      Width:=404;
  161.      BGColor:=clGreen;
  162.      Text:='MyCustomControl';
  163.      with MyCustomControl2 do begin
  164.        Name:='MyCustomControl2';
  165.        Parent:=MyCustomControl1;
  166.        Left:=14;
  167.        Height:=135;
  168.        Top:=14;
  169.        Width:=376;
  170.        BGColor:=clMaroon;
  171.        Text:='MyCustomControl';
  172.        with MyCustomControl3 do begin
  173.          Name:='MyCustomControl3';
  174.          Parent:=MyCustomControl2;
  175.          Left:=13;
  176.          Height:=99;
  177.          Top:=21;
  178.          Width:=347;
  179.          BGColor:=clBlue;
  180.          Text:='MyCustomControl';
  181.        end;
  182.      end;
  183.    end;
  184.    with MyCustomControl4 do begin
  185.      Name:='MyCustomControl4';
  186.      Parent:=MyCustomControl5;
  187.      Left:=32;
  188.      Height:=35;
  189.      Top:=200;
  190.      Width:=404;
  191.      BGColor:=clYellow;
  192.      Text:='MyCustomControl';
  193.    end;
  194.  end;
  195. finally
  196.  MyCustomControl5.EndUpdate;
  197.  MyCustomControl1.EndUpdate;
  198.  MyCustomControl2.EndUpdate;
  199.  MyCustomControl3.EndUpdate;
  200.  MyCustomControl4.EndUpdate;
  201. end;
  202. ------------------------------------------------------------------------------------------------------ 
  203.  
  204. ====== HTML OUTPUT =======================
  205. <div id="MyCustomControl1" zindex="0" tabindex="1" title=""
  206. style="overflow: hidden; cursor: default; outline: none; color: rgb(0, 0, 0); font-family: Tahoma; font-style: normal; font-size: 8pt; background-color: rgb(217, 231, 255); top: 11px; left: 30px; width: 460px; height: 248px; position: absolute;">
  207.  
  208.  <div id="MyCustomControl2" zindex="0" tabindex="1" title=""
  209.  style="overflow: hidden; cursor: default; outline: none; color: rgb(0, 0, 0); font-family: Tahoma; font-style: normal; font-size: 8pt; background-color: rgb(0, 128, 0); top: 16px; left: 32px; width: 404px; height: 168px; position: absolute;">
  210.  
  211.     <div id="MyCustomControl3" zindex="0" tabindex="1" title=""
  212.     style="overflow: hidden; cursor: default; outline: none; color: rgb(0, 0, 0); font-family: Tahoma; font-style: normal; font-size: 8pt; background-color: rgb(0, 0, 128); top: 14px; left: 14px; width: 376px; height: 135px; position: absolute;">
  213.  
  214.       <div id="MyCustomControl4" zindex="0" tabindex="1" title=""
  215.       style="overflow: hidden; cursor: default; outline: none; color: rgb(0, 0, 0); font-family: Tahoma; font-style: normal; font-size: 8pt; background-color: rgb(255, 0, 0); top: 21px; left: 13px; width: 347px; height: 99px; position: absolute;">
  216.       </div>
  217.     </div>
  218.  </div>
  219.  <div id="MyCustomControl5" zindex="0" tabindex="1" title=""
  220.  style="overflow: hidden; cursor: default; outline: none; color: rgb(0, 0, 0); font-family: Tahoma; font-style: normal; font-size: 8pt; background-color: rgb(0, 255, 255); top: 200px; left: 32px; width: 404px; height: 35px; position: absolute;">
  221.  </div>
  222. </div>
  223. ==============================================
  224.  
  225.    
  226. //**** PAS2JS/WEB COMPONENT VERSION ******************************************************************
  227.  
  228. unit MyCustomControl;
  229.  
  230. {$MODE objfpc}{$H+}
  231.  
  232. interface
  233.  
  234. uses
  235.  Classes, SysUtils, WEBLib.Controls, WEBLIB.Graphics, System.Color, Web;
  236.  
  237. type
  238.  TMyCustomControl = class(TCustomControl)
  239.  private
  240.    FColorBackground: TColor;
  241.    FText: string;
  242.    procedure SetText(const AValue: string);
  243.    procedure SetColorBackground(const AValue: TColor);
  244.  protected
  245.    (* create HTML element needed for the control.
  246.     responsible for returning the hierarchy of HTML elements representing the UI control.  *)
  247.    function CreateElement: TJSElement; override;
  248.    
  249.     (* To interface our Pascal class with the HTML elements two more virtual method overrides are important.
  250.     There is the UpdateElementVisual method and the UpdateElementData method.
  251.      The purpose of the UpdateElementVisual method is to do changes to HTML element properties that affect the UI control visually.  The UpdateElementVisual method is the place where typically Pascal class properties that affect the visual appearance of controls, are mapped *)    
  252.    procedure UpdateElementVisual; override;
  253.    
  254.     (* The UpdateElementData method is to do changes with respect to data contained in the HTML elements.
  255.     It is the place where properties that affect data connected to controls is updated in the HTML element. To illustrate this, let's assume our custom control mapping on a HTML DIV element has a color property to
  256.      set background color of the DIV and a text property for the text in the HTML DIV element. *)
  257.     procedure UpdateElementData; override;
  258.    
  259.     (* method DoClick *)
  260.     function HandleDoXXXX(Event: TEventListenerEvent): Boolean; virtual;
  261.    
  262.     (* bind the HTML element (FContent) returned by the CreateElement to a container element (FContainer) *)
  263.     procedure BindEvents; override;
  264.   published
  265.     property BGColor: TColor read FColorBackground write SetColorBackground;
  266.     property Text: string read FText write SetText;
  267.     property OnClick;
  268.   end;
  269.  
  270. implementation
  271.  
  272. function TMyCustomControl.CreateElement: TJSElement;
  273. begin
  274.   Result := document.createElement('DIV');
  275. end;
  276.  
  277. procedure TMyCustomControl.SetColorBackground(const AValue: TColor);
  278. begin
  279.   if (AValue <> FColorBackground) then
  280.   begin
  281.     FColorBackground := AValue;
  282.     UpdateElementVisual;
  283.   end;
  284. end;
  285.  
  286. procedure TMyCustomControl.SetText(const AValue: string);
  287. begin
  288.   if (AValue <> FText) then
  289.   begin
  290.     FText := AValue;
  291.     UpdateElementData;
  292.   end;
  293. end;
  294.  
  295. procedure TMyCustomControl.UpdateElementVisual;
  296. var
  297.   el: TJSHTMLElement;
  298. begin
  299.   inherited;
  300.   //el := TJSHTMLElement(ContainerElement);
  301.   el := GetElementHandle;
  302.   el.style.setProperty('background-color', ColorToHTML(BGColor));
  303. end;
  304.  
  305. procedure TMyCustomControl.UpdateElementData;
  306. var
  307.   el: TJSElement;
  308. begin
  309.   inherited;
  310.   //el := TJSHTMLElement(ContainerElement);
  311.   el := GetElementHandle;
  312.   //el.innerHTML:= Text;   //---> THIS IS PROBABLY A BUG, IT WILL CAUSE PAGE REFLOW SUB COMPONENTS
  313. end;
  314.  
  315. procedure TMyCustomControl.BindEvents;
  316. begin
  317.   inherited;
  318.   FContainer.addEventListener('click', @HandleDoXXXX);
  319. end;
  320.  
  321. function TMyCustomControl.HandleDoXXXX(Event: TEventListenerEvent):
  322.   Boolean;
  323. begin
  324.   // code to be executed when Javascript event XXXX is executed
  325.   console.log('clicked');
  326.   Result := true;
  327. end;
  328.  
  329. end.
  330. //*******************************************************************************************
  331.  
  332.  
  333. //=== LAZARUS VISUAL FAKE COMPONENT VERSION =================================================
  334. unit MyCustomControl;
  335.  
  336. {$mode objfpc}{$H+}
  337.  
  338. interface
  339.  
  340. uses
  341.   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs;
  342.  
  343. type
  344.  
  345.   { TMyCustomControl }
  346.  
  347.   TMyCustomControl = class(TCustomControl)
  348.   private
  349.     FColorFont,
  350.     FColorBackground,
  351.     FColorBorder: TColor;
  352.     FText: string;
  353.     procedure SetText(const AValue: string);
  354.   protected
  355.     procedure Paint; override;
  356.     procedure TextChanged; override;
  357.   public
  358.     constructor Create(AOwner: TComponent); override;
  359.     procedure SetColorBackground(AColor: TColor);
  360.   published
  361.     property BGColor: TColor read FColorBackground write SetColorBackground;
  362.     property Text: string read FText write SetText;
  363.     property OnClick;
  364.   end;
  365.  
  366. procedure Register;
  367.  
  368. implementation
  369.  
  370. { TMyCustomControl }
  371.  
  372. constructor TMyCustomControl.Create(AOwner: TComponent);
  373. begin
  374.   inherited;
  375.   ControlStyle := ControlStyle + [csAcceptsControls, csNoFocus, csSetCaption];
  376.   Width := 180;
  377.   Height := 100;
  378.   Text   := 'MyCustomControl';
  379.  
  380.   FColorFont := clBlack;
  381.   FColorBorder := $00F95800;
  382.   FColorBackground := $00FFE7D9; //$00F95800;
  383. end;
  384.  
  385. procedure TMyCustomControl.TextChanged;
  386. begin
  387.   Inherited;
  388.   Invalidate;
  389. end;
  390.  
  391. procedure TMyCustomControl.SetColorBackground(AColor: TColor);
  392. begin
  393.   FColorBackground := AColor;
  394.   Invalidate;
  395. end;
  396.  
  397. procedure TMyCustomControl.SetText(const AValue: string);
  398. begin
  399.   FText := AValue;
  400. end;
  401.  
  402. procedure TMyCustomControl.Paint;
  403. begin
  404.   inherited;
  405.   // Background
  406.   Canvas.Brush.Style := bsSolid;
  407.   Canvas.Brush.Color := FColorBackground;
  408.   Canvas.FillRect(ClientRect);
  409.  
  410.   // Border
  411.   Canvas.Brush.Style := bsClear;
  412.   Canvas.Pen.Color := FColorBorder;
  413.   Canvas.Rectangle(ClientRect);
  414.  
  415.   // Text
  416.   Canvas.Brush.Style := bsClear;
  417.   Canvas.Font.Color := FColorFont;
  418.   Canvas.TextOut((ClientWidth-Canvas.TextExtent(Caption).cx) div 2,
  419.       (ClientHeight-Canvas.TextExtent(Caption).cy) div 2, Caption);
  420. end;
  421.  
  422. procedure Register;
  423. begin
  424.   {$I mycustomcontrol_icon.lrs}
  425.   RegisterComponents('Web',[TMyCustomControl]);
  426. end;
  427.  
  428. end.
  429. //================================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement