Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Hi there, In my experimental Pas2JS project, I've created a visual lazarus component and its pas2js
- corresponding version. When designing forms, you often use container type controls to hold others controls.
- In complex form designs, where containers are used within others containers. For instance, I dropped onto
- the form 5 components:
- //+++++ Unit1.pas ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- unit Unit1;
- {$mode objfpc}{$H+}
- interface
- uses
- SysUtils, Classes, JS, Web,
- WEBLib.Graphics, WEBLIB.Controls, WEBLib.StdCtrls, WEBLib.ExtCtrls, WEBLib.Forms,
- WEBLib.Dialogs, System.Color, MyCustomControl;
- type
- { TForm1 }
- TForm1 = class(TWebForm)
- MyCustomControl1: TMyCustomControl;
- MyCustomControl2: TMyCustomControl;
- MyCustomControl3: TMyCustomControl;
- MyCustomControl4: TMyCustomControl;
- MyCustomControl5: TMyCustomControl;
- procedure MyCustomControl1Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- procedure LoadDFMValues; override;
- procedure WebButton1Click(Sender: TObject);
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.lfm}
- { TForm1 }
- procedure TForm1.MyCustomControl1Click(Sender: TObject);
- begin
- console.log('teste');
- end;
- procedure TForm1.LoadDFMValues;
- begin
- inherited;
- {$I 'Form1.lfm.inc'}
- end;
- procedure TForm1.WebButton1Click(Sender: TObject);
- begin
- console.log('button clicked');
- end;
- end.
- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- //// Form1.lfm //-----------------------------------------------------------------------
- object Form1: TForm1
- Left = 289
- Height = 480
- Hint = 'Form1'
- Top = 141
- Width = 640
- Caption = 'Form1'
- ClientHeight = 480
- ClientWidth = 640
- LCLVersion = '1.9.0.0'
- object MyCustomControl5: TMyCustomControl
- Left = 30
- Height = 248
- Top = 11
- Width = 460
- BGColor = 16771033
- Text = 'MyCustomControl'
- object MyCustomControl1: TMyCustomControl
- Left = 32
- Height = 168
- Top = 16
- Width = 404
- BGColor = clGreen
- Text = 'MyCustomControl'
- object MyCustomControl2: TMyCustomControl
- Left = 14
- Height = 135
- Top = 14
- Width = 376
- BGColor = clMaroon
- Text = 'MyCustomControl'
- object MyCustomControl3: TMyCustomControl
- Left = 13
- Height = 99
- Top = 21
- Width = 347
- BGColor = clBlue
- Text = 'MyCustomControl'
- end
- end
- end
- object MyCustomControl4: TMyCustomControl
- Left = 32
- Height = 35
- Top = 200
- Width = 404
- BGColor = clYellow
- Text = 'MyCustomControl'
- end
- end
- end
- //_____________________________________________________________________________________
- i modified the CompWriterPas, when we serialize as Pascal, we have this expected output:
- ----------------------------------------------------------------------------------------
- MyCustomControl5:=TMyCustomControl.Create(Self);
- MyCustomControl1:=TMyCustomControl.Create(Self);
- MyCustomControl2:=TMyCustomControl.Create(Self);
- MyCustomControl3:=TMyCustomControl.Create(Self);
- MyCustomControl4:=TMyCustomControl.Create(Self);
- MyCustomControl5.BeginUpdate;
- MyCustomControl1.BeginUpdate;
- MyCustomControl2.BeginUpdate;
- MyCustomControl3.BeginUpdate;
- MyCustomControl4.BeginUpdate;
- try
- Name:='Form1';
- Left:=289;
- Height:=480;
- Hint:='Form1';
- Top:=141;
- Width:=640;
- Caption:='Form1';
- ClientHeight:=480;
- ClientWidth:=640;
- LCLVersion:='1.9.0.0';
- with MyCustomControl5 do begin
- Name:='MyCustomControl5';
- Parent:=Self;
- Left:=30;
- Height:=248;
- Top:=11;
- Width:=460;
- BGColor:=16771033;
- Text:='MyCustomControl';
- with MyCustomControl1 do begin
- Name:='MyCustomControl1';
- Parent:=MyCustomControl5;
- Left:=32;
- Height:=168;
- Top:=16;
- Width:=404;
- BGColor:=clGreen;
- Text:='MyCustomControl';
- with MyCustomControl2 do begin
- Name:='MyCustomControl2';
- Parent:=MyCustomControl1;
- Left:=14;
- Height:=135;
- Top:=14;
- Width:=376;
- BGColor:=clMaroon;
- Text:='MyCustomControl';
- with MyCustomControl3 do begin
- Name:='MyCustomControl3';
- Parent:=MyCustomControl2;
- Left:=13;
- Height:=99;
- Top:=21;
- Width:=347;
- BGColor:=clBlue;
- Text:='MyCustomControl';
- end;
- end;
- end;
- with MyCustomControl4 do begin
- Name:='MyCustomControl4';
- Parent:=MyCustomControl5;
- Left:=32;
- Height:=35;
- Top:=200;
- Width:=404;
- BGColor:=clYellow;
- Text:='MyCustomControl';
- end;
- end;
- finally
- MyCustomControl5.EndUpdate;
- MyCustomControl1.EndUpdate;
- MyCustomControl2.EndUpdate;
- MyCustomControl3.EndUpdate;
- MyCustomControl4.EndUpdate;
- end;
- ------------------------------------------------------------------------------------------------------
- ====== HTML OUTPUT =======================
- <div id="MyCustomControl1" zindex="0" tabindex="1" title=""
- 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;">
- <div id="MyCustomControl2" zindex="0" tabindex="1" title=""
- 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;">
- <div id="MyCustomControl3" zindex="0" tabindex="1" title=""
- 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;">
- <div id="MyCustomControl4" zindex="0" tabindex="1" title=""
- 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;">
- </div>
- </div>
- </div>
- <div id="MyCustomControl5" zindex="0" tabindex="1" title=""
- 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;">
- </div>
- </div>
- ==============================================
- //**** PAS2JS/WEB COMPONENT VERSION ******************************************************************
- unit MyCustomControl;
- {$MODE objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, WEBLib.Controls, WEBLIB.Graphics, System.Color, Web;
- type
- TMyCustomControl = class(TCustomControl)
- private
- FColorBackground: TColor;
- FText: string;
- procedure SetText(const AValue: string);
- procedure SetColorBackground(const AValue: TColor);
- protected
- (* create HTML element needed for the control.
- responsible for returning the hierarchy of HTML elements representing the UI control. *)
- function CreateElement: TJSElement; override;
- (* To interface our Pascal class with the HTML elements two more virtual method overrides are important.
- There is the UpdateElementVisual method and the UpdateElementData method.
- 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 *)
- procedure UpdateElementVisual; override;
- (* The UpdateElementData method is to do changes with respect to data contained in the HTML elements.
- 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
- set background color of the DIV and a text property for the text in the HTML DIV element. *)
- procedure UpdateElementData; override;
- (* method DoClick *)
- function HandleDoXXXX(Event: TEventListenerEvent): Boolean; virtual;
- (* bind the HTML element (FContent) returned by the CreateElement to a container element (FContainer) *)
- procedure BindEvents; override;
- published
- property BGColor: TColor read FColorBackground write SetColorBackground;
- property Text: string read FText write SetText;
- property OnClick;
- end;
- implementation
- function TMyCustomControl.CreateElement: TJSElement;
- begin
- Result := document.createElement('DIV');
- end;
- procedure TMyCustomControl.SetColorBackground(const AValue: TColor);
- begin
- if (AValue <> FColorBackground) then
- begin
- FColorBackground := AValue;
- UpdateElementVisual;
- end;
- end;
- procedure TMyCustomControl.SetText(const AValue: string);
- begin
- if (AValue <> FText) then
- begin
- FText := AValue;
- UpdateElementData;
- end;
- end;
- procedure TMyCustomControl.UpdateElementVisual;
- var
- el: TJSHTMLElement;
- begin
- inherited;
- //el := TJSHTMLElement(ContainerElement);
- el := GetElementHandle;
- el.style.setProperty('background-color', ColorToHTML(BGColor));
- end;
- procedure TMyCustomControl.UpdateElementData;
- var
- el: TJSElement;
- begin
- inherited;
- //el := TJSHTMLElement(ContainerElement);
- el := GetElementHandle;
- //el.innerHTML:= Text; //---> THIS IS PROBABLY A BUG, IT WILL CAUSE PAGE REFLOW SUB COMPONENTS
- end;
- procedure TMyCustomControl.BindEvents;
- begin
- inherited;
- FContainer.addEventListener('click', @HandleDoXXXX);
- end;
- function TMyCustomControl.HandleDoXXXX(Event: TEventListenerEvent):
- Boolean;
- begin
- // code to be executed when Javascript event XXXX is executed
- console.log('clicked');
- Result := true;
- end;
- end.
- //*******************************************************************************************
- //=== LAZARUS VISUAL FAKE COMPONENT VERSION =================================================
- unit MyCustomControl;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs;
- type
- { TMyCustomControl }
- TMyCustomControl = class(TCustomControl)
- private
- FColorFont,
- FColorBackground,
- FColorBorder: TColor;
- FText: string;
- procedure SetText(const AValue: string);
- protected
- procedure Paint; override;
- procedure TextChanged; override;
- public
- constructor Create(AOwner: TComponent); override;
- procedure SetColorBackground(AColor: TColor);
- published
- property BGColor: TColor read FColorBackground write SetColorBackground;
- property Text: string read FText write SetText;
- property OnClick;
- end;
- procedure Register;
- implementation
- { TMyCustomControl }
- constructor TMyCustomControl.Create(AOwner: TComponent);
- begin
- inherited;
- ControlStyle := ControlStyle + [csAcceptsControls, csNoFocus, csSetCaption];
- Width := 180;
- Height := 100;
- Text := 'MyCustomControl';
- FColorFont := clBlack;
- FColorBorder := $00F95800;
- FColorBackground := $00FFE7D9; //$00F95800;
- end;
- procedure TMyCustomControl.TextChanged;
- begin
- Inherited;
- Invalidate;
- end;
- procedure TMyCustomControl.SetColorBackground(AColor: TColor);
- begin
- FColorBackground := AColor;
- Invalidate;
- end;
- procedure TMyCustomControl.SetText(const AValue: string);
- begin
- FText := AValue;
- end;
- procedure TMyCustomControl.Paint;
- begin
- inherited;
- // Background
- Canvas.Brush.Style := bsSolid;
- Canvas.Brush.Color := FColorBackground;
- Canvas.FillRect(ClientRect);
- // Border
- Canvas.Brush.Style := bsClear;
- Canvas.Pen.Color := FColorBorder;
- Canvas.Rectangle(ClientRect);
- // Text
- Canvas.Brush.Style := bsClear;
- Canvas.Font.Color := FColorFont;
- Canvas.TextOut((ClientWidth-Canvas.TextExtent(Caption).cx) div 2,
- (ClientHeight-Canvas.TextExtent(Caption).cy) div 2, Caption);
- end;
- procedure Register;
- begin
- {$I mycustomcontrol_icon.lrs}
- RegisterComponents('Web',[TMyCustomControl]);
- end;
- end.
- //================================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement