Quantcast
Viewing all 1006 articles
Browse latest View live

TMS Component Pack v8.8 is here

What initially started in 1999 as a small bundle of about 15 VCL user interface controls for Delphi, has grown in about 18 years to a set of over 400 powerful and feature-rich components for development of VCL Windows applications with Delphi and C++Builder.
Thousands and thousands of hours work went into this VCL component set that found its way to thousands of Delphi & C++Builder developers world-wide and this way, also to thousands of Windows applications used in so many places day-in, day-out to help and improve the life and work of so many people. As a small example, we learned that our VCL Planner is being used to track maintenance schedules of the French trains all over France, all in real-time.
And yet, every day our team continues to improve, extend the TMS Component Pack, assist the users in getting the most out of it and listen carefully to your needs and wishes. Also with the newest v8.8 release, we focused on user needs and added no less than 11 new features in existing components and 3 new components that were requested. We have our feature request logging & voting system for this where customers can add new feature requests and up-vote feature requests from other users so we can set the right priorities in our development.
As a result of this, these 3 new controls were added to TMS Component Pack v8.8:

New : TAdvHighLightLabel v1.0.0.0 : Label that allows to highlight specific words in the label text in different colors.

Image may be NSFW.
Clik here to view.
highlight label


New : TAdvTouchSpinEdit v1.0.0.0 : Spin edit control with spin buttons left and right from the edit control to allow easy up/down button access from touch screens.

Image may be NSFW.
Clik here to view.
spinedit


New : TAdvDBListBox v1.0.0.0 : Listbox control with embedded filter + insert data capability that can be bound to a dataset field.

Image may be NSFW.
Clik here to view.
listbox


In addition, 11 new features were added to existing components:


Whether you are using the newest Delphi 10.2.1, C++Builder 10.2.1 or still using an older version of Delphi, our TMS Component Pack installer detects the versions of Delphi or C++Builder installed on your system and will install for any version (from Delphi 7 onwards) it finds.
If you haven't used the TMS Component Pack yet, check out all the feature-rich components you have been missing all this time. If you have used an older verison of the TMS Component Pack, check out all latest additions & improvements and if you have just downloaded & installed the latest version 8.8, check out the new components and features that were added.

Now that TMS Component Pack v8.8 is released, we are already laying out plans for the next version and eagerly awaiting your favorite feature requests or feedback that you can send by email, in our forum or add to our feature request system.


TMS Analytics for nonlinear multiparametric approximation of surface data

The new version 2.2 of TMS Analytics and Physics pack contains the nonlinear least squares approximation tools. The nonlinear approximation tasks are widely used in statistics to fit experimental data with some random distribution function.


Let us consider the example of surface data fitting with the 2D Gaussian function. The Gaussian distribution of 2 variables x and y (https://en.wikipedia.org/wiki/Gaussian_function) has the following math expression:
Image may be NSFW.
Clik here to view.

Except the amplitude A, the distribution nonlinearly depends on four parameters: center coordinates x0, y0 and deviations sx, sy. The task of fitting data with the Gaussian function is to find optimal values of the four parameters, those minimize the error of the distribution and the experimental data zi(xi,yi), i=1..N.

The approximation task can be solved by the numerical tool with the following code:

var
  variables, coefficients: TArray;
  f: string;
  basis: TNonlinearBasis;
  cValues: TArray;
  appr: TNonlinearApproximator;
  opt: TSolverOptions;
  eValues: TArray;
  eValue: TFloat;
begin
  variables:= TArray.Create('x', 'y'); // 1
  coefficients:= TArray.Create('x0', 'Sx', 'y0', 'Sy'); // 2 
  f:= 'e^-((x-x0)^2/(2*Sx^2)+(y-y0)^2/(2*Sy^2))'; // 3
  basis:= TNonlinearScalarBasis.Create(variables, coefficients, nil, f); // 4 

  appr:= TGaussNewtonLeastSquares.Create; // 5
  appr.C0:= TArray.Create(0.1, 0.1, 0.1, 0.1); // 6
  opt:= TSolverOptions.Create(true);
  opt.MaxIterationCount:= 100;
  opt.Precision:= 0.2;
  appr.Options:= opt; // 7

  cValues:= appr.Approximate(basis, xyData, zData); // 8

  // use basis with optimal coefficients
end;

Line 1: Create array of variable names.
Line 2: Create array of four distribution coefficient names.
Line 3: Set up the approximation function expression.
Line 4: Create the nonlinear basis instance with specified data.
Line 5: Create the appropriate nonlinear approximator instance.
Line 6: Set up initial guess of coefficient values for nonlinear solution.
Line 7: Set up appropriate nonlinear solution options.
Line 8: Solve the problem (finding optimal values).

When optimal values of the Gauss distribution parameters found, they can be used with the basis instance to calculate the distribution function in any specified point (x,y) or for other analysis methods, like derivative calculations and so on.

On the pictures below there are results of the approximation made with some generated noisy data. The result presented as 1D section of the 2D function for two different x values: x=0.0 and x=0.6.

Image may be NSFW.
Clik here to view.


Image may be NSFW.
Clik here to view.


In this sample, we used the TMS FNC Chart to display the values and the approximated function. The advantage of using the TMS FNC Chart is that it can be used both for VCL and FMX applications and we can use the same code to create a VCL Windows application or a FireMonkey cross platform application.
The source code of the example application can be downloaded here.

The TMS Analytics and Physics pack version 2.2 includes also many other useful numerical tools: linear least squares approximation, 1D and 2D integration, ordinary differential equation solution, function analysis. Due to the addition of array and matrix support in version 2.2, many numerical calculations can be implemented in vector form with small and compact formulae. The version can be downloaded from the product page.

Document and test your REST API using OpenAPI/Swagger support in TMS XData

TMS XData 2.7 has been just release with lots of new features. The most interesting one, in my opinion, is OpenAPI/Swagger support.

TMS XData server can now optionally provide a JSON file containing the OpenAPI Specification (OAS, formerly Swagger) for your whole server API. This opens up a lot of possibilities, usage of several tools of the OpenAPI ecosystem is now possible. Main one would be the Swagger UI, a web front-end to describe and test your API.

Enabling support for OpenAPI

To enable OpenAPI support in your server, just use the unit XData.OpenAPI.Service and call the method RegisterOpenAPIService anywhere in your application:

uses {...}, XData.OpenAPI.Service;
 
{...}
  RegisterOpenAPIService;
It's as simple as that. XData will scan your whole API and build the specification file describing that API automatically. The specification will be very detailed as XData has all the metadata for your API: the method parameters, the mappings for entity classes, the data types, etc.

Retrieving the OpenAPI Specification (OAS) file

The OAS file is available through a GET request to the URL "/openapi/swagger.json" relative to your server root URL. For example, if your server root is http://myserver/tms/xdata/, then you will be able to access the file from this URL:

GET http://myserver/tms/xdata/openapi/swagger.json

Using Swagger UI

One of the main use cases is to be able to use the Swagger UI. It's a web-based front-end to dynamically document and test your API. From their website: "Swagger UI allows anyone - be it your development team or your end consumers - to visualize and interact with the API's resources without having any of the implementation logic in place. It's automatically generated from your Swagger specification, with the visual documentation making it easy for back end implementation and client side consumption.".

You can visit their site for more information, but here are quick steps to see it in action from your own server:

1. Create your XData Server and enable OpenAPI support as described above.

2. Enable CORS in your TXDataServerModule:
    Module.AccessControlAllowOrigin := '*';
3. Open the existing live demo of the Swagger UI at https://petstore.swagger.io.

4. In the edit box that appears at the top of the page, just type the URL that returns the OpenAPI Specification. For example, "http://myserver/tms/xdata/openapi/swagger.json", and click "Explore". That would be enough to list your API.

If you want an even faster way to see it in action with XData:

1. Run the demo named SQLiteConsoleServer. It's located in folder demossimple_sqlite. That demo is available when you install TMS XData trial or licensed version.

2. Open web site https://petstore.swagger.io.

3. In the edit box, enter the OAS file address: "http://localhost:2001/tms/music/openapi/swagger.json":

Image may be NSFW.
Clik here to view.


4. Click Explore to browse the API and test.

Image may be NSFW.
Clik here to view.


And that's it!

This new XData release doesn't stop there, there are lots of new features including several new types supported in method parameters, entity properties, PODO properties, and more!


Improvements for symbolic expressions simplification in TMS Analytics & Physics developing library

One of the unique features of the Analytics library is symbolic derivatives calculation. The derivative can be calculated just with several lines of Delphi code, for an example:

var
  f, df: string;
  t: TTranslator;
begin
  t:= TTranslator.Create;
  f:= 'x^2*e^(x/3)';
  df:= t.Derivative(f, 'x');
  //...
end;


The Analytics library guarantees that the result derivative expression is syntactically and mathematically correct and satisfies the derivative rules. From the first version, the derivative algorithm automatically simplifies the result derivative expression. Nevertheless, the library is not a Computer Algebra system, so it cannot simplify all the result expressions to the optimal representation.

New version 2.3 introduces new simplification algorithms for providing more readable and short symbolic derivatives. New simplification algorithms include: constants reducing in sum and product expressions; reducing nested sum or product expressions to one; reducing negation pairs in product expressions and others.

There are some examples of functions and their derivative expressions, evaluated with the old version of the library and with the 2.3 version:

f(x)       : x^2*e^(x/3)
df/dx (old): (2*x)*e^(x/3)+(e^(x/3)*(1/3))*x^2
df/dx (2.3): 2*x*e^(x/3)+e^(x/3)/3*x^2

f(x)       : 2*x^3+A/4*x^2-x/3
df/dx (old): (3*x^2)*2+((2*x)*A)/4-1/3
df/dx (2.3): 6*x^2+1/2*x*A-1/3

f(x)       : (A/2)*arctan(x^2)
df/dx (old): ((1/(1+(x^2)^2))*(2*x))*(A/2)
df/dx (2.3): x*A/(1+x^4)

f(x)       : P{n-1 m+2}(x)
df/dx (old): ((((n-1)+1)-(m+2))*P{(n-1)+1 m+2}(x) -(((n-1)+1)*x)*P{n-1 m+2}(x))/(x^2-1)
df/dx (2.3): ((n-m-2)*P{n m+2}(x)-n*x*P{n-1 m+2}(x))/(x^2-1)


As can be seen from the examples, new version gives shorter and more readable symbolic expressions for different function cases. The simplified representation of the formulae also reduces the calculation time. The new library version is already available here

The Exit Procedure

Image may be NSFW.
Clik here to view.
Photo by Kev Seto on Unsplash

All Pascal programmers know the Exit() procedure since the early versions of the compilers. But do they know how to use it correctly?

The Exit() procedure is used when we want to exit of running scope. That scope could be a function, procedure, method, or even the program itself.

Let's say that a console program calls a procedure named Execute:

    procedure Execute;
    begin
      Writeln('1. Passing on this line...');
      Exit;
      Writeln('2. It will not pass here');
    end;

In the example above, only the information from the first Writeln will be shown on the console.

When exiting a scope, the program immediately returns to the previous scope (another function/procedure/method or the program itself). The only exception to this rule is when there are try-finally blocks. If Exit () is called within a try-finally block, the compiler will execute the code inside the finally-end before it exits the scope.

Here is another example:

    procedure Execute;
    begin
      try
        Writeln('1. Passing on this line...');
        Exit;
      finally
        Writeln('2. I am still here!');
      end;
      Writeln('3. It will not pass here');
    end;

Texts #1 and #2 will be shown on the console. Even though Exit() was called before the text #2 was printed, the code still runs because of try-finally.

Another example of using Exit() is when we do validations. If a validation or checking does not return true, we use Exit() to stop execution of the current scope.

Suppose that we want to add two integer numbers, but we only want integers bigger than zero:

    function Sum(A, B: Integer): string;
    begin
      Result := 'Invalid result';
      if (A < 0) or (B < 0) then
        Exit;
      Result := Format('The result is %d', [A + B]);
    end;

In the above example, the return of Sum function is initialized with an invalid value and then there is a validation to know if the values are less than 0. If the test fails, the program will return to the prior scope to calling Sum function with the invalid result. But if the test does not fail, the function result will be the sum of A and B.

There are those who are adept at structured programming and prefer do not "break" the program execution with an "early exit", which means they do not use Exit() because they believe the code would be simpler.

So, let's rewrite the previous example:

    function Sum(A, B: Integer): string;
    begin
      if (A > 0) and (B > 0) then
        Result := Format('The result is %d', [A + B]);
      else
        Result := 'Invalid result';
    end;

Looks simpler? Well, in this example I would say yes. But for examples with more conditionals, I'd say no (let's see this below).

What if we wanted to tell the user that their data is not correct?

    function Sum(A, B: Integer): string;
    begin
      Result := 'Invalid result';
      if (A > 0) then
      begin
        if (B > 0) then
          Result := Format('The result is %d', [A + B]);
        else
          Writeln('B should be greater than zero');
      end
      else
        Writeln('A should be greater than zero');
    end;

In this example, we do not use Exit() and I think the code is quite confusing. The tests are "separated" from the warning return to the user (Writeln).

Kent Beck, Martin Fowler stated categorically that "one exit point is really not a useful rule. Clarity is the key principle: If the method is clearer with one exit point, use one exit point, otherwise don't".

So, let's rewrite the previous example using Exit():

    function Sum(A, B: Integer): string;
    begin
      Result := 'Invalid result';
      if (A < 0) then
      begin
        Writeln('A should be greater than zero');
        Exit;
      end;
      if (B < 0) then
      begin
        Writeln('B should be greater than zero');
        Exit;
      end;
      Result := Format('The result is %d', [A + B]);
    end;

The code got a little bigger, it's true, but the tests and warnings for the user got simpler, in my opinion. You do not have to follow all nested if-else's. For each test that fails, the warning is just below and the scope will be aborted with the use of Exit. If all tests do not fail, the function will return the sum of A and B.

In Delphi, as of 2009 version, Exit() procedure has gained an improvement: Exit() can have a parameter specifying a result. The parameter must be of the same type as the result of the function.

The FPC also has the same definition, but I do not know who implemented this new feature first.

Again, let's rewrite the previous example:

    function Sum(A, B: Integer): string;
    begin
      if (A < 0) then
        Exit('A should be greater than zero');
      if (B < 0) then
        Exit('B should be greater than zero');
      Result := Format('The result is %d', [A + B]);
    end;

Simple and clean.

Exit() can be given any type of return, even instances of Interfaces. Using this parameter, it is as if we get the same behavior as the return reserved word in Java. However, Exit() together with Result, gives us even more possibilities to return from functions.

See you.



Announcing TMS RADical WEB

The world of web development has evolved at a fascinating pace over the past 15 years. I still remember having developed around 2001 a CGI-bin based WAP pages server application, a solution that is these days not only completely irrelevant (anyone still knows what WAP and CGI-bin is?) but technically fully outdated.
Image may be NSFW.
Clik here to view.



While the strength of Delphi (and thus the Pascal language) was originally in Windows desktop applications and from 2011 in cross platform native desktop and mobile applications, developing web applications was always a kind of side-affair for Delphi developers. Many Delphi developers as such also looked over the fence at other solutions to create web applications.

Over the past couple of years several welcome trends have developed: the HTML5 standard became widely accepted and available in modern browsers, the Javascript Ecma 5 standard made it a stronger language with object-oriented capabilities, CSS3 offers a styling & layout features so rich that most developers know not even half of its power.
Image may be NSFW.
Clik here to view.


