Categories
Delphi Projects News

The First Computer Program – In Delphi

Lady Ada Lovelace using a modern day laptop
Charles Babbage

Lady Ada Lovelace is generally considered the world’s first computer programmer. Born Augusta Ada Byron, in 1815, she was the daughter of Lord Byron, the English romantic poet. She took an interest in mathematics and her talents lead her to work with Charles Babbage, “the father of computers,” whom she met in 1833.

Babbage started work on his Difference Engine, as a means to automatically calculate and print the values of polynomial functions. While he never saw his Difference Engine completed, two were finished in modern times based on his original designs. One of which is in the Computer History Museum in Silicon Valley, where I saw it in operation.

In 1837 Babbage first described his Analytical Engine, as a general-purpose computer. In 1843, Lovelace translated a French paper that Italian mathematician Luigi Menabrea wrote about Charles Babbage’s Analytical Engine. While translating it she added thousands of words of her own notes to the paper. As an example she wrote of one such sequence—how to calculate Bernoulli numbers. This is regarded by computer historians as the first computer program.

Lovelace's diagram from "note G", the first published computer algorithm https://commons.wikimedia.org/wiki/File:Diagram_for_the_computation_of_Bernoulli_numbers.jpg

Two Bit History has a great write up on Lovelace’s program: What Did Ada Lovelace’s Program Actually Do? which includes a C translation and a solution for the bug it included.

Naturally I wanted to see what her code would look like in Delphi’s Object Pascal.

program LovelaceBernoulli;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

function B7: extended;
(*
 * Calculates what Lady Ada Lovelace labeled "B7", 
 * which today we would call the 8th Bernoulli number.
 * Based on  https://gist.github.com/sinclairtarget/ad18ac65d277e453da5f479d6ccfc20e
 * More info https://twobithistory.org/2018/08/18/ada-lovelace-note-g.html
 * Bernoulli Numbers: https://en.wikipedia.org/wiki/Bernoulli_number
 *)
begin
    // ------------------------------------------------------------------------
    // Data
    // ------------------------------------------------------------------------
    var v1: Single := 1; // 1
    var v2: Single := 2; // 2
    var v3: Single := 4; // n

    // ------------------------------------------------------------------------
    // Working Variables
    // ------------------------------------------------------------------------
    var v4: Single := 0;
    var v5: Single := 0;
    var v6: Single := 0;                        // Factors in the numerator
    var v7: Single := 0;                        // Factors in the denominator
    var v8: Single := 0;
    var v10: Single := 0;                       // Terms remaining count, basically
    var v11: Single := 0;                       // Accumulates v6 / v7
    var v12: Single := 0;                       // Stores most recent calculated term
    var v13: Single := 0;                       // Accumulates the whole result

    // ------------------------------------------------------------------------
    // Result Variables
    // ------------------------------------------------------------------------
    var v21: Single := 1.0 / 6.0;             // B1
    var v22: Single := -1.0 / 30.0;           // B3
    var v23: Single := 1.0 / 42.0;            // B5
    var v24: Single := 0;                     // B7, not yet calculated

    // ------------------------------------------------------------------------
    // Calculation
    // ------------------------------------------------------------------------
    // ------- A0 -------
    (* 01 *) v6 := v2 * v3;                // 2n
    (* 02 *) v4 := v6 - v1;                // 2n - 1
    (* 03 *) v5 := v6 + v1;                // 2n + 1

    // In Lovelace's diagram, the below appears as v5 / v4, which is incorrect.
    (* 04 *) v11 := v4 / v5;               // (2n - 1) / (2n + 1)

    (* 05 *) v11 := v11 / v2;              // (1 / 2) * ((2n - 1) / (2n + 1))
    (* 06 *) v13 := v13 - v11;             // -(1 / 2) * ((2n - 1) / (2n + 1))
    (* 07 *) v10 := v3 - v1;               // (n - 1), set counter?

    // A0 = -(1 / 2) * ((2n - 1) / (2n + 1))

    // ------- B1A1 -------
    (* 08 *) v7 := v2 + v7;                // 2 + 0, basically a MOV instruction
    (* 09 *) v11 := v6 / v7;               // 2n / 2
    (* 10 *) v12 := v21 * v11;             // B1 * (2n / 2)

    // A1 = (2n / 2)
    // B1A1 = B1 * (2n / 2)

    // ------- A0 + B1A1 -------
    (* 11 *) v13 := v12 + v13;            // A0 + B1A1
    (* 12 *) v10 := v10 - v1;             // (n - 2)

    // On the first loop this calculates B3A3 and adds it on to v13.
    // On the second loop this calculates B5A5 and adds it on.
    while (v10 > 0) do
    begin
        // ------- B3A3, B5A5 -------
        while (v6 > 2 * v3 - (2 * (v3 - v10) - 2)) do
        begin                                // First Loop:
            (* 13 *) v6 := v6 - v1;           // 2n - 1
            (* 14 *) v7 := v1 + v7;           // 2 + 1
            (* 15 *) v8 := v6 / v7;           // (2n - 1) / 3
            (* 16 *) v11 := v8 * v11;         // (2n / 2) * ((2n - 1) / 3)

                                             // Second Loop:
            // 17    v6 := v6 - v1;              2n - 2
            // 18    v7 := v1 + v7;              3 + 1
            // 19    v8 := v6 / v7;              (2n - 2) / 4
            // 20    v11 := v8 * v11;            (2n / 2) * ((2n - 1) / 3) * ((2n - 2) / 4)
        end;

        // A better way to do this might be to use an array for all of the
        // "Working Variables" and then index into it based on some calculated
        // index. Lovelace might have intended v14-v20 to be used on the
        // second iteration of this loop.
        //
        // Lovelace's program only has the version of the below line using v22
        // in the multiplication.
        if (v10 = 2) then
        (* 21 *) v12 := v22 * v11             // B3 * A3
        else
        (* 21 *) v12 := v23 * v11;            // B5 * A5

        // B3A3 = B3 * (2n / 2) * ((2n - 1) / 3) * ((2n - 2) / 4)

        // ------- A0 + B1A1 + B3A3, A0 + B1A1 + B3A3 + B5A5 -------
        (* 22 *) v13 := v12 + v13;            // A0 + B1A1 + B3A3 (+ B5A5)
        (* 23 *) v10 := v10 - v1;             // (n - 3), (n - 4)
    end;

    (* 24 *) v24 := v13 + v24; // Store the final result in v24
    (* 25 *) v3 := v1 + v3;    // Move on to the next Bernoulli number!

    // This outputs a positive number, but really the answer should be
    // negative. There is some hand-waving in Lovelace's notes about the
    // Analytical Engine sorting out the proper sign.
    Result := v24;
end;

begin
  try
    Writeln('Calculates what Ada Lovelace labeled "B7", which today we would call the 8th Bernoulli number.');
    Writeln('--------------');
    Writeln('This outputs a positive number, but really the answer should be negative.');
    Writeln('There is some hand-waving in Lovelace''s notes about the Analytical Engine sorting out the proper sign.');
    Writeln('==============');
    Writeln(Format('A0 + B1A1 + B3A3 + B5A5: %.4f',[B7]));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Writeln('--------------');
  Writeln('Press [enter] to close');
  readln;
end.

While this is one way to calculate the 8th Bernoulli number, what would a modern implementation look like? Using Rudy’s Big Numbers library I created a sample application to calculate any Bernoulli number.

function Bernoulli(n: Uint64): BigRational;
begin
  var a: TArray<BigRational>;
  SetLength(a, n + 1);
  for var m := 0 to High(a) do
  begin
    a[m] := BigRational.Create(1, m + 1);
    for var j := m downto 1 do
    begin
      a[j - 1] := (a[j - 1] - a[j]) * j;
    end;
  end;
  Result := a[0];
end;

You can install the BigNumbers library via GetIt and this sample application is included.

Categories
News

13 Reasons NOT to use Delphi

