Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfManager/XspfMCoverFlowViewController.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 440 - (hide annotations) (download)
Sun Aug 15 03:11:35 2010 UTC (13 years, 8 months ago) by masakih
File size: 12294 byte(s)
[Fix] IKImageFlowViewがキービューになってしまう可能性があった問題を修正。
1 masaki 281 //
2     // XspfMCoverFlowViewController.m
3     // XspfManager
4     //
5     // Created by Hori,Masaki on 10/01/21.
6     //
7    
8 masakih 350 /*
9 masakih 365 This source code is release under the New BSD License.
10 masakih 355 Copyright (c) 2010, masakih
11 masakih 350 All rights reserved.
12    
13 masakih 365 ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満たす場合に
14     限り、再頒布および使用が許可されます。
15    
16     1, ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項を含
17     めること。
18     2, バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作権表
19     示、本条件一覧、および下記免責条項を含めること。
20     3, 書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進に、
21     コントリビューターの名前を使用してはならない。
22     本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供されており、
23     明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証
24     も含め、またそれに限定されない、いかなる保証もありません。著作権者もコントリビューター
25     も、事由のいかんを問わず、 損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか
26     厳格責任であるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生する
27     可能性を知らされていたとしても、本ソフトウェアの使用によって発生した(代替品または代用
28     サービスの調達、使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定
29     されない)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害につい
30     て、一切責任を負わないものとします。
31 masakih 350 -------------------------------------------------------------------
32 masakih 355 Copyright (c) 2010, masakih
33 masakih 350 All rights reserved.
34    
35 masakih 365 Redistribution and use in source and binary forms, with or without
36     modification, are permitted provided that the following conditions
37     are met:
38 masakih 350
39 masakih 365 1, Redistributions of source code must retain the above copyright
40     notice, this list of conditions and the following disclaimer.
41     2, Redistributions in binary form must reproduce the above copyright
42     notice, this list of conditions and the following disclaimer in
43     the documentation and/or other materials provided with the
44     distribution.
45     3, The names of its contributors may be used to endorse or promote
46     products derived from this software without specific prior
47     written permission.
48     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
51     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
52     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53     INCIDENTAL, SPECIAL,EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
54     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
56     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
58     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59     POSSIBILITY OF SUCH DAMAGE.
60 masakih 350 */
61    
62 masaki 281 #import "XspfMCoverFlowViewController.h"
63    
64     #import "XspfMListViewController.h"
65    
66 masaki 301 #import "XspfMXspfObject.h"
67     #import <Quartz/Quartz.h>
68 masaki 281
69 masaki 301 #import <objc/runtime.h>
70 masaki 281
71 masaki 301 @interface NSObject(XpsfMIKImageFlowViewSupport)
72     - (void)setShowSplitter:(BOOL)flag;
73     - (void)setInlinePreviewEnabled:(BOOL)flag;
74     - (void)setSelectedIndex:(NSUInteger)index;
75 masaki 304 - (NSRect)selectedImageFrame;
76 masaki 325 - (id)cacheManager;
77    
78    
79     - (void)IKCleanTimedOutCache;
80 masaki 301 @end
81    
82 masaki 281 @implementation XspfMCoverFlowViewController
83    
84     - (id)init
85     {
86     self = [super initWithNibName:@"XspfMCoverFlowView" bundle:nil];
87    
88     return self;
89     }
90    
91     - (void)awakeFromNib
92     {
93     NSArrayController *rep = [self representedObject];
94    
95 masaki 301 [coverFlow setShowSplitter:YES];
96 masaki 302 if([coverFlow respondsToSelector:@selector(setInlinePreviewEnabled:)]) {
97     [coverFlow setInlinePreviewEnabled:YES];
98     }
99 masaki 301 [coverFlow setDataSource:self];
100     [coverFlow setDelegate:self];
101 masaki 281
102     listViewController = [[XspfMListViewController alloc] init];
103     [listViewController view];
104     [listViewController setRepresentedObject:rep];
105     [listViewController recalculateKeyViewLoop];
106     [listPlaceHolder addSubview:[listViewController view]];
107     [[listViewController view] setFrame:[listPlaceHolder bounds]];
108     [self recalculateKeyViewLoop];
109    
110 masaki 294 [splitView setDelegate:self];
111 masakih 440
112     [[NSNotificationCenter defaultCenter] addObserver:self
113     selector:@selector(windowDidUpdate:)
114     name:NSWindowDidUpdateNotification
115     object:nil];
116 masaki 281 }
117    
118 masakih 440 - (void)windowDidUpdate:(id)notification
119 masakih 436 {
120 masakih 440 NSWindow *window = [notification object];
121    
122     if(window == [[self view] window]) {
123     [[NSApp mainWindow] addObserver:self forKeyPath:@"firstResponder" options:0 context:NULL];
124     [[NSNotificationCenter defaultCenter] removeObserver:self name:[notification name] object:nil];
125     }
126 masakih 436 }
127    
128 masaki 281 - (void)setRepresentedObject:(id)representedObject
129     {
130 masaki 301 id oldRep = [self representedObject];
131     if([oldRep isEqual:representedObject]) return;
132 masaki 329
133 masaki 281 if(representedObject) {
134 masaki 301 [representedObject addObserver:self forKeyPath:@"arrangedObjects" options:0 context:NULL];
135     [representedObject addObserver:self forKeyPath:@"selectionIndex" options:0 context:NULL];
136     [coverFlow setSelectedIndex:[representedObject selectionIndex]];
137 masaki 281 }
138 masaki 301
139     [super setRepresentedObject:representedObject];
140     [listViewController setRepresentedObject:representedObject];
141     [coverFlow reloadData];
142 masaki 281 }
143 masaki 329 - (void)recalculateKeyViewLoop
144     {
145 masakih 430 // [coverFlow setNextKeyView:[listViewController firstKeyView]];
146 masaki 329
147     // TODO: change key view loop if list view is not visible.
148 masakih 430 // lastKeyView = [listViewController lastKeyView];
149    
150     firstKeyView = [listViewController firstKeyView];
151     initialFirstResponder = [listViewController firstKeyView];
152 masaki 329 }
153 masaki 281
154 masaki 301 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
155 masaki 281 {
156 masaki 301 if([keyPath isEqualToString:@"arrangedObjects"]) {
157     [coverFlow reloadData];
158     return;
159     }
160     if([keyPath isEqualToString:@"selectionIndex"]) {
161     [coverFlow setSelectedIndex:[[self representedObject] selectionIndex]];
162 masakih 430 [listViewController scrollToSelection:self];
163 masaki 301 return;
164     }
165 masakih 436 if([keyPath isEqualToString:@"firstResponder"]) {
166     id firstResponder = [[splitView window] firstResponder];
167     if(firstResponder == coverFlow) {
168     [[splitView window] makeFirstResponder:[listViewController view]];
169     }
170     return;
171     }
172 masaki 281
173 masaki 301 [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
174 masaki 281 }
175    
176 masakih 430 - (void)keyDown:(NSEvent *)theEvent
177     {
178     unsigned short code = [theEvent keyCode];
179     #define kLEFT_ARROW_KEY 123
180     #define kRIGHT_ARROW_KEY 124
181     switch(code) {
182     case kLEFT_ARROW_KEY:
183     case kRIGHT_ARROW_KEY:
184     return [coverFlow keyDown:theEvent];
185     break;
186     }
187     NSBeep();
188     }
189 masaki 301
190 masaki 325 - (IBAction)clearCoverFlowCache:(id)sender
191     {
192     if(![coverFlow respondsToSelector:@selector(cacheManager)]) {
193     NSBeep();
194     return;
195     }
196     id cacheManager = [coverFlow cacheManager];
197     if(![cacheManager respondsToSelector:@selector(IKCleanTimedOutCache)]) {
198     NSBeep();
199     return;
200     }
201     [cacheManager IKCleanTimedOutCache];
202     }
203     - (IBAction)test01:(id)sender
204     {
205     [self clearCoverFlowCache:sender];
206     }
207    
208 masaki 301 - (NSUInteger)numberOfItemsInImageFlow:(id)imageFlowView
209     {
210     return [[[self representedObject] arrangedObjects] count];
211     }
212     - (id)imageFlow:(id)imageFlowView itemAtIndex:(NSUInteger)index
213     {
214     return [[[self representedObject] arrangedObjects] objectAtIndex:index];
215     }
216    
217 masakih 430 - (void)setRepSelectedIndex:(NSNumber *)indexValue
218     {
219     [[self representedObject] setSelectionIndex:[indexValue unsignedIntegerValue]];
220     }
221 masaki 301 - (void)imageFlow:(id)imageFlowView didSelectItemAtIndex:(NSUInteger)index
222     {
223 masakih 430 // [[self representedObject] setSelectionIndex:index];
224    
225     [NSObject cancelPreviousPerformRequestsWithTarget:self];
226     [self performSelector:@selector(setRepSelectedIndex:)
227     withObject:[NSNumber numberWithUnsignedInteger:index]
228     afterDelay:0.5];
229 masaki 301 }
230     - (void)imageFlow:(id)imageFlowView cellWasDoubleClickedAtIndex:(NSUInteger)index
231     {
232     [NSApp sendAction:@selector(openXspf:) to:nil from:nil];
233     }
234     - (void)imageFlow:(id)imageFlowView startResizingWithEvent:(NSEvent *)theEvent
235     {
236 masakih 345 NSPoint offset = [imageFlowView convertPoint:[theEvent locationInWindow] fromView:nil];
237    
238 masaki 301 NSWindow *window = [imageFlowView window];
239 masakih 345 while (theEvent = [window nextEventMatchingMask:NSLeftMouseDraggedMask | NSLeftMouseUpMask]) {
240     if(NSEventMaskFromType([theEvent type]) == NSLeftMouseUpMask) break;
241    
242     NSPoint p = [splitView convertPoint:[theEvent locationInWindow] fromView:nil];
243     [splitView setPosition:p.y+offset.y ofDividerAtIndex:0];
244     }
245 masaki 301 }
246    
247 masakih 429 - (IBAction)scrollToSelection:(id)sender
248     {
249     [listViewController scrollToSelection:sender];
250     }
251 masaki 301
252 masaki 304 // QLPreviewPanel support
253     - (NSRect)selectionItemRect
254     {
255     NSRect rect = [coverFlow selectedImageFrame];
256     rect = [coverFlow convertRectToBase:rect];
257     rect.origin = [[coverFlow window] convertBaseToScreen:rect.origin];
258     return rect;
259     }
260    
261 masaki 294 #pragma mark#### NSSplitView Delegate ####
262     - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex
263     {
264     return 130;
265     }
266 masakih 437 - (void)splitView:(NSSplitView *)aSplitView resizeSubviewsWithOldSize:(NSSize)oldSize
267     {
268     NSView *rightView = [[splitView subviews] objectAtIndex:1];
269     NSRect newsplitViewFrame = [splitView frame];
270     NSRect coverFlowFrame = [coverFlow frame];
271     NSRect listFrame = [rightView frame];
272     CGFloat dividerThickness = [splitView dividerThickness];
273    
274     coverFlowFrame.size.width = newsplitViewFrame.size.width;
275     listFrame.size.width = newsplitViewFrame.size.width;
276    
277     coverFlowFrame.size.height = newsplitViewFrame.size.height - listFrame.size.height - dividerThickness;
278    
279     if(listFrame.size.height < 0) {
280     listFrame.size.height = 0;
281     coverFlowFrame.size = newsplitViewFrame.size;
282     }
283    
284     coverFlowFrame.origin.y = 0;
285     listFrame.origin.y = NSMaxY(coverFlowFrame) + dividerThickness;
286    
287     [coverFlow setFrame:coverFlowFrame];
288     [rightView setFrame:listFrame];
289     }
290 masaki 281
291 masaki 301 @end
292 masaki 294
293    
294 masaki 301 @implementation XspfMXspfObject(XspfMIKImageBrowserItem)
295     /*!
296     @method imageUID
297     @abstract Returns a unique string that identify this data source item (required).
298     @discussion The image browser uses this identifier to keep the correspondance between its cache and the data source item
299     */
300     - (NSString *) imageUID
301     {
302     return self.urlString;
303     }
304    
305     /*!
306     @method imageRepresentationType
307     @abstract Returns the representation of the image to display (required).
308     @discussion Keys for imageRepresentationType are defined below.
309     */
310     - (NSString *) imageRepresentationType
311     {
312     return IKImageBrowserQuickLookPathRepresentationType;
313     }
314    
315     /*!
316     @method imageRepresentation
317     @abstract Returns the image to display (required). Can return nil if the item has no image to display.
318     @discussion This methods is called frequently, so the receiver should cache the returned instance.
319     */
320     - (id) imageRepresentation
321     {
322     return self.url;
323     }
324    
325     /*!
326     @method imageVersion
327     @abstract Returns a version of this item. The receiver can return a new version to let the image browser knows that it shouldn't use its cache for this item
328     */
329     //- (NSUInteger) imageVersion;
330    
331     /*!
332     @method imageTitle
333     @abstract Returns the title to display as a NSString. Use setValue:forKey: with IKImageBrowserCellTitleAttribute to set text attributes.
334     */
335     - (NSString *) imageTitle
336     {
337     return self.title;
338     }
339    
340     /*!
341     @method imageSubtitle
342     @abstract Returns the subtitle to display as a NSString. Use setValue:forKey: with IKImageBrowserCellSubtitleAttribute to set text attributes.
343     */
344     - (NSString *) imageSubtitle
345     {
346     return [NSString stringWithFormat:
347     NSLocalizedString(@"%@ Movies", @"%@ Movies"),
348     self.movieNum];
349     }
350    
351     /*!
352     @method isSelectable
353     @abstract Returns whether this item is selectable.
354     @discussion The receiver can implement this methods to forbid selection of this item by returning NO.
355     */
356     //- (BOOL) isSelectable;
357    
358 masaki 281 @end

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