source: trunk/SapphireCompatibilityClasses/SapphireFrontRowCompat.h @ 938

Revision 938, 18.2 KB checked in by gbooker, 5 years ago (diff)

A lot of Take 3 compatibility. The layout stuff is just removed there until I figure it out

Line 
1/*
2 * SapphireFrontRowCompat.h
3 * Sapphire
4 *
5 * Created by Graham Booker on Oct. 29, 2007.
6 * Copyright 2007 Sapphire Development Team and/or www.nanopi.net
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License as published by the Free Software Foundation; either version 3 of the License,
11 * or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
14 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with this program; if not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 */
20
21// Gesture events have a dictionary defining the touch points and other info.
22typedef enum {
23        kBREventOriginatorRemote = 1,
24        kBREventOriginatorGesture = 3
25} BREventOriginator;
26
27typedef enum {
28        // for originator kBREventOriginatorRemote
29        kBREventRemoteActionMenu = 1,
30        kBREventRemoteActionMenuHold,
31        kBREventRemoteActionUp,
32        kBREventRemoteActionDown,
33        kBREventRemoteActionPlay,
34        kBREventRemoteActionLeft,
35        kBREventRemoteActionRight,
36
37        kBREventRemoteActionPlayHold = 20,
38
39        // Gestures, for originator kBREventOriginatorGesture
40        kBREventRemoteActionTap = 30,
41        kBREventRemoteActionSwipeLeft,
42        kBREventRemoteActionSwipeRight,
43        kBREventRemoteActionSwipeUp,
44        kBREventRemoteActionSwipeDown,
45       
46        // Custom remote actions for old remote actions
47        kBREventRemoteActionHoldLeft = 0xfeed0001,
48        kBREventRemoteActionHoldRight,
49        kBREventRemoteActionHoldUp,
50        kBREventRemoteActionHoldDown,
51} BREventRemoteAction;
52
53/*!
54 * @brief A compatibility category for frontrow
55 *
56 * This is just here to make the compiler shut up.  The sharedInstance does not exist on the ATV, but it does on frontrow.  It is only called on frontrow.
57 */
58@interface BRRenderScene (compat)
59/*!
60 * @brief Get the shared insntance
61 *
62 * @return The shared instance
63 */
64+ (BRRenderScene *)sharedInstance;
65@end
66
67typedef enum {
68        SapphireFrontRowCompatATVVersionUnknown = 0,
69        SapphireFrontRowCompatATVVersion1 = 1,
70        SapphireFrontRowCompatATVVersionLeopardFrontrow,
71        SapphireFrontRowCompatATVVersion2,
72        SapphireFrontRowCompatATVVersion2Dot2,
73        SapphireFrontRowCompatATVVersion2Dot3,
74        SapphireFrontRowCompatATVVersion2Dot4,
75        SapphireFrontRowCompatATVVersion3,
76} SapphireFrontRowCompatATVVersion;
77
78/*!
79 * @brief A compatibility class for frontrow
80 *
81 * This class provides many compatibility functions for frontrow.  This class is never instanciated since it contains no data.  All of these functions could be implemented with C functions, but that looses the clarity of the exact meaning of parameters in Obj-C calls.
82 */
83@interface SapphireFrontRowCompat : NSObject {
84}
85
86/*!
87 * @brief Determine the ATV version
88 *
89 * @return The ATV Version
90 */
91+ (SapphireFrontRowCompatATVVersion)atvVersion;
92
93/*!
94 * @brief Are we on a leopard machine?
95 *
96 * @return YES if on leopard, NO otherwise
97 */
98+ (BOOL)usingLeopard;
99
100/*!
101 * @brief Are we on a type of ATV Take Two?
102 *
103 * @return YES if on take two, NO otherwise
104 */
105+ (BOOL)usingATypeOfTakeTwo;
106
107/*!
108 * @brief Are we on leopard or a type of ATV Take Two?
109 *
110 * @return YES if on leopard or take 2, NO otherwise
111 */
112+ (BOOL)usingLeopardOrATypeOfTakeTwo;
113
114/*!
115 * @brief Load an image at a path
116 *
117 * This returns a CGImageRef or a BRImage, depending on platform.
118 *
119 * @return The BRImage on Front Row or CGImageRef on ATV at a path
120 */
121+ (id)imageAtPath:(NSString *)path;
122
123/*!
124 * @brief Load an image texture at a path
125 *
126 * This is like imageAtPath:, only it will return a BRBitmapTexture
127 * on the ATV for setting as a menu item icon.
128 *
129 * @return BRImage or BRBitmapTexture at a path
130 */
131+ (id)imageAtPath:(NSString *)path scene:(BRRenderScene *)scene;
132
133/*
134 * @brief Load an image texture from data
135 *
136 * This returns a CGImageRef or a BRImage, depending on the platform.
137 *
138 * @return The BRImage on Front Row or CGImageRef on ATV from the data
139 */
140+ (id)imageFromData:(NSData *)imageData;
141
142/*!
143 * @brief Load an image from an Image Ref
144 *
145 * This returns a CGImageRef or a BRImage, depending on platform.
146 *
147 * @param[in]   imageRef  CGImageRef
148 * @return  BRImage on FrontRow of CGImageRef on ATV
149 */
150+ (id)coverartAsImage: (CGImageRef)imageRef;
151
152/*!
153 * @brief Get paragraph text attributes
154 *
155 * @return paragraph text attributes
156 */
157+ (NSDictionary *)paragraphTextAttributes;
158
159/*!
160 * @brief Get a menu text menu item
161 *
162 * Menu items are of different classes on the ATV and in frontrow.
163 *
164 * @param scene The scene, if exists
165 * @param folder YES if this is a folder, NO otherwise
166 * @return The new menu item
167 */
168+ (BRAdornedMenuItemLayer *)textMenuItemForScene:(BRRenderScene *)scene folder:(BOOL)folder;
169
170/*!
171 * @brief Set a menu item's title
172 *
173 * Menu items work differently in fronrow
174 *
175 * @param title The new title
176 * @param menu The menu item to set
177 */
178+ (void)setTitle:(NSString *)title forMenu:(BRAdornedMenuItemLayer *)menu;
179
180/*!
181 * @brief Set a menu item's title with attributes
182 *
183 * Menu items work differently in fronrow
184 *
185 * @param title The new title
186 * @param attributes The new attributes
187 * @param menu The menu item to set
188 */
189+ (void)setTitle:(NSString *)title withAttributes:(NSDictionary *)attributes forMenu:(BRAdornedMenuItemLayer *)menu;
190
191/*!
192 * @brief Get a menu item's title
193 *
194 * Menu items work differently in frontrow
195 *
196 * @param menu The menu item
197 */
198+ (NSString *)titleForMenu:(BRAdornedMenuItemLayer *)menu;
199
200/*!
201 * @brief Set a menu item's right justified text
202 *
203 * Menu items work differently in fronrow
204 *
205 * @param text The new text
206 * @param menu The menu item to set
207 */
208+ (void)setRightJustifiedText:(NSString *)text forMenu:(BRAdornedMenuItemLayer *)menu;
209
210/*!
211 * @brief Set a menu item's left icon
212 *
213 * Menu items work differently in fronrow
214 *
215 * @param icon The new icon
216 * @param menu The menu item to set
217 */
218+ (void)setLeftIcon:(BRTexture *)icon forMenu:(BRAdornedMenuItemLayer *)menu;
219
220/*!
221 * @brief Set a menu item's right icon
222 *
223 * Menu items work differently in fronrow
224 *
225 * @param icon The new icon
226 * @param menu The menu item to set
227 */
228+ (void)setRightIcon:(BRTexture *)icon forMenu:(BRAdornedMenuItemLayer *)menu;
229
230/*!
231 * @brief Get the checkmark image
232 *
233 * @param scene The secen, if exists
234 * @return The checkmark image
235 */
236+ (id)selectedSettingImageForScene:(BRRenderScene *)scene;
237
238/*!
239 * @brief Get the blue unplayed dot image
240 *
241 * @param scene The scene, if it exists
242 * @return The blue unplayed dot image
243 */
244+ (id)unplayedPodcastImageForScene:(BRRenderScene *)scene;
245
246/*!
247 * @brief Get the return to arrow image
248 *
249 * @param scene The scene, if it exists
250 * @return The return to arrow image
251 */ 
252+ (id)returnToImageForScene:(BRRenderScene *)scene;
253
254/*!
255 * @brief Get a controller's frame
256 *
257 * Controllers work differently in fronrow
258 *
259 * @param controller The controller
260 * @return The frame of the controller
261 */
262+ (NSRect)frameOfController:(id)controller;
263
264/*!
265 * @brief Set a controller's text
266 *
267 * Controllers work differently in fronrow
268 *
269 * @param text The new text
270 * @param attributes The new text's attributes
271 * @param control The control to set
272 */
273+ (void)setText:(NSString *)text withAtrributes:(NSDictionary *)attributes forControl:(BRTextControl *)control;
274
275/*!
276 * @brief Add a divider to a menu
277 *
278 * Lists work differently in fronrow
279 *
280 * @param index The index to add the divider
281 * @param list The list to add to
282 */
283+ (void)addDividerAtIndex:(int)index toList:(BRListControl *)list;
284
285/*!
286 * @brief Add a sublayer to a control
287 *
288 * Controllers work differently in fronrow
289 *
290 * @param sub The sublayer toadd
291 * @param controller The controller to add to
292 */
293+ (void)addSublayer:(id)sub toControl:(id)controller;
294
295/*!
296 * @brief Insert a sublayer at a position in a control
297 *
298 * Controllers and layers are different in frontrow
299 *
300 * @param sub The sublayer to add
301 * @param controller The controller to add to
302 * @param index The index to add the sublayer at
303 */
304+ (void)insertSublayer:(id)sub toControl:(id)controller atIndex:(long)index;
305
306/*!
307 * @brief Create a new header control
308 *
309 * Controllers are alloced differently in frontrow
310 *
311 * @param scene The scene, if exists.
312 */
313+ (BRHeaderControl *)newHeaderControlWithScene:(BRRenderScene *)scene;
314
315/*!
316 * @brief Create a new button control
317 *
318 * Controllers are alloced differently in frontrow
319 *
320 * @param scene The scene, if exists.
321 * @param size The size of the button
322 */
323+ (BRButtonControl *)newButtonControlWithScene:(BRRenderScene *)scene masterLayerSize:(NSSize)size;
324
325/*!
326 * @brief Create a new text control
327 *
328 * Controllers are alloced differently in frontrow
329 *
330 * @param scene The scene, if exists.
331 */
332+ (BRTextControl *)newTextControlWithScene:(BRRenderScene *)scene;
333
334/*!
335 * @brief Get the text control's rendered size within constraints
336 *
337 * @param text The text control
338 * @param maxSize The contrained maximum size
339 * @return The rendered size
340 */
341+ (NSSize)textControl:(BRTextControl *)text renderedSizeWithMaxSize:(NSSize)maxSize;
342
343/*!
344 * @brief Create a new text entry control
345 *
346 * Controllers are alloced differently in frontrow
347 *
348 * @param scene The scene, if exists.
349 */
350+ (BRTextEntryControl *)newTextEntryControlWithScene:(BRRenderScene *)scene;
351
352/*!
353 * @brief Sets the text entry's delegate
354 *
355 * ATV 3 has a different method of setting the delegate
356 *
357 * @param delegate The new delegate
358 * @param entry The text entry control
359 */
360+ (void)setDelegate:(id)delegate forTextEntry:(BRTextEntryControl *)entry;
361
362/*!
363 * @brief Create a new progress bar widget
364 *
365 * Widgets are alloced differently in frontrow
366 *
367 * @param scene The scene, if exists.
368 */
369+ (BRProgressBarWidget *)newProgressBarWidgetWithScene:(BRRenderScene *)scene;
370
371/*!
372 * @brief Create a new marching icon layer
373 *
374 * Layers are alloced differently in frontrow
375 *
376 * @param scene The scene, if exists.
377 */
378+ (BRMarchingIconLayer *)newMarchingIconLayerWithScene:(BRRenderScene *)scene;
379
380/*!
381 * @brief Create a new image layer
382 *
383 * Layers are different in frontrow
384 *
385 * @param scene The scene, if it exists.
386 */
387+ (BRImageLayer *)newImageLayerWithScene:(BRRenderScene *)scene;
388
389/*!
390 * @brief Set the image on a BRImageLayer
391 *
392 * FR uses BRImage instead of BRTexture
393 *
394 * @param image The image (BRImage on FR/BRTexture on ATV)
395 */
396+ (void)setImage:(id)image forLayer:(BRImageLayer *)layer;
397
398/*!
399 * @brief Create a new image layer with an image
400 *
401 * Just a shortcut around the previous two
402 *
403 * @param image The image (BRImage on FR/BRTexture on ATV)
404 * @param scene The scene, if it exists.
405 */
406+ (BRImageLayer *)newImageLayerWithImage:(id)image scene:(BRRenderScene *)scene;
407
408/*!
409 * @brief Render scene on the ATV
410 *
411 * Only does something on the ATV; frontrow has no need for this
412 *
413 * @param scene The scene to render, if exists.
414 */
415+ (void)renderScene:(BRRenderScene *)scene;
416
417/*!
418 * @brief Create a new BRAlertController
419 *
420 * Scene doesn't exist on frontrow
421 *
422 * @param type The type of the alert
423 * @param titled The title of the alert
424 * @param primaryText the primary text of the alert
425 * @param secondaryText the secondary text of the alert
426 * @param scene the scene
427 */
428+ (BRAlertController *)alertOfType:(int)type titled:(NSString *)title primaryText:(NSString *)primaryText secondaryText:(NSString *)secondaryText withScene:(BRRenderScene *)scene;
429
430/*!
431 * @brief Create a new BROptionDialog
432 *
433 * Scene doesn't exist in frontrow
434 *
435 * @param scene the scene
436 */
437+ (BROptionDialog *)newOptionDialogWithScene:(BRRenderScene *)scene;
438
439/*!
440 * @brief Set the primary info text on a BROptionDialog
441 *
442 * Text/attributes are different on frontrow
443 *
444 * @param primaryInfoText the primary info text
445 * @param attributes the attributes
446 * @param dialog the BROptionDialog
447 */
448+ (void)setOptionDialogPrimaryInfoText:(NSString *)primaryInfoText withAttributes:(NSDictionary *)attributes optionDialog:(BROptionDialog *)dialog;
449
450/*!
451 * @brief Create a new BRTextWithSpinnerController
452 *
453 * Method is different on frontrow
454 *
455 * @param title the title
456 * @param text the text
457 * @param networkDependent unknown
458 * @param scene the scene
459 */
460+ (BRTextWithSpinnerController *)newTextWithSpinnerControllerTitled:(NSString *)title text:(NSString *)text isNetworkDependent:(BOOL)networkDependent scene:(BRRenderScene *)scene;
461
462/*!
463 * @brief Sets whether a BRWaitSpinnerControl should spin or not
464 *
465 * @param spinner The spinner
466 * @param spin YES if the spinner should spin, NO otherwise
467 */
468+ (void)setSpinner:(BRWaitSpinnerControl *)spinner toSpin:(BOOL)spin;
469
470/*!
471 * @brief Get the remoteAction in a compatable way
472 *
473 * @param event The event for which to fetch the remote action
474 * @return The remote action for the event
475 */
476+ (BREventRemoteAction)remoteActionForEvent:(BREvent *)event;
477
478/*!
479 * @brief Get the call stack addresses for an exception
480 *
481 * This function exists mostly because this method is different on Tiger and Leopard.  This is not a significant differece between the ATV and Frontrow
482 *
483 * @param exception The exception to examine
484 * @return An array of call addresses if successful, nil otherwise
485 */
486+ (NSArray *)callStackReturnAddressesForException:(NSException *)exception;
487
488/*!
489 * @brief Get the sharedFrontRowPreferences object.
490 *
491 * On Apple TV < 2.1, the RUIPreferences class is used for this.  On 2.1, the class is renamed to BRPreferences.
492 *
493 * @return the preferences object
494 */
495+ (RUIPreferences *)sharedFrontRowPreferences;
496@end
497
498@interface SapphireFrontRowCompat (SapphireFrontRowCompatDeprecated)
499/*!
500 * @brief Are we on frontrow?
501 *
502 * @return YES if on frontrow, NO otherwise
503 */
504+ (BOOL)usingFrontRow DEPRECATED_ATTRIBUTE;
505
506/*!
507 * @brief Are we on ATV Take Two?
508 *
509 * @return YES if on take two, NO otherwise
510 */
511+ (BOOL)usingTakeTwo DEPRECATED_ATTRIBUTE;
512
513/*!
514 * @brief Are we on ATV 2.2?
515 *
516 * @return YES if on 2.2, NO otherwise
517 */
518+ (BOOL)usingTakeTwoDotTwo DEPRECATED_ATTRIBUTE;
519
520/*!
521 * @brief Are we on ATV 2.3?
522 *
523 * @return YES if on 2.3, NO otherwise
524 */
525+ (BOOL)usingTakeTwoDotThree DEPRECATED_ATTRIBUTE;
526
527/*!
528 * @brief Are we on ATV 2.4?
529 *
530 * @return YES if on 2.4, NO otherwise
531 */
532+ (BOOL)usingTakeTwoDotFour DEPRECATED_ATTRIBUTE;
533@end
534
535
536static inline void SapphireLoadFramework(NSString *frameworkPath)
537{
538        CFStringRef preferencesDomain = CFSTR("com.apple.frontrow.appliance.Sapphire.CompatClasses");
539        CFStringRef loadPathKey = CFSTR("loadPath");
540        CFPreferencesAppSynchronize(preferencesDomain);
541        CFPropertyListRef loadPathProperty = CFPreferencesCopyAppValue(loadPathKey, preferencesDomain);
542        CFStringRef loadPath = nil;
543        if(loadPathProperty != nil && CFGetTypeID(loadPathProperty) == CFStringGetTypeID())
544                loadPath = (CFStringRef)loadPathProperty;
545       
546        NSString *compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireCompatClasses.framework"];
547        NSBundle *compat = [NSBundle bundleWithPath:compatPath];
548       
549        if(NSClassFromString(@"SapphireFrontRowCompat") == nil)
550        {
551                if(loadPath != nil)
552                {
553                        NSBundle *otherBundle = [NSBundle bundleWithPath:(NSString *)loadPath];
554                        NSString *myVersion = [compat objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
555                        NSString *otherVersion = [otherBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
556                       
557                        if(otherVersion != nil && [myVersion compare:otherVersion] == NSOrderedAscending)
558                                compat = otherBundle;
559                }
560               
561                if( ![compat load]){ 
562                        @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
563                }
564                if([SapphireFrontRowCompat usingLeopardOrATypeOfTakeTwo])
565                {
566                        compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireLeopardCompatClasses.framework"];
567                        compat = [NSBundle bundleWithPath:compatPath];
568                        if( ![compat load]){ 
569                                @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireLeopardCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
570                        }
571                }
572                // ATV2
573                if([SapphireFrontRowCompat usingATypeOfTakeTwo])
574                {
575                        compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireTakeTwoCompatClasses.framework"];
576                        compat = [NSBundle bundleWithPath:compatPath];
577                        if( ![compat load]){ 
578                                @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireTakeTwoCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
579                        }
580                }
581                //ATV2.2
582                if([SapphireFrontRowCompat atvVersion] >= SapphireFrontRowCompatATVVersion2Dot2)
583                {
584                        compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireTakeTwoPointTwoCompatClasses.framework"];
585                        compat = [NSBundle bundleWithPath:compatPath];
586                        if( ![compat load]){ 
587                                @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireTakeTwoPointTwoCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
588                        }
589                }
590                //ATV3
591                if([SapphireFrontRowCompat atvVersion] >= SapphireFrontRowCompatATVVersion3)
592                {
593                        compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireTakeThreeCompatClasses.framework"];
594                        compat = [NSBundle bundleWithPath:compatPath];
595                        if( ![compat load]){ 
596                                @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireTakeThreeCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
597                        }
598                }
599        }
600        else
601        {
602                //Check to see if we are later and mark it in preferences
603                NSBundle *loadedBundle = [NSBundle bundleForClass:NSClassFromString(@"SapphireFrontRowCompat")];
604                NSString *loadedVersion = [loadedBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
605                NSString *myVersion = [compat objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
606               
607                if([loadedVersion compare:myVersion] == NSOrderedAscending)
608                {
609                        //Check the one in the prefs too
610                        NSBundle *otherBundle = [NSBundle bundleWithPath:(NSString *)loadPath];
611                        NSString *otherVersion = [otherBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
612                        if(otherVersion == nil || [otherVersion compare:myVersion] == NSOrderedAscending)
613                        {
614                                CFPreferencesSetAppValue(loadPathKey, (CFStringRef)compatPath, preferencesDomain);
615                                CFPreferencesAppSynchronize(preferencesDomain);
616                                //Likely need to restart Finder here (delayed) or something because the next time around, the newer framework will be loaded.
617                        }
618                }
619        }
620        if(loadPathProperty)
621                CFRelease(loadPathProperty);
622}
623
Note: See TracBrowser for help on using the repository browser.