OSDN Git Service

first commit
[eliscolors/main.git] / ElisTimeLineController.m
1 //
2 //  ElisTimeLineController.m
3 //  Elis Colors
4 //
5 //  Created by 柳 on 09/09/12.
6 //  Copyright 2009 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "ElisTimeLineController.h"
10
11
12 @implementation ElisTimeLineController
13
14 - (void)awakeFromNib
15 {
16     NSLog(@"Building TimeLine ...");
17     
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];
22
23     timeLineScale = 10.0; // 10倍表示
24     
25     rootLayer = [CALayer layer];
26     timeLine = [CALayer layer];
27     playbackBar = [CALayer layer];
28     
29     rootLayer.backgroundColor = CGColorCreateGenericGray(0, 0.4f);
30     playbackBar.contents = (id)bar;
31     playbackBar.frame = CGRectMake(0, 0, 1, 51*TRACK_MAX);
32     
33     int i;
34     CALayer* track;
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;
39         track.opacity = 0.35;
40         track.autoresizingMask = kCALayerWidthSizable;
41         [timeLine addSublayer:track];
42     }
43     timeLine.autoresizingMask = kCALayerWidthSizable;
44     
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;
49     
50     [rootLayer addSublayer:timeLine];
51     [rootLayer addSublayer:playbackBar];
52     [_timeLineView setLayer:rootLayer];
53     [_timeLineView setWantsLayer:YES];
54
55     draggingLayer = nil;
56     clickedPosition.x = -1;
57     dragging = NO;
58     _layerFactory = [[ElisAnimationLayerFactory alloc] init];
59 }
60
61 - (void)movePlaybackBar:(float)p
62 {
63     // 自動スクロールはうまくできないので無効にしてある。
64     // 再生中にフリーズするよ! よ!
65 //    NSRect r = [_timeLineView visibleRect];
66 //    if(p > r.origin.x){
67 //        r.origin.x += 2;
68 //        [_timeLineView scrollPoint:r.origin];
69 //    }
70     [CATransaction begin];
71     [CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration];
72     CGPoint po = playbackBar.position;
73     po.x = p;
74     playbackBar.position = po;
75     [CATransaction commit];
76 }
77
78 - (void)addMedia:(NSString*)path
79 {
80     CALayer* newLayer = [_mainController createNewLayer:path];
81     if(draggingLayer) draggingLayer.opacity = 0.75;
82     draggingLayer = newLayer;
83     [timeLine addSublayer:newLayer];
84 }
85
86 - (void)dragging:(NSPoint)point
87 {
88     if(draggingLayer == nil) return;
89     
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];
96         }
97         return;
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];
106         }
107         return;
108     }
109     
110     if(dragging == NO) dragging = YES;
111     if(clickedPosition.x == -1){
112         point.x -= 25;
113         point.y -= 25;
114     } else {
115         float dx = clickedPosition.x - point.x;
116         float dy = clickedPosition.y - point.y;
117         point = NSMakePoint(clickedLayerPosition.x - dx, clickedLayerPosition.y - dy);
118     }
119     [self changeLayerPosition:draggingLayer position:point];
120 }
121
122 - (void)draggingDone
123 {
124     if(draggingLayer == nil) return;
125     if(dragging){
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;
130         draggingLayer = nil;
131         clickedPosition.x = -1;
132         dragging = NO;
133 //        [_timeLineView setCursorRect:NSZeroRect]; // これなに?
134     }
135     [_timeLineView setCursorRect:draggingLayer.frame];
136     stretch = 0;
137 }
138
139 - (void)changeLayerPosition:(CALayer*)layer position:(NSPoint)point
140 {
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の構造が変わったので再描画を要請。ループしないよう注意。
149 }
150
151 - (void)changeLayerFrame:(CALayer*)layer rect:(CGRect)rect
152 {
153     [CATransaction begin];
154     [CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration];
155     layer.frame = rect;
156     [CATransaction commit];
157     [_mainController refresh];
158 }
159
160 - (IBAction)add:(id)sender
161 {
162     [self addMedia:@"/Users/yanagi/Desktop/59926_2_m1_1.mp4"];
163     NSValue* v = [draggingLayer valueForKey:@"frame"];
164     NSRect r = [v rectValue];
165     r.origin.x = 0;
166 //    [draggingLayer willChangeValueForKey:@"frame"];
167     [draggingLayer setValue:[NSValue valueWithRect:r] forKey:@"frame"];
168 //    [draggingLayer didChangeValueForKey:@"frame"];
169 }
170
171 - (void)clicked:(NSPoint)point
172 {
173     if(draggingLayer){
174         draggingLayer.opacity = 0.75;
175         draggingLayer = nil;
176     }
177     
178     NSArray* layers;
179     int i, size;
180
181     layers = [timeLine sublayers];
182     size = [layers count];
183     dragging = NO;
184     
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];
195             return;
196         }
197     }
198     if(draggingLayer){
199         draggingLayer.opacity = 0.75;
200         draggingLayer = nil;
201     }
202     clickedPosition.x = -1; // "レイヤーは選択されていない" という意味。
203     stretch = 0;
204 }
205
206 - (void)doubleClicked
207 {
208     if(draggingLayer == nil) return;
209     if([[draggingLayer valueForKey:@"have keyframeLayer"] boolValue]){
210         NSLog(@"release");
211         [[[draggingLayer sublayers] lastObject] removeFromSuperlayer];
212         [draggingLayer setValue:[NSNumber numberWithBool:NO] forKey:@"have keyframeLayer"];
213         [_layerFactory removeParentLayer]; // 参照を切る = GCで回収されるようにする
214         return;
215     }
216     
217     CALayer* keyframeLayer;
218     keyframeLayer = [_layerFactory createKeyframeLayerWithLayer:draggingLayer];
219     
220     float size = draggingLayer.frame.size.width;
221     float x;
222     CGRect r;
223     CALayer *miniLayer;
224     
225     [draggingLayer addSublayer:keyframeLayer];
226     [draggingLayer setValue:[NSNumber numberWithBool:YES] forKey:@"have keyframeLayer"];
227     
228     if([_tableController isSelected] == NO) return;
229     
230     for(x = 0.0; x < size-1; x += MINI_LAYER_WIDTH){
231         miniLayer = [_layerFactory createKeyframeLevelLayer];
232         r = miniLayer.frame;
233         r.size.height = 100 * [_tableController getSelectedValueForTime:x];
234         r.origin.x = x;
235         miniLayer.frame = r;
236         [keyframeLayer addSublayer:miniLayer];
237     }
238         
239 }
240
241 - (void)updateKeyframeLayer
242 {
243     if(draggingLayer == nil) return;
244     if([[draggingLayer valueForKey:@"have keyframeLayer"] boolValue] == NO) return;
245     
246     NSArray* minis;
247     minis = [[[draggingLayer sublayers] lastObject] sublayers];
248     CALayer* mini;
249     CGRect r;
250     
251     int i, size = [minis count];
252     for(i = 0; i < size; i++){
253         mini = [minis objectAtIndex:i];
254         r = mini.frame;
255         r.size.height = 100 * [_tableController getSelectedValueForTime:i * MINI_LAYER_WIDTH];
256         mini.frame = r;
257     }
258 }
259     
260 // 左側のマッピングを調整する。(レイヤー内オフセットをいじる)
261 - (void)stretchLeft
262 {
263     stretch = STRETCH_LEFT;
264 }
265
266 // 右側のマッピングを調整する。(マッピングの範囲を変えるだけ)
267 - (void)stretchRight
268 {
269     stretch = STRETCH_RIGHT;
270 }
271
272 - (BOOL)isInclude:(CALayer*)layer point:(NSPoint)point
273 {
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;
277 }
278
279 - (CALayer*)getSelectLayer
280 {
281     return draggingLayer;
282 }
283
284 - (void)removeSelectLayer
285 {
286     [draggingLayer setValue:nil forKey:@"ElisLayer"];
287     draggingLayer = nil;
288 }
289
290 @end