Archive

Archive for August 21, 2014

Adding support for Font Awesome

August 21, 2014 1 comment

This really made my day. I was busy hacking away at caseBook when I suddenly realized – I have no glyphs that fit the bill. So I googled CSS glyphs and voila – there was Font Awesome, 100% re-usable, CSS based glyphs. Ready to be used.

Font awesome really is awesome

Font awesome really is awesome

Since Smart Mobile Studio hides the HTML template for your project, I had to add a new function for adding a reference to external files. You will find it in qtxutils.pas (see google repository for QTXLibrary), and it goes a little something like this:

class function TQTXTools.addLinkToHead(const aRel,aHref:String):THandle;
var
  mLink:  THandle;
Begin
  //REL: Can be "stylesheet" and many more values.
  //     See http://www.w3schools.com/tags/att_link_rel.asp
  //     for a list of all options
  asm
    @mLink = document.createElement('link');
    (@mLink).href = @aHref;
    (@mLink).rel=@aRel;
    document.head.appendChild(@mLink);
  end;
  result:=mLink;
end;

Next, I went into the project-unit, and added the following to TApplication.ApplicationStarting:

  TQTXTools.addLinkToHead('stylesheet',
  'http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css');

And thats it! You can now use a plethora of CSS glyphs, including spinning cogs and all the whistles and bell’s used by popular high-end javascript websites.

And example would be, for instance, to get a home glyph + animated cog wheel (which rotates perfectly):

  FPanel.handle.style['color']:='#cccccc';
  FPanel.innerHTML:=#'<i class="fa fa-home fa-2x"></i>
    <i class="fa fa-user fa-2x"></i>
    <i class="fa fa-cog fa-spin fa-2x"></i>';
Now that was almost to easy!

Now that was almost to easy!

This really is a perfect example of just how easy it is to absorb already existing JavaScript and HTML5 libraries with Smart Mobile Studio. I could have gone with some hand painted 24×24 pixel png files — but why bother when someone has been kind enough to make such a fantastic library of scalable css based glyphs for the public?

And yes, I realize I just gave you a sneak-peek of caseBook.. It’s taking shape 🙂

Check out Font awesome here: http://fortawesome.github.io/Font-Awesome/

And as always, the QTXLibrary is located on google code, here: https://code.google.com/p/qtxlibrary/

Firemonkey like 3D for all Smart Mobile Elements

August 21, 2014 4 comments
火災猿はクールです

火災猿はクールです

Well, I might as well let the monkey out of the bag. For some time now I have spent a chunk of my spare time exploring the idea of adding 3D to Smart Mobile Studio. Not unlike what Firemonkey provides for Delphi these days. Naturally 3D and Javascript is pretty heavy duty stuff, completely dependent on webGL right? Well not really. In fact, with clever use of CSS Smart Pascal is (or will be) capable of doing most of the practical 3D stuff you find in Firemonkey. But yes, if your app can use webGL (depending on where it runs) that is the absolute best.

What I mean with practical 3D is simply that around 90% of what Firemonkey introduces is, well, a complete waste of time in a business application. I dont mean this in any negative way, I love Delphi and Firemonkey is a fantastic RTL and framework. But a rotating form or spreadsheet is .. well, perhaps not what you want when crunching numbers on a tax report due yesterday.

But Firemonkey really comes into it’s own on mobile devices, where you are almost expected to have widgets that wobble, rotate and gives visual feedback on every touch. So I’m not dizzing Firemonkey here — I am simply saying that for serious scientific or business apps – it’s out of place.

3D and Smart Mobile Studio

CSS3 have some neat features, like being able to position elements in 3d space. So using CSS you can not only animate elements between visual states (keyframe animations), you can apply those animations in 3D space. Meaning that you can rotate a DIV tag (the primary container Smart Pascal custom-controls manages) in X, Y and Z vectors. Here is a little example of a CSS animated cube.

If you define backface-visibility as active, your elements become semi-transparent, and elements behind your element (in 3d space) becomes visible. In the golden days of Amiga demo programming, we called that “glenz vectors”.

Partial classes, the death of plugins

