Knowledge Base Alert October, 2016







TMS VCL Chart:

Using the new Popup ToolBar



The chart supports displaying a helper popup toolbar that offers various functionality such as changing the series type, fill and line color as well a specifying the marker type and label visibility.

To enable the popup, set Popup.Enabled := True;

AdvChartView1.Popup.Enabled := True;

When clicking on a series point, slice, or bar depending on the chosen series type the popup will be shown and initialized based on the current settings of the series.


The popup options can be configured via the Popup.Options property. This allows you to show more or less dropdown pickers depending on the series configuration. Below is a sample that demonstrates displaying the full set of options versus a limited set with line color, type and width.

AdvChartView1.Popup.Options := AllOptions;


AdvChartView1.Popup.Options := [ctpoStroke, ctpoLineStyle, ctpoLineWidth];



TAdvStringGrid:

Image drag & drop



Here you can download a demo that shows how you can
  • Drag and drop of an image from one TAdvStringGrid to another TAdvStringGrid
  • Drag and drop of an image from Windows Explorer to TAdvStringGrid

TAdvOfficeHint:

Toggle between TMS Office hints and regular hints



You can easily toggle in the application between using TMS Office hints and regular hints via the code:

begin
  if NormalHints.Checked then
    HintWindowClass := THintWindow
  else
    HintWindowClass := TAdvOfficeHintWindow;
end;


TAdvCheckedTreeView:

Modifying the appearance of the TAdvCheckedTreeView with custom node indicators



Example:

procedure TForm1.FormCreate(Sender: TObject);
var
  pn, n: TAdvTreeViewNode;
  I: Integer;
begin
  AdvCheckedTreeView1.BeginUpdate;
  AdvCheckedTreeView1.ClearNodes;
  AdvCheckedTreeView1.ClearColumns;
  AdvCheckedTreeView1.Columns.Add.Text := '';
  AdvCheckedTreeView1.ColumnsAppearance.Layouts := [];
  AdvCheckedTreeView1.NodesAppearance.ShowLines := False;
  AdvCheckedTreeView1.NodesAppearance.LevelIndent := 0;
  AdvCheckedTreeView1.Color := RGB(51, 51, 51);
  AdvCheckedTreeView1.NodesAppearance.FontColor := clWhite;
  pn := AdvCheckedTreeView1.Nodes.Add;
  pn.Text[0] := 'Audi';
  n := pn.Nodes.Add;
  n.Text[0] := 'A3';
  n.CheckTypes[0] := tvntCheckBox;
  n := pn.Nodes.Add;
  n.Text[0] := 'A5';
  n.CheckTypes[0] := tvntCheckBox;
  n := pn.Nodes.Add;
  n.Text[0] := 'R8 Spyder';
  n.CheckTypes[0] := tvntCheckBox;
  pn := AdvCheckedTreeView1.Nodes.Add;
  pn.Text[0] := 'Mercedes';
  n := pn.Nodes.Add;
  n.Text[0] := 'SLS';
  n.CheckTypes[0] := tvntCheckBox;
  n := pn.Nodes.Add;
  n.Text[0] := 'SLK';
  n.CheckTypes[0] := tvntCheckBox;
  n := pn.Nodes.Add;
  n.Text[0] := 'Maybach';
  n.CheckTypes[0] := tvntCheckBox;
  n := pn.Nodes.Add;
  n.Text[0] := 'Sports Tourer';
  n.CheckTypes[0] := tvntCheckBox;
  n := pn.Nodes.Add;
  n.Text[0] := 'Electric Drive';
  n.CheckTypes[0] := tvntCheckBox;
  n := pn.Nodes.Add;
  n.Text[0] := 'Coupé';
  n.CheckTypes[0] := tvntCheckBox;
  AdvCheckedTreeView1.NodesAppearance.ExpandNodeIcon.LoadFromFile('ExpandIcon.png');
  AdvCheckedTreeView1.NodesAppearance.CollapseNodeIcon.LoadFromFile('CollapseIcon.png');
  AdvCheckedTreeView1.NodesAppearance.ExpandWidth := 16;
  AdvCheckedTreeView1.NodesAppearance.ExpandHeight := 16;
  AdvCheckedTreeView1.EndUpdate;
  AdvCheckedTreeView1.ExpandAll;
end;


TMSFNCGridDatabaseAdapter:

Programmatically setup a FireDac database connection via the new TTMSFNCGridDatabaseAdapter



Example:

uses
  DateUtils, Math, DB, FireDac.Comp.Client, FMX.TMSFNCGridDatabaseAdapter, FMX.TMSFNCGrid;

procedure TForm1.FormCreate(Sender: TObject);
const
  DBName = 'Sample.sdb';
  FirstNames: array[0 .. 19] of string = ('John', 'Sarah', 'Fred', 'Beth',
    'Eric', 'Tina', 'Thomas', 'Judy', 'Robert', 'Angela', 'Tim', 'Traci',
    'David', 'Paula', 'Bruce', 'Jessica', 'Richard', 'Carla', 'James',
    'Mary');
  LastNames: array[0 .. 11] of string = ('Parker', 'Johnson', 'Jones',
    'Thompson', 'Smith', 'Baker', 'Wallace', 'Harper', 'Parson', 'Edwards',
    'Mandel', 'Stone');