Wouldn't it be a dream come true that Delphi/Pascal developers could also reach out to this platform? At TMS software we always felt this lacking over the past years.

A little less than a year ago, we were approached by the bright minds who were for a longer time already working on a Pascal to Javascript compiler and asked if we didn't think it would be interesting to bring the power of this new compiler in the hands of Delphi developers with a framework & IDE integration to take advantage of it. This was the kind of moment where my enthusiasm must have been at about the same level when I dropped the first components on the Delphi 1 form designer in 1995 or when I got my first FireMonkey application started on my iPhone 4 thanks to the cross-platform capabilities in Delphi XE2. Now, in 2018, we're pleased to announce a kind of similar wow experience will become available that allows you to build an application in a component based RAD way in the Delphi IDE, press F9 and see the app working in your browser.
Image may be NSFW.
Clik here to view.


TMS RADical WEB is the umbrella name under which several web enabled products will be created and offered by TMS software and it is built upon a couple of fundamental pillars:

  • Backed by a solid & proven Delphi/Pascal to Javascript compiler that was years in development
  • Modern SPA web application model. The application consists of HTML & Javascript files that can be easily deployed on any existing light or heavyweight webservers or cloud services like AWS, Azure
  • Component based RAD development integrated in the Delphi IDE
  • Standard component framework for common UI controls and access to browser features
  • A truly revolutionary & innovative TMS FNC component framework that is now also web enabled, allowing to create UI controls that can be used on VCL, FMX, LCL and WEB!
  • Open to consume other existing Javascript frameworks & libraries, open to use HTML/CSS for design
  • Binding to server data via microservices with seamless interfacing to server data via TMS XData
  • Binding to cloud services


The first building block under the TMS RADical WEB umbrella is TMS WEB Core. TMS WEB Core offers the full RAD integration in the Delphi IDE of standard components, compiler & form designer. The next block is TMS FNC UI controls that are web-enabled. Third is TMS XData extended with a web XData client. As a first step to bring TMS RADical WEB to you, will be the delivery of a technical preview of TMS WEB Core, TMS FNC UI Controls for web and TMS XData with web client to our TMS ALL-ACCESS customers. Our TMS ALL-ACCESS customers sit as such in a first-class seat to experience this exciting new route to web development and influence the further fine-tuning with feedback, requests, comments. After this initial period, TMS WEB Core will then also become widely available to all customers.

Over the coming days, I'll give a deeper insight in each of these pillars of TMS RADical web. Watch this blog space! Every day we will have a new blog about our new web development products.
Coming blog articles are:
  • RAD web development from the Delphi IDE
  • Proud to announce a revolutionary & innovative UI control set that is TMS FNC
  • Connecting to data
  • Open to other Javascript frameworks
  • Using HTML & CSS for design & layout of your application pages
  • Using common web functionality & consuming cloud services
  • Debugging your code
  • History, team behind TMS RADical WEB and future



My colleague dr. Holger Flick, Embarcadero MVP brings it all together here:



Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, RAD web development from the Delphi IDE

It cannot be denied that RAD component-based application development is the very foundation of Delphi software development. It is the foundation that got us all so excited since Delphi 1 in 1995. It got us not only excited but most of all very productive.
Image may be NSFW.
Clik here to view.

Encapsulation of UI controls and other functionality in components with easy access to properties, method and events is what lets developers focus on business logic and their problem domain rather than underlying technical tricks used to render the UI or access operating system functionality.
It is in this respect that our team went to great lengths to offer this RAD experience in the Delphi IDE that does not really have a web target.
With TMS WEB Core, all that is offered. Via File, New, Other, select a new TMS Web application and a new project is created with a first form ready to start building your application.

Image may be NSFW.
Clik here to view.


While the developer cannot really see this, technically, this is a VCL form but our IDE integration ensures that for this web form, only TMS web controls can be picked from the tool palette. This is the tool palette with the set of UI controls & components that is currently already available.

Image may be NSFW.
Clik here to view.


You can build your UI together this way like you did the past 23 years for VCL applications or the past 7 years for FMX applications. When you compile the application, a HTML file and Javascript file is produced. By default, the TMS WEB Core IDE integration launches a small TMS Web server for debugging purposes allowing the developer to see the application running in the browser. As such, the so familiar development cycle of designing forms, setting properties, adding event handlers, writing code and press F9 and see within a fraction of time the result running and working or have the capability to debug the application, is achieved.

Image may be NSFW.
Clik here to view.


Compared to VCL or FMX application form designing, there is an optional but very fundamental difference between VCL/FMX application forms and web forms. While it is perfectly possible to have the WYSIWYG model, i.e. what you see in the Delphi IDE form designer is what you get when running the web application, TMS WEB Core facilitates alternative ways. The web page design and layout can be fully created with HTML/CSS. It can be easily created by people with different talents than us software developers, i.e. graphic designers. TMS WEB Core allows for easily hooking up our forms with UI controls to pages designed with HTML & CSS. More about this technique will be covered in a separate blog.

Image may be NSFW.
Clik here to view.


My colleague dr. Holger Flick, Embarcadero MVP, brings it all together here:



Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, proud to announce a revolutionary & innovative UI control set that is TMS FNC for web

Over two years ago, we did deep research at TMS to create a UI control abstraction layer that would allow to create UI controls that can be used to create VCL Windows applications, FMX cross platform applications for Windows, iOS, Android, macOS and also LCL applications with the free Lazarus IDE for Windows, macOS and Linux. The result of our deep research was our FNC component framework.

Image may be NSFW.
Clik here to view.

Meanwhile, we are proud that we have already a wide range of sophisticated UI controls based on the FNC framework available like a grid, treeview, planner, chart, ribbon, tableview and many more plus also several new controls in development. We have noticed that for many developers there is still a bit of confusion about what FNC really means. Except there is a lot of technical magic behind FNC, for developers the result is really simple. You have one UI control set available that you can use simultaneously to create VCL, FMX or LCL applications. Yes, with one UI control set, you choose what framework you want to use, be it VCL, FMX or LCL. Irrespective of the framework you use, you can use the exact same controls, you can share or reuse application code dealing with these UI controls between the different frameworks and you have only one learning curve to get the most out of these powerful controls.

Image may be NSFW.
Clik here to view.



While VCL, FMX, LCL have been able from the first stage of FNC controls, from now on, the web is a major new target for using your FNC UI controls. That we even managed to web-enable our FNC abstraction layer is certainly a proof how solid that framework was designed from the beginning, but it remains nothing short of unbelievable, revolutionary and innovation that the exact same source code produces UI controls usable simply everywhere: native desktop, native mobile and web. And this on almost any modern electronic device on the planet: as installed native application or as web application you use via your browser on your Windows laptop, your iPad or iPhone mobile device, your Android smartphone, your macOS, your Linux machine and even on your Raspberry Pi SBC.

See it to believe it and be amazed!

This is our FNC Planner that worked before in Windows, iOS, Android, macOS and yes also on Linux and even Raspberry PI, now it makes the giant leap to the web and runs in every HTML5 supporting web browser on every device on the planet:

Image may be NSFW.
Clik here to view.

Now, back to web development with TMS WEB Core and TMS FNC UI Controls installed, you have an FNC tab of UI controls available on the tool palette.

Image may be NSFW.
Clik here to view.


As you expect it, you drop the TMS FNC UI control on the web form, you set its properties, add event handlers, add code and you see the FNC UI control in the web application after pressing F9 to run the application. The FNC UI Control appears WYSIWYG in the web form designer as it appears in the browser and in the browser, it also nicely takes advantage of zoom in/out or retina/high DPI handling. Go ahead and play with the FNC controls demos in your browser of choice:

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.


TMS RADical WEB, connecting to data

