Tuesday, August 28, 2012

Gtk3, GObject Introspection and Free Pascal

A while back the Gtk community started a project called GObject Introspection. In short it exports the Gtk and Glib api, as well as many others, to an easily parsed xml format.

The result is gir2pascal.

gir2pascal can create bindings to pascal from any library that supports gobject introspection in just a few moments! The result is that Gtk3 bindings have been created fairly easily for pascal and can easily be updated simply by running gir2pascal against the latest version.

Here is part of the XML code from the Gtk3.gir file relating to the caption of the button:

<class name="Button"
           c:symbol-prefix="button"
           c:type="GtkButton"
           parent="Bin"
           glib:type-name="GtkButton"
           glib:get-type="gtk_button_get_type"
           glib:type-struct="ButtonClass">      
      <implements name="Atk.ImplementorIface"/>
      <implements name="Actionable"/>
      <implements name="Activatable"/>
      <implements name="Buildable"/>
      <constructor name="new" c:identifier="gtk_button_new">
        <return-value transfer-ownership="none">
          <type name="Widget" c:type="GtkWidget*"/>
        </return-value>
      </constructor>
      <method name="get_label" c:identifier="gtk_button_get_label">
        <return-value transfer-ownership="none">
          <type name="utf8" c:type="gchar*"/>
        </return-value>
      </method>      <method name="set_label" c:identifier="gtk_button_set_label">
        <return-value transfer-ownership="none">
          <type name="none" c:type="void"/>
        </return-value>
        <parameters>
          <parameter name="label" transfer-ownership="none">
            <type name="utf8" c:type="gchar*"/>
          </parameter>
        </parameters>
      </method>
      <property name="label"                construct="1"
                transfer-ownership="none">
        <type name="utf8"/>
      </property>
 </class>
  
One improvement over the current (Gtk2) bindings in use is that Pascal objects (not classes) have been used in place of records. The advantage is that GObjects, a C style quasi-object, can be accessed in an object oriented way instead of the flat C functions we use currently.

Here is the corresponding generated pascal code from the XML above:

type
  TGtkButton = object(TGtkBin)
    priv3: PGtkButtonPrivate; 
    function new: PGtkButton; cdecl; inline; static;
    function get_label: Pgchar; cdecl; inline;
    procedure set_label(label_: Pgchar); cdecl; inline;
    property label_: Pgchar read get_label write set_label;
  end;

function gtk_button_new: PGtkButton; cdecl; external;
function gtk_button_get_label(AButton: PGtkButton): Pgchar; cdecl; external;
procedure gtk_button_set_label(AButton: PGtkButton; label_: Pgchar); cdecl; external;

implementation

function TGtkButton.new: PGtkButton; cdecl;
begin
  Result := Gtk3.gtk_button_new();
end;

function TGtkButton.get_label: Pgchar; cdecl;
begin
  Result := Gtk3.gtk_button_get_label(@self);
end;

procedure TGtkButton.set_label(label_: Pgchar); cdecl;
begin
  Gtk3.gtk_button_set_label(@self, label_);
end;

You can see that we are using objects instead of records, compare this to the current Gtk2 bindings:

type
  PGtkButton = ^TGtkButton;
  TGtkButton = record
    bin : TGtkBin;
    event_window : PGdkWindow;
    label_text : Pgchar;
    activate_timeout : guint;
    flag0 : word;
  end; 

function gtk_button_new:PGtkWidget; cdecl; external gtklib;
procedure gtk_button_set_label(button:PGtkButton; _label:Pgchar); cdecl; external gtklib;
function gtk_button_get_label(button:PGtkButton):Pgchar; cdecl; external gtklib;


Before, our code would look like this:

procedure Foo;
var
  Button: PGtkWidget;
begin
  Button := gtk_button_new;
  gtk_button_set_label(PGtkButton(Button), 'Hello World!');
end;


But now it's possible to use this instead:

procedure Foo;
var
  Button: PGtkButton;
begin
  Button := TGtkButton.new;
  Button^.label_ := 'Hello World!';
end;

As you see it's a bit shorter to type the second way. Although either will work since the 'flat' functions are still available to use.

Using objects instead of records it is of course possible to access inherited methods and properties with greater ease than before, especially when using the code completion feature of Lazarus (which is extremely close to 1.0 now!). Button in the example above descends from GtkWidget which has the property tooltip_text.

This can be accessed with
Button^.tooltip_text := 'Don''t click me unless you want to!';
whereas before you had to do
gtk_widget_set_tooltip_text(PGtkWidget(Button) ,'Don''t click me unless you want to!');  

Here's the HelloWorld example included with the bindings, modified to have a tooltip.


 The Pascal Gtk3 bindings are not yet well tested. There are a couple of examples in the Lazarus-ccr repository in the folder /bindings/gtk3/examples/ including an example of GtkWebkit.

Perhaps you would like to try it out :)

Thursday, August 2, 2012

Preparing for Lazarus 1.0 (RC1)

Just to announce: Lazarus is preparing to go 1.0.

The first release candidate for the new Version has just been made public on sourceforge. Please test it.