var
  idx: Integer;
  ds: TDataSource;
  tbl: TFDMemTable;
  adapter: TTMSFNCGridDatabaseAdapter;
  g: TTMSFNCGrid;
begin
  g := TTMSFNCGrid.Create(Self);
  g.Parent := Self;

  tbl := TFDMemTable.Create(Self);
  tbl.FieldDefs.Add('ID', ftInteger, 0, True);
  tbl.FieldDefs.Add('Name', ftString, 20, True);
  tbl.FieldDefs.Add('Birthday', ftDateTime, 0, True);
  tbl.FieldDefs.Add('Salary', ftCurrency, 0, True);
  tbl.Open;
  tbl.DisableControls;
  try
   tbl.EmptyDataSet;
   for idx := 0 to 99999 do
   begin
     tbl.Append;
     tbl.FieldByName('ID').AsInteger := idx;
     tbl.FieldByName('Name').AsString := FirstNames[Random(20)] + ' ' + LastNames[Random(12)];
     tbl.FieldByName('Birthday').AsDateTime := IncDay(Now,  RandomRange(-10000, 10000));
     tbl.FieldByName('Salary').AsFloat := 20000.0 + Random(600) * 100;
     tbl.Post;
   end;
   tbl.First;
  finally
   tbl.EnableControls;
  end;
  tbl.Active := True;
  ds := TDataSource.Create(nil);
  ds.DataSet := tbl;

  adapter := TTMSFNCGridDatabaseAdapter.Create(Self);
  g.Adapter := adapter;
  adapter.Grid := g;
  adapter.DataSource := ds;
  adapter.Active := True;
end;


TMSFNCHint:

Enable HTML formatted hints in your FMX/VCL or LCL application



Drop an instance of TTMSFNCHint on the form, set ShowHint to true on your component and set a Hint property. The hint can be HTML formatted based on the miniHTML reference.


TMSFMXTableView:

Having a list of back and forth messages similar to iMessage



The best matching control for this purpose is the TTMSFMXTableView which is capable of fully customizing the appearance of the items. The following sample is based on a default TTMSFMXTableView:

procedure TForm1.FormCreate(Sender: TObject);
var
  it: TTMSFMXTableViewItem;
  I: Integer;
begin
  TMSFMXTableView1.BeginUpdate;
  TMSFMXTableView1.HeaderText := 'Conversation between Matt and John';
  TMSFMXTableView1.Items.Clear;
  TMSFMXTableView1.LayoutMode := lmGroup;
  TMSFMXTableView1.FooterVisible := False;
  it := TMSFMXTableView1.Items.Add;
  it.Caption := 'Matt';
  it.Description := 'Hi John, when does the game begin?';

  it := TMSFMXTableView1.Items.Add;
  it.Caption := 'John';
  it.Description := 'Hi Matt, the game begins at 7:30 pm!';

  it := TMSFMXTableView1.Items.Add;
  it.Caption := 'Matt';
  it.Description := 'Thanks, are you going alone there or with a friend?';

  it := TMSFMXTableView1.Items.Add;
  it.Caption := 'John';
  it.Description := 'We are travelling with a couple of friends'+#13#10+'If you want, you may join us at 7:00 pm at the parking lot';

  it := TMSFMXTableView1.Items.Add;
  it.Caption := 'Matt';
  it.Description := 'Ok, I will be there';

  it := TMSFMXTableView1.Items.Add;
  it.Caption := 'John';
  it.Description := 'See you at the parking lot then !';

  it := TMSFMXTableView1.Items.Add;
  it.Caption := 'John';
  it.Description := 'Oh, and do not forget your tickets';

  for I := 0 to TMSFMXTableView1.Items.Count - 1 do
  begin
    TMSFMXTableView1.Items[I].GroupIndex := I;
    TMSFMXTableView1.Items[I].AutoSize := True;
    TMSFMXTableView1.Items[I].DataString := TMSFMXTableView1.Items[I].Caption;
  end;

  TMSFMXTableView1.EndUpdate;
end;

procedure TForm1.TMSFMXTableView1ApplyStyleLookup(Sender: TObject);
begin
  TMSFMXTableView1.GetHeaderRectangle.Fill.Color := claWhite;
  TMSFMXTableView1.GetHeaderRectangle.Fill.Kind := TBrushKind.Solid;
  (TMSFMXTableView1.GetListBackGround as TRectangle).Fill.Color := claWhite;
  (TMSFMXTableView1.GetListBackGround as TRectangle).Fill.Kind := TBrushKind.Solid;
end;

procedure TForm1.TMSFMXTableView1ItemCustomize(Sender: TObject;
  AItem: TTMSFMXTableViewItem; AItemShape: TTMSFMXTableViewItemShape;
  AItemControlShape: TControl);