As Delphi developers we are used to frameworks and components to take the chore out of using databases. Ever since Delphi 1, database handling was abstracted by the TDataSet & TDataSource. Wouldn't it be nice (and mainly productive as this is what is important after all) if this exact abstraction model allowed us to create web applications consuming data? Exactly that goal is what we wanted to achieve with TMS WEB Core, only technically under the hood things are RADically different from the implementation of Delphi 1 like datasets and datasources. So, with TMS WEB Core, you have your DB-aware edit, label, combobox, datepicker etc... and these can be hooked up to a datasource and a datafield can be specified. The dataset though is in this case a wrapper component that will under the hood do its work getting data or updating data via the use of REST HTTP calls to microservices exposed on a data server. As our TMS XData product already provided exactly that: exposing your databases via REST HTTP calls, we extended it to have a web XData client component so you can from Delphi, create a web application against an XData client and hook up your DB-aware components to an XData dataset, pretty much the same way as you can for VCL or FMX native client applications.

For the sake of demo purposes, we have created a first sample app with a web client dataset. This web client dataset gets its data in JSON format from a server via a HTTP REST call. This allows to view and edit the data in the web client dataset but won't do updates server side so that it isn't possible to 'fiddle' with the data and break the sample this way.

Here you can see a form editing contact info with several DB-aware controls, including a DB-navigator.

Image may be NSFW.
Clik here to view.


When the dataset is connected to the server, the DB-aware controls display and can edit the data.

Image may be NSFW.
Clik here to view.


Connecting to an XData based server is one possible way to hook up to databases. You can implement your own interfaces to a database server via REST HTTP calls and over-time we plan to create and offer connectors to such server as Embarcadero RAD server, Google Cloud datastore and several others...

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, open to other Javascript frameworks

By design, the Pascal to Javascript compiler that is integrated in the Delphi IDE via TMS WEB Core provides a thin, direct and thus high-performance layer to Javascript. This also means that it is fairly easy to interface directly to all kinds of functionality offered by Javascript libraries including Javascript UI controls libraries.

The proof of the pudding is in the eating and to begin with, TMS WEB Core will offer out of the box a complete set of Pascal components that wrap the jQuery jQWidgets UI control set.

Image may be NSFW.
Clik here to view.


This is a very complete & consistent jQuery UI control set including masked editors, ribbon, calendars & datepicker, powerful paging grid, ... and many more.

We are busy creating this set of easy to use wrappers in agreement and cooperation with the jQWidgets company. A first set is already available in the TMS WEB Core technology preview available today. This is the list of controls on the Delphi tool palette we have so far covered and the team is at this very moment busy tackling the jQWidgets grid:

Image may be NSFW.
Clik here to view.


Via Delphi components you can drop these jQuery controls on the form, set properties, implement event handlers etc...

Image may be NSFW.
Clik here to view.


To interact with these jQuery controls, you will as such fully use the Pascal language. For deployment, all you need to do is put the jQWidgets Javascript & CSS files into the subfolder jQWidgets of your web project. Over time & steered by your feedback and requests, we will consider adding many more thin Pascal wrapper classes for other interesting Javascript libraries, frameworks, UI controls.

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers. The jQWidgets UI controls library files can be obtained from https://www.jqwidgets.com. jQWidgets offer a free for non-commercial use license as well as licenses for commercial use.

TMS RADical WEB, using HTML & CSS for design & layout of your application pages

By default, the Delphi form designer serves as a WYSIWYG design surface for your web application forms. This means that the UI controls on the Delphi form will appear absolute positioned on the web page. For page layout & organization, there are the typical Delphi container controls like a panel, groupbox, scrollbox, gridpanel.

Image may be NSFW.
Clik here to view.


The parent/child relationship of the Delphi controls is also reflected on the produced web pages. Additional facilities like control alignment, anchoring and a splitter control are available to let you and the end user control the layout of the pages. In this default mode, everything is as such very familiar to Delphi developers and users of Delphi VCL Windows applications and sometimes this similarity is desirable. However, the TMS WEB Core framework is also completely open to have the page layout designed directly from HTML & CSS. The architecture of the framework provides for separating design & code and even have the design done by people with a role, i.e. graphical designers.
So, how is this separation handled? Fortunately, in a very easy and straightforward way. The link between HTML and the UI controls and code used in the Delphi IDE is based on the unique HTML element ID. Every TMS WEB Core control has a property ElementID. When the ElementID is not used, i.e. left empty, the HTML elements the control consists of is generated by the TMS WEB Core framework. When the ElementID is specified, the HTML element found is hooked up to the Pascal class for the control. This means that property accessors directly get and set values from the HTML element and the various HTML element Javascript events are hooked up the class and exposed as Pascal event handlers.
Here the TWebMemo is hooked up via the ElementID property to a TEXTAREA HTML element with ID set to “mem” and already in the HTML file.

Image may be NSFW.
Clik here to view.


The software developer and the graphical designer can collaborate by simply ensuring that the designer provides the HTML element IDs to the software developer or the software developer can provide a list of IDs of controls needed to the graphical designer. It speaks for itself that using this technique empowers us to take advantage of responsive design for TMS WEB Core web applications. When the HTML template for the page is applying responsive design techniques, i.e. different layouts for different device screen sizes, the UI controls will appear where the designer defined these should appear depending on the screen size. That is not all though. It is also possible to let the Delphi designed UI be generated in the body part of a HTML page or in any specified HTML container element in a HTML page. As such, a graphical designer could create a page layout with a header, footer and other elements in the HTML page and add a specific area via a HTML DIV or SPAN element where the Delphi designed UI will be generated in. To do so, all that is needed is set to the ID for the HTML element where the form should be generated via the Form.AppContent property. Finally, each UI control also exposes an ElementClass property. Via this ElementClass property a CSS style can be specified for an UI control. Via this way for example, it is very easy to use a popular framework like bootstrap. It is sufficient to set the bootstrap CSS class names to the UI controls on the Delphi form designer by their ElementClass properties.

Image may be NSFW.
Clik here to view.

Here the ElementClass property of the edit control on the form is set to the bootstrap ‘form-control’ style:

One of the demos included in the TMS WEB Core framework shows this. By simply changing the bootstrap theme via changing the reference in the HTML page template, the appearance of the web application will adapt automatically.

Demo without styling:
http://www.tmssoftware.biz/tmsweb/demos/tmsweb_simple/

Demo with bootstrap styling applied:
http://www.tmssoftware.biz/tmsweb/demos/tmsweb_bootstrap/

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, using common web functionality & consuming cloud services

In web applications, we have come to expect that we can easily integrate audio, video or services like Youtube or Google Maps to embed video or geographical functionality. TMS WEB Core provides a multimedia component with which audio & video can be played. It provides a control that makes it dead-easy to add a Youtube video in a web application. All that is needed is setting the Youtube video ID and that's it. Also adding a map with Google Maps is easy. Drop the Google Maps component on the form and you see the map in the web application. The component offers right now already access to markers, zooming and panning and we plan to extend it over time with many more capabilities all easily accessible in Pascal code in a RAD way.

procedure TForm4.WebButton2Click(Sender: TObject);
var
  lat,lon: double;
begin
  lat := 48.8566;
  lon := 2.3522;
  WebGoogleMaps1.SetCenter(lat,lon);
  WebGoogleMaps1.AddMarker(lat,lon,'Paris');
end;

procedure TForm4.WebButton3Click(Sender: TObject);
var
  lat,lon: double;
begin
  lat := 51.5074;
  lon := 0.1278;
  WebGoogleMaps1.SetCenter(lat,lon);
  WebGoogleMaps1.AddMarker(lat,lon,'London');
end;

Image may be NSFW.
Clik here to view.


And of course, you can also experience this demo live.

Also, in a non-visual way, access to cloud services is possible. For consuming OAuth 2.0 based cloud services, there is a OAuth web client. Alternatively, for more strict & secure purposes, a server side accessor helper will be needed. At this time, there is a sample component demonstrating access to Google calendar as well as access to our myCloudData.net service. It is clear that over time, we will add more out of the box ready web clients for other cloud services as well as helpers to facilitate server-side cloud service access.