Over the years I’ve heard a lot of reasons or excuses people don’t use Delphi. I’ve collected the thirteen best reasons here.

1. Want to Write More Code – Delphi requires less code to accomplish the same task. If you want to write more code, don’t use Delphi. Especially helpful if writing more code gives you more sense of accomplishment, or you are paid based on lines of code written.

Number, 2, Digit, Figure, Cipher, Count, Numerary, Red

2. Larger Developer Teams – Who doesn’t love having lots of co-workers? If you use other tools and frameworks then you will need more developers, more developer tools, more frameworks, and more teams to support all the platforms. Makes for better office parties. Unfortunately, when you use Delphi you only need to write the app once for all the platforms, so one team and one code base for all the platforms. With Delphi, you just can’t justify hiring all those extra developers!

3. Like Fixing Bugs – All that code you had to write to implement the features on each platform? More code means more bugs! And more bugs means more job security for you and that huge team of testers. Gotta love bugs! Heck, you can even name some and keep them as pets! You know they will be around for a while.

4. More Meetings – Since each platform has its own code and own team you need more meetings to coordinate. You don’t want features to get out of sync between platforms! And then another round of meetings to coordinate bug fixes for each platform. Everyone knows meetings have the best snacks! Since Delphi lets you support all the platforms from one codebase then you can’t have all those planning meetings!

5. More Documentation – Each platform has a completely different app (despite all the meetings to keep them in sync) so now you need completely different documentation for each platform. We know how much you love writing code, so clearly you love writing end-user documentation too!

6. Larger Support Department – Each platform has its own version so you need to talk to a support tech that knows that version of the app. Who wants an Android version that behaves similar to the iOS version? Not to mention the desktop versions! 

7. Longer Compile Times – If it isn’t weren’t for long compiles developers would never get a break from their desk. We all know Delphi compiles super fast, which means you have less time to slack off.

'Are you stealing those LCDs?' 'Yeah, but I'm doing it while my code compiles.'
‘Are you stealing those LCDs?’ ‘Yeah, but I’m doing it while my code compiles.’
If Delphi can compile 1 million lines that quick, when will you slack off?

8. Slower Execution – If your executable runs slower the user feels safer and pretends that a lot of stuff is going on in the background. With Delphi’s native execution speed your programs are fast, so your users won’t believe it is doing anything. 

9. Separated Runtime – If your program depends on an external runtime library instead of having one executable on Windows, you can blame the runtime for any bugs. All those support calls just result in telling them to update or rollback the runtime libraries. You’ll be able to convince them it is all their fault that the program doesn’t work!

10. Putting Memory to Use – Great apps should use at least a full GB of memory just like small Electron utilities do. The great thing about Electron is it includes all of the Chrome browser features like Xbox 360 controller support. Why only use a few megabytes of memory for the same simple app? The more memory the better app. Electron puts all those CPU cores to use too!

11. In Deep Love With “DLL Hell” – You love sending your customer a dozen DLLs along with your EXE and you are having so much fun to debug over the phone, which DLL is not up-to-date and makes your app fail. Closely related to #9, but worth mentioning twice!

12. Unexpected Garbage Collection Pauses – Deterministic execution is boring! What fun is it to have your program behave the same every time it runs. Delphi doesn’t have any of those unexpected garbage collection pauses to mix things up. It gives you deterministic memory management either through ref-counting, an ownership / auto-free model, or whatever level of control you want. Why control when the memory is free when you can just wait for the garbage collector?

13. Would Rather “Re-Invent the Wheel” – Delphi comes with so many useful components and libraries and has a rich 3rd party ecosystem. This means there is usually some reusable code for any task you need. That means less opportunity to create something new.

Just in case it wasn’t obvious: This is a sarcastic list of bad reasons not to use Delphi. The reality is all the excuses are just reasons to use Delphi.

Carlos translated my post to Portuguese.

Categories
News

Integrating OBS Studio with X-Keys XK-24 USB Keypad

Short demo and introduction

I was a guest on X-Keys 5 Minute Friday showing off an integration between OBS Studio with the X-Keys XK-24 USB Keypad. I created a script that assigns F13 through F24 with and without the CTRL modifiers to the XK-24. You can simply assign these in the OBS hotkey settings and it will respond to those globally.

Here is the MW3(VB) script you can load into MacroWorks obs-xk-24.mw3

For some reason the F24 and CTRL+F24 didn’t work. I’m not sure if that is an OBS issue or where the cause originates. This would allow you to use your XK-24 with any software that that allows you to assign F13-F24 and recognizes global hotkeys.

Categories
Android devices News Source Code

WebBroker on Android and Raspberry Pi 3

I covered this previously in a few webinars and presentations, but never published the source code for WebBroker on Android. To be honest I hadn’t tested it with C++Builder before, but I completely expected it to work, and it did. I also updated the tests on Emteria.OS (FKA RTAndroid) and it also works there.

The process of porting a Delphi or C++Builder WebBroker project to Android is pretty straight forward, but I’m publishing the code anyway. You create a Windows FMX WebBroker project, then copy all the code into a regular FireMonkey project. You will need to copy a few files from the RTL folder locally so you can reference them since they aren’t included in the Android package.

  • Web.WebReq.pas
  • Web.WebBroker.pas
  • Web.WebConst.pas
  • IdHTTPWebBrokerBridge.pas
  • IdCompilerDefines.inc
  • For C++Builder you also need
    • Web.WebReq.hpp
    • Web.WebBroker.hpp
    • Web.WebConst.hpp
    • IdHTTPWebBrokerBridge.hpp

Here are the links for the Delphi and C++Builder projects. They were built and tested in with 10.3.1 Rio. I also compiled some updated details on how to build the project and how to install and test on Emteria.OS.

I mention this in the slide deck, but officially WebBroker isn’t supported on Android. I tested it, and it seems to work, but if you run into an instance where it doesn’t work as expected, then you are on your own. Please don’t contact support and tell them I said it should work. Thanks!

Previous webinars:

Delphi and C++Builder on Raspberry Pi and SBC

Slides

Revisiting Raspberry Pi, Android and the SBC

Slides

See also: Targeting Chrome OS with Delphi via Android and Linux

Categories
News

Animated Path Graphics of Grace Hopper

I wanted to finish this side project during Women’s History Month to honor the Amazing Grace Hopper and her contributions to the field of Computer Science. I found this interesting SVG of Grace Hopper that wanted to figure out how to render in Delphi using the FireMonkey TPath, but it also looked like it should be animated somehow . . . .

Grace Hopper illustration by gingercoons

I’ve rendered some simple SVG graphics with the TPath component before, but this one was more complicated. It has multiple colors and variable opacity. This requires multiple TPath instances to handle each variation. It was a simple matter of loading in the SVG file using an IXMLDocument, then parsing the elements, and creating a TPath for each one. For fun I included a variable sleep between each draw. Also, to make sure all the paths have the same relative size I added a couple MoveTo calls to define the client area.

var
  XmlSvg: IXMLDocument;
  val: String;
  vals: TArray<String>;
  node: IXMLNode;
  path: TPath;
