SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
HexFiend/HFVerticalScrollerRepresenter.m
1 //
2 // HFRepresenterVerticalScroller.m
3 // HexFiend_2
4 //
5 // Copyright 2007 ridiculous_fish. All rights reserved.
6 //
7
8 /* Note that on Tiger, NSScroller did not support double in any meaningful way; [scroller doubleValue] always returns 0, and setDoubleValue: doesn't look like it works either. */
9
10 #import <HexFiend/HFVerticalScrollerRepresenter.h>
11
12
13 @implementation HFVerticalScrollerRepresenter
14
15 /* No special NSCoding support needed */
16
17 - (NSView *)createView {
18 NSScroller *scroller = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, [NSScroller scrollerWidthForControlSize:NSRegularControlSize scrollerStyle:NSScrollerStyleLegacy], 64)];
19 [scroller setTarget:self];
20 [scroller setContinuous:YES];
21 [scroller setEnabled:YES];
22 [scroller setTarget:self];
23 [scroller setAction:@selector(scrollerDidChangeValue:)];
24 [scroller setAutoresizingMask:NSViewHeightSizable];
25 return scroller;
26 }
27
28 - (NSUInteger)visibleLines {
29 HFController *controller = [self controller];
30 HFASSERT(controller != NULL);
31 return ll2l(HFFPToUL(ceill([controller displayedLineRange].length)));
32 }
33
34 - (void)scrollByKnobToValue:(double)newValue {
35 HFASSERT(newValue >= 0. && newValue <= 1.);
36 HFController *controller = [self controller];
37 unsigned long long contentsLength = [controller contentsLength];
38 NSUInteger bytesPerLine = [controller bytesPerLine];
39 HFASSERT(bytesPerLine > 0);
40 unsigned long long totalLineCountTimesBytesPerLine = HFRoundUpToNextMultipleSaturate(contentsLength - 1, bytesPerLine);
41 HFASSERT(totalLineCountTimesBytesPerLine == ULLONG_MAX || totalLineCountTimesBytesPerLine % bytesPerLine == 0);
42 unsigned long long totalLineCount = HFDivideULLRoundingUp(totalLineCountTimesBytesPerLine, bytesPerLine);
43 HFFPRange currentLineRange = [controller displayedLineRange];
44 HFASSERT(currentLineRange.length < HFULToFP(totalLineCount));
45 long double maxScroll = totalLineCount - currentLineRange.length;
46 long double newScroll = maxScroll * (long double)newValue;
47 [controller setDisplayedLineRange:(HFFPRange){newScroll, currentLineRange.length}];
48 }
49
50 - (void)scrollByLines:(long long)linesInt {
51 if (linesInt == 0) return;
52
53 //note - this properly computes the absolute value even for LLONG_MIN
54 long double lines = HFULToFP((unsigned long long)llabs(linesInt));
55
56 HFController *controller = [self controller];
57 HFASSERT(controller != NULL);
58 HFFPRange displayedRange = [[self controller] displayedLineRange];
59 if (linesInt < 0) {
60 displayedRange.location -= MIN(lines, displayedRange.location);
61 }
62 else {
63 long double availableLines = HFULToFP([controller totalLineCount]);
64 displayedRange.location = MIN(availableLines - displayedRange.length, displayedRange.location + lines);
65 }
66 [controller setDisplayedLineRange:displayedRange];
67 }
68
69 - (void)scrollerDidChangeValue:(NSScroller *)scroller {
70 assert(scroller == [self view]);
71 switch ([scroller hitPart]) {
72 case NSScrollerDecrementPage: [self scrollByLines: -(long long)[self visibleLines]]; break;
73 case NSScrollerIncrementPage: [self scrollByLines: (long long)[self visibleLines]]; break;
74 case NSScrollerDecrementLine: [self scrollByLines: -1LL]; break;
75 case NSScrollerIncrementLine: [self scrollByLines: 1LL]; break;
76 case NSScrollerKnob: [self scrollByKnobToValue:[scroller doubleValue]]; break;
77 default: break;
78 }
79 }
80
81 - (void)updateScrollerValue {
82 HFController *controller = [self controller];
83 CGFloat value, proportion;
84 NSScroller *scroller = [self view];
85 BOOL enable = YES;
86 if (controller == nil) {
87 value = 0;
88 proportion = 0;
89 }
90 else {
91 unsigned long long length = [controller contentsLength];
92 HFFPRange lineRange = [controller displayedLineRange];
93 HFASSERT(lineRange.location >= 0 && lineRange.length >= 0);
94 if (length == 0) {
95 value = 0;
96 proportion = 1;
97 enable = NO;
98 }
99 else {
100 long double availableLines = HFULToFP([controller totalLineCount]);
101 long double consumedLines = MAX(1., lineRange.length);
102 proportion = ld2f(lineRange.length / availableLines);
103
104 long double maxScroll = availableLines - consumedLines;
105 HFASSERT(maxScroll >= lineRange.location);
106 if (maxScroll == 0.) {
107 enable = NO;
108 value = 0;
109 }
110 else {
111 value = ld2f(lineRange.location / maxScroll);
112 }
113 }
114 }
115 [scroller setDoubleValue:value];
116 [scroller setKnobProportion:proportion];
117 [scroller setEnabled:enable];
118 }
119
120 - (CGFloat)minimumViewWidthForBytesPerLine:(NSUInteger)bytesPerLine {
121 USE(bytesPerLine);
122 return [NSScroller scrollerWidthForControlSize:[[self view] controlSize] scrollerStyle:NSScrollerStyleLegacy];
123 }
124
125 - (void)controllerDidChange:(HFControllerPropertyBits)bits {
126 if (bits & (HFControllerContentLength | HFControllerDisplayedLineRange)) [self updateScrollerValue];
127 }
128
129 + (NSPoint)defaultLayoutPosition {
130 return NSMakePoint(2, 0);
131 }
132
133 @end
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.