begin
  if AItem.DataString = 'John' then
  begin
    AItemShape.Fill.Color := claSkyblue;
    AItemShape.Stroke.Color := claBlue;
    AItemShape.Margins.Left := 150;
    AItemShape.CaptionColor := claBlue;
  end
  else if AItem.DataString = 'Matt' then
  begin
    AItemShape.Fill.Color := claYellowgreen;
    AItemShape.Stroke.Color := claGreen;
    AItemShape.Margins.Right := 150;
    AItemShape.CaptionColor := claGreen;
  end;

  AItemShape.DescriptionColor := claWhite;
end;



TMSFMXWebGMaps:

How to redraw all the markers



There are two possible techniques:
  1. Clear all markers from the Markers collection and add the markers again so they also show on the map.
  2. Iterate the Markers collection and call CreateMapMarker for each Marker to show it on the map.
Please note that it is required to wait until after the OnMapTilesLoad event has been triggered to add the markers.

Example 1:

procedure TForm2.Button1Click(Sender: TObject); begin
  TMSFMXWebGMaps1.Visible := not TMSFMXWebGMaps1.Visible;

  if TMSFMXWebGMaps1.Visible then
    MapIsVisible := true;
end;

procedure TForm2.FormCreate(Sender: TObject); begin
  InitMarkers;
end;

procedure TForm2.InitMarkers;
begin
  TMSFMXWebGMaps1.Markers.Clear;
  TMSFMXWebGMaps1.Markers.Add(48.8, 2);
  TMSFMXWebGMaps1.Markers.Add(48.7, 2);
end;

procedure TForm2.TMSFMXWebGMaps1MapTilesLoad(Sender: TObject); var
  I: Integer;
begin
  if MapIsVisible then
  begin
    MapIsVisible := false;
    InitMarkers;
  end;
end;
Example 2:

procedure TForm2.Button1Click(Sender: TObject); begin
  TMSFMXWebGMaps1.Visible := not TMSFMXWebGMaps1.Visible;

  if TMSFMXWebGMaps1.Visible then
    MapIsVisible := true;
end;

procedure TForm2.FormCreate(Sender: TObject); begin
  InitMarkers;
end;

procedure TForm2.InitMarkers;
begin
  TMSFMXWebGMaps1.Markers.Clear;
  TMSFMXWebGMaps1.Markers.Add(48.8, 2);
  TMSFMXWebGMaps1.Markers.Add(48.7, 2);
end;

procedure TForm2.TMSFMXWebGMaps1MapTilesLoad(Sender: TObject); var
  I: Integer;
begin
  if MapIsVisible then
  begin
    MapIsVisible := false;
    for I := 0 to TMSFMXWebGMaps1.Markers.Count - 1 do
      TMSFMXWebGMaps1.CreateMapMarker(TMSFMXWebGMaps1.Markers[I]);
  end;
end;

TMSFMXWebGMaps:

Using the TLocationSensor with ReverseGeocoding on Android



When using the TLocationSensor and you wish to do a reverse geocoding call from the OnLocationChanged event on Android, you always have to use a TThread.Queue around your code to avoid network exceptions ( for example: "Project ABC.apk raised exception class EJNIException with message 'android.os.NetworkOnMainThreadException'").

Example:

procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
begin
  TThread.Queue(nil,
  procedure
  var
    cp: String;
  begin
    TMSFMXWebGMapsReverseGeocoding1.Latitude := NewLocation.Latitude;
    TMSFMXWebGMapsReverseGeocoding1.Longitude := NewLocation.Longitude;
    TMSFMXWebGMapsReverseGeocoding1.LaunchReverseGeocoding;
    cp := TMSFMXWebGMapsReverseGeocoding1.ResultAddress.PostalCode;
  end
  );
end;

TIWResponsiveList:

How to use the ItemStyle parameter of the OnItemRender event



You can use the ItemStyle parameter of the OnItemRender event in the same way as the ItemStyle property of a list item. First add an item to the ItemStyles collection then use its name to apply the style to a specific list item.

Example to use a red font color for the first item in the list:

var
  si: TIWItemStylesItem;
begin
  si := TIWResponsiveList1.ItemStyles.Add;
  si.ItemStyle.Font.Color := clWebRed;
  si.Name := 'RedFont';

procedure TformResponsiveList1.TIWResponsiveList1ItemRender(Sender: TObject;
  Index: Integer; var ItemStyle: string); begin
  if Index = 0 then
    ItemStyle := 'RedFont';
end;


As always, we thank all users for the numerous inputs, feedback, comments and suggestions. This is an invaluable help to steer our developments here at TMS software. We continue to look forward to all your further communications to direct our team to provide you better tools and components for your needs.

Kind regards,
TMS software team
Email: info@tmssoftware.com
Web: http://www.tmssoftware.com
Support, FAQ & Manuals: http://www.tmssoftware.com/site/support.asp


Follow latest developments at tmssoftware.com




NOTICE: If you wish to unsubscribe from the TMS software Newsletter, please click here.