begin
  tabControl.ActiveTab := TabItem2;
  // This removes the encoded carriage returns
  XmlSvg := LoadXMLData(StringReplace(memo1.Text, '&#xA;', '', [rfReplaceAll]));
  if XmlSvg.DocumentElement.HasAttribute('viewBox') then
  begin
    val := XmlSvg.DocumentElement.Attributes['viewBox'];
    vals := val.Split([' ']);
    SVGLayout.Width := vals[2].ToInteger - vals[0].ToInteger;
    SVGLayout.Height := vals[3].ToInteger - vals[1].ToInteger;
  end;
  for var idx := 0 to XmlSvg.DocumentElement.ChildNodes.Count - 1 do
  begin
    node := XmlSvg.DocumentElement.ChildNodes[idx];
    if (node.NodeName = 'path') and (node.HasAttribute('d')) then
    begin
      path := TPath.Create(svgLayout);
      path.Parent := svgLayout;

      path.WrapMode := TPathWrapMode.Stretch;
      path.Align := TAlignLayout.Contents;

      path.Data.Data := node.Attributes['d'];
      path.Data.MoveTo(TPointF.Zero);
      path.Data.MoveTo(TPointF.Create(SVGLayout.Width, SVGLayout.Height));

      if node.HasAttribute('opacity') then
        path.Opacity := StrToFloat(node.Attributes['opacity']);
      if node.HasAttribute('fill') and (node.Attributes['fill'] <> 'none') and (node.Attributes['fill'] <> '') then
        path.Fill.Color := TAlphaColorRec.Alpha or StringToAlphaColor(node.Attributes['fill']);

    end;
    Sleep(Trunc(TrackBar1.Value));
    svgLayout.Repaint;
    Application.ProcessMessages;
  end;

This is by no means a complete implementation of the SVG standard, but it is getting closer! Close enough for some simple SVG images though, and possibly a useful basis for more complicated ones.

The animations was just a matter of assigning a TFloatAnimation to each TPath that adds some random movement. I included both slight scales and rotations. I could have done both on each, but was afraid that might be too much movement.

var
  dance: TFloatAnimation;
  path: TPath;
  I: Integer;
begin
  for I := 0 to pred(SVGLayout.ChildrenCount) do
  begin
    if SVGLayout.Children[I] is TPath then
    begin
      path := SVGLayout.Children[I] as TPath;
      dance := TFloatAnimation.Create(nil);
      dancers.Add(dance);
      dance.Parent := Path;
      dance.AutoReverse := True;
      dance.Loop := True;
      dance.StartFromCurrent := True;
      case random(4) of
        0: begin
            case random(2) of
              0: dance.PropertyName := 'Scale.X';
              1: dance.PropertyName := 'Scale.Y';
            end;
            case random(2) of
              0: dance.StopValue := 1.01;
              1: dance.StopValue := 0.99;
            end;
        end;
        1: begin
            case random(2) of
              0: begin
                dance.PropertyName := 'Position.X';
                case random(2) of
                  0: dance.StopValue := Path.Position.X - random - 0.01;
                  1: dance.StopValue := Path.Position.X + random + 0.01;
                end;
              end;
              1: begin
                dance.PropertyName := 'Position.Y';
                case random(2) of
                  0: dance.StopValue := Path.Position.Y - random - 0.01;
                  1: dance.StopValue := Path.Position.Y + random + 0.01;
                end;
              end;
            end;
        end;
        2..3: begin
          dance.PropertyName := 'RotationAngle';
          path.RotationCenter.X := random;
          path.RotationCenter.Y := random;
          case random(2) of
            0: dance.StopValue := random + 0.01;
            1: dance.StopValue := -1 * random - 0.01;
          end;
        end;
      end;
      dance.Enabled := True;
    end;
  end;

And we end up with something like this . . .. (Down scaled and lower FPS)

I’m posting my code if you want to play with it some more. The source SVG is embedded in a memo instead of reading it from a file. It was written with Delphi 10.3.1 Rio.

Categories
News

Delphi’s Big Day (with a little SVG fun!)

A lot going on today for Delphi. Celebrating 24 years as being our favorite development tool, and also got the 10.3.1 Rio release! I wanted to do something fun for today, but I keep getting all wrapped up with webinars and other things, so this is a bit last minute, but still fun I think . .. .

I’ve been playing with SVG and the TPath shape component. If you are not familiar with SVG it stands for Scalable Vector Graphic and is a vector graphic format based on XML. I’ve always liked SVG, and am glad that it is finally catching on (in Oct 2018 they recommended a candidate for SVG2!) TPath on the other hand is a FireMonkey shape component that complex draws 2D shapes. Turns out the Path Data used by TPath is compatible with SVG path data.

There are a few full blown SVG components [RiverSoftAVG, BVerhue, M. Walter’s, Ekot1, and probably more…] for Delphi, but for fun I’ve been experimenting with building my own: having Delphi read the SVG XML file, and then render it with shapes, layouts, paths, etc. Not sure if it will ever get to a usable state, but I thought I would share a little TPath fun with you.

Create a new FireMonkey application and copy and paste this component onto your form.

object HappyBirthdayDelphi: TPath
  Data.Path = {
    D6000000000000007DFFF9435CAF3943020000002556FA43C71B8D4302000000
    93A8CD4387F69D430200000068D1B043D172B2430200000042709643142EC543
    0200000004B67F432180DF43020000001F457A43F42DEA4302000000BAE97343
    3148DF4302000000A05A4B43FAAEC54302000000B85E124352F8B24302000000
    2731AF4250AD9F430200000083C02ABF6FA28D43020000006F12833BEEBC3A43
    020000005A649B3F9A992F410200000027B13943CF7716C202000000F6687A43
    54A3E34202000000B6139C43E3A5FCC1020000005463F9430AD7174102000000
    7DFFF9435CAF3943030000007DFFF9435CAF394300000000F2925343C510BB43
    02000000E3656043C510BB430200000052F86F4344FBBB4302000000DFAF8043
    42D0BD430100000039448543CB91B54301000000A03A8043D793AA4302000000
    4C77754358A9A94302000000D7636B431934A94302000000602563431934A943
    020000003B3F4C431934A943020000003F95484314DEAC43020000003F954843
    14DEAC4301000000CFD73A43C3E5BC43020000004A6C3F4344FBBB4302000000
    C1AA4743C510BB4302000000F2925343C510BB4303000000F2925343C510BB43
    0000000077FE4E4314DEAC4302000000E9E65A431709AB430200000096036743
    58B9AA4302000000D5386D4396F3AB4302000000DDE46543D793AA4302000000
    73A8524393C8AD430200000073A8524393C8AD430100000044EB4443C966B743
    0300000077FE4E4314DEAC4300000000B87E2F436FC29E4301000000E9260C43
    1BEFA2430200000019040E43F46DA5430200000000800F43F648A74302000000
    A09A10430080A8430200000081B511430AB7A9430200000093781343566EAB43
    020000005AE4154304A6AD430100000023BB3643CBE1A44303000000B87E2F43
    6FC29E430000000046B629439EBF954301000000BC14044389D1914302000000
    4C9704435E1A944302000000140E0543AAD1954302000000D57805438DF79643
    02000000D7E30543711D9843020000009AB9064373F89943020000001DFA0743
    73889C4301000000088C2D4348619C4302000000F8932C43BA099B4302000000
    04D62B43C3059A43020000002D522B431F5599430200000056CE2A439CA49843
    020000001F452A43D17297430200000046B629439EBF95430300000046B62943
    9EBF954300000000F8B327431FC58743010000007FEA04439CE4794302000000
    960304431273804302000000FE740343080C834302000000FA3E03430EBD8443
    02000000F6080343146E864302000000F60803438DD7884302000000FA3E0343
    79F98B43010000008F4228430060924302000000C1CA27436616904302000000
    968327431B5F8E4302000000CD6C2743FC398D430200000004562743FE148C43
    02000000916D274354438A4302000000F8B327431FC5874303000000F8B32743
    1FC5874300000000088C2D437FAA77430100000037291143FC89514302000000
    B6930E437969574302000000D5B80C43FEF45B430200000052980B430E2D5F43
    02000000CF770A43DD64624302000000B61309434220674302000000C76B0743
    775E6D4301000000BA892843854B85430200000027712943A2F5824302000000
    1B2F2A43353E81430200000096C32A43812580430200000052582B439A197E43
    02000000E3452C439A397B4302000000088C2D437FAA774303000000088C2D43
    7FAA774300000000B83E3E4389815D4301000000AA7131437B74244302000000
    58F92A4352182B4302000000353E26433D4A304302000000004023433D0A3443
    02000000CB412043FCC9374302000000088C1C43852B3D4302000000351E1843
    562E444301000000B87E2F438736734302000000E9663243CBE16D4302000000
    C5A0344339146A4302000000CD2C364391CD67430200000093B837432B876543
    0200000037693A435218624302000000B83E3E4389815D4303000000B83E3E43
    89815D4300000000BE3F5E436085474301000000B87E6A433FD5004302000000
    75F35E43F8D3054302000000F2525643B4E8094302000000EE9C5043F8130D43
    02000000E9E64A433B3F104302000000E5504443649B144302000000A0DA3C43
    73281A430100000019244243FE54594302000000587948436F32544302000000
    4A4C4D433994504302000000EE9C50435E7A4E430200000091ED534383604C43
    0200000058795843D90E4A4302000000BE3F5E436085474303000000BE3F5E43
    6085474300000000029B8243E365414301000000D9CE9543D94EF44202000000
    10289043AC9CF2420200000000C08B43713DF24202000000C9968843AA31F342
    02000000916D8543E325F44202000000FE3481435C8FF642020000005EDA7743
    146EFA420100000066A66443EEBC44430200000017796C4373E8424302000000
    2751724385CB414302000000D92E7643E3654143020000008B0C7A4383004143
    02000000D90E7F438300414302000000029B8243E365414303000000029B8243
    E36541430000000027C19543C9964D4301000000DD74B8437533134302000000
    AE77B443ECD10D4302000000B062B043F45D0943020000000436AC438DD70543
    020000005809A843275102430200000017B9A343CBE1FE42020000003F459F43
    146EFA4201000000273187434AEC42430200000033438943858B434302000000
    AEE78B43C500454302000000B81E8F43084C47430300000027C19543C9964D43
    00000000A02A9C4344FBBB430200000060B59B434626BA4302000000640B9843
    981EAA4302000000B4D88943440BA043020000007563894304969F4302000000
    DD8482430A179A430200000042A07E43CFF7954301000000CD8C74434EE29643
    010000002D429043D783C64302000000AA0193435899C5430200000060B59B43
    1D7AC14302000000A02A9C4344FBBB4303000000A02A9C4344FBBB4300000000
    B29DA743DD248943010000003709A3433B7F594301000000DDE46543982E8E43
    010000005AA468435238934303000000B29DA743DD2489430000000054236F43
    500D9543010000005EFA6543CFF79543010000006250624319448D4301000000
    5E0A9E4337295D4302000000E7CB95430A974D4302000000F4CD8A4354834343
    0200000060458043548343430200000075D351435483434302000000E15A2B43
    29FC694302000000E15A2B439A598C4302000000E15A2B430C42984302000000
    566E35431FB5A34302000000C3D54643567EAB4302000000C1AA4843981EAA43
    02000000BA294E43DBE9A64302000000DF0F6543DBE9A64302000000564E6D43
    DBE9A643020000004C7776431B5FA74302000000A0BA80439A49A84303000000
    54236F43500D954300000000C5004443DF3FA34302000000F83316439AB97743
    0200000060256343442B524302000000D5386D4348814E4302000000DF0F6443
    442B524302000000F2B21B4312237E43020000003D6A4A4321E0A14302000000
    C1AA4743A0CAA24302000000C50044431FB5A34302000000C5004443DF3FA343
    03000000C5004443DF3FA343}
  Fill.Color = xFFD18C8C
  Size.Width = 500.000000000000000000
  Size.Height = 500.000000000000000000
  Size.PlatformDefault = False
