libui/macarea/alt/area.m

243 lines
6.0 KiB
Objective-C

// 9 september 2015
#include "area.h"
// TODO remove this
void addConstraint(NSView *view, NSString *constraint, NSDictionary *metrics, NSDictionary *views)
{
NSArray *constraints;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraint
options:0
metrics:metrics
views:views];
[view addConstraints:constraints];
}
// NSScrollers have no intrinsic size; here we give it one
@interface areaScroller : NSScroller {
BOOL libui_vertical;
}
- (id)initWithFrame:(NSRect)r vertical:(BOOL)v;
@end
@implementation areaScroller
- (id)initWithFrame:(NSRect)r vertical:(BOOL)v
{
self = [super initWithFrame:r];
if (self)
self->libui_vertical = v;
return self;
}
- (NSSize)intrinsicContentSize
{
NSSize s;
CGFloat scrollerWidth;
s = [super intrinsicContentSize];
scrollerWidth = [NSScroller scrollerWidthForControlSize:[self controlSize]
scrollerStyle:[self scrollerStyle]];
if (self->libui_vertical)
s.width = scrollerWidth;
else
s.height = scrollerWidth;
return s;
}
- (void)setControlSize:(NSControlSize)size
{
[super setControlSize:size];
[self invalidateIntrinsicContentSize];
}
- (void)setScrollerStyle:(NSScrollerStyle)style
{
[super setScrollerStyle:style];
[self invalidateIntrinsicContentSize];
}
@end
@interface areaDrawingView : NSView {
uiArea *libui_a;
}
- (id)initWithFrame:(NSRect)r area:(uiArea *)a;
@end
@interface areaView : NSView {
uiArea *libui_a;
areaDrawingView *drawingView;
areaScroller *hscrollbar;
areaScroller *vscrollbar;
}
- (id)initWithFrame:(NSRect)r area:(uiArea *)a;
@end
struct uiArea {
// uiDarwinControl c;
areaView *view;
uiAreaHandler *ah;
};
@implementation areaDrawingView
- (id)initWithFrame:(NSRect)r area:(uiArea *)a
{
self = [super initWithFrame:r];
if (self)
self->libui_a = a;
return self;
}
- (void)drawRect:(NSRect)r
{
CGContextRef c;
uiAreaDrawParams dp;
c = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
dp.Context = newContext(c);
dp.ClientWidth = [self frame].size.width;
dp.ClientHeight = [self frame].size.height;
dp.ClipX = r.origin.x;
dp.ClipY = r.origin.y;
dp.ClipWidth = r.size.width;
dp.ClipHeight = r.size.height;
// TODO DPI
// TODO scroll position
(*(self->libui_a->ah->Draw))(self->libui_a->ah, self->libui_a, &dp);
}
- (BOOL)isFlipped
{
return YES;
}
@end
@implementation areaView
- (id)initWithFrame:(NSRect)r area:(uiArea *)a
{
NSScrollerStyle style;
CGFloat swidth;
NSMutableDictionary *views;
NSLayoutConstraint *constraint;
self = [super initWithFrame:r];
if (self) {
self->libui_a = a;
self->drawingView = [[areaDrawingView alloc] initWithFrame:NSZeroRect area:self->libui_a];
[self->drawingView setTranslatesAutoresizingMaskIntoConstraints:NO];
style = [NSScroller preferredScrollerStyle];
swidth = [NSScroller scrollerWidthForControlSize:NSRegularControlSize
scrollerStyle:style];
self->hscrollbar = [[areaScroller alloc]
initWithFrame:NSMakeRect(0, 0, swidth * 5, swidth)
vertical:NO];
[self->hscrollbar setScrollerStyle:style];
[self->hscrollbar setKnobStyle:NSScrollerKnobStyleDefault];
[self->hscrollbar setControlTint:NSDefaultControlTint];
[self->hscrollbar setControlSize:NSRegularControlSize];
//TODO [self->hscrollbar setArrowsPosition:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx];
[self->hscrollbar setTranslatesAutoresizingMaskIntoConstraints:NO];
self->vscrollbar = [[areaScroller alloc]
initWithFrame:NSMakeRect(0, 0, swidth, swidth * 5)
vertical:YES];
[self->vscrollbar setScrollerStyle:style];
[self->vscrollbar setKnobStyle:NSScrollerKnobStyleDefault];
[self->vscrollbar setControlTint:NSDefaultControlTint];
[self->vscrollbar setControlSize:NSRegularControlSize];
//TODO [self->vscrollbar setArrowsPosition:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx];
[self->vscrollbar setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:self->drawingView];
[self addSubview:self->hscrollbar];
[self addSubview:self->vscrollbar];
// use visual constraints to arrange:
// - the drawing view and vertical scrollbar horizontally
// - the drawing view and horizontal scrollbar vertically
// - the horizontal scrollbar flush left
// - the vertical scrollbar flush top
views = [NSMutableDictionary new];
[views setObject:self->drawingView forKey:@"drawingView"];
[views setObject:self->hscrollbar forKey:@"hscrollbar"];
[views setObject:self->vscrollbar forKey:@"vscrollbar"];
addConstraint(self, @"H:|[drawingView][vscrollbar]|", nil, views);
addConstraint(self, @"V:|[drawingView][hscrollbar]|", nil, views);
addConstraint(self, @"H:|[hscrollbar]", nil, views);
addConstraint(self, @"V:|[vscrollbar]", nil, views);
[views release];
// use explicit layout constraints to line up
// - the bottom edge of the drawing view with the bottom edge of the vertical scrollbar
// - the right edge of the drawing view with the right edge of the horizontal scrollbar
constraint = [NSLayoutConstraint constraintWithItem:self->drawingView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self->vscrollbar
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0];
[self addConstraint:constraint];
[constraint release];
constraint = [NSLayoutConstraint constraintWithItem:self->drawingView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self->hscrollbar
attribute:NSLayoutAttributeRight
multiplier:1
constant:0];
[self addConstraint:constraint];
[constraint release];
}
return self;
}
@end
uiArea *newArea(uiAreaHandler *ah)
{
uiArea *a;
// TODO
a = (uiArea *) malloc(sizeof (uiArea));
a->ah = ah;
a->view = [[areaView alloc] initWithFrame:NSZeroRect area:a];
// set initial state
// TODO do this on other platforms?
areaUpdateScroll(a);
return a;
}
NSView *areaGetView(uiArea *a)
{
return a->view;
}
void areaUpdateScroll(uiArea *a)
{
/* TODO
NSRect frame;
frame.origin = NSMakePoint(0, 0);
frame.size.width = (*(a->ah->HScrollMax))(a->ah, a);
frame.size.height = (*(a->ah->VScrollMax))(a->ah, a);
[a->documentView setFrame:frame];
*/
}