summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Example Apps/Example ObjC/MenuManager.m6
-rw-r--r--Example Apps/Example Swift/MenuManager.swift6
-rw-r--r--SmartDeviceLink-iOS.podspec2
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj36
-rw-r--r--SmartDeviceLink.podspec2
-rw-r--r--SmartDeviceLink/SDLAddSubMenu.h13
-rw-r--r--SmartDeviceLink/SDLAddSubMenu.m39
-rw-r--r--SmartDeviceLink/SDLMenuCell.h20
-rw-r--r--SmartDeviceLink/SDLMenuCell.m12
-rw-r--r--SmartDeviceLink/SDLMenuConfiguration.h36
-rw-r--r--SmartDeviceLink/SDLMenuConfiguration.m31
-rw-r--r--SmartDeviceLink/SDLMenuLayout.h25
-rw-r--r--SmartDeviceLink/SDLMenuLayout.m12
-rw-r--r--SmartDeviceLink/SDLMenuManager.h3
-rw-r--r--SmartDeviceLink/SDLMenuManager.m50
-rw-r--r--SmartDeviceLink/SDLRPCParameterNames.h2
-rw-r--r--SmartDeviceLink/SDLRPCParameterNames.m2
-rw-r--r--SmartDeviceLink/SDLScreenManager.h12
-rw-r--r--SmartDeviceLink/SDLScreenManager.m8
-rw-r--r--SmartDeviceLink/SDLSetGlobalProperties.h28
-rw-r--r--SmartDeviceLink/SDLSetGlobalProperties.m17
-rw-r--r--SmartDeviceLink/SDLWindowCapability.h8
-rw-r--r--SmartDeviceLink/SDLWindowCapability.m8
-rw-r--r--SmartDeviceLink/SmartDeviceLink.h2
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m24
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuConfigurationSpec.m28
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m87
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLMenuLayoutSpec.m15
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAddSubMenuSpec.m21
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitiesSpec.m7
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitySpec.m1
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWindowCapabilitySpec.m3
32 files changed, 499 insertions, 67 deletions
diff --git a/Example Apps/Example ObjC/MenuManager.m b/Example Apps/Example ObjC/MenuManager.m
index 308a66eee..ec9d221b3 100644
--- a/Example Apps/Example ObjC/MenuManager.m
+++ b/Example Apps/Example ObjC/MenuManager.m
@@ -58,7 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
[submenuItems addObject:cell];
}
- return [[SDLMenuCell alloc] initWithTitle:ACGetAllVehicleDataMenuName icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:CarBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] subCells:submenuItems];
+ return [[SDLMenuCell alloc] initWithTitle:ACGetAllVehicleDataMenuName icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:CarBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] submenuLayout:SDLMenuLayoutTiles subCells:submenuItems];
}
+ (NSArray<NSString *> *)sdlex_allVehicleDataTypes {
@@ -117,7 +117,7 @@ NS_ASSUME_NONNULL_BEGIN
}];
[submenuItems addObject:cell2];
- return [[SDLMenuCell alloc] initWithTitle:ACSubmenuTemplateMenuName icon:nil subCells:[submenuItems copy]];
+ return [[SDLMenuCell alloc] initWithTitle:ACSubmenuTemplateMenuName icon:nil submenuLayout:SDLMenuLayoutList subCells:[submenuItems copy]];
}
+ (SDLMenuCell *)sdlex_menuCellWithSubmenuWithManager:(SDLManager *)manager {
@@ -129,7 +129,7 @@ NS_ASSUME_NONNULL_BEGIN
[submenuItems addObject:cell];
}
- return [[SDLMenuCell alloc] initWithTitle:ACSubmenuMenuName icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:MenuBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] subCells:[submenuItems copy]];
+ return [[SDLMenuCell alloc] initWithTitle:ACSubmenuMenuName icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:MenuBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] submenuLayout:SDLMenuLayoutList subCells:[submenuItems copy]];
}
+ (SDLMenuCell *)sdlex_sliderMenuCellWithManager:(SDLManager *)manager {
diff --git a/Example Apps/Example Swift/MenuManager.swift b/Example Apps/Example Swift/MenuManager.swift
index 89ae1c741..f87b66099 100644
--- a/Example Apps/Example Swift/MenuManager.swift
+++ b/Example Apps/Example Swift/MenuManager.swift
@@ -67,7 +67,7 @@ private extension MenuManager {
})
}
- return SDLMenuCell(title: ACGetAllVehicleDataMenuName, icon: SDLArtwork(image: UIImage(named: CarBWIconImageName)!.withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), subCells: submenuItems)
+ return SDLMenuCell(title: ACGetAllVehicleDataMenuName, submenuLayout: .tiles, icon: SDLArtwork(image: UIImage(named: CarBWIconImageName)!.withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), subCells: submenuItems)
}
/// A list of all possible vehicle data types
@@ -151,7 +151,7 @@ private extension MenuManager {
}
}))
- return SDLMenuCell(title: ACSubmenuTemplateMenuName, icon: nil, subCells: submenuItems)
+ return SDLMenuCell(title: ACSubmenuTemplateMenuName, submenuLayout: .list, icon: nil, subCells: submenuItems)
}
/// Menu item that opens a submenu when selected
@@ -174,7 +174,7 @@ private extension MenuManager {
}))
}
- return SDLMenuCell(title: ACSubmenuMenuName, icon: SDLArtwork(image: #imageLiteral(resourceName: "choice_set").withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), subCells: submenuItems)
+ return SDLMenuCell(title: ACSubmenuMenuName, submenuLayout: .list, icon: SDLArtwork(image: #imageLiteral(resourceName: "choice_set").withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), subCells: submenuItems)
}
private class func sliderMenuCell(with manager: SDLManager) -> SDLMenuCell {
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index ede06fda0..284577fc8 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -217,6 +217,8 @@ ss.public_header_files = [
'SmartDeviceLink/SDLMediaServiceManifest.h',
'SmartDeviceLink/SDLMediaType.h',
'SmartDeviceLink/SDLMenuCell.h',
+'SmartDeviceLink/SDLMenuConfiguration.h',
+'SmartDeviceLink/SDLMenuLayout.h',
'SmartDeviceLink/SDLMenuManagerConstants.h',
'SmartDeviceLink/SDLMenuParams.h',
'SmartDeviceLink/SDLMetadataTags.h',
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 18765fcd2..7e98d9a5b 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -1028,6 +1028,12 @@
5D75960D22972F830013207C /* TestSystemCapabilityObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D75960C22972F830013207C /* TestSystemCapabilityObserver.m */; };
5D75961122972FCA0013207C /* SDLSystemCapabilityObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D75960F22972FCA0013207C /* SDLSystemCapabilityObserver.h */; };
5D75961222972FCA0013207C /* SDLSystemCapabilityObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D75961022972FCA0013207C /* SDLSystemCapabilityObserver.m */; };
+ 5D76750E22D8FB3700E8D71A /* SDLMenuLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D76750C22D8FB3700E8D71A /* SDLMenuLayout.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5D76750F22D8FB3700E8D71A /* SDLMenuLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D76750D22D8FB3700E8D71A /* SDLMenuLayout.m */; };
+ 5D76751322D9088F00E8D71A /* SDLMenuConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D76751122D9088F00E8D71A /* SDLMenuConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5D76751422D9088F00E8D71A /* SDLMenuConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D76751222D9088F00E8D71A /* SDLMenuConfiguration.m */; };
+ 5D76751622D920FD00E8D71A /* SDLMenuConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D76751522D920FD00E8D71A /* SDLMenuConfigurationSpec.m */; };
+ 5D76751822D921CB00E8D71A /* SDLMenuLayoutSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D76751722D921CB00E8D71A /* SDLMenuLayoutSpec.m */; };
5D76E31C1D3805FF00647CFA /* SDLLockScreenManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D76E31B1D3805FF00647CFA /* SDLLockScreenManagerSpec.m */; };
5D76E3211D39742300647CFA /* SDLViewControllerPresentable.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D76E3201D39742300647CFA /* SDLViewControllerPresentable.h */; };
5D76E3241D39767000647CFA /* SDLLockScreenPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D76E3221D39767000647CFA /* SDLLockScreenPresenter.h */; };
@@ -2761,6 +2767,12 @@
5D75960C22972F830013207C /* TestSystemCapabilityObserver.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TestSystemCapabilityObserver.m; path = DevAPISpecs/TestSystemCapabilityObserver.m; sourceTree = "<group>"; };
5D75960F22972FCA0013207C /* SDLSystemCapabilityObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLSystemCapabilityObserver.h; sourceTree = "<group>"; };
5D75961022972FCA0013207C /* SDLSystemCapabilityObserver.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLSystemCapabilityObserver.m; sourceTree = "<group>"; };
+ 5D76750C22D8FB3700E8D71A /* SDLMenuLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLMenuLayout.h; sourceTree = "<group>"; };
+ 5D76750D22D8FB3700E8D71A /* SDLMenuLayout.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLMenuLayout.m; sourceTree = "<group>"; };
+ 5D76751122D9088F00E8D71A /* SDLMenuConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLMenuConfiguration.h; sourceTree = "<group>"; };
+ 5D76751222D9088F00E8D71A /* SDLMenuConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLMenuConfiguration.m; sourceTree = "<group>"; };
+ 5D76751522D920FD00E8D71A /* SDLMenuConfigurationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDLMenuConfigurationSpec.m; path = DevAPISpecs/SDLMenuConfigurationSpec.m; sourceTree = "<group>"; };
+ 5D76751722D921CB00E8D71A /* SDLMenuLayoutSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLMenuLayoutSpec.m; sourceTree = "<group>"; };
5D76E31B1D3805FF00647CFA /* SDLLockScreenManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLLockScreenManagerSpec.m; path = DevAPISpecs/SDLLockScreenManagerSpec.m; sourceTree = "<group>"; };
5D76E3201D39742300647CFA /* SDLViewControllerPresentable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLViewControllerPresentable.h; sourceTree = "<group>"; };
5D76E3221D39767000647CFA /* SDLLockScreenPresenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLockScreenPresenter.h; sourceTree = "<group>"; };
@@ -3460,6 +3472,7 @@
1EB59CC9202DC8E300343A61 /* SDLMassageZoneSpec.m */,
162E82061A9BDE8A00906325 /* SDLMediaClockFormatSpec.m */,
88E6F1A9220E1720006156F9 /* SDLMediaTypeSpec.m */,
+ 5D76751722D921CB00E8D71A /* SDLMenuLayoutSpec.m */,
8BBEA6081F324832003EEA26 /* SDLMetadataTypeSpec.m */,
1EB59CC7202DC86A00343A61 /* SDLModuleTypeSpec.m */,
88B58DC822204C9E0011B063 /* SDLNavigationActionSpec.m */,
@@ -4020,6 +4033,7 @@
5D339CE5207C0651000CC364 /* Menu */ = {
isa = PBXGroup;
children = (
+ 5D76751022D907F500E8D71A /* Configuration */,
755F175E229F14F70041B9CB /* Dynamic Menu Update Utilities */,
5D339CEC207C08AB000CC364 /* Cells */,
5D339CF1207C0ACE000CC364 /* SDLMenuManager.h */,
@@ -4898,10 +4912,12 @@
5D61FB0A1A84238A00846EE7 /* SDLMediaClockFormat.m */,
88E6F1A5220E1588006156F9 /* SDLMediaType.h */,
88E6F1A6220E1588006156F9 /* SDLMediaType.m */,
- 1E5AD0461F1F773E0029B8AF /* SDLModuleType.h */,
- 1E5AD0471F1F773E0029B8AF /* SDLModuleType.m */,
+ 5D76750C22D8FB3700E8D71A /* SDLMenuLayout.h */,
+ 5D76750D22D8FB3700E8D71A /* SDLMenuLayout.m */,
8BBEA6041F324165003EEA26 /* SDLMetadataType.h */,
8BBEA6051F324165003EEA26 /* SDLMetadataType.m */,
+ 1E5AD0461F1F773E0029B8AF /* SDLModuleType.h */,
+ 1E5AD0471F1F773E0029B8AF /* SDLModuleType.m */,
88B58DC422204AF10011B063 /* SDLNavigationAction.h */,
88B58DC522204AF10011B063 /* SDLNavigationAction.m */,
88B58DBE222045320011B063 /* SDLNavigationJunction.h */,
@@ -5353,6 +5369,15 @@
name = Utilities;
sourceTree = "<group>";
};
+ 5D76751022D907F500E8D71A /* Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ 5D76751122D9088F00E8D71A /* SDLMenuConfiguration.h */,
+ 5D76751222D9088F00E8D71A /* SDLMenuConfiguration.m */,
+ );
+ name = Configuration;
+ sourceTree = "<group>";
+ };
5D76E31A1D3805E600647CFA /* LockScreen */ = {
isa = PBXGroup;
children = (
@@ -6063,6 +6088,7 @@
5DAB5F5220989A8300A020C8 /* SDLVoiceCommandSpec.m */,
752ECDB8228C42E100D945F4 /* SDLMenuRunScoreSpec.m */,
752ECDBA228C532600D945F4 /* SDLMenuUpdateAlgorithmSpec.m */,
+ 5D76751522D920FD00E8D71A /* SDLMenuConfigurationSpec.m */,
);
name = Menu;
sourceTree = "<group>";
@@ -6681,6 +6707,7 @@
5D61FC511A84238C00846EE7 /* SDLButtonCapabilities.h in Headers */,
5D61FDE91A84238C00846EE7 /* SDLUnsubscribeButtonResponse.h in Headers */,
5D61FCD51A84238C00846EE7 /* SDLImageType.h in Headers */,
+ 5D76750E22D8FB3700E8D71A /* SDLMenuLayout.h in Headers */,
8803DCEF22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h in Headers */,
5D61FC2F1A84238C00846EE7 /* SDLAddCommandResponse.h in Headers */,
5D0C2A0020D9479B008B56CD /* SDLStreamingVideoLifecycleManager.h in Headers */,
@@ -6697,6 +6724,7 @@
5D61FD7B1A84238C00846EE7 /* SDLScrollableMessage.h in Headers */,
DA9F7E931DCC04E400ACAE48 /* SDLUnsubscribeWayPoints.h in Headers */,
5D61FD3D1A84238C00846EE7 /* SDLPrimaryAudioSource.h in Headers */,
+ 5D76751322D9088F00E8D71A /* SDLMenuConfiguration.h in Headers */,
DAC5725C1D10B81E0004288B /* SDLTouch.h in Headers */,
5D6F7A2E1BC5650B0070BF37 /* SDLLifecycleConfiguration.h in Headers */,
5D61FCCD1A84238C00846EE7 /* SDLImage.h in Headers */,
@@ -7515,6 +7543,7 @@
5D92935F20B33FF700FCC775 /* SDLChoiceSet.m in Sources */,
8855F9E4220CB04000A5C897 /* SDLOnAppServiceData.m in Sources */,
5D61FC321A84238C00846EE7 /* SDLAddSubMenu.m in Sources */,
+ 5D76751422D9088F00E8D71A /* SDLMenuConfiguration.m in Sources */,
5D61FDF61A84238C00846EE7 /* SDLV1ProtocolHeader.m in Sources */,
EE798CA620561218008EDE8E /* SDLSecondaryTransportManager.m in Sources */,
88B58DC1222045320011B063 /* SDLNavigationJunction.m in Sources */,
@@ -7560,6 +7589,7 @@
5D61FD9E1A84238C00846EE7 /* SDLSliderResponse.m in Sources */,
1EAA47462035623B000FE74B /* SDLLightControlData.m in Sources */,
0055412F22D759BD003194D3 /* SDLSeatLocation.m in Sources */,
+ 5D76750F22D8FB3700E8D71A /* SDLMenuLayout.m in Sources */,
5D61FC5C1A84238C00846EE7 /* SDLChangeRegistration.m in Sources */,
5D1665C91CF8CA3D00CC4CA1 /* SDLPermissionFilter.m in Sources */,
5D61FDBA1A84238C00846EE7 /* SDLSyncPDataResponse.m in Sources */,
@@ -7747,12 +7777,14 @@
162E82FD1A9BDE8B00906325 /* SDLSystemContextSpec.m in Sources */,
162E82E21A9BDE8B00906325 /* SDLIgnitionStableStatusSpec.m in Sources */,
162E82EE1A9BDE8B00906325 /* SDLMediaClockFormatSpec.m in Sources */,
+ 5D76751822D921CB00E8D71A /* SDLMenuLayoutSpec.m in Sources */,
5DA026901AD44EE700019F86 /* SDLDialNumberResponseSpec.m in Sources */,
162E83901A9BDE8B00906325 /* SDLTireStatusSpec.m in Sources */,
000DD57622EF0971005AB7A7 /* SDLReleaseInteriorVehicleDataModuleResponseSpec.m in Sources */,
162E82E01A9BDE8B00906325 /* SDLHMILevelSpec.m in Sources */,
88F65133220C6DC300CAF321 /* SDLWeatherAlertSpec.m in Sources */,
5DC09EDA1F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m in Sources */,
+ 5D76751622D920FD00E8D71A /* SDLMenuConfigurationSpec.m in Sources */,
1EB59CCE202DC97900343A61 /* SDLMassageCushionSpec.m in Sources */,
88EF8EBA22D8F48300CB06C2 /* SDLCancelInteractionSpec.m in Sources */,
162E83041A9BDE8B00906325 /* SDLUpdateModeSpec.m in Sources */,
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index a27254288..84841ee6e 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -218,6 +218,8 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLMediaServiceManifest.h',
'SmartDeviceLink/SDLMediaType.h',
'SmartDeviceLink/SDLMenuCell.h',
+'SmartDeviceLink/SDLMenuConfiguration.h',
+'SmartDeviceLink/SDLMenuLayout.h',
'SmartDeviceLink/SDLMenuManagerConstants.h',
'SmartDeviceLink/SDLMenuParams.h',
'SmartDeviceLink/SDLMetadataTags.h',
diff --git a/SmartDeviceLink/SDLAddSubMenu.h b/SmartDeviceLink/SDLAddSubMenu.h
index bd5537c2d..338ecd645 100644
--- a/SmartDeviceLink/SDLAddSubMenu.h
+++ b/SmartDeviceLink/SDLAddSubMenu.h
@@ -3,6 +3,8 @@
#import "SDLRPCRequest.h"
+#import "SDLMenuLayout.h"
+
@class SDLImage;
/**
@@ -25,9 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName;
-- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName position:(UInt8)position __deprecated_msg(("Use initWithId:menuName:menuIcon:position: instead"));
+- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName position:(UInt8)position __deprecated_msg("Use initWithId:menuName:menuLayout:menuIcon:position: instead");
+
+- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName menuIcon:(nullable SDLImage *)icon position:(UInt8)position __deprecated_msg("Use initWithId:menuName:menuLayout:menuIcon:position: instead");
-- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName menuIcon:(nullable SDLImage *)icon position:(UInt8)position;
+- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName menuLayout:(nullable SDLMenuLayout)menuLayout menuIcon:(nullable SDLImage *)icon position:(UInt8)position;
/**
* a Menu ID that identifies a sub menu
@@ -68,6 +72,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (strong, nonatomic, nullable) SDLImage *menuIcon;
+/**
+ The sub-menu layout. See available menu layouts on SDLWindowCapability.menuLayoutsAvailable. Defaults to LIST.
+ */
+@property (strong, nonatomic, nullable) SDLMenuLayout menuLayout;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLAddSubMenu.m b/SmartDeviceLink/SDLAddSubMenu.m
index 48ea43c8a..649a10a31 100644
--- a/SmartDeviceLink/SDLAddSubMenu.m
+++ b/SmartDeviceLink/SDLAddSubMenu.m
@@ -20,28 +20,33 @@ NS_ASSUME_NONNULL_BEGIN
}
#pragma clang diagnostic pop
-- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName menuIcon:(nullable SDLImage *)icon position:(UInt8)position {
- self = [self initWithId:menuId menuName:menuName];
- if (!self) { return nil; }
+- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
- self.position = @(position);
- self.menuIcon = icon;
+ self.menuID = @(menuId);
+ self.menuName = menuName;
return self;
}
- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName position:(UInt8)position {
- return [self initWithId:menuId menuName:menuName menuIcon:nil position:position];
+ return [self initWithId:menuId menuName:menuName menuLayout:nil menuIcon:nil position:position];
}
-- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName {
- self = [self init];
- if (!self) {
- return nil;
- }
+- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName menuIcon:(nullable SDLImage *)icon position:(UInt8)position {
+ return [self initWithId:menuId menuName:menuName menuLayout:nil menuIcon:icon position:position];
+}
- self.menuID = @(menuId);
- self.menuName = menuName;
+- (instancetype)initWithId:(UInt32)menuId menuName:(NSString *)menuName menuLayout:(nullable SDLMenuLayout)menuLayout menuIcon:(nullable SDLImage *)icon position:(UInt8)position {
+ self = [self initWithId:menuId menuName:menuName];
+ if (!self) { return nil; }
+
+ self.position = @(position);
+ self.menuIcon = icon;
+ self.menuLayout = menuLayout;
return self;
}
@@ -80,6 +85,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_objectForName:SDLRPCParameterNameMenuIcon ofClass:[SDLImage class] error:nil];
}
+- (void)setMenuLayout:(nullable SDLMenuLayout)menuLayout {
+ [self.parameters sdl_setObject:menuLayout forName:SDLRPCParameterNameMenuLayout];
+}
+
+- (nullable SDLMenuLayout)menuLayout {
+ return [self.parameters sdl_enumForName:SDLRPCParameterNameMenuLayout error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLMenuCell.h b/SmartDeviceLink/SDLMenuCell.h
index 1c9c8dcbc..5d5d1ea2b 100644
--- a/SmartDeviceLink/SDLMenuCell.h
+++ b/SmartDeviceLink/SDLMenuCell.h
@@ -8,6 +8,7 @@
#import <Foundation/Foundation.h>
+#import "SDLMenuLayout.h"
#import "SDLTriggerSource.h"
@class SDLArtwork;
@@ -44,6 +45,11 @@ typedef void(^SDLMenuCellSelectionHandler)(SDLTriggerSource triggerSource);
@property (copy, nonatomic, readonly, nullable) NSArray<SDLMenuCell *> *subCells;
/**
+ The layout in which the `subCells` will be displayed.
+ */
+@property (strong, nonatomic, readonly, nullable) SDLMenuLayout submenuLayout;
+
+/**
Create a menu cell that has no subcells.
@param title The cell's primary text
@@ -71,7 +77,19 @@ typedef void(^SDLMenuCellSelectionHandler)(SDLTriggerSource triggerSource);
@param subCells The subcells that will appear when the cell is selected
@return The menu cell
*/
-- (instancetype)initWithTitle:(NSString *)title icon:(nullable SDLArtwork *)icon subCells:(NSArray<SDLMenuCell *> *)subCells;
+- (instancetype)initWithTitle:(NSString *)title icon:(nullable SDLArtwork *)icon subCells:(NSArray<SDLMenuCell *> *)subCells __deprecated_msg("Use initWithTitle:icon:layout:subcells: instead");
+
+/**
+ Create a menu cell that has subcells and when selected will go into a deeper part of the menu
+
+ @param title The cell's primary text
+ @param icon The cell's image
+ @param layout The layout that the subCells will be layed out in if that submenu is entered
+ @param subCells The subcells that will appear when the cell is selected
+ @return The menu cell
+ */
+- (instancetype)initWithTitle:(NSString *)title icon:(nullable SDLArtwork *)icon submenuLayout:(nullable SDLMenuLayout)layout subCells:(NSArray<SDLMenuCell *> *)subCells;
+
@end
diff --git a/SmartDeviceLink/SDLMenuCell.m b/SmartDeviceLink/SDLMenuCell.m
index 81ba056bf..67281cb21 100644
--- a/SmartDeviceLink/SDLMenuCell.m
+++ b/SmartDeviceLink/SDLMenuCell.m
@@ -37,14 +37,19 @@ NS_ASSUME_NONNULL_BEGIN
}
- (instancetype)initWithTitle:(NSString *)title subCells:(NSArray<SDLMenuCell *> *)subCells {
- return [self initWithTitle:title icon:nil subCells:subCells];
+ return [self initWithTitle:title icon:nil submenuLayout:nil subCells:subCells];
}
- (instancetype)initWithTitle:(NSString *)title icon:(nullable SDLArtwork *)icon subCells:(NSArray<SDLMenuCell *> *)subCells {
+ return [self initWithTitle:title icon:icon submenuLayout:nil subCells:subCells];
+}
+
+- (instancetype)initWithTitle:(NSString *)title icon:(nullable SDLArtwork *)icon submenuLayout:(nullable SDLMenuLayout)layout subCells:(NSArray<SDLMenuCell *> *)subCells {
self = [super init];
if (!self) { return nil; }
_title = title;
+ _submenuLayout = layout;
_icon = icon;
_subCells = subCells;
@@ -55,7 +60,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (NSString *)description {
- return [NSString stringWithFormat:@"SDLMenuCell: %u-\"%@\", artworkName: %@, voice commands: %lu, isSubcell: %@, hasSubcells: %@", (unsigned int)_cellId, _title, _icon.name, (unsigned long)_voiceCommands.count, (_parentCellId != UINT32_MAX ? @"YES" : @"NO"), (_subCells.count > 0 ? @"YES" : @"NO")];
+ return [NSString stringWithFormat:@"SDLMenuCell: %u-\"%@\", artworkName: %@, voice commands: %lu, isSubcell: %@, hasSubcells: %@, submenuLayout: %@", (unsigned int)_cellId, _title, _icon.name, (unsigned long)_voiceCommands.count, (_parentCellId != UINT32_MAX ? @"YES" : @"NO"), (_subCells.count > 0 ? @"YES" : @"NO"), _submenuLayout];
}
#pragma mark - Object Equality
@@ -69,7 +74,8 @@ NSUInteger NSUIntRotateCell(NSUInteger val, NSUInteger howMuch) {
return NSUIntRotateCell(self.title.hash, NSUIntBitCell / 2)
^ NSUIntRotateCell(self.icon.name.hash, NSUIntBitCell / 3)
^ NSUIntRotateCell(self.voiceCommands.hash, NSUIntBitCell / 4)
- ^ NSUIntRotateCell(self.subCells.count !=0, NSUIntBitCell / 5 );
+ ^ NSUIntRotateCell(self.subCells.count !=0, NSUIntBitCell / 5)
+ ^ NSUIntRotateCell(self.submenuLayout.hash, NSUIntBitCell / 6);
}
- (BOOL)isEqual:(id)object {
diff --git a/SmartDeviceLink/SDLMenuConfiguration.h b/SmartDeviceLink/SDLMenuConfiguration.h
new file mode 100644
index 000000000..6aefdb2f4
--- /dev/null
+++ b/SmartDeviceLink/SDLMenuConfiguration.h
@@ -0,0 +1,36 @@
+//
+// SDLMenuConfiguration.h
+// SmartDeviceLink
+//
+// Created by Joel Fischer on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLMenuLayout.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLMenuConfiguration : NSObject
+
+/**
+ * Changes the default main menu layout. Defaults to `SDLMenuLayoutList`.
+ */
+@property (strong, nonatomic, readonly) SDLMenuLayout mainMenuLayout;
+
+/**
+ * Changes the default submenu layout. To change this for an individual submenu, set the `menuLayout` property on the `SDLMenuCell` initializer for creating a cell with sub-cells. Defaults to `SDLMenuLayoutList`.
+ */
+@property (strong, nonatomic, readonly) SDLMenuLayout defaultSubmenuLayout;
+
+/**
+ Initialize a new menu configuration with a main menu layout and a default submenu layout which can be overriden per-submenu if desired.
+
+ @param mainMenuLayout The new main menu layout
+ @param defaultSubmenuLayout The new default submenu layout
+ @return The menu configuration
+ */
+- (instancetype)initWithMainMenuLayout:(SDLMenuLayout)mainMenuLayout defaultSubmenuLayout:(SDLMenuLayout)defaultSubmenuLayout;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLMenuConfiguration.m b/SmartDeviceLink/SDLMenuConfiguration.m
new file mode 100644
index 000000000..2049c83bf
--- /dev/null
+++ b/SmartDeviceLink/SDLMenuConfiguration.m
@@ -0,0 +1,31 @@
+//
+// SDLMenuConfiguration.m
+// SmartDeviceLink
+//
+// Created by Joel Fischer on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLMenuConfiguration.h"
+
+@implementation SDLMenuConfiguration
+
+- (instancetype)init {
+ return [self initWithMainMenuLayout:SDLMenuLayoutList defaultSubmenuLayout:SDLMenuLayoutList];
+}
+
+- (instancetype)initWithMainMenuLayout:(SDLMenuLayout)mainMenuLayout defaultSubmenuLayout:(SDLMenuLayout)defaultSubmenuLayout {
+ self = [super init];
+ if (!self) { return nil; }
+
+ _mainMenuLayout = mainMenuLayout;
+ _defaultSubmenuLayout = defaultSubmenuLayout;
+
+ return self;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"Menu configuration, main menu layout: %@, submenu default layout: %@", _mainMenuLayout, _defaultSubmenuLayout];
+}
+
+@end
diff --git a/SmartDeviceLink/SDLMenuLayout.h b/SmartDeviceLink/SDLMenuLayout.h
new file mode 100644
index 000000000..e2fe8e40a
--- /dev/null
+++ b/SmartDeviceLink/SDLMenuLayout.h
@@ -0,0 +1,25 @@
+//
+// SDLMenuLayout.h
+// SmartDeviceLink
+//
+// Created by Joel Fischer on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLEnum.h"
+
+/**
+ * Enum for each type of video streaming protocol, used in VideoStreamingFormat
+ */
+typedef SDLEnum SDLMenuLayout SDL_SWIFT_ENUM;
+
+/**
+ * The menu should be laid out in a scrollable list format with one menu cell below the previous, each is stretched across the view
+ */
+extern SDLMenuLayout const SDLMenuLayoutList;
+
+/**
+ * The menu should be laid out in a scrollable tiles format with each menu cell laid out in a square-ish format next to each other horizontally
+ */
+extern SDLMenuLayout const SDLMenuLayoutTiles;
+
diff --git a/SmartDeviceLink/SDLMenuLayout.m b/SmartDeviceLink/SDLMenuLayout.m
new file mode 100644
index 000000000..8b1b95b38
--- /dev/null
+++ b/SmartDeviceLink/SDLMenuLayout.m
@@ -0,0 +1,12 @@
+//
+// SDLMenuLayout.m
+// SmartDeviceLink
+//
+// Created by Joel Fischer on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLMenuLayout.h"
+
+SDLMenuLayout const SDLMenuLayoutList = @"LIST";
+SDLMenuLayout const SDLMenuLayoutTiles = @"TILES";
diff --git a/SmartDeviceLink/SDLMenuManager.h b/SmartDeviceLink/SDLMenuManager.h
index 84a75170e..54701313b 100644
--- a/SmartDeviceLink/SDLMenuManager.h
+++ b/SmartDeviceLink/SDLMenuManager.h
@@ -11,6 +11,7 @@
@class SDLFileManager;
@class SDLMenuCell;
+@class SDLMenuConfiguration;
@class SDLSystemCapabilityManager;
@class SDLVoiceCommand;
@@ -34,6 +35,8 @@ typedef void(^SDLMenuUpdateCompletionHandler)(NSError *__nullable error);
*/
- (void)stop;
+@property (strong, nonatomic) SDLMenuConfiguration *menuConfiguration;
+
@property (copy, nonatomic) NSArray<SDLMenuCell *> *menuCells;
@property (assign, nonatomic) SDLDynamicMenuUpdatesMode dynamicMenuUpdatesMode;
diff --git a/SmartDeviceLink/SDLMenuManager.m b/SmartDeviceLink/SDLMenuManager.m
index be83af2e3..aa3a1e22f 100644
--- a/SmartDeviceLink/SDLMenuManager.m
+++ b/SmartDeviceLink/SDLMenuManager.m
@@ -22,6 +22,7 @@
#import "SDLImage.h"
#import "SDLLogMacros.h"
#import "SDLMenuCell.h"
+#import "SDLMenuConfiguration.h"
#import "SDLMenuParams.h"
#import "SDLDynamicMenuUpdateRunScore.h"
#import "SDLDynamicMenuUpdateAlgorithm.h"
@@ -32,6 +33,7 @@
#import "SDLRPCNotificationNotification.h"
#import "SDLRPCResponseNotification.h"
#import "SDLSetDisplayLayoutResponse.h"
+#import "SDLSetGlobalProperties.h"
#import "SDLScreenManager.h"
#import "SDLShowAppMenu.h"
#import "SDLSystemCapabilityManager.h"
@@ -51,6 +53,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLMenuManager()
+// Dependencies
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (weak, nonatomic) SDLFileManager *fileManager;
@property (weak, nonatomic) SDLSystemCapabilityManager *systemCapabilityManager;
@@ -78,6 +81,7 @@ UInt32 const MenuCellIdMin = 1;
if (!self) { return nil; }
_lastMenuId = MenuCellIdMin;
+ _menuConfiguration = [[SDLMenuConfiguration alloc] init];
_menuCells = @[];
_oldMenuCells = @[];
_dynamicMenuUpdatesMode = SDLDynamicMenuUpdatesModeOnWithCompatibility;
@@ -114,6 +118,42 @@ UInt32 const MenuCellIdMin = 1;
#pragma mark - Setters
+- (void)setMenuConfiguration:(SDLMenuConfiguration *)menuConfiguration {
+ NSArray<SDLMenuLayout> *layoutsAvailable = self.systemCapabilityManager.defaultMainWindowCapability.menuLayoutsAvailable;
+
+ if ([[SDLGlobals sharedGlobals].rpcVersion isLessThanVersion:[SDLVersion versionWithMajor:6 minor:0 patch:0]]) {
+ SDLLogW(@"Menu configurations is only supported on head units with RPC spec version 6.0.0 or later. Currently connected head unit RPC spec version is %@", [SDLGlobals sharedGlobals].rpcVersion);
+ return;
+ } else if (layoutsAvailable == nil) {
+ SDLLogW(@"Could not set the main menu configuration. Which menu layouts can be used is not available");
+ return;
+ } else if (![layoutsAvailable containsObject:menuConfiguration.mainMenuLayout]
+ || ![layoutsAvailable containsObject:menuConfiguration.defaultSubmenuLayout]) {
+ SDLLogE(@"One or more of the set menu layouts are not available on this system. The menu configuration will not be set. Available menu layouts: %@, set menu layouts: %@", layoutsAvailable, menuConfiguration);
+ return;
+ } else if (self.currentHMILevel == nil
+ || [self.currentHMILevel isEqualToEnum:SDLHMILevelNone]) {
+ SDLLogE(@"Could not set main menu configuration, HMI level: %@, required: 'Not-NONE', system context: %@, required: 'Not MENU'", self.currentHMILevel, self.currentSystemContext);
+ return;
+ }
+
+ SDLMenuConfiguration *oldConfig = _menuConfiguration;
+ _menuConfiguration = menuConfiguration;
+
+ SDLSetGlobalProperties *setGlobalsRPC = [[SDLSetGlobalProperties alloc] init];
+ setGlobalsRPC.menuLayout = menuConfiguration.mainMenuLayout;
+
+ __weak typeof(self) weakself = self;
+ [self.connectionManager sendConnectionRequest:setGlobalsRPC withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ __strong typeof(weakself) strongself = weakself;
+ if (error != nil) {
+ SDLLogE(@"Could not set main menu configuration: %@", error);
+ strongself.menuConfiguration = oldConfig;
+ return;
+ }
+ }];
+}
+
- (void)setMenuCells:(NSArray<SDLMenuCell *> *)menuCells {
if (self.currentHMILevel == nil
|| [self.currentHMILevel isEqualToEnum:SDLHMILevelNone]
@@ -561,7 +601,15 @@ UInt32 const MenuCellIdMin = 1;
- (SDLAddSubMenu *)sdl_subMenuCommandForMenuCell:(SDLMenuCell *)cell withArtwork:(BOOL)shouldHaveArtwork position:(UInt16)position {
SDLImage *icon = (shouldHaveArtwork && (cell.icon.name != nil)) ? cell.icon.imageRPC : nil;
- return [[SDLAddSubMenu alloc] initWithId:cell.cellId menuName:cell.title menuIcon:icon position:(UInt8)position];
+
+ SDLMenuLayout submenuLayout = nil;
+ if (cell.submenuLayout && [self.systemCapabilityManager.defaultMainWindowCapability.menuLayoutsAvailable containsObject:cell.submenuLayout]) {
+ submenuLayout = cell.submenuLayout;
+ } else {
+ submenuLayout = self.menuConfiguration.defaultSubmenuLayout;
+ }
+
+ return [[SDLAddSubMenu alloc] initWithId:cell.cellId menuName:cell.title menuLayout:submenuLayout menuIcon:icon position:(UInt8)position];
}
#pragma mark - Calling handlers
diff --git a/SmartDeviceLink/SDLRPCParameterNames.h b/SmartDeviceLink/SDLRPCParameterNames.h
index 03f919b23..718d42bfc 100644
--- a/SmartDeviceLink/SDLRPCParameterNames.h
+++ b/SmartDeviceLink/SDLRPCParameterNames.h
@@ -379,6 +379,8 @@ extern SDLRPCParameterName const SDLRPCParameterNameMediaType;
extern SDLRPCParameterName const SDLRPCParameterNameMemory;
extern SDLRPCParameterName const SDLRPCParameterNameMenuIcon;
extern SDLRPCParameterName const SDLRPCParameterNameMenuId;
+extern SDLRPCParameterName const SDLRPCParameterNameMenuLayout;
+extern SDLRPCParameterName const SDLRPCParameterNameMenuLayoutsAvailable;
extern SDLRPCParameterName const SDLRPCParameterNameMenuName;
extern SDLRPCParameterName const SDLRPCParameterNameMenuParams;
extern SDLRPCParameterName const SDLRPCParameterNameMenuTitle;
diff --git a/SmartDeviceLink/SDLRPCParameterNames.m b/SmartDeviceLink/SDLRPCParameterNames.m
index 4bd3f6115..c928fcb30 100644
--- a/SmartDeviceLink/SDLRPCParameterNames.m
+++ b/SmartDeviceLink/SDLRPCParameterNames.m
@@ -372,6 +372,8 @@ SDLRPCParameterName const SDLRPCParameterNameMemory = @"memory";
SDLRPCParameterName const SDLRPCParameterNameMemoryAvailable = @"memoryAvailable";
SDLRPCParameterName const SDLRPCParameterNameMenuIcon = @"menuIcon";
SDLRPCParameterName const SDLRPCParameterNameMenuId = @"menuID";
+SDLRPCParameterName const SDLRPCParameterNameMenuLayout = @"menuLayout";
+SDLRPCParameterName const SDLRPCParameterNameMenuLayoutsAvailable = @"menuLayoutsAvailable";
SDLRPCParameterName const SDLRPCParameterNameMenuName = @"menuName";
SDLRPCParameterName const SDLRPCParameterNameMenuParams = @"menuParams";
SDLRPCParameterName const SDLRPCParameterNameMenuTitle = @"menuTitle";
diff --git a/SmartDeviceLink/SDLScreenManager.h b/SmartDeviceLink/SDLScreenManager.h
index 15d159de4..0df4c21a6 100644
--- a/SmartDeviceLink/SDLScreenManager.h
+++ b/SmartDeviceLink/SDLScreenManager.h
@@ -20,6 +20,7 @@
@class SDLFileManager;
@class SDLKeyboardProperties;
@class SDLMenuCell;
+@class SDLMenuConfiguration;
@class SDLSoftButtonObject;
@class SDLSystemCapabilityManager;
@class SDLVoiceCommand;
@@ -123,6 +124,17 @@ typedef void(^SDLPreloadChoiceCompletionHandler)(NSError *__nullable error);
#pragma mark Menu
/**
+ Configures the layout of the menu and sub-menus. If set after a menu already exists, the existing main menu layout will be updated, _HOWEVER_ sub-menus will not be automatically updated; you will have to send a new menu to see the new submenu layout.
+
+ If set menu layouts don't match available menu layouts in WindowCapability, an error log will be emitted and the layout will not be set.
+
+ Setting this parameter will send a message to the remote system. This value will be set immediately, but if that message is rejected, the original value will be re-set and an error log will be emitted.
+
+ This only works on head units supporting RPC spec version 6.0 and newer. If the connected head unit does not support this feature, a warning log will be emitted and nothing will be set.
+ */
+@property (strong, nonatomic) SDLMenuConfiguration *menuConfiguration;
+
+/**
The current list of menu cells displayed in the app's menu.
*/
@property (copy, nonatomic) NSArray<SDLMenuCell *> *menu;
diff --git a/SmartDeviceLink/SDLScreenManager.m b/SmartDeviceLink/SDLScreenManager.m
index ea9ea5676..fac9ca4c0 100644
--- a/SmartDeviceLink/SDLScreenManager.m
+++ b/SmartDeviceLink/SDLScreenManager.m
@@ -138,6 +138,10 @@ NS_ASSUME_NONNULL_BEGIN
self.softButtonManager.softButtonObjects = softButtonObjects;
}
+- (void)setMenuConfiguration:(SDLMenuConfiguration *)menuConfiguration {
+ self.menuManager.menuConfiguration = menuConfiguration;
+}
+
- (void)setMenu:(NSArray<SDLMenuCell *> *)menu {
self.menuManager.menuCells = menu;
}
@@ -216,6 +220,10 @@ NS_ASSUME_NONNULL_BEGIN
return _softButtonManager.softButtonObjects;
}
+- (SDLMenuConfiguration *)menuConfiguration {
+ return _menuManager.menuConfiguration;
+}
+
- (NSArray<SDLMenuCell *> *)menu {
return _menuManager.menuCells;
}
diff --git a/SmartDeviceLink/SDLSetGlobalProperties.h b/SmartDeviceLink/SDLSetGlobalProperties.h
index a0a947757..ef1746ad5 100644
--- a/SmartDeviceLink/SDLSetGlobalProperties.h
+++ b/SmartDeviceLink/SDLSetGlobalProperties.h
@@ -3,6 +3,8 @@
#import "SDLRPCRequest.h"
+#import "SDLMenuLayout.h"
+
@class SDLImage;
@class SDLKeyboardProperties;
@class SDLTTSChunk;
@@ -27,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
@param timeoutText A string that will be turned into TTS chunks for the timeout prompt
@return The SetGlobalProperties RPC
*/
-- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText;
+- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText __deprecated_msg("Use initWithHelpText:timeoutText:vrHelpTitle:vrHelp:menuTitle:menuIcon:keyboardProperties:menuLayout: instead");
/**
Initialize SetGlobalProperties with help text, timeout text, help title, and help items
@@ -38,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
@param vrHelp The items of the help interface prompt
@return The SetGlobalProperties RPC
*/
-- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp;
+- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp __deprecated_msg("Use initWithHelpText:timeoutText:vrHelpTitle:vrHelp:menuTitle:menuIcon:keyboardProperties:menuLayout: instead");
/**
Initialize SetGlobalProperties with all possible items
@@ -52,7 +54,22 @@ NS_ASSUME_NONNULL_BEGIN
@param keyboardProperties The properties of a keyboard prompt
@return The SetGlobalProperties RPC
*/
-- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp menuTitle:(nullable NSString *)menuTitle menuIcon:(nullable SDLImage *)menuIcon keyboardProperties:(nullable SDLKeyboardProperties *)keyboardProperties;
+- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp menuTitle:(nullable NSString *)menuTitle menuIcon:(nullable SDLImage *)menuIcon keyboardProperties:(nullable SDLKeyboardProperties *)keyboardProperties __deprecated_msg("Use initWithHelpText:timeoutText:vrHelpTitle:vrHelp:menuTitle:menuIcon:keyboardProperties:menuLayout: instead");
+
+/**
+ Initialize SetGlobalProperties with all possible items
+
+ @param helpText A string that will be turned into TTS chunks for the help prompt
+ @param timeoutText A string that will be turned into TTS chunks for the timeout prompt
+ @param vrHelpTitle The title of the help interface prompt
+ @param vrHelp The items of the help interface prompt
+ @param menuTitle The title of the menu button
+ @param menuIcon The icon on the menu button
+ @param keyboardProperties The properties of a keyboard prompt
+ @param menuLayout The layout of the top-level main menu
+ @return The SetGlobalProperties RPC
+ */
+- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp menuTitle:(nullable NSString *)menuTitle menuIcon:(nullable SDLImage *)menuIcon keyboardProperties:(nullable SDLKeyboardProperties *)keyboardProperties menuLayout:(nullable SDLMenuLayout)menuLayout;
/**
Help prompt for when the user asks for help with an interface prompt
@@ -112,6 +129,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (strong, nonatomic, nullable) SDLSeatLocation *userLocation;
+/**
+ The main menu layout. If this is sent while a menu is already on-screen, the head unit will change the display to the new layout type. See available menu layouts on DisplayCapabilities.menuLayoutsAvailable. Defaults to the head unit default.
+ */
+@property (strong, nonatomic, nullable) SDLMenuLayout menuLayout;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLSetGlobalProperties.m b/SmartDeviceLink/SDLSetGlobalProperties.m
index 6dc337505..b502fcfd1 100644
--- a/SmartDeviceLink/SDLSetGlobalProperties.m
+++ b/SmartDeviceLink/SDLSetGlobalProperties.m
@@ -27,14 +27,18 @@ NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic pop
- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText {
- return [self initWithHelpText:helpText timeoutText:timeoutText vrHelpTitle:nil vrHelp:nil];
+ return [self initWithHelpText:helpText timeoutText:timeoutText vrHelpTitle:nil vrHelp:nil menuTitle:nil menuIcon:nil keyboardProperties:nil menuLayout:nil];
}
- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp {
- return [self initWithHelpText:helpText timeoutText:timeoutText vrHelpTitle:vrHelpTitle vrHelp:vrHelp menuTitle:nil menuIcon:nil keyboardProperties:nil];
+ return [self initWithHelpText:helpText timeoutText:timeoutText vrHelpTitle:vrHelpTitle vrHelp:vrHelp menuTitle:nil menuIcon:nil keyboardProperties:nil menuLayout:nil];
}
- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp menuTitle:(nullable NSString *)menuTitle menuIcon:(nullable SDLImage *)menuIcon keyboardProperties:(nullable SDLKeyboardProperties *)keyboardProperties {
+ return [self initWithHelpText:helpText timeoutText:timeoutText vrHelpTitle:vrHelpTitle vrHelp:vrHelp menuTitle:menuTitle menuIcon:menuIcon keyboardProperties:keyboardProperties menuLayout:nil];
+}
+
+- (instancetype)initWithHelpText:(nullable NSString *)helpText timeoutText:(nullable NSString *)timeoutText vrHelpTitle:(nullable NSString *)vrHelpTitle vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp menuTitle:(nullable NSString *)menuTitle menuIcon:(nullable SDLImage *)menuIcon keyboardProperties:(nullable SDLKeyboardProperties *)keyboardProperties menuLayout:(nullable SDLMenuLayout)menuLayout {
self = [self init];
if (!self) {
return nil;
@@ -47,6 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
self.menuTitle = menuTitle;
self.menuIcon = menuIcon;
self.keyboardProperties = keyboardProperties;
+ self.menuLayout = menuLayout;
return self;
}
@@ -115,6 +120,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_objectForName:SDLRPCParameterNameUserLocation ofClass:SDLSeatLocation.class error:nil];
}
+- (void)setMenuLayout:(nullable SDLMenuLayout)menuLayout {
+ [self.parameters sdl_setObject:menuLayout forName:SDLRPCParameterNameMenuLayout];
+}
+
+- (nullable SDLMenuLayout)menuLayout {
+ return [self.parameters sdl_enumForName:SDLRPCParameterNameMenuLayout error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLWindowCapability.h b/SmartDeviceLink/SDLWindowCapability.h
index b569f0020..a68eb0127 100644
--- a/SmartDeviceLink/SDLWindowCapability.h
+++ b/SmartDeviceLink/SDLWindowCapability.h
@@ -4,6 +4,7 @@
#import "SDLRPCStruct.h"
#import "SDLImageType.h"
+#import "SDLMenuLayout.h"
@class SDLTextField;
@class SDLImageField;
@@ -76,6 +77,13 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nullable, strong, nonatomic) NSArray<SDLSoftButtonCapabilities *> *softButtonCapabilities;
+/**
+ An array of available menu layouts. If this parameter is not provided, only the `LIST` layout is assumed to be available.
+
+ Optional, array of 1 to 100, see SDLMenuLayout
+ */
+@property (nullable, strong, nonatomic) NSArray<SDLMenuLayout> *menuLayoutsAvailable;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLWindowCapability.m b/SmartDeviceLink/SDLWindowCapability.m
index 6ace664b6..509e2aa96 100644
--- a/SmartDeviceLink/SDLWindowCapability.m
+++ b/SmartDeviceLink/SDLWindowCapability.m
@@ -78,4 +78,12 @@
return [self.store sdl_objectsForName:SDLRPCParameterNameSoftButtonCapabilities ofClass:SDLSoftButtonCapabilities.class error:nil];
}
+- (void)setMenuLayoutsAvailable:(nullable NSArray<SDLMenuLayout> *)menuLayoutsAvailable {
+ [self.store sdl_setObject:menuLayoutsAvailable forName:SDLRPCParameterNameMenuLayoutsAvailable];
+}
+
+- (nullable NSArray<SDLMenuLayout> *)menuLayoutsAvailable {
+ return [self.store sdl_enumsForName:SDLRPCParameterNameMenuLayoutsAvailable error:nil];
+}
+
@end
diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h
index 8292e5624..efa4f8b2d 100644
--- a/SmartDeviceLink/SmartDeviceLink.h
+++ b/SmartDeviceLink/SmartDeviceLink.h
@@ -335,6 +335,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLMassageZone.h"
#import "SDLMediaClockFormat.h"
#import "SDLMediaType.h"
+#import "SDLMenuLayout.h"
#import "SDLMenuManagerConstants.h"
#import "SDLMetadataType.h"
#import "SDLModuleType.h"
@@ -437,6 +438,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLSoftButtonState.h"
#import "SDLMenuCell.h"
+#import "SDLMenuConfiguration.h"
#import "SDLVoiceCommand.h"
#import "SDLChoiceCell.h"
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m
index ee6f61278..ab8b281fd 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m
@@ -9,6 +9,7 @@ QuickSpecBegin(SDLMenuCellSpec)
describe(@"a menu cell", ^{
__block SDLMenuCell *testCell = nil;
__block SDLMenuCell *testCell2 = nil;
+ __block SDLMenuLayout testLayout = SDLMenuLayoutList;
describe(@"initializing", ^{
__block NSString *someTitle = nil;
@@ -43,29 +44,44 @@ describe(@"a menu cell", ^{
expect(testCell.icon).to(beNil());
expect(testCell.voiceCommands).to(beNil());
expect(testCell.subCells).to(equal(someSubcells));
+ expect(testCell.submenuLayout).to(beNil());
#pragma clang diagnostic pop
});
it(@"should initialize properly as a submenu item with icon", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testCell = [[SDLMenuCell alloc] initWithTitle:someTitle icon:someArtwork subCells:someSubcells];
expect(testCell.title).to(equal(someTitle));
expect(testCell.icon).to(equal(someArtwork));
expect(testCell.voiceCommands).to(beNil());
expect(testCell.subCells).to(equal(someSubcells));
+ expect(testCell.submenuLayout).to(beNil());
+#pragma clang diagnostic pop
+ });
+
+ it(@"should initialize properly as a submenu item with icon and layout", ^{
+ testCell = [[SDLMenuCell alloc] initWithTitle:someTitle icon:someArtwork submenuLayout:testLayout subCells:someSubcells];
+
+ expect(testCell.title).to(equal(someTitle));
+ expect(testCell.icon).to(equal(someArtwork));
+ expect(testCell.voiceCommands).to(beNil());
+ expect(testCell.subCells).to(equal(someSubcells));
+ expect(testCell.submenuLayout).to(equal(testLayout));
});
});
describe(@"check cell eqality", ^{
it(@"should compare cells and return true if cells equal", ^{
- testCell = [[SDLMenuCell alloc] initWithTitle:@"Title" icon:nil subCells:@[]];
- testCell2 = [[SDLMenuCell alloc] initWithTitle:@"Title" icon:nil subCells:@[]];
+ testCell = [[SDLMenuCell alloc] initWithTitle:@"Title" icon:nil submenuLayout:testLayout subCells:@[]];
+ testCell2 = [[SDLMenuCell alloc] initWithTitle:@"Title" icon:nil submenuLayout:testLayout subCells:@[]];
expect([testCell isEqual:testCell2]).to(equal(true));
});
it(@"should compare cells and return false if not equal ", ^{
- testCell = [[SDLMenuCell alloc] initWithTitle:@"True" icon:nil subCells:@[]];
- testCell2 = [[SDLMenuCell alloc] initWithTitle:@"False" icon:nil subCells:@[]];
+ testCell = [[SDLMenuCell alloc] initWithTitle:@"True" icon:nil submenuLayout:testLayout subCells:@[]];
+ testCell2 = [[SDLMenuCell alloc] initWithTitle:@"False" icon:nil submenuLayout:testLayout subCells:@[]];
expect([testCell isEqual:testCell2]).to(equal(false));
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuConfigurationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuConfigurationSpec.m
new file mode 100644
index 000000000..3c8f5190c
--- /dev/null
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuConfigurationSpec.m
@@ -0,0 +1,28 @@
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLMenuConfiguration.h"
+
+QuickSpecBegin(SDLMenuConfigurationSpec)
+
+describe(@"a menu configuration", ^{
+ __block SDLMenuConfiguration *testConfiguration = nil;
+
+ describe(@"initializing", ^{
+ it(@"should initialize properly with no variables", ^{
+ testConfiguration = [[SDLMenuConfiguration alloc] init];
+
+ expect(testConfiguration.mainMenuLayout).to(equal(SDLMenuLayoutList));
+ expect(testConfiguration.defaultSubmenuLayout).to(equal(SDLMenuLayoutList));
+ });
+
+ it(@"should initialize properly when set", ^{
+ testConfiguration = [[SDLMenuConfiguration alloc] initWithMainMenuLayout:SDLMenuLayoutTiles defaultSubmenuLayout:SDLMenuLayoutTiles];
+
+ expect(testConfiguration.mainMenuLayout).to(equal(SDLMenuLayoutTiles));
+ expect(testConfiguration.defaultSubmenuLayout).to(equal(SDLMenuLayoutTiles));
+ });
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
index 29ed043c3..815105331 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
@@ -52,16 +52,20 @@ describe(@"menu manager", ^{
__block SDLMenuCell *submenuCell = nil;
__block SDLMenuCell *submenuImageCell = nil;
+ __block SDLMenuConfiguration *testMenuConfiguration = nil;
+
beforeEach(^{
testArtwork = [[SDLArtwork alloc] initWithData:[@"Test data" dataUsingEncoding:NSUTF8StringEncoding] name:@"some artwork name" fileExtension:@"png" persistent:NO];
testArtwork2 = [[SDLArtwork alloc] initWithData:[@"Test data 2" dataUsingEncoding:NSUTF8StringEncoding] name:@"some artwork name 2" fileExtension:@"png" persistent:NO];
textOnlyCell = [[SDLMenuCell alloc] initWithTitle:@"Test 1" icon:nil voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
textAndImageCell = [[SDLMenuCell alloc] initWithTitle:@"Test 2" icon:testArtwork voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
- submenuCell = [[SDLMenuCell alloc] initWithTitle:@"Test 3" icon:nil subCells:@[textOnlyCell, textAndImageCell]];
- submenuImageCell = [[SDLMenuCell alloc] initWithTitle:@"Test 4" icon:testArtwork2 subCells:@[textOnlyCell]];
+ submenuCell = [[SDLMenuCell alloc] initWithTitle:@"Test 3" icon:nil submenuLayout:nil subCells:@[textOnlyCell, textAndImageCell]];
+ submenuImageCell = [[SDLMenuCell alloc] initWithTitle:@"Test 4" icon:testArtwork2 submenuLayout:SDLMenuLayoutTiles subCells:@[textOnlyCell]];
textOnlyCell2 = [[SDLMenuCell alloc] initWithTitle:@"Test 5" icon:nil voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
+ testMenuConfiguration = [[SDLMenuConfiguration alloc] initWithMainMenuLayout:SDLMenuLayoutTiles defaultSubmenuLayout:SDLMenuLayoutList];
+
mockConnectionManager = [[TestConnectionManager alloc] init];
mockFileManager = OCMClassMock([SDLFileManager class]);
@@ -74,6 +78,7 @@ describe(@"menu manager", ^{
windowCapability.windowID = @(SDLPredefinedWindowsDefaultWindow);
windowCapability.imageFields = @[commandIconField];
windowCapability.imageTypeSupported = @[SDLImageTypeDynamic, SDLImageTypeStatic];
+ windowCapability.menuLayoutsAvailable = @[SDLMenuLayoutList, SDLMenuLayoutTiles];
SDLDisplayCapability *displayCapability = [[SDLDisplayCapability alloc] initWithDisplayName:SDLDisplayTypeGeneric];
displayCapability.windowCapabilities = @[windowCapability];
@@ -94,6 +99,7 @@ describe(@"menu manager", ^{
expect(testManager.lastMenuId).to(equal(1));
expect(testManager.oldMenuCells).to(beEmpty());
expect(testManager.waitingUpdateMenuCells).to(beNil());
+ expect(testManager.menuConfiguration).toNot(beNil());
});
describe(@"updating menu cells before HMI is ready", ^{
@@ -126,38 +132,31 @@ describe(@"menu manager", ^{
context(@"when no HMI level has been received", ^{
beforeEach(^{
testManager.currentHMILevel = nil;
- testManager.menuCells = @[textOnlyCell];
});
- it(@"should not update", ^{
+ it(@"should not update the menu configuration", ^{
+ testManager.menuConfiguration = testMenuConfiguration;
+ expect(mockConnectionManager.receivedRequests).to(beEmpty());
+ expect(testManager.menuConfiguration).toNot(equal(testMenuConfiguration));
+ });
+
+ it(@"should not update the menu cells", ^{
+ testManager.menuCells = @[textOnlyCell];
expect(mockConnectionManager.receivedRequests).to(beEmpty());
});
});
context(@"when in the menu", ^{
beforeEach(^{
+ [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithString:@"6.0.0"];
testManager.currentHMILevel = SDLHMILevelFull;
testManager.currentSystemContext = SDLSystemContextMenu;
- testManager.menuCells = @[textOnlyCell];
- });
-
- it(@"should not update", ^{
- expect(mockConnectionManager.receivedRequests).to(beEmpty());
});
- describe(@"when exiting the menu", ^{
- beforeEach(^{
- SDLOnHMIStatus *onHMIStatus = [[SDLOnHMIStatus alloc] init];
- onHMIStatus.hmiLevel = SDLHMILevelFull;
- onHMIStatus.systemContext = SDLSystemContextMain;
-
- SDLRPCNotificationNotification *testSystemContextNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:nil rpcNotification:onHMIStatus];
- [[NSNotificationCenter defaultCenter] postNotification:testSystemContextNotification];
- });
-
- it(@"should update", ^{
- expect(mockConnectionManager.receivedRequests).toNot(beEmpty());
- });
+ fit(@"should update the menu configuration", ^{
+ testManager.menuConfiguration = testMenuConfiguration;
+ expect(mockConnectionManager.receivedRequests).toNot(beEmpty());
+ expect(testManager.menuConfiguration).to(equal(testMenuConfiguration));
});
});
});
@@ -544,7 +543,7 @@ describe(@"menu manager", ^{
testTriggerSource = triggerSource;
}];
- SDLMenuCell *submenuCell = [[SDLMenuCell alloc] initWithTitle:@"Submenu" icon:nil subCells:@[cellWithHandler]];
+ SDLMenuCell *submenuCell = [[SDLMenuCell alloc] initWithTitle:@"Submenu" icon:nil submenuLayout:SDLMenuLayoutTiles subCells:@[cellWithHandler]];
testManager.menuCells = @[submenuCell];
});
@@ -563,7 +562,46 @@ describe(@"menu manager", ^{
});
});
- context(@"On disconnects", ^{
+ describe(@"updating the menu configuration", ^{
+ beforeEach(^{
+ testManager.currentHMILevel = SDLHMILevelFull;
+ testManager.currentSystemContext = SDLSystemContextMain;
+ });
+
+ context(@"if the connection RPC version is less than 6.0.0", ^{
+ beforeEach(^{
+ [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithString:@"5.0.0"];
+ });
+
+ it(@"should fail to send a SetGlobalProperties RPC update", ^{
+ testManager.menuConfiguration = testMenuConfiguration;
+
+ expect(testManager.menuConfiguration).toNot(equal(testMenuConfiguration));
+ expect(mockConnectionManager.receivedRequests).to(haveCount(0));
+ });
+ });
+
+ context(@"if the connection RPC version is greater than or equal to 6.0.0", ^{
+ beforeEach(^{
+ [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithString:@"6.0.0"];
+ });
+
+ it(@"should send a SetGlobalProperties RPC update", ^{
+ testManager.menuConfiguration = testMenuConfiguration;
+
+ expect(testManager.menuConfiguration).to(equal(testMenuConfiguration));
+ expect(mockConnectionManager.receivedRequests).to(haveCount(1));
+
+ SDLSetGlobalPropertiesResponse *response = [[SDLSetGlobalPropertiesResponse alloc] init];
+ response.success = @YES;
+ [mockConnectionManager respondToLastRequestWithResponse:response];
+
+ expect(testManager.menuConfiguration).to(equal(testMenuConfiguration));
+ });
+ });
+ });
+
+ context(@"when the manager stops", ^{
beforeEach(^{
[testManager stop];
});
@@ -580,6 +618,7 @@ describe(@"menu manager", ^{
expect(testManager.lastMenuId).to(equal(1));
expect(testManager.oldMenuCells).to(beEmpty());
expect(testManager.waitingUpdateMenuCells).to(beEmpty());
+ expect(testManager.menuConfiguration).toNot(beNil());
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLMenuLayoutSpec.m b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLMenuLayoutSpec.m
new file mode 100644
index 000000000..ce2b079a6
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLMenuLayoutSpec.m
@@ -0,0 +1,15 @@
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLMenuLayout.h"
+
+QuickSpecBegin(SDLMenuLayoutSpec)
+
+describe(@"Individual Enum Value Tests", ^{
+ it(@"Should match internal values", ^{
+ expect(SDLMenuLayoutList).to(equal(@"LIST"));
+ expect(SDLMenuLayoutTiles).to(equal(@"TILES"));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAddSubMenuSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAddSubMenuSpec.m
index 2efd1eee2..5c5e98547 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAddSubMenuSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAddSubMenuSpec.m
@@ -20,6 +20,7 @@ describe(@"Getter/Setter Tests", ^ {
__block UInt8 position = 27;
__block NSString *menuName = @"Welcome to the menu";
__block SDLImage *image = nil;
+ __block SDLMenuLayout testLayout = SDLMenuLayoutList;
beforeEach(^{
image = [[SDLImage alloc] initWithName:@"Test" isTemplate:false];
@@ -47,12 +48,25 @@ describe(@"Getter/Setter Tests", ^ {
});
it(@"should correctly initialize with initWithId:menuName:menuIcon:position:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLAddSubMenu *testRequest = [[SDLAddSubMenu alloc] initWithId:menuId menuName:menuName menuIcon:image position:position];
expect(testRequest.menuID).to(equal(@(menuId)));
expect(testRequest.position).to(equal(@(position)));
expect(testRequest.menuName).to(equal(menuName));
expect(testRequest.menuIcon).to(equal(image));
+#pragma clang diagnostic pop
+ });
+
+ it(@"should correctly initialize with initWithId:menuName:menuLayout:menuIcon:position:", ^{
+ SDLAddSubMenu *testRequest = [[SDLAddSubMenu alloc] initWithId:menuId menuName:menuName menuLayout:testLayout menuIcon:image position:position];
+
+ expect(testRequest.menuID).to(equal(@(menuId)));
+ expect(testRequest.position).to(equal(@(position)));
+ expect(testRequest.menuName).to(equal(menuName));
+ expect(testRequest.menuIcon).to(equal(image));
+ expect(testRequest.menuLayout).to(equal(testLayout));
});
it(@"Should set and get correctly", ^ {
@@ -62,11 +76,13 @@ describe(@"Getter/Setter Tests", ^ {
testRequest.position = @27;
testRequest.menuName = @"Welcome to the menu";
testRequest.menuIcon = image;
+ testRequest.menuLayout = testLayout;
expect(testRequest.menuID).to(equal(@(menuId)));
expect(testRequest.position).to(equal(@(position)));
expect(testRequest.menuName).to(equal(menuName));
expect(testRequest.menuIcon).to(equal(image));
+ expect(testRequest.menuLayout).to(equal(testLayout));
});
it(@"Should get correctly when initialized", ^ {
@@ -77,7 +93,8 @@ describe(@"Getter/Setter Tests", ^ {
SDLRPCParameterNameMenuName:@"Welcome to the menu",
SDLRPCParameterNameMenuIcon: @{
SDLRPCParameterNameValue: @"Test"
- }
+ },
+ SDLRPCParameterNameMenuLayout: testLayout
},
SDLRPCParameterNameOperationName:SDLRPCFunctionNameAddSubMenu}} mutableCopy];
#pragma clang diagnostic push
@@ -89,6 +106,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testRequest.position).to(equal(@(position)));
expect(testRequest.menuName).to(equal(menuName));
expect(testRequest.menuIcon.value).to(equal(@"Test"));
+ expect(testRequest.menuLayout).to(equal(testLayout));
});
it(@"Should return nil if not set", ^ {
@@ -98,6 +116,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testRequest.position).to(beNil());
expect(testRequest.menuName).to(beNil());
expect(testRequest.menuIcon).to(beNil());
+ expect(testRequest.menuLayout).to(beNil());
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitiesSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitiesSpec.m
index ab19ae425..6e89c7461 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitiesSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitiesSpec.m
@@ -39,7 +39,7 @@ describe(@"Getter/Setter Tests", ^ {
testStruct.templatesAvailable = [@[@"String", @"String", @"String"] mutableCopy];
testStruct.screenParams = screenParams;
testStruct.numCustomPresetsAvailable = @43;
-
+
expect(testStruct.displayType).to(equal(SDLDisplayTypeGen26DMA));
expect(testStruct.displayName).to(equal(@"test"));
expect(testStruct.textFields).to(equal([@[textField] mutableCopy]));
@@ -52,7 +52,7 @@ describe(@"Getter/Setter Tests", ^ {
});
it(@"Should get correctly when initialized", ^ {
- NSMutableDictionary* dict = [@{SDLRPCParameterNameDisplayType:SDLDisplayTypeGen26DMA,
+ NSMutableDictionary* dict = @{SDLRPCParameterNameDisplayType:SDLDisplayTypeGen26DMA,
SDLRPCParameterNameDisplayName: @"test",
SDLRPCParameterNameTextFields:[@[textField] mutableCopy],
SDLRPCParameterNameImageFields:[@[imageField] mutableCopy],
@@ -60,7 +60,8 @@ describe(@"Getter/Setter Tests", ^ {
SDLRPCParameterNameGraphicSupported:@YES,
SDLRPCParameterNameTemplatesAvailable:[@[@"String", @"String", @"String"] mutableCopy],
SDLRPCParameterNameScreenParams:screenParams,
- SDLRPCParameterNameNumberCustomPresetsAvailable:@43} mutableCopy];
+ SDLRPCParameterNameNumberCustomPresetsAvailable:@43,
+ };
SDLDisplayCapabilities* testStruct = [[SDLDisplayCapabilities alloc] initWithDictionary:dict];
expect(testStruct.displayType).to(equal(SDLDisplayTypeGen26DMA));
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitySpec.m
index 4cd68a799..1d0aad819 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitySpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLDisplayCapabilitySpec.m
@@ -63,7 +63,6 @@ describe(@"Getter/Setter Tests", ^ {
testWindowCapability.imageTypeSupported = @[testImageType];
testWindowCapability.buttonCapabilities = @[testButtonCapabilities];
testWindowCapability.softButtonCapabilities = @[testSoftButtonscapabilities];
-
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWindowCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWindowCapabilitySpec.m
index 0589337ce..94eecde90 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWindowCapabilitySpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWindowCapabilitySpec.m
@@ -17,7 +17,6 @@
QuickSpecBegin(SDLWindowCapabilitySpec)
describe(@"Getter/Setter Tests", ^ {
-
__block SDLTextField* testTextField = nil;
__block SDLImageField *testImageField = nil;
__block SDLButtonCapabilities *testButtonCapabilities = nil;
@@ -55,6 +54,7 @@ describe(@"Getter/Setter Tests", ^ {
testStruct.imageTypeSupported = @[testImageType];
testStruct.buttonCapabilities = @[testButtonCapabilities];
testStruct.softButtonCapabilities = @[testSoftButtonscapabilities];
+ testStruct.menuLayoutsAvailable = @[SDLMenuLayoutTiles];
expect(testStruct.windowID).to(equal(@444));
expect(testStruct.textFields.firstObject.name).to(equal(SDLTextFieldNameTertiaryText));
@@ -65,6 +65,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testStruct.buttonCapabilities.firstObject.longPressAvailable).to(equal(@YES));
expect(testStruct.buttonCapabilities.firstObject.name).to(equal(SDLButtonNameOk));
expect(testStruct.softButtonCapabilities.firstObject.imageSupported).to(equal(@YES));
+ expect(testStruct.menuLayoutsAvailable).to(equal(@[SDLMenuLayoutTiles]));
});
});