You can find the announcement for the RC here: http://forum.lazarus.freepascal.org/index.php/topic,17717
And a list of what changed is here: http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes

Friday, February 17, 2012

Pascal does a strong showing in the Linux Questions Members Choice

Of course that internet quiz is not something scientific but it is nevertheless good news. Both Pascal and Lazarus made a strong showing in the Linux Questions Annual Members Choice Awards, competing with software sponsored by huge corporations. Other software written in Lazarus also appeared in the show, such as Double Commander and LazPaint.

Let's start with Lazarus itself running against other IDEs:



And how Pascal / Object Pascal as a language fared well too (despite someone mistakenly having added it as "Free Pascal"). It is pretty hard to see because of so many multiple lines, so I added a bigger line connector, but anyone can check in the full description of the results here: http://www.linuxquestions.org/questions/linux-news-59/2011-linuxquestions-org-members-choice-award-winners-928502/



See also how Double Commander fared:



And LazPaint:



If there was a category for Accessibility probably the Virtual Magnifying Glass would appear =)

Felipe Monteiro de Carvalho

Wednesday, February 15, 2012

Exploring the iPhone

As all should know, since my previous post I managed to finish off all the missing bits and get a decent initial support for Android in the LCL. But of course we are not stopping there, so I started exploring the iPhone. I haven't yet done any programming, but I already found a lot of interesting thing. Many good things, but also many bad things.

So let's start with the good things:

I was expecting something similar to Android, just more expensive, but while the user interface is remarkably similar, I must say that Apple has an extremely good taste for designing things. Everything in the iPhone is just beautiful. Each small detail seams well though out to look good, while in Android everything exists in a similar shape, it just looks OK in Android while it look great in the iPhone. Sure that some manufacturer like HTC and Sony Ericsson changes radically the user interface and even UI widgetset look, but in all cases they don't come close to looking as good as the iPhone.

The available RAM in the iPhone is pretty excellent. The iPhone 4 comes with 512MB of RAM of which aprox. 300MB are free for user applications. That's a huge amount in comparison to Android devices where you might even have 300MB or RAM, but the system is already eating 250MB =( The iPhone is also free of all that crapware which manufacturers like to fill the scarce ROM memory of Android phones, and the iPhone has a huge common memory for both media files and applications, which makes it able to run bigger apps without problems.

Now some things which are different:

The start screen is nearly identical with horizontal scrolling except that the iPhone home screen is much less configurable. You cannot place those nice widgetset to turn on/off mobile network or WiFi on a single click. The iPhone is also not very intuitive to use at times, with only icons and no perceived way for me to find out what an icon does except by guessing or testing, while in Android text labels are used much more often. There are no hints either.

And now the bad:

Frankly I am appalled that I have never heard of the evil side of the iPhone before. Why is nobody commenting that?? Am I the only one deeply bothered by this!? For me this was so terrible that I will never buy an iPhone again, for sure my next smartphone will be Android again. The iPhone is just the most restricted device, the most DRM filled, the most anti-freedom, the most monopolist, the most anti file owning device I have seen in my life. Let's start with the basic. On Android you put a SDCard in the phone and then you connect it with a USB cable to the computer and voilà! It opens as a mass media device with zero drivers installation in *any* operating system. Windows, Linux, Mac, works just as great in all! Then you can copy your music there, copy APK packages, you can copy your personal documents, you can copy source code, I don't know, you can do whatever you want! Sadly Android doesn't come with a File Browser but you can easily install the "OI File Browser" and then with it you see all your files on the phone and manage them. You can install any app to read your files. You can use the phone as a pen drive, you can create a new application to open, view and modify any file extension in the world and share that application. You can share your files. That's freedom! That's general computing! The freedom that any computer should offer.

And the iPhone!? Where are the file managers? I haven't yet found a single one which will show my photos, movies and music. WTF!?!? There are some file managers which require installing extra programs in the desktop and essentially are a sort of hack around the limitations imposed by Apple. Is music just a product you consume from bigshot producers? Can you even run you own music there? Where is my freedom to run my MP3 which I generated myself from a CD I bought in Paraguay? Those guys are not in the iTunes Mr. Jobs and I don't want to restrict myself to your iWorld. Cloud storage as an extra option, OK, but ban file owning, copying and sharing!? That's the evil dream of any monopolist. I don't want to be part of that evil iWorld, I want a general computer. But that's what the iPhone certainly does not want to be.

So, well, let's say you are conformed with the iPhone having zero file owning capabilities. What's next? It only docks to your computer via the iTunes after installing a plethora of drivers and does not work at all in Linux. You cannot freely install applications which you wrote yourself without joining the Apple Developer Program and go through a complicated process. In Android you can write apps and share them easily without any of this non-sense.

And to make it worse: Apple is monopolistic. It banned 3rd party browsers. Where is the freedom? I don't want to be stuck with Safari. I already like Opera Mobile, but they banned it. Sure there is Opera Mini, but Mobile is much more what I want.

So here we are: A superb phone, the best looking GUI and design I have ever seen. Excellent quality of the touch screen. All ruined by monopolistic, anti-freedom non-sense! All ruined by a company which wants to ban people from owning files.

Felipe Monteiro de Carvalho