Image may be NSFW.
Clik here to view.


Image may be NSFW.
Clik here to view.


Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, debugging your code

Given TMS WEB Core is based on a Pascal to Javascript compiler with the Javascript code running in the browser, there is not a direct way to debug the code from the Delphi IDE. From the IDE, the Javascript code is generated and the browser is launched with the HTML page URL. After launching the browser, there is no further interaction between the IDE and the browser. Of course, since modern browsers come with a Javascript debugger integrated, you can debug the web applications this way directly from the browser. Of course, debugging this way means you need to need to be familiar with Javascript and figure out how the Javascript you step through corresponds to the Pascal code in your web application. Although this is still a possible way to debug, the Pascal to Javascript compiler provides for a way easier method to debug your code as original Pascal code when using the Google Chrome or the Mozilla Firefox browser debugger.

Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.


So, when you launch your web application in debug mode, with the help of an automatic generated map file, the Google browser debugger allows you to step through your original Pascal source code, inspect values, use watches, set breakpoints etc.. pretty much the same way as you would do from the Delphi IDE. So, all in all, this offers excellent debugging facilities for your web applications when using the Google Chrome browser or Mozilla Firefox browser.

Image may be NSFW.
Clik here to view.


So, with TMS WEB Core, if you compile in debug mode, this extra map file is generated that allows you to debug from the browser in Pascal code and when you compile in release mode, this map file is not generated and your Pascal code is not visible to users.

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, history, the team and future

Image may be NSFW.
Clik here to view.


There is the famous quote: "Everything starts with a dream" and many years ago, Michael Van Canneyt, one of the main contributors to the Lazarus and Free Pascal compiler project had the dream of having the Pascal language as a first-class language for creating web applications in pretty much the same way as Delphi developers can since 1995 create first-class Windows applications with the Pascal language and VCL.
Michael Van Canneyt did years of research on ways to achieve this goal, including what the best approaches are to create a high-performance Pascal to Javascript compiler and how to best map the Delphi RTL on Javascript. When Michael Van Canneyt shared his dreams with Detlef Overbeek, editor of the Blaise Pascal magazine, Detlef was so enthusiast that he initially funded the further development of this idea and this enabled to involve Mattias Gaertner to help the development of the compiler. Realizing much more would be needed than just a compiler, Detlef Overbeek got in touch with Bruno Fierens, founder & director of TMS software. Given the expertise of TMS software in UI control frameworks, bundling the forces would finally enable the dream to come true. Bruno Fierens was so thrilled by the idea of having the ability to create modern web applications in a component-based RAD way with the strictly typed and object oriented Pascal language from the Delphi IDE that he put a big part of the TMS team behind the project and even attracted some more brilliant minds to realize this goal. Over one year now, this team closely worked together to bring a first version of the product under the TMS RADical WEB umbrella: TMS WEB Core. The power team that brought this first part of the dream to reality is at this moment:

Bart Holvoet: Expert at TMS software in web development + cloud services and responsible for standard TMS WEB Core UI controls and jQuery control wrappers

Bruno Fierens: Embarcadero MVP, TMS software founder, director and responsible for the TMS RADical WEB strategy & overall product architecture

Detlef Overbeek: Editor of the Blaise Pascal magazine and never-ending source of inspiration, motivation & ideas

Holger Flick: Embarcadero MVP and TMS WEB Core evangelist, QA, training and UX expert and advisor

Masiha Zemarai: Marketing manager at TMS software responsible for TMS WEB Core sales & marketing

Mattias Gaertner: Compiler engineer responsible for the Pascal to Javascript compiler

Michael Van Canneyt: Architect of compiler and RTL and overall technical advisor

Pieter Scheldeman: Architect at TMS software responsible for the FNC framework and web-enabling the FNC framework for TMS WEB Core

Roman Kassebaum: Embarcadero MVP and responsible for the TMS WEB Core IDE integration

Sanjay Kanade: Software developer at TMS software developing web-enabled FNC UI controls

Wagner R. Landgraf: Architect of TMS Business Subscription line of tools and responsible for the XData client for TMS WEB Core



We have many plans for extending the capabilities of this technology and reach into new territories with new products under the TMS RADical WEB umbrella. Our roadmap for the next years is filled with ideas and we especially look forward to all your ideas & wishes to further extend and steer the plans for innovative new developments.

Image may be NSFW.
Clik here to view.
You feel as excited & thrilled as we are and want to become part of this brilliant top team? We've got much more plans and work to roll-out the full TMS RADical WEB. If you are the bright, motivated talent wanting to help make dreams come true, contact us today!



Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, Easy REST Server integration with TMS XData Client

One very cool feature of TMS RADical WEB (if not the main one) is that it allows Delphi developers to build Web applications that do not need a server connection. It's just HTML and JS files that run in the browser.

But we all know that there are some applications that need to retrieve data from somewhere, and also eventually persist data. We do not need a server to "run" the application, but we eventually might need communicate to a server to ask for data, perform centralized operations, authentication, etc.

While you can use any API server you want from the Web application, when using TMS XData to build the server your life will be way easier:


  • First, because with TMS XData you can write your backend server using Delphi and Pascal.
  • Also, because TMS XData is simply way too productive - it's very easy and fast to publish entities directly from database and to create service operations in a snap.
  • And, finally, because TMS XData provides first class support to TMS WEB Core, providing components that make it very easy and straightforward to connect to a XData server

The following screenshot shows the TMS XData Web Client demo in action. It's a sample that connects to a public XData REST server that holds information about music artists, albums, genres and tracks. With this demo you can retrieve and modify data from this server.

Image may be NSFW.
Clik here to view.


Note that this demo is dynamic. It means you can simply change the URL of server and it will work with any TMS XData Server you might have, regardless of the entities it publishes. The server provides the metadata for the whole API, and the client loads it at runtime allowing you to access the API in a very high level.

Also design-time components are available for you to simply assign properties and set handlers for the events that will fire when the server request is finished.

Image may be NSFW.
Clik here to view.


In case you're curious about how it's accomplished, here is the full source code for the implementation section of the single unit of the demo. The interface part was removed just because it's a bunch of declarations of the visual control fields.
procedure TForm1.btDeleteClick(Sender: TObject);
begin
  XDataWebClient1.Delete(SelectedEntitySet, TJSObject(TJSJSON.parse(DeleteMemo.Lines.Text)));
end;

procedure TForm1.btGetClick(Sender: TObject);
begin
  XDataWebClient1.Get(SelectedEntitySet, SelectedId);
end;

procedure TForm1.btListClick(Sender: TObject);
begin
  XDataWebClient1.List(SelectedEntitySet, edQuery.Text);
end;

function TForm1.SelectedEntitySet: string;
begin
  Result := cbEntitySets.Items[cbEntitySets.ItemIndex];
end;

function TForm1.SelectedId: Integer;
begin
  Result := StrToInt(edId.Text);
end;

procedure TForm1.ShowInfo(const Msg: string; Error: Boolean);
begin
  InfoLabel.Caption := Msg;
  if Error then
    InfoLabel.Font.Color := clRed
  else
    InfoLabel.Font.Color := clWindowText;
  InfoLabel.Visible := True;
end;

procedure TForm1.btPostClick(Sender: TObject);
begin
  XDataWebClient1.Post(SelectedEntitySet, TJSObject(TJSJSON.parse(PostMemo.Lines.Text)));
end;

procedure TForm1.btPutClick(Sender: TObject);
begin
  XDataWebClient1.Put(SelectedEntitySet, TJSObject(TJSJSON.parse(PutMemo.Lines.Text)));
end;

procedure TForm1.WebFormCreate(Sender: TObject);
begin
  ServerLabel.Caption := Format('XData Server URL: %s', [XDataConnection1.URL]);
  XDataConnection1.LoadModel;
end;