end

Or if you would rather just paste the path data into a new TPath component of your own you can do that too (just make sure it is square for the right aspect ratio and set the Fill color):

M 499.996 185.685 C 500.673 282.217 411.317 315.926 353.636 356.897 C 300.877 394.36 255.711 447.001 250.27 468.359 C 243.913 446.564 203.354 395.367 146.37 357.94 C 87.596 319.354 -0.667 283.269 0.004 186.738 C 1.214 10.975 185.692 -37.617 250.41 113.819 C 312.154 -31.581 498.776 9.49 499.996 185.685 Z M 211.574 374.131 C 224.398 374.131 239.97 375.963 257.374 379.627 L 266.533 363.139 L 256.458 341.155 C 245.466 339.323 235.39 338.407 227.146 338.407 C 204.247 338.407 200.583 345.735 200.583 345.735 L 186.843 377.795 C 191.423 375.963 199.667 374.131 211.574 374.131 Z M 206.994 345.735 C 218.902 342.071 231.014 341.448 237.222 343.903 C 229.894 341.155 210.658 347.567 210.658 347.567 L 196.919 366.803 Z M 175.495 317.519 L 140.152 325.868 C 142.016 330.859 143.5 334.57 144.604 337 
C 145.709 339.43 147.471 342.862 149.892 347.297 L 182.731 329.764 Z M 169.712 299.497 L 132.081 291.637 C 132.591 296.206 133.055 299.638 133.472 301.934 C 133.89 304.23 134.725 307.941 135.977 313.066 L 173.547 312.76 C 172.578 310.076 171.836 308.045 171.321 306.665 C 170.806 305.286 170.27 302.897 169.712 299.497 Z M 167.703 271.54 L 132.916 249.893 C 132.014 256.899 131.457 262.094 131.246 265.477 C 131.035 268.86 131.035 273.684 131.246 279.949 L 168.26 292.75 C 167.792 288.175 167.514 284.743 167.425 282.453 C 167.336 280.164 167.428 276.526 167.703 271.54 Z M 173.547 247.666 L 145.161 209.539 C 142.577 215.412 140.722 219.957 139.595 223.176 
C 138.468 226.394 137.077 231.126 135.421 237.369 L 168.538 266.59 C 169.442 261.919 170.184 258.486 170.764 256.293 C 171.345 254.1 172.273 251.225 173.547 247.666 Z M 190.245 221.506 L 177.444 164.455 C 170.974 171.095 166.243 176.29 163.25 180.04 C 160.257 183.789 156.547 189.17 152.118 196.181 L 175.495 243.213 C 178.402 237.882 180.628 234.079 182.175 231.803 C 183.721 229.528 186.411 226.095 190.245 221.506 Z M 222.249 199.521 L 234.495 128.833 C 222.951 133.828 214.324 137.909 208.613 141.078 C 202.902 144.247 196.316 148.607 188.854 154.158 L 194.141 217.332 C 200.474 212.197 205.298 208.579 208.613 206.478 C 211.928 204.377 216.474 202.058 222.249 199.521 Z M 261.211 193.398 L 299.616 122.154 C 288.313 121.306 279.5 121.12 273.178 121.597 C 266.856 122.074 258.414 123.28 247.853 125.215 L 228.65 196.738 C 236.473 194.908 242.317 193.795 246.183 193.398 C 250.049 193.002 255.058 193.002 261.211 193.398 Z M 299.509 205.589 L 368.913 147.201 C 360.935 141.82 352.771 137.367 344.422 133.842 
C 336.073 130.317 327.446 127.441 318.541 125.215 L 270.384 194.923 C 274.525 195.545 279.81 197.003 286.24 199.297 Z M 312.333 375.963 C 311.417 372.299 304.089 340.239 275.693 320.088 C 274.777 319.172 261.038 308.18 254.626 299.936 L 244.55 301.768 L 288.517 397.03 C 294.013 395.198 311.417 386.954 312.333 375.963 Z M 335.232 274.288 L 326.072 217.497 L 229.894 284.364 L 232.642 294.44 Z M 239.138 298.104 L 229.978 299.936 L 226.314 282.532 L 316.081 221.161 C 299.593 205.59 277.609 195.513 256.542 195.513 C 209.826 195.513 171.355 233.985 171.355 280.7 C 171.355 304.516 181.431 327.415 198.835 342.987 C 200.667 340.239 206.163 333.827 229.062 333.827 C 237.306 333.827 246.466 334.743 257.458 336.575 Z M 196.003 326.499 C 150.203 247.725 227.146 210.169 237.222 206.505 C 228.062 210.169 155.699 254.137 202.415 323.751 C 199.667 325.583 196.003 327.415 196.003 326.499 Z

