Smart Mobile Studio component writing is actually very simple. It’s much easier than under Delphi – but it involves one aspect that to some Spartans can feel.. well, a bit odd. Namely the fact that you have to take CSS into account.
Continue reading
Author Archives: Jon Lennart
Smart Graphics – Part 5
This is the final installment of our graphics programming overview. If you havent read the previous articles they can be found here:
In this final installment on graphics programming, we will be looking at Sprite3d. This is a very popular graphics library for HTML5 and javascript development which uses the latest hardware acelerated CSS technologies. In fact we found it so useful that we decided not to wrap it – but rather create a full implementation in object pascal from scratch.
Continue reading
Smart Graphics – Part 4
In this installment of our graphics tutorial we will be covering alpha blending (opacity) for controls and images, and also how to load images via code into your Smart applications. If you haven’t read the previous articles they can be found here:
There are also plenty of examples in the documentation, here (see bottom of page) that will get you up and running quickly.
Continue reading
Smart Graphics – Part 3
In our previous articles we covered general concepts related to graphics programming together with basic drawing methods, focusing on those that should be familiar to Delphi programmers. In this article we will investigate double buffering and learn about off-screen bitmaps.
Continue reading
Smart Graphics – Part 2
In the previous article we introduced some general graphical concepts, things like double buffering, per scene rendering, sprites and alpha blending. Time to get our hands dirty and jump into it – how can a Delphi developer leverage his skills under HTML5? Well let’s find out!
Continue reading
Smart Graphics
Every Delphi programmer knows how to use the canvas. Its easy, its straight forward and it can be a source of phenomenal frustration if you want to do more than draw straight lines. Good old TCanvas is, despite it’s ease of use, a dinosaur in terms of modern features. The moment you start thinking about anti-aliasing, alpha blending or anything pertaining to rotation – it’s game over for TCanvas.
A smarter canvas
Smart mobile studio implements (or wraps) the HTML5 canvas directly, which means that you have access to all the latest features. The HTML5 canvas was implemented by Apple (webkit codebase) and is the browser equivalent of their Quartz API. This means first of all that it’s a bit trickier to get going, but on the flipside once you master it you can generate some truly amazing graphical effects.
Before we dig into the canvas, i thought it might be best to get up to speed with some of the terminology you are bound to encounter. Some of the concepts are not bound directly to HTML5 but are loosely related to computer programming in general.
Double buffering
Double buffering simply means that you draw your graphics to an offscreen bitmap rather than directly onto the visible canvas. When you are finished drawing you copy (also called “blitting”) the result to the visible display in one fast operation. This technique reduces flickering and makes movement appear smooth. The reason double buffering works is because there is often a delay between your calls – and the actual pixel memory being altered by the CPU/GPU (graphical processing unit). It greatly depends on the kind of hardware you are running, but either way – double buffering is what people do.
On a side note I can mention that Delphi actually uses double buffering by default. If you look up the drawing mechanism for TWinControl you will find that Delphi allocates a new bitmap, draws the control, then copy the result onto the device context. The problem with Delphi is that it allocates a bitmap for each draw, which is extremely slow. Thankfully, we dont have to care about that under Smart Mobile Studio.
Per scene rendering
Under Delphi whenever you use the canvas and call methods like lineto, circle, ellipse etc. these functions are executed “as is”. So once you issue a call to lineTo the underlying WINAPI draws a line into the bitmap your canvas is connected to. This method is very effective, bare bone and does it’s job well. Sadly it is very tricky to create anything modern with this. It’s perfect for 1990’s user interfaces but doesnt cut it for 2013.
HTML5 doesnt really work this way (nor does quartz) because here everything is based on paths. A path is basically just an array of TPoints that you pre-calculate before anything is drawn on screen. So to draw a line you first have to call beginpath, then issue a moveto and lineto command (which we already know under delphi), and finally you draw the line with a call to stroke or endpath. Here is a code snippet from HTML5 Canvas Tutorials:
canvas.beginPath(); canvas.moveTo(100, 20); // line 1 canvas.lineTo(200, 160); // quadratic curve canvas.quadraticCurveTo(230, 200, 250, 120); // bezier curve canvas.bezierCurveTo(290, -40, 300, 200, 400, 150); // line 2 canvas.lineTo(500, 90); canvas.lineWidth := 5; canvas.strokeStyle := 'blue'; canvas.stroke();
As you can probably imagine, by automating the variables involved you can really get some amazing results with very little effort. Check out this liquid particles demo for instance (click image):
My personal favorite JavaScript demo has to be: or so they say
Also make sure you check out the graphics demos that ship with Smart Mobile Studio for more inspiration! And remember, the smart canvas maps more or less directly to the HTML5 canvas. We have added a few helper routines to make life easier for pascal programmers (and helper classes) but you will have no problems following a HTML5 JavaScript canvas tutorial with Smart Mobile Studio.
Alpha blending
Alpha blending simply means that you can draw graphics that is semi-transparent. Typically alpha blending is associated with 32bit graphics (RGBA) where each pixel or dot on the display is represented by 4 bytes. The first 3 bytes represents red, green and blue while the last byte defines the opacity of the pixel. When you copy a bitmap onto another which uses opacity as an option, it will merge with the existing graphics rather than overlap with it.
Sprites
In the golden days of 16 bit home computers (Amiga and Atari) the hardware supported sprites. A sprite is basically just a small, transparent picture which game programmers use to display and animate characters. In our day of fast processors and high speed 3d effects – there is no longer hardware support for sprites, but the concept of a “sprite” (as a moving graphical element) is still widely used. So if someone uses the term “sprite” or “bob” (the graphical co-processor in the Amiga was called “the blitter”, hence “blitter object”) you what they are talking about.
Next article
In this first installment we have taken a quick look at related concepts that you are bound to meet when programming graphics. Concepts like double buffering, sprites, alpha blending are universal and are deployed on all platforms regardless of language. So it’s handy to get to know these concepts straight away. We have also introduced how the HTML5 canvas works, that it uses paths rather than ad-hoc, brute force like good old TCanvas.
In the next installment we will dive into Smart Mobile Studio and familiarize ourselves with the API and draw some stuff. We will further look at how each of the above concepts work, things like double buffering, in real-life.
Reference material
Scrollcontrol, creating a better menu
Smart Mobile Studio comes with an implementation of the standard, round cornered, iPhone menu – but while handy, there are cases where you want to display more than just some options. What we really need is a scrolling menu that can be easily adapted to display more information. It’s time to dive deeper into the RTL and create a scrolling control.
Continue reading
Working with webSQL
In the current release of Smart Mobile Studio we have finally added database support. Since smart mobile development targets the browser API directly, the classes are more low-level than what we have in delphi, but the flip side is that there are a lot less elements involved and they are very easy to use.
Continue reading
Rethinking navigation, random rant from SMS development
In the previous update of Smart Mobile Studio (not the summer hotfix) we added support for CTRL + CLICK navigation inside the editor. So if you hold down the CTRL key and click a symbol (a method name for example) it would navigate to the declaration or implementation section for that symbol.
Getting this function to work as expected (i.e “like Delphi does it”) is actually quite tricky. Depending on the type of method for instance, being marked as either virtual or abstract, the navigation could result the IDE showing the ancestor implementation rather than the current overridden implementation. In other words, if you have written a class that inherits from a standard class – and then do a CTRL + CLICK on a method declaration – it can actually confuse the IDE and you end up looking at the implementation for the original base class.
Navigation should be linear and recursive. So if you inherit from a class, click a method you have overridden, you should end up at your own implementation. If you further click on your implemented method – you should go directly to the original implementation.
This has now been fixed, and I’ve also started on the reverse navigation (SHIFT + CTRL + CLICK should bring you from implementation to declaration). Once the reverse is in place we can add keyboard shortcuts like SHIFT + Up/Down as well, since that is more or less the same function in a non recursive form. Of-course, the reverse navigation will stop at the interface section of the baseclass since we don’t want to remember the top-level starting point (that could cause some confusion between units). Keep it simple and clean.
Battle for the sun
While we are busy chewing through the fogbugz list of reported issues (and adding new RTL features) we came across a very interesting side effect with relation to graphics. As you probably know modern browsers have a very tight security system built into it. One of the rules is that you cannot call or use resources from other domain (cross domain communication). The exception is JSONP or when the server provides a special header which tells the browser that you can, indeed, use any resources you want.
What I did not know was that the same security system (worthy of Alcatraz) also applies to graphics (!). In fact, your browser regards itself as one domain (127.0.0.1 or machine name to be precise) and the server where you download index.html and other files – as a distinctly separate domain. This is of-course all true in network terms. Your local PC, iPhone or iPad is not the same as your server (hence the concept of “sessions” – which is server controlled due to the fact that HTTP is stateless).
What does this mean? It means that if your app has images stored in your resource folder (added to the project via the IDE, or manually copied into the res folder), there will be limits to how you extract and move the pixeldata. For instance this example:
procedure TForm1.ButtonClick(Sender:TObject); begin FImage.OnLoad := procedure(Sender:TObject) var mData: TW3ImageData; x, y: Integer; begin try //Get the pixel buffer directly mData := FImage.ToImageData; if mData <> NIL then begin //Dump info to stdout WriteLn('Data is valid object'); WriteLn('Width=' + IntToStr(mData.Width)); WriteLn('Height=' + IntToStr(mData.Height)); //Set all pixels to red for y := 0 to mData.height-1 do for x := 0 to mData.Width-1 do mData.Colors[x,y] := clRed; //Apply as background to form Self.Background.FromURL(mData.ToDataUrl); //Release pixel buffer mData.Free; end else begin Raise Exception.Create('Image was NIL!'); end; except on e: exception do ShowMessage(e.Message); end; end; FImage.LoadFromURL('res/parallax.png'); end;
.. will work fine for desktop browsers (safari, chrome and firefox), but fail due to security reasons on the iPhone and iPad (which enforce CORS to the extreme). I’m not sure how beneficial such extreme security measures are to be frank, but that’s another story.
Solutions
In those rare cases where “security exception 18” will cause havoc, the obvious solution is to use the image converter (Tools -> Image converter) to turn your image into a constant and include it as source instead of as an external file. But for normal use (display, move around, rotate etc. ) you wont run into that problem. So it’s only for hard core programmers that like to fiddle with bits and bytes (like myself) that this will be a potential case.
The second solution, which is also what Smart was made to target, is to use phonegap. When you compile your app with phonegap all the security restraints go away, and you can pretty much do everything an ordinary .exe file can – including file access, camera access and the like.
Clearly, one does not simply waka waka into mordor 🙂
Making a slider control
In this mini article we are going to create a normal slider control. It is actually very simple and hardly deserves a full article, but since HTML and the DOM (document object model) have a long and bumpy trail of evolution behind it – some explanation is in order.
Setting it up
Under the DOM, a slider is actually a text-box in disguise. So to create a slider, you simply alter some properties of a normal TW3Editbox and it magically turns into a range-based slider instead. I’m not sure what the programmers behind the DOM thought when they made this rule, but I’m sure they had their reasons.
So, start by creating a new visual application. This also creates a default form for us. Now click the editbox icon from the component palette – and then click on the form. Resize and position the box as you see fit.
Now that we have our editbox lined up, make sure you click CTRL + S (save shortcut) so that the form design data is stored in your project file. Once you have done so, switch over to the code tab. Alter the initializeObject() method by adding the following text:
procedure TForm1.InitializeObject; begin inherited; {$I 'Form1:impl'} W3EditBox1.InputType:=itRange; W3EditBox1.setMin(0); W3EditBox1.setMax(100); w3EditBox1.OnChanged:=Procedure (sender:TObject) var mValue: Integer; begin mValue:=TVariant.asInteger(w3EditBox1.handle.value); writeln(mValue); end; end;
Why the esoteric handle stuff?
The reason we have to access the value property of the DOM element directly (handle always points to the actual HTML element), is because of an old difference in browser API. FireFox supports the older “range” property of the element, but the modern API supported by nearly all browsers today is to obtain the value via the.. well, value property. The Smart RTL sadly used the older variation when it was written, but the next update will have the correct range property.
Creating a list menu
Smart Mobile currently ships with a rather spartan number of custom controls. Originally we were aiming at a rather minimal RTL and only the basic iOS widgets, this is how C# does it when it comes to iOS development. While we have the rounded iphone menu in the IDE, what is missing is a more versatile menu. Both Android and iOS devices have scrollable list menus that are flat and designed to cover the iphone’s entire horizontal width. You can then move around it with one finger, and when you touch a single item without scrolling – that is considered a “click”.
In this little article I’m going to create this list control to demonstrate how easy it is.
Roll your own
First, let’s start with the baseclasses. We are going to keep it very simple, reducing the list to only two classes: one representing a list item – and another representing the actual list.
Since iPhone lists have the capacity to include sub-controls, we are not going to cheat and wrap UL / LI tags, but use fully functional TW3CustomControls as list items. This will give us the freedom to not only style our list items – but to add buttons and whatever we want to each element.
So let’s start by defining a couple of classes:
type (* Generic ancestor *) TLSTCustomMenuItem = Class(TW3CustomControl); (* Array type *) TLSTMenuItems = Array of TLSTCustomMenuItem; (* Menu item *) TLSTMenuItem = Class(TLSTCustomMenuItem) private FCaption: String; procedure setCaption(Const Value:String); protected procedure InitializeObject; override; public property Caption:String read FCaption write setCaption; end; (* selection event *) TMenuItemSelectedEvent = procedure (Sender:TObject;Const aItem:TLSTCustomMenuItem); (* Our menu *) TLSTMenu = Class(TW3ScrollControl) private FItems: TLSTMenuItems; FLastY: Integer; FSelected: TLSTMenuItem; FOnSelected: TMenuItemSelectedEvent; procedure HandleTouchBegins(Sender:TObject;Info:TW3TouchData); procedure HandleTouchEnds(Sender:TObject;Info:TW3TouchData); protected procedure HandleItemTapped(Const aItem:TLSTMenuItem); procedure InitializeObject; override; procedure FinalizeObject; override; procedure ReSize;override; public property OnItemSelected:TMenuItemSelectedEvent read FOnSelected write FOnSelected; property Items:TLSTMenuItems read FItems; function Add(Const aItem:TLSTCustomMenuItem):TLSTCustomMenuItem;overload; function Add:TLSTMenuItem;overload; end;
The FItems array is basically a list of the child items. This is actually a bit overkill, since TW3Component already support parent/child management – but it’s Friday so I just used an array to keep track of things.
Ok, let’s move on a bit and look at the implementation for our item:
//########################################################################### // TLSTMenuItem //########################################################################### procedure TLSTMenuItem.InitializeObject; begin inherited; Self.Color:=clWhite; Self.Height:=32; end; procedure TLSTMenuItem.setCaption(Const Value:String); begin FCaption:=Value; innerHTML:=Value; end;
This is a fairly simple setup. We give our item a default color of white, and set the height of the listitem to 22 pixels. The setcaption() is actually one you should look out for. As you can see i use the innerHTML property to set the caption. This is fine for this example – but it will kill all child controls (!). For a proper title, create a child TW3Label and position it by overriding the resize() method.
Ok, let’s look at the main scrolling control. The actual scrolling behavior is inherited from TW3ScrollControl which is a minimalistic, touch based scrollbox. Unlike the Delphi scrollbox – the smart version contains a sub-control called “content” which is what is actually moved.
This means that when we populate our listbox, we have to create our list-items with “content” as parent. Ok, let’s have a look:
//########################################################################### // TLSTMenu //########################################################################### procedure TLSTMenu.InitializeObject; begin inherited; FItems.SetLength(0); end; procedure TLSTMenu.FinalizeObject; begin FItems.Clear; inherited; end; procedure TLSTMenu.HandleTouchBegins(Sender:TObject;Info:TW3TouchData); begin (* remember current scroll position *) if (sender<>NIL) and (sender is TLSTMenuItem) then begin FLastY:=Content.Top; FSelected:=TLSTMenuItem(sender); end else begin FLastY:=-1; FSelected:=NIL; end; end; procedure TLSTMenu.HandleTouchEnds(Sender:TObject;Info:TW3TouchData); begin (* No scrolling but touched? Its a tap *) if Content.Top=FLastY then begin if (FSelected<>NIL) then begin if (FSelected=sender) then begin HandleItemTapped(FSelected); FLastY:=-1; FSelected:=NIL; end; end; end; end; procedure TLSTMenu.HandleItemTapped(Const aItem:TLSTMenuItem); begin if assigned(FOnSelected) then FOnSelected(self,aItem); end; function TLSTMenu.Add:TLSTMenuItem; begin result:=TLSTMenuItem(Add(TLSTMenuItem.Create(Content))); result.OnTouchBegin:=HandleTouchBegins; result.OnTouchEnd:=HandleTouchEnds; end; function TLSTMenu.Add(Const aItem:TLSTCustomMenuItem):TLSTCustomMenuItem; begin if aItem<>NIL then begin if FItems.IndexOf(aItem)<0 then begin BeginUpdate; FItems.Add(aItem); EndUpdate; content.LayoutChildren; end; end; result:=aItem; end; procedure TLSTMenu.ReSize; var mItem: TLSTCustomMenuItem; mSize: Integer; x: Integer; dy: Integer; begin inherited; for x:=0 to FItems.Length-1 do begin mItem:=FItems[x]; if mItem.visible then inc(mSize,mItem.height); end; Content.Height:=mSize; dy:=0; for x:=0 to FItems.Length-1 do begin mItem:=FItems[x]; if mItem.visible then begin mItem.SetBounds(0,dy,width,mItem.Height); inc(dy,mItem.Height); end; end; end;
Everything here should be fairly straight forward. We hook the onTouchBegins and onTouchEnd events on all our list items. Why? Because we have to solve a little problem. Since our list is scrollable, that means we have to somehow distinguish between a scroll swipe (up or down) and an actual tap. To achieve this we set down a simple law: If the Y position of the list is in both events, then we consider that a tap (or selection). If you have moved your finger on the other hand, then the tap is ignored.
The final procedure, namely resize, does two things: first, it calculates the total height of all the list items and size the content control accordingly. Then it loops through and positions the child elements.
Styling
Ok, with the behavior out of the way – we just need to add one final piece: namely styling. So double-click on the project CSS file and add the following:
.TLSTMenuItem { -webkit-user-select: auto; background: #FFFFFF; border-bottom: solid 1px #9A9A9A; font-family: "Helvetica Neue", Helvetica, sans-serif; font-size: 17px; color: #888888; }
Let’s give the control a test-drive, so we add the unit to our mainform’s uses clause, create an instance, and add some items:
unit Form1; interface uses w3system, w3graphics, w3ctrls, w3components, w3forms, w3fonts, w3borders, w3application, unit1; type TForm1=class(TW3form) private { Private methods } {$I 'Form1:intf'} FMenu: TLSTMenu; procedure HandleItemSelected(Sender:TObject;Const aItem:TLSTCustomMenuItem); protected { Protected methods } procedure InitializeObject; override; procedure FinalizeObject; override; procedure StyleTagObject; reintroduce; virtual; procedure Resize; override; end; implementation //############################################################################ // TForm1 //############################################################################ procedure TForm1.InitializeObject; var x: Integer; begin inherited; {$I 'Form1:impl'} W3HeaderControl1.Title.Caption:='Form header'; w3HeaderControl1.BackButton.Visible:=False; FMenu:=TLSTMenu.Create(self); FMenu.Color:=clWhite; FMenu.StyleClass:='TPDFMenu'; FMenu.Content.height:=120; FMenu.Content.color:=clGreen; FMenu.OnItemSelected:=HandleItemSelected; FMenu.BeginUpdate; try for x:=1 to 20 do FMenu.Add.Caption:='List item #' + IntToStr(x); finally FMenu.EndUpdate; end; end; procedure TForm1.FinalizeObject; begin FMenu.free; inherited; end; procedure TForm1.HandleItemSelected(Sender:TObject;Const aItem:TLSTCustomMenuItem); begin self.W3HeaderControl1.Title.Caption:=aItem.innerText; end; procedure TForm1.Resize; var dy: Integer; begin dy:=W3HeaderControl1.top + W3HeaderControl1.height + 2; FMenu.SetBounds(0,dy,width,height-dy); inherited; end; procedure TForm1.StyleTagObject; begin //Custom styling end; end.
As you can see from the code, we catch the touch events and change the title of a header control we added to the form. This makes it quite easy to see what you are doing.
You can download the project file here (zip archive) and play with it!
Box2d support
The ever creative Christian W. Budde is working on a wrapper for the famous Box2d library for Smart Mobile Studio.
What is Box2D?
Box2D is an open source C++ engine for simulating rigid bodies in 2D. Box2D is developed by Erin Catto and has the zlib license. While the zlib license does not require acknowledgement, we encourage you to give credit to Box2D in your product.
Box2D was converted from C++ to Javascript, which is the version Christian has based the Smart version on.
You can check out a live Smart compiled demo here!
Note: You can grab the shapes with the mouse and throw them around 🙂
The Smart Bible, book in the making
We are happy to announce that the ever productive Primož Gabrijelčič, who has followed Smart Mobile Studio from the beginning and contributed immensely, is busy writing a book on our flavor of Object Pascal. The book will be the defacto bible for HTML5 programming with Object Pascal and cover Smart Mobile Studio in depth.
The book goes through the primers, such as data-types, enumerations, arrays, records, anonymous records and language structures – but also more advanced topics like regular expressions, the layout library, touch and gesture, accelerometer, local storage, networking and serious graphics programming.
Head over to his blog and get a preview.
You should also show your interest at the publishers site.
Update:
Two chapters of the book is finished, and the book is now available for purchase!
Read more on the authors new Smart-blog: www.smartprogrammer.org
Creating a progress indicator
One of the things we did not have time to add for version 1.0 is a simple, graphical progress indicator. These are components we regard as standard in the world of delphi or freepascal – so it really should have been added. But, due to the nature of the VJL it’s very simple to make one. And in this little post I will show you how.
It is important to recognize that under smart, while we are striving to create a truly visual design environment (which is right now only at it’s very beginning), you are expected to write your own components. Writing a mobile application under monotouch (c#) or objective C would likewise demand that you write controls, and indeed – if you want your app to be unique then you must take the plunge. But under smart you only have to worry about a fraction of variables opposed to a delphi component. So let’s get cracking.
Chose your ancestors wisely
Beneath the nice object pascal surface, you are really programming the document object model. As such, all components are in reality html tags which are created and inserted “on the fly” when you create a control (or, when you constructor is called). With the advent of HTML5 the browser suddenly got a new type of tag that is different from all the rest, and that is the canvas tag. The canvas tag means you can define a square region and draw the content yourself via a canvas. So it’s pretty close to what we delphi developers have worked with for over a decade.
We have wrapped and isolated this special tag in the base control TW3GraphicControl. What you get with this control is that it automatically created a canvas tag and also updates the size and proportion of that surface should you alter the width or height properties. This is also where the paint() and invalidate() methods come into play.
Here is the complete unit of a very, very basic progress bar. Another way to do it would be to use TW3CustomControl as the base, and then have a child control inside it that you size accordingly. That would probably be cooler since you could add an animated background to it so it looks more “alive”.
unit w3progress; interface uses w3system, w3graphics, w3components; type TW3ProgressBar = Class(TW3GraphicControl) private FMax: Integer; FPos: Integer; Procedure setmax(aValue:Integer); procedure setpos(aValue:Integer); protected procedure Paint;Override; public property Max:Integer read FMax write setMax; property Position:Integer read Fpos write setpos; End; Implementation Procedure TW3ProgressBar.setmax(aValue:Integer); Begin if aValue <> FMax then begin FMax:=TInteger.EnsureRange(aValue,0,MAX_INT); if Fpos > FMax then FPos:=FMax; Invalidate; end; end; procedure TW3ProgressBar.setpos(aValue:Integer); begin if aValue <> FPos then begin FPos:=TInteger.EnsureRange(aValue,0,FMax); Invalidate; end; end; procedure TW3ProgressBar.Paint; var mRect: TRect; mFill: TRect; mPercent: Integer; mpixels: Integer; Begin // make clientrect mRect:=TRect.Create(0,0,Width,Height); //Clear background with random color canvas.fillstyle:=ColorToWebStr(clWhite); canvas.fillRect(mRect); //calculate totals to percent, and percent to pixels mFill:=mRect; mPercent:=TInteger.PercentOfValue(FPos,FMax); mPixels:=Round(Width * mPercent / 100.0); mFill.Right:=mPixels; inc(mFill.Right, mFill.Left); // fill in gauge region canvas.fillstyle:=ColorToWebStr(clGreen); canvas.fillRect(mFill); //show percent canvas.font:='10pt verdana'; canvas.FillStyle:='rgb(255,0,0)'; canvas.FillTextF(IntToStr(mPercent) + ' %', width div 2,(Height div 2) + 4,MAX_INT); end; end.
Using the control in your own projects
First, add a new unit to your project, then copy and paste in the code above. Now go back to your form unit, and make sure you add w3progress to the uses clause. Then you can do something like this:
// Add this to your forms private section FMyProgress: TW3ProgressBar // add this to your form InitializeObject method FMyProgress:=TW3Progressbar.Create(self); FMyprogress.setBounds(10,10,100,32); FMyprogress.max:=300; FMyprogress.position:=128;
Children books, games and smart
It’s been a while since I have written anything in the developers log, so I thought it would be nice to share two new avenues of the web marked that can benefit from smart mobile studio. In fact, I’m scheduled for a meeting with a Norwegian publisher regarding our upcoming command-line compiler. There is a huge demand for template based projects in the multimedia scene (where only the content is changed but the code remains the same).
Adobe PDF embedding of javascript
If you own an IPad and have children you will no doubt have noticed how much attention children give to iPad games, books and media. I have a 5 year old daughter that have no interest what so ever in computers, PlayStation or the sorts – but the moment she sat down with the iPad all that changed. I don’t know how many interactive books we have bought for her since we got the iPad but it’s quite a few. So where computers and digital gadgets used to be the domain of a predominantly male group in society – the ability to touch and interact with the devices is changing all that.
One of the latest advances in rich media (or should we say: interactive books that includes media) is not simply that they use javascript -but that the latest additions by Adobe to their PDF format is pretty much tailor made for iBooks and Amazon’s reader. But someone has to program the effects and movements of images using javascript (Adobe actually started adding javascript support 10 years ago, but hardly anyone have noticed that is not in the publishing business).
This is perfect for smart mobile studio which is capable of producing advanced yet compact apps that makes full use of hardware acceleration and all the latest web technologies. So if you’re into graphics and know smart – then this is absolutely knowledge publishers will be interested in. You wont believe some of the prices these publishers pay just for some javascript animations (I was gobsmacked by it). And with smart you can compete not only in terms of code complexity, but also in time to deliver.
Games and multimedia
Javascript games is becoming more and more popular. I really had to see it for myself to believe it, but kids today don’t grow up with or care about Amiga’s or commodore 64’s – they grow up with the browser. My 9 year old son loves to play online games but to my surprise, he is more interested in either retro games (super mario, sonic etc. in an emulator) or javascript games. He occasionally plays a game of FIFA on the PlayStation 3, but his generation prefers to play javascript games.
A good javascript game that can run in any webkit browser (we also support FireFox) can go a long way. Since smart compiles to javascript it can be played on all operative systems (linux, mac, windows, whatever has a modern browser, even my TV runs smart apps) and reach all mobile phones and pads at the same time. With a dedicated server and a REST API you could do a lot of cool stuff.
And one of our advantages that the others dont have, is quite frankly classes. Take something simple like hardware accelerated graphics. Sounds easy yeah? Well actually it’s not, at least not when you are hacking away in a javascript notepad editor, having not only to code the game – but also create the OOP layer as well (or use a framework that mimic these things). Most javascript developers end up with canvas games, because mixing pixel graphics with other elements is — well, let’s just say it quickly turns into a mess after 10.000 lines of javascript.
I invented the term ‘Object-Oriented’, and I can tell you I did not have C++ in mind.
-Source: Alan Kay. Creator of Smalltalk.
Since smart comes with a full implementation of sprite3d, reverse engineered in object pascal — creating responsive and blistering fast javascript games is really not that hard. And we have the benefit of classes, so our monsters can inherit things like behavior, animations and so on. For us coming from delphi we take that for granted, but it’s actually not something we should take for granted – because in a lot of languages you are expected to type quite a bit of code before you even see a pixel on screen.
Had I not been busy with the first smart update, I would probably be coding a Dune II clone right now.