diff --git a/darwin/GNUfiles.mk b/darwin/GNUfiles.mk index c420d02d..aacf382f 100644 --- a/darwin/GNUfiles.mk +++ b/darwin/GNUfiles.mk @@ -26,6 +26,7 @@ MFILES += \ darwin/multilineentry.m \ darwin/progressbar.m \ darwin/radiobuttons.m \ + darwin/scrollview.m \ darwin/separator.m \ darwin/slider.m \ darwin/spinbox.m \ diff --git a/darwin/autolayout.m b/darwin/autolayout.m index 00651d27..9964155f 100644 --- a/darwin/autolayout.m +++ b/darwin/autolayout.m @@ -159,78 +159,3 @@ void singleChildConstraintsSetMargined(struct singleChildConstraints *c, int mar if (c->bottomConstraintEqual != nil) [c->bottomConstraintEqual setConstant:margin]; } - -// based on http://blog.bjhomer.com/2014/08/nsscrollview-and-autolayout.html because (as pointed out there) Apple's official guide is really only for iOS -void scrollViewConstraintsEstablish(struct scrollViewConstraints *c, NSScrollView *sv, BOOL hscroll, BOOL vscroll, NSString *desc) -{ - NSView *cv, *dv; - NSLayoutRelation rel; - - scrollViewConstraintsRemove(c, sv); - cv = [sv contentView]; - dv = [sv documentView]; - - c->documentLeading = mkConstraint(dv, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - cv, NSLayoutAttributeLeading, - 1, 0, - [desc stringByAppendingString:@"document leading constraint"]); - [sv addConstraint:c->documentLeading]; - [c->documentLeading retain]; - - c->documentTop = mkConstraint(dv, NSLayoutAttributeTop, - NSLayoutRelationEqual, - cv, NSLayoutAttributeTop, - 1, 0, - [desc stringByAppendingString:@"document top constraint"]); - [sv addConstraint:c->documentTop]; - [c->documentTop retain]; - - c->hscroll = hscroll; - rel = NSLayoutRelationGreaterThanOrEqual; - if (!c->hscroll) - rel = NSLayoutRelationEqual; - c->documentTrailing = mkConstraint(dv, NSLayoutAttributeTrailing, - rel, - cv, NSLayoutAttributeTrailing, - 1, 0, - [desc stringByAppendingString:@"document trailing constraint"]); - [sv addConstraint:c->documentTrailing]; - [c->documentTrailing retain]; - - c->vscroll = vscroll; - rel = NSLayoutRelationGreaterThanOrEqual; - if (!c->vscroll) - rel = NSLayoutRelationEqual; - c->documentBottom = mkConstraint(dv, NSLayoutAttributeBottom, - rel, - cv, NSLayoutAttributeBottom, - 1, 0, - [desc stringByAppendingString:@"document bottom constraint"]); - [sv addConstraint:c->documentBottom]; - [c->documentBottom retain]; -} - -void scrollViewConstraintsRemove(struct scrollViewConstraints *c, NSScrollView *sv) -{ - if (c->documentLeading != nil) { - [sv removeConstraint:c->documentLeading]; - [c->documentLeading release]; - c->documentLeading = nil; - } - if (c->documentTop != nil) { - [sv removeConstraint:c->documentTop]; - [c->documentTop release]; - c->documentTop = nil; - } - if (c->documentTrailing != nil) { - [sv removeConstraint:c->documentTrailing]; - [c->documentTrailing release]; - c->documentTrailing = nil; - } - if (c->documentBottom != nil) { - [sv removeConstraint:c->documentBottom]; - [c->documentBottom release]; - c->documentBottom = nil; - } -} diff --git a/darwin/scrollview.m b/darwin/scrollview.m new file mode 100644 index 00000000..f02d5acf --- /dev/null +++ b/darwin/scrollview.m @@ -0,0 +1,133 @@ +// 27 may 2016 +#include "uipriv_darwin.h" + +struct scrollViewData { + NSLayoutConstraint *documentLeading; + NSLayoutConstraint *documentTop; + BOOL hscroll; + NSLayoutConstraint *documentTrailing; + BOOL vscroll; + NSLayoutConstraint *documentBottom; +}; + +NSScrollView *mkScrollView(struct scrollViewCreateParams *p, struct scrollViewData **dout) +{ + NSScrollView *sv; + NSBorderType border; + struct scrollViewData *d; + + sv = [[NSScrollView alloc] initWithFrame:NSZeroRect]; + // TODO verify background color for programmatically created NSTextView + if (p->BackgroundColor != nil) + [sv setBackgroundColor:p->BackgroundColor]; + [sv setDrawsBackground:p->DrawsBackground]; + border = NSNoBorder; + if (p->Bordered) + border = NSBezelBorder; + // TODO verify document cursor for programmatically created NSTextView + [sv setBorderType:border]; + [sv setAutohidesScrollers:YES]; + [sv setHasHorizontalRuler:NO]; + [sv setHasVerticalRuler:NO]; + [sv setRulersVisible:NO]; + [sv setScrollerKnobStyle:NSScrollerKnobStyleDefault]; + // the scroller style is documented as being set by default for us + // TODO verify line and page for programmatically created NSTextView + [sv scrollsDynamically:YES]; + [sv setFindBarPosition:NSScrollViewFindBarPositionAboveContent]; + [sv setUsesPredominantAxisScrolling:NO]; + [sv setHorizontalElasticity:NSScrollElasticityAutomatic]; + [sv setVerticalElasticity:NSScrollElasticityAutomatic]; + [sv setAllowsMagnification:NO]; + + [p->DocumentView setTranslatesAutoresizingMaskIntoConstraints:NO]; + [sv setDocumentView:p->DocumentView]; + d = uiNew(struct scrollViewData); + scrollViewSetScrolling(sv, d, p->HScroll, p->VScroll); + + *dout = d; + return sv; +} + +static void scrollViewConstraintsRemove(NSScrollView *sv, struct scrollViewData *d) +{ + if (d->documentLeading != nil) { + [sv removeConstraint:d->documentLeading]; + [d->documentLeading release]; + d->documentLeading = nil; + } + if (d->documentTop != nil) { + [sv removeConstraint:d->documentTop]; + [d->documentTop release]; + d->documentTop = nil; + } + if (d->documentTrailing != nil) { + [sv removeConstraint:d->documentTrailing]; + [d->documentTrailing release]; + d->documentTrailing = nil; + } + if (d->documentBottom != nil) { + [sv removeConstraint:d->documentBottom]; + [d->documentBottom release]; + d->documentBottom = nil; + } +} + +// based on http://blog.bjhomer.com/2014/08/nsscrollview-and-autolayout.html because (as pointed out there) Apple's official guide is really only for iOS +void scrollViewSetScrolling(NSScrollView *sv, struct scrollViewData *d, BOOL hscroll, BOOL vscroll) +{ + NSView *cv, *dv; + NSLayoutRelation rel; + + scrollViewConstraintsRemove(sv, d); + cv = [sv contentView]; + dv = [sv documentView]; + + d->documentLeading = mkConstraint(dv, NSLayoutAttributeLeading, + NSLayoutRelationEqual, + cv, NSLayoutAttributeLeading, + 1, 0, + @"NSScrollView document leading constraint"); + [sv addConstraint:d->documentLeading]; + [d->documentLeading retain]; + + d->documentTop = mkConstraint(dv, NSLayoutAttributeTop, + NSLayoutRelationEqual, + cv, NSLayoutAttributeTop, + 1, 0, + @"NSScrollView document top constraint"); + [sv addConstraint:d->documentTop]; + [d->documentTop retain]; + + d->hscroll = hscroll; + [sv setHasHorizontalScroller:d->hscroll]; + rel = NSLayoutRelationGreaterThanOrEqual; + if (!d->hscroll) + rel = NSLayoutRelationEqual; + d->documentTrailing = mkConstraint(dv, NSLayoutAttributeTrailing, + rel, + cv, NSLayoutAttributeTrailing, + 1, 0, + @"NSScrollView document trailing constraint"); + [sv addConstraint:d->documentTrailing]; + [d->documentTrailing retain]; + + d->vscroll = vscroll; + [sv setHasVerticalScroller:d->vscroll]; + rel = NSLayoutRelationGreaterThanOrEqual; + if (!d->vscroll) + rel = NSLayoutRelationEqual; + d->documentBottom = mkConstraint(dv, NSLayoutAttributeBottom, + rel, + cv, NSLayoutAttributeBottom, + 1, 0, + @"NSScrollView document bottom constraint"); + [sv addConstraint:d->documentBottom]; + [d->documentBottom retain]; +} + +void scrollViewFreeData(NSScrollView *sv, struct scrollViewData *d) +{ + scrollViewConstraintsRemove(sv, d); + uiFree(d); +} diff --git a/darwin/uipriv_darwin.h b/darwin/uipriv_darwin.h index 36bf674a..e016bf3e 100644 --- a/darwin/uipriv_darwin.h +++ b/darwin/uipriv_darwin.h @@ -72,16 +72,6 @@ struct singleChildConstraints { extern void singleChildConstraintsEstablish(struct singleChildConstraints *c, NSView *contentView, NSView *childView, BOOL hugsTrailing, BOOL hugsBottom, int margined, NSString *desc); extern void singleChildConstraintsRemove(struct singleChildConstraints *c, NSView *cv); extern void singleChildConstraintsSetMargined(struct singleChildConstraints *c, int margined); -struct scrollViewConstraints { - NSLayoutConstraint *documentLeading; - NSLayoutConstraint *documentTop; - BOOL hscroll; - NSLayoutConstraint *documentTrailing; - BOOL vscroll; - NSLayoutConstraint *documentBottom; -}; -extern void scrollViewConstraintsEstablish(struct scrollViewConstraints *c, NSScrollView *sv, BOOL hscroll, BOOL vscroll, NSString *desc); -extern void scrollViewConstraintsRemove(struct scrollViewConstraints *c, NSScrollView *sv); // map.m extern struct mapTable *newMap(void); @@ -115,3 +105,16 @@ extern void setupFontPanel(void); // colorbutton.m extern BOOL colorButtonInhibitSendAction(SEL sel, id from, id to); + +// scrollview.m +struct scrollViewCreateParams { + NSView *DocumentView; + NSColor *BackgroundColor; + BOOL DrawsBackground; + BOOL Bordered; + BOOL HScroll; + BOOL VScroll; +}; +extern NSScrollView *mkScrollView(struct scrollViewCreateParams *p, struct scrollViewData **dout); +extern void scrollViewSetScrolling(NSScrollView *sv, struct scrollViewData *d, BOOL hscroll, BOOL vscroll); +extern void scrollViewFreeData(NSScrollView *sv, struct scrollViewData *d);