243 lines
6.0 KiB
Mathematica
243 lines
6.0 KiB
Mathematica
|
// 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];
|
||
|
*/
|
||
|
}
|