win32 branch commit

This commit is contained in:
Dillon Aumiller 2012-01-04 20:22:08 -06:00
parent 3a0d3fd94e
commit bbbeb0bebe
15 changed files with 1337 additions and 1 deletions

6
.hgignore Normal file
View file

@ -0,0 +1,6 @@
syntax: glob
*.dll
*.so
*.o
*.a
*.exe

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011, 2012, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
@ -22,7 +23,24 @@
#import "OGWidget.h"
#ifdef OG_W32
typedef struct s_OGBoxChild
{
HWND hwnd;
BOOL expand;
BOOL fill;
int padding;
int originalSize;
float currentSize;
struct s_OGBoxChild *next;
} OGBoxChild;
#endif
@interface OGBox: OGWidget
#ifdef OG_W32
{ OGBoxChild *firstBorn; }
- (void)resizeChildren;
#endif
+ box;
- (void)appendChild: (OGWidget*)child
expand: (BOOL)expand

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011, 2012, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
@ -42,6 +43,12 @@
id <OGComboBoxDataSource> dataSource;
}
#ifdef OG_W32
//unfortunately, the built-in Win32 ListBox stores a pointer to it's parent (for sending selection changed notifications) during CreateWindow().
//it does not update it after a SetParent()... unless we implement a custom ListBox control i don't see a way around this...
- initWithParent : (OGWidget *)parent;
#endif
@property (assign) id <OGComboBoxDelegate> delegate;
@property (assign) id <OGComboBoxDataSource> dataSource;

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011, 2012, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
@ -21,7 +22,10 @@
*/
#ifdef OG_GTK
# include <gtk/gtk.h>
#i nclude <gtk/gtk.h>
#endif
#ifdef OG_W32
# include <windows.h>
#endif
#import <ObjFW/ObjFW.h>
@ -32,10 +36,18 @@
#ifdef OG_GTK
GtkWidget *widget;
#endif
#ifdef OG_W32
HWND widget;
#endif
}
- (void)show;
- (void)hide;
@end
#ifdef OG_GTK
extern void og_destroy(GtkWidget*, OGWidget*);
#endif
#ifdef OG_W32
extern void og_destroy(HWND widget, OGWidget *object);
#endif

12
win32/Makefile Normal file
View file

@ -0,0 +1,12 @@
PREFIX ?= /usr/local
all : test.exe
%.o : %.m
gcc -g -DOG_W32 -I../headers -c -o $@ $^ `objfw-config --cppflags --objcflags`
test.exe : OGApplication.o OGWidget.o OGWindow.o OGBox.o OGVBox.o OGHBox.o OGButton.o OGComboBox.o OGComboBoxItem.o test.o
gcc -mwindows -o test.exe *.o `objfw-config --libs`
clean :
rm -f *.exe *.o

