修订版 | 8 (tree) |
---|---|
时间 | 2011-10-02 01:24:49 |
作者 | toshinagata1964 |
Solo track capability is implemented.
@@ -908,7 +908,7 @@ | ||
908 | 908 | if (MDSequenceSetMuteFlagOnTrack(sequence, trackNo, flag)) { |
909 | 909 | [[[self undoManager] prepareWithInvocationTarget: self] |
910 | 910 | setTrackAttributes: attr]; |
911 | - [self enqueueTrackModifiedNotification: trackNo]; | |
911 | + // [self enqueueTrackModifiedNotification: trackNo]; | |
912 | 912 | [self updateTrackDestinations]; |
913 | 913 | return YES; |
914 | 914 | } |
@@ -924,7 +924,7 @@ | ||
924 | 924 | if (MDSequenceSetSoloFlagOnTrack(sequence, trackNo, flag)) { |
925 | 925 | [[[self undoManager] prepareWithInvocationTarget: self] |
926 | 926 | setTrackAttributes: attr]; |
927 | - [self enqueueTrackModifiedNotification: trackNo]; | |
927 | + // [self enqueueTrackModifiedNotification: trackNo]; | |
928 | 928 | [self updateTrackDestinations]; |
929 | 929 | return YES; |
930 | 930 | } |
@@ -129,6 +129,9 @@ | ||
129 | 129 | // Zoom/unzoom buffer and current position |
130 | 130 | NSMutableArray *zoomUndoBuffer; |
131 | 131 | int zoomUndoIndex; |
132 | + | |
133 | + // Selected tracks when the selection changed last | |
134 | + NSIndexSet *lastSelectedTracks; | |
132 | 135 | } |
133 | 136 | |
134 | 137 | //+ (NSCursor *)horizontalMoveCursor; |
@@ -66,7 +66,7 @@ | ||
66 | 66 | |
67 | 67 | /* IDs for track list tableView */ |
68 | 68 | static NSString *sTableColumnIDs[] = { |
69 | - @"number", @"edit", @"visible", @"name", @"ch", @"mute", @"device" | |
69 | + @"number", @"edit", @"visible", @"name", @"ch", @"solo", @"mute", @"device" | |
70 | 70 | }; |
71 | 71 | |
72 | 72 | enum { |
@@ -75,8 +75,9 @@ | ||
75 | 75 | kVisibleID = 2, |
76 | 76 | kTrackNameID = 3, |
77 | 77 | kChannelID = 4, |
78 | - kMuteID = 5, | |
79 | - kDeviceNameID = 6 | |
78 | + kSoloID = 5, | |
79 | + kMuteID = 6, | |
80 | + kDeviceNameID = 7 | |
80 | 81 | }; |
81 | 82 | |
82 | 83 | static NSImage *sPencilSmallImage = NULL; |
@@ -83,6 +84,11 @@ | ||
83 | 84 | static NSImage *sEyeOpenImage = NULL; |
84 | 85 | static NSImage *sEyeCloseImage = NULL; |
85 | 86 | static NSImage *sSpeakerImage = NULL; |
87 | +static NSImage *sSpeakerGrayImage = NULL; | |
88 | +static NSImage *sMuteImage = NULL; | |
89 | +static NSImage *sMuteNonImage = NULL; | |
90 | +static NSImage *sSoloImage = NULL; | |
91 | +static NSImage *sSoloNonImage = NULL; | |
86 | 92 | |
87 | 93 | static NSString *sNeedsReloadClientViewNotification = @"reload client views"; |
88 | 94 |
@@ -1755,16 +1761,30 @@ | ||
1755 | 1761 | sEyeCloseImage = [[NSImage imageNamed: @"eye_close.png"] retain]; |
1756 | 1762 | if (sSpeakerImage == NULL) |
1757 | 1763 | sSpeakerImage = [[NSImage imageNamed: @"speaker.png"] retain]; |
1758 | - | |
1759 | - for (i = 0; i < 3; i++) { | |
1760 | - static int s[] = {kEditableID, kVisibleID, kMuteID}; | |
1764 | + if (sSpeakerGrayImage == NULL) | |
1765 | + sSpeakerGrayImage = [[NSImage imageNamed: @"speaker_gray.png"] retain]; | |
1766 | + if (sMuteImage == NULL) | |
1767 | + sMuteImage = [[NSImage imageNamed: @"mute.png"] retain]; | |
1768 | + if (sMuteNonImage == NULL) | |
1769 | + sMuteNonImage = [[NSImage imageNamed: @"mute_non.png"] retain]; | |
1770 | + if (sSoloImage == NULL) | |
1771 | + sSoloImage = [[NSImage imageNamed: @"solo.png"] retain]; | |
1772 | + if (sSoloNonImage == NULL) | |
1773 | + sSoloNonImage = [[NSImage imageNamed: @"solo_non.png"] retain]; | |
1774 | + | |
1775 | + for (i = 0; i < 4; i++) { | |
1776 | + static int s[] = {kEditableID, kVisibleID, kSoloID, kMuteID}; | |
1761 | 1777 | // static NSString *n[] = {@"pencil_small.png", @"eye_open.png", @"speaker.png"}; |
1762 | - NSImage *im[] = {sPencilSmallImage, sEyeOpenImage, sSpeakerImage}; | |
1778 | + NSImage *im[] = {sPencilSmallImage, sEyeOpenImage, sSoloImage, sSpeakerImage}; | |
1763 | 1779 | tableColumn = [myTableView tableColumnWithIdentifier: sTableColumnIDs[s[i]]]; |
1764 | 1780 | cell = [[[ColorCell alloc] init] autorelease]; |
1765 | 1781 | [cell setTarget: self]; |
1766 | 1782 | // [cell setAction: @selector(trackTableAction:)]; |
1767 | 1783 | [cell setImage: im[i]]; |
1784 | + if (s[i] == kSoloID) { | |
1785 | + [cell setRepresentedObject:[NSColor colorWithDeviceRed:1.0 green:1.0 blue:0.3 alpha:1.0]]; | |
1786 | + [(ColorCell *)cell setStrokesColor:NO]; | |
1787 | + } | |
1768 | 1788 | [tableColumn setDataCell: cell]; |
1769 | 1789 | [[tableColumn headerCell] setImage: im[i]]; |
1770 | 1790 | } |
@@ -2337,13 +2357,22 @@ | ||
2337 | 2357 | return [[[self document] myMIDISequence] deviceName: rowIndex]; |
2338 | 2358 | case kEditableID: |
2339 | 2359 | case kVisibleID: |
2360 | + case kSoloID: | |
2340 | 2361 | case kMuteID: { |
2341 | 2362 | MDTrackAttribute attr; |
2342 | 2363 | attr = [[[self document] myMIDISequence] trackAttributeAtIndex: rowIndex]; |
2343 | 2364 | if (idnum == kEditableID) { |
2344 | 2365 | return (attr & kMDTrackAttributeEditable ? sPencilSmallImage : nil); |
2366 | + } else if (idnum == kSoloID) { | |
2367 | + // return (attr & kMDTrackAttributeMute ? nil : sSpeakerImage); | |
2368 | + return (attr & kMDTrackAttributeSolo ? sSoloImage : sSoloNonImage); | |
2345 | 2369 | } else if (idnum == kMuteID) { |
2346 | - return (attr & kMDTrackAttributeMute ? nil : sSpeakerImage); | |
2370 | + // return (attr & kMDTrackAttributeMute ? nil : sSpeakerImage); | |
2371 | + if (attr & kMDTrackAttributeMute) | |
2372 | + return nil; | |
2373 | + else if (attr & kMDTrackAttributeMuteBySolo) | |
2374 | + return sSpeakerGrayImage; | |
2375 | + else return sSpeakerImage; | |
2347 | 2376 | } else if (idnum == kVisibleID) { |
2348 | 2377 | return (attr & kMDTrackAttributeHidden ? sEyeCloseImage : sEyeOpenImage); |
2349 | 2378 | } else return nil; |
@@ -2378,16 +2407,15 @@ | ||
2378 | 2407 | |
2379 | 2408 | - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex |
2380 | 2409 | { |
2410 | + MDTrackAttribute attr; | |
2381 | 2411 | int idnum = sTableColumnIDToInt([aTableColumn identifier]); |
2382 | 2412 | if (idnum == kEditableID) { |
2383 | - MDTrackAttribute attr; | |
2384 | 2413 | [aCell setRepresentedObject: [self colorForTrack: rowIndex enabled: YES]]; |
2385 | 2414 | attr = [[[self document] myMIDISequence] trackAttributeAtIndex: rowIndex]; |
2386 | - if (attr & kMDTrackAttributeHidden) { | |
2387 | - [aCell setFillsColor: NO]; | |
2388 | - } else { | |
2389 | - [aCell setFillsColor: YES]; | |
2390 | - } | |
2415 | + [aCell setFillsColor:(attr & kMDTrackAttributeHidden) == 0]; | |
2416 | + } else if (idnum == kSoloID) { | |
2417 | + attr = [[[self document] myMIDISequence] trackAttributeAtIndex: rowIndex]; | |
2418 | + [aCell setFillsColor: (attr & kMDTrackAttributeSolo) != 0]; | |
2391 | 2419 | } else if (idnum == kChannelID || idnum == kDeviceNameID) { |
2392 | 2420 | if (rowIndex == 0) |
2393 | 2421 | [aCell setEnabled: NO]; |
@@ -2472,6 +2500,7 @@ | ||
2472 | 2500 | int idnum; |
2473 | 2501 | NSRect frame; |
2474 | 2502 | BOOL editableTrackWasHidden = NO; |
2503 | + BOOL shiftFlag = (([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) != 0); | |
2475 | 2504 | |
2476 | 2505 | row = [myTableView clickedRow]; |
2477 | 2506 | column = [myTableView clickedColumn]; |
@@ -2494,6 +2523,9 @@ | ||
2494 | 2523 | case kEditableID: |
2495 | 2524 | attrMask = kMDTrackAttributeEditable; |
2496 | 2525 | break; |
2526 | + case kSoloID: | |
2527 | + attrMask = kMDTrackAttributeSolo; | |
2528 | + break; | |
2497 | 2529 | case kMuteID: |
2498 | 2530 | attrMask = kMDTrackAttributeMute; |
2499 | 2531 | break; |
@@ -2543,7 +2575,6 @@ | ||
2543 | 2575 | return; |
2544 | 2576 | switch (idnum) { |
2545 | 2577 | case kEditableID: { |
2546 | - BOOL shiftFlag = (([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) != 0); | |
2547 | 2578 | attr = [seq trackAttributeAtIndex: row]; |
2548 | 2579 | if (attr & kMDTrackAttributeHidden) |
2549 | 2580 | break; |
@@ -2557,6 +2588,9 @@ | ||
2557 | 2588 | case kMuteID: |
2558 | 2589 | [doc setMuteFlagOnTrack: row flag: -1]; |
2559 | 2590 | break; |
2591 | + case kSoloID: | |
2592 | + [doc setSoloFlagOnTrack: row flag: -1]; | |
2593 | + break; | |
2560 | 2594 | case kVisibleID: |
2561 | 2595 | attr = [seq trackAttributeAtIndex: row]; |
2562 | 2596 | if (attr & kMDTrackAttributeHidden) { |
@@ -2636,6 +2670,8 @@ | ||
2636 | 2670 | } */ |
2637 | 2671 | /* Rebuild sortedTrackNumbers later */ |
2638 | 2672 | visibleTrackCount = -1; |
2673 | + [lastSelectedTracks release]; | |
2674 | + lastSelectedTracks = [[NSIndexSet alloc] initWithIndexSet:[myTableView selectedRowIndexes]]; | |
2639 | 2675 | [self setNeedsReloadClientViews]; |
2640 | 2676 | } |
2641 | 2677 |
@@ -19,8 +19,10 @@ | ||
19 | 19 | |
20 | 20 | @interface ColorCell : NSActionCell { |
21 | 21 | BOOL noFillsColor; |
22 | + BOOL noStrokesColor; | |
22 | 23 | } |
23 | 24 | - (BOOL)fillsColor; |
24 | 25 | - (void)setFillsColor: (BOOL)flag; |
25 | - | |
26 | +- (BOOL)strokesColor; | |
27 | +- (void)setStrokesColor: (BOOL)flag; | |
26 | 28 | @end |
@@ -36,10 +36,10 @@ | ||
36 | 36 | rep = [self representedObject]; |
37 | 37 | if (rep != nil && [rep isKindOfClass: [NSColor class]]) { |
38 | 38 | [rep set]; |
39 | - if (noFillsColor) | |
39 | + if (!noFillsColor) | |
40 | + NSRectFill(cellFrame); | |
41 | + else if (!noStrokesColor) | |
40 | 42 | NSFrameRect(cellFrame); |
41 | - else | |
42 | - NSRectFill(cellFrame); | |
43 | 43 | } |
44 | 44 | image = [self objectValue]; |
45 | 45 | if (image != nil && [image isKindOfClass: [NSImage class]]) { |
@@ -63,4 +63,14 @@ | ||
63 | 63 | noFillsColor = !flag; |
64 | 64 | } |
65 | 65 | |
66 | +- (BOOL)strokesColor | |
67 | +{ | |
68 | + return !noStrokesColor; | |
69 | +} | |
70 | + | |
71 | +- (void)setStrokesColor: (BOOL)flag | |
72 | +{ | |
73 | + noStrokesColor = !flag; | |
74 | +} | |
75 | + | |
66 | 76 | @end |
@@ -241,7 +241,10 @@ | ||
241 | 241 | if (mySequence != NULL) { |
242 | 242 | MDTrack *track = MDSequenceGetTrack(mySequence, index); |
243 | 243 | if (track != NULL) { |
244 | + MDTrackAttribute oldAttr = MDTrackGetAttribute(track); | |
244 | 245 | MDTrackSetAttribute(track, attribute); |
246 | + if ((oldAttr & kMDTrackAttributeSolo) != (attribute & kMDTrackAttributeSolo)) | |
247 | + MDSequenceUpdateMuteBySoloFlag(mySequence); | |
245 | 248 | } |
246 | 249 | } |
247 | 250 | } |
@@ -105,6 +105,9 @@ | ||
105 | 105 | /* index 番目のトラックの Mute フラグをセットする。flag = 0: OFF, 1: ON, -1: toggle */ |
106 | 106 | int MDSequenceSetMuteFlagOnTrack(MDSequence *inSequence, long index, int flag); |
107 | 107 | |
108 | +/* MuteBySolo フラグを更新する。Solo フラグを変更したあと呼び出す。 */ | |
109 | +void MDSequenceUpdateMuteBySoloFlag(MDSequence *inSequence); | |
110 | + | |
108 | 111 | /* Record フラグが立っているトラックの番号を得る。なければ -1 を返す。 */ |
109 | 112 | long MDSequenceGetIndexOfRecordingTrack(MDSequence *inSequence); |
110 | 113 |
@@ -1511,10 +1511,6 @@ | ||
1511 | 1511 | if (inPlayer == NULL || inPlayer->merger == NULL || (sequence = MDMergerGetSequence(inPlayer->merger)) == NULL) |
1512 | 1512 | return kMDNoError; |
1513 | 1513 | |
1514 | - oldTick = MDCalibratorTimeToTick(inPlayer->calib, inPlayer->time); | |
1515 | - | |
1516 | - MDMergerReset(inPlayer->merger); | |
1517 | - | |
1518 | 1514 | num = MDSequenceGetNumberOfTracks(sequence); |
1519 | 1515 | inPlayer->trackNum = num; |
1520 | 1516 | inPlayer->destIndex = (long *)re_malloc(inPlayer->destIndex, num * sizeof(long)); |
@@ -1531,12 +1527,12 @@ | ||
1531 | 1527 | if (temp == NULL) |
1532 | 1528 | return kMDErrorOutOfMemory; |
1533 | 1529 | |
1534 | - MDSequenceLock(sequence); | |
1535 | - | |
1536 | 1530 | for (i = 0; i < inPlayer->destNum; i++) |
1537 | 1531 | temp[i] = inPlayer->destInfo[i]->dev; |
1538 | 1532 | origDestNum = inPlayer->destNum; |
1539 | 1533 | |
1534 | + MDSequenceLock(sequence); | |
1535 | + | |
1540 | 1536 | /* Update destIndex[] and destChannel[] */ |
1541 | 1537 | for (n = 0; n < num; n++) { |
1542 | 1538 | MDTrack *track; |
@@ -1571,10 +1567,11 @@ | ||
1571 | 1567 | if (inPlayer->destInfo == NULL) { |
1572 | 1568 | status = kMDErrorOutOfMemory; |
1573 | 1569 | } else { |
1570 | + oldTick = MDCalibratorTimeToTick(inPlayer->calib, inPlayer->time); | |
1571 | + /* MDMergerReset(inPlayer->merger); */ | |
1574 | 1572 | for (i = origDestNum; i < inPlayer->destNum; i++) |
1575 | 1573 | inPlayer->destInfo[i] = MDPlayerNewDestinationInfo(temp[i]); |
1576 | - | |
1577 | - MDPlayerJumpToTick(inPlayer, oldTick); | |
1574 | + /* MDPlayerJumpToTick(inPlayer, oldTick); */ | |
1578 | 1575 | status = kMDNoError; |
1579 | 1576 | } |
1580 | 1577 |
@@ -1589,8 +1586,8 @@ | ||
1589 | 1586 | MDStatus |
1590 | 1587 | MDPlayerJumpToTick(MDPlayer *inPlayer, MDTickType inTick) |
1591 | 1588 | { |
1592 | - if (inPlayer->status == kMDPlayer_playing || inPlayer->status == kMDPlayer_exhausted) | |
1593 | - MDPlayerStop(inPlayer); | |
1589 | +/* if (inPlayer->status == kMDPlayer_playing || inPlayer->status == kMDPlayer_exhausted) | |
1590 | + MDPlayerStop(inPlayer); */ | |
1594 | 1591 | MDMergerJumpToTick(inPlayer->merger, inTick); |
1595 | 1592 | MDCalibratorJumpToTick(inPlayer->calib, inTick); |
1596 | 1593 | /* inPlayer->tick = inTick; */ |
@@ -258,7 +258,7 @@ | ||
258 | 258 | #pragma mark ====== MDTrack attribute manipulations ====== |
259 | 259 | #endif |
260 | 260 | |
261 | -static void | |
261 | +void | |
262 | 262 | MDSequenceUpdateMuteBySoloFlag(MDSequence *inSequence) |
263 | 263 | { |
264 | 264 | MDTrack *track; |
@@ -682,17 +682,19 @@ | ||
682 | 682 | void |
683 | 683 | MDSequenceLock(MDSequence *inSequence) |
684 | 684 | { |
685 | + int n; | |
685 | 686 | if (inSequence == NULL || inSequence->mutex == NULL) |
686 | 687 | return; |
687 | - pthread_mutex_lock(inSequence->mutex); | |
688 | + n = pthread_mutex_lock(inSequence->mutex); | |
688 | 689 | } |
689 | 690 | |
690 | 691 | void |
691 | 692 | MDSequenceUnlock(MDSequence *inSequence) |
692 | 693 | { |
694 | + int n; | |
693 | 695 | if (inSequence == NULL || inSequence->mutex == NULL) |
694 | 696 | return; |
695 | - pthread_mutex_unlock(inSequence->mutex); | |
697 | + n = pthread_mutex_unlock(inSequence->mutex); | |
696 | 698 | } |
697 | 699 | |
698 | 700 | int |