Selection by a ListBox and RadioButtons

This demonstration is based on our Oxygene example showing selection in an Android application. The ListBox can contain different types of visual component and a Label was a convenient choice for us. In Version 2.1 of Smart Mobile Studio it is not possible to drop a RadioButton onto the form, so we created our own from the closely related CheckBox. The conversion required:
  1. changing identifiers;
  2. Changing the line in StyleTagObject to w3_setProperty(Handle, 'type', 'radio');
  3. Changing HandleLabelClick so that a click can select a button but not deselect it.

The Smart Pascal code of the main unit and the RadioButton unit and the XML code of the form follow the working demonstration. If the program does not work in your current browser, try another such as Chrome. If you see no display at school, the security system might have blocked it. You can try instead this direct link to the program running on its own page.

SelectionDemo.html

Code of the Main Unit

unit Form1;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Label,
  SmartCL.Controls.Listbox, System.Colors, System.Types, RadioButton;

type
  TForm1 = class(TW3Form)
  private
    {$I 'Form1:intf'}
    const Colours: array[0..4] of TColor = [clRed, clOrange, clYellow, clGreen, clBlue];
    const strColours: array[0..4] of string = ['Red', 'Orange', 'Yellow', 'Green', 'Blue'];
    rbSmall, rbMedium, rbLarge: TW3RadioButton;
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
  end;

implementation

procedure TForm1.InitializeForm;
begin
  inherited;
  rbSmall := new TW3RadioButton(self);
  rbSmall.SetBounds(10, 230, 120, 50);
  rbSmall.Checked := False;
  rbSmall.Caption := 'Small text';
  rbSmall.OnClick := procedure(sender: TObject)
    begin
      W3Label1.Font.Size := 10;
      rbMedium.Checked := False;
      rbLarge.Checked := False;
    end;

  rbMedium := new TW3RadioButton(self);
  rbMedium.SetBounds(10, 260, 120, 50);
  rbMedium.Checked := False;
  rbMedium.Caption := 'Medium text';
  rbMedium.OnClick := procedure(sender: TObject)
    begin
      W3Label1.Font.Size := 14;
      rbSmall.Checked := False;
      rbLarge.Checked := False;
    end;

  rbLarge := new TW3RadioButton(self);
  rbLarge.SetBounds(10, 290, 120, 50);
  rbLarge.Checked := True;
  rbLarge.Caption := 'Large text';
  rbLarge.OnClick := procedure(sender: TObject)
    begin
      W3Label1.Font.Size := 18;
      rbSmall.Checked := False;
      rbMedium.Checked := False;
    end;
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
  W3Label1.Caption := 'Please select text colour and size.';
  W3Label1.Font.Color := clRed;
  W3Label1.Font.Size := 18;
  W3ListBox1.ItemClass := TW3Label;
  for var i := 1 to 5 do
    W3ListBox1.Add;
  W3ListBox1.Styles.SelectedColor := clLightBlue;
  W3ListBox1.SelectedIndex := 0;
  W3ListBox1.EnableAnimation := false;
  W3ListBox1.OnSelected := procedure (sender: TObject; idx: integer)
    begin
      W3Label1.Font.Color := Colours[idx];
    end;
  for var i := 0 to 4 do
    TW3Label(W3ListBox1.Items[i]).Caption:= strColours[i];
end;
 
initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.

Code of RadioButton Unit

{ **************************************************************************** }
{ Adapted from CheckBox in                                                     }
{                                                                              }
{ Smart Mobile Studio - Runtime Library                                        }
{                                                                              }
{ Copyright © 2012-2014 Optimale Systemer AS.                                  }
{                                                                              }
{ **************************************************************************** }

unit RadioButton;

interface

uses
  System.Types, SmartCL.System, SmartCL.Components, SmartCL.Controls.Label;

