source: trunk/SapphireCompatibilityClasses/SapphireFrontRowCompat.h @ 897

Revision 897, 17.4 KB checked in by gbooker, 5 years ago (diff)

Added mechanism to create an image from NSData in a compatible manner.

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} SapphireFrontRowCompatATVVersion;
76
77/*!
78 * @brief A compatibility class for frontrow
79 *
80 * 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.
81 */
82@interface SapphireFrontRowCompat : NSObject {
83}
84
85/*!
86 * @brief Determine the ATV version
87 *
88 * @return The ATV Version
89 */
90+ (SapphireFrontRowCompatATVVersion)atvVersion;
91
92/*!
93 * @brief Are we on a leopard machine?
94 *
95 * @return YES if on leopard, NO otherwise
96 */
97+ (BOOL)usingLeopard;
98
99/*!
100 * @brief Are we on a type of ATV Take Two?
101 *
102 * @return YES if on take two, NO otherwise
103 */
104+ (BOOL)usingATypeOfTakeTwo;
105
106/*!
107 * @brief Are we on leopard or a type of ATV Take Two?
108 *
109 * @return YES if on leopard or take 2, NO otherwise
110 */
111+ (BOOL)usingLeopardOrATypeOfTakeTwo;
112
113/*!
114 * @brief Load an image at a path
115 *
116 * This returns a CGImageRef or a BRImage, depending on platform.
117 *
118 * @return The BRImage on Front Row or CGImageRef on ATV at a path
119 */
120+ (id)imageAtPath:(NSString *)path;
121
122/*!
123 * @brief Load an image texture at a path
124 *
125 * This is like imageAtPath:, only it will return a BRBitmapTexture
126 * on the ATV for setting as a menu item icon.
127 *
128 * @return BRImage or BRBitmapTexture at a path
129 */
130+ (id)imageAtPath:(NSString *)path scene:(BRRenderScene *)scene;
131
132/*
133 * @brief Load an image texture from data
134 *
135 * This returns a CGImageRef or a BRImage, depending on the platform.
136 *
137 * @return The BRImage on Front Row or CGImageRef on ATV from the data
138 */
139+ (id)imageFromData:(NSData *)imageData;
140
141/*!
142 * @brief Load an image from an Image Ref
143 *
144 * This returns a CGImageRef or a BRImage, depending on platform.
145 *
146 * @param[in]   imageRef  CGImageRef
147 * @return  BRImage on FrontRow of CGImageRef on ATV
148 */
149+ (id)coverartAsImage: (CGImageRef)imageRef;
150
151/*!
152 * @brief Get a menu text menu item
153 *
154 * Menu items are of different classes on the ATV and in frontrow.
155 *
156 * @param scene The scene, if exists
157 * @param folder YES if this is a folder, NO otherwise
158 * @return The new menu item
159 */
160+ (BRAdornedMenuItemLayer *)textMenuItemForScene:(BRRenderScene *)scene folder:(BOOL)folder;
161
162/*!
163 * @brief Set a menu item's title
164 *
165 * Menu items work differently in fronrow
166 *
167 * @param title The new title
168 * @param menu The menu item to set
169 */
170+ (void)setTitle:(NSString *)title forMenu:(BRAdornedMenuItemLayer *)menu;
171
172/*!
173 * @brief Set a menu item's title with attributes
174 *
175 * Menu items work differently in fronrow
176 *
177 * @param title The new title
178 * @param attributes The new attributes
179 * @param menu The menu item to set
180 */
181+ (void)setTitle:(NSString *)title withAttributes:(NSDictionary *)attributes forMenu:(BRAdornedMenuItemLayer *)menu;
182
183/*!
184 * @brief Get a menu item's title
185 *
186 * Menu items work differently in frontrow
187 *
188 * @param menu The menu item
189 */
190+ (NSString *)titleForMenu:(BRAdornedMenuItemLayer *)menu;
191
192/*!
193 * @brief Set a menu item's right justified text
194 *
195 * Menu items work differently in fronrow
196 *
197 * @param text The new text
198 * @param menu The menu item to set
199 */
200+ (void)setRightJustifiedText:(NSString *)text forMenu:(BRAdornedMenuItemLayer *)menu;
201
202/*!
203 * @brief Set a menu item's left icon
204 *
205 * Menu items work differently in fronrow
206 *
207 * @param icon The new icon
208 * @param menu The menu item to set
209 */
210+ (void)setLeftIcon:(BRTexture *)icon forMenu:(BRAdornedMenuItemLayer *)menu;
211
212/*!
213 * @brief Set a menu item's right icon
214 *
215 * Menu items work differently in fronrow
216 *
217 * @param icon The new icon
218 * @param menu The menu item to set
219 */
220+ (void)setRightIcon:(BRTexture *)icon forMenu:(BRAdornedMenuItemLayer *)menu;
221
222/*!
223 * @brief Get the checkmark image
224 *
225 * @param scene The secen, if exists
226 * @return The checkmark image
227 */
228+ (id)selectedSettingImageForScene:(BRRenderScene *)scene;
229
230/*!
231 * @brief Get the blue unplayed dot image
232 *
233 * @param scene The scene, if it exists
234 * @return The blue unplayed dot image
235 */
236+ (id)unplayedPodcastImageForScene:(BRRenderScene *)scene;
237
238/*!
239 * @brief Get the return to arrow image
240 *
241 * @param scene The scene, if it exists
242 * @return The return to arrow image
243 */ 
244+ (id)returnToImageForScene:(BRRenderScene *)scene;
245
246/*!
247 * @brief Get a controller's frame
248 *
249 * Controllers work differently in fronrow
250 *
251 * @param controller The controller
252 * @return The frame of the controller
253 */
254+ (NSRect)frameOfController:(id)controller;
255
256/*!
257 * @brief Set a controller's text
258 *
259 * Controllers work differently in fronrow
260 *
261 * @param text The new text
262 * @param attributes The new text's attributes
263 * @param control The control to set
264 */
265+ (void)setText:(NSString *)text withAtrributes:(NSDictionary *)attributes forControl:(BRTextControl *)control;
266
267/*!
268 * @brief Add a divider to a menu
269 *
270 * Lists work differently in fronrow
271 *
272 * @param index The index to add the divider
273 * @param list The list to add to
274 */
275+ (void)addDividerAtIndex:(int)index toList:(BRListControl *)list;
276
277/*!
278 * @brief Add a sublayer to a control
279 *
280 * Controllers work differently in fronrow
281 *
282 * @param sub The sublayer toadd
283 * @param controller The controller to add to
284 */
285+ (void)addSublayer:(id)sub toControl:(id)controller;
286
287/*!
288 * @brief Insert a sublayer at a position in a control
289 *
290 * Controllers and layers are different in frontrow
291 *
292 * @param sub The sublayer to add
293 * @param controller The controller to add to
294 * @param index The index to add the sublayer at
295 */
296+ (void)insertSublayer:(id)sub toControl:(id)controller atIndex:(long)index;
297
298/*!
299 * @brief Create a new header control
300 *
301 * Controllers are alloced differently in frontrow
302 *
303 * @param scene The scene, if exists.
304 */
305+ (BRHeaderControl *)newHeaderControlWithScene:(BRRenderScene *)scene;
306
307/*!
308 * @brief Create a new button control
309 *
310 * Controllers are alloced differently in frontrow
311 *
312 * @param scene The scene, if exists.
313 * @param size The size of the button
314 */
315+ (BRButtonControl *)newButtonControlWithScene:(BRRenderScene *)scene masterLayerSize:(NSSize)size;
316
317/*!
318 * @brief Create a new text control
319 *
320 * Controllers are alloced differently in frontrow
321 *
322 * @param scene The scene, if exists.
323 */
324+ (BRTextControl *)newTextControlWithScene:(BRRenderScene *)scene;
325
326/*!
327 * @brief Get the text control's rendered size within constraints
328 *
329 * @param text The text control
330 * @param maxSize The contrained maximum size
331 * @return The rendered size
332 */
333+ (NSSize)textControl:(BRTextControl *)text renderedSizeWithMaxSize:(NSSize)maxSize;
334
335/*!
336 * @brief Create a new text entry control
337 *
338 * Controllers are alloced differently in frontrow
339 *
340 * @param scene The scene, if exists.
341 */
342+ (BRTextEntryControl *)newTextEntryControlWithScene:(BRRenderScene *)scene;
343
344/*!
345 * @brief Create a new progress bar widget
346 *
347 * Widgets are alloced differently in frontrow
348 *
349 * @param scene The scene, if exists.
350 */
351+ (BRProgressBarWidget *)newProgressBarWidgetWithScene:(BRRenderScene *)scene;
352
353/*!
354 * @brief Create a new marching icon layer
355 *
356 * Layers are alloced differently in frontrow
357 *
358 * @param scene The scene, if exists.
359 */
360+ (BRMarchingIconLayer *)newMarchingIconLayerWithScene:(BRRenderScene *)scene;
361
362/*!
363 * @brief Create a new image layer
364 *
365 * Layers are different in frontrow
366 *
367 * @param scene The scene, if it exists.
368 */
369+ (BRImageLayer *)newImageLayerWithScene:(BRRenderScene *)scene;
370
371/*!
372 * @brief Set the image on a BRImageLayer
373 *
374 * FR uses BRImage instead of BRTexture
375 *
376 * @param image The image (BRImage on FR/BRTexture on ATV)
377 */
378+ (void)setImage:(id)image forLayer:(BRImageLayer *)layer;
379
380/*!
381 * @brief Create a new image layer with an image
382 *
383 * Just a shortcut around the previous two
384 *
385 * @param image The image (BRImage on FR/BRTexture on ATV)
386 * @param scene The scene, if it exists.
387 */
388+ (BRImageLayer *)newImageLayerWithImage:(id)image scene:(BRRenderScene *)scene;
389
390/*!
391 * @brief Render scene on the ATV
392 *
393 * Only does something on the ATV; frontrow has no need for this
394 *
395 * @param scene The scene to render, if exists.
396 */
397+ (void)renderScene:(BRRenderScene *)scene;
398
399/*!
400 * @brief Create a new BRAlertController
401 *
402 * Scene doesn't exist on frontrow
403 *
404 * @param type The type of the alert
405 * @param titled The title of the alert
406 * @param primaryText the primary text of the alert
407 * @param secondaryText the secondary text of the alert
408 * @param scene the scene
409 */
410+ (BRAlertController *)alertOfType:(int)type titled:(NSString *)title primaryText:(NSString *)primaryText secondaryText:(NSString *)secondaryText withScene:(BRRenderScene *)scene;
411
412/*!
413 * @brief Create a new BROptionDialog
414 *
415 * Scene doesn't exist in frontrow
416 *
417 * @param scene the scene
418 */
419+ (BROptionDialog *)newOptionDialogWithScene:(BRRenderScene *)scene;
420
421/*!
422 * @brief Set the primary info text on a BROptionDialog
423 *
424 * Text/attributes are different on frontrow
425 *
426 * @param primaryInfoText the primary info text
427 * @param attributes the attributes
428 * @param dialog the BROptionDialog
429 */
430+ (void)setOptionDialogPrimaryInfoText:(NSString *)primaryInfoText withAttributes:(NSDictionary *)attributes optionDialog:(BROptionDialog *)dialog;
431
432/*!
433 * @brief Create a new BRTextWithSpinnerController
434 *
435 * Method is different on frontrow
436 *
437 * @param title the title
438 * @param text the text
439 * @param networkDependent unknown
440 * @param scene the scene
441 */
442+ (BRTextWithSpinnerController *)newTextWithSpinnerControllerTitled:(NSString *)title text:(NSString *)text isNetworkDependent:(BOOL)networkDependent scene:(BRRenderScene *)scene;
443
444/*!
445 * @brief Sets whether a BRWaitSpinnerControl should spin or not
446 *
447 * @param spinner The spinner
448 * @param spin YES if the spinner should spin, NO otherwise
449 */
450+ (void)setSpinner:(BRWaitSpinnerControl *)spinner toSpin:(BOOL)spin;
451
452/*!
453 * @brief Get the remoteAction in a compatable way
454 *
455 * @param event The event for which to fetch the remote action
456 * @return The remote action for the event
457 */
458+ (BREventRemoteAction)remoteActionForEvent:(BREvent *)event;
459
460/*!
461 * @brief Get the call stack addresses for an exception
462 *
463 * This function exists mostly because this method is different on Tiger and Leopard.  This is not a significant differece between the ATV and Frontrow
464 *
465 * @param exception The exception to examine
466 * @return An array of call addresses if successful, nil otherwise
467 */
468+ (NSArray *)callStackReturnAddressesForException:(NSException *)exception;
469
470/*!
471 * @brief Get the sharedFrontRowPreferences object.
472 *
473 * On Apple TV < 2.1, the RUIPreferences class is used for this.  On 2.1, the class is renamed to BRPreferences.
474 *
475 * @return the preferences object
476 */
477+ (RUIPreferences *)sharedFrontRowPreferences;
478@end
479
480@interface SapphireFrontRowCompat (SapphireFrontRowCompatDeprecated)
481/*!
482 * @brief Are we on frontrow?
483 *
484 * @return YES if on frontrow, NO otherwise
485 */
486+ (BOOL)usingFrontRow DEPRECATED_ATTRIBUTE;
487
488/*!
489 * @brief Are we on ATV Take Two?
490 *
491 * @return YES if on take two, NO otherwise
492 */
493+ (BOOL)usingTakeTwo DEPRECATED_ATTRIBUTE;
494
495/*!
496 * @brief Are we on ATV 2.2?
497 *
498 * @return YES if on 2.2, NO otherwise
499 */
500+ (BOOL)usingTakeTwoDotTwo DEPRECATED_ATTRIBUTE;
501
502/*!
503 * @brief Are we on ATV 2.3?
504 *
505 * @return YES if on 2.3, NO otherwise
506 */
507+ (BOOL)usingTakeTwoDotThree DEPRECATED_ATTRIBUTE;
508
509/*!
510 * @brief Are we on ATV 2.4?
511 *
512 * @return YES if on 2.4, NO otherwise
513 */
514+ (BOOL)usingTakeTwoDotFour DEPRECATED_ATTRIBUTE;
515@end
516
517
518static inline void SapphireLoadFramework(NSString *frameworkPath)
519{
520        CFStringRef preferencesDomain = CFSTR("com.apple.frontrow.appliance.Sapphire.CompatClasses");
521        CFStringRef loadPathKey = CFSTR("loadPath");
522        CFPreferencesAppSynchronize(preferencesDomain);
523        CFPropertyListRef loadPathProperty = CFPreferencesCopyAppValue(loadPathKey, preferencesDomain);
524        CFStringRef loadPath = nil;
525        if(loadPathProperty != nil && CFGetTypeID(loadPathProperty) == CFStringGetTypeID())
526                loadPath = (CFStringRef)loadPathProperty;
527       
528        NSString *compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireCompatClasses.framework"];
529        NSBundle *compat = [NSBundle bundleWithPath:compatPath];
530       
531        if(NSClassFromString(@"SapphireFrontRowCompat") == nil)
532        {
533                if(loadPath != nil)
534                {
535                        NSBundle *otherBundle = [NSBundle bundleWithPath:(NSString *)loadPath];
536                        NSString *myVersion = [compat objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
537                        NSString *otherVersion = [otherBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
538                       
539                        if(otherVersion != nil && [myVersion compare:otherVersion] == NSOrderedAscending)
540                                compat = otherBundle;
541                }
542               
543                if( ![compat load]){ 
544                        @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
545                }
546                if([SapphireFrontRowCompat usingLeopardOrATypeOfTakeTwo])
547                {
548                        compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireLeopardCompatClasses.framework"];
549                        compat = [NSBundle bundleWithPath:compatPath];
550                        if( ![compat load]){ 
551                                @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireLeopardCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
552                        }
553                }
554                // ATV2
555                if([SapphireFrontRowCompat usingATypeOfTakeTwo])
556                {
557                        compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireTakeTwoCompatClasses.framework"];
558                        compat = [NSBundle bundleWithPath:compatPath];
559                        if( ![compat load]){ 
560                                @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireTakeTwoCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
561                        }
562                }
563                //ATV2.2
564                if([SapphireFrontRowCompat atvVersion] >= SapphireFrontRowCompatATVVersion2Dot2)
565                {
566                        compatPath = [frameworkPath stringByAppendingPathComponent:@"SapphireTakeTwoPointTwoCompatClasses.framework"];
567                        compat = [NSBundle bundleWithPath:compatPath];
568                        if( ![compat load]){ 
569                                @throw [NSException exceptionWithName:@"FileNotFoundException" reason:[NSString stringWithFormat:@"SapphireTakeTwoPointTwoCompatClasses could not be loaded from path %@", compatPath] userInfo:nil];
570                        }
571                }
572        }
573        else
574        {
575                //Check to see if we are later and mark it in preferences
576                NSBundle *loadedBundle = [NSBundle bundleForClass:NSClassFromString(@"SapphireFrontRowCompat")];
577                NSString *loadedVersion = [loadedBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
578                NSString *myVersion = [compat objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
579               
580                if([loadedVersion compare:myVersion] == NSOrderedAscending)
581                {
582                        //Check the one in the prefs too
583                        NSBundle *otherBundle = [NSBundle bundleWithPath:(NSString *)loadPath];
584                        NSString *otherVersion = [otherBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
585                        if(otherVersion == nil || [otherVersion compare:myVersion] == NSOrderedAscending)
586                        {
587                                CFPreferencesSetAppValue(loadPathKey, (CFStringRef)compatPath, preferencesDomain);
588                                CFPreferencesAppSynchronize(preferencesDomain);
589                                //Likely need to restart Finder here (delayed) or something because the next time around, the newer framework will be loaded.
590                        }
591                }
592        }
593        if(loadPathProperty)
594                CFRelease(loadPathProperty);
595}
596
Note: See TracBrowser for help on using the repository browser.