procedure TForm1.XDataConnection1ModelLoad(Sender: TObject);
var
  Container: TXDataEntityContainer;
  I: Integer;
begin
  Container  := XDataConnection1.Model.DefaultEntityContainer;

  cbEntitySets.Items.Clear;
  for I := 0 to Container.EntitySets.Count - 1 do
    cbEntitySets.Items.Add(Container.EntitySets[I].Name);
  if cbEntitySets.Items.Count > 0 then
    cbEntitySets.ItemIndex := 0;
end;

procedure TForm1.XDataWebClient1Error(Error: TXDataClientError);
begin
  ShowInfo(
    Format('%s. RequestId: %s. Code: %s. Request Url: %s',
      [Error.ErrorMessage, Error.RequestId, Error.ErrorCode, Error.RequestUrl]),
    True
  );
end;

procedure TForm1.XDataWebClient1Load(Response: TXDataClientResponse);
begin
  InfoLabel.Visible := False;
  if Response.RequestId = 'get' then
    GetMemo.Lines.Text := TJSJson.stringify(Response.Result)
  else
  if Response.RequestId = 'list' then
    ListMemo.Lines.Text := TJSJson.stringify(Response.Result)
  else
  if Response.RequestId = 'post' then
    ShowInfo(Format('New entity created in %s collection.', [SelectedEntitySet]))
  else
  if Response.RequestId = 'put' then
    ShowInfo(Format('Entity updated in %s collection.', [SelectedEntitySet]))
  else
  if Response.RequestId = 'delete' then
    ShowInfo(Format('Entity removed from %s collection.', [SelectedEntitySet]));
end;

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.


TMS RADical WEB, developing custom controls

In November 2016, I created a presentation for Embarcadero CodeRage about creating FNC custom controls. You can find this presentation including its source code here: https://community.embarcadero.com/blogs/entry/developing-user-interface-controls-for-both-vcl-and-fmx-with-bruno-fierens Unless you have been living under a rock the past 2 weeks, you have most certainly seen we have recently introduced the technology preview of TMS WEB Core and with that also the news that the TMS FNC framework is now also web-enabled. So, I thought it was a good moment to revisit this November 2016 CodeRage presentation and see how applicable it still is for creating custom TMS FNC UI controls, but this time for using this in the web!
The good news is that this took me less than 10 minutes to get the original custom TMS FNC UI control I created for VCL, FMX and LCL now also working for the web.

So, what did I have to do?

I started from the unit VCL.TMSFNCFancyTrackbar that contained the source code for the VCL variant of the FNC Fancy trackbar control. I renamed this file VCL.TMSFNCFancyTrackbar to WEBLib.TMSFNCFancyTrackBar.pas as WEBLIB is the prefix for the namespace for the web variant of the FNC controls. Further, for this small test, I manually renamed the unit references in the uses list in WEBLib.TMSFNCFancyTrackBar.pas.

  VCL.Controls,
  VCL.TMSFNCCustomControl,
  VCL.TMSFNCGraphics,
  VCL.TMSFNCTypes,
  VCL.TMSFNCGraphicsTypes;
to
  WEBLib.Controls,
  WEBLib.TMSFNCCustomControl,
  WEBLib.TMSFNCGraphics,
  WEBLib.TMSFNCTypes,
  WEBLib.TMSFNCGraphicsTypes;

I did not touch any other part of the code. Next, I copied the code to instantiate this custom control TTMSFNCFancyTrackBar from the test project to the TMS WEB Core test project:

begin
  tb := TTMSFNCFancyTrackBar.Create(Self);
  tb.Parent := Self;
  tb.Width := 600;
  tb.Height := 200;
  tb.Slider.LoadFromFile('slider.png');
  tb.Thumb.LoadFromFile('thumb.png');
end;

As I knew my app was going to need a PNG file for the trackbar background and the trackbar thumb, I copied the PNG files to the folder where the web application is deployed and from where its files are being served to the browser. 5 minutes later, the web application was running and resulted in:

Image may be NSFW.
Clik here to view.

So, a kind of half working trackbar. The tickmarks are displayed and the position value as well but my trackbar background and trackbar thumb were missing.
Then it dawned on me that the most likely reason of the issue was that my custom control didn’t have OnChange handlers for the TTMSFNCBitmap classes that were used as class properties to hold the trackbar background and thumb. When using the code in a native client application, the loading of the images from file is instant and thus, when the native app starts, the images are loaded and being used immediately to paint the control. So, I had never noticed this before.
In the web this is different. Under the hood, we have implemented TMSFNCBitmap.LoadFromFile() via asynchronous loading of the image file via an XMLHttpRequest() object. This means there is no instant synchronous loading and therefore it means that I need to signal the custom control to refresh itself when the images are loaded. This is achieved by assigning an event handler to the TTMSFNCBitmap.OnChange event and from there, Invalidate the control.

TTMSFNCFancyTrackBar = class(TTMSFNCCustomControl)
…
protected
    procedure ImageChanged(Sender: TObject);
…
end;

procedure TTMSFNCFancyTrackBar.ImageChanged(Sender: TObject);
begin
  Invalidate;
end;

constructor TTMSFNCFancyTrackBar.Create(AOwner: TComponent);
begin
  inherited;
  FThumb := TTMSFNCBitmap.Create;
  FSlider := TTMSFNCBitmap.Create;
  FThumb.OnChange := ImageChanged;
  FSlider.OnChange := ImageChanged;
  …
end;
With this inplace, the TTMSFNCFancyTrackbar custom control looks 100% identical to the native versions created earlier for VCL, FMX and LCL applications:

Image may be NSFW.
Clik here to view.

and yes, also the interaction with keyboard and mouse work fine.

If you already embarked on creating custom FNC controls, this means there is excellent news. With little or no effort, you will be able to use these custom FNC UI controls also in your web applications created with TMS WEB Core!
The full source code of the web version of the TTMSFNCFancyTrackbar can be downloaded here but you can as well easily play with it directly from your browser in this demo app: http://www.tmssoftware.biz/tmsweb/demos/tmsweb_customcontrol/


Well, this is just one approach for creating custom UI controls for TMS WEB Core. This approach offers you to create controls pretty much with the same UI control model as you could from Delphi 1. In another upcoming blog article, we'll present an entirely different way for creating custom UI controls where the control will be fully built-up from HTML elements!

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, technology preview update

We’ve been overwhelmed by the enthusiasm of many users about the news of TMS WEB Core and also the many reactions, feedback, comments of users who immediately got their hands wet with the technology preview.

From all feedback received combined with our internal planning, we’re pleased to inform that there is now a technology preview update available that brings not only many small improvements but also some exciting new features!

The highlight of the technology preview update is the introduction of the jQWidgets jQxGrid UI control. This control can now be easily used from your Pascal code from a TMS WEB Core application. jQxGrid is a high performance jQuery grid with paging, sorting, grouping, editing & filtering capabilities. It also features different column types.

Image may be NSFW.
Clik here to view.


If you get TMS WEB Core 0.9.2 you can start playing with the new grid right-away or you can explore the grid via the online demo.

Second new big feature is that now data-modules, i.e. the TWebDataModule, are also available. The same easy-to-use centralized place for databinding & business logic that we are used to in Delphi VCL or FMX applications is now also available in TMS WEB Core applications.

Image may be NSFW.
Clik here to view.


Also new is a Twitter feed display component. Showing your personal or company Twitter feed integrated in your web application is now as easy as dropping a component and setting your feed name.

Image may be NSFW.
Clik here to view.


We’ve also made it easier to use cookies and query parameters directly from your Pascal code. Getting or settings cookie values is now very easy. You can use code like:

Cookies.Add(‘CompanyNameCookie’,’tmssoftware’, Now + 5000);
Cookies.Add(‘UserNameCookie’,’Bruno Fierens’, Now + 5000);
Cookies.SetCookies;
And there is more!
The IDE integration was also improved with built-in automatic listing of CSS style classnames or HTML element IDs, so you can pick directly from the Object Inspector what CSS style from your HTML template you want to assign to a control or to what HTML element you want to link a control.

