Smart Mobile Studio
  • News
  • Forums
  • Download
  • Store
  • Showcases
    • Featured demos
    • The Smart Contest 2013, Round 1 – Graphics
  • Documentation
    • Get the book
    • System requirements
    • Prerequisites
    • Getting started
      • Introduction
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • Themes and styles
    • Project types
      • Visual project
      • Game project
      • Console project
    • Layout manager
    • Networking
      • TW3HttpRequest
      • TW3JSONP
      • Loading files
  • About

Monthly Archives: July 2012

Smart Mobile Studio Hotfix 2

Posted on 16.07.2012 by Smart Mobile Studio Team Posted in Developers log, News

We are happy to announce a second hotfix to Smart Mobile Studio (build 1.0.1.122). This hotfix is released due to a couple of important bugfixes (*).

The hotfix deals with the following issues:

  • (*) Designer losing track of controls, not saving changes if one or more forms are open
  • (*) Relative paths when creating a new project was not correct for external files
  • Initial support for dotted unit names
  • Missing <%rescode%> tag in HTML template corrected
  • Support for recursive folders in libraries, rtl and local project directory
  • New compiler switch “devirtualize” added
  • Compiler switch for “optimization” fixed
  • bug in w3inet.pas fixed (event handler failed under obfuscation)
  • w3storage.pas unit rewritten to use THandle rather than TObject references
  • Optimized background compilation and unit scanning (less calls, more accurate)
  • Sourcecode mouse hints
  • Initial support for initialization/finalization
  • Added swap() function on compiler level
  • Fixed resolution of overloaded = & <> operators for classes
  • Fixed support for DateToWeekNumber
  • Added StrToBool
  • Fixed parsing of Unicode literals in JSON
  • Support publishing record properties that map to class functions, class const and class variables

The helper object syntax has been extended to restrict the helper type, and provide Delphi source code compatibility, you can now use the following variants, which also restrict the allowed types

  • class helper for sometype : sometype has to be a clas or metaclass
  • interface helper for sometype : sometype has to be an interface
  • record helper for sometype : sometype has to be a record or base type

Getting the update

Simply uninstall your current version of Smart Mobile Studio and download and install the latest demo from this website.

Sincerely

The Smart Mobile Studio Team

Hotfix release

Creating a list menu

Posted on 13.07.2012 by Jon Lennart Posted in Developers log 4 Comments

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&lt;&gt;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&lt;&gt;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&lt;&gt;NIL then
    begin
      if FItems.IndexOf(aItem)&lt;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: &quot;Helvetica Neue&quot;, 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 &#039;Form1:intf&#039;}
    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 &#039;Form1:impl&#039;}
  W3HeaderControl1.Title.Caption:=&#039;Form header&#039;;
  w3HeaderControl1.BackButton.Visible:=False;

  FMenu:=TLSTMenu.Create(self);
  FMenu.Color:=clWhite;
  FMenu.StyleClass:=&#039;TPDFMenu&#039;;
  FMenu.Content.height:=120;
  FMenu.Content.color:=clGreen;
  FMenu.OnItemSelected:=HandleItemSelected;

  FMenu.BeginUpdate;
  try
    for x:=1 to 20 do
    FMenu.Add.Caption:=&#039;List item #&#039; + 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.

Scroll list galore

Scroll list galore

You can download the project file here (zip archive) and play with it!

Box2d support

Posted on 04.07.2012 by Jon Lennart Posted in News
Box2d running from Smart

Box2d running from Smart

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 🙂

Pages

  • About
  • Feature Matrix
  • Forums
  • News
  • Release History
  • Download
  • Showcases
    • The Smart Contest 2013, Round 1 – Graphics
  • Store
  • Documentation
    • Creating your own controls
    • Debugging, exceptions and error handling
    • Differences between Delphi and Smart
    • Get the book
    • Getting started
      • Introduction
      • Local storage, session storage and global storage
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • pmSmart Box Model
      • Themes and styles
    • Layout manager
    • Networking
      • Loading files
      • TW3HttpRequest
      • TW3JSONP
    • Prerequisites
    • Real data, talking to sqLite
    • System requirements
    • Project types
      • Visual project
      • Game project
      • Console project

Archives

  • December 2019
  • December 2018
  • November 2018
  • July 2018
  • June 2018
  • February 2018
  • September 2017
  • April 2017
  • November 2016
  • October 2016
  • September 2016
  • April 2016
  • March 2016
  • January 2016
  • October 2015
  • September 2015
  • July 2015
  • April 2015
  • January 2015
  • December 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • November 2011
  • October 2011
  • September 2011

Categories

  • Announcements (25)
  • Developers log (119)
  • Documentation (26)
  • News (104)
  • News and articles (16)

WordPress

  • Register
  • Log in
  • WordPress

Subscribe

  • Entries (RSS)
  • Comments (RSS)
© Optimale Systemer AS