Archive

Posts Tagged ‘CoreGTK’

Adding GTK+ 3 support and building CoreGTK using GObject Introspection

May 3rd, 2015 No comments

It has been a while since I made any mention of my side project CoreGTK. I’m sure many people can relate that with life generally being very busy it is often hard to find time to work on hobby projects like this. Thankfully while that certainly has slowed the pace of development it hasn’t stopped it outright and now I am just about ready to show off the next update for CoreGTK.

First off thank you to everyone who took a look at the previous release. I received quite a few nice comments as well as some excellent feedback and hope to address quite a bit of that here. The feedback plus my own ideas of where I wanted to take the project defined the goal for the next release that I am currently working toward.

Goals for this release:

  • Move from GTK+ 2 to GTK+ 3
  • Prefer the use of glib data types over boxed OpenStep/Cocoa objects (i.e. gint vs NSNumber)
  • Base code generation on GObject Introspection instead of a mix of automated source parsing and manual correction

In order to explain the rationale behind these goals I figured I would address each point in more detail.

Move from GTK+ 2 to GTK+ 3

This one was pretty much a no-brainer. GTK+ 3 is now the current supported widget toolkit and has been since February 2011. Previously my choice to use GTK+ 2 was simply due to the fact that I wanted to make it as cross-platform as possible and at the time of release GTK+ 3 was not supported on Windows. Now that this has changed it only makes sense to continue forward using the current standard.

Additionally this allows for a natural break in compatibility with the previous release of CoreGTK. What that means for the end user is that I currently don’t have any plans on going back and applying any of these new ideas/changes to the old GTK+ 2 version of the code base, instead focusing my time and effort on GTK+ 3.

Prefer the use of glib data types over boxed OpenStep/Cocoa objects (i.e. gint vs NSNumber)

When originally designing CoreGTK I decided to put a stake in the ground and simply always favour OpenStep/Cocoa objects where possible. The hope was that this would allow for easier integration with existing Objective-C code bases. Unfortunately good intentions don’t always work out in the best way. One of the major pieces of feedback I got was to take a less strict approach on this and drop the use of some classes where it makes sense. Specifically keep using NSString instead of C strings but stop using NSNumber in place of primitives like gint (which itself is really just a C int). The net result of this change is far less boilerplate code and faster performance.

So instead of writing this:

/* Sets the border width of the window */
[window setBorderWidth: [NSNumber numberWithInt:10]];

you can now simply write this:

/* Sets the border width of the window */
[window setBorderWidth: 10];

Base code generation on GObject Introspection instead of a mix of automated source parsing and manual correction

The previous version of CoreGTK was, shall we say, hand crafted. I had written some code to parse header files and generate a basic structure for the Objective-C output but there was still quite a bit of manual work involved to clean up this output and make it what it was. Other than the significant investment in time required to make this happen it was also prone to errors and would require starting back at square one with every new release of GTK+. This time around the output is generated using GObject Introspection, specifically by parsing the generated GIR file for that library. Currently, and I must stress that there is still quite a bit of room for improvement, this allows me to generate CoreGTK bindings from scratch within an hour or so. With some of the final touches I have in mind the time required for this should hopefully be down to minutes (the auto-generation itself only takes seconds but it isn’t 100% yet). Better still once this process is perfected it should be relatively easy to adapt it to support other GObject Introspection supported libraries like Pango, Gdk, GStreamer, etc.

So where is this new release?

I am getting closer to showing off this new code but first I have to do a bit of cleanup on it. This hopefully won’t take too much longer and to show you how close I am here is a screenshot of CoreGTK running using GTK+ 3.

coregtk-3

This post originally appeared on my personal website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Check out my profile for more information.

CoreGTK 2.24.0 Released!

August 4th, 2014 No comments

The initial version of CoreGTK, version 2.24.0, has been tagged for release today.

Features include:

  • Targets GTK+ 2.24
  • Support for GtkBuilder
  • Can be used on Linux, Mac and Windows

CoreGTK is an Objective-C language binding for the GTK+ widget toolkit. Like other “core” Objective-C libraries, CoreGTK is designed to be a thin wrapper. CoreGTK is free software, licensed under the GNU LGPL.

You can find more information about the project here and the release itself here.

This post originally appeared on my personal website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Check out my profile for more information.

CoreGTK

January 28th, 2014 2 comments

A while back I made it my goal to put together an open source project as my way of contributing back to the community. Well fast forward a couple of months and my hobby project is finally ready to be shown the light of day. I give you… CoreGTK

CoreGTK is an Objective-C binding for the GTK+ library which wraps all objects descending from GtkWidget (plus a few others here and there). Like other “core” Objective-C libraries it is designed to be a very thin wrapper, so that anyone familiar with the C version of GTK+ should be able to pick it up easily.

However the real goal of CoreGTK is not to replace the C implementation for every day use but instead to allow developers to more easily code GTK+ interfaces using Objective-C. This could be especially useful if a developer already has a program, say one they are developing for the Mac, and they want to port it to Linux or Windows. With a little bit of MVC a savvy developer would only need to re-write the GUI portion of their application in CoreGTK.