Image may be NSFW.
Clik here to view.


Other than this there are numerous smaller improvements in aligning, splitter, Google Maps geolocation, Google maps route display, …

We’ll keep you posted with more updates as we continue to execute the planning and we look forward to hear all your feedback!

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, time for some fun

Last week, our team was brainstorming and as usual, lots of interesting and cool ideas come up. Based on these ideas, we have some more exciting technology being worked on now and coming up soon and you’ll learn about it here shortly. But, from time to time, there are also fun ideas that come up during our brainstorm sessions. One such idea was to check if it wouldn’t be possible to port an existing Pascal game to TMS WEB Core and this way, make the game available via our website for playing it directly online. We thought this was not only a good idea but also a perfect validation to see how well our TMS WEB Core performed in enabling Delphi developers to move existing code over to the web. So, our software architect Pieter Scheldeman, also the architect of the cross-framework, cross-platform FNC framework, searched for some open-source Pascal games. One of the games Pieter found was the Tetris game in the Bianco Games collection from Marco Bianchini: https://torry.net/authorsmore.php?id=800

After checking out the source code of the Tetris game a bit, we were amazed that after less than 30 minutes of work by Pieter, the game was already running in the browser!

Image may be NSFW.
Clik here to view.

You can play with the game for yourself here:

http://www.tmssoftware.biz/tmsweb/demos/tmsweb_tetris

The game does all its painting via the Delphi TCanvas in a custom control. As TMS WEB Core introduces a TCustomControl class with access to a TCanvas object with the same interface as the Delphi TCanvas, the control in which the Tetris blocks fall was working quickly with almost no code changes in the web. It shows the strength of the Pascal to Javascript compiler combined with the component framework we have designed for it.

Have fun playing the Tetris game without needing to install it on your machine. We’re curious and eager to learn if you have more cool challenges to validate our TMS WEB Core technology against.

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

TMS RADical WEB, custom controls using HTML elements

In a previous blog, it was demonstrated how custom controls for TMS WEB Core could be created using the FNC framework and how easy it was to use FNC code that was written for VCL, FMX or LCL applications also for web applications.
In this article, we want to cover custom controls from an entirely different angle. That means custom controls that are built from a hierarchy of HTML elements. The example via which we want to explain building such custom controls is about a commonly used UI concept in web development, i.e. a login panel. This is where the user enters his username & password to authenticate. So, in this article, we’ll show the details how to make a TMS WEB Core custom UI control that represents such reusable login panel.

Image may be NSFW.
Clik here to view.

In terms of HTML, the login panel consists of an outer DIV element. In this DIV, we put different DIV elements to hold label text to indicate where the username HTML INPUT element is and where the password HTML input element is. Finally, there is a HTML BUTTON used to confirm the actual entry and do a login.

From a TMS WEB Core custom control perspective, this means we will create a Pascal class descending from TCustomControl and we’ll override the CreateElement virtual method. This CreateElement virtual method is what is responsible for returning the hierarchy of HTML elements representing the UI control. In this case, the code for CreateElement is:

function TLoginPanel.CreateElement: TJSElement;
var
  br: TJSElement;
begin
  Result := document.createElement('SPAN');
  FCaption := TJSHTMLElement(document.createElement('DIV'));
  FUserInput := TJSHTMLElement(document.createElement('INPUT'));
  FPasswordInput := TJSHTMLElement(document.createElement('INPUT'));
  FPasswordInput.setAttribute('type','password');
  FUserLabelSpan := TJSHTMLElement(document.createElement('DIV'));
  FPasswordLabelSpan := TJSHTMLElement(document.createElement('DIV'));
  Result.appendChild(FCaption);
  Result.appendChild(FUserLabelSpan);
  Result.appendChild(FUserInput);
  Result.appendChild(FPasswordLabelSpan);
  Result.appendChild(FPasswordInput);
  br := document.createElement('BR');
  Result.appendChild(br);
  FButton := TJSHTMLElement(document.createElement('BUTTON'));
  Result.appendChild(FButton);
  FButton.addEventListener('click', @HandleLoginClick);
end;

Here FCaption, FUserLabelSpan, FUserInput, FPasswordLabelSpan, FPasswordInput and FButton are Pascal references to the HTML elements SPAN, INPUT and BUTTON used in the control. You can see that the HTML elements are created with document.createElement(). This is almost as if one would do this in Javascript, but via the Pascal to Javascript compiler, you can see the DOM object document can be used as Pascal object.

One more note about the CreateElement method, you can see that the purpose of the last line in the method: FButton.addEventListener('click', @HandleLoginClick);
is to attach a TLoginPanel method HandleLoginClick to the HTML element ‘onclick’ event handler. The HandleLoginClick method is declared as

function HandleLoginClick(Event: TJSMouseEvent): Boolean; virtual;

To see how this HTML element event handler is eventually hooked up to trigger the TLoginPanel.OnLogin event, see this code snippet from the TLoginPanel class:

TLoginPanel = class(TCustomControl)
private
    FOnLogin: TNotifyEvent;
    function HandleLoginClick(Event: TJSMouseEvent): Boolean; virtual;
protected
   procedure DoLogin; virtual;
published
    property OnLogin: TNotifyEvent read FOnLogin write FOnLogin;
end;

function TLoginPanel.HandleLoginClick(Event: TJSMouseEvent): Boolean;
begin
  DoLogin;
end;
procedure TLoginPanel.DoLogin;
begin
  if Assigned(OnLogin) then
    OnLogin(Self);
end;

To interface our Pascal class with the HTML elements two more virtual method overrides are important. There is the UpdateElementVisual method and the UpdateElementData method. The purpose of the UpdateElementVisual method is to do changes to HTML element properties that affect the UI control visually. The UpdateElementData method is to do changes with respect to data contained in the HTML elements.
For this TLoginPanel control, we expose a few properties to set captions for labels in the UI control as well as the values of the HTML INPUT elements for username and password.

The properties of the TLoginPanel used for the login panel data are:

TLoginPanel = class(TCustomControl)
published
    property CaptionLabel: string read FCaptionLabel write SetCaptionLabel;
    property LoginLabel: string read FLoginLabel write FLoginLabel;
    property Password: string read GetPassword write SetPassword;
    property PasswordLabel: string read FPasswordLabel write SetPasswordLabel;
    property User: string read GetUser write SetUser;
    property UserLabel: string read FUserLabel write SetUserLabel;
end;
The UpdateElementData method is:

procedure TLoginPanel.UpdateElementData;
begin
  inherited;
  FUserLabelSpan.innerHTML := FUserLabel;
  FPasswordLabelSpan.innerHTML := FPasswordLabel;
  FButton.innerHTML := FLoginLabel;
  FCaption.innerHTML := FCaptionLabel;
  (FUserInput as TJSHTMLInputElement).value := FUser;
  (FPasswordInput as TJSHTMLInputElement).value := FPassword;
end;

To customize the look and feel of the login panel, there is a dual approach. The first and classic Pascal like approach is the basic properties are defined to set the background & border color of the panel and the padding and margin of the controls within the panel. The second approach is that the CSS class can be set for the HTML elements used and that also via CSS full customization of look and feel is possible. This leaves the choice to either stick to classical Delphi style RAD development and do all from the form designer or work with separate CSS and perhaps leave the styling to a graphic designer instead of letting the developer do everything.

The visual properties exposed for the TLoginPanel class are:

