commit b5f40d159efd909f5df2abb3c4b909b0037465cf Author: Jonathan Schleifer Date: Tue Dec 27 22:09:33 2011 +0100 Initial import. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1dc32a8 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +PREFIX ?= /usr/local + +all: + @objfw-compile -Wall -g --lib 0.0 -o objgui \ + `pkg-config --cflags --libs gtk+-3.0` \ + `ls *.m | fgrep -v test.m` + +test: + @objfw-compile -Wall -g -o test \ + `pkg-config --cflags --libs gtk+-3.0` \ + *.m + +install: + mkdir -p ${PREFIX}/include/ObjGUI + cp *.h ${PREFIX}/include/ObjGUI/ + cp libobjgui.so ${PREFIX}/lib/libobjgui.so.0.0 + ln -sf libobjgui.so.0.0 ${PREFIX}/lib/libobjgui.so.0 + ln -sf libobjgui.so.0 ${PREFIX}/lib/libobjgui.so + +clean: + rm -f test *.so *.o *~ diff --git a/OGApplication.h b/OGApplication.h new file mode 100644 index 0000000..c684343 --- /dev/null +++ b/OGApplication.h @@ -0,0 +1,23 @@ +#include + +#import + +@protocol OGApplicationDelegate +- (void)applicationDidFinishLaunching; +@optional +- (void)applicationWillTerminate; +@end + +@interface OGApplication: OFObject +{ + id delegate; +} + ++ (void)quit; +@end + +#define OG_APPLICATION_DELEGATE(cls) \ + Class \ + og_application_delegate() { \ + return [cls class]; \ + } diff --git a/OGApplication.m b/OGApplication.m new file mode 100644 index 0000000..0c36e82 --- /dev/null +++ b/OGApplication.m @@ -0,0 +1,36 @@ +#import "OGApplication.h" + +OF_APPLICATION_DELEGATE(OGApplication) + +extern Class og_application_delegate(void); + +@implementation OGApplication ++ (void)quit +{ + gtk_main_quit(); +} + +- (void)applicationDidFinishLaunching +{ + OFAutoreleasePool *pool; + int *argc; + char ***argv; + + delegate = [[og_application_delegate() alloc] init]; + + [[OFApplication sharedApplication] getArgumentCount: &argc + andArgumentValues: &argv]; + gtk_init(argc, argv); + + pool = [OFAutoreleasePool new]; + [delegate applicationDidFinishLaunching]; + [pool release]; + + gtk_main(); +} + +- (void)applicationWillTerminate +{ + [delegate applicationWillTerminate]; +} +@end diff --git a/OGBox.h b/OGBox.h new file mode 100644 index 0000000..90b7d4b --- /dev/null +++ b/OGBox.h @@ -0,0 +1,14 @@ +#import "OGWidget.h" + +@interface OGBox: OGWidget ++ box; + +- (void)appendChild: (OGWidget*)child + expand: (BOOL)expand + fill: (BOOL)fill + padding: (float)padding; +- (void)prependChild: (OGWidget*)child + expand: (BOOL)expand + fill: (BOOL)fill + padding: (float)padding; +@end diff --git a/OGBox.m b/OGBox.m new file mode 100644 index 0000000..e75fe05 --- /dev/null +++ b/OGBox.m @@ -0,0 +1,42 @@ +#import "OGBox.h" + +@implementation OGBox ++ box +{ + return [[[self alloc] init] autorelease]; +} + +- init +{ + self = [super init]; + + @try { + if (isa == [OGBox class]) + @throw [OFNotImplementedException + exceptionWithClass: isa + selector: _cmd]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)appendChild: (OGWidget*)child + expand: (BOOL)expand + fill: (BOOL)fill + padding: (float)padding +{ + gtk_box_pack_start(GTK_BOX(widget), child->widget, expand, fill, + padding); +} + +- (void)prependChild: (OGWidget*)child + expand: (BOOL)expand + fill: (BOOL)fill + padding: (float)padding +{ + gtk_box_pack_end(GTK_BOX(widget), child->widget, expand, fill, padding); +} +@end diff --git a/OGButton.h b/OGButton.h new file mode 100644 index 0000000..755792e --- /dev/null +++ b/OGButton.h @@ -0,0 +1,19 @@ +#import "OGWidget.h" + +@class OGButton; + +@protocol OGButtonDelegate +@optional +- (void)buttonWasClicked: (OGButton*)button; +@end + +@interface OGButton: OGWidget +{ + id delegate; +} + +@property (assign) id delegate; +@property (copy) OFString *label; + ++ button; +@end diff --git a/OGButton.m b/OGButton.m new file mode 100644 index 0000000..c06210e --- /dev/null +++ b/OGButton.m @@ -0,0 +1,56 @@ +#import "OGButton.h" + +@interface OGButton () +- (void)OG_clicked; +@end + +static void +clicked(GtkWidget *widget, gpointer data) +{ + [(OGButton*)data OG_clicked]; +} + +@implementation OGButton +@synthesize delegate; + ++ button +{ + return [[[self alloc] init] autorelease]; +} + +- init +{ + self = [super init]; + + widget = gtk_button_new(); + g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(clicked), + self); + + g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(og_destroy), + self); + [self retain]; + + return self; +} + +- (OFString*)label +{ + return [OFString stringWithUTF8String: + gtk_button_get_label(GTK_BUTTON(widget))]; +} + +- (void)setLabel: (OFString*)label +{ + gtk_button_set_label(GTK_BUTTON(widget), [label UTF8String]); +} + +- (void)OG_clicked +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + if ([delegate respondsToSelector: @selector(buttonWasClicked:)]) + [delegate buttonWasClicked: self]; + + [pool release]; +} +@end diff --git a/OGHBox.h b/OGHBox.h new file mode 100644 index 0000000..a1f2183 --- /dev/null +++ b/OGHBox.h @@ -0,0 +1,4 @@ +#import "OGBox.h" + +@interface OGHBox: OGBox +@end diff --git a/OGHBox.m b/OGHBox.m new file mode 100644 index 0000000..585abd0 --- /dev/null +++ b/OGHBox.m @@ -0,0 +1,16 @@ +#import "OGHBox.h" + +@implementation OGHBox +- init +{ + self = [super init]; + + widget = gtk_hbox_new(FALSE, 0); + + g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(og_destroy), + self); + [self retain]; + + return self; +} +@end diff --git a/OGVBox.h b/OGVBox.h new file mode 100644 index 0000000..150eabd --- /dev/null +++ b/OGVBox.h @@ -0,0 +1,4 @@ +#import "OGBox.h" + +@interface OGVBox: OGBox +@end diff --git a/OGVBox.m b/OGVBox.m new file mode 100644 index 0000000..583397a --- /dev/null +++ b/OGVBox.m @@ -0,0 +1,16 @@ +#import "OGVBox.h" + +@implementation OGVBox +- init +{ + self = [super init]; + + widget = gtk_vbox_new(FALSE, 0); + + g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(og_destroy), + self); + [self retain]; + + return self; +} +@end diff --git a/OGWidget.h b/OGWidget.h new file mode 100644 index 0000000..f3bbb25 --- /dev/null +++ b/OGWidget.h @@ -0,0 +1,15 @@ +#include + +#import + +@interface OGWidget: OFObject +{ +@public + GtkWidget *widget; +} + +- (void)show; +- (void)hide; +@end + +extern void og_destroy(GtkWidget*, OGWidget*); diff --git a/OGWidget.m b/OGWidget.m new file mode 100644 index 0000000..2d481e2 --- /dev/null +++ b/OGWidget.m @@ -0,0 +1,35 @@ +#include "OGWidget.h" + +void og_destroy(GtkWidget *widget, OGWidget *object) +{ + [object release]; +} + +@implementation OGWidget +- init +{ + self = [super init]; + + @try { + if (isa == [OGWidget class]) + @throw [OFNotImplementedException + exceptionWithClass: isa + selector: @selector(init)]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)show +{ + gtk_widget_show_all(widget); +} + +- (void)hide +{ + gtk_widget_hide(widget); +} +@end diff --git a/OGWindow.h b/OGWindow.h new file mode 100644 index 0000000..cdac999 --- /dev/null +++ b/OGWindow.h @@ -0,0 +1,22 @@ +#import "OGWidget.h" + +@class OGWindow; + +@protocol OGWindowDelegate +@optional +- (BOOL)windowWillClose: (OGWindow*)window; +@end + +@interface OGWindow: OGWidget +{ + id delegate; +} + +@property (assign) id delegate; +@property (copy) OFString *title; +@property (assign) of_point_t position; +@property (assign) of_dimension_t dimension; + ++ window; +- (void)addChild: (OGWidget*)widget; +@end diff --git a/OGWindow.m b/OGWindow.m new file mode 100644 index 0000000..3af3a2b --- /dev/null +++ b/OGWindow.m @@ -0,0 +1,92 @@ +#import "OGWindow.h" + +@interface OGWindow () +- (BOOL)OG_willClose; +@end + +static gboolean +willClose(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + return ([(OGWindow*)data OG_willClose] ? FALSE : TRUE); +} + +@implementation OGWindow +@synthesize delegate; + ++ window +{ + return [[[self alloc] init] autorelease]; +} + +- init +{ + self = [super init]; + + widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); + g_signal_connect(G_OBJECT(widget), "delete-event", + G_CALLBACK(willClose), self); + + g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(og_destroy), + self); + [self retain]; + + return self; +} + +- (OFString*)title +{ + return [OFString stringWithUTF8String: + gtk_window_get_title(GTK_WINDOW(widget))]; +} + +- (void)setTitle: (OFString*)title +{ + gtk_window_set_title(GTK_WINDOW(widget), [title UTF8String]); +} + +- (of_point_t)position +{ + gint x, y; + + gtk_window_get_position(GTK_WINDOW(widget), &x, &y); + + return of_point(x, y); +} + +- (void)setPosition: (of_point_t)position +{ + gtk_window_move(GTK_WINDOW(widget), position.x, position.y); +} + +- (of_dimension_t)dimension +{ + gint width, height; + + gtk_window_get_size(GTK_WINDOW(widget), &width, &height); + + return of_dimension(width, height); +} + +- (void)setDimension: (of_dimension_t)dimension +{ + gtk_window_resize(GTK_WINDOW(widget), + dimension.width, dimension.height); +} + +- (void)addChild: (OGWidget*)child +{ + gtk_container_add(GTK_CONTAINER(widget), child->widget); +} + +- (BOOL)OG_willClose +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + if ([delegate respondsToSelector: @selector(windowWillClose:)]) + return [delegate windowWillClose: self]; + + [pool release]; + + return YES; +} +@end diff --git a/test.m b/test.m new file mode 100644 index 0000000..ec07b83 --- /dev/null +++ b/test.m @@ -0,0 +1,74 @@ +#import "OGApplication.h" +#import "OGWindow.h" +#import "OGButton.h" +#import "OGHBox.h" +#import "OGVBox.h" + +@interface Test: OFObject +@end + +OG_APPLICATION_DELEGATE(Test) + +@implementation Test +- (void)applicationDidFinishLaunching +{ + OGWindow *w = [OGWindow window]; + w.title = @"Hallo Welt!"; + w.position = of_point(100, 100); + w.dimension = of_dimension(600, 400); + w.delegate = self; + + OGVBox *vbox = [OGVBox box]; + [w addChild: vbox]; + + OGButton *b = [OGButton button]; + b.label = @"Klick mich!"; + b.delegate = self; + [vbox appendChild: b + expand: YES + fill: YES + padding: 0]; + + OGHBox *hbox = [OGHBox box]; + [vbox appendChild: hbox + expand: NO + fill: NO + padding: 0]; + + OGButton *b1 = [OGButton button]; + b1.label = @"Ich"; + [hbox appendChild: b1 + expand: YES + fill: YES + padding: 0]; + + OGButton *b2 = [OGButton button]; + b2.label = @"mach"; + [hbox appendChild: b2 + expand: YES + fill: YES + padding: 0]; + + OGButton *b3 = [OGButton button]; + b3.label = @"nix"; + [hbox appendChild: b3 + expand: YES + fill: YES + padding: 0]; + + [w show]; +} + +- (BOOL)windowWillClose: (OGWindow*)window +{ + [OGApplication quit]; + + return YES; +} + +- (void)buttonWasClicked: (OGButton*)button +{ + of_log(@"Hallo!"); +} +@end