ADDED .hgignore Index: .hgignore ================================================================== --- .hgignore +++ .hgignore @@ -0,0 +1,6 @@ +syntax: glob +*.dll +*.so +*.o +*.a +*.exe Index: headers/OGBox.h ================================================================== --- headers/OGBox.h +++ headers/OGBox.h @@ -1,7 +1,8 @@ /* * Copyright (c) 2011, 2012, Jonathan Schleifer + * Copyright (c) 2011, 2012, Dillon Aumiller * * 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 @@ -19,12 +20,29 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #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 fill: (BOOL)fill padding: (float)padding; Index: headers/OGComboBox.h ================================================================== --- headers/OGComboBox.h +++ headers/OGComboBox.h @@ -1,7 +1,8 @@ /* * Copyright (c) 2011, 2012, Jonathan Schleifer + * Copyright (c) 2011, 2012, Dillon Aumiller * * 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 @@ -39,11 +40,17 @@ @interface OGComboBox: OGWidget { id delegate; id 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 delegate; @property (assign) id dataSource; + comboBox; @end Index: headers/OGWidget.h ================================================================== --- headers/OGWidget.h +++ headers/OGWidget.h @@ -1,7 +1,8 @@ /* * Copyright (c) 2011, 2012, Jonathan Schleifer + * Copyright (c) 2011, 2012, Dillon Aumiller * * 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 @@ -19,11 +20,14 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifdef OG_GTK -# include +#i nclude +#endif +#ifdef OG_W32 +# include #endif #import @interface OGWidget: OFObject @@ -30,12 +34,20 @@ { @public #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 ADDED win32/Makefile Index: win32/Makefile ================================================================== --- win32/Makefile +++ win32/Makefile @@ -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 ADDED win32/OGApplication.m Index: win32/OGApplication.m ================================================================== --- win32/OGApplication.m +++ win32/OGApplication.m @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 //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]; +} +//================================================================================================================================== ADDED win32/OGBox.m Index: win32/OGBox.m ================================================================== --- win32/OGBox.m +++ win32/OGBox.m @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +#include +#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 +//================================================================================================================================== ADDED win32/OGButton.m Index: win32/OGButton.m ================================================================== --- win32/OGButton.m +++ win32/OGButton.m @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +//================================================================================================================================== ADDED win32/OGComboBox.m Index: win32/OGComboBox.m ================================================================== --- win32/OGComboBox.m +++ win32/OGComboBox.m @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 )dataSource +{ + return dataSource; +} +//---------------------------------------------------------------------------------------------------------------------------------- +- (void)setDataSource: (id )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 +//================================================================================================================================== ADDED win32/OGComboBoxItem.m Index: win32/OGComboBoxItem.m ================================================================== --- win32/OGComboBoxItem.m +++ win32/OGComboBoxItem.m @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +//================================================================================================================================== ADDED win32/OGHBox.m Index: win32/OGHBox.m ================================================================== --- win32/OGHBox.m +++ win32/OGHBox.m @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +#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 +//================================================================================================================================== ADDED win32/OGVBox.m Index: win32/OGVBox.m ================================================================== --- win32/OGVBox.m +++ win32/OGVBox.m @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +#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 +//================================================================================================================================== ADDED win32/OGWidget.m Index: win32/OGWidget.m ================================================================== --- win32/OGWidget.m +++ win32/OGWidget.m @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +#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 +//================================================================================================================================== ADDED win32/OGWindow.m Index: win32/OGWindow.m ================================================================== --- win32/OGWindow.m +++ win32/OGWindow.m @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +#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 +//================================================================================================================================== ADDED win32/test.m Index: win32/test.m ================================================================== --- win32/test.m +++ win32/test.m @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2011, 2012, Dillon Aumiller + * + * 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 +@interface TestSource : OFObject +{ + 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 +@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