summaryrefslogtreecommitdiff
path: root/new
diff options
context:
space:
mode:
Diffstat (limited to 'new')
-rw-r--r--new/GNUmakefile62
-rw-r--r--new/TODO.md27
-rw-r--r--new/darwin/GNUmakeinc.mk19
-rw-r--r--new/darwin/alloc.m44
-rw-r--r--new/darwin/button.m86
-rw-r--r--new/darwin/checkbox.m107
-rw-r--r--new/darwin/entry.m73
-rw-r--r--new/darwin/init.m67
-rw-r--r--new/darwin/label.m59
-rw-r--r--new/darwin/main.m27
-rw-r--r--new/darwin/newcontrol.m231
-rw-r--r--new/darwin/parent.m118
-rw-r--r--new/darwin/tab.m73
-rw-r--r--new/darwin/text.m19
-rw-r--r--new/darwin/uipriv_darwin.h40
-rw-r--r--new/darwin/util.m20
-rw-r--r--new/darwin/window.m162
-rw-r--r--new/leaks.awk56
-rw-r--r--new/parentplan57
-rw-r--r--new/stack.c398
-rw-r--r--new/test.c337
-rw-r--r--new/ui.idl161
-rw-r--r--new/ui_darwin.h25
-rw-r--r--new/ui_unix.h20
-rw-r--r--new/ui_windows.h59
-rw-r--r--new/uipriv.h10
-rw-r--r--new/unix/GNUmakeinc.mk18
-rw-r--r--new/unix/alloc.c33
-rw-r--r--new/unix/button.c71
-rw-r--r--new/unix/checkbox.c95
-rw-r--r--new/unix/entry.c45
-rw-r--r--new/unix/init.c23
-rw-r--r--new/unix/label.c49
-rw-r--r--new/unix/main.c23
-rw-r--r--new/unix/newcontrol.c225
-rw-r--r--new/unix/parent.c183
-rw-r--r--new/unix/tab.c61
-rw-r--r--new/unix/uipriv_unix.h14
-rw-r--r--new/unix/util.c7
-rw-r--r--new/unix/window.c137
-rw-r--r--new/windows/GNUmakeinc.mk33
-rw-r--r--new/windows/alloc.c49
-rw-r--r--new/windows/button.c112
-rw-r--r--new/windows/checkbox.c129
-rw-r--r--new/windows/comctl32.c105
-rw-r--r--new/windows/debug.c111
-rw-r--r--new/windows/entry.c69
-rw-r--r--new/windows/init.c112
-rw-r--r--new/windows/label.c73
-rw-r--r--new/windows/main.c56
-rw-r--r--new/windows/newcontrol.c237
-rw-r--r--new/windows/parent.c268
-rw-r--r--new/windows/tab.c190
-rw-r--r--new/windows/text.c55
-rw-r--r--new/windows/uipriv_windows.h69
-rw-r--r--new/windows/util.c73
-rw-r--r--new/windows/window.c216
57 files changed, 0 insertions, 5298 deletions
diff --git a/new/GNUmakefile b/new/GNUmakefile
deleted file mode 100644
index 457efe4..0000000
--- a/new/GNUmakefile
+++ /dev/null
@@ -1,62 +0,0 @@
-# 15 april 2015
-
-OBJDIR = .obj
-
-# MAME does this so :/
-ifeq ($(OS),Windows_NT)
-OS = windows
-endif
-
-ifndef OS
-UNAME = $(shell uname -s)
-ifeq ($(UNAME),Darwin)
-OS = darwin
-else
-OS = unix
-endif
-endif
-
-CFILES = \
- stack.c \
- test.c
-HFILES = \
- ui.h \
- uipriv.h \
- ui_$(OS).h \
- $(OS)/uipriv_$(OS).h
-
-xCFLAGS = \
- -g \
- -Wall -Wextra \
- -Wno-unused-parameter \
- --std=c99 \
- $(CFLAGS)
-xLDFLAGS = \
- -g \
- $(LDFLAGS)
-
-include $(OS)/GNUmakeinc.mk
-xOSCFILES = $(OSCFILES:%=$(OS)/%)
-xOSMFILES = $(OSMFILES:%=$(OS)/%)
-
-OFILES = $(CFILES:%.c=$(OBJDIR)/%.o) \
- $(xOSCFILES:$(OS)/%.c=$(OBJDIR)/%_$(OS).o) \
- $(xOSMFILES:$(OS)/%.m=$(OBJDIR)/%_$(OS).o)
-
-$(OUT): $(OFILES)
- $(CC) -o $(OUT) $(OFILES) $(xLDFLAGS)
-
-$(OBJDIR)/%.o: %.c $(OBJDIR) $(HFILES)
- $(CC) -o $@ -c $< $(xCFLAGS)
-
-$(OBJDIR)/%_$(OS).o: $(OS)/%.c $(OBJDIR) $(HFILES)
- $(CC) -o $@ -c $< $(xCFLAGS)
-
-$(OBJDIR)/%_$(OS).o: $(OS)/%.m $(OBJDIR) $(HFILES)
- $(CC) -o $@ -c $< $(xCFLAGS)
-
-$(OBJDIR):
- mkdir -p $(OBJDIR)
-
-ui.h: ui.idl
- idl2h < ui.idl > ui.h
diff --git a/new/TODO.md b/new/TODO.md
deleted file mode 100644
index d3004f0..0000000
--- a/new/TODO.md
+++ /dev/null
@@ -1,27 +0,0 @@
-- change all private names to uipXxxx
-- make it so Windows API calls that do logLastError(), etc. abort whatever they're doing and not try to continue, just like wintable
-- figure out what to cleanup in darwin terminate:
- - delegate
- - deleted objects view
-- assign control IDs on windows
- - GWL(P)_ID
- - related? [12:25] <ZeroOne> And the blue outline on those buttons [ALL clicked buttons on Windows 7] won't go away
- - I get this too
-- make sure all terminology is consistent
-- 32-bit Mac OS X support (requires lots of code changes)
-- add a test for hidden controls when a window is shown
-- SWP_NOCOPYBITS (or was it WS_CLIPCHILDREN?)
- - buttons not in tab get drawover issues
- - buttons in tab without transparent drawing code get copied into the label when stack shown and rehidden
-- see if we can clean up the backends
- - rename all method implementations to typeMethod
- - especially clean up the Darwin backend
-
-ultimately:
-- make everything vtable-based
- - provide macros for the vtables
- - figure out where updateParent() plays into this
- - figure out what to do about custom containers
- - rename container to parent?
- - make the code flow of all platforms fully symmetrical
-- add some sort of runtime type checking
diff --git a/new/darwin/GNUmakeinc.mk b/new/darwin/GNUmakeinc.mk
deleted file mode 100644
index 22ca1e3..0000000
--- a/new/darwin/GNUmakeinc.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-OSMFILES = \
- alloc.m \
- button.m \
- checkbox.m \
- entry.m \
- init.m \
- label.m \
- main.m \
- newcontrol.m \
- parent.m \
- tab.m \
- text.m \
- util.m \
- window.m
-
-xCFLAGS += -mmacosx-version-min=10.7 -DMACOSX_DEPLOYMENT_TARGET=10.7
-xLDFLAGS += -mmacosx-version-min=10.7 -lobjc -framework Foundation -framework AppKit
-
-OUT = new
diff --git a/new/darwin/alloc.m b/new/darwin/alloc.m
deleted file mode 100644
index 8f539af..0000000
--- a/new/darwin/alloc.m
+++ /dev/null
@@ -1,44 +0,0 @@
-// 4 december 2014
-#import <stdio.h>
-#import "uipriv_darwin.h"
-
-void *uiAlloc(size_t size, const char *type)
-{
- void *out;
-
- out = malloc(size);
- if (out == NULL) {
- fprintf(stderr, "memory exhausted in uiAlloc() allocating %s\n", type);
- abort();
- }
- memset(out, 0, size);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p alloc %s\n", out, type);
- return out;
-}
-
-void *uiRealloc(void *p, size_t size, const char *type)
-{
- void *out;
-
- if (p == NULL)
- return uiAlloc(size, type);
- out = realloc(p, size);
- if (out == NULL) {
- fprintf(stderr, "memory exhausted in uiRealloc() reallocating %s\n", type);
- abort();
- }
- // TODO zero the extra memory
- if (options.debugLogAllocations)
- fprintf(stderr, "%p realloc %p\n", p, out);
- return out;
-}
-
-void uiFree(void *p)
-{
- if (p == NULL)
- return;
- free(p);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p free\n", p);
-}
diff --git a/new/darwin/button.m b/new/darwin/button.m
deleted file mode 100644
index 3ec8a54..0000000
--- a/new/darwin/button.m
+++ /dev/null
@@ -1,86 +0,0 @@
-// 7 april 2015
-#import "uipriv_darwin.h"
-
-@interface uiNSButton : NSButton
-@property uiButton *uiB;
-@property void (*uiOnClicked)(uiButton *, void *);
-@property void *uiOnClickedData;
-@end
-
-@implementation uiNSButton
-
-- (void)viewDidMoveToSuperview
-{
- if (uiDarwinControlFreeWhenAppropriate(uiControl(self.uiB), [self superview])) {
- [self setTarget:nil];
- self.uiB = NULL;
- }
- [super viewDidMoveToSuperview];
-}
-
-- (IBAction)uiButtonClicked:(id)sender
-{
- (*(self.uiOnClicked))(self.uiB, self.uiOnClickedData);
-}
-
-@end
-
-static void defaultOnClicked(uiButton *c, void *data)
-{
- // do nothing
-}
-
-static char *buttonText(uiButton *bb)
-{
- uiNSButton *b;
-
- b = (uiNSButton *) uiControlHandle(uiControl(bb));
- return uiDarwinNSStringToText([b title]);
-}
-
-static void buttonSetText(uiButton *bb, const char *text)
-{
- uiNSButton *b;
-
- b = (uiNSButton *) uiControlHandle(uiControl(bb));
- [b setTitle:toNSString(text)];
-}
-
-static void buttonOnClicked(uiButton *bb, void (*f)(uiButton *, void *), void *data)
-{
- uiNSButton *b;
-
- b = (uiNSButton *) uiControlHandle(uiControl(bb));
- b.uiOnClicked = f;
- b.uiOnClickedData = data;
-}
-
-uiButton *uiNewButton(const char *text)
-{
- uiButton *b;
- uiNSButton *bb;
-
- b = uiNew(uiButton);
-
- uiDarwinNewControl(uiControl(b), [uiNSButton class], NO, NO);
- bb = (uiNSButton *) uiControlHandle(uiControl(b));
-
- [bb setTitle:toNSString(text)];
- [bb setButtonType:NSMomentaryPushInButton];
- [bb setBordered:YES];
- [bb setBezelStyle:NSRoundedBezelStyle];
- setStandardControlFont((NSControl *) bb);
-
- [bb setTarget:bb];
- [bb setAction:@selector(uiButtonClicked:)];
-
- bb.uiOnClicked = defaultOnClicked;
-
- uiButton(b)->Text = buttonText;
- uiButton(b)->SetText = buttonSetText;
- uiButton(b)->OnClicked = buttonOnClicked;
-
- bb.uiB = b;
-
- return bb.uiB;
-}
diff --git a/new/darwin/checkbox.m b/new/darwin/checkbox.m
deleted file mode 100644
index a7ccfb3..0000000
--- a/new/darwin/checkbox.m
+++ /dev/null
@@ -1,107 +0,0 @@
-// 7 april 2015
-#import "uipriv_darwin.h"
-
-@interface uiCheckboxNSButton : NSButton
-@property uiCheckbox *uiC;
-@property void (*uiOnToggled)(uiCheckbox *, void *);
-@property void *uiOnToggledData;
-@end
-
-@implementation uiCheckboxNSButton
-
-- (void)viewDidMoveToSuperview
-{
- if (uiDarwinControlFreeWhenAppropriate(uiControl(self.uiC), [self superview])) {
- [self setTarget:nil];
- self.uiC = NULL;
- }
- [super viewDidMoveToSuperview];
-}
-
-- (IBAction)uiCheckboxToggled:(id)sender
-{
- (*(self.uiOnToggled))(self.uiC, self.uiOnToggledData);
-}
-
-@end
-
-static void defaultOnToggled(uiCheckbox *c, void *data)
-{
- // do nothing
-}
-
-static char *checkboxText(uiCheckbox *c)
-{
- uiCheckboxNSButton *cc;
-
- cc = (uiCheckboxNSButton *) uiControlHandle(uiControl(c));
- return uiDarwinNSStringToText([cc title]);
-}
-
-static void checkboxSetText(uiCheckbox *c, const char *text)
-{
- uiCheckboxNSButton *cc;
-
- cc = (uiCheckboxNSButton *) uiControlHandle(uiControl(c));
- [cc setTitle:toNSString(text)];
-}
-
-static void checkboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *, void *), void *data)
-{
- uiCheckboxNSButton *cc;
-
- cc = (uiCheckboxNSButton *) uiControlHandle(uiControl(c));
- cc.uiOnToggled = f;
- cc.uiOnToggledData = data;
-}
-
-static int checkboxChecked(uiCheckbox *c)
-{
- uiCheckboxNSButton *cc;
-
- cc = (uiCheckboxNSButton *) uiControlHandle(uiControl(c));
- return [cc state] == NSOnState;
-}
-
-static void checkboxSetChecked(uiCheckbox *c, int checked)
-{
- uiCheckboxNSButton *cc;
- NSInteger state;
-
- cc = (uiCheckboxNSButton *) uiControlHandle(uiControl(c));
- state = NSOnState;
- if (!checked)
- state = NSOffState;
- [cc setState:state];
-}
-
-uiCheckbox *uiNewCheckbox(const char *text)
-{
- uiCheckbox *c;
- uiCheckboxNSButton *cc;
-
- c = uiNew(uiCheckbox);
-
- uiDarwinNewControl(uiControl(c), [uiCheckboxNSButton class], NO, NO);
- cc = (uiCheckboxNSButton *) uiControlHandle(uiControl(c));
-
- [cc setTitle:toNSString(text)];
- [cc setButtonType:NSSwitchButton];
- [cc setBordered:NO];
- setStandardControlFont((NSControl *) cc);
-
- [cc setTarget:cc];
- [cc setAction:@selector(uiCheckboxToggled:)];
-
- cc.uiOnToggled = defaultOnToggled;
-
- uiCheckbox(c)->Text = checkboxText;
- uiCheckbox(c)->SetText = checkboxSetText;
- uiCheckbox(c)->OnToggled = checkboxOnToggled;
- uiCheckbox(c)->Checked = checkboxChecked;
- uiCheckbox(c)->SetChecked = checkboxSetChecked;
-
- cc.uiC = c;
-
- return cc.uiC;
-}
diff --git a/new/darwin/entry.m b/new/darwin/entry.m
deleted file mode 100644
index 7189156..0000000
--- a/new/darwin/entry.m
+++ /dev/null
@@ -1,73 +0,0 @@
-// 9 april 2015
-#import "uipriv_darwin.h"
-
-@interface uiNSTextField : NSTextField
-@property uiEntry *uiE;
-@end
-
-@implementation uiNSTextField
-
-- (void)viewDidMoveToSuperview
-{
- if (uiDarwinControlFreeWhenAppropriate(uiControl(self.uiE), [self superview])) {
- [self setTarget:nil];
- self.uiE = NULL;
- }
- [super viewDidMoveToSuperview];
-}
-
-@end
-
-static char *entryText(uiEntry *e)
-{
- uiNSTextField *t;
-
- t = (uiNSTextField *) uiControlHandle(uiControl(e));
- return uiDarwinNSStringToText([t stringValue]);
-}
-
-static void entrySetText(uiEntry *e, const char *text)
-{
- uiNSTextField *t;
-
- t = (uiNSTextField *) uiControlHandle(uiControl(e));
- [t setStringValue:toNSString(text)];
-}
-
-// TOOD move elsewhere
-// these are based on interface builder defaults; my comments in the old code weren't very good so I don't really know what talked about what, sorry :/
-void finishNewTextField(NSTextField *t, BOOL isEntry)
-{
- setStandardControlFont((id) t);
-
- // THE ORDER OF THESE CALLS IS IMPORTANT; CHANGE IT AND THE BORDERS WILL DISAPPEAR
- [t setBordered:NO];
- [t setBezelStyle:NSTextFieldSquareBezel];
- [t setBezeled:isEntry];
-
- // we don't need to worry about substitutions/autocorrect here; see window_darwin.m for details
-
- [[t cell] setLineBreakMode:NSLineBreakByClipping];
- [[t cell] setScrollable:YES];
-}
-
-uiEntry *uiNewEntry(void)
-{
- uiEntry *e;
- uiNSTextField *t;
-
- e = uiNew(uiEntry);
-
- uiDarwinNewControl(uiControl(e), [uiNSTextField class], NO, NO);
- t = (uiNSTextField *) uiControlHandle(uiControl(e));
-
- [t setSelectable:YES]; // otherwise the setting is masked by the editable default of YES
- finishNewTextField((NSTextField *) t, YES);
-
- uiEntry(e)->Text = entryText;
- uiEntry(e)->SetText = entrySetText;
-
- t.uiE = e;
-
- return t.uiE;
-}
diff --git a/new/darwin/init.m b/new/darwin/init.m
deleted file mode 100644
index 4f14a0a..0000000
--- a/new/darwin/init.m
+++ /dev/null
@@ -1,67 +0,0 @@
-// 6 april 2015
-#import "uipriv_darwin.h"
-
-@interface uiApplication : NSApplication
-@end
-
-@implementation uiApplication
-
-// hey look! we're overriding terminate:!
-// we're going to make sure we can go back to main() whether Cocoa likes it or not!
-// and just how are we going to do that, hm?
-// (note: this is called after applicationShouldTerminate:)
-- (void)terminate:(id)sender
-{
- // yes that's right folks: DO ABSOLUTELY NOTHING.
- // the magic is [NSApp run] will just... stop.
-
- // for debugging
- NSLog(@"in terminate:");
-}
-
-@end
-
-@interface uiAppDelegate : NSObject <NSApplicationDelegate>
-@end
-
-@implementation uiAppDelegate
-
-- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app
-{
- // for debugging
- NSLog(@"in applicationShouldTerminate:");
- return NSTerminateNow;
-}
-
-- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app
-{
- return NO;
-}
-
-@end
-
-// we are not in control of the actual lifetimes and refcounts of NSViews (see http://stackoverflow.com/a/29523141/3408572)
-// when we're done with a view, it'll be added as a subview of this one, and this one will be released on application shutdown
-// we need this separate view because it's possible for controls to have no parent but still be alive
-NSView *destroyedControlsView;
-
-uiInitOptions options;
-
-const char *uiInit(uiInitOptions *o)
-{
- options = *o;
- [uiApplication sharedApplication];
- // don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy!
- // see https://github.com/andlabs/ui/issues/6
- [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
- [NSApp setDelegate:[uiAppDelegate new]];
-
- // we can use a stock NSView for this
- destroyedControlsView = [[NSView alloc] initWithFrame:NSZeroRect];
-
- return NULL;
-}
-
-void uiFreeInitError(const char *err)
-{
-}
diff --git a/new/darwin/label.m b/new/darwin/label.m
deleted file mode 100644
index 56780d0..0000000
--- a/new/darwin/label.m
+++ /dev/null
@@ -1,59 +0,0 @@
-// 9 april 2015
-#import "uipriv_darwin.h"
-
-@interface uiLabelNSTextField : NSTextField
-@property uiLabel *uiL;
-@end
-
-@implementation uiLabelNSTextField
-
-- (void)viewDidMoveToSuperview
-{
- if (uiDarwinControlFreeWhenAppropriate(uiControl(self.uiL), [self superview])) {
- [self setTarget:nil];
- self.uiL = NULL;
- }
- [super viewDidMoveToSuperview];
-}
-
-@end
-
-static char *labelText(uiLabel *l)
-{
- uiLabelNSTextField *t;
-
- t = (uiLabelNSTextField *) uiControlHandle(uiControl(l));
- return uiDarwinNSStringToText([t stringValue]);
-}
-
-static void labelSetText(uiLabel *l, const char *text)
-{
- uiLabelNSTextField *t;
-
- t = (uiLabelNSTextField *) uiControlHandle(uiControl(l));
- [t setStringValue:toNSString(text)];
-}
-
-uiLabel *uiNewLabel(const char *text)
-{
- uiLabel *l;
- uiLabelNSTextField *t;
-
- l = uiNew(uiLabel);
-
- uiDarwinNewControl(uiControl(l), [uiLabelNSTextField class], NO, NO);
- t = (uiLabelNSTextField *) uiControlHandle(uiControl(l));
-
- [t setStringValue:toNSString(text)];
- [t setEditable:NO];
- [t setSelectable:NO];
- [t setDrawsBackground:NO];
- finishNewTextField((NSTextField *) t, NO);
-
- uiLabel(l)->Text = labelText;
- uiLabel(l)->SetText = labelSetText;
-
- t.uiL = l;
-
- return t.uiL;
-}
diff --git a/new/darwin/main.m b/new/darwin/main.m
deleted file mode 100644
index 8663b58..0000000
--- a/new/darwin/main.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// 6 april 2015
-#import "uipriv_darwin.h"
-
-// #qo LDFLAGS: -lobjc -framework Foundation -framework AppKit
-
-void uiMain(void)
-{
- [NSApp run];
-}
-
-void uiQuit(void)
-{
- NSEvent *e;
-
- [NSApp stop:NSApp];
- // stop: won't register until another event has passed; let's synthesize one
- e = [NSEvent otherEventWithType:NSApplicationDefined
- location:NSZeroPoint
- modifierFlags:0
- timestamp:[[NSProcessInfo processInfo] systemUptime]
- windowNumber:0
- context:[NSGraphicsContext currentContext]
- subtype:0
- data1:0
- data2:0];
- [NSApp postEvent:e atStart:NO]; // let pending events take priority (this is what PostQuitMessage() on Windows does so we have to do it here too for parity; thanks to mikeash in irc.freenode.net/#macdev for confirming that this parameter should indeed be NO)
-}
diff --git a/new/darwin/newcontrol.m b/new/darwin/newcontrol.m
deleted file mode 100644
index 12967c5..0000000
--- a/new/darwin/newcontrol.m
+++ /dev/null
@@ -1,231 +0,0 @@
-// 7 april 2015
-#include "uipriv_darwin.h"
-
-typedef struct singleView singleView;
-
-struct singleView {
- NSView *view;
- NSScrollView *scrollView;
- NSView *immediate; // the control that is added to the parent container; either view or scrollView
- uiParent *parent;
- BOOL userHid;
- BOOL containerHid;
- BOOL userDisabled;
- BOOL containerDisabled;
-};
-
-static void singleDestroy(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- [destroyedControlsView addSubview:s->immediate];
-}
-
-static uintptr_t singleHandle(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- return (uintptr_t) (s->view);
-}
-
-static void singleSetParent(uiControl *c, uiParent *parent)
-{
- singleView *s = (singleView *) (c->Internal);
- NSView *parentView;
- uiParent *oldparent;
-
- oldparent = s->parent;
- s->parent = parent;
- if (oldparent != NULL) {
- [s->immediate removeFromSuperview];
- uiParentUpdate(oldparent);
- }
- if (s->parent != NULL) {
- // TODO uiControlView(), uiParentView()
- parentView = (NSView *) uiParentHandle(s->parent);
- [parentView addSubview:s->immediate];
- uiParentUpdate(s->parent);
- }
-}
-
-// also good for NSBox and NSProgressIndicator
-static void singlePreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- singleView *s = (singleView *) (c->Internal);
- NSControl *control;
- NSRect r;
-
- control = (NSControl *) (s->view);
- [control sizeToFit];
- // use alignmentRect here instead of frame because we'll be resizing based on that
- r = [control alignmentRectForFrame:[control frame]];
- *width = (intmax_t) r.size.width;
- *height = (intmax_t) r.size.height;
-}
-
-static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
-{
- singleView *s = (singleView *) (c->Internal);
- NSRect frame;
-
- frame.origin.x = x;
- // mac os x coordinate system has (0,0) in the lower-left
- frame.origin.y = ([[s->immediate superview] bounds].size.height - height) - y;
- frame.size.width = width;
- frame.size.height = height;
- frame = [s->immediate frameForAlignmentRect:frame];
- [s->immediate setFrame:frame];
-}
-
-static int singleVisible(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- if (s->userHid)
- return 0;
- return 1;
-}
-
-static void singleShow(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->userHid = NO;
- if (!s->containerHid) {
- [s->immediate setHidden:NO];
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void singleHide(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->userHid = YES;
- [s->immediate setHidden:YES];
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void singleContainerShow(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->containerHid = NO;
- if (!s->userHid) {
- [s->immediate setHidden:NO];
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void singleContainerHide(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->containerHid = YES;
- [s->immediate setHidden:YES];
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void enable(singleView *s)
-{
- if ([s->view respondsToSelector:@selector(setEnabled:)])
- [((NSControl *) (s->view)) setEnabled:YES];
-}
-
-static void disable(singleView *s)
-{
- if ([s->view respondsToSelector:@selector(setEnabled:)])
- [((NSControl *) (s->view)) setEnabled:NO];
-}
-
-static void singleEnable(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->userDisabled = NO;
- if (!s->containerDisabled)
- enable(s);
-}
-
-static void singleDisable(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->userDisabled = YES;
- disable(s);
-}
-
-static void singleContainerEnable(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->containerDisabled = NO;
- if (!s->userDisabled)
- enable(s);
-}
-
-static void singleContainerDisable(uiControl *c)
-{
- singleView *s = (singleView *) (c->Internal);
-
- s->containerDisabled = YES;
- disable(s);
-}
-
-void uiDarwinNewControl(uiControl *c, Class class, BOOL inScrollView, BOOL scrollViewHasBorder)
-{
- singleView *s;
-
- s = uiNew(singleView);
- // thanks to autoxr and arwyn in irc.freenode.net/#macdev
- s->view = (NSView *) [[class alloc] initWithFrame:NSZeroRect];
- s->immediate = s->view;
-
- if (inScrollView) {
- s->scrollView = [[NSScrollView alloc] initWithFrame:NSZeroRect];
- [s->scrollView setDocumentView:s->view];
- [s->scrollView setHasHorizontalScroller:YES];
- [s->scrollView setHasVerticalScroller:YES];
- [s->scrollView setAutohidesScrollers:YES];
- if (scrollViewHasBorder)
- [s->scrollView setBorderType:NSBezelBorder];
- else
- [s->scrollView setBorderType:NSNoBorder];
- s->immediate = (NSView *) (s->scrollView);
- }
-
- // and keep a reference to s->immediate for when we remove the control from its parent
- [s->immediate retain];
-
- c->Internal = s;
- c->Destroy = singleDestroy;
- c->Handle = singleHandle;
- c->SetParent = singleSetParent;
- c->PreferredSize = singlePreferredSize;
- c->Resize = singleResize;
- c->Visible = singleVisible;
- c->Show = singleShow;
- c->Hide = singleHide;
- c->ContainerShow = singleContainerShow;
- c->ContainerHide = singleContainerHide;
- c->Enable = singleEnable;
- c->Disable = singleDisable;
- c->ContainerEnable = singleContainerEnable;
- c->ContainerDisable = singleContainerDisable;
-}
-
-BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview)
-{
- singleView *s = (singleView *) (c->Internal);
-
- if (newSuperview == destroyedControlsView) {
- [s->immediate release]; // we don't need the reference anymore
- uiFree(s);
- return YES;
- }
- return NO;
-}
diff --git a/new/darwin/parent.m b/new/darwin/parent.m
deleted file mode 100644
index abf0e59..0000000
--- a/new/darwin/parent.m
+++ /dev/null
@@ -1,118 +0,0 @@
-// 4 august 2014
-#import "uipriv_darwin.h"
-
-// calling -[className] on the content views of NSWindow, NSTabItem, and NSBox all return NSView, so I'm assuming I just need to override these
-// fornunately:
-// - NSWindow resizing calls -[setFrameSize:] (but not -[setFrame:])
-// - NSTabView resizing calls both -[setFrame:] and -[setFrameSIze:] on the current tab
-// - NSTabView switching tabs calls both -[setFrame:] and -[setFrameSize:] on the new tab
-// so we just override setFrameSize:
-// thanks to mikeash and JtRip in irc.freenode.net/#macdev
-@interface uipParent : NSView {
-// TODO
-@public
- uiControl *child;
- intmax_t marginLeft;
- intmax_t marginTop;
- intmax_t marginRight;
- intmax_t marginBottom;
-}
-- (void)uiUpdateNow;
-@end
-
-@implementation uipParent
-
-uiLogObjCClassAllocations
-
-- (void)viewDidMoveToSuperview
-{
- // we can't just use nil because NSTabView will set page views to nil when they're tabbed away
- // this means that we have to explicitly move them to the destroyed controls view when we're done with them, and likewise in NSWindow
- if ([self superview] == destroyedControlsView)
- if (self->child != NULL) {
- uiControlDestroy(self->child);
- self->child = NULL;
- [self release];
- }
- [super viewDidMoveToSuperview];
-}
-
-- (void)setFrameSize:(NSSize)s
-{
- [super setFrameSize:s];
- [self uiUpdateNow];
-}
-
-// These are based on measurements from Interface Builder.
-// These seem to be based on Auto Layout constants, but I don't see an API that exposes these...
-// This one is 8 for most pairs of controls that I've tried; the only difference is between two pushbuttons, where it's 12...
-#define macXPadding 8
-// Likewise, this one appears to be 12 for pairs of push buttons...
-#define macYPadding 8
-
-- (void)uiUpdateNow
-{
- uiSizing d;
- intmax_t x, y, width, height;
-
- if (self->child == NULL)
- return;
- x = [self bounds].origin.x + self->marginLeft;
- y = [self bounds].origin.y + self->marginTop;
- width = [self bounds].size.width - (self->marginLeft + self->marginRight);
- height = [self bounds].size.height - (self->marginTop + self->marginBottom);
- d.xPadding = macXPadding;
- d.yPadding = macYPadding;
- uiControlResize(self->child, x, y, width, height, &d);
-}
-
-@end
-
-static uintptr_t parentHandle(uiParent *p)
-{
- uipParent *pp = (uipParent *) (p->Internal);
-
- return (uintptr_t) pp;
-}
-
-static void parentSetChild(uiParent *p, uiControl *child)
-{
- uipParent *pp = (uipParent *) (p->Internal);
-
- pp->child = child;
- if (pp->child != NULL)
- uiControlSetParent(child, p);
-}
-
-static void parentSetMargins(uiParent *p, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
-{
- uipParent *pp = (uipParent *) (p->Internal);
-
- pp->marginLeft = left;
- pp->marginTop = top;
- pp->marginRight = right;
- pp->marginBottom = bottom;
-}
-
-static void parentUpdate(uiParent *p)
-{
- uipParent *pp = (uipParent *) (p->Internal);
-
- [pp uiUpdateNow];
-}
-
-uiParent *uiNewParent(uintptr_t osParent)
-{
- uiParent *p;
-
- p = uiNew(uiParent);
- p->Internal = [[uipParent alloc] initWithFrame:NSZeroRect];
- p->Handle = parentHandle;
- p->SetChild = parentSetChild;
- p->SetMargins = parentSetMargins;
- p->Update = parentUpdate;
- // don't use osParent; we'll need to call specific selectors to set the parent view
- // and keep the view alive so we can release it properly later
- [((uipParent *) (p->Internal)) retain];
- return p;
-} \ No newline at end of file
diff --git a/new/darwin/tab.m b/new/darwin/tab.m
deleted file mode 100644
index b84ee9a..0000000
--- a/new/darwin/tab.m
+++ /dev/null
@@ -1,73 +0,0 @@
-// 12 april 2015
-#import "uipriv_darwin.h"
-
-// TODO
-// - verify margins against extra space around the tab
-// - free child containers properly
-
-@interface uiNSTabView : NSTabView
-@property uiTab *uiT;
-@end
-
-@implementation uiNSTabView
-
-- (void)viewDidMoveToSuperview
-{
- // TODO free all tabs explicitly
- if (uiDarwinControlFreeWhenAppropriate(uiControl(self.uiT), [self superview]))
- self.uiT = NULL;
- [super viewDidMoveToSuperview];
-}
-
-@end
-
-// the default new control implementation uses -sizeToFit, which we don't have with NSTabView
-// fortunately, we do have -minimumSize
-static void preferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- uiNSTabView *tv;
- NSSize s;
-
- tv = (uiNSTabView *) uiControlHandle(c);
- s = [tv minimumSize];
- *width = (intmax_t) (s.width);
- *height = (intmax_t) (s.height);
-}
-
-static void tabAddPage(uiTab *t, const char *name, uiControl *child)
-{
- uiNSTabView *tv;
- uiParent *content;
- NSTabViewItem *i;
-
- content = uiNewParent(0);
- uiParentSetChild(content, child);
-
- i = [[NSTabViewItem alloc] initWithIdentifier:nil];
- [i setLabel:toNSString(name)];
- [i setView:((NSView *) uiParentHandle(content))];
- tv = (uiNSTabView *) uiControlHandle(uiControl(t));
- [tv addTabViewItem:i];
-}
-
-uiTab *uiNewTab(void)
-{
- uiTab *t;
- uiNSTabView *tv;
-
- t = uiNew(uiTab);
-
- uiDarwinNewControl(uiControl(t), [uiNSTabView class], NO, NO);
- tv = (uiNSTabView *) uiControlHandle(uiControl(t));
-
- // also good for NSTabView (same selector and everything)
- setStandardControlFont((NSControl *) tv);
-
- uiControl(t)->PreferredSize = preferredSize;
-
- uiTab(t)->AddPage = tabAddPage;
-
- tv.uiT = t;
-
- return tv.uiT;
-}
diff --git a/new/darwin/text.m b/new/darwin/text.m
deleted file mode 100644
index f0d3dab..0000000
--- a/new/darwin/text.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// 10 april 2015
-#import "uipriv_darwin.h"
-
-char *uiDarwinNSStringToText(NSString *s)
-{
- char *out;
-
- out = strdup([s UTF8String]);
- if (out == NULL) {
- fprintf(stderr, "memory exhausted in uiDarwinNSStringToText()\n");
- abort();
- }
- return out;
-}
-
-void uiFreeText(char *s)
-{
- free(s);
-}
diff --git a/new/darwin/uipriv_darwin.h b/new/darwin/uipriv_darwin.h
deleted file mode 100644
index 36de1f1..0000000
--- a/new/darwin/uipriv_darwin.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// 6 january 2015
-#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_7
-#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_7
-#import <Cocoa/Cocoa.h>
-#import "../uipriv.h"
-#import "../ui_darwin.h"
-
-#define toNSString(str) [NSString stringWithUTF8String:(str)]
-#define fromNSString(str) [(str) UTF8String]
-
-#define uiLogObjCClassAllocations \
-+ (id)alloc \
-{ \
- id thing; \
- thing = [super alloc]; \
- if (options.debugLogAllocations) \
- fprintf(stderr, "%p alloc %s\n", thing, [[self className] UTF8String]); \
- return thing; \
-} \
-- (void)dealloc \
-{ \
- [super dealloc]; \
- if (options.debugLogAllocations) \
- fprintf(stderr, "%p free\n", self); \
-}
-
-// init_darwin.m
-extern NSView *destroyedControlsView;
-
-// util_darwin.m
-extern void setStandardControlFont(NSControl *);
-extern void disableAutocorrect(NSTextView *);
-
-// These are based on measurements from Interface Builder.
-// These seem to be based on Auto Layout constants, but I don't see an API that exposes these...
-#define macXMargin 20
-#define macYMargin 20
-
-// entry_darwin.m
-extern void finishNewTextField(NSTextField *, BOOL);
diff --git a/new/darwin/util.m b/new/darwin/util.m
deleted file mode 100644
index 906a0ea..0000000
--- a/new/darwin/util.m
+++ /dev/null
@@ -1,20 +0,0 @@
-// 7 april 2015
-#import "uipriv_darwin.h"
-
-// also fine for NSCells and NSTexts (NSTextViews)
-void setStandardControlFont(NSControl *control)
-{
- [control setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
-}
-
-void disableAutocorrect(NSTextView *tv)
-{
- [tv setEnabledTextCheckingTypes:0];
- [tv setAutomaticDashSubstitutionEnabled:NO];
- // don't worry about automatic data detection; it won't change stringValue (thanks pretty_function in irc.freenode.net/#macdev)
- [tv setAutomaticSpellingCorrectionEnabled:NO];
- [tv setAutomaticTextReplacementEnabled:NO];
- [tv setAutomaticQuoteSubstitutionEnabled:NO];
- [tv setAutomaticLinkDetectionEnabled:NO];
- [tv setSmartInsertDeleteEnabled:NO];
-}
diff --git a/new/darwin/window.m b/new/darwin/window.m
deleted file mode 100644
index c243374..0000000
--- a/new/darwin/window.m
+++ /dev/null
@@ -1,162 +0,0 @@
-// 6 april 2015
-#import "uipriv_darwin.h"
-
-// TODO
-// - free chilld containers properly
-
-@interface uiWindowDelegate : NSObject <NSWindowDelegate>
-@property (assign) NSWindow *w;
-@property uiParent *content;
-@property int (*onClosing)(uiWindow *, void *);
-@property void *onClosingData;
-@property struct window *uiw;
-@end
-
-@implementation uiWindowDelegate
-
-uiLogObjCClassAllocations
-
-- (BOOL)windowShouldClose:(id)win
-{
- // return exact constants to be safe
- if ((*(self.onClosing))(uiWindow(self.uiw), self.onClosingData))
- return YES;
- return NO;
-}
-
-// after this method returns we assume the window will be released (see below), so we can go too
-- (void)windowWillClose:(NSNotification *)note
-{
- [self.w setDelegate:nil]; // see http://stackoverflow.com/a/29523141/3408572
-
- // when we reach this point, we need to ensure that all the window's children are destroyed (for OS parity)
- // because we need to set the content view's superview to the destroyed controls view to trigger deletion, we need to do this manually
- // first, replace the current content view...
- [self.w setContentView:[[NSView alloc] initWithFrame:NSZeroRect]];
- // ...then, trigger the deletion
- [destroyedControlsView addSubview:((NSView *) uiParentHandle(self.content))];
-
- uiFree(self.uiw);
- [self release];
-}
-
-@end
-
-struct window {
- uiWindow w;
- uiWindowDelegate *d;
- int margined;
-};
-
-static int defaultOnClosing(uiWindow *w, void *data)
-{
- return 1;
-}
-
-#define D (((struct window *) w)->d)
-
-static void windowDestroy(uiWindow *w)
-{
- [D.w close];
-}
-
-static uintptr_t windowHandle(uiWindow *w)
-{
- return (uintptr_t) (D.w);
-}
-
-static char *windowTitle(uiWindow *w)
-{
- return uiDarwinNSStringToText([D.w title]);
-}
-
-static void windowSetTitle(uiWindow *w, const char *title)
-{
- [D.w setTitle:toNSString(title)];
-}
-
-static void windowShow(uiWindow *w)
-{
- [D.w makeKeyAndOrderFront:D.w];
-}
-
-static void windowHide(uiWindow *w)
-{
- [D.w orderOut:D.w];
-}
-
-static void windowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
-{
- D.onClosing = f;
- D.onClosingData = data;
-}
-
-static void windowSetChild(uiWindow *w, uiControl *c)
-{
- uiParentSetChild(D.content, c);
-}
-
-static int windowMargined(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- return w->margined;
-}
-
-static void windowSetMargined(uiWindow *ww, int margined)
-{
- struct window *w = (struct window *) ww;
-
- w->margined = margined;
- if (w->margined)
- uiParentSetMargins(D.content, macXMargin, macYMargin, macXMargin, macYMargin);
- else
- uiParentSetMargins(D.content, 0, 0, 0, 0);
- uiParentUpdate(D.content);
-}
-
-uiWindow *uiNewWindow(const char *title, int width, int height)
-{
- uiWindowDelegate *d;
-
- d = [uiWindowDelegate new];
-
- d.w = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, (CGFloat) width, (CGFloat) height)
- styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)
- backing:NSBackingStoreBuffered
- defer:YES];
- [d.w setTitle:toNSString(title)];
-
- // we do not want substitutions
- // text fields, labels, etc. take their smart quotes and other autocorrect settings from their parent window, which provides a shared "field editor"
- // so we have to turn them off here
- // thanks akempgen in irc.freenode.net/#macdev
- // for some reason, this selector returns NSText but is documented to return NSTextView...
- // NOTE: if you disagree with me about disabling substitutions, start a github issue with why and I'll be happy to consider it
- disableAutocorrect((NSTextView *) [d.w fieldEditor:YES forObject:nil]);
-
- // this is what will destroy the window on close
- [d.w setReleasedWhenClosed:YES];
-
- d.content = uiNewParent(0);
- [d.w setContentView:((NSView *) uiParentHandle(d.content))];
-
- d.onClosing = defaultOnClosing;
- [d.w setDelegate:d];
-
- d.uiw = uiNew(struct window);
- d.uiw->d = d;
-
- uiWindow(d.uiw)->Destroy = windowDestroy;
- uiWindow(d.uiw)->Handle = windowHandle;
- uiWindow(d.uiw)->Title = windowTitle;
- uiWindow(d.uiw)->SetTitle = windowSetTitle;
- uiWindow(d.uiw)->Show = windowShow;
- uiWindow(d.uiw)->Hide = windowHide;
- uiWindow(d.uiw)->OnClosing = windowOnClosing;
- uiWindow(d.uiw)->SetChild = windowSetChild;
- uiWindow(d.uiw)->Margined = windowMargined;
- uiWindow(d.uiw)->SetMargined = windowSetMargined;
-
- return uiWindow(d.uiw);
-}
diff --git a/new/leaks.awk b/new/leaks.awk
deleted file mode 100644
index 1d19ea8..0000000
--- a/new/leaks.awk
+++ /dev/null
@@ -1,56 +0,0 @@
-# 7 april 2015
-
-$2 == "alloc" {
- if ($1 in A) {
- problem($1 " already allocated (" A[$1] "); allocated at " NR)
- next
- }
- A[$1] = type()
- next
-}
-
-$2 == "realloc" {
- if (!($1 in A)) {
- problem($1 " not yet allocated; reallocated at " NR)
- next
- }
- if ($3 in A) {
- problem($3 " already allocated (" A[$3] "); reallocated at " NR)
- next
- }
- t = A[$1]
- delete A[$1]
- A[$3] = t
- next
-}
-
-$2 == "free" {
- if (!($1 in A)) {
- problem($1 " not yet allocated; freed at " NR)
- next
- }
- delete A[$1]
- next
-}
-
-{ problem("unrecognized line " $0 " at " NR) }
-
-END {
- for (i in A)
- problem("leaked " A[i] " at " i)
- close("/dev/stderr")
- if (hasProblems)
- exit 1
-}
-
-function problem(s) {
- print s > "/dev/stderr"
- hasProblems = 1
-}
-
-function type( s, i) {
- s = $3
- for (i = 4; i <= NF; i++)
- s = s " " $i
- return s
-}
diff --git a/new/parentplan b/new/parentplan
deleted file mode 100644
index 83c581e..0000000
--- a/new/parentplan
+++ /dev/null
@@ -1,57 +0,0 @@
-current situation
-
-let's say the control hierarchy is
-w window
- p parent
-c stack
- d stack
- e button
- f button
- g button
-h button
-i entry
-
-w = NewWindow()
- p = NewParent(w.Handle)
-w.SetChild(c)
- p.SetChild(c)
- c.SetParent(p)
- d.SetParent(p)
- e.SetParent(p)
- f.SetParent(p)
- g.SetParent(p)
- p.Update()
- c.Resize()
-c.Add(h)
- h.SetParent(p)
- p.Update()
- c.Resize()
-d.Remove(1)
- f.SetParent(NULL)
- p.Update()
- c.Resize()
-g.Hide()
- p.Update()
- c.Resize()
-w.SetChild(i)
- p.SetChild(i)
- c.SetParent(NULL)
- d.SetParent(NULL)
- ...
- i.SetParent(p)
- ...
- p.Update()
- i.Resize()
-w.SetChild(NULL)
- p.SetChild(NULL)
- i.SetParent(NULL)
- p.Update()
-w.SetChild(i)
- (again)
-w.Destroy()
- p.Destroy()
- i.Destroy()
-
-TODO
-- rename these methods
-- p.DeferUpdate()/p.EndDeferUpdate()
diff --git a/new/stack.c b/new/stack.c
deleted file mode 100644
index 8a3906f..0000000
--- a/new/stack.c
+++ /dev/null
@@ -1,398 +0,0 @@
-// 7 april 2015
-#include "uipriv.h"
-
-// TODO
-// - rename to uiBox
-
-typedef struct stack stack;
-typedef struct stackControl stackControl;
-
-struct stack {
- uiStack s;
- stackControl *controls;
- uintmax_t len;
- uintmax_t cap;
- int vertical;
- uiParent *parent;
- int padded;
- int userHid;
- int containerHid;
- int userDisabled;
- int containerDisabled;
-};
-
-struct stackControl {
- uiControl *c;
- int stretchy;
- intmax_t width; // both used by resize(); preallocated to save time and reduce risk of failure
- intmax_t height;
-};
-
-static void stackDestroy(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- for (i = 0; i < s->len; i++)
- uiControlDestroy(s->controls[i].c);
- uiFree(s->controls);
- uiFree(s);
-}
-
-static uintptr_t stackHandle(uiControl *c)
-{
- return 0;
-}
-
-static void stackSetParent(uiControl *c, uiParent *parent)
-{
- stack *s = (stack *) c;
- uintmax_t i;
- uiParent *oldparent;
-
- oldparent = s->parent;
- s->parent = parent;
- for (i = 0; i < s->len; i++)
- uiControlSetParent(s->controls[i].c, s->parent);
- if (oldparent != NULL)
- uiParentUpdate(oldparent);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void stackPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- stack *s = (stack *) c;
- int xpadding, ypadding;
- uintmax_t nStretchy;
- // these two contain the largest preferred width and height of all stretchy controls in the stack
- // all stretchy controls will use this value to determine the final preferred size
- intmax_t maxStretchyWidth, maxStretchyHeight;
- uintmax_t i;
- intmax_t preferredWidth, preferredHeight;
-
- *width = 0;
- *height = 0;
- if (s->len == 0)
- return;
-
- // 0) get this Stack's padding
- xpadding = 0;
- ypadding = 0;
- if (s->padded) {
- xpadding = d->xPadding;
- ypadding = d->yPadding;
- }
-
- // 1) initialize the desired rect with the needed padding
- if (s->vertical)
- *height = (s->len - 1) * ypadding;
- else
- *width = (s->len - 1) * xpadding;
-
- // 2) add in the size of non-stretchy controls and get (but not add in) the largest widths and heights of stretchy controls
- // we still add in like direction of stretchy controls
- nStretchy = 0;
- maxStretchyWidth = 0;
- maxStretchyHeight = 0;
- for (i = 0; i < s->len; i++) {
- if (!uiControlVisible(s->controls[i].c))
- continue;
- uiControlPreferredSize(s->controls[i].c, d, &preferredWidth, &preferredHeight);
- if (s->controls[i].stretchy) {
- nStretchy++;
- if (maxStretchyWidth < preferredWidth)
- maxStretchyWidth = preferredWidth;
- if (maxStretchyHeight < preferredHeight)
- maxStretchyHeight = preferredHeight;
- }
- if (s->vertical) {
- if (*width < preferredWidth)
- *width = preferredWidth;
- if (!s->controls[i].stretchy)
- *height += preferredHeight;
- } else {
- if (!s->controls[i].stretchy)
- *width += preferredWidth;
- if (*height < preferredHeight)
- *height = preferredHeight;
- }
- }
-
- // 3) and now we can add in stretchy controls
- if (s->vertical)
- *height += nStretchy * maxStretchyHeight;
- else
- *width += nStretchy * maxStretchyWidth;
-}
-
-static void stackResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
-{
- stack *s = (stack *) c;
- int xpadding, ypadding;
- uintmax_t nStretchy;
- intmax_t stretchywid, stretchyht;
- uintmax_t i;
- intmax_t preferredWidth, preferredHeight;
-
- if (s->len == 0)
- return;
-
- // -1) get this Stack's padding
- xpadding = 0;
- ypadding = 0;
- if (s->padded) {
- xpadding = d->xPadding;
- ypadding = d->yPadding;
- }
-
- // 0) inset the available rect by the needed padding
- if (s->vertical)
- height -= (s->len - 1) * ypadding;
- else
- width -= (s->len - 1) * xpadding;
-
- // 1) get width and height of non-stretchy controls
- // this will tell us how much space will be left for stretchy controls
- stretchywid = width;
- stretchyht = height;
- nStretchy = 0;
- for (i = 0; i < s->len; i++) {
- if (!uiControlVisible(s->controls[i].c))
- continue;
- if (s->controls[i].stretchy) {
- nStretchy++;
- continue;
- }
- uiControlPreferredSize(s->controls[i].c, d, &preferredWidth, &preferredHeight);
- if (s->vertical) { // all controls have same width
- s->controls[i].width = width;
- s->controls[i].height = preferredHeight;
- stretchyht -= preferredHeight;
- } else { // all controls have same height
- s->controls[i].width = preferredWidth;
- s->controls[i].height = height;
- stretchywid -= preferredWidth;
- }
- }
-
- // 2) now get the size of stretchy controls
- if (nStretchy != 0)
- if (s->vertical)
- stretchyht /= nStretchy;
- else
- stretchywid /= nStretchy;
- for (i = 0; i < s->len; i++) {
- if (!uiControlVisible(s->controls[i].c))
- continue;
- if (s->controls[i].stretchy) {
- s->controls[i].width = stretchywid;
- s->controls[i].height = stretchyht;
- }
- }
-
- // 3) now we can position controls
- for (i = 0; i < s->len; i++) {
- if (!uiControlVisible(s->controls[i].c))
- continue;
- uiControlResize(s->controls[i].c, x, y, s->controls[i].width, s->controls[i].height, d);
- if (s->vertical)
- y += s->controls[i].height + ypadding;
- else
- x += s->controls[i].width + xpadding;
- }
-}
-
-static int stackVisible(uiControl *c)
-{
- stack *s = (stack *) c;
-
- return !(s->userHid);
-}
-
-static void stackShow(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->userHid = 0;
- if (!s->containerHid) {
- for (i = 0; i < s->len; i++)
- uiControlContainerShow(s->controls[i].c);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void stackHide(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->userHid = 1;
- for (i = 0; i < s->len; i++)
- uiControlContainerHide(s->controls[i].c);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void stackContainerShow(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->containerHid = 0;
- if (!s->userHid) {
- for (i = 0; i < s->len; i++)
- uiControlContainerShow(s->controls[i].c);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void stackContainerHide(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->containerHid = 1;
- for (i = 0; i < s->len; i++)
- uiControlContainerHide(s->controls[i].c);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void stackEnable(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->userDisabled = 0;
- if (!s->containerDisabled)
- for (i = 0; i < s->len; i++)
- uiControlContainerEnable(s->controls[i].c);
-}
-
-static void stackDisable(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->userDisabled = 1;
- for (i = 0; i < s->len; i++)
- uiControlContainerDisable(s->controls[i].c);
-}
-
-static void stackContainerEnable(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->containerDisabled = 0;
- if (!s->userDisabled)
- for (i = 0; i < s->len; i++)
- uiControlContainerEnable(s->controls[i].c);
-}
-
-static void stackContainerDisable(uiControl *c)
-{
- stack *s = (stack *) c;
- uintmax_t i;
-
- s->containerDisabled = 1;
- for (i = 0; i < s->len; i++)
- uiControlContainerDisable(s->controls[i].c);
-}
-
-#define stackCapGrow 32
-
-static void stackAppend(uiStack *ss, uiControl *c, int stretchy)
-{
- stack *s = (stack *) ss;
-
- if (s->len >= s->cap) {
- s->cap += stackCapGrow;
- s->controls = (stackControl *) uiRealloc(s->controls, s->cap * sizeof (stackControl), "stackControl[]");
- }
- s->controls[s->len].c = c;
- s->controls[s->len].stretchy = stretchy;
- s->len++; // must be here for parent updates to work
- if (s->parent != NULL) {
- uiControlSetParent(s->controls[s->len - 1].c, s->parent);
- uiParentUpdate(s->parent);
- }
-}
-
-static void stackDelete(uiStack *ss, uintmax_t index)
-{
- stack *s = (stack *) ss;
- uiControl *removed;
- uintmax_t i;
-
- removed = s->controls[index].c;
- // TODO switch to memmove?
- for (i = index; i < s->len - 1; i++)
- s->controls[i] = s->controls[i + 1];
- // TODO memset the last one to NULL
- s->len--;
- if (s->parent != NULL) {
- uiControlSetParent(removed, NULL);
- uiParentUpdate(s->parent);
- }
-}
-
-static int stackPadded(uiStack *ss)
-{
- stack *s = (stack *) ss;
-
- return s->padded;
-}
-
-static void stackSetPadded(uiStack *ss, int padded)
-{
- stack *s = (stack *) ss;
-
- s->padded = padded;
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-uiStack *uiNewHorizontalStack(void)
-{
- stack *s;
-
- s = uiNew(stack);
-
- uiControl(s)->Destroy = stackDestroy;
- uiControl(s)->Handle = stackHandle;
- uiControl(s)->SetParent = stackSetParent;
- uiControl(s)->PreferredSize = stackPreferredSize;
- uiControl(s)->Resize = stackResize;
- uiControl(s)->Visible = stackVisible;
- uiControl(s)->Show = stackShow;
- uiControl(s)->Hide = stackHide;
- uiControl(s)->ContainerShow = stackContainerShow;
- uiControl(s)->ContainerHide = stackContainerHide;
- uiControl(s)->Enable = stackEnable;
- uiControl(s)->Disable = stackDisable;
- uiControl(s)->ContainerEnable = stackContainerEnable;
- uiControl(s)->ContainerDisable = stackContainerDisable;
-
- uiStack(s)->Append = stackAppend;
- uiStack(s)->Delete = stackDelete;
- uiStack(s)->Padded = stackPadded;
- uiStack(s)->SetPadded = stackSetPadded;
-
- return uiStack(s);
-}
-
-uiStack *uiNewVerticalStack(void)
-{
- uiStack *ss;
- stack *s;
-
- ss = uiNewHorizontalStack();
- s = (stack *) ss;
- s->vertical = 1;
- return ss;
-}
diff --git a/new/test.c b/new/test.c
deleted file mode 100644
index b8ee418..0000000
--- a/new/test.c
+++ /dev/null
@@ -1,337 +0,0 @@
-// 6 april 2015
-#include "ui.h"
-#include <stdio.h>
-#include <string.h>
-
-// TODO convert to using the new conversion macros
-
-int onClosing(uiWindow *w, void *data)
-{
- printf("in closing!\n");
- uiQuit();
- return 1;
-}
-
-uiEntry *e;
-
-static void getWindowText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiWindowTitle(uiWindow(data));
- uiEntrySetText(e, text);
- uiFreeText(text);
-}
-
-static void setWindowText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiEntryText(e);
- uiWindowSetTitle(uiWindow(data), text);
- uiFreeText(text);
-}
-
-static void getButtonText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiButtonText(uiButton(data));
- uiEntrySetText(e, text);
- uiFreeText(text);
-}
-
-static void setButtonText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiEntryText(e);
- uiButtonSetText(uiButton(data), text);
- uiFreeText(text);
-}
-
-static void getCheckboxText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiCheckboxText(uiCheckbox(data));
- uiEntrySetText(e, text);
- uiFreeText(text);
-}
-
-static void setCheckboxText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiEntryText(e);
- uiCheckboxSetText(uiCheckbox(data), text);
- uiFreeText(text);
-}
-
-uiWindow *w;
-#define nStacks 11
-uiStack *stacks[nStacks];
-uiCheckbox *spaced;
-
-static void setSpaced(int spaced)
-{
- int i;
-
- uiWindowSetMargined(w, spaced);
- for (i = 0; i < nStacks; i++)
- uiStackSetPadded(stacks[i], spaced);
-}
-
-static void toggleSpaced(uiCheckbox *c, void *data)
-{
- int s;
-
- s = uiCheckboxChecked(spaced);
- printf("toggled %d\n", s);
- setSpaced(s);
-}
-
-// these will also be used to test if setting checks will trigger events
-static void forceSpacedOn(uiButton *b, void *data)
-{
- uiCheckboxSetChecked(spaced, 1);
-}
-
-static void forceSpacedOff(uiButton *b, void *data)
-{
- uiCheckboxSetChecked(spaced, 0);
-}
-
-static void showSpaced(uiButton *b, void *data)
-{
- char msg[] = { 'm', ' ', '0', ' ', 'p', ' ', '0', '\0' };
-
- if (uiWindowMargined(w))
- msg[2] = '1';
- if (uiStackPadded(stacks[0]))
- msg[6] = '1';
- uiEntrySetText(e, msg);
-}
-
-static void showControl(uiButton *b, void *data)
-{
- uiControlShow(uiControl(data));
-}
-
-static void hideControl(uiButton *b, void *data)
-{
- uiControlHide(uiControl(data));
-}
-
-static void enableControl(uiButton *b, void *data)
-{
- uiControlEnable(uiControl(data));
-}
-
-static void disableControl(uiButton *b, void *data)
-{
- uiControlDisable(uiControl(data));
-}
-
-static void getLabelText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiLabelText(uiLabel(data));
- uiEntrySetText(e, text);
- uiFreeText(text);
-}
-
-static void setLabelText(uiButton *b, void *data)
-{
- char *text;
-
- text = uiEntryText(e);
- uiLabelSetText(uiLabel(data), text);
- uiFreeText(text);
-}
-
-uiStack *firstStack;
-uiStack *secondStack;
-uiLabel *movingLabel;
-
-static void moveToFirst(uiButton *b, void *data)
-{
- uiStackDelete(secondStack, 1);
- uiStackAppend(firstStack, uiControl(movingLabel), 1);
-}
-
-static void moveToSecond(uiButton *b, void *data)
-{
- uiStackDelete(firstStack, 1);
- uiStackAppend(secondStack, uiControl(movingLabel), 1);
-}
-
-int main(int argc, char *argv[])
-{
- uiInitOptions o;
- int i;
- const char *err;
- uiButton *getButton, *setButton;
- uiLabel *label;
- uiTab *tab;
- int page2stack;
-
- memset(&o, 0, sizeof (uiInitOptions));
- for (i = 1; i < argc; i++)
- if (strcmp(argv[i], "leaks") == 0)
- o.debugLogAllocations = 1;
- else {
- fprintf(stderr, "%s: unrecognized option %s\n", argv[0], argv[i]);
- return 1;
- }
-
- err = uiInit(&o);
- if (err != NULL) {
- fprintf(stderr, "error initializing ui: %s\n", err);
- uiFreeInitError(err);
- return 1;
- }
-
- w = uiNewWindow("Hello", 320, 240);
- uiWindowOnClosing(w, onClosing, NULL);
-
- stacks[0] = uiNewVerticalStack();
-
- e = uiNewEntry();
- uiStackAppend(stacks[0], uiControl(e), 0);
-
- i = 1;
-
- stacks[i] = uiNewHorizontalStack();
- getButton = uiNewButton("Get Window Text");
- uiButtonOnClicked(getButton, getWindowText, w);
- setButton = uiNewButton("Set Window Text");
- uiButtonOnClicked(setButton, setWindowText, w);
- uiStackAppend(stacks[i], uiControl(getButton), 1);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- uiStackAppend(stacks[0], uiControl(stacks[i]), 0);
- i++;
-
- stacks[i] = uiNewHorizontalStack();
- getButton = uiNewButton("Get Button Text");
- uiButtonOnClicked(getButton, getButtonText, getButton);
- setButton = uiNewButton("Set Button Text");
- uiButtonOnClicked(setButton, setButtonText, getButton);
- uiStackAppend(stacks[i], uiControl(getButton), 1);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- uiStackAppend(stacks[0], uiControl(stacks[i]), 0);
- i++;
-
- // this will also be used to make sure tab stops work properly when inserted out of creation order, especially on Windows
- spaced = uiNewCheckbox("Spaced");
- uiCheckboxOnToggled(spaced, toggleSpaced, NULL);
-
- stacks[i] = uiNewHorizontalStack();
- getButton = uiNewButton("Get Checkbox Text");
- uiButtonOnClicked(getButton, getCheckboxText, spaced);
- setButton = uiNewButton("Set Checkbox Text");
- uiButtonOnClicked(setButton, setCheckboxText, spaced);
- uiStackAppend(stacks[i], uiControl(getButton), 1);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- uiStackAppend(stacks[0], uiControl(stacks[i]), 0);
- i++;
-
- label = uiNewLabel("Label");
-
- stacks[i] = uiNewHorizontalStack();
- getButton = uiNewButton("Get Label Text");
- uiButtonOnClicked(getButton, getLabelText, label);
- setButton = uiNewButton("Set Label Text");
- uiButtonOnClicked(setButton, setLabelText, label);
- uiStackAppend(stacks[i], uiControl(getButton), 1);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- uiStackAppend(stacks[0], uiControl(stacks[i]), 0);
- i++;
-
- stacks[i] = uiNewHorizontalStack();
- uiStackAppend(stacks[i], uiControl(spaced), 1);
- getButton = uiNewButton("On");
- uiButtonOnClicked(getButton, forceSpacedOn, NULL);
- setButton = uiNewButton("Off");
- uiButtonOnClicked(setButton, forceSpacedOff, NULL);
- uiStackAppend(stacks[i], uiControl(getButton), 0);
- uiStackAppend(stacks[i], uiControl(setButton), 0);
- setButton = uiNewButton("Show");
- uiButtonOnClicked(setButton, showSpaced, NULL);
- uiStackAppend(stacks[i], uiControl(setButton), 0);
- uiStackAppend(stacks[0], uiControl(stacks[i]), 0);
- i++;
-
- stacks[i] = uiNewHorizontalStack();
- getButton = uiNewButton("Button");
- uiStackAppend(stacks[i], uiControl(getButton), 1);
- setButton = uiNewButton("Show");
- uiButtonOnClicked(setButton, showControl, getButton);
- uiStackAppend(stacks[i], uiControl(setButton), 0);
- setButton = uiNewButton("Hide");
- uiButtonOnClicked(setButton, hideControl, getButton);
- uiStackAppend(stacks[i], uiControl(setButton), 0);
- setButton = uiNewButton("Enable");
- uiButtonOnClicked(setButton, enableControl, getButton);
- uiStackAppend(stacks[i], uiControl(setButton), 0);
- setButton = uiNewButton("Disable");
- uiButtonOnClicked(setButton, disableControl, getButton);
- uiStackAppend(stacks[i], uiControl(setButton), 0);
- uiStackAppend(stacks[0], uiControl(stacks[i]), 0);
- i++;
-
- stacks[i] = uiNewHorizontalStack();
- setButton = uiNewButton("Show Stack");
- uiButtonOnClicked(setButton, showControl, stacks[i - 1]);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- setButton = uiNewButton("Hide Stack");
- uiButtonOnClicked(setButton, hideControl, stacks[i - 1]);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- setButton = uiNewButton("Enable Stack");
- uiButtonOnClicked(setButton, enableControl, stacks[i - 1]);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- setButton = uiNewButton("Disable Stack");
- uiButtonOnClicked(setButton, disableControl, stacks[i - 1]);
- uiStackAppend(stacks[i], uiControl(setButton), 1);
- uiStackAppend(stacks[0], uiControl(stacks[i]), 0);
- i++;
-
- uiStackAppend(stacks[0], uiControl(label), 0);
-
- tab = uiNewTab();
- uiWindowSetChild(w, uiControl(tab));
- uiTabAddPage(tab, "Page 1", uiControl(stacks[0]));
-
- page2stack = i;
- stacks[i] = uiNewVerticalStack();
- uiTabAddPage(tab, "Page 2", uiControl(stacks[i]));
- i++;
-
- stacks[i] = uiNewHorizontalStack();
- firstStack = stacks[i];
- getButton = uiNewButton("Move Here");
- uiButtonOnClicked(getButton, moveToFirst, NULL);
- uiStackAppend(stacks[i], uiControl(getButton), 0);
- movingLabel = uiNewLabel("This label moves!");
- uiStackAppend(stacks[i], uiControl(movingLabel), 1);
- uiStackAppend(stacks[page2stack], uiControl(stacks[i]), 0);
- i++;
-
- stacks[i] = uiNewHorizontalStack();
- secondStack = stacks[i];
- getButton = uiNewButton("Move Here");
- uiButtonOnClicked(getButton, moveToSecond, NULL);
- uiStackAppend(stacks[i], uiControl(getButton), 0);
- uiStackAppend(stacks[page2stack], uiControl(stacks[i]), 0);
- i++;
-
- if (i != nStacks) {
- fprintf(stderr, "forgot to update nStacks (expected %d)\n", i);
- return 1;
- }
- uiWindowShow(w);
- uiMain();
- printf("after uiMain()\n");
- return 0;
-}
diff --git a/new/ui.idl b/new/ui.idl
deleted file mode 100644
index e820002..0000000
--- a/new/ui.idl
+++ /dev/null
@@ -1,161 +0,0 @@
-// 6 april 2015
-
-// This is not an IDL file for the conventional RPC or Microsoft IDLs.
-// Instead, this is for a custom IDL of my own creation.
-// You can find it at github.com/andlabs/pgidl
-
-package ui {
-
-// TODO autogenerate this somehow
-// TODO alternatively, move AFTER typedefs
-raw "#ifndef __UI_UI_H__";
-raw "#define __UI_UI_H__";
-
-raw "#include <stdint.h>";
-
-// TODO note that should be initialized to zero
-struct InitOptions {
- // TODO cbSize
-
- // If nonzero, allocations will be logged to stderr.
- // See leaks.awk.
- field debugLogAllocations int;
-};
-
-// TODO const char
-raw "const char *uiInit(uiInitOptions *);";
-raw "void uiFreeInitError(const char *);";
-
-func Main(void);
-func Quit(void);
-
-func FreeText(text *char);
-
-raw "typedef struct uiSizingSys uiSizingSys;";
-
-struct Sizing {
- field xPadding intmax_t;
- field yPadding intmax_t;
- field sys *uiSizingSys;
-};
-
-interface Control {
- field Internal *void; // for use by ui only
- func Destroy(void);
- func Handle(void) uintptr_t;
- func SetParent(p *Parent);
- func PreferredSize(d *Sizing, width *intmax_t, height *intmax_t);
- func Resize(x intmax_t, y intmax_t, width intmax_t, height intmax_t, d *Sizing);
- func Visible(void) int;
- func Show(void);
- func Hide(void);
- func ContainerShow(void);
- func ContainerHide(void);
- func Enable(void);
- func Disable(void);
- func ContainerEnable(void);
- func ContainerDisable(void);
-};
-
-// Parent represents an OS control that hosts other OS controls.
-// It is used internally by package ui and by implementations.
-// Window, Tab, and Group all use uiParents to store their controls.
-interface Parent {
- // Internal points to internal data.
- // Do not access or alter this field.
- field Internal *void;
-
- // TODO destroy
- // TODO object destruction debug handler
-
- // Handle returns the window handle of the uiParent.
- // On Windows, this is a HWND.
- // On GTK+, this is a GtkContainer.
- // On Mac OS X, this is a NSView.
- func Handle(void) uintptr_t;
-
- // TODO rename and clean this up
- // SetChild sets the uiControl that this uiParent relegates.
- // It calls uiControl.SetParent() which should, in turn, call uiParent.Update().
- // The uiParent should already not have a child and the uiControl should already not have a parent.
- //
- // child can be NULL, in which case the uiParent has no children.
- // This version should also call uiControl.SetParent(), passing NULL.
- //
- // If this uiParent has a child already, then the current child is replaced with the new one.
- func SetChild(c *Control);
-
- // SetMargins sets the margins of the uiParent to the given margins.
- // It does not call uiParent.Update(); its caller must.
- // The units of the margins are backend-defined.
- // The initial margins are all 0.
- func SetMargins(left intmax_t, top intmax_t, right intmax_t, bottom intmax_t);
-
- // TODO Resize?
-
- // Update tells the uiParent to re-layout its children immediately.
- // It is called when a widget is shown or hidden or when a control is added or removed from a container such as uiStack.
- func Update(void);
-};
-func NewParent(osParent uintptr_t) *Parent;
-
-interface Window {
- field Internal *void;
- func Destroy(void);
- func Handle(void) uintptr_t;
- func Title(void) *char;
- func SetTitle(title *const char);
- func Show(void);
- func Hide(void);
- func OnClosing(f *func(w *Window, data *void) int, data *void);
- func SetChild(c *Control);
- func Margined(void) int;
- func SetMargined(margined int);
-};
-func NewWindow(title *const char, width int, height int) *Window;
-
-interface Button from Control {
- func Text(void) *char;
- func SetText(text *const char);
- func OnClicked(f *func(b *Button, data *void), data *void);
-};
-func NewButton(text *const char) *Button;
-
-interface Stack from Control {
- func Append(c *Control, stretchy int);
- func Delete(index uintmax_t);
- func Padded(void) int;
- func SetPadded(padded int);
-};
-func NewHorizontalStack(void) *Stack;
-func NewVerticalStack(void) *Stack;
-
-interface Entry from Control {
- func Text(void) *char;
- func SetText(text *const char);
-};
-func NewEntry(void) *Entry;
-
-interface Checkbox from Control {
- func Text(void) *char;
- func SetText(text *const char);
- func OnToggled(f *func(c *Checkbox, data *void), data *void);
- func Checked(void) int;
- func SetChecked(checked int);
-};
-func NewCheckbox(text *const char) *Checkbox;
-
-interface Label from Control {
- func Text(void) *char;
- func SetText(text *const char);
-};
-func NewLabel(text *const char) *Label;
-
-interface Tab from Control {
- func AddPage(name *const char, c *Control);
-};
-func NewTab(void) *Tab;
-
-raw "#endif";
-
-};
diff --git a/new/ui_darwin.h b/new/ui_darwin.h
deleted file mode 100644
index cab61d1..0000000
--- a/new/ui_darwin.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// 7 april 2015
-
-/*
-This file assumes that you have imported <Cocoa/Cocoa.h> and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls on Mac OS X.
-*/
-
-#ifndef __UI_UI_DARWIN_H__
-#define __UI_UI_DARWIN_H__
-
-// uiDarwinNewControl() initializes the given uiControl with the given Cocoa control inside.
-// The second parameter should come from [RealControlType class].
-// The two scrollView parameters allow placing scrollbars on the new control.
-// Your control must call uiDarwinControlFreeWhenAppropriate() on the returned uiControl in its -[viewDidMoveToSuperview] method.
-// If it returns a value other than NO, then the uiControl has been freed and you should set references to it to NULL.
-extern void uiDarwinNewControl(uiControl *c, Class class, BOOL inScrollView, BOOL scrollViewHasBorder);
-extern BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview);
-
-// You can use this function from within your control implementations to return text strings that can be freed with uiTextFree().
-extern char *uiDarwinNSStringToText(NSString *);
-
-struct uiSizingSys {
- // this structure currently left blank
-};
-
-#endif
diff --git a/new/ui_unix.h b/new/ui_unix.h
deleted file mode 100644
index 3911416..0000000
--- a/new/ui_unix.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// 7 april 2015
-
-/*
-This file assumes that you have included <gtk/gtk.h> and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls on Unix systems that use GTK+ to provide their UI (currently all except Mac OS X).
-*/
-
-#ifndef __UI_UI_UNIX_H__
-#define __UI_UI_UNIX_H__
-
-// uiUnixNewControl() creates a new uiControl with the given GTK+ control inside, storing it in the uiControl at c.
-// The second parameter is the type of the control, as passed to the first argument of g_object_new().
-// The two scrolledWindow parameters allow placing scrollbars on the new control.
-// The firstProperty parameter and beyond allow passing construct properties to the new control, as with g_object_new(); end this list with NULL.
-extern void uiUnixNewControl(uiControl *c, GType type, gboolean inScrolledWindow, gboolean scrolledWindowHasBorder, const char *firstProperty, ...);
-
-struct uiSizingSys {
- // this structure currently left blank
-};
-
-#endif
diff --git a/new/ui_windows.h b/new/ui_windows.h
deleted file mode 100644
index 806cac1..0000000
--- a/new/ui_windows.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// 7 april 2015
-
-/*
-This file assumes that you have included <windows.h> and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls in Windows.
-*/
-
-#ifndef __UI_UI_WINDOWS_H__
-#define __UI_UI_WINDOWS_H__
-
-// Correctness macros.
-#define uiControlHWND(c) ((HWND) uiControlHandle(c))
-#define uiParentHWND(p) ((HWND) uiParentHandle(p))
-
-// uiWindowsNewControl() initializes the given uiControl with the given Windows API control inside.
-// You will need to provide the preferredSize() method yourself.
-typedef struct uiWindowsNewControlParams uiWindowsNewControlParams;
-struct uiWindowsNewControlParams {
- // These match the CreateWindowExW() function.
- DWORD dwExStyle;
- LPCWSTR lpClassName;
- LPCWSTR lpWindowName;
- DWORD dwStyle; // WS_CHILD and WS_VISIBLE are automatically applied.
- HINSTANCE hInstance;
-
- // Set this to non-FALSE to use the standard control font used by other ui controls.
- BOOL useStandardControlFont;
-
- // These are called when the control sends a WM_COMMAND or WM_NOTIFY (respectively) to its parent.
- // ui redirects the message back and calls these functions.
- // Store the result in *lResult and return any non-FALSE value (such as TRUE) to return the given result; return FALSE to pass the notification up to your window procedure.
- // Note that these are only issued if they come from the uiControl itself; notifications from children of the uiControl (such as a header control) will be received normally.
- BOOL (*onWM_COMMAND)(uiControl *c, WORD code, LRESULT *lResult);
- BOOL (*onWM_NOTIFY)(uiControl *c, NMHDR *nm, LRESULT *lResult);
- // This is called in WM_DESTROY.
- void (*onWM_DESTROY)(uiControl *c);
-};
-void uiWindowsNewControl(uiControl *c, uiWindowsNewControlParams *p);
-
-// This contains the Windows-specific parts of the uiSizing structure.
-// baseX and baseY are the dialog base units.
-// internalLeading is the standard control font's internal leading; labels in uiForms use this for correct Y positioning.
-struct uiSizingSys {
- int baseX;
- int baseY;
- LONG internalLeading;
-};
-// Use these in your preferredSize() implementation with baseX and baseY.
-#define uiDlgUnitsToX(dlg, baseX) MulDiv((dlg), baseX, 4)
-#define uiDlgUnitsToY(dlg, baseY) MulDiv((dlg), baseY, 8)
-
-// and use this if you need the text of the window width
-extern intmax_t uiWindowsWindowTextWidth(HWND hwnd);
-
-// these functions get and set the window text for such a uiControl
-// the value returned should be freed with uiFreeText()
-extern char *uiWindowsControlText(uiControl *);
-extern void uiWindowsControlSetText(uiControl *, const char *);
-
-#endif
diff --git a/new/uipriv.h b/new/uipriv.h
deleted file mode 100644
index 7cc1795..0000000
--- a/new/uipriv.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// 6 april 2015
-#include <stdlib.h>
-#include "ui.h"
-
-extern uiInitOptions options;
-
-extern void *uiAlloc(size_t, const char *);
-#define uiNew(T) ((T *) uiAlloc(sizeof (T), #T ))
-extern void *uiRealloc(void *, size_t, const char *);
-extern void uiFree(void *);
diff --git a/new/unix/GNUmakeinc.mk b/new/unix/GNUmakeinc.mk
deleted file mode 100644
index 4f707b3..0000000
--- a/new/unix/GNUmakeinc.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-OSCFILES = \
- alloc.c \
- button.c \
- checkbox.c \
- entry.c \
- init.c \
- label.c \
- main.c \
- newcontrol.c \
- parent.c \
- tab.c \
- util.c \
- window.c
-
-xCFLAGS += `pkg-config --cflags gtk+-3.0`
-xLDFLAGS += `pkg-config --libs gtk+-3.0`
-
-OUT = new
diff --git a/new/unix/alloc.c b/new/unix/alloc.c
deleted file mode 100644
index 33482b2..0000000
--- a/new/unix/alloc.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// 7 april 2015
-#include <stdio.h>
-#include "uipriv_unix.h"
-
-void *uiAlloc(size_t size, const char *type)
-{
- void *out;
-
- out = g_malloc0(size);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p alloc %s\n", out, type);
- return out;
-}
-
-void *uiRealloc(void *p, size_t size, const char *type)
-{
- void *out;
-
- if (p == NULL)
- return uiAlloc(size, type);
- // TODO fill with 0s
- out = g_realloc(p, size);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p realloc %p\n", p, out);
- return out;
-}
-
-void uiFree(void *p)
-{
- g_free(p);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p free\n", p);
-}
diff --git a/new/unix/button.c b/new/unix/button.c
deleted file mode 100644
index 404d7a8..0000000
--- a/new/unix/button.c
+++ /dev/null
@@ -1,71 +0,0 @@
-// 7 april 2015
-#include "uipriv_unix.h"
-
-struct button {
- uiButton b;
- void (*onClicked)(uiButton *, void *);
- void *onClickedData;
-};
-
-static void clicked(GtkButton *button, gpointer data)
-{
- struct button *b = (struct button *) data;
-
- (*(b->onClicked))(uiButton(b), b->onClickedData);
-}
-
-static void defaultOnClicked(uiButton *b, void *data)
-{
- // do nothing
-}
-
-static void destroy(GtkWidget *widget, gpointer data)
-{
- struct button *b = (struct button *) data;
-
- uiFree(b);
-}
-
-#define BUTTON(b) GTK_BUTTON(widget(b))
-
-static char *buttonText(uiButton *bb)
-{
- return g_strdup(gtk_button_get_label(BUTTON(bb)));
-}
-
-static void buttonSetText(uiButton *bb, const char *text)
-{
- gtk_button_set_label(BUTTON(bb), text);
-}
-
-static void buttonOnClicked(uiButton *bb, void (*f)(uiButton *, void *), void *data)
-{
- struct button *b = (struct button *) bb;
-
- b->onClicked = f;
- b->onClickedData = data;
-}
-
-uiButton *uiNewButton(const char *text)
-{
- struct button *b;
- GtkWidget *widget;
-
- b = uiNew(struct button);
-
- uiUnixNewControl(uiControl(b), GTK_TYPE_BUTTON,
- FALSE, FALSE,
- "label", text,
- NULL);
-
- widget = WIDGET(b);
- g_signal_connect(widget, "clicked", G_CALLBACK(clicked), b);
- g_signal_connect(widget, "destroy", G_CALLBACK(destroy), b);
- b->onClicked = defaultOnClicked;
-
- uiButton(b)->Text = buttonText;
- uiButton(b)->SetText = buttonSetText;
- uiButton(b)->OnClicked = buttonOnClicked;
-
- return uiButton(b);
-}
diff --git a/new/unix/checkbox.c b/new/unix/checkbox.c
deleted file mode 100644
index f3563a1..0000000
--- a/new/unix/checkbox.c
+++ /dev/null
@@ -1,95 +0,0 @@
-// 7 april 2015
-#include "uipriv_unix.h"
-
-struct checkbox {
- uiCheckbox c;
- void (*onToggled)(uiCheckbox *, void *);
- void *onToggledData;
- gulong onToggledSignal;
-};
-
-static void onToggled(GtkToggleButton *b, gpointer data)
-{
- struct checkbox *c = (struct checkbox *) data;
-
- (*(c->onToggled))(uiCheckbox(c), c->onToggledData);
-}
-
-static void defaultOnToggled(uiCheckbox *c, void *data)
-{
- // do nothing
-}
-
-static void onDestroy(GtkWidget *widget, gpointer data)
-{
- struct checkbox *c = (struct checkbox *) data;
-
- uiFree(c);
-}
-
-#define CHECKBOX(c) GTK_CHECK_BUTTON(uiControlHandle(uiControl(c)))
-
-static char *getText(uiCheckbox *c)
-{
- return g_strdup(gtk_button_get_label(GTK_BUTTON(CHECKBOX(c))));
-}
-
-static void setText(uiCheckbox *c, const char *text)
-{
- gtk_button_set_label(GTK_BUTTON(CHECKBOX(c)), text);
-}
-
-static void setOnToggled(uiCheckbox *cc, void (*f)(uiCheckbox *, void *), void *data)
-{
- struct checkbox *c = (struct checkbox *) cc;
-
- c->onToggled = f;
- c->onToggledData = data;
-}
-
-static int getChecked(uiCheckbox *c)
-{
- return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(CHECKBOX(c))) != FALSE;
-}
-
-static void setChecked(uiCheckbox *cc, int checked)
-{
- struct checkbox *c = (struct checkbox *) cc;
- GtkToggleButton *button;
- gboolean active;
-
- active = FALSE;
- if (checked)
- active = TRUE;
- // we need to inhibit sending of ::toggled because this WILL send a ::toggled otherwise
- button = GTK_TOGGLE_BUTTON(CHECKBOX(c));
- g_signal_handler_block(button, c->onToggledSignal);
- gtk_toggle_button_set_active(button, active);
- g_signal_handler_unblock(button, c->onToggledSignal);
-}
-
-uiCheckbox *uiNewCheckbox(const char *text)
-{
- struct checkbox *c;
- GtkWidget *widget;
-
- c = uiNew(struct checkbox);
-
- uiUnixNewControl(uiControl(c), GTK_TYPE_CHECK_BUTTON,
- FALSE, FALSE,
- "label", text,
- NULL);
-
- widget = GTK_WIDGET(CHECKBOX(c));
- g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), c);
- c->onToggledSignal = g_signal_connect(widget, "toggled", G_CALLBACK(onToggled), c);
- c->onToggled = defaultOnToggled;
-
- uiCheckbox(c)->Text = getText;
- uiCheckbox(c)->SetText = setText;
- uiCheckbox(c)->OnToggled = setOnToggled;
- uiCheckbox(c)->Checked = getChecked;
- uiCheckbox(c)->SetChecked = setChecked;
-
- return uiCheckbox(c);
-}
diff --git a/new/unix/entry.c b/new/unix/entry.c
deleted file mode 100644
index 4731f68..0000000
--- a/new/unix/entry.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// 8 april 2015
-#include "uipriv_unix.h"
-
-struct entry {
- uiEntry e;
-};
-
-static void onDestroy(GtkWidget *widget, gpointer data)
-{
- struct entry *e = (struct entry *) data;
-
- uiFree(e);
-}
-
-#define ENTRY(e) GTK_ENTRY(uiControlHandle(uiControl(e)))
-
-static char *getText(uiEntry *e)
-{
- return g_strdup(gtk_entry_get_text(ENTRY(e)));
-}
-
-static void setText(uiEntry *e, const char *text)
-{
- gtk_entry_set_text(ENTRY(e), text);
-}
-
-uiEntry *uiNewEntry(void)
-{
- struct entry *e;
- GtkWidget *widget;
-
- e = uiNew(struct entry);
-
- uiUnixNewControl(uiControl(e), GTK_TYPE_ENTRY,
- FALSE, FALSE,
- NULL);
-
- widget = GTK_WIDGET(ENTRY(e));
- g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), e);
-
- uiEntry(e)->Text = getText;
- uiEntry(e)->SetText = setText;
-
- return uiEntry(e);
-}
diff --git a/new/unix/init.c b/new/unix/init.c
deleted file mode 100644
index b10c05b..0000000
--- a/new/unix/init.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// 6 april 2015
-#include "uipriv_unix.h"
-
-uiInitOptions options;
-
-const char *uiInit(uiInitOptions *o)
-{
- GError *err = NULL;
- const char *msg;
-
- options = *o;
- if (gtk_init_with_args(NULL, NULL, NULL, NULL, NULL, &err) == FALSE) {
- msg = g_strdup(err->message);
- g_error_free(err);
- return msg;
- }
- return NULL;
-}
-
-void uiFreeInitError(const char *err)
-{
- g_free((gpointer) err);
-}
diff --git a/new/unix/label.c b/new/unix/label.c
deleted file mode 100644
index 1a7aa28..0000000
--- a/new/unix/label.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// 11 april 2015
-#include "uipriv_unix.h"
-
-struct label {
- uiLabel l;
-};
-
-static void onDestroy(GtkWidget *widget, gpointer data)
-{
- struct label *l = (struct label *) data;
-
- uiFree(l);
-}
-
-#define LABEL(l) GTK_LABEL(uiControlHandle(uiControl(l)))
-
-static char *getText(uiLabel *l)
-{
- // TODO change g_strdup() to a wrapper function for export in ui_unix.h
- return g_strdup(gtk_label_get_text(LABEL(l)));
-}
-
-static void setText(uiLabel *l, const char *text)
-{
- gtk_label_set_text(LABEL(l), text);
-}
-
-uiLabel *uiNewLabel(const char *text)
-{
- struct label *l;
- GtkWidget *widget;
-
- l = uiNew(struct label);
-
- uiUnixNewControl(uiControl(l), GTK_TYPE_LABEL,
- FALSE, FALSE,
- "label", text,
- "xalign", 0.0, // note: must be a float constant, otherwise the ... will turn it into an int and we get segfaults on some platforms (thanks ebassi in irc.gimp.net/#gtk+)
- // TODO yalign 0?
- NULL);
-
- widget = GTK_WIDGET(LABEL(l));
- g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), l);
-
- uiLabel(l)->Text = getText;
- uiLabel(l)->SetText = setText;
-
- return uiLabel(l);
-}
diff --git a/new/unix/main.c b/new/unix/main.c
deleted file mode 100644
index 10af782..0000000
--- a/new/unix/main.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// 6 april 2015
-#include "uipriv_unix.h"
-
-// #qo pkg-config: gtk+-3.0
-
-void uiMain(void)
-{
- gtk_main();
-}
-
-// gtk_main_quit() may run immediately, or it may wait for other pending events; "it depends" (thanks mclasen in irc.gimp.net/#gtk+)
-// PostQuitMessage() on Windows always waits, so we must do so too
-// we'll do it by using an idle callback
-static gboolean quit(gpointer data)
-{
- gtk_main_quit();
- return FALSE;
-}
-
-void uiQuit(void)
-{
- gdk_threads_add_idle(quit, NULL);
-}
diff --git a/new/unix/newcontrol.c b/new/unix/newcontrol.c
deleted file mode 100644
index d23e190..0000000
--- a/new/unix/newcontrol.c
+++ /dev/null
@@ -1,225 +0,0 @@
-// 7 april 2015
-#include "uipriv_unix.h"
-
-typedef struct singleWidget singleWidget;
-
-struct singleWidget {
- GtkWidget *widget;
- GtkWidget *scrolledWindow;
- GtkWidget *immediate; // the widget that is added to the parent container; either widget or scrolledWindow
- uiParent *parent;
- gboolean userHid;
- gboolean containerHid;
- gboolean userDisabled;
- gboolean containerDisabled;
-};
-
-static void singleDestroy(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- gtk_widget_destroy(s->immediate);
-}
-
-static uintptr_t singleHandle(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- return (uintptr_t) (s->widget);
-}
-
-static void singleSetParent(uiControl *c, uiParent *parent)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
- uiParent *oldparent;
-
- oldparent = s->parent;
- s->parent = parent;
- if (oldparent != NULL) {
- gtk_container_remove(GTK_CONTAINER(uiParentHandle(oldparent)), s->immediate);
- uiParentUpdate(oldparent);
- }
- if (s->parent != NULL) {
- gtk_container_add(GTK_CONTAINER(uiParentHandle(s->parent)), s->immediate);
- uiParentUpdate(s->parent);
- }
-}
-
-static void singlePreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
- GtkRequisition natural;
-
- // use the natural size as the minimum size is an *absolute* minimum
- // for example, if a label has ellipsizing on, it can be the width of the ellipses, not the text
- // there is a warning about height-for-width sizing, but in my tests this isn't an issue
- gtk_widget_get_preferred_size(s->widget, NULL, &natural);
- *width = natural.width;
- *height = natural.height;
-}
-
-static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
- GtkAllocation a;
-
- a.x = x;
- a.y = y;
- a.width = width;
- a.height = height;
- gtk_widget_size_allocate(s->immediate, &a);
-}
-
-static int singleVisible(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- if (s->userHid)
- return 0;
- return 1;
-}
-
-static void singleShow(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->userHid = FALSE;
- if (!s->containerHid) {
- gtk_widget_show_all(s->immediate);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void singleHide(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->userHid = TRUE;
- gtk_widget_hide(s->immediate);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void singleContainerShow(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->containerHid = FALSE;
- if (!s->userHid) {
- gtk_widget_show_all(s->immediate);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void singleContainerHide(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->containerHid = TRUE;
- gtk_widget_hide(s->immediate);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void singleEnable(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->userDisabled = FALSE;
- if (!s->containerDisabled)
- gtk_widget_set_sensitive(s->immediate, TRUE);
-}
-
-static void singleDisable(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->userDisabled = TRUE;
- gtk_widget_set_sensitive(s->immediate, FALSE);
-}
-
-static void singleContainerEnable(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->containerDisabled = FALSE;
- if (!s->userDisabled)
- gtk_widget_set_sensitive(s->immediate, TRUE);
-}
-
-static void singleContainerDisable(uiControl *c)
-{
- singleWidget *s = (singleWidget *) (c->Internal);
-
- s->containerDisabled = TRUE;
- gtk_widget_set_sensitive(s->immediate, FALSE);
-}
-
-static void onDestroy(GtkWidget *widget, gpointer data)
-{
- singleWidget *s = (singleWidget *) data;
-
- uiFree(s);
-}
-
-void uiUnixNewControl(uiControl *c, GType type, gboolean inScrolledWindow, gboolean scrolledWindowHasBorder, const char *firstProperty, ...)
-{
- singleWidget *s;
- va_list ap;
-
- s = uiNew(singleWidget);
-
- va_start(ap, firstProperty);
- s->widget = GTK_WIDGET(g_object_new_valist(type, firstProperty, ap));
- va_end(ap);
- s->immediate = s->widget;
-
- if (inScrolledWindow) {
- s->scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
- if (!GTK_IS_SCROLLABLE(s->widget))
- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(s->scrolledWindow), s->widget);
- else
- gtk_container_add(GTK_CONTAINER(s->scrolledWindow), s->widget);
- if (scrolledWindowHasBorder)
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(s->scrolledWindow), GTK_SHADOW_IN);
- s->immediate = s->scrolledWindow;
- }
-
- // we need to keep an extra reference on the immediate widget
- // this is so uiControlDestroy() can work regardless of when it is called and who calls it
- // without this:
- // - end user call works (only one ref)
- // - call in uiContainer destructor fails (uiContainer ref freed)
- // with this:
- // - end user call works (shoudn't be in any container)
- // - call in uiContainer works (both refs freed)
- // this also ensures singleRemoveParent() works properly
- g_object_ref_sink(s->immediate);
-
- // assign s later; we still need it for one more thing
- c->Destroy = singleDestroy;
- c->Handle = singleHandle;
- c->SetParent = singleSetParent;
- c->PreferredSize = singlePreferredSize;
- c->Resize = singleResize;
- c->Visible = singleVisible;
- c->Show = singleShow;
- c->Hide = singleHide;
- c->ContainerShow = singleContainerShow;
- c->ContainerHide = singleContainerHide;
- c->Enable = singleEnable;
- c->Disable = singleDisable;
- c->ContainerEnable = singleContainerEnable;
- c->ContainerDisable = singleContainerDisable;
-
- // and let's free everything with the immediate widget
- // we send s as data instead of c just in case c is gone by then
- g_signal_connect(s->immediate, "destroy", G_CALLBACK(onDestroy), s);
-
- // finally, call gtk_widget_show_all() here to set the initial visibility of the widget
- gtk_widget_show_all(s->immediate);
-
- c->Internal = s;
-}
diff --git a/new/unix/parent.c b/new/unix/parent.c
deleted file mode 100644
index 54d5d06..0000000
--- a/new/unix/parent.c
+++ /dev/null
@@ -1,183 +0,0 @@
-// 13 august 2014
-#include "uipriv_unix.h"
-
-#define uipParentType (uipParent_get_type())
-#define uipParent(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), uipParentType, uipParent))
-#define uipIsParent(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), uipParentType))
-#define uipParentClass(class) (G_TYPE_CHECK_CLASS_CAST((class), uipParentType, uipParentClass))
-#define uipIsParentClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), uipParent))
-#define uipGetParentClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), uipParentType, uipParentClass))
-
-typedef struct uipParent uipParent;
-typedef struct uipParentClass uipParentClass;
-
-struct uipParent {
- GtkContainer parent_instance;
- // this is what triggers the resizing of all the children
- uiControl *child;
- // these are the actual children widgets of the container as far as GTK+ is concerned
- GPtrArray *children; // for forall()
- intmax_t marginLeft;
- intmax_t marginTop;
- intmax_t marginRight;
- intmax_t marginBottom;
-};
-
-struct uipParentClass {
- GtkContainerClass parent_class;
-};
-
-G_DEFINE_TYPE(uipParent, uipParent, GTK_TYPE_CONTAINER)
-
-static void uipParent_init(uipParent *p)
-{
- if (options.debugLogAllocations)
- fprintf(stderr, "%p alloc uipParent\n", p);
- p->children = g_ptr_array_new();
- gtk_widget_set_has_window(GTK_WIDGET(p), FALSE);
-}
-
-// instead of having GtkContainer itself unref all our controls, we'll run our own uiControlDestroy() functions for child, which will do that and more
-// we still chain up because we need to, but by that point there will be no children for GtkContainer to free
-static void uipParent_dispose(GObject *obj)
-{
- uipParent *p = uipParent(obj);
-
- if (p->children != NULL) {
- g_ptr_array_unref(p->children);
- p->children = NULL;
- }
- if (p->child != NULL) {
- uiControlDestroy(p->child);
- p->child = NULL;
- }
- G_OBJECT_CLASS(uipParent_parent_class)->dispose(obj);
-}
-
-static void uipParent_finalize(GObject *obj)
-{
- G_OBJECT_CLASS(uipParent_parent_class)->finalize(obj);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p free\n", obj);
-}
-
-static void uipParent_add(GtkContainer *container, GtkWidget *widget)
-{
- uipParent *p = uipParent(container);
-
- gtk_widget_set_parent(widget, GTK_WIDGET(p));
- if (p->children != NULL)
- g_ptr_array_add(p->children, widget);
-}
-
-static void uipParent_remove(GtkContainer *container, GtkWidget *widget)
-{
- uipParent *p = uipParent(container);
-
- gtk_widget_unparent(widget);
- if (p->children != NULL)
- g_ptr_array_remove(p->children, widget);
-}
-
-#define gtkXPadding 12
-#define gtkYPadding 6
-
-static void uipParent_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
- uipParent *p = uipParent(widget);
- uiSizing d;
- intmax_t x, y, width, height;
-
- gtk_widget_set_allocation(GTK_WIDGET(p), allocation);
- if (p->child == NULL)
- return;
- x = allocation->x + p->marginLeft;
- y = allocation->y + p->marginTop;
- width = allocation->width - (p->marginLeft + p->marginRight);
- height = allocation->height - (p->marginTop + p->marginBottom);
- d.xPadding = gtkXPadding;
- d.yPadding = gtkYPadding;
- uiControlResize(p->child, x, y, width, height, &d);
-}
-
-struct forall {
- GtkCallback callback;
- gpointer data;
-};
-
-static void doforall(gpointer obj, gpointer data)
-{
- struct forall *s = (struct forall *) data;
-
- (*(s->callback))(GTK_WIDGET(obj), s->data);
-}
-
-static void uipParent_forall(GtkContainer *container, gboolean includeInternals, GtkCallback callback, gpointer data)
-{
- uipParent *p = uipParent(container);
- struct forall s;
-
- s.callback = callback;
- s.data = data;
- if (p->children != NULL)
- g_ptr_array_foreach(p->children, doforall, &s);
-}
-
-static void uipParent_class_init(uipParentClass *class)
-{
- G_OBJECT_CLASS(class)->dispose = uipParent_dispose;
- G_OBJECT_CLASS(class)->finalize = uipParent_finalize;
- GTK_WIDGET_CLASS(class)->size_allocate = uipParent_size_allocate;
- GTK_CONTAINER_CLASS(class)->add = uipParent_add;
- GTK_CONTAINER_CLASS(class)->remove = uipParent_remove;
- GTK_CONTAINER_CLASS(class)->forall = uipParent_forall;
-}
-
-static uintptr_t parentHandle(uiParent *p)
-{
- uipParent *pp = uipParent(p->Internal);
-
- return (uintptr_t) pp;
-}
-
-static void parentSetChild(uiParent *p, uiControl *child)
-{
- uipParent *pp = uipParent(p->Internal);
-
- pp->child = child;
- if (pp->child != NULL)
- uiControlSetParent(child, p);
-}
-
-static void parentSetMargins(uiParent *p, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
-{
- uipParent *pp = uipParent(p->Internal);
-
- pp->marginLeft = left;
- pp->marginTop = top;
- pp->marginRight = right;
- pp->marginBottom = bottom;
-}
-
-static void parentUpdate(uiParent *p)
-{
- uipParent *pp = uipParent(p->Internal);
-
- gtk_widget_queue_resize(GTK_WIDGET(pp));
-}
-
-uiParent *uiNewParent(uintptr_t osParent)
-{
- uiParent *p;
-
- p = uiNew(uiParent);
- p->Internal = g_object_new(uipParentType, NULL);
- p->Handle = parentHandle;
- p->SetChild = parentSetChild;
- p->SetMargins = parentSetMargins;
- p->Update = parentUpdate;
- gtk_container_add(GTK_CONTAINER(osParent), GTK_WIDGET(p->Internal));
- // and make it visible by default
- gtk_widget_show_all(GTK_WIDGET(p->Internal));
- return p;
-}
diff --git a/new/unix/tab.c b/new/unix/tab.c
deleted file mode 100644
index bb168f5..0000000
--- a/new/unix/tab.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// 12 april 2015
-#include "uipriv_unix.h"
-
-struct tab {
- uiTab t;
- uiParent **pages;
- uintmax_t len;
- uintmax_t cap;
-};
-
-static void onDestroy(GtkWidget *widget, gpointer data)
-{
- struct tab *t = (struct tab *) data;
-
- uiFree(t->pages);
- uiFree(t);
-}
-
-#define TAB(t) GTK_NOTEBOOK(uiControlHandle(uiControl(t)))
-
-#define tabCapGrow 32
-
-static void addPage(uiTab *tt, const char *name, uiControl *child)
-{
- struct tab *t = (struct tab *) tt;
- GtkWidget *notebook;
- uiParent *content;
-
- if (t->len >= t->cap) {
- t->cap += tabCapGrow;
- t->pages = (uiParent **) uiRealloc(t->pages, t->cap * sizeof (uiParent *), "uiParent *[]");
- }
-
- notebook = GTK_WIDGET(TAB(t));
- content = uiNewParent((uintptr_t) notebook);
- uiParentSetChild(content, child);
- uiParentUpdate(content);
- gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(notebook), GTK_WIDGET(uiParentHandle(content)), name);
-
- t->pages[t->len] = content;
- t->len++;
-}
-
-uiTab *uiNewTab(void)
-{
- struct tab *t;
- GtkWidget *widget;
-
- t = uiNew(struct tab);
-
- uiUnixNewControl(uiControl(t), GTK_TYPE_NOTEBOOK,
- FALSE, FALSE,
- NULL);
-
- widget = GTK_WIDGET(TAB(t));
- g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), t);
-
- uiTab(t)->AddPage = addPage;
-
- return uiTab(t);
-}
diff --git a/new/unix/uipriv_unix.h b/new/unix/uipriv_unix.h
deleted file mode 100644
index 0f460cb..0000000
--- a/new/unix/uipriv_unix.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// 6 april 2015
-#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_32
-#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_32
-#define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_4
-#define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_4
-#include <gtk/gtk.h>
-#include "../uipriv.h"
-#include "../ui_unix.h"
-
-#define gtkXMargin 12
-#define gtkYMargin 12
-
-#define widget(c) uiControlHandle(uiControl(c))
-#define WIDGET(c) GTK_WIDGET(widget(c))
diff --git a/new/unix/util.c b/new/unix/util.c
deleted file mode 100644
index 72b71df..0000000
--- a/new/unix/util.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// 9 april 2015
-#include "uipriv_unix.h"
-
-void uiFreeText(char *t)
-{
- g_free(t);
-}
diff --git a/new/unix/window.c b/new/unix/window.c
deleted file mode 100644
index 039feb7..0000000
--- a/new/unix/window.c
+++ /dev/null
@@ -1,137 +0,0 @@
-// 6 april 2015
-#include "uipriv_unix.h"
-
-struct window {
- uiWindow w;
- GtkWidget *widget;
- uiParent *content;
- int (*onClosing)(uiWindow *, void *);
- void *onClosingData;
- int margined;
-};
-
-static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data)
-{
- struct window *w = (struct window *) data;
-
- // return exact values just in case
- if ((*(w->onClosing))(uiWindow(w), w->onClosingData))
- return FALSE;
- return TRUE;
-}
-
-static int defaultOnClosing(uiWindow *w, void *data)
-{
- return 1;
-}
-
-static void onDestroy(GtkWidget *widget, gpointer data)
-{
- struct window *w = (struct window *) data;
-
- uiFree(w);
-}
-
-static void windowDestroy(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- gtk_widget_destroy(w->widget);
-}
-
-static uintptr_t handle(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- return (uintptr_t) (w->widget);
-}
-
-static char *getTitle(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- return g_strdup(gtk_window_get_title(GTK_WINDOW(w->widget)));
-}
-
-static void setTitle(uiWindow *ww, const char *title)
-{
- struct window *w = (struct window *) ww;
-
- gtk_window_set_title(GTK_WINDOW(w->widget), title);
-}
-
-static void show(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- // don't use gtk_widget_show_all(); that will override user hidden settings
- gtk_widget_show(w->widget);
-}
-
-static void hide(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
- gtk_widget_hide(w->widget);
-}
-
-static void setOnClosing(uiWindow *ww, int (*f)(uiWindow *, void *), void *data)
-{
- struct window *w = (struct window *) ww;
-
- w->onClosing = f;
- w->onClosingData = data;
-}
-
-static void setChild(uiWindow *ww, uiControl *c)
-{
- struct window *w = (struct window *) ww;
-
- uiParentSetChild(w->content, c);
- uiParentUpdate(w->content);
-}
-
-static int margined(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- return w->margined;
-}
-
-static void setMargined(uiWindow *ww, int margined)
-{
- struct window *w = (struct window *) ww;
-
- w->margined = margined;
- if (w->margined)
- uiParentSetMargins(w->content, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
- else
- uiParentSetMargins(w->content, 0, 0, 0, 0);
- uiParentUpdate(w->content);
-}
-
-uiWindow *uiNewWindow(const char *title, int width, int height)
-{
- struct window *w;
-
- w = uiNew(struct window);
- w->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(w->widget), title);
- gtk_window_resize(GTK_WINDOW(w->widget), width, height);
- g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
- g_signal_connect(w->widget, "destroy", G_CALLBACK(onDestroy), w);
- w->content = uiNewParent((uintptr_t) (w->widget));
- w->onClosing = defaultOnClosing;
-
- uiWindow(w)->Destroy = windowDestroy;
- uiWindow(w)->Handle = handle;
- uiWindow(w)->Title = getTitle;
- uiWindow(w)->SetTitle = setTitle;
- uiWindow(w)->Show = show;
- uiWindow(w)->Hide = hide;
- uiWindow(w)->OnClosing = setOnClosing;
- uiWindow(w)->SetChild = setChild;
- uiWindow(w)->Margined = margined;
- uiWindow(w)->SetMargined = setMargined;
-
- return uiWindow(w);
-}
diff --git a/new/windows/GNUmakeinc.mk b/new/windows/GNUmakeinc.mk
deleted file mode 100644
index 494b8e3..0000000
--- a/new/windows/GNUmakeinc.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-OSCFILES = \
- alloc.c \
- button.c \
- checkbox.c \
- comctl32.c \
- debug.c \
- entry.c \
- init.c \
- label.c \
- main.c \
- newcontrol.c \
- parent.c \
- tab.c \
- text.c \
- util.c \
- window.c
-
-xLDFLAGS += \
- -luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32 -lcomdlg32 -lole32 -loleaut32 -loleacc -luuid
-
-OUT = new.exe
-
-ifeq ($(ARCH),64)
- CC = x86_64-w64-mingw32-gcc
- RC = x86_64-w64-mingw32-windres
- xCFLAGS += -m64
- xLDFLAGS += -m64
-else
- CC = i686-w64-mingw32-gcc
- RC = i686-w64-mingw32-windres
- xCFLAGS += -m32
- xLDFLAGS += -m32
-endif
diff --git a/new/windows/alloc.c b/new/windows/alloc.c
deleted file mode 100644
index 147c90d..0000000
--- a/new/windows/alloc.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// 4 december 2014
-#include "uipriv_windows.h"
-
-// wrappers for allocator of choice
-// panics on memory exhausted, undefined on heap corruption or other unreliably-detected malady (see http://stackoverflow.com/questions/28761680/is-there-a-windows-api-memory-allocator-deallocator-i-can-use-that-will-just-giv)
-// new memory is set to zero
-// passing NULL to tableRealloc() acts like tableAlloc()
-// passing NULL to tableFree() is a no-op
-
-void *uiAlloc(size_t size, const char *type)
-{
- void *out;
-
- out = malloc(size);
- if (out == NULL) {
- fprintf(stderr, "memory exhausted in uiAlloc() allocating %s\n", type);
- abort();
- }
- ZeroMemory(out, size);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p alloc %s\n", out, type);
- return out;
-}
-
-void *uiRealloc(void *p, size_t size, const char *type)
-{
- void *out;
-
- if (p == NULL)
- return uiAlloc(size, type);
- out = realloc(p, size);
- if (out == NULL) {
- fprintf(stderr, "memory exhausted in uiRealloc() reallocating %s\n", type);
- abort();
- }
- // TODO zero the extra memory
- if (options.debugLogAllocations)
- fprintf(stderr, "%p realloc %p\n", p, out);
- return out;
-}
-
-void uiFree(void *p)
-{
- if (p == NULL)
- return;
- free(p);
- if (options.debugLogAllocations)
- fprintf(stderr, "%p free\n", p);
-}
diff --git a/new/windows/button.c b/new/windows/button.c
deleted file mode 100644
index fd7afa3..0000000
--- a/new/windows/button.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// 7 april 2015
-#include "uipriv_windows.h"
-
-struct button {
- uiButton b;
- void (*onClicked)(uiButton *, void *);
- void *onClickedData;
-};
-
-static BOOL onWM_COMMAND(uiControl *c, WORD code, LRESULT *lResult)
-{
- struct button *b = (struct button *) c;
-
- if (code != BN_CLICKED)
- return FALSE;
- (*(b->onClicked))(uiButton(b), b->onClickedData);
- *lResult = 0;
- return TRUE;
-}
-
-static BOOL onWM_NOTIFY(uiControl *c, NMHDR *nm, LRESULT *lResult)
-{
- return FALSE;
-}
-
-static void onWM_DESTROY(uiControl *c)
-{
- struct button *b = (struct button *) c;
-
- uiFree(b);
-}
-
-// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
-#define buttonHeight 14
-
-static void preferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- HWND hwnd;
- SIZE size;
-
- hwnd = uiControlHWND(c);
-
- // try the comctl32 version 6 way
- size.cx = 0; // explicitly ask for ideal size
- size.cy = 0;
- if (SendMessageW(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) {
- *width = size.cx;
- *height = size.cy;
- return;
- }
-
- // that didn't work; fall back to using Microsoft's metrics
- // Microsoft says to use a fixed width for all buttons; this isn't good enough
- // use the text width instead, with some edge padding
- *width = uiWindowsWindowTextWidth(hwnd) + (2 * GetSystemMetrics(SM_CXEDGE));
- *height = uiDlgUnitsToY(buttonHeight, d->sys->baseY);
-}
-
-static void defaultOnClicked(uiButton *b, void *data)
-{
- // do nothing
-}
-
-static char *getText(uiButton *b)
-{
- return uiWindowsControlText(uiControl(b));
-}
-
-static void setText(uiButton *b, const char *text)
-{
- uiWindowsControlSetText(uiControl(b), text);
-}
-
-static void setOnClicked(uiButton *bb, void (*f)(uiButton *, void *), void *data)
-{
- struct button *b = (struct button *) bb;
-
- b->onClicked = f;
- b->onClickedData = data;
-}
-
-uiButton *uiNewButton(const char *text)
-{
- struct button *b;
- uiWindowsNewControlParams p;
- WCHAR *wtext;
-
- b = uiNew(struct button);
-
- p.dwExStyle = 0;
- p.lpClassName = L"button";
- wtext = toUTF16(text);
- p.lpWindowName = wtext;
- p.dwStyle = BS_PUSHBUTTON | WS_TABSTOP;
- p.hInstance = hInstance;
- p.useStandardControlFont = TRUE;
- p.onWM_COMMAND = onWM_COMMAND;
- p.onWM_NOTIFY = onWM_NOTIFY;
- p.onWM_DESTROY = onWM_DESTROY;
- uiWindowsNewControl(uiControl(b), &p);
- uiFree(wtext);
-
- b->onClicked = defaultOnClicked;
-
- uiControl(b)->PreferredSize = preferredSize;
-
- uiButton(b)->Text = getText;
- uiButton(b)->SetText = setText;
- uiButton(b)->OnClicked = setOnClicked;
-
- return uiButton(b);
-}
diff --git a/new/windows/checkbox.c b/new/windows/checkbox.c
deleted file mode 100644
index c1d5a6f..0000000
--- a/new/windows/checkbox.c
+++ /dev/null
@@ -1,129 +0,0 @@
-// 7 april 2015
-#include "uipriv_windows.h"
-
-struct checkbox {
- uiCheckbox c;
- void (*onToggled)(uiCheckbox *, void *);
- void *onToggledData;
-};
-
-static BOOL onWM_COMMAND(uiControl *cc, WORD code, LRESULT *lResult)
-{
- struct checkbox *c = (struct checkbox *) cc;
- HWND hwnd;
- WPARAM check;
-
- if (code != BN_CLICKED)
- return FALSE;
-
- // we didn't use BS_AUTOCHECKBOX (see controls_windows.go) so we have to manage the check state ourselves
- hwnd = uiControlHWND(uiControl(c));
- check = BST_CHECKED;
- if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED)
- check = BST_UNCHECKED;
- SendMessage(hwnd, BM_SETCHECK, check, 0);
-
- (*(c->onToggled))(uiCheckbox(c), c->onToggledData);
- *lResult = 0;
- return TRUE;
-}
-
-static BOOL onWM_NOTIFY(uiControl *c, NMHDR *nm, LRESULT *lResult)
-{
- return FALSE;
-}
-
-static void onWM_DESTROY(uiControl *cc)
-{
- struct checkbox *c = (struct checkbox *) cc;
-
- uiFree(c);
-}
-
-// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
-#define checkboxHeight 10
-// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx
-#define checkboxXFromLeftOfBoxToLeftOfLabel 12
-
-static void preferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- *width = uiDlgUnitsToX(checkboxXFromLeftOfBoxToLeftOfLabel, d->sys->baseX) + uiWindowsWindowTextWidth(uiControlHWND(c));
- *height = uiDlgUnitsToY(checkboxHeight, d->sys->baseY);
-}
-
-static void defaultOnToggled(uiCheckbox *c, void *data)
-{
- // do nothing
-}
-
-static char *getText(uiCheckbox *c)
-{
- return uiWindowsControlText(uiControl(c));
-}
-
-static void setText(uiCheckbox *c, const char *text)
-{
- uiWindowsControlSetText(uiControl(c), text);
-}
-
-static void setOnToggled(uiCheckbox *cc, void (*f)(uiCheckbox *, void *), void *data)
-{
- struct checkbox *c = (struct checkbox *) cc;
-
- c->onToggled = f;
- c->onToggledData = data;
-}
-
-static int getChecked(uiCheckbox *c)
-{
- HWND hwnd;
-
- hwnd = uiControlHWND(uiControl(c));
- return SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED;
-}
-
-static void setChecked(uiCheckbox *c, int checked)
-{
- HWND hwnd;
- WPARAM check;
-
- hwnd = uiControlHWND(uiControl(c));
- check = BST_CHECKED;
- if (!checked)
- check = BST_UNCHECKED;
- SendMessage(hwnd, BM_SETCHECK, check, 0);
-}
-
-uiCheckbox *uiNewCheckbox(const char *text)
-{
- struct checkbox *c;
- uiWindowsNewControlParams p;
- WCHAR *wtext;
-
- c = uiNew(struct checkbox);
-
- p.dwExStyle = 0;
- p.lpClassName = L"button";
- wtext = toUTF16(text);
- p.lpWindowName = wtext;
- p.dwStyle = BS_CHECKBOX | WS_TABSTOP;
- p.hInstance = hInstance;
- p.useStandardControlFont = TRUE;
- p.onWM_COMMAND = onWM_COMMAND;
- p.onWM_NOTIFY = onWM_NOTIFY;
- p.onWM_DESTROY = onWM_DESTROY;
- uiWindowsNewControl(uiControl(c), &p);
- uiFree(wtext);
-
- c->onToggled = defaultOnToggled;
-
- uiControl(c)->PreferredSize = preferredSize;
-
- uiCheckbox(c)->Text = getText;
- uiCheckbox(c)->SetText = setText;
- uiCheckbox(c)->OnToggled = setOnToggled;
- uiCheckbox(c)->Checked = getChecked;
- uiCheckbox(c)->SetChecked = setChecked;
-
- return uiCheckbox(c);
-}
diff --git a/new/windows/comctl32.c b/new/windows/comctl32.c
deleted file mode 100644
index 93b3a27..0000000
--- a/new/windows/comctl32.c
+++ /dev/null
@@ -1,105 +0,0 @@
-// 17 july 2014
-#include "uipriv_windows.h"
-
-static ULONG_PTR comctlManifestCookie;
-static HMODULE comctl32;
-
-// these are listed as WINAPI in both Microsoft's and MinGW's headers, but not on MSDN for some reason
-BOOL (*WINAPI fv_SetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
-BOOL (*WINAPI fv_RemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
-LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
-
-#define wantedICCClasses ( \
- ICC_STANDARD_CLASSES | /* user32.dll controls */ \
- ICC_PROGRESS_CLASS | /* progress bars */ \
- ICC_TAB_CLASSES | /* tabs */ \
- ICC_LISTVIEW_CLASSES | /* table headers */ \
- ICC_UPDOWN_CLASS | /* spinboxes */ \
- 0)
-
-// note that this is an 8-bit character string we're writing; see the encoding clause
-static const char manifest[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n<assemblyIdentity\n version=\"1.0.0.0\"\n processorArchitecture=\"*\"\n name=\"CompanyName.ProductName.YourApplication\"\n type=\"win32\"\n/>\n<description>Your application description here.</description>\n<dependency>\n <dependentAssembly>\n <assemblyIdentity\n type=\"win32\"\n name=\"Microsoft.Windows.Common-Controls\"\n version=\"6.0.0.0\"\n processorArchitecture=\"*\"\n publicKeyToken=\"6595b64144ccf1df\"\n language=\"*\"\n />\n </dependentAssembly>\n</dependency>\n</assembly>\n";
-
-/*
-Windows requires a manifest file to enable Common Controls version 6.
-The only way to not require an external manifest is to synthesize the manifest ourselves.
-We can use the activation context API to load it at runtime.
-References:
-- http://stackoverflow.com/questions/4308503/how-to-enable-visual-styles-without-a-manifest
-- http://support.microsoft.com/kb/830033
-Because neither Go nor MinGW have ways to compile in resources like this (as far as I know), we have to do the work ourselves.
-*/
-const char *initCommonControls(void)
-{
- WCHAR temppath[MAX_PATH + 1];
- WCHAR filename[MAX_PATH + 1];
- HANDLE file;
- DWORD nExpected, nGot;
- ACTCTX actctx;
- HANDLE ac;
- INITCOMMONCONTROLSEX icc;
- FARPROC f;
- // this is listed as WINAPI in both Microsoft's and MinGW's headers, but not on MSDN for some reason
- BOOL (*WINAPI ficc)(const LPINITCOMMONCONTROLSEX);
-
- if (GetTempPathW(MAX_PATH + 1, temppath) == 0)
- return "getting temporary path for writing manifest file in initCommonControls()";
- if (GetTempFileNameW(temppath, L"manifest", 0, filename) == 0)
- return "getting temporary filename for writing manifest file in initCommonControls()";
- file = CreateFileW(filename, GENERIC_WRITE,
- 0, // don't share while writing
- NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (file == NULL)
- return "creating manifest file in initCommonControls()";
- nExpected = (sizeof manifest / sizeof manifest[0]) - 1; // - 1 to omit the terminating null character)
- SetLastError(0); // catch errorless short writes
- if (WriteFile(file, manifest, nExpected, &nGot, NULL) == 0)
- return "writing manifest file in initCommonControls()";
- if (nGot != nExpected) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == 0)
- return "writing entire manifest file (short write) without error code in initCommonControls()";
- return "writing entire manifest file (short write) in initCommonControls()";
- }
- if (CloseHandle(file) == 0)
- return "closing manifest file (this IS an error here because not doing so will prevent Windows from being able to use the manifest file in an activation context) in initCommonControls()";
-
- ZeroMemory(&actctx, sizeof (ACTCTX));
- actctx.cbSize = sizeof (ACTCTX);
- actctx.dwFlags = ACTCTX_FLAG_SET_PROCESS_DEFAULT;
- actctx.lpSource = filename;
- ac = CreateActCtx(&actctx);
- if (ac == INVALID_HANDLE_VALUE)
- return "creating activation context for synthesized manifest file in initCommonControls()";
- if (ActivateActCtx(ac, &comctlManifestCookie) == FALSE)
- return "activating activation context for synthesized manifest file in initCommonControls()";
-
- ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX));
- icc.dwSize = sizeof (INITCOMMONCONTROLSEX);
- icc.dwICC = wantedICCClasses;
-
- comctl32 = LoadLibraryW(L"comctl32.dll");
- if (comctl32 == NULL)
- return "loading comctl32.dll in initCommonControls()";
-
- // GetProcAddress() only takes a multibyte string
-#define LOAD(fn) f = GetProcAddress(comctl32, fn); \
- if (f == NULL) \
- return "loading " fn "() in initCommonControls()";
-
- LOAD("InitCommonControlsEx");
- ficc = (BOOL (*WINAPI)(const LPINITCOMMONCONTROLSEX)) f;
- LOAD("SetWindowSubclass");
- fv_SetWindowSubclass = (BOOL (*WINAPI)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR)) f;
- LOAD("RemoveWindowSubclass");
- fv_RemoveWindowSubclass = (BOOL (*WINAPI)(HWND, SUBCLASSPROC, UINT_PTR)) f;
- LOAD("DefSubclassProc");
- fv_DefSubclassProc = (LRESULT (*WINAPI)(HWND, UINT, WPARAM, LPARAM)) f;
-
- if ((*ficc)(&icc) == FALSE)
- return "initializing Common Controls (comctl32.dll) in initCommonControls()";
-
- return NULL;
-}
diff --git a/new/windows/debug.c b/new/windows/debug.c
deleted file mode 100644
index bc84b63..0000000
--- a/new/windows/debug.c
+++ /dev/null
@@ -1,111 +0,0 @@
-// 25 february 2015
-#include "uipriv_windows.h"
-
-// uncomment the following line to enable debug messages
-#define tableDebug
-// uncomment the following line to halt on a debug message
-#define tableDebugStop
-
-#ifdef tableDebug
-
-#include <stdio.h>
-
-HRESULT logLastError(const char *context)
-{
- DWORD le;
- WCHAR *msg;
- BOOL parenthesize = FALSE;
- BOOL localFreeFailed = FALSE;
- DWORD localFreeLastError;
-
- le = GetLastError();
- fprintf(stderr, "%s: ", context);
- if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, le, 0, (LPWSTR) (&msg), 0, NULL) != 0) {
- fprintf(stderr, "%S (", msg);
- if (LocalFree(msg) != NULL) {
- localFreeFailed = TRUE;
- localFreeLastError = GetLastError();
- }
- parenthesize = TRUE;
- }
- fprintf(stderr, "GetLastError() == %I32u", le);
- if (parenthesize)
- fprintf(stderr, ")");
- if (localFreeFailed)
- fprintf(stderr, "; local free of system message failed with last error %I32u", localFreeLastError);
- fprintf(stderr, "\n");
-#ifdef tableDebugStop
- DebugBreak();
-#endif
- SetLastError(le);
- // a function does not have to set a last error
- // if the last error we get is actually 0, then HRESULT_FROM_WIN32(0) will return S_OK (0 cast to an HRESULT, since 0 <= 0), which we don't want
- // prevent this by returning E_FAIL, so the rest of the Table code doesn't barge onward
- if (le == 0)
- return E_FAIL;
- return HRESULT_FROM_WIN32(le);
-}
-
-HRESULT logHRESULT(const char *context, HRESULT hr)
-{
- WCHAR *msg;
- BOOL parenthesize = FALSE;
- BOOL localFreeFailed = FALSE;
- DWORD localFreeLastError;
-
- fprintf(stderr, "%s: ", context);
- // this isn't technically documented, but everyone does it, including Microsoft (see the implementation of _com_error::ErrorMessage() in a copy of comdef.h that comes with the Windows DDK)
- if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) hr, 0, (LPWSTR) (&msg), 0, NULL) != 0) {
- fprintf(stderr, "%S (", msg);
- if (LocalFree(msg) != NULL) {
- localFreeFailed = TRUE;
- localFreeLastError = GetLastError();
- }
- parenthesize = TRUE;
- }
- fprintf(stderr, "HRESULT == 0x%I32X", hr);
- if (parenthesize)
- fprintf(stderr, ")");
- if (localFreeFailed)
- fprintf(stderr, "; local free of system message failed with last error %I32u", localFreeLastError);
- fprintf(stderr, "\n");
-#ifdef tableDebugStop
- DebugBreak();
-#endif
- return hr;
-}
-
-HRESULT logMemoryExhausted(const char *reason)
-{
- fprintf(stderr, "memory exhausted %s\n", reason);
-#ifdef tableDebugStop
- DebugBreak();
-#endif
- return E_OUTOFMEMORY;
-}
-
-#else
-
-HRESULT logLastError(const char *reason)
-{
- DWORD le;
-
- le = GetLastError();
- // we shouldn't need to do this, but let's do this anyway just to be safe
- SetLastError(le);
- if (le == 0)
- return E_FAIL;
- return HRESULT_FROM_WIN32(le);
-}
-
-HRESULT logHRESULT(const char *reason, HRESULT hr)
-{
- return hr;
-}
-
-HRESULT logMemoryExhausted(const char *reason)
-{
- return E_OUTOFMEMORY;
-}
-
-#endif
diff --git a/new/windows/entry.c b/new/windows/entry.c
deleted file mode 100644
index 22c108a..0000000
--- a/new/windows/entry.c
+++ /dev/null
@@ -1,69 +0,0 @@
-// 8 april 2015
-#include "uipriv_windows.h"
-
-struct entry {
- uiEntry e;
-};
-
-static BOOL onWM_COMMAND(uiControl *c, WORD code, LRESULT *lResult)
-{
- return FALSE;
-}
-
-static BOOL onWM_NOTIFY(uiControl *c, NMHDR *nm, LRESULT *lResult)
-{
- return FALSE;
-}
-
-static void onWM_DESTROY(uiControl *c)
-{
- struct entry *e = (struct entry *) c;
-
- uiFree(e);
-}
-
-// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
-#define entryWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */
-#define entryHeight 14
-
-static void preferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- *width = uiDlgUnitsToX(entryWidth, d->sys->baseX);
- *height = uiDlgUnitsToY(entryHeight, d->sys->baseY);
-}
-
-static char *getText(uiEntry *e)
-{
- return uiWindowsControlText(uiControl(e));
-}
-
-static void setText(uiEntry *e, const char *text)
-{
- uiWindowsControlSetText(uiControl(e), text);
-}
-
-uiEntry *uiNewEntry(void)
-{
- struct entry *e;
- uiWindowsNewControlParams p;
-
- e = uiNew(struct entry);
-
- p.dwExStyle = WS_EX_CLIENTEDGE;
- p.lpClassName = L"edit";
- p.lpWindowName = L"";
- p.dwStyle = ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP;
- p.hInstance = hInstance;
- p.useStandardControlFont = TRUE;
- p.onWM_COMMAND = onWM_COMMAND;
- p.onWM_NOTIFY = onWM_NOTIFY;
- p.onWM_DESTROY = onWM_DESTROY;
- uiWindowsNewControl(uiControl(e), &p);
-
- uiControl(e)->PreferredSize = preferredSize;
-
- uiEntry(e)->Text = getText;
- uiEntry(e)->SetText = setText;
-
- return uiEntry(e);
-}
diff --git a/new/windows/init.c b/new/windows/init.c
deleted file mode 100644
index 9903934..0000000
--- a/new/windows/init.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// 6 april 2015
-#include "uipriv_windows.h"
-
-HINSTANCE hInstance;
-int nCmdShow;
-
-HFONT hMessageFont;
-
-HBRUSH hollowBrush;
-
-struct uiInitError {
- char *msg;
- char failbuf[256];
-};
-
-#define initErrorFormat L"error %s: %s%sGetLastError() == %I32u%s"
-#define initErrorArgs wmessage, sysmsg, beforele, le, afterle
-
-static const char *loadLastError(const char *message)
-{
- WCHAR *sysmsg;
- BOOL hassysmsg;
- WCHAR *beforele;
- WCHAR *afterle;
- int n;
- WCHAR *wmessage;
- WCHAR *wstr;
- const char *str;
- DWORD le;
-
- le = GetLastError();
- if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, le, 0, (LPWSTR) (&sysmsg), 0, NULL) != 0) {
- hassysmsg = TRUE;
- beforele = L" (";
- afterle = L")";
- } else {
- hassysmsg = FALSE;
- sysmsg = L"";
- beforele = L"";
- afterle = L"";
- }
- wmessage = toUTF16(message);
- n = _scwprintf(initErrorFormat, initErrorArgs);
- wstr = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]");
- snwprintf(wstr, n + 1, initErrorFormat, initErrorArgs);
- str = toUTF8(wstr);
- uiFree(wstr);
- if (hassysmsg)
- if (LocalFree(sysmsg) != NULL)
- logLastError("error freeing system message in loadLastError()");
- uiFree(wmessage);
- return str;
-}
-
-uiInitOptions options;
-
-const char *uiInit(uiInitOptions *o)
-{
- STARTUPINFOW si;
- const char *ce;
- HICON hDefaultIcon;
- HCURSOR hDefaultCursor;
- NONCLIENTMETRICSW ncm;
-
- options = *o;
-
- hInstance = GetModuleHandle(NULL);
- if (hInstance == NULL)
- return loadLastError("getting program HINSTANCE");
-
- nCmdShow = SW_SHOWDEFAULT;
- GetStartupInfoW(&si);
- if ((si.dwFlags & STARTF_USESHOWWINDOW) != 0)
- nCmdShow = si.wShowWindow;
-
- ce = initCommonControls();
- if (ce != NULL)
- return loadLastError(ce);
-
- hDefaultIcon = LoadIconW(NULL, IDI_APPLICATION);
- if (hDefaultIcon == NULL)
- return loadLastError("loading default icon for window classes");
- hDefaultCursor = LoadCursorW(NULL, IDC_ARROW);
- if (hDefaultCursor == NULL)
- return loadLastError("loading default cursor for window classes");
-
- if (registerWindowClass(hDefaultIcon, hDefaultCursor) == 0)
- return loadLastError("registering uiWindow window class");
-
- ZeroMemory(&ncm, sizeof (NONCLIENTMETRICSW));
- ncm.cbSize = sizeof (NONCLIENTMETRICSW);
- if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof (NONCLIENTMETRICSW), &ncm, sizeof (NONCLIENTMETRICSW)) == 0)
- return loadLastError("getting default fonts");
- hMessageFont = CreateFontIndirectW(&(ncm.lfMessageFont));
- if (hMessageFont == NULL)
- return loadLastError("loading default messagebox font; this is the default UI font");
-
- ce = initParent(hDefaultIcon, hDefaultCursor);
- if (ce != NULL)
- return loadLastError(ce);
-
- hollowBrush = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
- if (hollowBrush == NULL)
- return loadLastError("getting hollow brush");
-
- return NULL;
-}
-
-void uiFreeInitError(const char *err)
-{
- uiFree((void *) err);
-}
diff --git a/new/windows/label.c b/new/windows/label.c
deleted file mode 100644
index 29c03f7..0000000
--- a/new/windows/label.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// 11 april 2015
-#include "uipriv_windows.h"
-
-struct label {
- uiLabel l;
-};
-
-static BOOL onWM_COMMAND(uiControl *c, WORD code, LRESULT *lResult)
-{
- return FALSE;
-}
-
-static BOOL onWM_NOTIFY(uiControl *c, NMHDR *nm, LRESULT *lResult)
-{
- return FALSE;
-}
-
-static void onWM_DESTROY(uiControl *c)
-{
- struct label *l = (struct label *) c;
-
- uiFree(l);
-}
-
-// via http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
-#define labelHeight 8
-
-static void preferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- *width = uiWindowsWindowTextWidth(uiControlHWND(c));
- *height = uiDlgUnitsToY(labelHeight, d->sys->baseY);
-}
-
-static char *getText(uiLabel *l)
-{
- return uiWindowsControlText(uiControl(l));
-}
-
-static void setText(uiLabel *l, const char *text)
-{
- uiWindowsControlSetText(uiControl(l), text);
-}
-
-uiLabel *uiNewLabel(const char *text)
-{
- struct label *l;
- uiWindowsNewControlParams p;
- WCHAR *wtext;
-
- l = uiNew(struct label);
-
- p.dwExStyle = 0;
- p.lpClassName = L"static";
- wtext = toUTF16(text);
- p.lpWindowName = wtext;
- // SS_LEFTNOWORDWRAP clips text past the end; SS_NOPREFIX avoids accelerator translation
- // controls are vertically aligned to the top by default (thanks Xeek in irc.freenode.net/#winapi)
- p.dwStyle = SS_LEFTNOWORDWRAP | SS_NOPREFIX;
- p.hInstance = hInstance;
- p.useStandardControlFont = TRUE;
- p.onWM_COMMAND = onWM_COMMAND;
- p.onWM_NOTIFY = onWM_NOTIFY;
- p.onWM_DESTROY = onWM_DESTROY;
- uiWindowsNewControl(uiControl(l), &p);
- uiFree(wtext);
-
- uiControl(l)->PreferredSize = preferredSize;
-
- uiLabel(l)->Text = getText;
- uiLabel(l)->SetText = setText;
-
- return uiLabel(l);
-}
diff --git a/new/windows/main.c b/new/windows/main.c
deleted file mode 100644
index bd973b7..0000000
--- a/new/windows/main.c
+++ /dev/null
@@ -1,56 +0,0 @@
-// 6 april 2015
-#include "uipriv_windows.h"
-
-// #qo LDFLAGS: -luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32 -lcomdlg32 -lole32 -loleaut32 -loleacc -luuid
-
-static void uimsgloop_else(MSG *msg)
-{
- TranslateMessage(msg);
- DispatchMessage(msg);
-}
-
-void uiMain(void)
-{
- MSG msg;
- int res;
- HWND active, focus;
-
- for (;;) {
- SetLastError(0);
- res = GetMessageW(&msg, NULL, 0, 0);
- if (res < 0)
- logLastError("error calling GetMessage() in uiMain()");
- if (res == 0) // WM_QUIT
- break;
- active = GetActiveWindow();
- if (active == NULL) {
- uimsgloop_else(&msg);
- continue;
- }
-
- // bit of logic involved here:
- // we don't want dialog messages passed into Areas, so we don't call IsDialogMessageW() there
- // as for Tabs, we can't have both WS_TABSTOP and WS_EX_CONTROLPARENT set at the same time, so we hotswap the two styles to get the behavior we want
- focus = GetFocus();
- if (focus != NULL) {
-/*TODO switch (windowClassOf(focus, areaWindowClass, WC_TABCONTROLW, NULL)) {
- case 0: // areaWindowClass
- uimsgloop_area(active, focus, &msg);
- continue;
- case 1: // WC_TABCONTROLW
- uimsgloop_tab(active, focus, &msg);
- continue;
- }
- // else fall through
-*/ }
-
- if (IsDialogMessage(active, &msg) != 0)
- continue;
- uimsgloop_else(&msg);
- }
-}
-
-void uiQuit(void)
-{
- PostQuitMessage(0);
-}
diff --git a/new/windows/newcontrol.c b/new/windows/newcontrol.c
deleted file mode 100644
index 565ec05..0000000
--- a/new/windows/newcontrol.c
+++ /dev/null
@@ -1,237 +0,0 @@
-// 6 april 2015
-#include "uipriv_windows.h"
-
-typedef struct singleHWND singleHWND;
-
-struct singleHWND {
- HWND hwnd;
- BOOL (*onWM_COMMAND)(uiControl *, WORD, LRESULT *);
- BOOL (*onWM_NOTIFY)(uiControl *, NMHDR *, LRESULT *);
- void (*onWM_DESTROY)(uiControl *);
- uiParent *parent;
- BOOL userHid;
- BOOL containerHid;
- BOOL userDisabled;
- BOOL containerDisabled;
-};
-
-static void singleDestroy(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- if (DestroyWindow(s->hwnd) == 0)
- logLastError("error destroying control in singleDestroy()");
- // the data structures are destroyed in the subclass procedure
-}
-
-static uintptr_t singleHandle(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- return (uintptr_t) (s->hwnd);
-}
-
-static void singleSetParent(uiControl *c, uiParent *parent)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
- uiParent *oldparent;
- HWND newParentHWND;
-
- oldparent = s->parent;
- s->parent = parent;
- newParentHWND = initialParent;
- if (s->parent != NULL)
- newParentHWND = uiParentHWND(s->parent);
- if (SetParent(s->hwnd, newParentHWND) == NULL)
- logLastError("error setting control parent in singleSetParent()");
- if (oldparent != NULL)
- uiParentUpdate(oldparent);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- if (MoveWindow(s->hwnd, x, y, width, height, TRUE) == 0)
- logLastError("error moving control in singleResize()");
-}
-
-static int singleVisible(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- if (s->userHid)
- return 0;
- return 1;
-}
-
-static void singleShow(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->userHid = FALSE;
- if (!s->containerHid) {
- ShowWindow(s->hwnd, SW_SHOW);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void singleHide(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->userHid = TRUE;
- ShowWindow(s->hwnd, SW_HIDE);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void singleContainerShow(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->containerHid = FALSE;
- if (!s->userHid) {
- ShowWindow(s->hwnd, SW_SHOW);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
- }
-}
-
-static void singleContainerHide(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->containerHid = TRUE;
- ShowWindow(s->hwnd, SW_HIDE);
- if (s->parent != NULL)
- uiParentUpdate(s->parent);
-}
-
-static void singleEnable(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->userDisabled = FALSE;
- if (!s->containerDisabled)
- EnableWindow(s->hwnd, TRUE);
-}
-
-static void singleDisable(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->userDisabled = TRUE;
- EnableWindow(s->hwnd, FALSE);
-}
-
-static void singleContainerEnable(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->containerDisabled = FALSE;
- if (!s->userDisabled)
- EnableWindow(s->hwnd, TRUE);
-}
-
-static void singleContainerDisable(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
-
- s->containerDisabled = TRUE;
- EnableWindow(s->hwnd, FALSE);
-}
-
-static LRESULT CALLBACK singleSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
-{
- uiControl *c = (uiControl *) dwRefData;
- singleHWND *s = (singleHWND *) (c->Internal);
- LRESULT lResult;
-
- switch (uMsg) {
- case msgCOMMAND:
- if ((*(s->onWM_COMMAND))(c, HIWORD(wParam), &lResult) != FALSE)
- return lResult;
- break;
- case msgNOTIFY:
- if ((*(s->onWM_NOTIFY))(c, (NMHDR *) lParam, &lResult) != FALSE)
- return lResult;
- break;
- case WM_DESTROY:
- (*(s->onWM_DESTROY))(c);
- uiFree(s);
- break;
- case WM_NCDESTROY:
- if ((*fv_RemoveWindowSubclass)(hwnd, singleSubclassProc, uIdSubclass) == FALSE)
- logLastError("error removing Windows control subclass in singleSubclassProc()");
- break;
- }
- return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
-}
-
-void uiWindowsNewControl(uiControl *c, uiWindowsNewControlParams *p)
-{
- singleHWND *s;
-
- s = uiNew(singleHWND);
- s->hwnd = CreateWindowExW(p->dwExStyle,
- p->lpClassName, p->lpWindowName,
- p->dwStyle | WS_CHILD | WS_VISIBLE,
- 0, 0,
- // use a nonzero initial size just in case some control breaks with a zero initial size
- 100, 100,
- initialParent, NULL, p->hInstance, NULL);
- if (s->hwnd == NULL)
- logLastError("error creating control in uiWindowsNewControl()");
- s->onWM_COMMAND = p->onWM_COMMAND;
- s->onWM_NOTIFY = p->onWM_NOTIFY;
- s->onWM_DESTROY = p->onWM_DESTROY;
-
- c->Destroy = singleDestroy;
- c->Handle = singleHandle;
- c->SetParent = singleSetParent;
- c->Resize = singleResize;
- c->Visible = singleVisible;
- c->Show = singleShow;
- c->Hide = singleHide;
- c->ContainerShow = singleContainerShow;
- c->ContainerHide = singleContainerHide;
- c->Enable = singleEnable;
- c->Disable = singleDisable;
- c->ContainerEnable = singleContainerEnable;
- c->ContainerDisable = singleContainerDisable;
-
- if (p->useStandardControlFont)
- SendMessageW(s->hwnd, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE);
-
- if ((*fv_SetWindowSubclass)(s->hwnd, singleSubclassProc, 0, (DWORD_PTR) c) == FALSE)
- logLastError("error subclassing Windows control in uiWindowsNewControl()");
-
- c->Internal = s;
-}
-
-char *uiWindowsControlText(uiControl *c)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
- WCHAR *wtext;
- char *text;
-
- wtext = windowText(s->hwnd);
- text = toUTF8(wtext);
- uiFree(wtext);
- return text;
-}
-
-void uiWindowsControlSetText(uiControl *c, const char *text)
-{
- singleHWND *s = (singleHWND *) (c->Internal);
- WCHAR *wtext;
-
- wtext = toUTF16(text);
- if (SetWindowTextW(s->hwnd, wtext) == 0)
- logLastError("error setting control text in uiWindowsControlSetText()");
- uiFree(wtext);
-}
diff --git a/new/windows/parent.c b/new/windows/parent.c
deleted file mode 100644
index b3606d1..0000000
--- a/new/windows/parent.c
+++ /dev/null
@@ -1,268 +0,0 @@
-// 10 april 2015
-#include "uipriv_windows.h"
-
-// All controls in package ui are children of a window of this class.
-// This keeps everything together, makes hiding controls en masse (tab page switching, for instance) easy, and makes the overall design cleaner.
-// In addition, controls that are first created or don't have a parent are considered children of the "initial parent", which is also of this class.
-// This parent is invisible, disabled, and should not be interacted with.
-
-// TODOs
-// - wiith CTLCOLOR handler: [12:24] <ZeroOne> There's flickering between tabs
-// - with CTLCOLOR handler: [12:24] <ZeroOne> And setting the button text blanked out the entire GUI until I ran my mouse over the elements / [12:25] <ZeroOne> https://dl.dropboxusercontent.com/u/15144168/GUI%20stuff.png / [12:41] <ZeroOne> https://dl.dropboxusercontent.com/u/15144168/stack.png here have another screenshot
-// - I get this too
-
-#define uiParentClass L"uiParentClass"
-
-HWND initialParent;
-
-static void paintControlBackground(HWND hwnd, HDC dc)
-{
- HWND parent;
- RECT r;
- POINT pOrig;
- DWORD le;
-
- parent = hwnd;
- for (;;) {
- parent = GetParent(parent);
- if (parent == NULL)
- logLastError("error getting parent control of control in paintControlBackground()");
- // wine sends these messages early, yay...
- if (parent == initialParent)
- return;
- // skip groupboxes; they're (supposed to be) transparent
- if (windowClassOf(parent, L"button", NULL) != 0)
- break;
- }
- if (GetWindowRect(hwnd, &r) == 0)
- logLastError("error getting control's window rect in paintControlBackground()");
- // the above is a window rect in screen coordinates; convert to parent coordinates
- SetLastError(0);
- if (MapWindowRect(NULL, parent, &r) == 0) {
- le = GetLastError();
- SetLastError(le); // just to be safe
- if (le != 0)
- logLastError("error getting client origin of control in paintControlBackground()");
- }
- if (SetWindowOrgEx(dc, r.left, r.top, &pOrig) == 0)
- logLastError("error moving window origin in paintControlBackground()");
- SendMessageW(parent, WM_PRINTCLIENT, (WPARAM) dc, PRF_CLIENT);
- if (SetWindowOrgEx(dc, pOrig.x, pOrig.y, NULL) == 0)
- logLastError("error resetting window origin in paintControlBackground()");
-}
-
-// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing and https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx
-// this X value is really only for buttons but I don't see a better one :/
-#define winXPadding 4
-#define winYPadding 4
-
-static void resize(uiControl *control, HWND parent, RECT r, RECT margin)
-{
- uiSizing d;
- uiSizingSys sys;
- HDC dc;
- HFONT prevfont;
- TEXTMETRICW tm;
- SIZE size;
-
- size.cx = 0;
- size.cy = 0;
- ZeroMemory(&tm, sizeof (TEXTMETRICW));
- dc = GetDC(parent);
- if (dc == NULL)
- logLastError("error getting DC in resize()");
- prevfont = (HFONT) SelectObject(dc, hMessageFont);
- if (prevfont == NULL)
- logLastError("error loading control font into device context in resize()");
- if (GetTextMetricsW(dc, &tm) == 0)
- logLastError("error getting text metrics in resize()");
- if (GetTextExtentPoint32W(dc, L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &size) == 0)
- logLastError("error getting text extent point in resize()");
- sys.baseX = (int) ((size.cx / 26 + 1) / 2);
- sys.baseY = (int) tm.tmHeight;
- sys.internalLeading = tm.tmInternalLeading;
- if (SelectObject(dc, prevfont) != hMessageFont)
- logLastError("error restoring previous font into device context in resize()");
- if (ReleaseDC(parent, dc) == 0)
- logLastError("error releasing DC in resize()");
- r.left += uiDlgUnitsToX(margin.left, sys.baseX);
- r.top += uiDlgUnitsToY(margin.top, sys.baseY);
- r.right -= uiDlgUnitsToX(margin.right, sys.baseX);
- r.bottom -= uiDlgUnitsToY(margin.bottom, sys.baseY);
- d.xPadding = uiDlgUnitsToX(winXPadding, sys.baseX);
- d.yPadding = uiDlgUnitsToY(winYPadding, sys.baseY);
- d.sys = &sys;
- uiControlResize(control, r.left, r.top, r.right - r.left, r.bottom - r.top, &d);
-}
-
-struct parent {
- HWND hwnd;
- uiControl *child;
- intmax_t marginLeft;
- intmax_t marginTop;
- intmax_t marginRight;
- intmax_t marginBottom;
-};
-
-static LRESULT CALLBACK parentWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- uiParent *p;
- struct parent *pp;
- CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
- HWND control;
- NMHDR *nm = (NMHDR *) lParam;
- WINDOWPOS *wp = (WINDOWPOS *) lParam;
- RECT r, margin;
-
- // these must always be executed, even on the initial parent
- // why? http://blogs.msdn.com/b/oldnewthing/archive/2010/03/16/9979112.aspx
- switch (uMsg) {
- case WM_COMMAND:
- // bounce back to the control in question
- // except if to the initial parent, in which case act as if the message was ignored
- control = (HWND) lParam;
- if (control != NULL && IsChild(initialParent, control) == 0)
- return SendMessageW(control, msgCOMMAND, wParam, lParam);
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case WM_NOTIFY:
- // same as WM_COMMAND
- control = nm->hwndFrom;
- if (control != NULL && IsChild(initialParent, control) == 0)
- return SendMessageW(control, msgNOTIFY, wParam, lParam);
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case WM_CTLCOLORSTATIC:
- case WM_CTLCOLORBTN:
-/*TODO // read-only TextFields and Textboxes are exempt
- // this is because read-only edit controls count under WM_CTLCOLORSTATIC
- if (windowClassOf((HWND) lParam, L"edit", NULL) == 0)
- if (textfieldReadOnly((HWND) lParam))
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
-*/ if (SetBkMode((HDC) wParam, TRANSPARENT) == 0)
- logLastError("error setting transparent background mode to controls in parentWndProc()");
- paintControlBackground((HWND) lParam, (HDC) wParam);
- return (LRESULT) hollowBrush;
- }
-
- // these are only executed on actual parents
- p = (uiParent *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
- if (p == NULL) {
- if (uMsg == WM_NCCREATE) {
- p = (uiParent *) (cs->lpCreateParams);
- // this will be NULL for the initial parent; that's what we want
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) p);
- // fall through to DefWindowProcW()
- }
- // this is the return the initial parent will always use
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- }
- pp = (struct parent *) (p->Internal);
- switch (uMsg) {
- case WM_NCDESTROY:
- // no need to explicitly destroy children; they're already gone by this point (and so are their data structures; they clean up after themselves)
- uiFree(p->Internal);
- uiFree(p);
- break; // fall through to DefWindowPocW()
- case WM_WINDOWPOSCHANGED:
- if ((wp->flags & SWP_NOSIZE) != 0)
- break;
- // fall through
- case msgUpdateChild:
- if (pp->child == NULL)
- break;
- if (GetClientRect(pp->hwnd, &r) == 0)
- logLastError("error getting client rect for resize in parentWndProc()");
- margin.left = pp->marginLeft;
- margin.top = pp->marginTop;
- margin.right = pp->marginRight;
- margin.bottom = pp->marginBottom;
- resize(pp->child, pp->hwnd, r, margin);
- return 0;
- }
-
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
-}
-
-const char *initParent(HICON hDefaultIcon, HCURSOR hDefaultCursor)
-{
- WNDCLASSW wc;
-
- ZeroMemory(&wc, sizeof (WNDCLASSW));
- wc.lpszClassName = uiParentClass;
- wc.lpfnWndProc = parentWndProc;
- wc.hInstance = hInstance;
- wc.hIcon = hDefaultIcon;
- wc.hCursor = hDefaultCursor;
- wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
- if (RegisterClassW(&wc) == 0)
- return "registering parent window class";
-
- initialParent = CreateWindowExW(0,
- uiParentClass, L"",
- WS_OVERLAPPEDWINDOW,
- 0, 0,
- 100, 100,
- NULL, NULL, hInstance, NULL);
- if (initialParent == NULL)
- return "creating initial parent window";
-
- // just to be safe, disable the initial parent so it can't be interacted with accidentally
- // if this causes issues for our controls, we can remove it
- EnableWindow(initialParent, FALSE);
- return NULL;
-}
-
-static uintptr_t parentHandle(uiParent *p)
-{
- struct parent *pp = (struct parent *) (p->Internal);
-
- return (uintptr_t) (pp->hwnd);
-}
-
-static void parentSetChild(uiParent *p, uiControl *child)
-{
- struct parent *pp = (struct parent *) (p->Internal);
-
- pp->child = child;
- if (pp->child != NULL)
- uiControlSetParent(child, p);
-}
-
-static void parentSetMargins(uiParent *p, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
-{
- struct parent *pp = (struct parent *) (p->Internal);
-
- pp->marginLeft = left;
- pp->marginTop = top;
- pp->marginRight = right;
- pp->marginBottom = bottom;
-}
-
-static void parentUpdate(uiParent *p)
-{
- struct parent *pp = (struct parent *) (p->Internal);
-
- SendMessageW(pp->hwnd, msgUpdateChild, 0, 0);
-}
-
-uiParent *uiNewParent(uintptr_t osParent)
-{
- uiParent *p;
- struct parent *pp;
-
- p = uiNew(uiParent);
- p->Internal = uiNew(struct parent); // set now in case the parent class window procedure uses it
- pp = (struct parent *) (p->Internal);
- pp->hwnd = CreateWindowExW(0,
- uiParentClass, L"",
- WS_CHILD | WS_VISIBLE,
- 0, 0,
- 0, 0,
- (HWND) osParent, NULL, hInstance, p);
- if (pp->hwnd == NULL)
- logLastError("error creating uiParent window in uiNewParent()");
- p->Handle = parentHandle;
- p->SetChild = parentSetChild;
- p->SetMargins = parentSetMargins;
- p->Update = parentUpdate;
- return p;
-}
diff --git a/new/windows/tab.c b/new/windows/tab.c
deleted file mode 100644
index d2cbd62..0000000
--- a/new/windows/tab.c
+++ /dev/null
@@ -1,190 +0,0 @@
-// 12 april 2015
-#include "uipriv_windows.h"
-
-// TODO
-// - tab change notifications aren't being sent on wine (anymore...? TODO)
-// - tell wine developers that tab controls do respond to parent changes on real windows (at least comctl6 tab controls do)
-
-struct tab {
- uiTab t;
- uiParent **pages;
- uintmax_t len;
- uintmax_t cap;
-};
-
-static BOOL onWM_COMMAND(uiControl *c, WORD code, LRESULT *lResult)
-{
- return FALSE;
-}
-
-// we have to handle hiding and showing of tab pages ourselves
-static BOOL onWM_NOTIFY(uiControl *c, NMHDR *nm, LRESULT *lResult)
-{
- struct tab *t = (struct tab *) c;
- LRESULT n;
-
- switch (nm->code) {
- case TCN_SELCHANGING:
- n = SendMessageW(uiControlHWND(c), TCM_GETCURSEL, 0, 0);
- if (n != (LRESULT) (-1)) // if we're changing to a real tab
- ShowWindow(uiParentHWND(t->pages[n]), SW_HIDE);
- *lResult = FALSE; // and allow the change
- return TRUE;
- case TCN_SELCHANGE:
- n = SendMessageW(uiControlHWND(c), TCM_GETCURSEL, 0, 0);
- if (n != (LRESULT) (-1)) { // if we're changing to a real tab
- ShowWindow(uiParentHWND(t->pages[n]), SW_SHOW);
- // because we only resize the current child on resize, we'll need to trigger an update here
- // don't call uiParentUpdate(); doing that won't size the content area (so we'll still have a 0x0 content area, for instance)
- SendMessageW(uiControlHWND(c), msgUpdateChild, 0, 0);
- }
- *lResult = 0;
- return TRUE;
- }
- return FALSE;
-}
-
-static void onWM_DESTROY(uiControl *c)
-{
- struct tab *t = (struct tab *) c;
-
- // no need to worry about freeing the pages themselves; they'll destroy themselves after we return
- uiFree(t->pages);
- uiFree(t);
-}
-
-static void preferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- // TODO
-}
-
-// common code for resizes
-static void resizeTab(uiControl *c, LONG width, LONG height)
-{
- struct tab *t = (struct tab *) c;
- HWND hwnd;
- LRESULT n;
- RECT r;
-
- hwnd = uiControlHWND(c);
-
- n = SendMessageW(hwnd, TCM_GETCURSEL, 0, 0);
- if (n == (LRESULT) (-1)) // no child selected; do nothing
- return;
-
- // make a rect at (0, 0) of the given window size
- // this should give us the correct client coordinates
- r.left = 0;
- r.top = 0;
- r.right = width;
- r.bottom = height;
- // convert to the display rectangle
- SendMessageW(hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM) (&r));
-
- if (MoveWindow(uiParentHWND(t->pages[n]), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE) == 0)
- logLastError("error resizing current tab page in resizeTab()");
-}
-
-// and finally, because we have to resize parents, we have to handle resizes and updates
-static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
-{
- uiControl *c = (uiControl *) dwRefData;
- WINDOWPOS *wp = (WINDOWPOS *) lParam;
- LRESULT lResult;
- RECT r;
-
- switch (uMsg) {
- case WM_WINDOWPOSCHANGED:
- if ((wp->flags & SWP_NOSIZE) != 0)
- break;
- // first, let the tab control handle it
- lResult = (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
- // we have the window rect width as part of the WINDOWPOS; resize
- resizeTab(c, wp->cx, wp->cy);
- return lResult;
- case msgUpdateChild:
- if (GetWindowRect(uiControlHWND(c), &r) == 0)
- logLastError("error getting Tab window rect for synthesized resize message in tabSubProc()");
- // these are in screen coordinates, which match what WM_WINDOWPOSCHANGED gave us (thanks TODOTODOTODOTODOTODOTODOTODO)
- resizeTab(c, r.right - r.left, r.bottom - r.top);
- return 0;
- case WM_NCDESTROY:
- if ((*fv_RemoveWindowSubclass)(hwnd, tabSubProc, uIdSubclass) == FALSE)
- logLastError("error removing Tab resize handling subclass in tabSubProc()");
- break;
- }
- return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
-}
-
-#define tabCapGrow 32
-
-void addPage(uiTab *tt, const char *name, uiControl *child)
-{
- struct tab *t = (struct tab *) tt;
- HWND hwnd;
- TCITEMW item;
- LRESULT n;
- uiParent *parent;
- WCHAR *wname;
-
- if (t->len >= t->cap) {
- t->cap += tabCapGrow;
- t->pages = (uiParent **) uiRealloc(t->pages, t->cap * sizeof (uiParent *), "uiParent *[]");
- }
-
- hwnd = uiControlHWND(uiControl(t));
- n = SendMessageW(hwnd, TCM_GETITEMCOUNT, 0, 0);
-
- parent = uiNewParent((uintptr_t) hwnd);
- uiParentSetChild(parent, child);
- uiParentUpdate(parent);
- if (n != 0) // if this isn't the first page, we have to hide the other controls
- ShowWindow(uiParentHWND(parent), SW_HIDE);
- t->pages[t->len] = parent;
- t->len++;
-
- ZeroMemory(&item, sizeof (TCITEMW));
- item.mask = TCIF_TEXT;
- wname = toUTF16(name);
- item.pszText = wname;
- // MSDN's example code uses the first invalid index directly for this
- if (SendMessageW(hwnd, TCM_INSERTITEM, (WPARAM) n, (LPARAM) (&item)) == (LRESULT) -1)
- logLastError("error adding tab to Tab in uiTabAddPage()");
- uiFree(wname);
-
- // if this is the first tab, Windows will automatically show it /without/ sending a TCN_SELCHANGE notification
- // (TODO verify that)
- // so we need to manually resize the tab ourselves
- // don't use uiUpdateParent() for the same reason as in the TCN_SELCHANGE handler
- SendMessageW(hwnd, msgUpdateChild, 0, 0);
-}
-
-uiTab *uiNewTab(void)
-{
- struct tab *t;
- uiWindowsNewControlParams p;
- HWND hwnd;
-
- t = uiNew(struct tab);
-
- p.dwExStyle = 0; // don't set WS_EX_CONTROLPARENT yet; we do that dynamically in the message loop (see main_windows.c)
- p.lpClassName = WC_TABCONTROLW;
- p.lpWindowName = L"";
- p.dwStyle = TCS_TOOLTIPS | WS_TABSTOP;
- p.hInstance = hInstance;
- p.useStandardControlFont = TRUE;
- p.onWM_COMMAND = onWM_COMMAND;
- p.onWM_NOTIFY = onWM_NOTIFY;
- p.onWM_DESTROY = onWM_DESTROY;
- uiWindowsNewControl(uiControl(t), &p);
-
- hwnd = uiControlHWND(uiControl(t));
- if ((*fv_SetWindowSubclass)(hwnd, tabSubProc, 0, (DWORD_PTR) t) == FALSE)
- logLastError("error subclassing Tab to give it its own resize handler in uiNewTab()");
-
- uiControl(t)->PreferredSize = preferredSize;
-
- uiTab(t)->AddPage = addPage;
-
- return uiTab(t);
-}
diff --git a/new/windows/text.c b/new/windows/text.c
deleted file mode 100644
index 8d6d0b0..0000000
--- a/new/windows/text.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// 9 april 2015
-#include "uipriv_windows.h"
-
-// see http://stackoverflow.com/a/29556509/3408572
-
-#define MBTWC(str, wstr, bufsiz) MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, bufsiz)
-
-WCHAR *toUTF16(const char *str)
-{
- WCHAR *wstr;
- int n;
-
- n = MBTWC(str, NULL, 0);
- if (n == 0)
- logLastError("error figuring out number of characters to convert to in toUTF16()");
- wstr = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]");
- if (MBTWC(str, wstr, n) != n)
- logLastError("error converting from UTF-8 to UTF-16 in toUTF16()");
- return wstr;
-}
-
-#define WCTMB(wstr, str, bufsiz) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, bufsiz, NULL, NULL)
-
-char *toUTF8(const WCHAR *wstr)
-{
- char *str;
- int n;
-
- n = WCTMB(wstr, NULL, 0);
- if (n == 0)
- logLastError("error figuring out number of characters to convert to in toUTF8()");
- str = (char *) uiAlloc(n * sizeof (char), "char[]");
- if (WCTMB(wstr, str, n) != n)
- logLastError("error converting from UTF-16 to UTF-8 in toUTFF8()");
- return str;
-}
-
-WCHAR *windowText(HWND hwnd)
-{
- LRESULT n;
- WCHAR *text;
-
- n = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
- // WM_GETTEXTLENGTH does not include the null terminator
- text = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]");
- // note the comparison: the size includes the null terminator, but the return does not
- if (GetWindowTextW(hwnd, text, n + 1) != n)
- logLastError("error getting window text in windowText()");
- return text;
-}
-
-void uiFreeText(char *text)
-{
- uiFree(text);
-}
diff --git a/new/windows/uipriv_windows.h b/new/windows/uipriv_windows.h
deleted file mode 100644
index 4ba0f5a..0000000
--- a/new/windows/uipriv_windows.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// 6 january 2015
-#define UNICODE
-#define _UNICODE
-#define STRICT
-#define STRICT_TYPED_ITEMIDS
-#define CINTERFACE
-#define COBJMACROS
-// see https://github.com/golang/go/issues/9916#issuecomment-74812211
-#define INITGUID
-// get Windows version right; right now Windows XP
-#define WINVER 0x0501
-#define _WIN32_WINNT 0x0501
-#define _WIN32_WINDOWS 0x0501 /* according to Microsoft's winperf.h */
-#define _WIN32_IE 0x0600 /* according to Microsoft's sdkddkver.h */
-#define NTDDI_VERSION 0x05010000 /* according to Microsoft's sdkddkver.h */
-#include <windows.h>
-#include <commctrl.h>
-#include <stdint.h>
-#include <uxtheme.h>
-#include <string.h>
-#include <wchar.h>
-#include <windowsx.h>
-#include <vsstyle.h>
-#include <vssym32.h>
-#include <stdarg.h>
-#include <oleacc.h>
-#include <stdio.h>
-#include "../uipriv.h"
-#include "../ui_windows.h"
-
-// ui internal window messages
-enum {
- // redirected WM_COMMAND and WM_NOTIFY
- msgCOMMAND = WM_APP + 0x40, // start offset just to be safe
- msgNOTIFY,
- msgUpdateChild, // fake because Windows seems to SWP_NOSIZE MoveWindow()s and SetWindowPos()s that don't change the window size (even if SWP_NOSIZE isn't specified)
-};
-
-// debug_windows.c
-extern HRESULT logLastError(const char *);
-extern HRESULT logHRESULT(const char *, HRESULT);
-extern HRESULT logMemoryExhausted(const char *);
-
-// init_windows.c
-extern HINSTANCE hInstance;
-extern int nCmdShow;
-extern HFONT hMessageFont;
-extern HBRUSH hollowBrush;
-
-// util_windows.c
-extern int windowClassOf(HWND, ...);
-
-// text_windows.c
-extern WCHAR *toUTF16(const char *);
-extern char *toUTF8(const WCHAR *);
-extern WCHAR *windowText(HWND);
-
-// comctl32_windows.c
-extern BOOL (*WINAPI fv_SetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
-extern BOOL (*WINAPI fv_RemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
-extern LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
-extern const char *initCommonControls(void);
-
-// window_windows.c
-extern ATOM registerWindowClass(HICON, HCURSOR);
-
-// parent_windows.c
-extern HWND initialParent;
-extern const char *initParent(HICON, HCURSOR);
diff --git a/new/windows/util.c b/new/windows/util.c
deleted file mode 100644
index 93b32d8..0000000
--- a/new/windows/util.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// 6 april 2015
-#include "uipriv_windows.h"
-
-intmax_t uiWindowsWindowTextWidth(HWND hwnd)
-{
- LRESULT len;
- WCHAR *text;
- HDC dc;
- HFONT prevfont;
- SIZE size;
-
- size.cx = 0;
- size.cy = 0;
-
- // first we need the window text
- len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
- if (len == 0) // no text; nothing to do
- return 0;
- text = (WCHAR *) uiAlloc((len + 1) * sizeof (WCHAR), "WCHAR[]");
- // note the comparison: the size includes the null terminator, but the return does not
- if (GetWindowText(hwnd, text, len + 1) != len)
- logLastError("error getting window text in uiWindowsWindowTextWidth()");
-
- // now we can do the calculations
- dc = GetDC(hwnd);
- if (dc == NULL)
- logLastError("error getting DC in uiWindowsWindowTextWidth()");
- prevfont = (HFONT) SelectObject(dc, hMessageFont);
- if (prevfont == NULL)
- logLastError("error loading control font into device context in uiWindowsWindowTextWidth()");
- if (GetTextExtentPoint32W(dc, text, len, &size) == 0)
- logLastError("error getting text extent point in uiWindowsWindowTextWidth()");
- if (SelectObject(dc, prevfont) != hMessageFont)
- logLastError("error restoring previous font into device context in uiWindowsWindowTextWidth()");
- if (ReleaseDC(hwnd, dc) == 0)
- logLastError("error releasing DC in uiWindowsWindowTextWidth()");
- uiFree(text);
-
- return size.cx;
-}
-
-// this is a helper function that takes the logic of determining window classes and puts it all in one place
-// there are a number of places where we need to know what window class an arbitrary handle has
-// theoretically we could use the class atom to avoid a _wcsicmp()
-// however, raymond chen advises against this - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/11/240744.aspx (and we're not in control of the Tab class, before you say anything)
-// usage: windowClassOf(hwnd, L"class 1", L"class 2", ..., NULL)
-int windowClassOf(HWND hwnd, ...)
-{
-// MSDN says 256 is the maximum length of a class name; add a few characters just to be safe (because it doesn't say whether this includes the terminating null character)
-#define maxClassName 260
- WCHAR classname[maxClassName + 1];
- va_list ap;
- WCHAR *curname;
- int i;
-
- if (GetClassNameW(hwnd, classname, maxClassName) == 0)
- logLastError("error getting name of window class in windowClassOf()");
- va_start(ap, hwnd);
- i = 0;
- for (;;) {
- curname = va_arg(ap, WCHAR *);
- if (curname == NULL)
- break;
- if (_wcsicmp(classname, curname) == 0) {
- va_end(ap);
- return i;
- }
- i++;
- }
- // no match
- va_end(ap);
- return -1;
-}
diff --git a/new/windows/window.c b/new/windows/window.c
deleted file mode 100644
index e9360eb..0000000
--- a/new/windows/window.c
+++ /dev/null
@@ -1,216 +0,0 @@
-// 6 april 2015
-#include "uipriv_windows.h"
-
-struct window {
- uiWindow w;
- HWND hwnd;
- uiParent *content;
- BOOL shownOnce;
- int (*onClosing)(uiWindow *, void *);
- void *onClosingData;
- int margined;
-};
-
-#define uiWindowClass L"uiWindowClass"
-
-static LRESULT CALLBACK uiWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- struct window *w;
- CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
- WINDOWPOS *wp = (WINDOWPOS *) lParam;
- RECT r;
- HWND contenthwnd;
-
- w = (struct window *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
- if (w == NULL) {
- if (uMsg == WM_CREATE)
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (cs->lpCreateParams));
- // fall through to DefWindowProc() anyway
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- }
- switch (uMsg) {
- case WM_WINDOWPOSCHANGED:
- if ((wp->flags & SWP_NOSIZE) != 0)
- break;
- // fall through
- case msgUpdateChild:
- if (GetClientRect(w->hwnd, &r) == 0)
- logLastError("error getting window client rect for resize in uiWindowWndProc()");
- contenthwnd = uiParentHWND(w->content);
- if (MoveWindow(contenthwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE) == 0)
- logLastError("error resizing window content parent in uiWindowWndProc()");
- return 0;
- case WM_CLOSE:
- if (!(*(w->onClosing))(uiWindow(w), w->onClosingData))
- return 0;
- break; // fall through to DefWindowProcW()
- case WM_DESTROY:
- // no need to free the child ourselves; it'll destroy itself after we leave this handler
- uiFree(w);
- break; // fall through to DefWindowProcW()
- }
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
-}
-
-ATOM registerWindowClass(HICON hDefaultIcon, HCURSOR hDefaultCursor)
-{
- WNDCLASSW wc;
-
- ZeroMemory(&wc, sizeof (WNDCLASSW));
- wc.lpszClassName = uiWindowClass;
- wc.lpfnWndProc = uiWindowWndProc;
- wc.hInstance = hInstance;
- wc.hIcon = hDefaultIcon;
- wc.hCursor = hDefaultCursor;
- wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
- return RegisterClassW(&wc);
-}
-
-#define exstyle 0
-#define style WS_OVERLAPPEDWINDOW
-
-static int defaultOnClosing(uiWindow *w, void *data)
-{
- return 1;
-}
-
-static void windowDestroy(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- DestroyWindow(w->hwnd);
-}
-
-static uintptr_t windowHandle(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- return (uintptr_t) (w->hwnd);
-}
-
-static char *windowTitle(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
- WCHAR *wtext;
- char *text;
-
- wtext = windowText(w->hwnd);
- text = toUTF8(wtext);
- uiFree(wtext);
- return text;
-}
-
-static void windowSetTitle(uiWindow *ww, const char *text)
-{
- struct window *w = (struct window *) ww;
- WCHAR *wtext;
-
- wtext = toUTF16(text);
- if (SetWindowTextW(w->hwnd, wtext) == 0)
- logLastError("error setting window title in uiWindowSetTitle()");
- uiFree(wtext);
-}
-
-static void windowShow(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- if (w->shownOnce) {
- ShowWindow(w->hwnd, SW_SHOW);
- return;
- }
- w->shownOnce = TRUE;
- ShowWindow(w->hwnd, nCmdShow);
- if (UpdateWindow(w->hwnd) == 0)
- logLastError("error calling UpdateWindow() after showing uiWindow for the first time");
-}
-
-static void windowHide(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- ShowWindow(w->hwnd, SW_HIDE);
-}
-
-static void windowOnClosing(uiWindow *ww, int (*f)(uiWindow *, void *), void *data)
-{
- struct window *w = (struct window *) ww;
-
- w->onClosing = f;
- w->onClosingData = data;
-}
-
-static void windowSetChild(uiWindow *ww, uiControl *c)
-{
- struct window *w = (struct window *) ww;
-
- uiParentSetChild(w->content, c);
- // don't call uiParentUpdate(); instead, synthesize a resize
- // otherwise, we'll have a 0x0 content area at first
- SendMessageW(w->hwnd, msgUpdateChild, 0, 0);
-}
-
-static int windowMargined(uiWindow *ww)
-{
- struct window *w = (struct window *) ww;
-
- return w->margined;
-}
-
-// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
-#define windowMargin 7
-
-static void windowSetMargined(uiWindow *ww, int margined)
-{
- struct window *w = (struct window *) ww;
-
- w->margined = margined;
- if (w->margined)
- uiParentSetMargins(w->content, windowMargin, windowMargin, windowMargin, windowMargin);
- else
- uiParentSetMargins(w->content, 0, 0, 0, 0);
- uiParentUpdate(w->content);
-}
-
-uiWindow *uiNewWindow(const char *title, int width, int height)
-{
- struct window *w;
- RECT adjust;
- WCHAR *wtitle;
-
- w = uiNew(struct window);
- w->onClosing = defaultOnClosing;
-
- adjust.left = 0;
- adjust.top = 0;
- adjust.right = width;
- adjust.bottom = height;
- if (AdjustWindowRectEx(&adjust, style, FALSE, exstyle) == 0)
- logLastError("error getting real window coordinates in uiWindow()");
-
- wtitle = toUTF16(title);
- w->hwnd = CreateWindowExW(exstyle,
- uiWindowClass, wtitle,
- style,
- CW_USEDEFAULT, CW_USEDEFAULT,
- adjust.right - adjust.left, adjust.bottom - adjust.top,
- NULL, NULL, hInstance, w);
- if (w->hwnd == NULL)
- logLastError("error creating window in uiWindow()");
- uiFree(wtitle);
-
- w->content = uiNewParent((uintptr_t) (w->hwnd));
-
- uiWindow(w)->Destroy = windowDestroy;
- uiWindow(w)->Handle = windowHandle;
- uiWindow(w)->Title = windowTitle;
- uiWindow(w)->SetTitle = windowSetTitle;
- uiWindow(w)->Show = windowShow;
- uiWindow(w)->Hide = windowHide;
- uiWindow(w)->OnClosing = windowOnClosing;
- uiWindow(w)->SetChild = windowSetChild;
- uiWindow(w)->Margined = windowMargined;
- uiWindow(w)->SetMargined = windowSetMargined;
-
- return uiWindow(w);
-}