If you are curious what the whole SVG file looks like, here it is:

<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
  <path id="Delphi" d="M 499.996 185.685 C 500.673 282.217 411.317 315.926 353.636 356.897 C 300.877 394.36 255.711 447.001 250.27 468.359 C 243.913 446.564 203.354 395.367 146.37 357.94 C 87.596 319.354 -0.667 283.269 0.004 186.738 C 1.214 10.975 185.692 -37.617 250.41 113.819 C 312.154 -31.581 498.776 9.49 499.996 185.685 Z M 211.574 374.131 C 224.398 374.131 239.97 375.963 257.374 379.627 L 266.533 363.139 L 256.458 341.155 C 245.466 339.323 235.39 338.407 227.146 338.407 C 204.247 338.407 200.583 345.735 200.583 345.735 L 186.843 377.795 C 191.423 375.963 199.667 374.131 211.574 374.131 Z M 206.994 345.735 C 218.902 342.071 231.014 341.448 237.222 343.903 C 229.894 341.155 210.658 347.567 210.658 347.567 L 196.919 366.803 
Z M 175.495 317.519 L 140.152 325.868 C 142.016 330.859 143.5 334.57 144.604 337 C 145.709 339.43 147.471 342.862 149.892 347.297 L 182.731 329.764 Z M 169.712 299.497 L 132.081 291.637 C 132.591 296.206 133.055 299.638 133.472 301.934 C 133.89 304.23 134.725 307.941 135.977 313.066 L 173.547 312.76 C 172.578 310.076 171.836 308.045 171.321 306.665 C 170.806 305.286 170.27 302.897 169.712 299.497 Z M 167.703 271.54 L 132.916 249.893 C 132.014 256.899 131.457 262.094 131.246 265.477 C 131.035 268.86 131.035 273.684 131.246 279.949 L 168.26 292.75 C 167.792 288.175 167.514 284.743 167.425 282.453 C 167.336 280.164 167.428 276.526 167.703 271.54 Z M 173.547 247.666 L 145.161 209.539 C 142.577 215.412 140.722 219.957 139.595 223.176 C 138.468 226.394 137.077 231.126 135.421 237.369 L 168.538 266.59 
C 169.442 261.919 170.184 258.486 170.764 256.293 C 171.345 254.1 172.273 251.225 173.547 247.666 Z M 190.245 221.506 L 177.444 164.455 C 170.974 171.095 166.243 176.29 163.25 180.04 C 160.257 183.789 156.547 189.17 152.118 196.181 L 175.495 243.213 C 178.402 237.882 180.628 234.079 182.175 231.803 C 183.721 229.528 186.411 226.095 190.245 221.506 Z M 222.249 199.521 L 234.495 128.833 C 222.951 133.828 214.324 137.909 208.613 141.078 C 202.902 144.247 196.316 148.607 188.854 154.158 L 194.141 217.332 C 200.474 212.197 205.298 208.579 208.613 206.478 C 211.928 204.377 216.474 202.058 222.249 199.521 Z M 261.211 193.398 L 299.616 122.154 C 288.313 121.306 279.5 121.12 273.178 121.597 C 266.856 122.074 258.414 123.28 247.853 125.215 L 228.65 196.738 C 236.473 194.908 242.317 193.795 246.183 193.398 C 250.049 193.002 255.058 193.002 261.211 193.398 Z M 299.509 205.589 L 368.913 147.201 C 360.935 141.82 352.771 137.367 344.422 133.842 
C 336.073 130.317 327.446 127.441 318.541 125.215 L 270.384 194.923 C 274.525 195.545 279.81 197.003 286.24 199.297 Z M 312.333 375.963 C 311.417 372.299 304.089 340.239 275.693 320.088 C 274.777 319.172 261.038 308.18 254.626 299.936 L 244.55 301.768 L 288.517 397.03 C 294.013 395.198 311.417 386.954 312.333 375.963 Z M 335.232 274.288 L 326.072 217.497 L 229.894 284.364 L 232.642 294.44 Z M 239.138 298.104 L 229.978 299.936 L 226.314 282.532 L 316.081 221.161 C 299.593 205.59 277.609 195.513 256.542 195.513 C 209.826 195.513 171.355 233.985 171.355 280.7 C 171.355 304.516 181.431 327.415 198.835 342.987 C 200.667 340.239 206.163 333.827 229.062 333.827 C 237.306 333.827 246.466 334.743 257.458 336.575 Z M 196.003 326.499 C 150.203 247.725 227.146 210.169 237.222 206.505 C 228.062 210.169 155.699 254.137 202.415 323.751 C 199.667 325.583 196.003 327.415 196.003 326.499 Z" fill="#d40000"/>
</svg>

And for those of you who are impatient, here is the output:

The path data rendered in Delphi with a TPath component 
(The strokes default to black, but you can tweak that)
Rendered in Delphi with a TPath component
(The strokes default to black, but you can tweak that)
The default SVG
And as an SVG

And since it is a vector graphic it will look great at any resolution, as long as you maintain a 1:1 aspect ratio.

What fun Delphi side projects are you working on? What did you do to celebrate the birthday of your favorite programming language?

Categories
10.3 Rio Android News webinar

Get the Most out of Android with 10.3 Rio

Today, I have a webinar on Getting the Most out of Android with 10.3 Rio. I want it to be a bit of a State of Android development today, as well as a What’s New in 10.3 Rio for Android. During CodeRage 2018 presented on what’s new in 10.3 Rio around Android. That session evolved into this webinar.

You can access the slides directly too.