TLoginPanel = class(TCustomControl)
published
    property BorderColor: TColor read FBorderColor write SetBorderColor;
    property Color: TColor read FColor write SetColor;
    property ElementClassName: string read FElementClassName write SetElementClassName;
    property ElementCaptionClassName: string read FElementCaptionClassName write SetElementCaptionClassName;
    property ElementInputClassName: string read FElementInputClassName write SetElementInputClassName;
    property ElementButtonClassName: string read FElementButtonClassName write SetElementButtonClassName;
    property ElementLabelClassName: string read FElementLabelClassName write SetElementLabelClassName;
    property Margin: integer read FMargin write SetMargin;
    property Padding: integer read FPadding write SetPadding;
end;

The Element*ClassName properties allow to set CSS class names for the control itself (outer DIV), the SPAN elements for the labels associated with the INPUT elements and of course of also for the HTML INPUT and BUTTON elements.

The UpdateElementVisual override becomes:
procedure TLoginPanel.UpdateElementVisual;
var
  strpadding,strmargin: string;
begin
  inherited;
  if Assigned(ElementHandle) then
  begin
    strpadding := IntToStr(Padding)+'px';
    strmargin := IntToStr(Margin)+'px';
    ElementHandle.setAttribute('class',ElementClassName);
    if (ElementClassName = '') then
    begin
      ElementHandle.style.setProperty('background-Color',ColorToHTML(Color));
      ElementHandle.style.setProperty('border', 'solid 1px '+ColorToHTML(BorderColor));
      ElementHandle.style.setProperty('padding',strPadding);
    end;
    ElementHandle.style.setProperty('display','table');
    FCaption.setAttribute('class',ElementCaptionClassName);
    if (ElementCaptionClassName = '') then
    begin
      FCaption.style.setProperty('margin-top',strMargin);
      FCaption.style.setProperty('margin-bottom',strMargin);
      FCaption.style.setProperty('font-weight','bold');
    end;
    FUserInput.setAttribute('class',ElementInputClassName);
    FPasswordInput.setAttribute('class',ElementInputClassName);
    if (ElementInputClassName = '') then
    begin
      FUserInput.style.setProperty('margin-top',strMargin);
      FUserInput.style.setProperty('margin-bottom',strMargin);
      FPasswordInput.style.setProperty('margin-top',strMargin);
      FPasswordInput.style.setProperty('margin-bottom',strMargin);
    end;
    FUserInput.style.setProperty('width','100%');
    FUserInput.style.setProperty('display','table-cell');
    FPasswordInput.style.setProperty('width','100%');
    FPasswordInput.style.setProperty('display','table-cell');
    FUserLabelSpan.setAttribute('class',ElementLabelClassName);
    FPasswordLabelSpan.setAttribute('class',ElementLabelClassName);
    if (ElementLabelClassName = '') then
    begin
      FUserLabelSpan.style.setProperty('margin-top',strMargin);
      FUserLabelSpan.style.setProperty('margin-bottom',strMargin);
      FPasswordLabelSpan.style.setProperty('margin-top',strMargin);
      FPasswordLabelSpan.style.setProperty('margin-bottom',strMargin);
    end;
    FButton.setAttribute('class',ElementButtonClassName);
    if (ElementButtonClassname = '') then
    begin
      FButton.style.setProperty('margin-top',strMargin);
      FButton.style.setProperty('margin-bottom',strMargin);
    end;
    FButton.style.setProperty('float','right');
  end;
end;

Notice how the properties are set when no CSS class is specified for HTML elements or otherwise the look and feel will be determined by the CSS.

The result becomes:
Image may be NSFW.
Clik here to view.

This is the basic look and feel without CSS.

Now, let’s bring bootstrap CSS and some custom CSS in the game and see the new look and feel.

Bootstrap is introduced with adding

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

to the project HTML file and in addition we add CSS in the project HTML file <STYLE> section to control the LoginPanel look & feel:
<style>
    .labelcenter {
      text-align: center;
    }
    .loginpanel {
      padding: 15px;
    }
    .loginpanelelement {
      margin-top: 2px;
      margin-bottom: 2px;
    }
</style>
Now the appearance of the panel becomes:

Image may be NSFW.
Clik here to view.


We have only scratched the surface here of the many possibilities to enrich the TMS WEB Core framework with custom UI controls but we hope we have generated interest and enthusiasm.

Get started today: Technical previews of TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are exclusively available now for all active TMS-ALL-ACCESS customers.

Object Pascal: Declaring Units

Image may be NSFW.
Clik here to view.
Unsplash image

Declaring units in a specific order in code would facilitate the code maintenance in the future.

Introduction

When we're organizing our things, we tend to keep closer to us all objects that we use daily, right?

So it should be with the units of a project.

The order that units appear in the code could facilitate or not the maintenance.

In that article, I will show you what order I use to declare units in my own projects.

Compiler

The units, also known as modules, compose the projects.

Every project must be divided into logical units and make that division it's not always easy, because it involves an abstract and logical level of thinking.

After dividing the project units, we also need to concern with third-party units.

Nowadays it's almost mandatory that we use lib's and frameworks. Mostly, they are Open Source projects.

Such third-party units make our work easier, as they already have ready-made artifacts that speed up the development of projects.

In addition to these third-party units, we also have the default units located in Run-time Library (RTL) or VCL/LCL, which have many interfaces, classes, functions, and artifacts, ready-to-use.

So, what order we should declare such units in our code?

Here is the order that I propose:

    unit MyUnit;
    uses
      // 1. fpc/lazarus/delphi units,
      // 2. 3rd units,
      // 3. my open source units,
      // 4. project units

When the compiler starts parsing your code and it arrives at MyUnit, it will read the units in the sequence in which they were declared — there may be some optimization, but the important thing is the final result, which depends on the order above — and the identifiers (classes, interfaces, functions/procedures, variables and constants) will be "stored in order" in which they were declared.

So, I propose to declare, initially, all units that are standard to the compiler and IDE. Then, all third-party units such as libs and frameworks. After, all units referring to your public projects, be them OpenSource or shared within sectors of your company. Finally, we declare all units of the project itself, that is, the project we are currently working on.

And why is this important?

The reason is because the compiler needs to know in which unit a particular artefact (class, function, etc) is located.

The rule is that:

If you have 3 units (Unit1, Unit2 and Unit3 ) and each has a class named TFoo, the compiler will "inform" your code that TFoo is located in the last declared unit.

For example:

    uses
      Unit1, Unit3, Unit2;

Notice that I reversed the numerical order. First is 1, then 3, and finally 2.

Where is located TFoo class when you'll use it in yourMyUnit?

The answer is: In Unit2.

Because it was declared by last.

Imagine that the compiler is putting a reference table into memory for all the identifiers it finds. First, it finds TFoo when it reads Unit1. Then, it finds it again when it reads Unit3. At this point it overrides the reference that says that TFoo is in Unit1, because it is now in Unit3. Finally, when it reads Unit2 the identifier is repositioned again.

If in that same MyUnit I need to use TFoo from Unit1, I am required to qualify the class with the unit name instead of just using identifier:

    Foo := Unit1.TFoo.Create...

You can see another example here

Sections

In the Object Pascal language we have two places (sections) where we can declare the units that will be used.

We can declare in the interface section or in the implementation section.

Is it worth declaring Units in the implementation section?

In my opinion, no.

In doing so, you will have 2 places to organize the precedence of the Units, meaning you will have more work.

Because the Object Pascal language does not support Circular Reference between Units, one of the reasons for having the option to declare Units in the implementation section is to allow this bi-directional reference between them. However, this also indicates a bad design in the division of the project units.

Conclusion

Defining the order of declaration of the units in each unit of your project can be extremely important to facilitate maintenance and organization.

As you add new identifiers, you will be sure that the compiler will give you "priority" to use the identifiers for your project, without having to prefix it with the unit name.

If you add some identifier and it conflicts with another unit that has the same name, simply prefix that identifier with the name of the unit, either from third parties or from the environment itself. However, this conflict will not exist in the identifiers of the units of your project.

Therefore, in your code, you should better "get closer" units that belong to the project, because they are more used, than from other auxiliary units.

See you.



Viewing all 1006 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>