2 // ElisTimeLineController.m
5 // Created by 柳 on 09/09/12.
6 // Copyright 2009 __MyCompanyName__. All rights reserved.
9 #import "ElisTimeLineController.h"
12 @implementation ElisTimeLineController
16 NSLog(@"Building TimeLine ...");
18 CGImageRef bar, trblack;
19 NSBundle *bundle = [NSBundle mainBundle];
20 bar = [[NSBitmapImageRep imageRepWithContentsOfFile:[bundle pathForResource:@"white" ofType:@"jpg"]] CGImage];
21 trblack = [[NSBitmapImageRep imageRepWithContentsOfFile:[bundle pathForResource:@"trackgray" ofType:@"jpg"]] CGImage];
23 timeLineScale = 10.0; // 10倍表示
25 rootLayer = [CALayer layer];
26 timeLine = [CALayer layer];
27 playbackBar = [CALayer layer];
29 rootLayer.backgroundColor = CGColorCreateGenericGray(0, 0.4f);
30 playbackBar.contents = (id)bar;
31 playbackBar.frame = CGRectMake(0, 0, 1, 51*TRACK_MAX);
35 for(i = 0; i < TRACK_MAX; i++){
36 track = [CALayer layer];
37 track.frame = CGRectMake(0, 51*i+1, [_timeLineView frame].size.width, 50);
38 track.contents = (id)trblack;
40 track.autoresizingMask = kCALayerWidthSizable;
41 [timeLine addSublayer:track];
43 timeLine.autoresizingMask = kCALayerWidthSizable;
45 NSRect r = [_timeLineView frame];
46 [_timeLineView setFrame:NSMakeRect(0, 0, 10*60*timeLineScale, 51*TRACK_MAX)];
47 rootLayer.frame = *(CGRect*)&r;
48 rootLayer.masksToBounds = YES;
50 [rootLayer addSublayer:timeLine];
51 [rootLayer addSublayer:playbackBar];
52 [_timeLineView setLayer:rootLayer];
53 [_timeLineView setWantsLayer:YES];
56 clickedPosition.x = -1;
58 _layerFactory = [[ElisAnimationLayerFactory alloc] init];
61 - (void)movePlaybackBar:(float)p
63 // 自動スクロールはうまくできないので無効にしてある。
65 // NSRect r = [_timeLineView visibleRect];
66 // if(p > r.origin.x){
68 // [_timeLineView scrollPoint:r.origin];
70 [CATransaction begin];
71 [CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration];
72 CGPoint po = playbackBar.position;
74 playbackBar.position = po;
75 [CATransaction commit];
78 - (void)addMedia:(NSString*)path
80 CALayer* newLayer = [_mainController createNewLayer:path];
81 if(draggingLayer) draggingLayer.opacity = 0.75;
82 draggingLayer = newLayer;
83 [timeLine addSublayer:newLayer];
86 - (void)dragging:(NSPoint)point
88 if(draggingLayer == nil) return;
90 if(stretch == STRETCH_RIGHT){
91 CGRect rect = draggingLayer.frame;
92 float dx = point.x - rect.origin.x - rect.size.width;
93 rect.size.width += dx;
94 if([[draggingLayer valueForKey:@"ElisLayer"] canChangeMapping:rect]){
95 [self changeLayerFrame:draggingLayer rect:rect];
98 } else if (stretch == STRETCH_LEFT){
99 CGRect rect = draggingLayer.frame;
100 float dx = point.x - rect.origin.x;
101 if([[draggingLayer valueForKey:@"ElisLayer"] canChangeOffset:dx]){
102 [[draggingLayer valueForKey:@"ElisLayer"] changeOffset:dx];
103 rect.size.width -= dx;
104 [self changeLayerFrame:draggingLayer rect:rect];
105 [_mainController refresh];
110 if(dragging == NO) dragging = YES;
111 if(clickedPosition.x == -1){
115 float dx = clickedPosition.x - point.x;
116 float dy = clickedPosition.y - point.y;
117 point = NSMakePoint(clickedLayerPosition.x - dx, clickedLayerPosition.y - dy);
119 [self changeLayerPosition:draggingLayer position:point];
124 if(draggingLayer == nil) return;
126 CGPoint point = draggingLayer.position;
127 point.y = floor(point.y/51.0) * 51 + 1 + 25; // +25ってどこから出てきた?
128 draggingLayer.position = point;
129 draggingLayer.opacity = 0.75;
131 clickedPosition.x = -1;
133 // [_timeLineView setCursorRect:NSZeroRect]; // これなに?
135 [_timeLineView setCursorRect:draggingLayer.frame];
139 - (void)changeLayerPosition:(CALayer*)layer position:(NSPoint)point
141 [CATransaction begin];
142 [CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration];
143 CGRect r = layer.frame;
144 r.origin.x = point.x;
145 r.origin.y = point.y;
146 layer.frame = r; // KVOでCALayerに対応してElisLayerも変化
147 [CATransaction commit];
148 [_mainController refresh]; // ElisLayerの構造が変わったので再描画を要請。ループしないよう注意。
151 - (void)changeLayerFrame:(CALayer*)layer rect:(CGRect)rect
153 [CATransaction begin];
154 [CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration];
156 [CATransaction commit];
157 [_mainController refresh];
160 - (IBAction)add:(id)sender
162 [self addMedia:@"/Users/yanagi/Desktop/59926_2_m1_1.mp4"];
163 NSValue* v = [draggingLayer valueForKey:@"frame"];
164 NSRect r = [v rectValue];
166 // [draggingLayer willChangeValueForKey:@"frame"];
167 [draggingLayer setValue:[NSValue valueWithRect:r] forKey:@"frame"];
168 // [draggingLayer didChangeValueForKey:@"frame"];
171 - (void)clicked:(NSPoint)point
174 draggingLayer.opacity = 0.75;
181 layers = [timeLine sublayers];
182 size = [layers count];
185 for(i = TRACK_MAX; i < size; i++){
186 if([self isInclude:[layers objectAtIndex:i] point:point]){
187 draggingLayer = [layers objectAtIndex:i];
188 draggingLayer.opacity = 1.0;
189 clickedPosition = point;
190 clickedLayerPosition = draggingLayer.frame.origin;
191 [_timeLineView setCursorRect:draggingLayer.frame];
192 [_tableController createPropertyTable:[draggingLayer valueForKey:@"ElisLayer"]];
193 [_tableController reload];
194 [_mainController refresh];
199 draggingLayer.opacity = 0.75;
202 clickedPosition.x = -1; // "レイヤーは選択されていない" という意味。
206 - (void)doubleClicked
208 if(draggingLayer == nil) return;
209 if([[draggingLayer valueForKey:@"have keyframeLayer"] boolValue]){
211 [[[draggingLayer sublayers] lastObject] removeFromSuperlayer];
212 [draggingLayer setValue:[NSNumber numberWithBool:NO] forKey:@"have keyframeLayer"];
213 [_layerFactory removeParentLayer]; // 参照を切る = GCで回収されるようにする
217 CALayer* keyframeLayer;
218 keyframeLayer = [_layerFactory createKeyframeLayerWithLayer:draggingLayer];
220 float size = draggingLayer.frame.size.width;
225 [draggingLayer addSublayer:keyframeLayer];
226 [draggingLayer setValue:[NSNumber numberWithBool:YES] forKey:@"have keyframeLayer"];
228 if([_tableController isSelected] == NO) return;
230 for(x = 0.0; x < size-1; x += MINI_LAYER_WIDTH){
231 miniLayer = [_layerFactory createKeyframeLevelLayer];
233 r.size.height = 100 * [_tableController getSelectedValueForTime:x];
236 [keyframeLayer addSublayer:miniLayer];
241 - (void)updateKeyframeLayer
243 if(draggingLayer == nil) return;
244 if([[draggingLayer valueForKey:@"have keyframeLayer"] boolValue] == NO) return;
247 minis = [[[draggingLayer sublayers] lastObject] sublayers];
251 int i, size = [minis count];
252 for(i = 0; i < size; i++){
253 mini = [minis objectAtIndex:i];
255 r.size.height = 100 * [_tableController getSelectedValueForTime:i * MINI_LAYER_WIDTH];
260 // 左側のマッピングを調整する。(レイヤー内オフセットをいじる)
263 stretch = STRETCH_LEFT;
266 // 右側のマッピングを調整する。(マッピングの範囲を変えるだけ)
269 stretch = STRETCH_RIGHT;
272 - (BOOL)isInclude:(CALayer*)layer point:(NSPoint)point
274 CGRect r = layer.frame;
275 return r.origin.x <= point.x && point.x <= r.origin.x + r.size.width
276 && r.origin.y <= point.y && point.y <= r.origin.y + r.size.height;
279 - (CALayer*)getSelectLayer
281 return draggingLayer;
284 - (void)removeSelectLayer
286 [draggingLayer setValue:nil forKey:@"ElisLayer"];