Here is the Q&A log. I’ve gone back and typed answers to all the questions and included links too when possible. I may have edited some questions for length or clarity. The recording of the Q&A failed, and despite trying to recover it I wasn’t able to.

  • Question: what about Samsung Tizen os mobile? I think it’s different than Android OS
  • Answer:
    • When I worked for a large PC manufacturer, it was common for companies to tell Intel they were looking at AMD CPUs as a bargaining technique
    • Samsung mostly uses Tizen as a way to tell Google that they have options aren’t too attached to Android
    • Abandoning Android compatibility and ecosystem is dangerous
  • Question: and what about Android Intel processors or Android emulator with Intel Atom (x86)
  • Answer:
    • Intel’s Atom processors made a short appearance in Android devices 
    • They were x86 instead of ARM base 
    • Android 4.4 KitKat included libHoudini to provide ARM compatibility 
    • ARM compatibility was required because of widespread native NDK apps 
    • Most games include native NDK parts 
    • Discontinued for Android in 2016
  • Question: 8.1 Oreo not yet available for S8+
    • Answer: That is unfortunate, I thought it was. I recently read that Android 9.0 Pie is coming.
  • Question: In case I need an external Android library (jar file) included in my project, what should I do?
    • Answer: Check out the DocWiki for information. But you can add the JAR file in the Project Manager under Targets -> Android -> Libraries and then use Java2OP to create a JNI Bridge file. There is good information in the DocWiki
  • Question: Will there be the same webinar for iOS?
    • Answer: Maybe. I’m not as familiar with iOS, but I’ll see what I can do.
  • Question: Just a Note that Huawei also has a Dex equivalent and it seems to work better than Samsung’s. Please don’t ignore that
    • Answer: Very cool! It looks like it called EMUI Desktop on their HUAWEI Mate 10
  • Question: I am trying to use Drag and Drop to re-sequence TListView items and cannot find any relevant examples. (only things moving panels etc). how would I go about this?
    • Answer: I’ve not tried, but I’ve seen it done. I would treat the ListView items as individual items like panels and then drag those. On drop just look at where it as in the list and change the index.
  • Question: LivePreview are available somehow for Delphi CE?
  • Answer: Yes, just build it and install it. You can find the source here 
    • C:\Program Files (x86)\Embarcadero\Studio\20.0\source\Tools\FireUIAppPreview\
    • and more information on using it DocWiki
  • Question: Are there examples of how to make accepting permissions and explain why needed?
    • Answer: In the DocWiki and I covered it in the webinar.
  • Question: Receiving “Can’t open socket: Permission denied. Exiting” message when trying to debug an Android app. Running Android 8.0. This has been a problem since 10.2.
    • Answer: I just tested this with Rio and a Note 9 running Oreo 8.1 and it worked fine. There was a bug in Android 8.0 that impacted all debuggers. You can find more information on Marco’s blog post.
  • Question: Why does Delphi take so long, literally 5+ minutes, to recognize an Android device connected, via USB, to my laptop? Windows recognizes the device immediately and I’m able to browse the device within Windows file explorer. Clicking the refresh devices button has no effect. Is there a way to speed up this device recognition process?
    • Answer: Odd. I’ve not seen that. If you run ADB DEVICES from the command line does it recognize it? If not then that would be an issue with the Android Debug Bridge (ADB) so could be related to your device or the ADB USB driver. The single physical device has multiple devices that Windows recognizes. One is the MTP device for transferring files, the other is the ADB device for debugging. So just because windows recognizes the MTP device doesn’t mean it has recognized the ADB device yet. What device is it?
  • Question: Re: Delay recognizing device: Device is a Samsung Galaxy S8+. Also tried an HTC One M7 with the same result.
    • Answer: Did you try ADB DEVICES from the command line? It could be a Windows issue.
  • Question: Re: Open Socket error: Android version 8.0. Device Samsung Galaxy S8+. Running Delphi Rio 10.3 So there’s no workaround? Given the current route that Android updates arrive at devices: Google -> Manufacturer -> Telcom -> Device means that I’m stuck with no debugging for potentially years … already been ~6 months? Debugging is the reason I’ve invested in Delphi.
    • Answer: That was a bug in 8.0 Oreo that was fixed in Android 8.1 – it wasn’t specific to Delphi. Unfortunately, we don’t have any control over the Android OS or what Samsung installs on their devices. Wish we did. 
  • Question: What’s the best way to end an Android app?
    • Answer: Best practice on Android is that you don’t close your app, but let the OS manage that. If you need to though, then just call Close on your main form like you would on another platform. You could also try Application.Terminate and Halt.
  • Question: Just want to say that this has been an excellent seminar. Thank you for putting it on.
    • Answer: My pleasure. Glad it is of value.
  • Question: what are the sound capabilities in RAD Studio for Android?
    • Answer: You can do quite a bit. Anything that Android supports (which is a lot). There is a media player component that comes with FireMonkey. Take a look at the 4 sample games in GetIt. They have music and sound effects if I recall correctly. The great thing about using FireMonkey is you can get the productivity of all the FireMonkey components, libraries, etc. and then when you need to you can reach down and access the Android APIs just like developers who don’t use FireMonkey.
  • Question: Wouldn’t it nice to have a component for permissions?
    • Answer: The PermisionService makes it really easy, but a component could be useful too I suppose.
  • Question: Where are we with 64 bit for Android? 
    • Answer: R&D is working on it and it is on the Roadmap for later 2019.
  • Question: Give them the coming end of GCM, any plans for built-in FCM components?
    • Answer: Good question. I’ll need to look into that. I know there are some free 3rd party libraries that do that.
  • Question: Hello. where find more info about splash screen? It not clear how to control it.
  • Question: I can’t find LivePreview App on Google Play Store? Does it still exist?
    • Answer: Not currently, but the source ships with the IDE and you can build it and install it yourself. You can find the source here 
    • C:\Program Files (x86)\Embarcadero\Studio\20.0\source\Tools\FireUIAppPreview
    • and more information on using it in the DocWiki
  • Question: is possible to active and android Delphi generated app on both and remain on background sending GPS updates? any sample?
    • Answer: No samples, but I believe people have done it. You would need to be concerned about the battery though. You might need to go directly to the Android GPS API. I would suggest researching Android services on the Android developer site. There are a lot of rules about them.
  • Question: Hello, I’m wondering why for demos all presenters use a mac? Is better have Delphi on a Mac laptop?
    • Answer: I prefer Windows, and most developers I know do too, but Apple requires you to have a Mac if you want to build for iOS, and since I need to demo for iOS too then it makes sense to have just one computer.
  • Question: Ok. It will be great a webinar about to setup Delphi on Mac !!!
    • Answer: There is a good guide in the DocWiki 
  • Question: Is Firebase supported on Rio? from Rad Server?
  • Question: What about GUI test automation for mobile Delphi projects? Is there finally something available for that?
  • Question: 
    • Does the HTTP client library cover all SSL related topics or is there a need for “raw” TCP SSL sockets? If yes, the HTTP client might not be of help.
    • Although Android still supports SSL (Indy libraries), what about the support for the Google libraries (boring SSL).
      • Answer: Check out the new HTTP Client library that was introduced in XE8 – it uses the platform libraries, but don’t know if it supports Google’s Boring SSL specifically
  • Question: Does Fire Monkey support right to left languages like Arabic and Hebrew?
    • Answer: Take a look at FMX RTL. Also, if a 3rd party can do it, then you can do it yourself too. But using their library will certainly make it easier.
  • Question: Huawei is pronounced “hwah way” 🙂
    • Answer: Thanks! I tried to research it, but I am not good at pronunciations. 
  • Question: Are improvements in FMX listed. For example, when saving a TBitmap by SaveToFile, it did not pop up in the media on Android in my previous version. I had to add this programmatically.
    • Answer: I believe it has to do with where you save it and what file format. Save it as a JPEG or PNG and try saving it in a shared location like TPath.GetSharedPicturesPath.
  • Question: No question, just a hint: someone asked for Ranorex and Android. There is documentation on ranorex.com
    • Answer: Cool
  • Question: Google just announced a few days ago “Starting August 1, 2019: All new apps and app updates that include native code are required to provide 64-bit versions in addition to 32-bit versions when publishing to Google Play.” Looks like our apps will be orphaned later this year without a 64-bit compiler – what is the ETA for a 64-bit android compiler?
    • Answer: The  Roadmap has 10.4.x with 64-bit Android planned for “mid-2019”
  • Question: When will we see more common UI features as components (ie. not having to do things manually), such as slide menus, for example.
    • Answer: Like the TMultiView? It is a great common UI component that was introduced in XE7
  • Question: Can the location sensor be used in an Android service now?
    • Answer: I personally haven’t tested it . . . You may need to research the Android platform limitations on using location services in the background because of battery consumption issues. 
  • Question: how can we handle the android permission requests?
    • Answer: It is covered in the DocWiki and here is a sample in the location samples folder
  • Question: Did I understand correctly that there is a C++ Builder community edition accessible and free for any non-commercial use? (i.e., creating apps for personal use and for open-source distributed apps?)
  • Question: Doesn’t RAD Studio (or C++ Builder) have its own emulator to “test” apps on *all* platforms in a more-or-less automatic way? (assuming that the emulation is faithful enough)
    • Answer: We used to offer a bundle deal with MacInCloud but it didn’t get enough use to justify continue it since most people use devices. You can use the Android emulator but it isn’t great, and there are services that let you test on devices in the cloud. Samsung offers one too specifically for their devices. I’ve also heard some people have good luck with using Bluestacks, but I haven’t tried it. There are a lot of options.
  • Question: Speaking of how iOS is so different and has such different nuances compared to Android…
    • Answer: There is a lot you can do with a complete multi-platform approach, but then there are specifics to each platform you can take advantage of. For example, your desktop has a larger screen, and more input and output options. A pure multi-device approach does a lot and makes you really productive, but then the great thing about Delphi, C++Builder, & FireMonkey is you can also take advantage of platform-specific features and APIs. Kind of a best of both worlds approach!
  • Question: Thanks!
    • Answer: welcome!
  • Question: but there is a lot of devices that still running 8.0! Even Samsung …
    • Answer: Yes, it is an unfortunate bug in Android 8.0. Samsung says they have an update coming, and I hear the beta is already available. Have you tried that?
  • Question: What about 64-bit on Android, iOS, and macOS?
    • Answer: iOS 64-bit has been available for a while, bot macOS (10.3.x) and Android 64-bit (10.4.x) are on the roadmap for release this year. 
  • Question: what is the best way for FireMonkey mobile app to work with DB (on a server). REST or FireDAC? Or something else?
  • Answer: 
    • The best way depends on your goals and the scenario. 
    • I would recommend starting with RAD Server (EMS) using FireDAC to connect to the server database and then connect to RAD Server from your mobile app. 
    • You could also use DataSnap in the same situation (RAD Server is more of a turnkey, while DataSnap lets you build it from scratch so more flexible). 
    • If you don’t control the server then if the server is exposing the data over REST then you can use the REST Client libraries  or the BAAS libraries 
    • Although if it is on Azure or Amazon Cloud then use the cloud libraries 
    • You could also use DevArt’s UniDAC to connect directly to some databases from the mobile app
  • Question: Hello, what is the best way to show forms and destroy it for android application?
    • Answer: You can show and destroy forms just like you would on other platforms, or you might consider using frames on a Tab Control. Also, take a look at TFrameStand which is available in the GetIt package manager
  • Question: Is C++Builder Community Edition available for macOS?
    • Answer: Yes, it can target macOS. The same features as C++Builder Professional
  • Question: Is the size of the executable file for Android, prepared in FireMonkey still a problem?
    • Answer: It never was a problem. A “hello world” app in FireMonkey is larger than an equivalent app in Java because FireMonkey is including a lot of other additional libraries and features for building more complicated apps. There is a lot you can do to make a FireMonkey app smaller, but you give up functionality. If you look at real apps you will see that a Java based app and a FireMonky based app are much closer to the same size.
    • Take a look at this Anatomy diagram for more information. 
