win32 branch commit
This commit is contained in:
parent
3a0d3fd94e
commit
bbbeb0bebe
15 changed files with 1337 additions and 1 deletions
6
.hgignore
Normal file
6
.hgignore
Normal file
|
@ -0,0 +1,6 @@
|
|||
syntax: glob
|
||||
*.dll
|
||||
*.so
|
||||
*.o
|
||||
*.a
|
||||
*.exe
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
12
win32/Makefile
Normal 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
119
win32/OGApplication.m
Normal 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
90
win32/OGBox.m
Normal 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
111
win32/OGButton.m
Normal 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
129
win32/OGComboBox.m
Normal 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
59
win32/OGComboBoxItem.m
Normal 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
186
win32/OGHBox.m
Normal 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
187
win32/OGVBox.m
Normal 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
79
win32/OGWidget.m
Normal 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
174
win32/OGWindow.m
Normal 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
147
win32/test.m
Normal 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
|
Reference in a new issue