So what does a CoreGTK application look like? Pretty much like a normal Objective-C program:

/*
 * Objective-C imports
 */
#import <Foundation/Foundation.h>
#import "CGTK.h"
#import "CGTKButton.h"
#import "CGTKSignalConnector.h"
#import "CGTKWindow.h"

/*
 * C imports
 */
#import <gtk/gtk.h>

@interface HelloWorld : NSObject
/* This is a callback function. The data arguments are ignored
 * in this example. More callbacks below. */
+(void)hello;

/* Another callback */
+(void)destroy;
@end

@implementation HelloWorld
int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    /* We could use also CGTKWidget here instead */
    CGTKWindow *window;
    CGTKButton *button;

    /* This is called in all GTK applications. Arguments are parsed
    * from the command line and are returned to the application. */
    [CGTK autoInitWithArgc:argc andArgv:argv];

    /* Create a new window */
    window = [[CGTKWindow alloc] initWithGtkWindowType:GTK_WINDOW_TOPLEVEL];

    /* Here we connect the "destroy" event to a signal handler in 
     * the HelloWorld class */
    [CGTKSignalConnector connectGpointer:[window WIDGET] 
        withSignal:@"destroy" toTarget:[HelloWorld class] 
        withSelector:@selector(destroy) andData:NULL];

    /* Sets the border width of the window */
    [window setBorderWidth: [NSNumber numberWithInt:10]];

    /* Creates a new button with the label "Hello World" */
    button = [[CGTKButton alloc] initWithLabel:@"Hello World"];

    /* When the button receives the "clicked" signal, it will call the
     * function hello() in the HelloWorld class (below) */
    [CGTKSignalConnector connectGpointer:[button WIDGET] 
        withSignal:@"clicked" toTarget:[HelloWorld class] 
        withSelector:@selector(hello) andData:NULL];

    /* This packs the button into the window (a gtk container) */
    [window add:button];

    /* The final step is to display this newly created widget */
    [button show];

    /* and the window */
    [window show];

    /* All GTK applications must have a [CGTK main] call. Control ends here
     * and waits for an event to occur (like a key press or
     * mouse event). */
    [CGTK main];

    [pool release];

    return 0;
}

+(void)hello
{
    NSLog(@"Hello World");
}

+(void)destroy
{
    [CGTK mainQuit];
}
@end
Hello World in action

Hello World in action

And because Objective-C is completely compatible with regular old C code there is nothing stopping you from simply extracting the GTK+ objects and using them like normal.

// Use it as an Objective-C CoreGTK object!
CGTKWindow *cWindow = [[CGTKWindow alloc] 
    initWithGtkWindowType:GTK_WINDOW_TOPLEVEL];

// Or as a C GTK+ window!
GtkWindow *gWindow = [cWindow WINDOW];

// Or even as a C GtkWidget!
GtkWidget *gWidget = [cWindow WIDGET];

// This...
[cWindow show];

// ...is the same as this:
gtk_widget_show([cWindow WIDGET]);

You can even use a UI builder like GLADE, import the XML and wire up the signals to Objective-C instance and class methods.

CGTKBuilder *builder = [[CGTKBuilder alloc] init];
if(![builder addFromFile:@"test.glade"])
{
    NSLog(@"Error loading GUI file");
    return 1;
}

[CGTKBuilder setDebug:YES];

NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:
                 [CGTKCallbackData withObject:[CGTK class] 
                     andSEL:@selector(mainQuit)], @"endMainLoop",
                 [CGTKCallbackData withObject:[HelloWorld class] 
                     andSEL:@selector(hello)], @"on_button2_clicked",
                 [CGTKCallbackData withObject:[HelloWorld class] 
                     andSEL:@selector(hello)], @"on_button1_activate",
                 nil];

[builder connectSignalsToObjects:dic];

CGTKWidget *w = [builder getWidgetWithName:@"window1"];
if(w != nil)
{
    [w showAll];
}

[builder release];

So there you have it that’s CoreGTK in a nutshell.

There are a variety of ways to help me out with this project if you are so inclined to do so. The first task is probably just to get familiar with it. Download CoreGTK from the GitHub project page and play around with it. If you find a bug (very likely) please create an issue for it.

Another easy way to get familiar with CoreGTK is to help write/fix documentation – a lot of which is written in the source code itself. Sadly most of the current documentation simply states which underlying GTK+ function is called and so it could be cleaned up quite a bit.

At the moment there really isn’t anything more formal than that in place but of course code contributions would also be welcome!

Update: added some pictures of the same program running on all three operating systems.

Hello World on Windows

Hello World on Windows

Hello World on Mac

Hello World on Mac

Hello World on Linux

Hello World on Linux

This post originally appeared on my personal website here.




I am currently running a variety of distributions, primarily Linux Mint 17.
Previously I was running KDE 4.3.3 on top of Fedora 11 (for the first experiment) and KDE 4.6.5 on top of Gentoo (for the second experiment).
Check out my profile for more information.