119
win32/OGApplication.m Normal file
View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGApplication.m
//==================================================================================================================================
#import <ObjFW/OFApplication.h> //this seems to be needed for "OF_APPLICATION_DELEGATE"
#import "OGWidget.h"
#import "OGApplication.h"
//==================================================================================================================================
void win32_init(int *argc, char ***argv);
void win32_main();
LRESULT CALLBACK win32_OGWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
//==================================================================================================================================
@interface WndMsgReceiver
- (int)MessageReceived : (HWND)hwnd : (UINT)msg : (WPARAM)wparam : (LPARAM)lparam;
@end
//==================================================================================================================================
OF_APPLICATION_DELEGATE(OGApplication)
extern Class og_application_delegate(void);
//==================================================================================================================================
@implementation OGApplication
//----------------------------------------------------------------------------------------------------------------------------------
+ (void)quit
{
PostQuitMessage(0);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)applicationDidFinishLaunching
{
OFAutoreleasePool *pool;
int *argc;
char ***argv;
delegate = [[og_application_delegate() alloc] init];
[[OFApplication sharedApplication] getArgumentCount: &argc
andArgumentValues: &argv];
win32_init(argc, argv);
pool = [OFAutoreleasePool new];
[delegate applicationDidFinishLaunching];
[pool release];
win32_main();
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)applicationWillTerminate
{
[delegate applicationWillTerminate];
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================
void win32_init(int *argc, char ***argv)
{
//register a single window class; we'll customize later, as needed
char *clsName = "OFWidgetClass";
HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
WNDCLASSEX wcx;
wcx.cbSize = sizeof(wcx);
wcx.style = CS_VREDRAW | CS_HREDRAW;
wcx.lpfnWndProc = (WNDPROC)win32_OGWndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInst;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = clsName;
wcx.hIconSm = NULL;
RegisterClassEx(&wcx);
//TODO: although this doesn't ever really fail, we should probably Throw an Exception here...
//if(!RegisterClassEx(&wcx)) @throw ...;
}
//==================================================================================================================================
void win32_main()
{
MSG msg; int msgCode;
while((msgCode = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if(msgCode == -1)
return;
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
//==================================================================================================================================
LRESULT CALLBACK win32_OGWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
void *ptr = (void *)GetWindowLong(hwnd, GWL_USERDATA);
if(ptr == NULL) return DefWindowProc(hwnd, msg, wparam, lparam);
return [(id)ptr MessageReceived : hwnd : msg : wparam : lparam];
}
//==================================================================================================================================

90
win32/OGBox.m Normal file
View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGBox.m
//==================================================================================================================================
#include <malloc.h>
#include <windows.h>
#import "OGBox.h"
//==================================================================================================================================
@implementation OGBox
//----------------------------------------------------------------------------------------------------------------------------------
+ box
{
return [[[self alloc] init] autorelease];
}
//----------------------------------------------------------------------------------------------------------------------------------
- init
{
self = [super init];
SetWindowLong(widget, GWL_STYLE, WS_CHILD | WS_VISIBLE);
firstBorn = NULL;
@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
{
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)prependChild: (OGWidget*)child
expand: (BOOL)expand
fill: (BOOL)fill
padding: (float)padding
{
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)resizeChildren
{
}
//----------------------------------------------------------------------------------------------------------------------------------
- (int)MessageReceived : (HWND)hwnd : (UINT)msg : (WPARAM)wparam : (LPARAM)lparam
{
HWND parent;
switch(msg)
{
case WM_COMMAND:
parent = GetParent(hwnd);
if(parent != NULL)
return SendMessage(parent, msg, wparam, lparam);
break;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

111
win32/OGButton.m Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGButton.m
//==================================================================================================================================
#define BCM_GETIDEALSIZE 0x1601
#import "OGButton.h"
//==================================================================================================================================
@interface OGButton ()
- (void)OG_clicked;
@end
//==================================================================================================================================
typedef void(*CommandHandler)(id,WPARAM);
typedef struct
{
CommandHandler funct;
id object;
} CommandHandlerData;
//----------------------------------------------------------------------------------------------------------------------------------
static void CH_Command(id object, WPARAM wparam)
{
[object OG_clicked];
}
//==================================================================================================================================
@implementation OGButton
//----------------------------------------------------------------------------------------------------------------------------------
@synthesize delegate;
//----------------------------------------------------------------------------------------------------------------------------------
+ button
{
return [[[self alloc] init] autorelease];
}
//----------------------------------------------------------------------------------------------------------------------------------
- init
{
self = [super init];
//we're specifying a different class name...
//so we'll have to discard the default OGWidget HWND...
DestroyWindow(widget);
//and create a new one
widget = NULL;
HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
widget = CreateWindow("button", "", BS_PUSHBUTTON,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
SetWindowLong(widget, GWL_STYLE, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP);
//crazy workaround since we don't have control of our WNDPROC for default "button"s
CommandHandlerData *chd = (CommandHandlerData *)malloc(sizeof(CommandHandlerData));
chd->funct = CH_Command;
chd->object = self;
//and another workaround because "button" class seems to mess with our GWL_USERDATA storage...
//SetWindowLong(widget, GWL_USERDATA, (UINT)(chd));
SetProp(widget, "CommandHandlerData", chd);
[self retain];
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (OFString*)label
{
int tlen = GetWindowTextLength(widget);
char *buff = (char *)malloc(tlen + 1);
GetWindowText(widget, buff, tlen+1);
OFString *ret = [OFString stringWithUTF8String : buff];
free(buff);
return ret;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)setLabel: (OFString*)label
{
SIZE sz; sz.cx = sz.cy = 0;
SetWindowText(widget, [label UTF8String]);
SendMessage(widget, BCM_GETIDEALSIZE, 0, (LPARAM)(&sz));
//SetWindowPos(widget, NULL, 0, 0, sz.cx, sz.cy, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
SetWindowPos(widget, NULL, 0, 0, 32, 32, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)OG_clicked
{
OFAutoreleasePool *pool = [OFAutoreleasePool new];
if ([delegate respondsToSelector: @selector(buttonWasClicked:)])
[delegate buttonWasClicked: self];
[pool release];
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

129
win32/OGComboBox.m Normal file
View file

@ -0,0 +1,129 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGComboBox.m
//==================================================================================================================================
#import "OGComboBox.h"
//==================================================================================================================================
@interface OGComboBox ()
- (void)OG_changed;
@end
//==================================================================================================================================
typedef void(*CommandHandler)(id,WPARAM);
typedef struct
{
CommandHandler funct;
id object;
} CommandHandlerData;
//----------------------------------------------------------------------------------------------------------------------------------
static void CH_Command(id object, WPARAM wparam)
{
if(HIWORD(wparam) == LBN_SELCHANGE) //selection changed
[object OG_changed];
}
//==================================================================================================================================
@implementation OGComboBox
//----------------------------------------------------------------------------------------------------------------------------------
@synthesize delegate;
//----------------------------------------------------------------------------------------------------------------------------------
+ comboBox
{
return [[[self alloc] init] autorelease];
}
//----------------------------------------------------------------------------------------------------------------------------------
- init
{
self = [super init];
//see [OGButton init] for reasoning here...
DestroyWindow(widget);
widget = NULL;
HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
widget = CreateWindow("LISTBOX", "", LBS_NOINTEGRALHEIGHT,
0, 0, 32, 32,
NULL, NULL, hInst, NULL);
SetWindowLong(widget, GWL_STYLE, LBS_NOINTEGRALHEIGHT | LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_TABSTOP);
CommandHandlerData *chd = (CommandHandlerData *)malloc(sizeof(CommandHandlerData));
chd->funct = CH_Command;
chd->object = self;
SetProp(widget, "CommandHandlerData", chd);
[self retain];
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- initWithParent : (OGWidget *)parent
{
self = [super init];
//see [OGButton init] for reasoning here...
DestroyWindow(widget);
widget = NULL;
HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
widget = CreateWindow("LISTBOX", "", LBS_NOINTEGRALHEIGHT | LBS_NOTIFY | WS_CHILD | WS_VISIBLE,
0, 0, 32, 32,
parent->widget, NULL, hInst, NULL);
CommandHandlerData *chd = (CommandHandlerData *)malloc(sizeof(CommandHandlerData));
chd->funct = CH_Command;
chd->object = self;
SetProp(widget, "CommandHandlerData", chd);
[self retain];
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (id <OGComboBoxDataSource>)dataSource
{
return dataSource;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)setDataSource: (id <OGComboBoxDataSource>)dataSource_
{
OGComboBoxItem* (*itemAtIndex)(id, SEL, OGComboBox*, size_t);
dataSource = dataSource_;
itemAtIndex = (OGComboBoxItem*(*)(id, SEL, OGComboBox*, size_t))
[dataSource methodForSelector: @selector(comboBox:itemAtIndex:)];
size_t i, size = [dataSource numberOfItemsInComboBox: self];
for (i = 0; i < size; i++)
{
OGComboBoxItem *item = itemAtIndex(dataSource,
@selector(comboBox:itemAtIndex:), self, i);
SendMessage(widget, LB_ADDSTRING, 0, (WPARAM)[item.label UTF8String]);
}
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)OG_changed
{
OFAutoreleasePool *pool = [OFAutoreleasePool new];
if ([delegate respondsToSelector: @selector(comboBoxWasChanged:)])
[delegate comboBoxWasChanged: self];
[pool release];
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

59
win32/OGComboBoxItem.m Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGComboBoxItem.m
//==================================================================================================================================
#import "OGComboBoxItem.h"
//==================================================================================================================================
@implementation OGComboBoxItem
//----------------------------------------------------------------------------------------------------------------------------------
@synthesize label;
//----------------------------------------------------------------------------------------------------------------------------------
+ comboBoxItemWithLabel: (OFString*)label
{
return [[[self alloc] initWithLabel: label] autorelease];
}
//----------------------------------------------------------------------------------------------------------------------------------
- initWithLabel: (OFString*)label_
{
self = [super init];
@try {
label = [label_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)dealloc
{
[label release];
[super dealloc];
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

186
win32/OGHBox.m Normal file
View file

@ -0,0 +1,186 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGHBox.m
//==================================================================================================================================
#include <windows.h>
#import "OGHBox.h"
//==================================================================================================================================
@implementation OGHBox
//----------------------------------------------------------------------------------------------------------------------------------
- init
{
self = [super init];
[self retain];
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)appendChild: (OGWidget*)child
expand: (BOOL)expand
fill: (BOOL)fill
padding: (float)padding
{
RECT rc;
SetParent(child->widget, widget);
GetWindowRect(child->widget, &rc);
OGBoxChild *newChild = (OGBoxChild *)malloc(sizeof(OGBoxChild));
newChild->hwnd = child->widget;
newChild->expand = expand;
newChild->fill = fill;
newChild->padding = (int)padding;
newChild->originalSize = (rc.right - rc.left);
newChild->currentSize = (float)(newChild->originalSize + (newChild->padding << 1));
newChild->next = NULL;
if(firstBorn == NULL)
firstBorn = newChild;
else
{
OGBoxChild *curr = firstBorn;
while(curr->next != NULL) curr = curr->next;
curr->next = newChild;
}
[self resizeChildren];
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)prependChild: (OGWidget*)child
expand: (BOOL)expand
fill: (BOOL)fill
padding: (float)padding
{
RECT rc;
SetParent(child->widget, widget);
GetWindowRect(child->widget, &rc);
OGBoxChild *newChild = (OGBoxChild *)malloc(sizeof(OGBoxChild));
newChild->hwnd = child->widget;
newChild->expand = expand;
newChild->fill = fill;
newChild->padding = (int)padding;
newChild->originalSize = (rc.right - rc.left);
newChild->currentSize = (float)(newChild->originalSize + (newChild->padding << 1));
newChild->next = firstBorn;
firstBorn = newChild;
[self resizeChildren];
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)resizeChildren
{
RECT rc;
OGBoxChild *curr;
//get our available size
GetClientRect(widget, &rc);
int width = rc.right;
int height = rc.bottom;
//get total of childrens' widths
int childOriginal = 0;
curr = firstBorn;
while(curr != NULL)
{
childOriginal += (curr->originalSize + (curr->padding << 1));
curr = curr->next;
}
//how to divide our extra space
int extra = width - childOriginal;
float evenShare = 0.0f;
if(extra <= 0)
{
curr = firstBorn;
while(curr != NULL)
{
curr->currentSize = curr->originalSize;
curr = curr->next;
}
if(extra < 0)
{
//this will generate a WM_SIZE message, and we'll come back to resizeChildren
SetWindowPos(widget, NULL, 0, 0, childOriginal, height, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
return;
}
}
else
{
int sharers = 0;
curr = firstBorn;
while(curr != NULL)
{
if(curr->expand == YES)
sharers++;
curr = curr->next;
}
if(sharers > 0)
evenShare = (float)extra / (float)sharers;
if(evenShare > 0.0f)
{
curr = firstBorn;
while(curr != NULL)
{
if(curr->expand == YES)
if(curr->fill == YES)
curr->currentSize = (float)curr->originalSize + evenShare;
curr = curr->next;
}
}
}
//assign new positions/heights
float x = 0.0f;
curr = firstBorn;
while(curr != NULL)
{
x += (float)curr->padding;
SetWindowPos(curr->hwnd, NULL, (int)x, 0, curr->currentSize, height, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
x += (float)curr->currentSize;
if(curr->fill == NO) if(curr->expand == YES) x += evenShare;
x += (float)curr->padding;
curr = curr->next;
}
}
//----------------------------------------------------------------------------------------------------------------------------------
- (int)MessageReceived : (HWND)hwnd : (UINT)msg : (WPARAM)wparam : (LPARAM)lparam
{
switch(msg)
{
case WM_SIZE:
[self resizeChildren];
return DefWindowProc(hwnd, msg, wparam, lparam);
break;
case WM_SIZING:
[self resizeChildren];
return DefWindowProc(hwnd, msg, wparam, lparam);
break;
}
return [(id)super MessageReceived : hwnd : msg : wparam : lparam];
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

187
win32/OGVBox.m Normal file
View file

@ -0,0 +1,187 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGVBox.m
//==================================================================================================================================
#include <windows.h>
#import "OGVBox.h"
//==================================================================================================================================
@implementation OGVBox
//----------------------------------------------------------------------------------------------------------------------------------
- init
{
self = [super init];
[self retain];
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)appendChild: (OGWidget*)child
expand: (BOOL)expand
fill: (BOOL)fill
padding: (float)padding
{
RECT rc;
SetParent(child->widget, widget);
GetWindowRect(child->widget, &rc);
OGBoxChild *newChild = (OGBoxChild *)malloc(sizeof(OGBoxChild));
newChild->hwnd = child->widget;
newChild->expand = expand;
newChild->fill = fill;
newChild->padding = (int)padding;
newChild->originalSize = (rc.bottom - rc.top);
newChild->currentSize = (float)(newChild->originalSize + (newChild->padding << 1));
newChild->next = NULL;
if(firstBorn == NULL)
firstBorn = newChild;
else
{
OGBoxChild *curr = firstBorn;
while(curr->next != NULL) curr = curr->next;
curr->next = newChild;
}
[self resizeChildren];
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)prependChild: (OGWidget*)child
expand: (BOOL)expand
fill: (BOOL)fill
padding: (float)padding
{
RECT rc;
SetParent(child->widget, widget);
GetWindowRect(child->widget, &rc);
OGBoxChild *newChild = (OGBoxChild *)malloc(sizeof(OGBoxChild));
newChild->hwnd = child->widget;
newChild->expand = expand;
newChild->fill = fill;
newChild->padding = (int)padding;
newChild->originalSize = (rc.bottom - rc.top);
newChild->currentSize = (float)(newChild->originalSize + (newChild->padding << 1));
newChild->next = firstBorn;
firstBorn = newChild;
SetParent(child->widget, widget);
[self resizeChildren];
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)resizeChildren
{
RECT rc;
OGBoxChild *curr;
//get our available size
GetClientRect(widget, &rc);
int width = rc.right;
int height = rc.bottom;
//get total of childrens' heights
int childOriginal = 0;
curr = firstBorn;
while(curr != NULL)
{
childOriginal += (curr->originalSize + (curr->padding << 1));
curr = curr->next;
}
//how to divide our extra space
int extra = height - childOriginal;
float evenShare = 0.0f;
if(extra <= 0)
{
curr = firstBorn;
while(curr != NULL)
{
curr->currentSize = curr->originalSize;
curr = curr->next;
}
if(extra < 0)
{
//this will generate a WM_SIZE message, and we'll come back to resizeChildren
SetWindowPos(widget, NULL, 0, 0, width, childOriginal, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
return;
}
}
else
{
int sharers = 0;
curr = firstBorn;
while(curr != NULL)
{
if(curr->expand == YES)
sharers++;
curr = curr->next;
}
if(sharers > 0)
evenShare = (float)extra / (float)sharers;
if(evenShare > 0.0f)
{
curr = firstBorn;
while(curr != NULL)
{
if(curr->expand == YES)
if(curr->fill == YES)
curr->currentSize = (float)curr->originalSize + evenShare;
curr = curr->next;
}
}
}
//assign new positions/heights
float y = 0;
curr = firstBorn;
while(curr != NULL)
{
y += (float)curr->padding;
SetWindowPos(curr->hwnd, NULL, 0, (int)y, width, curr->currentSize, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
y += (float)curr->currentSize;
if(curr->fill == NO) if(curr->expand == YES) y += evenShare;
y += (float)curr->padding;
curr = curr->next;
}
}
//----------------------------------------------------------------------------------------------------------------------------------
- (int)MessageReceived : (HWND)hwnd : (UINT)msg : (WPARAM)wparam : (LPARAM)lparam
{
switch(msg)
{
case WM_SIZE:
[self resizeChildren];
return DefWindowProc(hwnd, msg, wparam, lparam);
break;
case WM_SIZING:
[self resizeChildren];
return DefWindowProc(hwnd, msg, wparam, lparam);
break;
}
return [(id)super MessageReceived : hwnd : msg : wparam : lparam];
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

79
win32/OGWidget.m Normal file
View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGWidget.m
//==================================================================================================================================
#include <windows.h>
#import "OGWidget.h"
//==================================================================================================================================
void og_destroy(HWND widget, OGWidget *object)
{
if(widget != NULL)
DestroyWindow(widget);
[object release];
}
//==================================================================================================================================
@implementation OGWidget
//----------------------------------------------------------------------------------------------------------------------------------
- init
{
self = [super init];
widget = NULL;
HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
widget = CreateWindowEx(WS_EX_LEFT, "OFWidgetClass", "OFWidget", WS_OVERLAPPEDWINDOW,
0, 0, 1, 1, NULL, NULL, hInst, NULL);
SetWindowLong(widget, GWL_USERDATA, (int)self);
@try {
if (isa == [OGWidget class])
@throw [OFNotImplementedException
exceptionWithClass: isa
selector: @selector(init)];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)show
{
if(widget != NULL)
ShowWindow(widget, SW_SHOWNORMAL);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)hide
{
if(widget != NULL)
ShowWindow(widget, SW_HIDE);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (int)MessageReceived : (HWND)hwnd : (UINT)msg : (WPARAM)wparam : (LPARAM)lparam
{
return DefWindowProc(hwnd, msg, wparam, lparam);
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

174
win32/OGWindow.m Normal file
View file

@ -0,0 +1,174 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//==================================================================================================================================
// OGWindow.m
//==================================================================================================================================
#include <windows.h>
#import "OGWidget.h"
#import "OGWindow.h"
//==================================================================================================================================
@interface OGWindow ()
- (BOOL)OG_willClose;
@end
//==================================================================================================================================
typedef void(*CommandHandler)(id,WPARAM);
typedef struct
{
CommandHandler funct;
id object;
} CommandHandlerData;
//==================================================================================================================================
static int CALLBACK Resize_EnumChildren(HWND child, LPARAM lparam)
{
//it appears this is actually EnumAncestorWindows, and not EnumDirectChildWindows
//so make sure child.parent == use
HWND parent = (HWND)lparam;
if(GetParent(child) != parent) return 1;
RECT rc;
GetClientRect(parent, &rc);
SetWindowPos(child, NULL, 0, 0, rc.right, rc.bottom,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
return 1;
}
//==================================================================================================================================
@implementation OGWindow
//----------------------------------------------------------------------------------------------------------------------------------
@synthesize delegate;
//----------------------------------------------------------------------------------------------------------------------------------
+ window
{
return [[[self alloc] init] autorelease];
}
//----------------------------------------------------------------------------------------------------------------------------------
- init
{
self = [super init];
SetWindowLong(widget, GWL_EXSTYLE, WS_EX_OVERLAPPEDWINDOW);
//"event connections" are handled in MessageReceived
[self retain];
return self;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (OFString*)title
{
int tlen = GetWindowTextLength(widget);
char *buff = (char *)malloc(tlen + 1);
GetWindowText(widget, buff, tlen+1);
OFString *ret = [OFString stringWithUTF8String : buff];
free(buff);
return ret;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)setTitle: (OFString*)title
{
SetWindowText(widget, [title UTF8String]);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (of_point_t)position
{
RECT rc;
GetWindowRect(widget, &rc);
return of_point((int)rc.left, (int)rc.top);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)setPosition: (of_point_t)position
{
SetWindowPos(widget, NULL, position.x, position.y, 0, 0,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (of_dimension_t)dimension
{
RECT rc;
GetWindowRect(widget, &rc);
return of_dimension(rc.right - rc.left, rc.bottom - rc.top);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)setDimension: (of_dimension_t)dimension
{
SetWindowPos(widget, NULL, 0, 0, dimension.width, dimension.height,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (void)addChild: (OGWidget*)child
{
SetParent(child->widget, widget);
//act like GTK; we'll assume a single child, and expand it to our size
RECT rc;
GetClientRect(widget, &rc);
SetWindowPos(child->widget, NULL, 0, 0, rc.right, rc.bottom,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
}
//----------------------------------------------------------------------------------------------------------------------------------
- (BOOL)OG_willClose
{
OFAutoreleasePool *pool = [OFAutoreleasePool new];
if ([delegate respondsToSelector: @selector(windowWillClose:)])
return [delegate windowWillClose: self];
[pool release];
return YES;
}
//----------------------------------------------------------------------------------------------------------------------------------
- (int)MessageReceived : (HWND)hwnd : (UINT)msg : (WPARAM)wparam : (LPARAM)lparam
{
HWND ctrlHwnd;
switch(msg)
{
case WM_COMMAND:
//NOTE: TODO: IMPLEMENT: this may need revised later for Menus and Accelerators
ctrlHwnd = (HWND)lparam;
CommandHandlerData *chd = (CommandHandlerData *)GetProp(ctrlHwnd, "CommandHandlerData");
if(chd == NULL) return DefWindowProc(hwnd, msg, wparam, lparam);
if(chd->funct == NULL) return DefWindowProc(hwnd, msg, wparam, lparam);
chd->funct(chd->object, wparam);
return 0;
break;
case WM_CLOSE:
if([self OG_willClose] == YES)
og_destroy(hwnd, self);
return 0;
break;
case WM_SIZE:
//act like GTK; expand our child(ren) to fit
EnumChildWindows(widget, Resize_EnumChildren, (LPARAM)widget);
break;
case WM_SIZING:
//act like GTK; expand our child(ren) to fit
EnumChildWindows(widget, Resize_EnumChildren, (LPARAM)widget);
break;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
//----------------------------------------------------------------------------------------------------------------------------------
@end
//==================================================================================================================================

147
win32/test.m Normal file
View file

@ -0,0 +1,147 @@
/*
* Copyright (c) 2011, 2012, Dillon Aumiller <dillonaumiller@gmail.com>
*
* https://webkeks.org/hg/objgui/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import "OGApplication.h"
#import "OGWindow.h"
#import "OGButton.h"
#import "OGHBox.h"
#import "OGVBox.h"
#import "OGComboBox.h"
//i know it's ugly, but it's just for testing...
#include <malloc.h>
@interface TestSource : OFObject <OGComboBoxDataSource>
{
OGComboBoxItem **items;
}
@end
@implementation TestSource
- init
{
self = [super init];
items = (OGComboBoxItem **)malloc(sizeof(OGComboBoxItem *) << 2);
items[0] = [OGComboBoxItem comboBoxItemWithLabel : @"Test Combo Item 0"];
items[1] = [OGComboBoxItem comboBoxItemWithLabel : @"Test Combo Item 1"];
items[2] = [OGComboBoxItem comboBoxItemWithLabel : @"Test Combo Item 2"];
items[3] = [OGComboBoxItem comboBoxItemWithLabel : @"Test Combo Item 3"];
[self retain];
return self;
}
- (size_t)numberOfItemsInComboBox: (OGComboBox*)comboBox
{
return 4;
}
- (OGComboBoxItem*)comboBox: (OGComboBox*)comboBox itemAtIndex: (size_t)index
{
return items[index];
}
@end
@interface Test: OFObject <OGApplicationDelegate, OGWindowDelegate, OGButtonDelegate, OGComboBoxDelegate>
@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];
OGHBox *hboxPre = [OGHBox box];
[vbox appendChild: hboxPre
expand: YES
fill: YES
padding: 0];
OGButton *b = [OGButton button];
b.label = @"Klick mich!";
b.delegate = self;
[hboxPre appendChild: b
expand: YES
fill: YES
padding: 0];
OGComboBox *cb = [[OGComboBox alloc] initWithParent : hboxPre];
cb.dataSource = [[TestSource alloc] init];
cb.delegate = self;
[hboxPre appendChild: cb
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
{
MessageBox(NULL, "Hallo!", "OGButton says:", MB_OK);
}
- (void)comboBoxWasChanged: (OGComboBox*)comboBox
{
MessageBox(NULL, "Selected Item Changed", "OGComboBox says:", MB_OK);
}
@end