• R/O
  • SSH
  • HTTPS

alchemusica: 提交


Commit MetaInfo

修订版200 (tree)
时间2022-04-07 23:14:06
作者toshinagata1964

Log Message

Add/sub and scale tools in strip chart views are improved

更改概述

差异

--- trunk/Classes/GraphicClientView.m (revision 199)
+++ trunk/Classes/GraphicClientView.m (revision 200)
@@ -57,11 +57,45 @@
5757 [super dealloc];
5858 }
5959
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+
6076 - (void)setDataSource: (id)object
6177 {
6278 if (dataSource != nil)
6379 [dataSource release];
6480 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];
6599 }
66100
67101 - (id)dataSource
--- trunk/Classes/GraphicWindowController.m (revision 199)
+++ trunk/Classes/GraphicWindowController.m (revision 200)
@@ -1954,6 +1954,7 @@
19541954
19551955 - (IBAction)modeSelected: (id)sender
19561956 {
1957+ int index;
19571958 switch ([sender tag]) {
19581959 case kSetMenuTag: graphicEditingMode = kGraphicSetMode; break;
19591960 case kAddMenuTag: graphicEditingMode = kGraphicAddMode; break;
@@ -1961,6 +1962,11 @@
19611962 case kLimitMaxMenuTag: graphicEditingMode = kGraphicLimitMaxMode; break;
19621963 case kLimitMinMenuTag: graphicEditingMode = kGraphicLimitMinMode; break;
19631964 }
1965+ // Redraw the strip chart views
1966+ for (index = 0; index < myClientViewsCount; index++) {
1967+ if ([records[index].client isKindOfClass: [StripChartView class]])
1968+ [records[index].client setNeedsDisplay:YES];
1969+ }
19641970 }
19651971
19661972 - (IBAction)quantizeSelected: (id)sender
--- trunk/Classes/StripChartView.h (revision 199)
+++ trunk/Classes/StripChartView.h (revision 200)
@@ -45,6 +45,9 @@
4545 int32_t initialDraggedTick; // The initial tick value of the dragged event
4646 int deltaDraggedValue;
4747 int32_t deltaDraggedTick;
48+
49+ // The center y coordinate when dragging is started; this is the baseline for add/sub or scale tool
50+ CGFloat centerY;
4851 }
4952
5053 - (void)setKindAndCode: (int32_t)kindAndCode;
--- trunk/Classes/StripChartView.m (revision 199)
+++ trunk/Classes/StripChartView.m (revision 200)
@@ -78,6 +78,39 @@
7878 }
7979 */
8080
81+- (void)updateCenterY
82+{
83+ NSRect bounds = [[self superview] bounds];
84+ float y = floor(bounds.origin.y + bounds.size.height * 0.5);
85+ // Round to the nearest Y value
86+ float newCenterY = [self convertFromYValue:[self convertToYValue:y]] + 0.5;
87+ // If lineShape > 0, then we do not update the baseline
88+ if (lineShape == 0 && centerY != newCenterY) {
89+ [self invalidateCenterLine];
90+ centerY = newCenterY;
91+ [self invalidateCenterLine];
92+ }
93+}
94+
95+// Respond when the scroll position changed
96+- (void)superBoundsDidChange: (NSNotification *)aNotification
97+{
98+ [self updateCenterY];
99+}
100+
101+// Respond when the frame of the superview changed
102+// i.e. the scroll view containing the client view is resized
103+- (void)superFrameDidChange: (NSNotification *)aNotification
104+{
105+ [self updateCenterY];
106+}
107+
108+// Respond when the frame of the client view, i.e. data range and/or scale are changed
109+- (void)frameDidChange: (NSNotification *)aNotification
110+{
111+ [self updateCenterY];
112+}
113+
81114 static float
82115 getYValue(const MDEvent *ep, int eventKind)
83116 {
@@ -90,6 +123,18 @@
90123 else return MDGetData1(ep);
91124 }
92125
126+- (CGFloat)convertFromYValue:(float)yValue
127+{
128+ NSRect bounds = [self bounds];
129+ return (CGFloat)(floor(bounds.origin.y + (yValue - minValue) * ((bounds.size.height - sVerticalMargin * 2) / (maxValue - minValue)) + 0.5) + sVerticalMargin);
130+}
131+
132+- (float)convertToYValue:(CGFloat)y
133+{
134+ NSRect bounds = [self bounds];
135+ return (float)(floor((y - bounds.origin.y - sVerticalMargin) * (maxValue - minValue) / (bounds.size.height - sVerticalMargin * 2) + 0.5) + minValue);
136+}
137+
93138 - (void)drawVelocityInRect: (NSRect)aRect
94139 {
95140 float ppt, height;
@@ -135,7 +180,8 @@
135180 while ((ep = MDPointerForward(pt)) != NULL && MDGetTick(ep) < endTick) {
136181 if (MDGetKind(ep) != kMDEventNote)
137182 continue;
138- y = (float)(ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2)) + 0.5) + sVerticalMargin;
183+ //y = (float)(ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2)) + 0.5) + sVerticalMargin;
184+ y = [self convertFromYValue:getYValue(ep, eventKind)];
139185 x = (float)(floor(MDGetTick(ep) * ppt) + 0.5);
140186 if (y >= aRect.origin.y) {
141187 if ([[dataSource document] isSelectedAtPosition: MDPointerGetPosition(pt) inTrack: trackNo]) {
@@ -229,7 +275,8 @@
229275 xlast = ylast = 0;
230276 poslast = -1;
231277 } else {
232- ylast = (float)(ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2))) + sVerticalMargin;
278+ //ylast = (float)(ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2))) + sVerticalMargin;
279+ ylast = [self convertFromYValue:getYValue(ep, eventKind)];
233280 xlast = (float)(floor(MDGetTick(ep) * ppt));
234281 poslast = MDPointerGetPosition(pt);
235282 }
@@ -240,7 +287,8 @@
240287 continue;
241288 if (eventCode != -1 && MDGetCode(ep) != eventCode)
242289 continue;
243- y = (float)(ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2))) + sVerticalMargin;
290+ //y = (float)(ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2))) + sVerticalMargin;
291+ y = [self convertFromYValue:getYValue(ep, eventKind)];
244292 x = (float)(floor(MDGetTick(ep) * ppt));
245293 } else {
246294 x = [self bounds].size.width;
@@ -329,9 +377,27 @@
329377 [[NSColor lightGrayColor] set];
330378 for (y = minValue; y <= maxValue + 1; y += grid) {
331379 float y0 = (y > maxValue ? maxValue : y);
332- pt.y = (CGFloat)(floor(bounds.origin.y + y0 * ((bounds.size.height - sVerticalMargin * 2) / (maxValue - minValue)) + sVerticalMargin) + 0.5);
380+ //pt.y = (CGFloat)(floor(bounds.origin.y + y0 * ((bounds.size.height - sVerticalMargin * 2) / (maxValue - minValue)) + sVerticalMargin) + 0.5);
381+ pt.y = [self convertFromYValue:y0];
333382 [NSBezierPath strokeLineFromPoint: pt toPoint: NSMakePoint(pt.x + bounds.size.width, pt.y)];
334383 }
384+ int editingMode = [[self dataSource] graphicEditingMode];
385+ if (editingMode == kGraphicAddMode || editingMode == kGraphicScaleMode) {
386+ // Draw baseline
387+ pt.y = centerY;
388+ if (pt.y >= bounds.origin.y && pt.y < bounds.origin.y + bounds.size.height) {
389+ float saveLineWidth = [NSBezierPath defaultLineWidth];
390+ [NSBezierPath setDefaultLineWidth: saveLineWidth * 2];
391+ [[NSColor colorWithDeviceRed:1.0 green:1.0 blue:1.0 alpha:0.5] set];
392+ [NSBezierPath strokeLineFromPoint: pt toPoint: NSMakePoint(pt.x + bounds.size.width, pt.y)];
393+ [NSBezierPath setDefaultLineWidth: saveLineWidth];
394+ if (editingMode == kGraphicAddMode)
395+ [[NSColor blueColor] set];
396+ else
397+ [[NSColor redColor] set];
398+ [NSBezierPath strokeLineFromPoint: pt toPoint: NSMakePoint(pt.x + bounds.size.width, pt.y)];
399+ }
400+ }
335401 if ([self isDragging])
336402 [self drawSelectRegion];
337403 }
@@ -402,6 +468,7 @@
402468 [self reloadData];
403469 [self setNeedsDisplay: YES];
404470 }
471+ [self updateCenterY];
405472 }
406473
407474 - (BOOL)isFocusTrack: (int)trackNum
@@ -476,6 +543,16 @@
476543 [self setNeedsDisplayInRect: rect];
477544 }
478545
546+// Invalidate the region including the center line
547+// (Should be only called when centerY is valid, i.e. during add/sub or scale dragging)
548+- (void)invalidateCenterLine
549+{
550+ NSRect rect = [self bounds];
551+ rect.origin.y = centerY - 1;
552+ rect.size.height = 2;
553+ [self setNeedsDisplayInRect: rect];
554+}
555+
479556 - (NSRect)boundRectForSelection
480557 {
481558 int i, n;
@@ -569,7 +646,8 @@
569646 xlast = ylast = 0;
570647 poslast = -1;
571648 } else {
572- ylast = (float)ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2)) + sVerticalMargin;
649+ //ylast = (float)ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2)) + sVerticalMargin;
650+ ylast = [self convertFromYValue:getYValue(ep, eventKind)];
573651 xlast = (float)floor(MDGetTick(ep) * ppt);
574652 poslast = MDPointerGetPosition(pt);
575653 }
@@ -580,7 +658,8 @@
580658 continue;
581659 if (eventCode != -1 && MDGetCode(ep) != eventCode)
582660 continue;
583- y = (float)ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2)) + sVerticalMargin;
661+ //y = (float)ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - sVerticalMargin * 2)) + sVerticalMargin;
662+ y = [self convertFromYValue:getYValue(ep, eventKind)];
584663 x = (float)floor(MDGetTick(ep) * ppt);
585664 } else {
586665 x = [self bounds].size.width + 2;
@@ -777,7 +856,7 @@
777856 - (int)modifyLocalGraphicTool:(int)originalGraphicTool
778857 {
779858 NSEvent *event = [NSApp currentEvent];
780- NSUInteger flags = [event modifierFlags];
859+ NSUInteger flags = (isDragging ? initialModifierFlags : [event modifierFlags]);
781860 int tool = originalGraphicTool;
782861 if ((flags & NSCommandKeyMask) != 0) {
783862 if (tool == kGraphicPencilTool)
@@ -800,7 +879,7 @@
800879 float fromValue, toValue;
801880 float pixelsPerTick, height;
802881 const float *p;
803- int v1, v2;
882+ float v1, v2;
804883 int editingMode;
805884 BOOL shiftFlag = (([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) != 0);
806885 MyDocument *doc = (MyDocument *)[dataSource document];
@@ -817,8 +896,10 @@
817896 height = [self bounds].size.height;
818897 t1 = (MDTickType)floor(pt1.x / pixelsPerTick + 0.5);
819898 t2 = (MDTickType)floor(pt2.x / pixelsPerTick + 0.5);
820- v1 = (int)floor((pt1.y - sVerticalMargin) * (maxValue - minValue) / (height - sVerticalMargin * 2) + 0.5 + minValue);
821- v2 = (int)floor((pt2.y - sVerticalMargin) * (maxValue - minValue) / (height - sVerticalMargin * 2) + 0.5 + minValue);
899+ //v1 = (int)floor((pt1.y - sVerticalMargin) * (maxValue - minValue) / (height - sVerticalMargin * 2) + 0.5 + minValue);
900+ //v2 = (int)floor((pt2.y - sVerticalMargin) * (maxValue - minValue) / (height - sVerticalMargin * 2) + 0.5 + minValue);
901+ v1 = [self convertToYValue:pt1.y];
902+ v2 = [self convertToYValue:pt2.y];
822903 if (v1 < minValue)
823904 v1 = minValue;
824905 if (v2 < minValue)
@@ -1068,7 +1149,7 @@
10681149 y = cubicFunc(t, pp + 1);
10691150 } else break;
10701151 } else break;
1071- v = (float)floor(y * (v2 - v1) + v1 + 0.5);
1152+ v = y * (v2 - v1) + v1;
10721153 }
10731154 switch (eventKind) {
10741155 case kMDEventNote:
@@ -1085,15 +1166,22 @@
10851166 break;
10861167 }
10871168 if (editingMode == kGraphicAddMode) {
1088- /* The vertical center will be zero */
1089- v = v0 + v - (maxValue - minValue + 1) * 0.5f;
1169+ // The center line will be zero
1170+ float cy = [self convertToYValue:centerY];
1171+ v = v0 + floor(v + 0.5 - cy);
10901172 } else if (editingMode == kGraphicScaleMode) {
1091- /* The full scale is 0..200% */
1092- v = v0 * (v - minValue) / (maxValue - minValue + 1) * 2.0f;
1173+ // The visible vertical range is 0..200%
1174+ float visibleHeight = [[self superview] bounds].size.height;
1175+ float cy = [self convertToYValue:centerY];
1176+ float fully = [self convertToYValue:(centerY + visibleHeight * 0.5)];
1177+ if (fully > cy)
1178+ v = floor(v0 * ((v - cy) / (fully - cy) + 1.0) + 0.5);
10931179 } else if (editingMode == kGraphicLimitMaxMode) {
1180+ v = floor(v + 0.5);
10941181 if (v0 < v)
10951182 v = v0;
10961183 } else if (editingMode == kGraphicLimitMinMode) {
1184+ v = floor(v + 0.5);
10971185 if (v0 > v)
10981186 v = v0;
10991187 }
@@ -1116,7 +1204,7 @@
11161204 - (NSString *)infoTextForMousePoint:(NSPoint)pt dragging:(BOOL)flag option:(int *)option
11171205 {
11181206 int yval;
1119- NSString *s;
1207+ NSString *s = nil;
11201208 if (option != NULL)
11211209 *option = 0;
11221210 if (stripDraggingMode > 0) {
@@ -1127,12 +1215,30 @@
11271215 *option = 1;
11281216 return s;
11291217 }
1130- yval = (int)floor((maxValue - minValue) * (pt.y - sVerticalMargin) / ([self frame].size.height - sVerticalMargin * 2) + minValue + 0.5);
1218+ //yval = (int)floor((maxValue - minValue) * (pt.y - sVerticalMargin) / ([self frame].size.height - sVerticalMargin * 2) + minValue + 0.5);
1219+ yval = [self convertToYValue:pt.y];
11311220 if (yval < minValue)
11321221 yval = minValue;
11331222 if (yval > maxValue)
11341223 yval = maxValue;
1135- s = [[NSString stringWithFormat:@"%d, ", yval] stringByAppendingString:[super infoTextForMousePoint:pt dragging:flag option:option]];
1224+ if (localGraphicTool == kGraphicPencilTool) {
1225+ int editingMode = [[self dataSource] graphicEditingMode];
1226+ float cy = [self convertToYValue:centerY];
1227+ if (editingMode == kGraphicAddMode) {
1228+ s = [NSString stringWithFormat:@"%+d, ", (int)(floor(yval + 0.5 - cy))];
1229+ } else if (editingMode == kGraphicScaleMode) {
1230+ float visibleHeight = [[self superview] bounds].size.height;
1231+ float fully = [self convertToYValue:(centerY + visibleHeight * 0.5)];
1232+ if (fully > cy)
1233+ yval = floor(((yval - cy) / (fully - cy) + 1.0) * 100);
1234+ else yval = 100;
1235+ s = [NSString stringWithFormat:@"%d%%, ", yval];
1236+ }
1237+ }
1238+ if (s == nil) {
1239+ s = [NSString stringWithFormat:@"%d, ", yval];
1240+ }
1241+ s = [s stringByAppendingString:[super infoTextForMousePoint:pt dragging:flag option:option]];
11361242 if (!flag) {
11371243 return s;
11381244 } else {
@@ -1155,6 +1261,17 @@
11551261 localGraphicTool = [self modifyLocalGraphicTool:[[self dataSource] graphicTool]];
11561262 if (localGraphicTool == kGraphicPencilTool) {
11571263 [[NSCursor pencilCursor] set];
1264+ // Set the vertical center of the visible rect
1265+/* NSRect bounds = [[self superview] bounds];
1266+ float y = floor(bounds.origin.y + bounds.size.height * 0.5);
1267+ // Round to the nearest Y value
1268+ float newCenterY = [self convertFromYValue:[self convertToYValue:y]] + 0.5;
1269+ if (centerY != newCenterY) {
1270+ [self invalidateCenterLine];
1271+ centerY = newCenterY;
1272+ [self invalidateCenterLine];
1273+ [self displayIfNeeded];
1274+ } */
11581275 return;
11591276 }
11601277 n = [self findStripUnderPoint: pt track: &track position: &pos mdEvent: &ep];
@@ -1210,6 +1327,7 @@
12101327 // for this class.
12111328 [super doMouseDown: theEvent];
12121329 lineShape = [[self dataSource] graphicLineShape];
1330+ [self invalidateCenterLine];
12131331 return;
12141332 }
12151333
@@ -1260,6 +1378,8 @@
12601378 // for this class.
12611379 if (lineShape > 0) {
12621380 [super doMouseDragged: theEvent];
1381+ // Redraw the baseline region
1382+ [self invalidateCenterLine];
12631383 return;
12641384 }
12651385
@@ -1332,6 +1452,7 @@
13321452 if (lineShape > 0) {
13331453 [self doPencilEdit];
13341454 lineShape = 0;
1455+ [self updateCenterY];
13351456 return;
13361457 }
13371458
@@ -1387,7 +1508,9 @@
13871508 continue;
13881509 if (eventCode != -1 && MDGetCode(ep) != eventCode)
13891510 continue;
1390- point.y = (CGFloat)ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - 2)) + 1;
1511+
1512+ // point.y = (CGFloat)ceil((getYValue(ep, eventKind) - minValue) / (maxValue - minValue) * (height - 2)) + 1;
1513+ point.y = [self convertFromYValue:getYValue(ep, eventKind)];
13911514 point.x = (CGFloat)floor(MDGetTick(ep) * ppt);
13921515 // point.x = floor(MDGetTick(ep) * ppt);
13931516 // point.y = floor(MDGetCode(ep) * ys + 0.5) + 0.5 * ys;
Show on old repository browser