Anatomy Of A Delphi 10.3 Rio FireMonkey App from FMXExpress.com?
Anatomy Of A Delphi 10.3 Rio FireMonkey App from FMXExpress.com
  • Question: When will there be support for 64 bit Android?
    • Answer:It is on the roadmap for 10.4.x this year (2019) 
  • Question: Jim: When will Update 1 be available for Rio?
    • Answer: When it is ready. I expect it will be soon, but I can’t say specifically when.
  • Question: What are the critical target versions that should be tested?
    • Answer: All of them? 😉
    • You should be testing on Oreo 8.1 (the target SDK version) and probably Marshmallow (the minimum SDK version) too.
    • You should test on as many devices and OS versions as you can.
    • Pay attention to the Version Distributions Dashboard on the Android site to see what versions are most popular  
    • You can also follow other sites like to see what versions and devices that are popular
    • It can also depend on your app and your user base. Maybe you are targeting a specific region or tablets.
    • Then select the targets that give you the largest coverage.
  • Question: Best Book for quick start to sophisticated Android apps?
  • Question: Timeline for support of WatchOS from Apple?
    • Answer: Both WatchOS and AppleTV require apps published to the app store are in an intermediate format that Apple hasn’t published. 
    • I believe you can still build apps to deploy directly the platform though. 
    • Those platforms are not on the roadmap.
  • Question: I received this from Google: Ensure that your app supports 64-bit devices. Does Rio support this?
    • Answer: 64-bit is on the roadmap for mid 2019 
  • Question: For a Delphi Windows application to access files on your Android phone connected via USB. See MTP13.zip
    • Answer:Useful. That is using the PortableDeviceApiLib Type Library, good idea. You could also do it via ADB if you enable debug mode on the device.
  • Question: Why don’t forms have an option to auto create?
  • Question: How to send SMS from an Android app?
    • Answer:Yes there is sample code online although I haven’t tested it and it may need to be updated.
  • Question: Is there a easy way to get some values from a record from a local website
  • Question: Please address how to read and write external files from/to the SD Card.
    • Answer: That isn’t something I was planning to cover, but I will test it and post to later.
  • Question: Is adding other android SDKs to 10.3 fixed – had a hard time with 10.2?
    • Answer: I’ll blog about it some more. It is pretty straight forward, but there are some details in the DocWiki 
  • Question: I miss the DBaware components from VCL in FMX. How can I get Design time data?

Here are some interesting statistics I originally didn’t include because of time . . .

Android � Logos Download
Android statistics and facts
  • 85% of the global mobile operating system market runs Android
    • 62% of US,  76.4% of China, & 25% Enterprise markets
  • 37.93% of all devices connected to the Internet
  • 70% of tablet market
  • 400+ manufacturers with 4000+ devices on 500 carriers
    • 600+ devices launched in 2015 alone
  • The average Android smartphone user
    • Touches smartphone 2,617 times a day
    • Has 95 apps installed, but only uses 35 apps daily  
    • Deletes unused apps after 12 weeks
  • 34% of US smartphones are by Samsung (running Android)

Android Statistics Sources: 

I pulled a couple of graphics from my presentation that I thought were interesting and that you are free to share. (Select an image for the larger version.)

Categories
10.3 Rio Android FireMonkey News

Android Z-Order, Native Controls, and 10.3 Rio

Z-order represents stacking controls
Z-order represents stacking controls

Before 10.3 Rio when you used a a platform-native control, like TWebBrowser or TMediaPlayer, you were not able to put other controls on top of them. That stacking of controls is knowns as Z-Order. This was especially annoying when you were using them with the TMultiView (one of my favorite controls), because the drawer would slide out under instead of over the platform-native control. There were ways around it, but it was still frustrating.

In XE7 we introduced the ControlType property for iOS, and then in Seattle we brought it to Windows. Setting it to Platform switches a FireMonkey control to a platform-native control at runtime.

Now with the upcoming 10.3 Rio release the ControlType property is coming to Android, and it is brining two significant benefits: More Native Controls, and corrected Z-Ordering.

More Android Native Controls

The TWebBrowser, TMediaPlayer, TBannerAd, and TMapView are always platform native controls (they are rendered by the underlying Android OS and not by FireMonkey.) But in 10.3 Rio there are 4 new controls that are optionally platform native.

TSwitch component

That means when you set the ControlType property on these controls they will be rendered by the Android system instead of FireMonkey. You may notice some slight changes in the way they look and work because of this.

This is especially important in the TEdit as there are certain behaviors that are attached to the way users provide keyboard input and edit text. Here are some of the advantages your users will now have when you use a ControlType of Platform with your TEdit

  • Auto-Correction: Words are suggested while typing, these can be used by clicking on the space bar.
  • Define: You can select a word and click on Define to see the definition of such word in the dictionary.
  • “.” Shortcut: Double tapping the space bar inserts a period followed by a space.
  • Text Shortcuts:? That will expand into the word or phrase as you type.

Some of these behaviors vary from one Android platform to others (for example Samsung has a Clipboard feature). You can configure these settings on your Android devices in Settings > General > Keyboard.

Native Aware Android Z-Ordering

Additionally many controls now are able to handle a Z-Order over a platform native control. Now you can put control buttons over your TMediaPlayer for example. These controls have a ControlType property that when you set it to Platform it will maintain the Z-Order with other platform-native controls.

Setting their ControlType to Platform doesn’t make these platform-native, it just makes them work correctly with other platform native controls.

What’s Next?

10.3 Rio is in beta (which means these features are subject to change) and available to update subscription customers. Once it is released you can learn more about all of these features in the DocWiki. Also, if you are already using Platform native ControlType on iOS or Windows then those control will take advantage of the Android Platform native ControlType right away!

Android Z-Order and the Native Controls - Coming soon to a RAD Studio 10.3 Rio Near you!
Categories
News Source Code

Unexpected Benefit of Inline Variables: Conditional Blocks