So, the challenge at hand for me, is to provide full 3d support without messing up the RTL (which should be considered as the seed-stone and foundation for SMS apps, bordering on sacred). The only way to do this is to use partial classes. If you dont know what that is you can read up on the topic — but in general it means that you can extend a class anywhere by adding the Partial keyword. And voila, all the new features you add to your partial class, becomes a part of the class you extend.

In other words, plugins have no place in SMS because partial classes completely removes the need for them. A plugin could never really extend a class in the same way anyhow – so it’s no competition at all.

Using the force

Before you start to play around with effects, you really should download and install my QTX library. This is hosted on Google code and contains whatever classes and examples I post here. So use SVN and check it out into your $SMS/Libraries folder (! important !) so the IDE automatically locates the files.

The library also adds a wealth of “missing” tidbits and stuff to the RTL (safely, without messing up anything) so it should be considered “a must have” for all SMS hackers out there.

Simple 3d

Right. For simple 3d effects that you can apply to anything (buttons, lists, checkboxes, labels or whatever) you simply add the unit qtxTransformController (which is in the QTX library). This unit contains a class called TQTXTransformController. You can create an instance of this class, proving the handle of the control you want to play with — and voila, you can rotate your element in whatever X, Y, Z vector you want.

procedure TForm1.AnimateStuff;
var
  mObj: TQTXTransformController;
begin
  mObj:=TQTXTransformController.Create(w3button1.handle);
  mObj.x:=100;
  mobj.y:=100;
  mObj.z:=-50;
  mObj.update;
end;

But all of this is tiresome work. I mean, we cant create transform controllers for each and every element right? It may be kosher for games where you have a fixed number of sprites, but it would take ages to manage for ordinary apps. So my mission at the moment is to merge TQTXTransformController with TW3CustomControl using a partial class — thus exposing the 3D framework directly

Digging into it

Perspective is depth

Perspective is depth

But there are real challenges. For 3D perspective to work properly, it has to be defined by the container. In other words, if you want to rotate a button using the X Vector around it’s own axis — the perspective (Z vector) of the container defines it. In other words, the depth perception is set in the container tag, typically 1000 — meaning that you can then rotate your button and it can have a depth into space of 1000 pixels. Anything deeper looks.. well, a bit 80’s spaceship weirdo demo-ish.

The best way to think about this — is like a tub of water with a plank of wood floating on the surface. The Z vector of the parent defines how deep the tub is, while the X, Y and Z vectors of the element defines how deep you push the plank, and in what end you apply force.

So X = -50 means that you push the left side of the plank down by 50 pixels. X = 50 means that you push the right edge of the plank down by 50 pixels (at which point the left side of the plank goes up by the same amount). The Z factor for the element is how deep the in the water the plank is held.

-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);

The above CSS will look.. well, flat, unless we apply this to the container elements (form, panel etc..):

-webkit-perspective: 1000px;
perspective: 1000px;

Once you apply that snippet of CSS to the container, suddenly the element gains depth and truly looks 3D. We also want the elements to preserve their 3D modifications after an effect has been applied, which is what the “preserve 3d” property is all about:

-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);
transform-style: preserve-3d;

So what is the problem? Well, if you already have a CSS3 GPU effect running on the container – there is no telling what happens. It’s a bit like flipping a coin which effect is annulled by the browser. Hence we need to be clever about this. We need a easy to use, lightweight, ad-hoc framework which is capable of handling possible conflicts, and also – in some cases, merge effects on elements that can handle multiple adjustments.

If you want to see what can be achieved by JavaScript and 3D, check out this demo — which used webGL (sadly, because we want to avoid dependencies on that — but still support it for desktop code). Before we run, we have to make sure we walk properly first. A three.JS port to Smart Mobile Studio is available at Andre’s github repo. Sadly I dont remember the link right now, but will post it later.

Three JS, probably the best 3D library out there

Three JS, probably the best 3D library out there

Anyways, while I research the future of Object Pascal in the world of JavaScript — use my 3d controller to play around with your GUI’s. And dont forget to apply perspective to your containers! Be it the form or a TW3CustomControl (which really is the best way to do this!).