2013-11-22 14:30:02 +00:00
/ * RetroArch - A frontend for libretro .
2014-01-01 00:50:59 +00:00
* Copyright ( C ) 2013 -2014 - Jason Fetters
2015-01-07 16:46:50 +00:00
* Copyright ( C ) 2014 -2015 - Jay McCarthy
2013-11-22 14:30:02 +00:00
*
* RetroArch is free software : you can redistribute it and / or modify it under the terms
* of the GNU General Public License as published by the Free Software Found -
* ation , either version 3 of the License , or ( at your option ) any later version .
*
* RetroArch is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE . See the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along with RetroArch .
* If not , see < http : // www . gnu . org / licenses / > .
* /
2014-05-22 16:54:10 +00:00
# include "../common/RetroArch_Apple.h"
2014-05-03 17:00:12 +00:00
# include "../../input/input_common.h"
2014-10-27 03:29:21 +00:00
# include "../../input/input_keymaps.h"
2015-01-12 05:20:19 +00:00
# include "../../input/drivers/apple_input.h"
2014-10-21 22:23:06 +00:00
# include < file / file_path . h >
2015-01-17 04:47:33 +00:00
# include < retro_miscellaneous . h >
2013-11-22 14:30:02 +00:00
# include "menu.h"
2015-03-30 16:16:09 +00:00
# include < objc / runtime . h >
2015-01-10 03:53:37 +00:00
# include "../../menu/menu.h"
2014-11-05 16:50:56 +00:00
# include "../../menu/menu_entries.h"
2015-01-26 10:17:38 +00:00
# include "../../menu/drivers/shared.h"
2014-11-05 03:01:01 +00:00
2013-12-10 00:50:46 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RunActionSheet * /
/ * Creates and displays a UIActionSheet with * /
/ * buttons pulled from a RetroArch * /
/ * string_list structure . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2013-12-30 23:20:31 +00:00
static const void * const associated_delegate _key = & associated_delegate _key ;
2013-12-26 21:00:29 +00:00
typedef void ( ^ RAActionSheetCallback ) ( UIActionSheet * , NSInteger ) ;
@ interface RARunActionSheetDelegate : NSObject < UIActionSheetDelegate >
@ property ( nonatomic , copy ) RAActionSheetCallback callbackBlock ;
@ end
@ implementation RARunActionSheetDelegate
- ( id ) initWithCallbackBlock : ( RAActionSheetCallback ) callback
{
if ( ( self = [ super init ] ) )
_callbackBlock = callback ;
return self ;
}
- ( void ) actionSheet : ( UIActionSheet * ) actionSheet willDismissWithButtonIndex : ( NSInteger ) buttonIndex
{
if ( self . callbackBlock )
self . callbackBlock ( actionSheet , buttonIndex ) ;
}
@ end
static void RunActionSheet ( const char * title , const struct string_list * items , UIView * parent , RAActionSheetCallback callback )
2013-12-10 00:50:46 +00:00
{
2014-09-21 01:38:59 +00:00
size_t i ;
2013-12-30 23:20:31 +00:00
RARunActionSheetDelegate * delegate = [ [ RARunActionSheetDelegate alloc ] initWithCallbackBlock : callback ] ;
2013-12-10 00:50:46 +00:00
UIActionSheet * actionSheet = [ UIActionSheet new ] ;
2014-07-08 16:23:30 +00:00
2013-12-12 19:49:18 +00:00
actionSheet . title = BOXSTRING ( title ) ;
2013-12-30 23:20:31 +00:00
actionSheet . delegate = delegate ;
2013-12-10 00:50:46 +00:00
2014-07-08 16:23:30 +00:00
for ( i = 0 ; i < items -> size ; i + + )
2013-12-12 19:49:18 +00:00
[ actionSheet addButtonWithTitle : BOXSTRING ( items -> elems [ i ] . data ) ] ;
2013-12-10 00:50:46 +00:00
2014-07-08 16:23:30 +00:00
actionSheet . cancelButtonIndex = [ actionSheet addButtonWithTitle : BOXSTRING ( "Cancel" ) ] ;
2013-12-30 23:20:31 +00:00
objc_setAssociatedObject ( actionSheet , associated_delegate _key , delegate , OBJC_ASSOCIATION _RETAIN _NONATOMIC ) ;
2013-12-10 00:50:46 +00:00
[ actionSheet showInView : parent ] ;
}
2013-11-22 14:30:02 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuBase * /
/ * A menu class that displays RAMenuItemBase * /
/ * objects . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuBase
- ( id ) initWithStyle : ( UITableViewStyle ) style
{
if ( ( self = [ super initWithStyle : style ] ) )
2013-12-26 22:36:00 +00:00
_sections = [ NSMutableArray array ] ;
2013-11-22 14:30:02 +00:00
return self ;
}
- ( NSInteger ) numberOfSectionsInTableView : ( UITableView * ) tableView
{
return self . sections . count ;
}
- ( NSString * ) tableView : ( UITableView * ) tableView titleForHeaderInSection : ( NSInteger ) section
{
2015-01-14 23:57:37 +00:00
if ( self . hidesHeaders )
return nil ;
return self . sections [ section ] [ 0 ] ;
2013-11-22 14:30:02 +00:00
}
- ( 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 ] ;
}
2013-12-16 02:27:17 +00:00
- ( void ) willReloadData
{
}
- ( void ) reloadData
{
[ self willReloadData ] ;
[ [ self tableView ] reloadData ] ;
}
2013-11-22 14:30:02 +00:00
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemBasic * /
/ * A simple menu item that displays a text * /
/ * description and calls a block object when * /
/ * selected . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuItemBasic
2014-09-20 20:54:02 +00:00
@ synthesize description ;
@ synthesize userdata ;
@ synthesize action ;
@ synthesize detail ;
2013-11-22 14:30:02 +00:00
+ ( 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
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemGeneralSetting * /
/ * A simple menu item that displays the * /
/ * state , and allows editing , of a string or * /
/ * numeric setting . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ interface RAMenuItemGeneralSetting ( ) < UIAlertViewDelegate >
@ property ( nonatomic ) RANumberFormatter * formatter ;
@ end
@ implementation RAMenuItemGeneralSetting
2014-12-31 20:50:09 +00:00
+ ( id ) itemForSetting : ( rarch_setting _t * ) setting action : ( void ( ^ ) ( ) ) action
2013-11-22 14:30:02 +00:00
{
2014-11-11 17:11:48 +00:00
switch ( setting -> type ) {
case ST_NONE :
case ST_ACTION :
return [ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Shouldn't be called with ST_NONE or ST_ACTION" )
action : ^ { } ] ;
case ST_BOOL :
2014-12-31 20:50:09 +00:00
return [ [ RAMenuItemBooleanSetting alloc ] initWithSetting : setting action : action ] ;
2014-11-11 17:11:48 +00:00
case ST_INT :
case ST_UINT :
case ST_FLOAT :
break ;
case ST_PATH :
case ST_DIR :
2014-12-31 20:50:09 +00:00
return [ [ RAMenuItemPathSetting alloc ] initWithSetting : setting action : action ] ;
2014-11-11 17:11:48 +00:00
case ST_STRING :
case ST_HEX :
break ;
case ST_BIND :
2014-12-31 20:50:09 +00:00
return [ [ RAMenuItemBindSetting alloc ] initWithSetting : setting action : action ] ;
2014-11-11 17:11:48 +00:00
case ST_GROUP :
case ST_SUB _GROUP :
case ST_END _GROUP :
case ST_END _SUB _GROUP :
default :
return [ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Shouldn't be called with ST_*GROUP" )
action : ^ { } ] ;
}
2013-11-30 02:34:12 +00:00
2013-12-04 00:46:30 +00:00
if ( setting -> type = = ST_STRING && setting -> values )
2014-12-31 20:50:09 +00:00
return [ [ RAMenuItemEnumSetting alloc ] initWithSetting : setting action : action ] ;
2013-12-04 00:46:30 +00:00
2014-12-31 20:50:09 +00:00
RAMenuItemGeneralSetting * item = [ [ RAMenuItemGeneralSetting alloc ] initWithSetting : setting action : action ] ;
2013-11-22 14:30:02 +00:00
2014-11-11 17:11:48 +00:00
if ( item . setting -> type = = ST_INT ||
2014-09-28 16:18:26 +00:00
item . setting -> type = = ST_UINT ||
item . setting -> type = = ST_FLOAT )
2013-11-22 14:30:02 +00:00
item . formatter = [ [ RANumberFormatter alloc ] initWithSetting : item . setting ] ;
return item ;
}
2014-12-31 20:50:09 +00:00
- ( id ) initWithSetting : ( rarch_setting _t * ) setting action : ( void ( ^ ) ( ) ) action
2013-11-30 02:34:12 +00:00
{
2014-12-31 20:50:09 +00:00
if ( ( self = [ super init ] ) ) {
_setting = setting ;
_action = action ;
}
return self ;
2013-11-30 02:34:12 +00:00
}
2013-11-22 14:30:02 +00:00
- ( UITableViewCell * ) cellForTableView : ( UITableView * ) tableView
{
2015-01-17 04:47:33 +00:00
char buffer [ PATH_MAX _LENGTH ] ;
2015-01-14 23:57:37 +00:00
UITableViewCell * result ;
2013-11-22 14:30:02 +00:00
static NSString * const cell_id = @ "string_setting" ;
self . parentTable = tableView ;
2015-01-14 23:57:37 +00:00
result = [ tableView dequeueReusableCellWithIdentifier : cell_id ] ;
2013-11-22 14:30:02 +00:00
if ( ! result )
{
result = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : cell_id ] ;
result . selectionStyle = UITableViewCellSelectionStyleNone ;
}
2013-12-26 21:17:37 +00:00
[ self attachDefaultingGestureTo : result ] ;
2013-11-22 14:30:02 +00:00
2014-11-11 17:11:48 +00:00
result . textLabel . text = BOXSTRING ( "<Uninitialized>" ) ;
2013-11-22 14:30:02 +00:00
if ( self . setting )
2013-12-03 00:55:58 +00:00
{
2014-08-17 14:20:37 +00:00
if ( self . setting -> short_description )
result . textLabel . text = BOXSTRING ( self . setting -> short_description ) ;
2015-03-20 23:56:26 +00:00
setting_get _string _representation ( self . setting , buffer , sizeof ( buffer ) ) ;
2014-08-17 14:20:37 +00:00
if ( buffer [ 0 ] = = ' \ 0 ' )
2014-11-11 17:11:48 +00:00
strlcpy ( buffer , "<default>" , sizeof ( buffer ) ) ;
2014-08-17 14:20:37 +00:00
result . detailTextLabel . text = BOXSTRING ( buffer ) ;
2013-12-03 00:55:58 +00:00
if ( self . setting -> type = = ST_PATH )
result . detailTextLabel . text = [ result . detailTextLabel . text lastPathComponent ] ;
}
2013-11-22 14:30:02 +00:00
return result ;
}
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2015-01-17 04:47:33 +00:00
char buffer [ PATH_MAX _LENGTH ] ;
2014-07-25 17:45:52 +00:00
NSString * desc = BOXSTRING ( "N/A" ) ;
UIAlertView * alertView ;
UITextField * field ;
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 ] ;
2013-11-22 14:30:02 +00:00
alertView . alertViewStyle = UIAlertViewStylePlainTextInput ;
2014-07-25 17:45:52 +00:00
field = [ alertView textFieldAtIndex : 0 ] ;
2013-11-22 14:30:02 +00:00
field . delegate = self . formatter ;
2014-08-17 14:20:37 +00:00
2015-03-20 23:56:26 +00:00
setting_get _string _representation ( self . setting , buffer , sizeof ( buffer ) ) ;
2014-08-17 14:20:37 +00:00
if ( buffer [ 0 ] = = ' \ 0 ' )
strlcpy ( buffer , "N/A" , sizeof ( buffer ) ) ;
field . placeholder = BOXSTRING ( buffer ) ;
2013-11-22 14:30:02 +00:00
[ alertView show ] ;
}
- ( void ) alertView : ( UIAlertView * ) alertView clickedButtonAtIndex : ( NSInteger ) buttonIndex
{
2014-04-19 18:16:29 +00:00
NSString * text = ( NSString * ) [ alertView textFieldAtIndex : 0 ] . text ;
2013-11-22 14:30:02 +00:00
2015-01-14 23:57:37 +00:00
if ( buttonIndex ! = alertView . firstOtherButtonIndex )
return ;
if ( ! text . length )
return ;
2015-03-20 23:56:26 +00:00
setting_set _with _string _representation ( self . setting , [ text UTF8String ] ) ;
2015-01-14 23:57:37 +00:00
[ self . parentTable reloadData ] ;
2013-11-22 14:30:02 +00:00
}
2013-12-26 21:17:37 +00:00
- ( void ) attachDefaultingGestureTo : ( UIView * ) view
{
for ( UIGestureRecognizer * i in view . gestureRecognizers )
[ view removeGestureRecognizer : i ] ;
[ view addGestureRecognizer : [ [ UILongPressGestureRecognizer alloc ] initWithTarget : self
action : @ selector ( resetValue : ) ] ] ;
}
- ( void ) resetValue : ( UIGestureRecognizer * ) gesture
{
2015-01-14 23:50:16 +00:00
struct string_list * items ;
RAMenuItemGeneralSetting __weak * weakSelf ;
if ( gesture . state ! = UIGestureRecognizerStateBegan )
return ;
weakSelf = self ;
items = ( struct string_list * ) string_split ( "OK" , "|" ) ;
RunActionSheet ( "Really Reset Value?" , items , self . parentTable ,
2013-12-26 21:17:37 +00:00
^ ( UIActionSheet * actionSheet , NSInteger buttonIndex )
{
if ( buttonIndex ! = actionSheet . cancelButtonIndex )
2015-03-20 23:56:26 +00:00
setting_reset _setting ( self . setting ) ;
2013-12-26 21:17:37 +00:00
[ weakSelf . parentTable reloadData ] ;
} ) ;
2015-01-14 23:50:16 +00:00
string_list _free ( items ) ;
2013-12-26 21:17:37 +00:00
}
2013-11-22 14:30:02 +00:00
@ end
2013-11-30 02:34:12 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemBooleanSetting * /
/ * A simple menu item that displays the * /
/ * state , and allows editing , of a boolean * /
/ * setting . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuItemBooleanSetting
2014-12-31 20:50:09 +00:00
- ( id ) initWithSetting : ( rarch_setting _t * ) setting action : ( void ( ^ ) ( ) ) action
2013-11-30 02:34:12 +00:00
{
2015-01-14 23:50:16 +00:00
if ( ( self = [ super init ] ) )
{
2014-12-31 20:50:09 +00:00
_setting = setting ;
_action = action ;
}
2013-11-30 02:34:12 +00:00
return self ;
}
- ( UITableViewCell * ) cellForTableView : ( UITableView * ) tableView
{
static NSString * const cell_id = @ "boolean_setting" ;
2014-04-19 18:16:29 +00:00
UITableViewCell * result = ( UITableViewCell * ) [ tableView dequeueReusableCellWithIdentifier : cell_id ] ;
2015-01-07 00:18:41 +00:00
2013-11-30 02:34:12 +00:00
if ( ! result )
{
result = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : cell_id ] ;
result . selectionStyle = UITableViewCellSelectionStyleNone ;
result . accessoryView = [ UISwitch new ] ;
}
2013-12-12 19:49:18 +00:00
result . textLabel . text = BOXSTRING ( self . setting -> short_description ) ;
2013-11-30 02:34:12 +00:00
[ ( 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 ;
}
- ( void ) handleBooleanSwitch : ( UISwitch * ) swt
{
2015-01-07 00:18:41 +00:00
if ( self . setting )
2014-12-31 20:50:09 +00:00
* self . setting -> value . boolean = swt . on ? true : false ;
2015-01-07 00:18:41 +00:00
if ( self . action )
2014-12-31 20:50:09 +00:00
self . action ( ) ;
2013-11-30 02:34:12 +00:00
}
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
}
@ end
2013-11-22 14:30:02 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemPathSetting * /
/ * A menu item that displays and allows * /
/ * browsing for a path setting . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2013-12-26 06:43:10 +00:00
@ interface RAMenuItemPathSetting ( ) @ end
2013-11-22 14:30:02 +00:00
@ implementation RAMenuItemPathSetting
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2014-07-08 16:23:30 +00:00
NSString * path ;
RADirectoryList * list ;
2013-12-26 06:43:10 +00:00
RAMenuItemPathSetting __weak * weakSelf = self ;
2015-01-07 02:53:18 +00:00
if ( self . setting && self . setting -> type = = ST_ACTION &&
self . setting -> flags & SD_FLAG _BROWSER _ACTION &&
self . setting -> action_toggle &&
2015-01-14 23:50:16 +00:00
self . setting -> change_handler )
2015-03-09 13:55:27 +00:00
self . setting -> action_toggle ( self . setting , MENU_ACTION _RIGHT , false ) ;
2015-01-07 13:07:47 +00:00
path = BOXSTRING ( self . setting -> value . string ) ;
2015-01-14 23:50:16 +00:00
if ( self . setting -> type = = ST_PATH )
2015-01-07 13:07:47 +00:00
path = [ path stringByDeletingLastPathComponent ] ;
2015-01-14 23:50:16 +00:00
2014-07-08 16:23:30 +00:00
list = [ [ RADirectoryList alloc ] initWithPath : path extensions : self . setting -> values action :
2013-12-26 06:43:10 +00:00
^ ( RADirectoryList * list , RADirectoryItem * item )
{
2015-01-14 23:50:16 +00:00
const char * newval = "" ;
2015-01-07 00:18:41 +00:00
if ( item )
{
2014-11-26 19:24:18 +00:00
if ( list . forDirectory && ! item . isDirectory )
2013-12-26 06:43:10 +00:00
return ;
2014-11-26 19:24:18 +00:00
newval = [ item . path UTF8String ] ;
2015-01-07 00:18:41 +00:00
}
else
{
2014-11-26 19:24:18 +00:00
if ( ! list . allowBlank )
2013-12-26 06:43:10 +00:00
return ;
2014-11-26 19:24:18 +00:00
}
2015-01-07 02:53:18 +00:00
2015-03-20 23:56:26 +00:00
setting_set _with _string _representation ( weakSelf . setting , newval ) ;
2014-11-26 19:24:18 +00:00
[ [ list navigationController ] popViewControllerAnimated : YES ] ;
2014-12-31 20:50:09 +00:00
weakSelf . action ( ) ;
2013-12-26 06:43:10 +00:00
2014-11-26 19:24:18 +00:00
[ weakSelf . parentTable reloadData ] ;
2013-12-26 06:43:10 +00:00
} ] ;
2014-11-11 17:11:48 +00:00
2013-12-24 19:03:43 +00:00
list . allowBlank = ( self . setting -> flags & SD_FLAG _ALLOW _EMPTY ) ;
list . forDirectory = ( self . setting -> flags & SD_FLAG _PATH _DIR ) ;
2013-11-22 14:30:02 +00:00
[ controller . navigationController pushViewController : list animated : YES ] ;
}
@ end
2013-12-04 00:46:30 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * 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
{
2014-07-08 16:23:30 +00:00
struct string_list * items ;
2014-01-06 01:12:04 +00:00
RAMenuItemEnumSetting __weak * weakSelf = self ;
2014-07-08 16:23:30 +00:00
items = ( struct string_list * ) string_split ( self . setting -> values , "|" ) ;
2013-12-26 21:00:29 +00:00
RunActionSheet ( self . setting -> short_description , items , self . parentTable ,
^ ( UIActionSheet * actionSheet , NSInteger buttonIndex )
{
2015-01-14 23:50:16 +00:00
if ( buttonIndex = = actionSheet . cancelButtonIndex )
return ;
2015-03-20 23:56:26 +00:00
setting_set _with _string _representation ( self . setting , [ [ actionSheet buttonTitleAtIndex : buttonIndex ] UTF8String ] ) ;
2015-01-14 23:50:16 +00:00
[ weakSelf . parentTable reloadData ] ;
2013-12-26 21:00:29 +00:00
} ) ;
2013-12-10 00:50:46 +00:00
string_list _free ( items ) ;
2013-12-04 00:46:30 +00:00
}
@ end
2013-11-22 14:30:02 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemBindSetting * /
/ * A menu item that displays and allows * /
/ * mapping of a keybinding . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ interface RAMenuItemBindSetting ( ) < UIAlertViewDelegate >
@ property ( nonatomic ) NSTimer * bindTimer ;
@ property ( nonatomic ) UIAlertView * alert ;
@ end
@ implementation RAMenuItemBindSetting
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2014-04-19 18:16:29 +00:00
self . alert = [ [ UIAlertView alloc ] initWithTitle : BOXSTRING ( "RetroArch" )
2013-12-12 19:49:18 +00:00
message : BOXSTRING ( self . setting -> short_description )
2013-11-22 14:30:02 +00:00
delegate : self
2014-04-19 18:16:29 +00:00
cancelButtonTitle : BOXSTRING ( "Cancel" )
otherButtonTitles : BOXSTRING ( "Clear Keyboard" ) , BOXSTRING ( "Clear Joystick" ) , BOXSTRING ( "Clear Axis" ) , nil ] ;
2013-12-06 01:33:31 +00:00
2013-11-22 14:30:02 +00:00
[ self . alert show ] ;
[ self . parentTable reloadData ] ;
self . bindTimer = [ NSTimer scheduledTimerWithTimeInterval : .1 f 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 ;
2013-12-06 01:33:31 +00:00
apple_input _reset _icade _buttons ( ) ;
2013-11-22 14:30:02 +00:00
}
- ( 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 ;
2014-10-20 17:33:50 +00:00
int32_t idx = 0 ;
2014-07-08 16:23:30 +00:00
if ( self . setting -> index )
2014-10-20 17:33:50 +00:00
idx = self . setting -> index - 1 ;
2013-11-22 14:30:02 +00:00
if ( ( value = apple_input _find _any _key ( ) ) )
2015-01-12 01:52:52 +00:00
BINDFOR ( * self . setting ) . key = input_keymaps _translate _keysym _to _rk ( value ) ;
2014-10-20 17:33:50 +00:00
else if ( ( value = apple_input _find _any _button ( idx ) ) >= 0 )
2013-11-22 14:30:02 +00:00
BINDFOR ( * self . setting ) . joykey = value ;
2014-10-20 17:33:50 +00:00
else if ( ( value = apple_input _find _any _axis ( idx ) ) )
2013-12-10 21:53:01 +00:00
BINDFOR ( * self . setting ) . joyaxis = ( value > 0 ) ? AXIS_POS ( value - 1 ) : AXIS_NEG ( abs ( value ) - 1 ) ;
2013-11-22 14:30:02 +00:00
else
return ;
[ self finishWithClickedButton : false ] ;
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMainMenu * /
/ * Menu object that is displayed immediately * /
/ * after startup . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMainMenu
- ( id ) init
{
if ( ( self = [ super initWithStyle : UITableViewStylePlain ] ) )
2014-04-19 18:16:29 +00:00
self . title = BOXSTRING ( "RetroArch" ) ;
2013-11-22 14:30:02 +00:00
return self ;
}
2013-12-17 22:38:43 +00:00
- ( void ) viewWillAppear : ( BOOL ) animated
{
[ self reloadData ] ;
}
- ( void ) willReloadData
2014-11-05 03:01:01 +00:00
{
2014-11-17 12:09:05 +00:00
size_t i , end ;
char title [ 256 ] , title_msg [ 256 ] ;
2015-01-14 23:50:16 +00:00
NSMutableArray * everything ;
RAMainMenu * __weak weakSelf ;
2015-03-21 04:42:49 +00:00
global_t * global = global_get _ptr ( ) ;
const char * core_name = global -> menu . info . library_name ;
const char * core_version = global -> menu . info . library_version ;
const char * dir = NULL ;
const char * label = NULL ;
unsigned menu_type = 0 ;
2015-03-21 22:56:42 +00:00
menu_handle _t * menu = menu_driver _get _ptr ( ) ;
2015-01-14 23:50:16 +00:00
2015-02-13 19:23:23 +00:00
if ( ! menu )
return ;
menu_list _get _last _stack ( menu -> menu_list ,
2014-11-05 03:01:01 +00:00
& dir , & label , & menu_type ) ;
get_title ( label , dir , menu_type , title , sizeof ( title ) ) ;
2015-01-14 23:50:16 +00:00
weakSelf = self ;
self . sections = [ NSMutableArray array ] ;
2014-11-05 03:01:01 +00:00
if ( ! core_name )
2015-03-21 04:42:49 +00:00
core_name = global -> system . info . library_name ;
2014-11-05 03:01:01 +00:00
if ( ! core_name )
core_name = "No Core" ;
if ( ! core_version )
2015-03-21 04:42:49 +00:00
core_version = global -> system . info . library_version ;
2014-11-05 03:01:01 +00:00
if ( ! core_version )
core_version = "" ;
snprintf ( title_msg , sizeof ( title_msg ) , "%s - %s %s" , PACKAGE_VERSION ,
core_name , core_version ) ;
self . title = BOXSTRING ( title_msg ) ;
2015-01-14 23:50:16 +00:00
everything = [ NSMutableArray array ] ;
2014-11-05 03:01:01 +00:00
[ everything addObject : BOXSTRING ( title ) ] ;
2015-02-13 19:23:23 +00:00
end = menu_list _get _size ( menu -> menu_list ) ;
2014-11-17 12:09:05 +00:00
2015-02-13 19:23:23 +00:00
for ( i = menu -> begin ; i < end ; i + + )
2014-11-17 12:09:05 +00:00
{
2015-01-14 23:50:16 +00:00
rarch_setting _t * setting ;
2015-01-17 04:47:33 +00:00
char type_str [ PATH_MAX _LENGTH ] , path_buf [ PATH_MAX _LENGTH ] ;
2015-01-14 23:50:16 +00:00
menu_file _list _cbs _t * cbs = NULL ;
2014-11-05 03:01:01 +00:00
const char * path = NULL , * entry_label = NULL ;
unsigned type = 0 , w = 0 ;
2015-02-13 19:23:23 +00:00
menu_list _get _at _offset ( menu -> menu_list -> selection_buf , i , & path ,
2014-11-05 03:01:01 +00:00
& entry_label , & type ) ;
2015-01-14 23:50:16 +00:00
setting =
2015-03-20 23:56:26 +00:00
( rarch_setting _t * ) setting_find _setting
2015-02-13 19:23:23 +00:00
( menu -> list_settings ,
menu -> menu_list -> selection_buf -> list [ i ] . label ) ;
2014-11-05 03:01:01 +00:00
2015-01-14 23:50:16 +00:00
cbs = ( menu_file _list _cbs _t * ) menu_list _get _actiondata _at _offset (
2015-02-13 19:23:23 +00:00
menu -> menu_list -> selection_buf , i ) ;
2014-11-05 16:19:41 +00:00
2015-02-05 10:09:06 +00:00
if ( cbs && cbs -> action_get _representation ) {
cbs -> action_get _representation
2015-02-13 19:23:23 +00:00
( menu -> menu_list -> selection_buf ,
2015-02-05 10:09:06 +00:00
& w , type , i , label ,
type_str , sizeof ( type_str ) ,
entry_label , path ,
path_buf , sizeof ( path_buf ) ) ;
}
2015-01-07 02:53:18 +00:00
if ( setting && setting -> type = = ST_ACTION &&
setting -> flags & SD_FLAG _BROWSER _ACTION &&
setting -> action_toggle &&
2015-01-14 23:50:16 +00:00
setting -> change_handler )
{
2015-01-07 02:53:18 +00:00
[ everything
addObject :
[ [ RAMenuItemPathSetting alloc ]
initWithSetting : setting
action : ^ { } ] ] ;
2015-01-14 23:50:16 +00:00
}
else if ( setting && ST_ACTION < setting -> type && setting -> type < ST_GROUP )
{
2015-01-07 02:53:18 +00:00
[ everything
addObject :
[ RAMenuItemGeneralSetting
2014-12-31 20:50:09 +00:00
itemForSetting : setting
action : ^ {
2015-02-15 03:08:46 +00:00
menu -> navigation . selection_ptr = i ;
2015-01-07 02:53:18 +00:00
if ( cbs && cbs -> action_ok )
cbs -> action_ok ( path , entry_label , type , i ) ;
} ] ] ;
2015-01-14 23:50:16 +00:00
}
else
{
2015-01-07 02:53:18 +00:00
[ everything
addObject :
[ RAMenuItemBasic
2014-11-05 16:31:20 +00:00
itemWithDescription : BOXSTRING ( path_buf )
action : ^ {
2015-02-15 03:08:46 +00:00
menu -> navigation . selection_ptr = i ;
2015-01-07 02:53:18 +00:00
if ( cbs && cbs -> action_ok )
cbs -> action_ok ( path , entry_label , type , i ) ;
else
{
if ( cbs && cbs -> action_start )
cbs -> action_start ( type , entry_label , MENU_ACTION _START ) ;
if ( cbs && cbs -> action_toggle )
2015-03-09 03:12:42 +00:00
cbs -> action_toggle ( type , entry_label , MENU_ACTION _RIGHT , true ) ;
2015-02-13 19:23:23 +00:00
menu_list _push _stack ( menu -> menu_list , "" ,
2015-01-07 02:53:18 +00:00
"info_screen" , 0 , i ) ;
}
[ weakSelf menuRefresh ] ;
[ weakSelf reloadData ] ;
} ] ] ;
2014-11-05 16:31:20 +00:00
}
2014-11-05 03:01:01 +00:00
}
[ self . sections addObject : everything ] ;
2014-11-05 16:19:41 +00:00
2015-02-13 19:23:23 +00:00
if ( menu_list _get _stack _size ( menu -> menu_list ) > 1 )
2014-11-05 16:50:56 +00:00
self . navigationItem . leftBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : BOXSTRING ( "Back" ) style : UIBarButtonItemStyleBordered target : weakSelf action : @ selector ( menuBack ) ] ;
2014-11-17 12:09:05 +00:00
else
2014-11-05 16:19:41 +00:00
self . navigationItem . leftBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : BOXSTRING ( "Resume" ) style : UIBarButtonItemStyleBordered target : [ RetroArch_iOS get ] action : @ selector ( showGameView ) ] ;
2014-11-11 17:11:48 +00:00
2015-02-13 19:23:23 +00:00
if ( menu -> message_contents [ 0 ] ! = ' \ 0 ' )
apple_display _alert ( menu -> message_contents , NULL ) ;
2014-11-05 16:19:41 +00:00
}
2014-11-17 12:09:05 +00:00
- ( void ) menuRefresh
{
2015-03-21 22:56:42 +00:00
menu_handle _t * menu = menu_driver _get _ptr ( ) ;
2015-02-13 19:23:23 +00:00
if ( ! menu )
return ;
if ( ! menu -> need_refresh )
2015-01-14 23:50:16 +00:00
return ;
2015-02-13 19:23:23 +00:00
menu_entries _deferred _push ( menu -> menu_list -> selection_buf ,
menu -> menu_list -> menu_stack ) ;
menu -> need_refresh = false ;
2014-11-05 16:19:41 +00:00
}
2014-11-17 12:09:05 +00:00
- ( void ) menuBack
{
2015-03-21 22:56:42 +00:00
menu_handle _t * menu = menu_driver _get _ptr ( ) ;
2015-02-13 19:23:23 +00:00
if ( ! menu )
return ;
2015-01-10 15:49:10 +00:00
menu_apply _deferred _settings ( ) ;
2015-02-13 19:23:23 +00:00
menu_list _pop _stack ( menu -> menu_list ) ;
2014-11-05 16:19:41 +00:00
[ self menuRefresh ] ;
[ self reloadData ] ;
2014-11-05 03:01:01 +00:00
}
2013-11-22 14:30:02 +00:00
@ end