4343#include "../menu_driver.h"
4444#include "../menu_screensaver.h"
4545
46+ #ifdef HAVE_COCOATOUCH
47+ #include "../../ui/drivers/cocoa/apple_platform.h"
48+ #endif
49+
4650#include "../../gfx/gfx_animation.h"
4751#include "../../gfx/gfx_thumbnail.h"
4852#include "../../msg_hash_lbl_str.h"
@@ -6785,6 +6789,10 @@ static void materialui_render_entry_touch_feedback(
67856789 }
67866790}
67876791
6792+ static bool materialui_search_filter_enabled (void );
6793+ static bool materialui_settings_search_filter_enabled (void );
6794+ static const char * materialui_search_filter_get_value (void );
6795+
67886796static void materialui_render_header (
67896797 materialui_handle_t * mui ,
67906798 const uintptr_t * tex_list ,
@@ -6808,7 +6816,10 @@ static void materialui_render_header(
68086816 bool show_search_icon =
68096817 (mui -> flags & MUI_FLAG_IS_PLAYLIST )
68106818 || (mui -> flags & MUI_FLAG_IS_FILE_LIST )
6811- || (mui -> flags & MUI_FLAG_IS_CORE_UPDATER_LIST );
6819+ || (mui -> flags & MUI_FLAG_IS_CORE_UPDATER_LIST )
6820+ || materialui_search_filter_enabled ();
6821+ bool show_search_field =
6822+ materialui_settings_search_filter_enabled ();
68126823 bool show_switch_view_icon =
68136824 (mui -> flags & MUI_FLAG_IS_PLAYLIST )
68146825 && (mui -> flags & MUI_FLAG_PRIMARY_THUMBNAIL_AVAILABLE );
@@ -7085,20 +7096,145 @@ static void materialui_render_header(
70857096 /* > Draw 'search' icon, if required */
70867097 if (show_search_icon )
70877098 {
7088- materialui_draw_icon (
7089- userdata , p_disp ,
7090- video_width ,
7091- video_height ,
7092- mui -> icon_size ,
7093- tex_list [MUI_TEXTURE_SEARCH ],
7094- (int )video_width - (int )mui -> icon_size - (int )mui -> nav_bar_layout_width ,
7095- (int )mui -> sys_bar_height ,
7096- 0 ,
7097- 1 ,
7098- mui -> colors .header_icon ,
7099- mymat );
7099+ int search_icon_x = (int )video_width - (int )mui -> icon_size
7100+ - (int )mui -> nav_bar_layout_width ;
7101+ bool draw_search_icon = true;
7102+
7103+ if (show_search_field )
7104+ {
7105+ const char * search_value = materialui_search_filter_get_value ();
7106+ bool search_has_value = !string_is_empty (search_value );
7107+ const char * search_label = search_has_value
7108+ ? search_value
7109+ : msg_hash_to_str (MENU_ENUM_LABEL_VALUE_SEARCH );
7110+ unsigned search_field_width = mui -> icon_size * 4 ;
7111+ unsigned search_field_height = mui -> title_bar_height ;
7112+ int search_field_x = (int )video_width - (int )search_field_width
7113+ - (int )mui -> nav_bar_layout_width ;
7114+ int search_field_y = (int )mui -> sys_bar_height + (int )(mui -> margin >> 2 );
7115+ unsigned search_text_width = search_field_width
7116+ - mui -> icon_size - mui -> margin ;
7117+ char search_label_buf [NAME_MAX_LENGTH ];
7118+
7119+ search_label_buf [0 ] = '\0' ;
7120+
7121+ if (mui -> title_bar_height > (mui -> margin >> 1 ))
7122+ search_field_height = mui -> title_bar_height - (mui -> margin >> 1 );
7123+
7124+ gfx_display_draw_quad (
7125+ p_disp ,
7126+ userdata ,
7127+ video_width ,
7128+ video_height ,
7129+ search_field_x ,
7130+ search_field_y ,
7131+ search_field_width ,
7132+ search_field_height ,
7133+ video_width ,
7134+ video_height ,
7135+ mui -> colors .sys_bar_background ,
7136+ NULL );
7137+
7138+ mui -> ticker .s = search_label_buf ;
7139+ mui -> ticker .len = (unsigned )(search_text_width / mui -> font_data .hint .glyph_width );
7140+ if (mui -> ticker .len < 1 )
7141+ mui -> ticker .len = 1 ;
7142+ mui -> ticker .str = search_label ;
7143+ mui -> ticker .selected = true;
7144+
7145+ gfx_animation_ticker (& mui -> ticker );
7146+
7147+ gfx_display_draw_text (mui -> font_data .hint .font ,
7148+ search_label_buf ,
7149+ search_field_x + (int )(mui -> margin >> 1 ),
7150+ (int )(mui -> sys_bar_height + (mui -> title_bar_height / 2.0f ) + mui -> font_data .hint .line_centre_offset ),
7151+ video_width , video_height , mui -> colors .header_text ,
7152+ TEXT_ALIGN_LEFT , 1.0f , false, 0.0f , false);
7153+
7154+ if (menu_input_dialog_get_display_kb ())
7155+ {
7156+ retro_time_t caret_time = menu_driver_get_current_time ();
7157+ if (((caret_time / 500000 ) % 2 ) == 0 )
7158+ {
7159+ int caret_x ;
7160+ unsigned caret_h = (unsigned )(mui -> font_data .hint .line_height * 0.8f );
7161+ int caret_y = (int )(mui -> sys_bar_height
7162+ + (mui -> title_bar_height / 2.0f ))
7163+ - (int )(caret_h / 2 );
7164+
7165+ if (search_has_value )
7166+ {
7167+ unsigned text_w = font_driver_get_message_width (
7168+ mui -> font_data .hint .font ,
7169+ search_label_buf ,
7170+ strlen (search_label_buf ),
7171+ 1.0f );
7172+ caret_x = search_field_x + (int )(mui -> margin >> 1 ) + (int )text_w ;
7173+ if (caret_x > search_field_x + (int )search_text_width )
7174+ caret_x = search_field_x + (int )search_text_width ;
7175+ }
7176+ else
7177+ caret_x = search_field_x + (int )(mui -> margin >> 1 );
7178+
7179+ gfx_display_draw_quad (
7180+ p_disp ,
7181+ userdata ,
7182+ video_width ,
7183+ video_height ,
7184+ caret_x ,
7185+ caret_y ,
7186+ 2 ,
7187+ caret_h ,
7188+ video_width ,
7189+ video_height ,
7190+ mui -> colors .header_icon ,
7191+ NULL );
7192+ }
7193+ }
71007194
7101- usable_title_bar_width -= mui -> icon_size ;
7195+ search_icon_x = search_field_x + (int )search_field_width
7196+ - (int )mui -> icon_size ;
7197+ usable_title_bar_width -= search_field_width ;
7198+
7199+ if (search_has_value )
7200+ {
7201+ unsigned clear_icon_size = (mui -> icon_size * 2 ) / 3 ;
7202+ int clear_icon_x = search_icon_x
7203+ + ((int )mui -> icon_size - (int )clear_icon_size ) / 2 ;
7204+ int clear_icon_y = (int )mui -> sys_bar_height
7205+ + ((int )mui -> title_bar_height - (int )clear_icon_size ) / 2 ;
7206+
7207+ materialui_draw_icon (
7208+ userdata , p_disp ,
7209+ video_width ,
7210+ video_height ,
7211+ clear_icon_size ,
7212+ tex_list [MUI_TEXTURE_CLOSE ],
7213+ clear_icon_x ,
7214+ clear_icon_y ,
7215+ 0 ,
7216+ 1 ,
7217+ mui -> colors .header_icon ,
7218+ mymat );
7219+ draw_search_icon = false;
7220+ }
7221+ }
7222+ else
7223+ usable_title_bar_width -= mui -> icon_size ;
7224+
7225+ if (draw_search_icon )
7226+ materialui_draw_icon (
7227+ userdata , p_disp ,
7228+ video_width ,
7229+ video_height ,
7230+ mui -> icon_size ,
7231+ tex_list [MUI_TEXTURE_SEARCH ],
7232+ search_icon_x ,
7233+ (int )mui -> sys_bar_height ,
7234+ 0 ,
7235+ 1 ,
7236+ mui -> colors .header_icon ,
7237+ mymat );
71027238
71037239 /* > Draw 'switch view' icon, if required
71047240 * Note: We can take a shortcut here because
@@ -7207,6 +7343,41 @@ static void materialui_render_header(
72077343 TEXT_ALIGN_LEFT , 1.0f , false, 0.0f , false);
72087344}
72097345
7346+ static bool materialui_search_filter_enabled (void )
7347+ {
7348+ const char * label = NULL ;
7349+ unsigned type = MENU_SETTINGS_NONE ;
7350+
7351+ menu_entries_get_last_stack (NULL , & label , & type , NULL , NULL );
7352+
7353+ return menu_driver_search_filter_enabled (label , type );
7354+ }
7355+
7356+ static bool materialui_settings_search_filter_enabled (void )
7357+ {
7358+ const char * label = NULL ;
7359+ unsigned type = MENU_SETTINGS_NONE ;
7360+
7361+ menu_entries_get_last_stack (NULL , & label , & type , NULL , NULL );
7362+
7363+ return !string_is_empty (label )
7364+ && string_is_equal (label , MENU_ENUM_LABEL_SETTINGS_TAB_STR )
7365+ && menu_driver_search_filter_enabled (label , type );
7366+ }
7367+
7368+ static const char * materialui_search_filter_get_value (void )
7369+ {
7370+ menu_search_terms_t * search_terms = menu_entries_search_get_terms ();
7371+
7372+ if (menu_input_dialog_get_display_kb ())
7373+ return menu_input_dialog_get_buffer ();
7374+
7375+ if (search_terms && search_terms -> size > 0 )
7376+ return search_terms -> terms [search_terms -> size - 1 ];
7377+
7378+ return "" ;
7379+ }
7380+
72107381/* Use separate functions for bottom/right navigation
72117382 * bars. This involves substantial code duplication, but if
72127383 * we try to handle this with a single function then
@@ -8380,6 +8551,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
83808551 font_flush (video_width , video_height , & mui -> font_data .title );
83818552 font_flush (video_width , video_height , & mui -> font_data .hint );
83828553
8554+ #ifndef HAVE_COCOATOUCH
83838555 /* Handle onscreen keyboard */
83848556 if (menu_input_dialog_get_display_kb ())
83858557 {
@@ -8432,6 +8604,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
84328604 * > Message box & osk only use list font */
84338605 font_flush (video_width , video_height , & mui -> font_data .list );
84348606 }
8607+ #endif
84358608
84368609 /* Draw message box */
84378610 if (* mui -> msgbox )
@@ -10493,6 +10666,10 @@ static int materialui_switch_tabs(materialui_handle_t *mui,
1049310666 if (!selection_buf )
1049410667 return -1 ;
1049510668
10669+ /* Dismiss keyboard if search was active on the current tab */
10670+ if (menu_input_dialog_get_display_kb ())
10671+ menu_input_dialog_end ();
10672+
1049610673 /* Perform pre-switch operations */
1049710674 stack_flushed = materialui_preswitch_tabs (mui , target_tab );
1049810675
@@ -11387,25 +11564,46 @@ static int materialui_pointer_up(void *userdata,
1138711564 /* Tap/press header: Menu back/cancel, or search/switch view */
1138811565 else if (y < header_height )
1138911566 {
11390- /* If this is a playlist, file list or core
11391- * updater list, enable search functionality */
11392- if ( (mui -> flags & MUI_FLAG_IS_PLAYLIST )
11567+ /* If this list supports search filtering,
11568+ * enable search functionality */
11569+ if ( materialui_search_filter_enabled ()
11570+ || (mui -> flags & MUI_FLAG_IS_PLAYLIST )
1139311571 || (mui -> flags & MUI_FLAG_IS_FILE_LIST )
1139411572 || (mui -> flags & MUI_FLAG_IS_CORE_UPDATER_LIST ))
1139511573 {
11574+ bool settings_search_enabled =
11575+ materialui_settings_search_filter_enabled ();
11576+ bool search_has_value = settings_search_enabled
11577+ && !string_is_empty (materialui_search_filter_get_value ());
1139611578 bool switch_view_enabled =
1139711579 (mui -> flags & MUI_FLAG_IS_PLAYLIST )
1139811580 && (mui -> flags & MUI_FLAG_PRIMARY_THUMBNAIL_AVAILABLE );
11581+ unsigned search_width = settings_search_enabled
11582+ ? mui -> icon_size * 4
11583+ : mui -> icon_size ;
1139911584 /* Note: We add a little extra padding to minimise
1140011585 * the risk of accidentally triggering a cancel */
1140111586 unsigned back_x_threshold =
1140211587 width -
11403- ((switch_view_enabled ? 3 : 2 ) * mui -> icon_size ) -
11404- mui -> nav_bar_layout_width ;
11588+ (switch_view_enabled ? (search_width + 2 * mui -> icon_size )
11589+ : (search_width + mui -> icon_size )) -
11590+ mui -> nav_bar_layout_width ;
1140511591
11406- /* Check if user has touched search icon */
11407- if (x > width - mui -> icon_size - mui -> nav_bar_layout_width )
11592+ /* Check if user has touched search affordance */
11593+ if (x > width - search_width - mui -> nav_bar_layout_width )
11594+ {
11595+ if ( settings_search_enabled
11596+ && search_has_value
11597+ && x > width - mui -> icon_size - mui -> nav_bar_layout_width )
11598+ {
11599+ menu_driver_search_filter_update ("" );
11600+ #ifdef HAVE_COCOATOUCH
11601+ ios_keyboard_set_text ("" );
11602+ #endif
11603+ return 0 ;
11604+ }
1140811605 return menu_input_dialog_start_search () ? 0 : -1 ;
11606+ }
1140911607 /* Check if user has touched switch view icon */
1141011608 else if (switch_view_enabled &&
1141111609 x > width - (2 * mui -> icon_size ) - mui -> nav_bar_layout_width )
0 commit comments