Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/Classes/GraphicClientView.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 200 - (show annotations) (download)
Thu Apr 7 14:14:06 2022 UTC (2 years, 1 month ago) by toshinagata1964
File size: 22615 byte(s)
Add/sub and scale tools in strip chart views are improved
1 //
2 // GraphicClientView.m
3 //
4 /*
5 Copyright (c) 2000-2017 Toshi Nagata. All rights reserved.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 2 of the License.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 */
16
17 #import "GraphicClientView.h"
18 #import "GraphicWindowController.h" // for trackDuration
19 #import "MyDocument.h"
20 #import "NSCursorAdditions.h"
21 #import "MyAppController.h" // for getOSXVersion
22
23 @implementation GraphicClientView
24
25 - (BOOL)hasVerticalScroller
26 {
27 return YES;
28 }
29
30 + (float)minHeight
31 {
32 return 32.0f;
33 }
34
35 - (int)clientViewType
36 {
37 return kGraphicGenericViewType;
38 }
39
40 - (id)initWithFrame: (NSRect)rect
41 {
42 self = [super initWithFrame: rect];
43 if (self) {
44 minValue = 0.0f;
45 maxValue = 128.0f;
46 dataSource = nil;
47 visibleRangeMin = 0.0f;
48 visibleRangeMax = 1.0f;
49 autoScaleOnResizing = YES;
50 }
51 return self;
52 }
53
54 - (void)dealloc
55 {
56 [dataSource release];
57 [super dealloc];
58 }
59
60 // Respond when the scroll position changed
61 - (void)superBoundsDidChange: (NSNotification *)aNotification
62 {
63 }
64
65 // Respond when the frame of the superview changed
66 // i.e. the scroll view containing the client view is resized
67 - (void)superFrameDidChange: (NSNotification *)aNotification
68 {
69 }
70
71 // Respond when the frame of the client view, i.e. data range and/or scale are changed
72 - (void)frameDidChange: (NSNotification *)aNotification
73 {
74 }
75
76 - (void)setDataSource: (id)object
77 {
78 if (dataSource != nil)
79 [dataSource release];
80 dataSource = [object retain];
81
82 // Listen to notifications
83 // This should be somewhere after creation of GraphicClientView
84 [[NSNotificationCenter defaultCenter]
85 addObserver: self
86 selector: @selector(superBoundsDidChange:)
87 name: NSViewBoundsDidChangeNotification
88 object: [self superview]];
89 [[NSNotificationCenter defaultCenter]
90 addObserver: self
91 selector: @selector(superFrameDidChange:)
92 name: NSViewFrameDidChangeNotification
93 object: [self superview]];
94 [[NSNotificationCenter defaultCenter]
95 addObserver: self
96 selector: @selector(frameDidChange:)
97 name: NSViewFrameDidChangeNotification
98 object: self];
99 }
100
101 - (id)dataSource
102 {
103 return dataSource;
104 }
105
106 - (BOOL)isFocusTrack: (int)trackNum
107 {
108 return [dataSource isFocusTrack:trackNum];
109 }
110 - (int32_t)visibleTrackCount
111 {
112 return [dataSource visibleTrackCount];
113 }
114
115 - (int)sortedTrackNumberAtIndex: (int)index
116 {
117 return [dataSource sortedTrackNumberAtIndex:index];
118 }
119
120 - (void)setFocusTrack:(int)aTrack
121 {
122 }
123
124 - (int)focusTrack
125 {
126 return -1;
127 }
128
129 - (void)doTrackModified:(int)aTrack
130 {
131 }
132
133 CGFloat gLineDash1[] = {6.0f, 2.0f};
134 CGFloat gLineDash2[] = {2.0f, 6.0f};
135 CGFloat gDashWidth = 8.0f;
136
137 - (NSColor *)verticalLineColor: (BOOL)beforeEndOfSequence;
138 {
139 if (beforeEndOfSequence)
140 return [NSColor blackColor];
141 else
142 return [NSColor grayColor];
143 }
144
145 - (void)drawVerticalLinesInRect: (NSRect)aRect
146 {
147 float ppt;
148 MDTickType beginTick, endTick, duration;
149 float originx, limitx;
150 NSPoint pt1, pt2;
151 int i, numLines;
152 NSBezierPath *lines, *subLines;
153 ppt = [dataSource pixelsPerTick];
154 beginTick = aRect.origin.x / ppt;
155 endTick = (aRect.origin.x + aRect.size.width) / ppt + 1;
156 duration = [dataSource sequenceDuration];
157 limitx = duration * ppt;
158 pt1.y = (CGFloat)(floor(aRect.origin.y / gDashWidth) * gDashWidth);
159 pt2.y = (CGFloat)(ceil((aRect.origin.y + aRect.size.height) / gDashWidth) * gDashWidth);
160 lines = [[NSBezierPath allocWithZone: [self zone]] init];
161 subLines = [[NSBezierPath allocWithZone: [self zone]] init];
162 originx = aRect.origin.x;
163 if (originx == 0.0f)
164 originx = 1.0f; /* Avoid drawing line at tick = 0 */
165 pt2.x = 0.0f;
166 while (beginTick < endTick) {
167 int mediumCount, majorCount;
168 MDEvent *sig1, *sig2;
169 MDTickType sigTick, nextSigTick;
170 float interval, startx;
171 [dataSource verticalLinesFromTick: beginTick timeSignature: &sig1 nextTimeSignature: &sig2 lineIntervalInPixels: &interval mediumCount: &mediumCount majorCount: &majorCount];
172 sigTick = (sig1 == NULL ? 0 : MDGetTick(sig1));
173 nextSigTick = (sig2 == NULL ? kMDMaxTick : MDGetTick(sig2));
174 if (nextSigTick > endTick)
175 nextSigTick = endTick;
176 startx = sigTick * ppt;
177 numLines = (int)floor((nextSigTick - sigTick) * ppt / interval) + 1;
178 i = (startx >= originx ? 0 : (int)floor((originx - startx) / interval));
179 [[self verticalLineColor:true] set];
180 for ( ; i < numLines; i++) {
181 pt1.x = (CGFloat)(floor(startx + i * interval) + 0.5);
182 if (pt1.x >= originx && pt1.x <= aRect.origin.x + aRect.size.width) {
183 if (pt1.x > limitx && pt2.x <= limitx) {
184 /* Draw the lines and set the color to gray */
185 [lines setLineDash: gLineDash1 count: 2 phase: 0.0f];
186 [subLines setLineDash: gLineDash2 count: 2 phase: 0.0f];
187 [lines stroke];
188 [subLines stroke];
189 [lines removeAllPoints];
190 [subLines removeAllPoints];
191 [[self verticalLineColor:false] set];
192 }
193 pt2.x = pt1.x;
194 if (i % majorCount == 0) {
195 [lines moveToPoint: pt1];
196 [lines lineToPoint: pt2];
197 } else {
198 [subLines moveToPoint: pt1];
199 [subLines lineToPoint: pt2];
200 }
201 }
202 }
203 beginTick = nextSigTick;
204 }
205 [lines setLineDash: gLineDash1 count: 2 phase: 0.0f];
206 [subLines setLineDash: gLineDash2 count: 2 phase: 0.0f];
207 [lines stroke];
208 [subLines stroke];
209 [lines release];
210 [subLines release];
211
212 [[NSColor blackColor] set];
213 if (limitx < aRect.origin.x + aRect.size.width) {
214 /* Draw the "end of sequence" line */
215 float width = [NSBezierPath defaultLineWidth];
216 pt1.x = pt2.x = limitx;
217 [NSBezierPath strokeLineFromPoint: pt1 toPoint: pt2];
218 [NSBezierPath setDefaultLineWidth: 2.0f];
219 pt1.x = pt2.x += 3.0f;
220 [NSBezierPath strokeLineFromPoint: pt1 toPoint: pt2];
221 [NSBezierPath setDefaultLineWidth: width];
222 }
223 }
224
225
226 // Should be overridden in subclasses
227 - (void)drawContentsInRect: (NSRect)aRect
228 {
229 }
230
231 - (void)drawRect: (NSRect)aRect
232 {
233 [self drawContentsInRect:aRect];
234 }
235
236 - (void)paintEditingRange: (NSRect)aRect startX: (float *)startp endX: (float *)endp
237 {
238 MDTickType startTick, endTick;
239 float startx, endx;
240 NSRect rect;
241 float ppt = [dataSource pixelsPerTick];
242 [(MyDocument *)[dataSource document] getEditingRangeStart: &startTick end: &endTick];
243 if (startTick >= 0 && startTick < kMDMaxTick && endTick >= startTick) {
244 startx = (float)floor(startTick * ppt);
245 endx = (float)floor(endTick * ppt);
246 rect = NSIntersectionRect(aRect, NSMakeRect(startx, aRect.origin.y, endx - startx, aRect.size.height));
247 [[MyDocument colorForEditingRange] set];
248 NSRectFillUsingOperation(rect, NSCompositeSourceAtop);
249 [[NSColor blackColor] set];
250 } else {
251 startx = endx = -1;
252 }
253 if (startp != NULL)
254 *startp = startx;
255 if (endp != NULL)
256 *endp = endx;
257 }
258
259 - (void)reloadData
260 {
261 NSRect rect = [self frame];
262 NSRect superRect = [[self superview] bounds];
263 rect.size.width = [dataSource clientViewWidth];
264 // rect.size.width = [dataSource sequenceDurationInQuarter] * [dataSource pixelsPerQuarter];
265 // if (rect.size.width < superRect.size.width) {
266 // rect.size.width = superRect.size.width;
267 // NSLog(@"reloadData: want to adjust rect.size.width");
268 // }
269 if (![self hasVerticalScroller]) {
270 rect.size.height = superRect.size.height;
271 }
272 // NSLog(@"reloadData for %@: %@", self, NSStringFromRect(rect));
273 // if (yScale > 0 && maxValue > minValue)
274 // rect.size.height = floor(yScale * (maxValue - minValue));
275 [self setFrame: rect];
276 [self setNeedsDisplay: YES];
277 }
278
279 - (void)setYScale: (float)y
280 {
281 NSRect rect;
282 if (maxValue > minValue) {
283 rect = [self frame];
284 rect.size.height = (CGFloat)floor(y * (maxValue - minValue) + 0.5);
285 [self setFrame: rect];
286 }
287 }
288
289 - (float)yScale
290 {
291 float ys;
292 if (maxValue > minValue)
293 ys = [self frame].size.height / (maxValue - minValue);
294 else ys = 0.0f;
295 return ys;
296 }
297
298 - (void)setMinValue: (float)value
299 {
300 minValue = value;
301 }
302
303 - (float)minValue
304 {
305 return minValue;
306 }
307
308 - (void)setMaxValue: (float)value
309 {
310 maxValue = value;
311 }
312
313 - (float)maxValue
314 {
315 return maxValue;
316 }
317
318 - (void)convertFromPoint:(NSPoint)pt toY:(float *)y andTick:(int32_t *)tick
319 {
320 NSRect frame = [self frame];
321 float pixelsPerTick = [[self dataSource] pixelsPerTick];
322 *y = (pt.y - frame.origin.y) * (maxValue - minValue) / frame.size.height + minValue;
323 *tick = (pt.x - frame.origin.x) / pixelsPerTick;
324 }
325
326 - (NSPoint)convertToPointFromY:(float)y andTick:(int32_t)tick
327 {
328 NSPoint pt;
329 NSRect frame = [self frame];
330 float pixelsPerTick = [[self dataSource] pixelsPerTick];
331 pt.x = tick * pixelsPerTick + frame.origin.x;
332 pt.y = (y - minValue) * frame.size.height / (maxValue - minValue) + frame.origin.y;
333 return pt;
334 }
335
336 - (void)setVisibleRangeMin:(float)min max:(float)max
337 {
338 visibleRangeMin = min;
339 visibleRangeMax = max;
340 [self restoreVisibleRange];
341 }
342
343 - (void)getVisibleRangeMin:(float *)min max:(float *)max
344 {
345 [self saveVisibleRange];
346 *min = visibleRangeMin;
347 *max = visibleRangeMax;
348 }
349
350 - (void)saveVisibleRange
351 {
352 NSRect frame = [self frame];
353 NSRect clipBounds = [[self superview] bounds];
354 visibleRangeMin = clipBounds.origin.y / frame.size.height;
355 visibleRangeMax = (clipBounds.origin.y + clipBounds.size.height) / frame.size.height;
356 }
357
358 - (void)restoreVisibleRange
359 {
360 NSRect clipBounds = [[self superview] bounds];
361 NSRect frame = [self frame];
362 frame.size.height = (CGFloat)floor(clipBounds.size.height / (visibleRangeMax - visibleRangeMin) + 0.5);
363 [self setFrame:frame];
364 clipBounds.origin.y = visibleRangeMin * frame.size.height;
365 [self scrollPoint:clipBounds.origin];
366 }
367
368 /*
369 - (void)getScrollPositionWithRangeMin:(float *)rangeMin max:(float *)rangeMax
370 {
371 NSRect frame = [self frame];
372 NSRect clipBounds = [[self superview] bounds];
373 *rangeMin = clipBounds.origin.y / frame.size.height;
374 *rangeMax = (clipBounds.origin.y + clipBounds.size.height) / frame.size.height;
375 }
376
377 - (void)rescaleToShowRangeMin:(float)rangeMin max:(float)rangeMax
378 {
379 NSRect clipBounds = [[self superview] bounds];
380 NSRect frame = [self frame];
381 frame.size.height = floor(clipBounds.size.height / (rangeMax - rangeMin) + 0.5);
382 [self setFrame:frame];
383 clipBounds.origin.y = rangeMin * frame.size.height;
384 [self scrollPoint:clipBounds.origin];
385 }
386 */
387
388 /* Modify rectangle for redrawing selection region */
389 - (NSRect)willInvalidateSelectRect: (NSRect)rect
390 {
391 return rect;
392 }
393
394 - (void)invalidateSelectRegion
395 {
396 NSRect rect;
397 if (selectionPath != nil) {
398 rect = [selectionPath bounds];
399 rect = NSInsetRect(rect, -0.5f, -0.5f);
400 rect = [self willInvalidateSelectRect: rect];
401 // NSEraseRect(rect);
402 rect = NSIntersectionRect(rect, [self visibleRect]);
403 [self setNeedsDisplayInRect: rect];
404 }
405 }
406
407 - (void)calcSelectRegion
408 {
409 NSPoint pt1, pt2;
410 NSRect rect;
411 if (selectPoints != nil && [selectPoints count] > 1) {
412 if (localGraphicTool == kGraphicRectangleSelectTool || localGraphicTool == kGraphicIbeamSelectTool || localGraphicTool == kGraphicPencilTool) {
413 pt1 = [[selectPoints objectAtIndex: 0] pointValue];
414 pt2 = [[selectPoints objectAtIndex: 1] pointValue];
415 rect.origin = pt1;
416 rect.size.width = pt2.x - pt1.x;
417 if (rect.size.width < 0) {
418 rect.size.width = -rect.size.width;
419 rect.origin.x = pt2.x;
420 }
421 if (localGraphicTool == kGraphicRectangleSelectTool) {
422 rect.size.height = pt2.y - pt1.y;
423 if (rect.size.height < 0) {
424 rect.size.height = -rect.size.height;
425 rect.origin.y = pt2.y;
426 }
427 } else {
428 NSRect bounds = [self bounds];
429 rect.origin.y = bounds.origin.y - 1.0f;
430 rect.size.height = bounds.size.height + 2.0f;
431 }
432 rect = NSInsetRect(rect, -0.5f, -0.5f);
433 [selectionPath release];
434 selectionPath = [[NSBezierPath bezierPathWithRect: rect] retain];
435 }
436 }
437 }
438
439 - (void)setSelectRegion: (NSBezierPath *)path
440 {
441 [self invalidateSelectRegion];
442 [selectionPath release];
443 if (path == nil)
444 selectionPath = nil;
445 else {
446 selectionPath = [path copyWithZone: [self zone]];
447 [self invalidateSelectRegion];
448 }
449 }
450
451 //- (int)selectMode
452 //{
453 // return selectMode;
454 //}
455
456 - (BOOL)isDragging
457 {
458 return isDragging;
459 }
460
461 //- (BOOL)shiftDown
462 //{
463 // return shiftDown;
464 //}
465
466 - (NSArray *)selectPoints
467 {
468 return selectPoints;
469 }
470
471 - (NSBezierPath *)selectionPath
472 {
473 return selectionPath;
474 }
475
476 - (void)drawSelectRegion
477 {
478 if (selectionPath != nil) {
479 [[[MyDocument colorForSelectingRange] colorWithAlphaComponent: 0.1f] set];
480 [selectionPath fill];
481 [[NSColor blackColor] set];
482 [selectionPath stroke];
483 }
484 }
485
486 - (BOOL)isPointInSelectRegion: (NSPoint)point
487 {
488 if (selectionPath != nil)
489 return [selectionPath containsPoint: point];
490 else return NO;
491 }
492
493 - (void)autoscrollTimerCallback: (NSTimer *)timer
494 {
495 NSEvent *event = (NSEvent *)[timer userInfo];
496 [autoscrollTimer release];
497 autoscrollTimer = nil;
498 [self mouseDragged: event];
499 }
500
501 - (NSString *)infoTextForMousePoint:(NSPoint)pt dragging:(BOOL)flag option:(int *)option
502 {
503 MDTickType theTick;
504 int32_t measure, beat, tick;
505 if (option != NULL)
506 *option = 0;
507 theTick = [dataSource quantizedTickFromPixel:pt.x];
508 [dataSource convertTick:theTick toMeasure:&measure beat:&beat andTick:&tick];
509 return [NSString stringWithFormat:@"%d.%d.%d", measure, beat, tick];
510 }
511
512 - (int)modifyLocalGraphicTool:(int)originalGraphicTool
513 {
514 return originalGraphicTool;
515 }
516
517 - (void)doMouseDown: (NSEvent *)theEvent
518 {
519 if (initialModifierFlags & NSAlternateKeyMask) {
520 [[NSCursor loupeCursor] set];
521 isLoupeDragging = YES;
522 } else {
523 if ((initialModifierFlags & NSShiftKeyMask) == 0) {
524 MyDocument *doc = [dataSource document];
525 [doc unselectAllEventsInAllTracks: self];
526 [self reloadData];
527 }
528 }
529 }
530
531 - (void)mouseDown: (NSEvent *)theEvent
532 {
533 NSPoint pt;
534
535 [dataSource mouseEvent:theEvent receivedByClientView:self];
536 pt = [self convertPoint: [theEvent locationInWindow] fromView: nil];
537 pt.x = [dataSource quantizedPixelFromPixel: pt.x];
538 if (selectPoints == nil)
539 selectPoints = [[NSMutableArray allocWithZone: [self zone]] init];
540 else
541 [selectPoints removeAllObjects];
542 [selectPoints addObject: [NSValue valueWithPoint: pt]];
543 initialModifierFlags = [theEvent modifierFlags];
544 currentModifierFlags = initialModifierFlags;
545 isDragging = isLoupeDragging = NO;
546 localGraphicTool = [self modifyLocalGraphicTool:[dataSource graphicTool]];
547 [self doMouseDown: theEvent];
548 [dataSource updateCursorInfoForView:self atPosition:pt];
549 }
550
551 - (void)doMouseDragged: (NSEvent *)theEvent
552 {
553 [self invalidateSelectRegion];
554 [self calcSelectRegion];
555 [self invalidateSelectRegion];
556 }
557
558 - (void)mouseDragged: (NSEvent *)theEvent
559 {
560 NSPoint pt;
561 NSRect bounds;
562 NSValue *val;
563 [dataSource mouseEvent:theEvent receivedByClientView:self];
564 if (selectPoints == nil || [selectPoints count] == 0) {
565 [super mouseDragged: theEvent];
566 return;
567 }
568 if (autoscrollTimer != nil) {
569 [autoscrollTimer invalidate];
570 [autoscrollTimer release];
571 autoscrollTimer = nil;
572 }
573 isDragging = YES;
574 if ([self autoscroll: theEvent]) {
575 float pos;
576 autoscrollTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.2 target: self selector:@selector(autoscrollTimerCallback:) userInfo: theEvent repeats: NO] retain];
577 /* Scroll position after autoscroll */
578 pos = [[self superview] bounds].origin.x - [self frame].origin.x;
579 /* Scroll all the clientViews */
580 [(GraphicWindowController *)[self dataSource] scrollClientViewsToPosition: pos];
581 }
582 currentModifierFlags = [theEvent modifierFlags];
583 pt = [self convertPoint: [theEvent locationInWindow] fromView: nil];
584 pt.x = [dataSource quantizedPixelFromPixel: pt.x];
585 [dataSource setInfoText:[self infoTextForMousePoint:pt dragging:YES option:NULL]];
586 [dataSource updateCursorInfoForView:self atPosition:pt];
587 bounds = [self bounds];
588 if (pt.x < bounds.origin.x)
589 pt.x = bounds.origin.x;
590 if (pt.x > bounds.origin.x + bounds.size.width)
591 pt.x = bounds.origin.x + bounds.size.width;
592 if (pt.y < bounds.origin.y)
593 pt.y = bounds.origin.y;
594 if (pt.y > bounds.origin.y + bounds.size.height)
595 pt.y = bounds.origin.y + bounds.size.height;
596 val = [NSValue valueWithPoint: pt];
597 /* This is for linear (rectangle or ibeam) selection; also for pencil editing of strip chart */
598 if (localGraphicTool == kGraphicRectangleSelectTool || localGraphicTool == kGraphicIbeamSelectTool || localGraphicTool == kGraphicPencilTool) {
599 if ([selectPoints count] == 1)
600 [selectPoints addObject: val];
601 else
602 [selectPoints replaceObjectAtIndex: 1 withObject: val];
603 } else {
604 /* If marquee selection tool or free-hand pencil tool is to be implemented,
605 the last point should be added to selectPoints here */
606 }
607 [self doMouseDragged: theEvent];
608 [self displayIfNeeded];
609 }
610
611 - (void)doZoomByOptionDrag: (NSEvent *)theEvent
612 {
613 NSPoint pt1, pt2;
614 NSRect visibleRect, documentRect;
615 float pos, wid, r, oldppq;
616 /* Option + drag: zoom, Option + double click: unzoom */
617 switch ([theEvent clickCount]) {
618 case 0: /* drag */
619 pt1 = [[selectPoints objectAtIndex: 0] pointValue];
620 pt2 = [[selectPoints objectAtIndex: 1] pointValue];
621 visibleRect = [[self superview] bounds];
622 documentRect = [self frame];
623 if (pt1.x > pt2.x) {
624 pos = pt2.x;
625 wid = pt1.x - pt2.x;
626 } else {
627 pos = pt1.x;
628 wid = pt2.x - pt1.x;
629 }
630 if (wid < 5)
631 wid = 5;
632 r = visibleRect.size.width / wid;
633 if (r > 1) {
634 oldppq = [dataSource pixelsPerQuarter];
635 [dataSource zoomClientViewsWithPixelsPerQuarter:oldppq * r startingPos:pos * r];
636 /* [dataSource setPixelsPerQuarter: oldppq * r];
637 [dataSource scrollClientViewsToPosition: pos * r];
638 [dataSource reflectClientViews]; */
639 }
640 break;
641 case 2: /* double-click */
642 if ([theEvent modifierFlags] & NSShiftKeyMask)
643 [dataSource rezoomClientViews];
644 else [dataSource unzoomClientViews];
645 break;
646 }
647 [[NSCursor arrowCursor] set];
648 }
649
650 - (void)doMouseUp: (NSEvent *)theEvent
651 {
652 if (initialModifierFlags & NSAlternateKeyMask) {
653 [self doZoomByOptionDrag: theEvent];
654 }
655 }
656
657 - (void)mouseUp: (NSEvent *)theEvent
658 {
659 NSPoint pt = [self convertPoint: [theEvent locationInWindow] fromView: nil];
660 pt.x = [dataSource quantizedPixelFromPixel: pt.x];
661 [dataSource mouseEvent:theEvent receivedByClientView:self];
662 [dataSource updateCursorInfoForView:self atPosition:pt];
663
664 if (selectPoints == nil || [selectPoints count] == 0) {
665 [super mouseUp: theEvent];
666 return;
667 }
668 if (autoscrollTimer != nil) {
669 [autoscrollTimer invalidate];
670 [autoscrollTimer release];
671 autoscrollTimer = nil;
672 }
673 [self invalidateSelectRegion];
674 currentModifierFlags = [theEvent modifierFlags];
675 [self doMouseUp: theEvent];
676 isDragging = isLoupeDragging = NO;
677 [selectPoints removeAllObjects];
678 [selectionPath release];
679 selectionPath = nil;
680 [self displayIfNeeded];
681 }
682
683 //- (void)draggingDidEnd: (NSRect)bounds
684 //{
685 //}
686
687 - (void)doMouseMoved: (NSEvent *)theEvent
688 {
689 localGraphicTool = [self modifyLocalGraphicTool:[[self dataSource] graphicTool]];
690 if ([theEvent modifierFlags] & NSAlternateKeyMask)
691 [[NSCursor loupeCursor] set];
692 else if (localGraphicTool == kGraphicPencilTool)
693 [[NSCursor pencilCursor] set];
694 else if (localGraphicTool == kGraphicRectangleSelectTool)
695 [[NSCursor crosshairCursor] set];
696 else if (localGraphicTool == kGraphicIbeamSelectTool)
697 [[NSCursor IBeamCursor] set];
698 else [[NSCursor arrowCursor] set];
699 }
700
701 - (void)doFlagsChanged: (NSEvent *)theEvent
702 {
703 localGraphicTool = [self modifyLocalGraphicTool:[[self dataSource] graphicTool]];
704 if ([theEvent modifierFlags] & NSAlternateKeyMask)
705 [[NSCursor loupeCursor] set];
706 else if (localGraphicTool == kGraphicPencilTool)
707 [[NSCursor pencilCursor] set];
708 else if (localGraphicTool == kGraphicRectangleSelectTool)
709 [[NSCursor crosshairCursor] set];
710 else if (localGraphicTool == kGraphicIbeamSelectTool)
711 [[NSCursor IBeamCursor] set];
712 else
713 [[NSCursor arrowCursor] set];
714 }
715
716 - (float)scrollVerticalPosition
717 {
718 NSRect visibleRect = [[self superview] bounds];
719 return visibleRect.origin.y;
720 }
721
722 - (void)scrollToVerticalPosition:(float)pos
723 {
724 NSRect visibleRect = [[self superview] bounds];
725 NSRect documentRect = [self frame];
726 float y1;
727 y1 = documentRect.origin.y;
728 if (pos < y1)
729 pos = y1;
730 y1 = documentRect.origin.y + documentRect.size.height - visibleRect.size.height;
731 if (pos > y1)
732 pos = y1;
733 visibleRect.origin.y = pos;
734 [self scrollPoint: visibleRect.origin];
735 [self setNeedsDisplay:YES];
736 }
737
738 - (void)scrollWheel:(NSEvent *)theEvent
739 {
740 static int scroll_direction = 0;
741 float dx, dy, newpos;
742
743 if (scroll_direction == 0) {
744 // Scroll wheel behavior was changed in 10.7
745 if ([(MyAppController *)[NSApp delegate] getOSXVersion] < 10700)
746 scroll_direction = -1;
747 else scroll_direction = 1;
748 }
749
750 dx = [theEvent deltaX];
751 dy = [theEvent deltaY];
752 if (dx != 0.0) {
753 newpos = [[self dataSource] scrollPositionOfClientViews] - dx * (8 * scroll_direction);
754 [[self dataSource] scrollClientViewsToPosition:newpos];
755 }
756 if (dy != 0.0) {
757 // Implement vertical scroll by ourselves
758 newpos = [self scrollVerticalPosition] + dy * (4 * scroll_direction);
759 [self scrollToVerticalPosition:newpos];
760 }
761 }
762
763 - (void)viewWillStartLiveResize
764 {
765 [self saveVisibleRange];
766 [super viewWillStartLiveResize];
767 }
768
769 - (void)viewDidEndLiveResize
770 {
771 if (autoScaleOnResizing)
772 [self restoreVisibleRange];
773 [super viewDidEndLiveResize];
774 }
775
776 @end

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26