type
  TW3RadioCheckMark = class(TW3CustomControl)
  protected
    procedure setWidth(aValue: Integer); override;
    procedure setHeight(aValue: Integer); override;
    function makeElementTagObj: THandle; override;
    procedure StyleTagObject; override;
    function getChecked: Boolean; virtual;
    procedure setChecked(const aValue: Boolean); virtual;
  published
    property Checked: Boolean read getChecked write setChecked;
  end;

  TW3RadioButton = class(TW3CustomControl)
  private
    FLabel: TW3Label;
    FMark: TW3RadioCheckMark;
    procedure HandleLabelClick(Sender: TObject);
  protected
    function getCaption: String;
    procedure setCaption(aValue: String);
    function getChecked: Boolean;
    procedure setChecked(aValue: Boolean);
    function getEnabled: Boolean; override;
    procedure setEnabled(aValue: Boolean); override;
    procedure InitializeObject; override;
    procedure FinalizeObject; override;
    procedure Resize; override;
  public
    property Label: TW3Label read FLabel;
    property CheckMark: TW3RadioCheckMark read FMark;
  published
    property Caption: String read getCaption write setCaption;
    property Checked: Boolean read getChecked write setChecked;
  end;

implementation

{ **************************************************************************** }
{ TW3RadioCheckMark                                                            }
{ **************************************************************************** }

procedure TW3RadioCheckMark.setWidth(aValue: Integer);
begin
//
end;

procedure TW3RadioCheckMark.setHeight(aValue: Integer);
begin
//
end;

function TW3RadioCheckMark.getChecked: Boolean;
begin
  Result := w3_getPropertyAsBool(Handle, 'checked');
end;

procedure TW3RadioCheckMark.setChecked(const aValue: Boolean);
begin
  w3_setProperty(Handle, 'checked', aValue);
end;

function TW3RadioCheckMark.makeElementTagObj: THandle;
begin
  Result := w3_createHtmlElement('input');
end;

procedure TW3RadioCheckMark.StyleTagObject;
begin
  inherited;
  w3_setProperty(Handle, 'type', 'radio');
end;

{ **************************************************************************** }
{ TW3RadioButton                                                               }
{ **************************************************************************** }

procedure TW3RadioButton.InitializeObject;
begin
  inherited;
  FLabel := TW3Label.Create(Self);
  FMark := TW3RadioCheckMark.Create(Self);
  FLabel.Caption := 'Radio Button';
  FLabel.Container.OnClick := HandleLabelClick;
end;

procedure TW3RadioButton.FinalizeObject;
begin
  FMark.Free;
  FLabel.Free;
  inherited;
end;

function TW3RadioButton.getEnabled: Boolean;
begin
  Result := FMark.Enabled;
end;

procedure TW3RadioButton.HandleLabelClick(Sender: TObject);
begin
  if FLabel.Enabled then
    if not Checked then
      setChecked(true);
end;

function TW3RadioButton.getChecked: Boolean;
begin
  Result := FMark.Checked;
end;

procedure TW3RadioButton.setChecked(aValue: Boolean);
begin
  FMark.Checked := aValue;
end;

procedure TW3RadioButton.setEnabled(aValue: Boolean);
begin
  FMark.Enabled := aValue;
  FLabel.Enabled := aValue;
end;

function TW3RadioButton.getCaption: String;
begin
  Result := FLabel.Caption;
end;

procedure TW3RadioButton.setCaption(aValue: String);
begin
  FLabel.Caption := aValue;
end;

procedure TW3RadioButton.Resize;
var
  dx, dy: Integer;
begin
  inherited;

  dy := (ClientHeight div 2) - (FMark.Height div 2);
  FMark.MoveTo(0,dy);

  dx := FMark.Left + FMark.Width + 1;

  FLabel.SetBounds(dx, 0, ClientWidth - dx, ClientHeight);
end;

end.

XML Code of Form

<SMART>
  <Form version="2" subversion="1">
    <Created>2014-10-23T20:06:13.174</Created>
    <Modified>2014-10-24T11:12:26.382</Modified>
    <object type="TW3Form">
      <Caption>W3Form</Caption>
      <Name>Form1</Name>
      <object type="TW3Label">
        <Caption>W3Label</Caption>
        <Width>296</Width>
        <Left>8</Left>
        <Height>48</Height>
        <Name>W3Label1</Name>
      </object>
      <object type="TW3ListBox">
        <Width>296</Width>
        <Top>48</Top>
        <Left>8</Left>
        <Height>176</Height>
        <Name>W3ListBox1</Name>
      </object>
    </object>
  </Form>
</SMART>
Programming - a skill for life!

How to use a range of visual components such as edit boxes, combo boxes, grids and charts on one or multiple forms (including a modal form)