diff --git a/ui/drivers/cocoa/cocoatouch_browser.m b/ui/drivers/cocoa/cocoatouch_browser.m index 5eebd6e8b6..794a8388bf 100644 --- a/ui/drivers/cocoa/cocoatouch_browser.m +++ b/ui/drivers/cocoa/cocoatouch_browser.m @@ -165,6 +165,78 @@ static void file_action(enum file_action action, NSString* source, NSString* tar @end +/*********************************************/ +/* RAMenuItemBasic */ +/* A simple menu item that displays a text */ +/* description and calls a block object when */ +/* selected. */ +/*********************************************/ +@interface RAMenuItemBasic : NSObject +@property (nonatomic) NSString* description; +@property (nonatomic) id userdata; +@property (copy) void (^action)(id userdata); +@property (copy) NSString* (^detail)(id userdata); + ++ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action; ++ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action detail:(NSString* (^)())detail; ++ (RAMenuItemBasic*)itemWithDescription:(NSString*)description association:(id)userdata action:(void (^)())action detail:(NSString* (^)())detail; + +@end + +/*********************************************/ +/* RAMenuItemBasic */ +/* A simple menu item that displays a text */ +/* description and calls a block object when */ +/* selected. */ +/*********************************************/ +@implementation RAMenuItemBasic +@synthesize description; +@synthesize userdata; +@synthesize action; +@synthesize detail; + ++ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action +{ + return [self itemWithDescription:description action:action detail:Nil]; +} + ++ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action detail:(NSString* (^)())detail +{ + return [self itemWithDescription:description association:nil action:action detail:detail]; +} + ++ (RAMenuItemBasic*)itemWithDescription:(NSString*)description association:(id)userdata action:(void (^)())action detail:(NSString* (^)())detail +{ + RAMenuItemBasic* item = [RAMenuItemBasic new]; + item.description = description; + item.userdata = userdata; + item.action = action; + item.detail = detail; + return item; +} + +- (UITableViewCell*)cellForTableView:(UITableView*)tableView +{ + static NSString* const cell_id = @"text"; + + UITableViewCell* result = [tableView dequeueReusableCellWithIdentifier:cell_id]; + if (!result) + result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cell_id]; + + result.selectionStyle = UITableViewCellSelectionStyleNone; + result.textLabel.text = self.description; + result.detailTextLabel.text = self.detail ? self.detail(self.userdata) : nil; + return result; +} + +- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller +{ + if (self.action) + self.action(self.userdata); +} + +@end + @implementation RADirectoryList - (id)initWithPath:(NSString*)path extensions:(const char*)extensions diff --git a/ui/drivers/cocoa/cocoatouch_menu.m b/ui/drivers/cocoa/cocoatouch_menu.m index d313498ce7..b433a1a5c3 100644 --- a/ui/drivers/cocoa/cocoatouch_menu.m +++ b/ui/drivers/cocoa/cocoatouch_menu.m @@ -31,162 +31,10 @@ #include "../../../menu/menu_setting.h" #include "../../../menu/drivers/shared.h" -@protocol RAMenuItemBase -- (UITableViewCell*)cellForTableView:(UITableView*)tableView; -- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller; -@end +#include "cocoatouch_support.c" -/*********************************************/ -/* RAMenuItemBasic */ -/* A simple menu item that displays a text */ -/* description and calls a block object when */ -/* selected. */ -/*********************************************/ -@interface RAMenuItemBasic : NSObject -@property (nonatomic) NSString* description; -@property (nonatomic) id userdata; -@property (copy) void (^action)(id userdata); -@property (copy) NSString* (^detail)(id userdata); +// Menu Support -+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action; -+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action detail:(NSString* (^)())detail; -+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description association:(id)userdata action:(void (^)())action detail:(NSString* (^)())detail; - -@end - -/*********************************************/ -/* RAMenuItemGeneralSetting */ -/* A simple menu item that displays the */ -/* state, and allows editing, of a string or */ -/* numeric setting. */ -/*********************************************/ -@interface RAMenuItemGeneralSetting : NSObject -@property (nonatomic) rarch_setting_t* setting; -@property (copy) void (^action)(); -@property (nonatomic, weak) UITableView* parentTable; -- (id)initWithSetting:(rarch_setting_t*)setting action:(void (^)())action; -@end - -/*********************************************/ -/* RAMenuItemBooleanSetting */ -/* A simple menu item that displays the */ -/* state, and allows editing, of a boolean */ -/* setting. */ -/*********************************************/ -@interface RAMenuItemBooleanSetting : NSObject -@property (nonatomic) rarch_setting_t* setting; -@property (copy) void (^action)(); -- (id)initWithSetting:(rarch_setting_t*)setting action:(void (^)())action; -@end - -/*********************************************/ -/* RAMenuItemPathSetting */ -/* A menu item that displays and allows */ -/* browsing for a path setting. */ -/*********************************************/ -@interface RAMenuItemPathSetting : RAMenuItemGeneralSetting @end - -/*********************************************/ -/* RAMenuItemEnumSetting */ -/* A menu item that displays and allows */ -/* a setting to be set from a list of */ -/* allowed choices. */ -/*********************************************/ -@interface RAMenuItemEnumSetting : RAMenuItemGeneralSetting @end - -/*********************************************/ -/* RAMenuItemBindSetting */ -/* A menu item that displays and allows */ -/* mapping of a keybinding. */ -/*********************************************/ -@interface RAMenuItemBindSetting : RAMenuItemGeneralSetting @end - -/*********************************************/ -/* RAMainMenu */ -/* Menu object that is displayed immediately */ -/* after startup. */ -/*********************************************/ -@interface RAMainMenu : RAMenuBase -@property (nonatomic) NSString* core; -@end - -@interface RADirectoryItem : NSObject -@property (nonatomic) NSString* path; -@property (nonatomic) bool isDirectory; -@end - -@interface RADirectoryList : RAMenuBase -@property (nonatomic, weak) RADirectoryItem* selectedItem; - -@property (nonatomic, copy) void (^chooseAction)(RADirectoryList* list, RADirectoryItem* item); -@property (nonatomic, copy) NSString* path; -@property (nonatomic, copy) NSString* extensions; - -@property (nonatomic) bool allowBlank; -@property (nonatomic) bool forDirectory; - -- (id)initWithPath:(NSString*)path extensions:(const char*)extensions action:(void (^)(RADirectoryList* list, RADirectoryItem* item))action; -- (void)browseTo:(NSString*)path; -@end - -@interface RANumberFormatter : NSNumberFormatter - -- (id)initWithSetting:(const rarch_setting_t*)setting; -@end - -// Number formatter class for setting strings -@implementation RANumberFormatter -- (id)initWithSetting:(const rarch_setting_t*)setting -{ - if ((self = [super init])) - { - [self setAllowsFloats:(setting->type == ST_FLOAT)]; - - if (setting->flags & SD_FLAG_HAS_RANGE) - { - [self setMinimum:BOXFLOAT(setting->min)]; - [self setMaximum:BOXFLOAT(setting->max)]; - } - } - - return self; -} - -- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:(NSString**)newString errorDescription:(NSString**)error -{ - unsigned i; - bool hasDot = false; - - if (partialString.length) - for (i = 0; i < partialString.length; i ++) - { - unichar ch = [partialString characterAtIndex:i]; - - if (i == 0 && (!self.minimum || self.minimum.intValue < 0) && ch == '-') - continue; - else if (self.allowsFloats && !hasDot && ch == '.') - hasDot = true; - else if (!isdigit(ch)) - return NO; - } - - return YES; -} - -- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string -{ - NSString* text = (NSString*)[[textField text] stringByReplacingCharactersInRange:range withString:string]; - return [self isPartialStringValid:text newEditingString:nil errorDescription:nil]; -} - -@end - -/*********************************************/ -/* RunActionSheet */ -/* Creates and displays a UIActionSheet with */ -/* buttons pulled from a RetroArch */ -/* string_list structure. */ -/*********************************************/ static const void* const associated_delegate_key = &associated_delegate_key; typedef void (^RAActionSheetCallback)(UIActionSheet*, NSInteger); @@ -212,10 +60,12 @@ typedef void (^RAActionSheetCallback)(UIActionSheet*, NSInteger); @end -static void RunActionSheet(const char* title, const struct string_list* items, UIView* parent, RAActionSheetCallback callback) +static void RunActionSheet(const char* title, const struct string_list* items, + UIView* parent, RAActionSheetCallback callback) { size_t i; - RARunActionSheetDelegate* delegate = [[RARunActionSheetDelegate alloc] initWithCallbackBlock:callback]; + RARunActionSheetDelegate* delegate = + [[RARunActionSheetDelegate alloc] initWithCallbackBlock:callback]; UIActionSheet* actionSheet = [UIActionSheet new]; actionSheet.title = BOXSTRING(title); @@ -226,200 +76,386 @@ static void RunActionSheet(const char* title, const struct string_list* items, U actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:BOXSTRING("Cancel")]; - objc_setAssociatedObject(actionSheet, associated_delegate_key, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(actionSheet, associated_delegate_key, + delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [actionSheet showInView:parent]; } +// Menu Entries -/*********************************************/ -/* RAMenuBase */ -/* A menu class that displays RAMenuItemBase */ -/* objects. */ -/*********************************************/ -@implementation RAMenuBase - -- (id)initWithStyle:(UITableViewStyle)style -{ - if ((self = [super initWithStyle:style])) - _sections = [NSMutableArray array]; - return self; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView -{ - return self.sections.count; -} - -- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section -{ - if (self.hidesHeaders) - return nil; - return self.sections[section][0]; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [self.sections[section] count] - 1; -} - -- (id)itemForIndexPath:(NSIndexPath*)indexPath -{ - return self.sections[indexPath.section][indexPath.row + 1]; -} - -- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - return [[self itemForIndexPath:indexPath] cellForTableView:tableView]; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [[self itemForIndexPath:indexPath] wasSelectedOnTableView:tableView ofController:self]; -} - -- (void)willReloadData -{ - -} - -- (void)reloadData -{ - [self willReloadData]; - [[self tableView] reloadData]; -} - +@protocol RAMenuActioner +- (void)menuSelect:(uint32_t) i; @end -/*********************************************/ -/* RAMenuItemBasic */ -/* A simple menu item that displays a text */ -/* description and calls a block object when */ -/* selected. */ -/*********************************************/ -@implementation RAMenuItemBasic -@synthesize description; -@synthesize userdata; -@synthesize action; -@synthesize detail; +@interface RAMenuItemBase : NSObject +@property (nonatomic) id main; +@property (nonatomic) uint32_t i; +@property (nonatomic, weak) UITableView* parentTable; +- (void)initialize:(NSObject *) main idx:(uint32_t) i; +- (UITableViewCell*)cellForTableView:(UITableView*)tableView; +- (void)wasSelectedOnTableView:(UITableView*)tableView + ofController:(UIViewController*)controller; +@end -+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action -{ - return [self itemWithDescription:description action:action detail:Nil]; -} - -+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action detail:(NSString* (^)())detail -{ - return [self itemWithDescription:description association:nil action:action detail:detail]; -} - -+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description association:(id)userdata action:(void (^)())action detail:(NSString* (^)())detail -{ - RAMenuItemBasic* item = [RAMenuItemBasic new]; - item.description = description; - item.userdata = userdata; - item.action = action; - item.detail = detail; - return item; +@implementation RAMenuItemBase +- (void)initialize:(NSObject*)main idx:(uint32_t) i { + _main = main; + _i = i; } - (UITableViewCell*)cellForTableView:(UITableView*)tableView { - static NSString* const cell_id = @"text"; - - UITableViewCell* result = [tableView dequeueReusableCellWithIdentifier:cell_id]; - if (!result) - result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cell_id]; - - result.selectionStyle = UITableViewCellSelectionStyleNone; - result.textLabel.text = self.description; - result.detailTextLabel.text = self.detail ? self.detail(self.userdata) : nil; - return result; + char buffer[PATH_MAX_LENGTH]; + static NSString* const cell_id = @"text"; + + self.parentTable = tableView; + + UITableViewCell* result = [tableView dequeueReusableCellWithIdentifier:cell_id]; + if (!result) + result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 + reuseIdentifier:cell_id]; + + result.selectionStyle = UITableViewCellSelectionStyleNone; + result.textLabel.text = BOXSTRING(get_menu_entry_label(self.i)); + menu_entry_value_get(self.i, buffer, sizeof(buffer)); + if (buffer[0] == '\0') + strlcpy(buffer, "", sizeof(buffer)); + result.detailTextLabel.text = BOXSTRING(buffer); + return result; } -- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller -{ - if (self.action) - self.action(self.userdata); +- (void)wasSelectedOnTableView:(UITableView*)tableView + ofController:(UIViewController*)controller { } @end -/*********************************************/ -/* RAMenuItemGeneralSetting */ -/* A simple menu item that displays the */ -/* state, and allows editing, of a string or */ -/* numeric setting. */ -/*********************************************/ -@interface RAMenuItemGeneralSetting() +@interface RAMenuItemBool : RAMenuItemBase +@end + +@implementation RAMenuItemBool + +- (UITableViewCell*)cellForTableView:(UITableView*)tableView +{ + static NSString* const cell_id = @"boolean_setting"; + + UITableViewCell* result = + (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:cell_id]; + + if (!result) + { + result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 + reuseIdentifier:cell_id]; + result.selectionStyle = UITableViewCellSelectionStyleNone; + result.accessoryView = [UISwitch new]; + } + + result.textLabel.text = BOXSTRING(get_menu_entry_label(self.i)); + [(id)result.accessoryView removeTarget:nil + action:NULL + forControlEvents:UIControlEventValueChanged]; + [(id)result.accessoryView addTarget:self + action:@selector(handleBooleanSwitch:) + forControlEvents:UIControlEventValueChanged]; + [(id)result.accessoryView setOn:(menu_entry_bool_value_get(self.i))]; + return result; +} + +- (void)handleBooleanSwitch:(UISwitch*)swt +{ + menu_entry_bool_value_set(self.i, swt.on ? true : false); + [self.main menuSelect: self.i]; +} + +- (void)wasSelectedOnTableView:(UITableView*)tableView + ofController:(UIViewController*)controller +{ +} +@end + +@interface RAMenuItemAction : RAMenuItemBase +@end + +@implementation RAMenuItemAction + +- (void)wasSelectedOnTableView:(UITableView*)tableView + ofController:(UIViewController*)controller +{ + [self.main menuSelect: self.i]; +} + +@end + +@interface RAMenuItemEnum : RAMenuItemBase +@end + +@implementation RAMenuItemEnum +- (void)wasSelectedOnTableView:(UITableView*)tableView + ofController:(UIViewController*)controller +{ + struct string_list* items; + RAMenuItemEnum __weak* weakSelf = self; + + items = menu_entry_enum_values(self.i); + RunActionSheet(get_menu_entry_label(self.i), items, self.parentTable, + ^(UIActionSheet* actionSheet, NSInteger buttonIndex) + { + if (buttonIndex == actionSheet.cancelButtonIndex) + return; + + menu_entry_enum_value_set_with_string + (self.i, [[actionSheet buttonTitleAtIndex:buttonIndex] UTF8String]); + [weakSelf.parentTable reloadData]; + }); + string_list_free(items); +} +@end + +@interface RAMenuItemBind : RAMenuItemBase +@property (nonatomic) NSTimer* bindTimer; +@property (nonatomic) UIAlertView* alert; +@end + +@implementation RAMenuItemBind + +- (void)wasSelectedOnTableView:(UITableView *)tableView + ofController:(UIViewController *)controller +{ + self.alert = [[UIAlertView alloc] + initWithTitle:BOXSTRING("RetroArch") + message:BOXSTRING(get_menu_entry_label(self.i)) + delegate:self + cancelButtonTitle:BOXSTRING("Cancel") + otherButtonTitles:BOXSTRING("Clear Keyboard"), + BOXSTRING("Clear Joystick"), BOXSTRING("Clear Axis"), nil]; + + [self.alert show]; + + [self.parentTable reloadData]; + + self.bindTimer = [NSTimer + scheduledTimerWithTimeInterval:.1f + target:self + selector:@selector(checkBind:) + userInfo:nil + repeats:YES]; +} + +- (void)finishWithClickedButton:(bool)clicked +{ + if (!clicked) + [self.alert dismissWithClickedButtonIndex:self.alert.cancelButtonIndex + animated:YES]; + self.alert = nil; + + [self.parentTable reloadData]; + + [self.bindTimer invalidate]; + self.bindTimer = nil; + + cocoa_input_reset_icade_buttons(); +} + +- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == alertView.firstOtherButtonIndex) { + menu_entry_bind_key_set(self.i, RETROK_UNKNOWN); + } else if(buttonIndex == alertView.firstOtherButtonIndex + 1) { + menu_entry_bind_joykey_set(self.i, NO_BTN); + } else if(buttonIndex == alertView.firstOtherButtonIndex + 2) { + menu_entry_bind_joyaxis_set(self.i, AXIS_NONE); + } + + [self finishWithClickedButton:true]; +} + +- (void)checkBind:(NSTimer*)send +{ + int32_t value = 0; + int32_t idx = menu_entry_bind_index(self.i); + + if ((value = cocoa_input_find_any_key())) { + menu_entry_bind_key_set(self.i, input_keymaps_translate_keysym_to_rk(value)); + } else if ((value = cocoa_input_find_any_button(idx)) >= 0) { + menu_entry_bind_joykey_set(self.i, value); + } else if ((value = cocoa_input_find_any_axis(idx))) { + menu_entry_bind_joyaxis_set(self.i, (value > 0) ? AXIS_POS(value - 1) : AXIS_NEG(abs(value) - 1)); + } else { + return; + } + + [self finishWithClickedButton:false]; +} +@end + +@interface RAMenuItemPathDir : RAMenuItemBase +@end + +@interface RADirectoryItem : NSObject +@property (nonatomic) NSString* path; +@property (nonatomic) bool isDirectory; +@end + +@interface RADirectoryList : RAMenuBase +@property (nonatomic, weak) RADirectoryItem* selectedItem; + +@property (nonatomic, copy) void (^chooseAction)(RADirectoryList* list, RADirectoryItem* item); +@property (nonatomic, copy) NSString* path; +@property (nonatomic, copy) NSString* extensions; + +@property (nonatomic) bool allowBlank; +@property (nonatomic) bool forDirectory; + +- (id)initWithPath:(NSString*)path extensions:(const char*)extensions action:(void (^)(RADirectoryList* list, RADirectoryItem* item))action; +- (void)browseTo:(NSString*)path; +@end + +@implementation RAMenuItemPathDir + +- (void)wasSelectedOnTableView:(UITableView*)tableView + ofController:(UIViewController*)controller +{ + NSString *path; + RADirectoryList* list; + RAMenuItemPathDir __weak* weakSelf = self; + + menu_entry_pathdir_selected(self.i); + + path = BOXSTRING(menu_entry_pathdir_value_get(self.i)); + + if ( get_menu_entry_type(self.i) == MENU_ENTRY_PATH ) + path = [path stringByDeletingLastPathComponent]; + + list = + [[RADirectoryList alloc] + initWithPath:path + extensions:menu_entry_pathdir_extensions(self.i) + action:^(RADirectoryList* list, RADirectoryItem* item) { + const char *newval = ""; + if (item) { + if (list.forDirectory && !item.isDirectory) + return; + + newval = [item.path UTF8String]; + } else { + if (!list.allowBlank) + return; + } + + menu_entry_pathdir_value_set(self.i, newval); + [[list navigationController] popViewControllerAnimated:YES]; + menu_select_entry(self.i); + [weakSelf.parentTable reloadData]; + }]; + + list.allowBlank = menu_entry_pathdir_allow_empty(self.i); + // JM: Is this just Dir vs Path? + list.forDirectory = menu_entry_pathdir_for_directory(self.i); + + [controller.navigationController pushViewController:list animated:YES]; +} + +@end + +@interface RAMenuItemPath : RAMenuItemPathDir +@end + +@implementation RAMenuItemPath +@end + +@interface RAMenuItemDir : RAMenuItemPathDir +@end + +@implementation RAMenuItemDir +@end + +@interface RANumberFormatter : NSNumberFormatter +- (void)setRangeFrom: (NSNumber*) min To: (NSNumber*) max; +@end + +@implementation RANumberFormatter +- (void)setRangeFrom: (NSNumber*) min To: (NSNumber*) max { + [self setMinimum: min]; + [self setMaximum: max]; +} + +- (BOOL)isPartialStringValid:(NSString*)partialString + newEditingString:(NSString**)newString + errorDescription:(NSString**)error +{ + unsigned i; + bool hasDot = false; + + if (partialString.length) + for (i = 0; i < partialString.length; i ++) + { + unichar ch = [partialString characterAtIndex:i]; + + if (i == 0 && (!self.minimum || self.minimum.intValue < 0) && ch == '-') + continue; + else if (self.allowsFloats && !hasDot && ch == '.') + hasDot = true; + else if (!isdigit(ch)) + return NO; + } + + return YES; +} + +- (BOOL)textField:(UITextField *)textField +shouldChangeCharactersInRange:(NSRange)range +replacementString:(NSString *)string +{ + NSString* text = (NSString*)[[textField text] + stringByReplacingCharactersInRange:range + withString:string]; + return [self isPartialStringValid:text + newEditingString:nil + errorDescription:nil]; +} + +@end + +@interface RAMenuItemGeneric : RAMenuItemBase @property (nonatomic) RANumberFormatter* formatter; @end -@implementation RAMenuItemGeneralSetting - -- (id)initWithSetting:(rarch_setting_t*)setting action:(void (^)())action -{ - if ((self = [super init])) { - _setting = setting; - _action = action; - } - return self; -} - +@implementation RAMenuItemGeneric - (UITableViewCell*)cellForTableView:(UITableView*)tableView { - char buffer[PATH_MAX_LENGTH]; UITableViewCell* result; - static NSString* const cell_id = @"string_setting"; - self.parentTable = tableView; - - result = [tableView dequeueReusableCellWithIdentifier:cell_id]; - if (!result) - { - result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cell_id]; - result.selectionStyle = UITableViewCellSelectionStyleNone; - } + result = [super cellForTableView: tableView]; [self attachDefaultingGestureTo:result]; - result.textLabel.text = BOXSTRING(""); - - if (self.setting) - { - if (self.setting->short_description) - result.textLabel.text = BOXSTRING(self.setting->short_description); - - setting_get_string_representation(self.setting, buffer, sizeof(buffer)); - if (buffer[0] == '\0') - strlcpy(buffer, "", sizeof(buffer)); - - result.detailTextLabel.text = BOXSTRING(buffer); - - if (self.setting->type == ST_PATH) - result.detailTextLabel.text = [result.detailTextLabel.text lastPathComponent]; - } return result; } -- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller +- (void)wasSelectedOnTableView:(UITableView*)tableView + ofController:(UIViewController*)controller { char buffer[PATH_MAX_LENGTH]; NSString *desc = BOXSTRING("N/A"); UIAlertView *alertView; UITextField *field; + + desc = BOXSTRING(get_menu_entry_label(self.i)); - if (self.setting && self.setting->short_description) - desc = BOXSTRING(self.setting->short_description); - - alertView = [[UIAlertView alloc] initWithTitle:BOXSTRING("Enter new value") message:desc delegate:self cancelButtonTitle:BOXSTRING("Cancel") otherButtonTitles:BOXSTRING("OK"), nil]; + alertView = + [[UIAlertView alloc] initWithTitle:BOXSTRING("Enter new value") + message:desc + delegate:self + cancelButtonTitle:BOXSTRING("Cancel") + otherButtonTitles:BOXSTRING("OK"), nil]; alertView.alertViewStyle = UIAlertViewStylePlainTextInput; field = [alertView textFieldAtIndex:0]; field.delegate = self.formatter; - setting_get_string_representation(self.setting, buffer, sizeof(buffer)); + menu_entry_value_get(self.i, buffer, sizeof(buffer)); if (buffer[0] == '\0') strlcpy(buffer, "N/A", sizeof(buffer)); @@ -436,8 +472,8 @@ static void RunActionSheet(const char* title, const struct string_list* items, U return; if (!text.length) return; - - setting_set_with_string_representation(self.setting, [text UTF8String]); + + menu_entry_value_set(self.i, [text UTF8String]); [self.parentTable reloadData]; } @@ -445,27 +481,29 @@ static void RunActionSheet(const char* title, const struct string_list* items, U { for (UIGestureRecognizer* i in view.gestureRecognizers) [view removeGestureRecognizer:i]; - [view addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self - action:@selector(resetValue:)]]; + [view addGestureRecognizer: + [[UILongPressGestureRecognizer alloc] + initWithTarget:self + action:@selector(resetValue:)]]; } - (void)resetValue:(UIGestureRecognizer*)gesture { struct string_list* items; - RAMenuItemGeneralSetting __weak* weakSelf; + RAMenuItemGeneric __weak* weakSelf; if (gesture.state != UIGestureRecognizerStateBegan) return; weakSelf = self; items = (struct string_list*)string_split("OK", "|"); - RunActionSheet("Really Reset Value?", items, self.parentTable, ^(UIActionSheet* actionSheet, NSInteger buttonIndex) { - if (buttonIndex != actionSheet.cancelButtonIndex) - setting_reset_setting(self.setting); - [weakSelf.parentTable reloadData]; + if (buttonIndex != actionSheet.cancelButtonIndex) { + menu_entry_reset(self.i); + } + [weakSelf.parentTable reloadData]; }); string_list_free(items); @@ -473,226 +511,120 @@ static void RunActionSheet(const char* title, const struct string_list* items, U @end -/*********************************************/ -/* RAMenuItemBooleanSetting */ -/* A simple menu item that displays the */ -/* state, and allows editing, of a boolean */ -/* setting. */ -/*********************************************/ -@implementation RAMenuItemBooleanSetting +@interface RAMenuItemNum : RAMenuItemGeneric +@end -- (id)initWithSetting:(rarch_setting_t*)setting action:(void (^)())action -{ - if ((self = [super init])) - { - _setting = setting; - _action = action; +@implementation RAMenuItemNum + +- (void)initialize:(NSObject *) main idx:(uint32_t) i { + [super initialize:main idx:i]; + self.formatter = [RANumberFormatter new]; + + if (menu_entry_num_has_range(self.i)) { + [self.formatter setRangeFrom:BOXFLOAT(menu_entry_num_min(self.i)) + To:BOXFLOAT(menu_entry_num_max(self.i))]; } +} +@end + +@interface RAMenuItemInt : RAMenuItemNum +@end + +@implementation RAMenuItemInt +@end + +@interface RAMenuItemUInt : RAMenuItemNum +@end + +@implementation RAMenuItemUInt +@end + +@interface RAMenuItemFloat : RAMenuItemNum +@end + +@implementation RAMenuItemFloat +- (void)initialize:(NSObject *) main idx:(uint32_t) i { + [super initialize:main idx:i]; + [self.formatter setAllowsFloats: true]; +} +@end + +@interface RAMenuItemString : RAMenuItemGeneric +@end + +@implementation RAMenuItemString +@end + +// XXX This should be a new kind that opens a color picker +@interface RAMenuItemHex : RAMenuItemGeneric +@end + +@implementation RAMenuItemHex +@end + +@implementation RAMenuBase + +- (id)initWithStyle:(UITableViewStyle)style +{ + if ((self = [super initWithStyle:style])) + _sections = [NSMutableArray array]; return self; } -- (UITableViewCell*)cellForTableView:(UITableView*)tableView +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { - static NSString* const cell_id = @"boolean_setting"; - - UITableViewCell* result = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:cell_id]; - - if (!result) - { - result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cell_id]; - result.selectionStyle = UITableViewCellSelectionStyleNone; - result.accessoryView = [UISwitch new]; - } - - result.textLabel.text = BOXSTRING(self.setting->short_description); - [(id)result.accessoryView removeTarget:nil action:NULL forControlEvents:UIControlEventValueChanged]; - [(id)result.accessoryView addTarget:self action:@selector(handleBooleanSwitch:) forControlEvents:UIControlEventValueChanged]; - - if (self.setting) - [(id)result.accessoryView setOn:*self.setting->value.boolean]; - return result; + return self.sections.count; } -- (void)handleBooleanSwitch:(UISwitch*)swt +- (NSString*)tableView:(UITableView*)tableView +titleForHeaderInSection:(NSInteger)section { - if (self.setting) - *self.setting->value.boolean = swt.on ? true : false; - if (self.action) - self.action(); + if (self.hidesHeaders) + return nil; + return self.sections[section][0]; } -- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller +- (NSInteger)tableView:(UITableView *)tableView + numberOfRowsInSection:(NSInteger)section { + return [self.sections[section] count] - 1; +} + +- (id)itemForIndexPath:(NSIndexPath*)indexPath +{ + return self.sections[indexPath.section][indexPath.row + 1]; +} + +- (UITableViewCell*)tableView:(UITableView *)tableView + cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return [[self itemForIndexPath:indexPath] cellForTableView:tableView]; +} + +- (void)tableView:(UITableView *)tableView +didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [[self itemForIndexPath:indexPath] + wasSelectedOnTableView:tableView + ofController:self]; +} + +- (void)willReloadData +{ + +} + +- (void)reloadData +{ + [self willReloadData]; + [[self tableView] reloadData]; } @end -/*********************************************/ -/* RAMenuItemPathSetting */ -/* A menu item that displays and allows */ -/* browsing for a path setting. */ -/*********************************************/ -@interface RAMenuItemPathSetting() @end -@implementation RAMenuItemPathSetting - -- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller -{ - NSString *path; - RADirectoryList* list; - RAMenuItemPathSetting __weak* weakSelf = self; - - if (setting_is_of_path_type(self.setting)) - self.setting->action_toggle( self.setting, MENU_ACTION_RIGHT, false); - - path = BOXSTRING(self.setting->value.string); - - if ( self.setting->type == ST_PATH ) - path = [path stringByDeletingLastPathComponent]; - - list = [[RADirectoryList alloc] initWithPath:path extensions:self.setting->values action: - ^(RADirectoryList* list, RADirectoryItem* item) - { - const char *newval = ""; - if (item) - { - if (list.forDirectory && !item.isDirectory) - return; - - newval = [item.path UTF8String]; - } - else - { - if (!list.allowBlank) - return; - } - - setting_set_with_string_representation(weakSelf.setting, newval); - [[list navigationController] popViewControllerAnimated:YES]; - - weakSelf.action(); - - [weakSelf.parentTable reloadData]; - }]; - - list.allowBlank = (self.setting->flags & SD_FLAG_ALLOW_EMPTY); - list.forDirectory = (self.setting->flags & SD_FLAG_PATH_DIR); - - [controller.navigationController pushViewController:list animated:YES]; -} - +@interface RAMainMenu : RAMenuBase @end -/*********************************************/ -/* RAMenuItemEnumSetting */ -/* A menu item that displays and allows */ -/* a setting to be set from a list of */ -/* allowed choices. */ -/*********************************************/ -@implementation RAMenuItemEnumSetting - -- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller -{ - struct string_list* items; - RAMenuItemEnumSetting __weak* weakSelf = self; - - items = (struct string_list*)string_split(self.setting->values, "|"); - RunActionSheet(self.setting->short_description, items, self.parentTable, - ^(UIActionSheet* actionSheet, NSInteger buttonIndex) - { - if (buttonIndex == actionSheet.cancelButtonIndex) - return; - - setting_set_with_string_representation(self.setting, [[actionSheet buttonTitleAtIndex:buttonIndex] UTF8String]); - [weakSelf.parentTable reloadData]; - }); - string_list_free(items); -} - -@end - - -/*********************************************/ -/* RAMenuItemBindSetting */ -/* A menu item that displays and allows */ -/* mapping of a keybinding. */ -/*********************************************/ -@interface RAMenuItemBindSetting() -@property (nonatomic) NSTimer* bindTimer; -@property (nonatomic) UIAlertView* alert; -@end - -@implementation RAMenuItemBindSetting - -- (void)wasSelectedOnTableView:(UITableView *)tableView ofController:(UIViewController *)controller -{ - self.alert = [[UIAlertView alloc] initWithTitle:BOXSTRING("RetroArch") - message:BOXSTRING(self.setting->short_description) - delegate:self - cancelButtonTitle:BOXSTRING("Cancel") - otherButtonTitles:BOXSTRING("Clear Keyboard"), BOXSTRING("Clear Joystick"), BOXSTRING("Clear Axis"), nil]; - - [self.alert show]; - - [self.parentTable reloadData]; - - self.bindTimer = [NSTimer scheduledTimerWithTimeInterval:.1f target:self selector:@selector(checkBind:) - userInfo:nil repeats:YES]; -} - -- (void)finishWithClickedButton:(bool)clicked -{ - if (!clicked) - [self.alert dismissWithClickedButtonIndex:self.alert.cancelButtonIndex animated:YES]; - self.alert = nil; - - [self.parentTable reloadData]; - - [self.bindTimer invalidate]; - self.bindTimer = nil; - - cocoa_input_reset_icade_buttons(); -} - -- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if (buttonIndex == alertView.firstOtherButtonIndex) - BINDFOR(*self.setting).key = RETROK_UNKNOWN; - else if(buttonIndex == alertView.firstOtherButtonIndex + 1) - BINDFOR(*self.setting).joykey = NO_BTN; - else if(buttonIndex == alertView.firstOtherButtonIndex + 2) - BINDFOR(*self.setting).joyaxis = AXIS_NONE; - - [self finishWithClickedButton:true]; -} - -- (void)checkBind:(NSTimer*)send -{ - int32_t value = 0; - int32_t idx = 0; - - if (self.setting->index) - idx = self.setting->index - 1; - - if ((value = cocoa_input_find_any_key())) - BINDFOR(*self.setting).key = input_keymaps_translate_keysym_to_rk(value); - else if ((value = cocoa_input_find_any_button(idx)) >= 0) - BINDFOR(*self.setting).joykey = value; - else if ((value = cocoa_input_find_any_axis(idx))) - BINDFOR(*self.setting).joyaxis = (value > 0) ? AXIS_POS(value - 1) : AXIS_NEG(abs(value) - 1); - else - return; - - [self finishWithClickedButton:false]; -} - -@end - - -/*********************************************/ -/* RAMainMenu */ -/* Menu object that is displayed immediately */ -/* after startup. */ -/*********************************************/ @implementation RAMainMenu - (id)init @@ -730,8 +662,7 @@ static void RunActionSheet(const char* title, const struct string_list* items, U get_title(label, dir, menu_type, title, sizeof(title)); [everything addObject:BOXSTRING(title)]; - end = menu_list_get_size(menu->menu_list); - + end = menu_list_get_size(menu->menu_list); for (i = menu->begin; i < end; i++) [everything addObject:[self make_menu_item_for_entry: i]]; @@ -772,119 +703,37 @@ static void RunActionSheet(const char* title, const struct string_list* items, U action:action]; } -// JM: This could go down into RA -void get_core_title(char *title_msg, size_t title_msg_len) +- (RAMenuItemBase*)make_menu_item_for_entry: (uint32_t) i { - global_t *global = global_get_ptr(); - const char *core_name = global->menu.info.library_name; - const char *core_version = global->menu.info.library_version; - - if (!core_name) - core_name = global->system.info.library_name; - if (!core_name) - core_name = "No Core"; + RAMenuItemBase *me = nil; + switch (get_menu_entry_type(i)) { + case MENU_ENTRY_ACTION: + me = [RAMenuItemAction new]; break; + case MENU_ENTRY_BOOL: + me = [RAMenuItemBool new]; break; + case MENU_ENTRY_INT: + me = [RAMenuItemInt new]; break; + case MENU_ENTRY_UINT: + me = [RAMenuItemUInt new]; break; + case MENU_ENTRY_FLOAT: + me = [RAMenuItemFloat new]; break; + case MENU_ENTRY_PATH: + me = [RAMenuItemPath new]; break; + case MENU_ENTRY_DIR: + me = [RAMenuItemDir new]; break; + case MENU_ENTRY_STRING: + me = [RAMenuItemString new]; break; + case MENU_ENTRY_HEX: + me = [RAMenuItemHex new]; break; + case MENU_ENTRY_BIND: + me = [RAMenuItemBind new]; break; + case MENU_ENTRY_ENUM: + me = [RAMenuItemEnum new]; break; + }; - if (!core_version) - core_version = global->system.info.library_version; - if (!core_version) - core_version = ""; + [me initialize:self idx:i]; - snprintf(title_msg, title_msg_len, "%s - %s %s", PACKAGE_VERSION, - core_name, core_version); -} - -- (NSObject*)make_menu_item_for_entry: (uint32_t) i -{ - menu_handle_t *menu = menu_driver_get_ptr(); - RAMainMenu* __weak weakSelf; - rarch_setting_t *setting; - char type_str[PATH_MAX_LENGTH], path_buf[PATH_MAX_LENGTH]; - menu_file_list_cbs_t *cbs = NULL; - const char *path = NULL, *entry_label = NULL; - unsigned type = 0, w = 0; - const char *dir = NULL; - const char *label = NULL; - menu_list_t *menu_list = menu_list_get_ptr(); - unsigned menu_type = 0; - - weakSelf = self; - menu_list_get_last_stack(menu_list, &dir, &label, &menu_type); - - menu_list_get_at_offset(menu_list->selection_buf, i, &path, - &entry_label, &type); - - // JM: Ideally, this would be simpler because RA would provide a - // function that takes "i" and returns either Path, DirPath, Bool, - // Bind, Enum, Number, String, Action. [Sub-menus would be action, - // because it causes an effect] - - setting = setting_find_setting - (menu->list_settings, - menu_list->selection_buf->list[i].label); - - if (setting_is_of_path_type(setting)) - { - return [[RAMenuItemPathSetting alloc] - initWithSetting:setting - action:^{}]; - } - else if (setting && setting->type == ST_BOOL ) - { - return [[RAMenuItemBooleanSetting alloc] - initWithSetting:setting - action:^{[weakSelf menuSelect: i];}]; - } - else if (setting && ST_PATH <= setting->type && setting->type <= ST_DIR) - { - return [[RAMenuItemPathSetting alloc] - initWithSetting:setting - action:^{[weakSelf menuSelect: i];}]; - } - else if (setting && setting->type == ST_BIND ) - { - return [[RAMenuItemBindSetting alloc] - initWithSetting:setting - action:^{[weakSelf menuSelect: i];}]; - } - else if (setting_is_of_enum_type(setting)) - { - return [[RAMenuItemEnumSetting alloc] - initWithSetting:setting - action:^{[weakSelf menuSelect: i];}]; - } - else if (setting && ST_INT <= setting->type && setting->type <= ST_HEX) - { - RAMenuItemGeneralSetting* item = - [[RAMenuItemGeneralSetting alloc] - initWithSetting:setting - action:^{[weakSelf menuSelect: i];}]; - - if (setting->type == ST_INT || - setting->type == ST_UINT || - setting->type == ST_FLOAT) - item.formatter = [[RANumberFormatter alloc] initWithSetting:item.setting]; - - return item; - } - else - { // This is for ST_GROUP/etc - cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(menu_list->selection_buf, i); - - if (cbs && cbs->action_get_representation) - { - cbs->action_get_representation - (menu_list->selection_buf, - &w, type, i, label, - type_str, sizeof(type_str), - entry_label, path, - path_buf, sizeof(path_buf)); - } - - return [RAMenuItemBasic - itemWithDescription:BOXSTRING(path_buf) - action:^{[weakSelf menuSelect: i];}]; - } + return me; } - (void)menuSelect: (uint32_t) i @@ -896,50 +745,6 @@ void get_core_title(char *title_msg, size_t title_msg_len) } } -// JM: This could be moved down to RA -uint32_t menu_select_entry(uint32_t i) -{ - menu_entry_t entry; - rarch_setting_t *setting; - menu_file_list_cbs_t *cbs = NULL; - menu_navigation_t *nav = menu_navigation_get_ptr(); - menu_list_t *menu_list = menu_list_get_ptr(); - - setting = menu_setting_find(menu_list->selection_buf->list[i].label); - - menu_list_get_entry(&entry, i, NULL, false); - - cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(menu_list->selection_buf, i); - - if (setting_is_of_path_type(setting)) - return false; - else if (setting_is_of_general_type(setting)) - { - nav->selection_ptr = i; - if (cbs && cbs->action_ok) - cbs->action_ok(entry.path, entry.label, entry.type, i); - - return false; - } - else - { - nav->selection_ptr = i; - if (cbs && cbs->action_ok) - cbs->action_ok(entry.path, entry.label, entry.type, i); - else - { - if (cbs && cbs->action_start) - cbs->action_start(entry.type, entry.label, MENU_ACTION_START); - if (cbs && cbs->action_toggle) - cbs->action_toggle(entry.type, entry.label, MENU_ACTION_RIGHT, true); - menu_list_push(menu_list->menu_stack, "", - "info_screen", 0, i); - } - return true; - } -} - - (void)menuRefresh { menu_handle_t *menu = menu_driver_get_ptr(); diff --git a/ui/drivers/cocoa/cocoatouch_support.c b/ui/drivers/cocoa/cocoatouch_support.c new file mode 100644 index 0000000000..74c81e6dae --- /dev/null +++ b/ui/drivers/cocoa/cocoatouch_support.c @@ -0,0 +1,253 @@ +// JM: The idea of this file is that these will be moved down into +// ../../../menu/something + +void get_core_title(char *title_msg, size_t title_msg_len) +{ + global_t *global = global_get_ptr(); + const char *core_name = global->menu.info.library_name; + const char *core_version = global->menu.info.library_version; + + if (!core_name) + core_name = global->system.info.library_name; + if (!core_name) + core_name = "No Core"; + + if (!core_version) + core_version = global->system.info.library_version; + if (!core_version) + core_version = ""; + + snprintf(title_msg, title_msg_len, "%s - %s %s", PACKAGE_VERSION, + core_name, core_version); +} + +enum menu_entry_type +{ + MENU_ENTRY_ACTION = 0, + MENU_ENTRY_BOOL, + MENU_ENTRY_INT, + MENU_ENTRY_UINT, + MENU_ENTRY_FLOAT, + MENU_ENTRY_PATH, + MENU_ENTRY_DIR, + MENU_ENTRY_STRING, + MENU_ENTRY_HEX, + MENU_ENTRY_BIND, + MENU_ENTRY_ENUM, +}; + +rarch_setting_t *get_menu_entry_setting(uint32_t i) { + menu_handle_t *menu = menu_driver_get_ptr(); + rarch_setting_t *setting; + const char *path = NULL, *entry_label = NULL; + unsigned type = 0; + const char *dir = NULL; + const char *label = NULL; + menu_list_t *menu_list = menu_list_get_ptr(); + unsigned menu_type = 0; + + menu_list_get_last_stack(menu_list, &dir, &label, &menu_type); + + menu_list_get_at_offset(menu_list->selection_buf, i, &path, + &entry_label, &type); + + setting = setting_find_setting + (menu->list_settings, + menu_list->selection_buf->list[i].label); + + return setting; +} + +enum menu_entry_type get_menu_entry_type(uint32_t i) { + rarch_setting_t *setting; + const char *path = NULL, *entry_label = NULL; + unsigned type = 0; + const char *dir = NULL; + const char *label = NULL; + menu_list_t *menu_list = menu_list_get_ptr(); + unsigned menu_type = 0; + + menu_list_get_last_stack(menu_list, &dir, &label, &menu_type); + + menu_list_get_at_offset(menu_list->selection_buf, i, &path, + &entry_label, &type); + + setting = get_menu_entry_setting(i); + + // XXX Really a special kind of ST_ACTION, but this should be + // changed + if (setting_is_of_path_type(setting)) { + return MENU_ENTRY_PATH; + } else if (setting && setting->type == ST_BOOL ) { + return MENU_ENTRY_BOOL; + } else if (setting && setting->type == ST_BIND ) { + return MENU_ENTRY_BIND; + } else if (setting_is_of_enum_type(setting)) { + return MENU_ENTRY_ENUM; + } else if (setting && setting->type == ST_INT ) { + return MENU_ENTRY_INT; + } else if (setting && setting->type == ST_UINT ) { + return MENU_ENTRY_UINT; + } else if (setting && setting->type == ST_FLOAT ) { + return MENU_ENTRY_FLOAT; + } else if (setting && setting->type == ST_PATH ) { + return MENU_ENTRY_PATH; + } else if (setting && setting->type == ST_DIR ) { + return MENU_ENTRY_DIR; + } else if (setting && setting->type == ST_STRING ) { + return MENU_ENTRY_STRING; + } else if (setting && setting->type == ST_HEX ) { + return MENU_ENTRY_HEX; + } else { + return MENU_ENTRY_ACTION; + } +} + +const char *get_menu_entry_label(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + if (setting) { + return setting->short_description; + } else { + return ""; + } +} + +uint32_t menu_entry_bool_value_get(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return *setting->value.boolean; +} +void menu_entry_bool_value_set(uint32_t i, uint32_t new_val) { + rarch_setting_t *setting = get_menu_entry_setting(i); + *setting->value.boolean = new_val; +} + +struct string_list *menu_entry_enum_values(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return string_split(setting->values, "|"); +} + +void menu_entry_enum_value_set_with_string(uint32_t i, const char *s) { + rarch_setting_t *setting = get_menu_entry_setting(i); + setting_set_with_string_representation(setting, s); +} + +int32_t menu_entry_bind_index(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + if (setting->index) { + return setting->index - 1; + } else { + return 0; + } +} + +void menu_entry_bind_key_set(uint32_t i, int32_t value) { + rarch_setting_t *setting = get_menu_entry_setting(i); + BINDFOR(*setting).key = value; +} +void menu_entry_bind_joykey_set(uint32_t i, int32_t value) { + rarch_setting_t *setting = get_menu_entry_setting(i); + BINDFOR(*setting).joykey = value; +} +void menu_entry_bind_joyaxis_set(uint32_t i, int32_t value) { + rarch_setting_t *setting = get_menu_entry_setting(i); + BINDFOR(*setting).joyaxis = value; +} + +void menu_entry_pathdir_selected(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + if (setting_is_of_path_type(setting)) + setting->action_toggle( setting, MENU_ACTION_RIGHT, false); +} + +uint32_t menu_entry_pathdir_allow_empty(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return setting->flags & SD_FLAG_ALLOW_EMPTY; +} +uint32_t menu_entry_pathdir_for_directory(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return setting->flags & SD_FLAG_PATH_DIR; +} + +const char *menu_entry_pathdir_value_get(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return setting->value.string; +} +void menu_entry_pathdir_value_set(uint32_t i, const char *s) { + rarch_setting_t *setting = get_menu_entry_setting(i); + setting_set_with_string_representation(setting, s); +} +const char *menu_entry_pathdir_extensions(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return setting->values; +} + +void menu_entry_reset(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + setting_reset_setting(setting); +} +void menu_entry_value_get(uint32_t i, char *s, size_t len) { + rarch_setting_t *setting = get_menu_entry_setting(i); + setting_get_string_representation(setting, s, len); +} +void menu_entry_value_set(uint32_t i, const char *s) { + rarch_setting_t *setting = get_menu_entry_setting(i); + setting_set_with_string_representation(setting, s); +} + +uint32_t menu_entry_num_has_range(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return (setting->flags & SD_FLAG_HAS_RANGE); +} + +float menu_entry_num_min(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return setting->min; +} +float menu_entry_num_max(uint32_t i) { + rarch_setting_t *setting = get_menu_entry_setting(i); + return setting->max; +} + +// Returns true if the menu should reload +uint32_t menu_select_entry(uint32_t i) +{ + menu_entry_t entry; + rarch_setting_t *setting; + menu_file_list_cbs_t *cbs = NULL; + menu_navigation_t *nav = menu_navigation_get_ptr(); + menu_list_t *menu_list = menu_list_get_ptr(); + + setting = menu_setting_find(menu_list->selection_buf->list[i].label); + + menu_list_get_entry(&entry, i, NULL, false); + + cbs = (menu_file_list_cbs_t*) + menu_list_get_actiondata_at_offset(menu_list->selection_buf, i); + + if (setting_is_of_path_type(setting)) + return false; + else if (setting_is_of_general_type(setting)) + { + nav->selection_ptr = i; + if (cbs && cbs->action_ok) + cbs->action_ok(entry.path, entry.label, entry.type, i); + + return false; + } + else + { + nav->selection_ptr = i; + if (cbs && cbs->action_ok) + cbs->action_ok(entry.path, entry.label, entry.type, i); + else + { + if (cbs && cbs->action_start) + cbs->action_start(entry.type, entry.label, MENU_ACTION_START); + if (cbs && cbs->action_toggle) + cbs->action_toggle(entry.type, entry.label, MENU_ACTION_RIGHT, true); + menu_list_push(menu_list->menu_stack, "", + "info_screen", 0, i); + } + return true; + } +}