From b5f40d159efd909f5df2abb3c4b909b0037465cf Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Tue, 27 Dec 2011 22:09:33 +0100 Subject: [PATCH] Initial import. --- Makefile | 21 +++++++++++ OGApplication.h | 23 +++++++++++++ OGApplication.m | 36 +++++++++++++++++++ OGBox.h | 14 ++++++++ OGBox.m | 42 ++++++++++++++++++++++ OGButton.h | 19 ++++++++++ OGButton.m | 56 ++++++++++++++++++++++++++++++ OGHBox.h | 4 +++ OGHBox.m | 16 +++++++++ OGVBox.h | 4 +++ OGVBox.m | 16 +++++++++ OGWidget.h | 15 ++++++++ OGWidget.m | 35 +++++++++++++++++++ OGWindow.h | 22 ++++++++++++ OGWindow.m | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ test.m | 74 +++++++++++++++++++++++++++++++++++++++ 16 files changed, 489 insertions(+) create mode 100644 Makefile create mode 100644 OGApplication.h create mode 100644 OGApplication.m create mode 100644 OGBox.h create mode 100644 OGBox.m create mode 100644 OGButton.h create mode 100644 OGButton.m create mode 100644 OGHBox.h create mode 100644 OGHBox.m create mode 100644 OGVBox.h create mode 100644 OGVBox.m create mode 100644 OGWidget.h create mode 100644 OGWidget.m create mode 100644 OGWindow.h create mode 100644 OGWindow.m create mode 100644 test.m 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