Inline variables is one of the cool new feature coming in 10.3. The obvious huge use case is loop control variables, but I just discovered another great use case while reviewing some code. 

procedure DoesSomething;
var
  var1, var2: Integer;
begin
  // use var1
  {$IFDEF Something}
  // use var1 &amp;amp;amp;amp;amp; var2
  {$ENDIF Something}
end;

This is a pattern I see a lot, and it generates a hint on var2 being unused based on the current compiler directive status.

[dcc32 Hint] myUnit.pas(123): H2164 Variable 'var2' is declared but never used in 'DoesSomething'

Now there are a number of ways to deal with this with more compiler directives, which is what I’ve done in the past, but I never like adding more compiler directives. It makes the code way more complicated and harder to maintain. Now with Inline Variables I can simplify it, make it easier to maintain, and hande the hint! (all of which makes me so happy!)

procedure DoesSomething;
var
  var1: Integer;
begin
  // use var1
  {$IFDEF Something}
  var var2: Integer;
  // use var1 and var2
  {$ENDIF Something}
end;
Happy dance commencing in T-minus 10 seconds. 

What are some interesting ways you see inline variables benefiting you?

Categories
News

Arduino & Delphi Cosplay

Me with a Spartan Boba Fett, but I thought he was more of a Delphi Dude ?(FanX Salt Lake City - 2018)
Me with a Spartan Boba Fett. I thought he was more of a Delphi Dude (FanX Salt Lake City – 2018)

Cosplay (aka costume-play) takes the fun and imagination of childhood dress-up to extreme levels only justifiable by an adult! Not only is it expensive, and needs a large time commitment, but it is rarely comfortable.

Comic conventions are the usual place to find cosplay, but Halloween is also a good excuse for some cosplay fun. I’m a huge fan of creative cosplay and love getting my picture with cosplayers.

In writing this post I realized I am frequently attaching LEDs to my face.

The V character from Cyberpunk 2077. Cosplayer Maul. photo by eosAndy.
The V character from Cyberpunk 2077. Cosplayer Maul. photo by eosAndy. His cosplay is much better than mine.

This year I am putting together my Ultimate Cyberpunk cosplay. The first part is a jacket based on the main character from the game Cyberpunk 2077 by CD Projekt RED. Neuromancer, by William Gibson, inspired the Cyberpunk 2020 RPG by Mike Pondsmith. They both inspired this unreleased video game Cyberpunk 2077.

I’m a big fan of both the book and the original RPG and am looking forward to the video game. I combined elements from all three sources for my cosplay. The character V is more of a Street Samurai / Solo, while I wanted to go for more of a Decker / Netrunner (a little Shadowrun RPG influence in there too).

At this point the secret is out, I’m a huge nerd. I love Role Playing Games, and Cyberpunk & Shadowrun are my favorite genres.

I didn’t have my RGB Shades in time for Salt Lake FanX, so I justed glued some extra LEDs (NeoPixel 4×4 grids) to my face. They represent cybernetic enhancements, which is why I left the wires exposed. I used an Arduino MEGA 2560 by ELEGOO as the controller. It also controlled the string of NeoPixel lights in the collar. I attached a Bluetooth keyboard to one wrist and an Android Pixel phone to the other. The phone was decorative for now.

Later I got my RGB LED Shades which will become the key to my outfit for this Halloween. The RGB LED Shades use an Arduino Mini as the brains. I added an HC-06 Serial Bluetooth module to control the leds remotely.

After soldering the HC-06 onto my shades I can power them up and pair my Android phone with the HC-06 module. One note about my soldering is that if you look you will see that it is connected to two analog pins instead of digital pins. On most Arduinos the analog pins can double as digital pins (see the Pinout).

Android Bluetooth Pairing Dialog
Android Bluetooth Pairing Dialog

After that, a TBluetooth component is able to open a socket to the shades. Start the pairing with Bluetooth1.DiscoverDevices( 5000 ); In the DiscoveryEnd event handler the following code will open a socket to the HC-06 module (Thanks to Boian Mitov for the basis of this code):

var
  ADevice   : TBluetoothDevice;
  AService  : TBluetoothService;
begin
  for ADevice in ADeviceList do
  begin
    // HC-06 is the name of the bluetooth device
    if ADevice.DeviceName = 'HC-06' then 
    begin
      Bluetooth1.Pair( ADevice );
      for AService in ADevice.LastServiceList do
      begin
        // FSocket is a TBluetoothSocket with larger scope
        FSocket := ADevice.CreateClientSocket( 
            AService.UUID, False );
        If Assigned( FSocket ) then
        begin
          FSocket.Connect;
          Break;
        end;
      end;
      Break;
    end;
  end;
end;

Once the socket is open you can send characters with this code.

FSocket.SendData( TEncoding.UTF8.GetBytes( 'D' ));

It is so easy to work with Classic Serial Bluetooth in Delphi (or C++Builder) and the TBluetooth component. You even could send a whole string or other binary data. For this project a single character was all I needed to change modes on the shades. A single character is also easier to process on the Arduino side. (Technically Bluetooth Classic works on all platforms, but on iOS you need special approval from Apple on a per app basis.)

RGB Rio Shades
I’m wearing the Rio RGB Shades with the Delphi powered controller on my Android phone

I took my RGB Shades with me to Sao Paulo Brazil for the 10.3 Rio preview. Even though the Bluetooth worked before the conference, my phone couldn’t make the connection on stage. When I opened my phone’s Bluetooth connection window it was obvious that with 750+ people in attendance there were a few hundred Bluetooth devices broadcasting on the same wavelength.

David Millington kicking off the Keynote
David Millington kicking off the 10.3 Keynote

My next project involves Bluetooth LE with these RGB LED Steampunk Goggles.

Jim wearing LED Steampunk Goggles
RGB LED Steampunk Goggles

I built them a year ago from an AdaFruit kit. Later I added a Bluetooth LE Module to make them controllable. Unfortunately, my soldering didn’t hold up and I need to rebuild them. This makes them both my previous and next cosplay project.

RGB LED Goggles, a horse mask, and a Los Angeles Kings hockey jersey
RGB LED Goggles, a horse mask, and a Los Angeles Kings hockey jersey (don’t ask)

I’m considering salvaging the NeoPixels and rebuilding them with an ESP32 microcontroller. The ESP32 is a little larger than the original Trinket microcontroller. This is because it has integrated Bluetooth LE, WiFi, and more pins. I’d also like to get some 50% mirrors to create an infinite LED tunnel effect (I’ll post pictures when I get them – it is really amazing).

I met Star Lord!
I met Star Lord!

I’ve worked with the TBluetoothLE component before and it is even easier to work with than TBluetooth. So I’m really looking forward to this project.

On the Arduino side, you can use the Arduino IDE and flex your C programming skills. Or you can do like I usually do and use Visuino by Boian Mitov of Mitov Software. It provides a visual drag and drop interface for programming Arduino devices. It won the Embarcadero Cool App contest in April 2017 as Boian used Delphi to develop Visuino. Boian also recently added RGB LED Shades support to Visuino (along with unboxing and assembly videos.)

Visuino makes Arduino and LED RGB Shade development easy. It is an Embarcadero Cool App developed with Delphi!
Visuino makes Arduino and LED RGB Shade development easy. It is an Embarcadero Cool App developed with Delphi!

I think Boian is a great guy who makes some great technology. Most of it has a free version and the commercial prices are very reasonable too. He is always very helpful as well.

Boian and Jim at the 2017 SoCal CodeCamp in Los Angeles
Boian and Jim at the 2017 SoCal CodeCamp in Los Angeles

So what’s next (after the Bluetooth LE RGB Steampunk Goggles obviously)? I’m working on a design for an electronic physical polyhedral die with Bluetooth LE. So you roll a physical die of a single size and it can become any number of sides you need, all controlled via your phone. Did I mention how much of a nerd I am?

I love polyhedral dice
I love polyhedral dice