Component Integration with HTML5 Builder

From HTML5 Builder
Jump to: navigation, search

When you develop components, you usually want them to be used from HTML5 Builder.

Package

To make it possible to install your components on HTML5 Builder, you need to create a package that provides detailed information about your components and the way they should be managed.

Component

You can also improve the way HTML5 Builder handles the rendering of your components or interacts with them implementing some HTML5 Builder-specific features in your component’s source code.

Rendering Type

When adding a component to the Designer, the component will be processed in the background. Then it will be displayed on the Designer:

  • If the component has a visual representation in HTML, it will be rendered on the Designer as it would be seen on a web browser after deployment. The JavaScript code of the component will also be read.
  • If the component outputs a binary image file, the image will represent the component on the Designer.
  • For non-visual components, a 32×32 pixel button with component’s icon will be rendered on the Designer.

Rendering Settings

When you develop a component, use its ControlStyle property to provide data about the rendering requirements of your component, so the Designer can render it properly. The following settings are available:

csAcceptsControls
Whether the control can contain other controls inside (true) or not (false).
csDesignEncoding
Character encoding to be used when rendering the component.
csImageContent
Whether the component renders binary data (true) or text (false). This is used, for example, for the ZBarcode component.
csLeftOffset
Displacement (integer) in pixels from the left to be used for the image of the component.
csRenderAlso
Comma-separated list of class names for components to be rendered too when rendering this component.
csRenderOwner
Whether the owner of the component should be redrawn when redrawing the component (true) or not (false).
csSlowRedraw
Whether the component includes JavaScript or any other feature that takes time to redraw (true) or not (false).
csTemplateOutput
Whether this component produces valid template output (true) or not (false).
csTopOffset
Displacement (integer) in pixels from the top to be used for the image of the component.
csVerySlowRedraw
Variation of csSlowRedraw for heavy components.
csWebEngine
Web engine to be used when rendering the component:

The rendering settings are assigned to the ControlStyle property, on your component’s constructor, as a string defining a key-value pair: $this->ControlStyle = "SettingName=Value";. You can repeat the assignation for as many settings as you need: $this->ControlStyle = "Setting1=Value1"; $this->ControlStyle = "Setting2=Value2"; For example, to request that any SpeedButton component on the form is rendered whenever our component is:

function __construct($aowner=null)
{
  parent::__construct($aowner); // Call parent constructor.
  $this->ControlStyle = "csRenderAlso=SpeedButton";
}

Conditional Rendering

You can render components on the Designer differently from the way they are rendered on a web browser. Check whether their control state is set to csDesigning or not:

if( ($this->ControlState & csDesigning) === csDesigning )
{
  // The code here will only be executed when the component is rendered on the Designer.
}

Tip: To run code when the components is rendered on a web browser, replace === with !==.

This feature is specially important when dealing with property changes with side effects over other properties. For example, properties like Orientation that usually switch the height and width of their control as a side effect.

At design time, when you change the value of a property, this is what HTML5 Builder does internally:

  1. Instantiation. An instance of the component’s underlying PHP class is created.
  2. Initialization. The instance is configured with the property values defined in the Object Inspector — other than the one that has just been changed.
  3. Update. Finally, configure the property that was actually changes in the Object Inspector with its new value.

At design time, you should only apply those side effects — that changing a property has over other properties — when the property is the one that was changed in the Object Inspector. The PHP global variable $allowupdates will be true in that situation, so you can control whether or not the side effects must be applied:

function setPropertyName($value) {
    global $allowupdates;
    if( ($this->ControlState & csDesigning) === csDesigning && $allowupdates)
    {
        // The code here will only be executed when PropertyName was change in the Object Inspector.
    }
    $this->_propertyName = $value;
}

Component Editors

Component editors are special editors that make it possible to run PHP code defined on your component from the Designer. They let you define actions to be listed on the drop-down list that pops up when you right-click on your component from the Designer. When an action is clicked, its PHP code is executed on the component.

To define a component editor, inherit from ComponentEditor (defined on designide.inc.php) and define the getVerbs() and executeVerbs() functions:

class CustomComponentEditor extends ComponentEditor
{
  // Print a list of action names, separated by line breaks.
  function getVerbs()
  {
    echo "First Action\nSecond Action";
  }

  // Define the code to be executed, depending on the selected action.
  // You will get the index of the selected action, starting with 0 for the first action.
  function executeVerb($verb)
  {
    switch($verb)
    {
      case 0:
        // Code for the first action.
        break;
      case 1:
        // Code for the second action.
        break;
    }
  }
}

To access the target component from executeVerb(), use $this->component. Any output you echo will be displayed on a dialog window.

Once your component editor is defined, you must register it on the components package with the following function:

registerComponentEditor("ComponentName","ComponentEditorName","descriptionFile.inc.php");

For an example of a component editor, see the Database component.

HTML5 Builder Extensions

Layout Managers

Layout managers allow you to write Delphi code that gets executed whenever a component is moved or resized on the Designer. This feature is used to provide the visual part of layouts that work on PHP.

Certain containers require a higher control of their children, and it cannot be achieved with PHP due to performance reasons — this is where layout managers come in.

A layout manager must inherit from TD4PHPLayoutManager and must implement two methods:

procedure Execute(params: TStringList; container: TWinControl); virtual; stdcall; abstract; // Called when the position of the container changes.
procedure ResizeParent(params: TStringList; container: TWinControl; previousbounds: TRect); virtual; stdcall; abstract; // Called to resize or move all the children of the container.

After that, it must be registered into HTML5 Builder:

// Register a layout manager for a specific layout type.
procedure RegisterLayoutManager(const layouttype: string; layoutmanagerclass: TD4PHPLayoutManagerClass);

When the Designer moves or resizes a control, it checks whether there is a layout manager available for the layout types involved in the move or resize operation, so you can perform any action with the controls on the container, or even with the container itself.