From 105fba6abe34e4edc04031300af1efe042181830 Mon Sep 17 00:00:00 2001 From: alfrix Date: Fri, 17 Aug 2018 19:38:18 -0300 Subject: [PATCH 01/17] XMB add an option to show desktop ui aka WIMP --- CHANGES.md | 4 +++- intl/msg_hash_es.h | 4 ++++ intl/msg_hash_us.h | 4 ++++ menu/cbs/menu_cbs_ok.c | 49 ++++++++++++++++++++++++----------------- menu/drivers/xmb.c | 11 ++++++++- menu/menu_displaylist.c | 22 ++++++++++-------- menu/menu_setting.c | 41 ++++++++++++++++++++-------------- msg_hash.h | 3 +++ 8 files changed, 91 insertions(+), 47 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0ddf01b29a..4adbdf50d1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,8 @@ - MENU/QT/WIMP: Initial grid view. - MENU/QT/WIMP: Drag&drop to add new playlist items, add option to add/edit/delete playlists. - MENU/QT/WIMP: Add menu option to update RetroArch (Windows only for now). +- MENU/XMB: Add new icons for the settings +- MENU/XMB: Add an option to show the desktop ui - METAL: Initial work-in-progress video driver for Metal. macOS-only right now, and currently requires macOS 10.13. - METAL: Supports XMB/MaterialUI, has a menu display driver. Has a font rendering driver. - METAL/SLANG: Slang shaders should be compatible with Metal video driver. @@ -91,7 +93,7 @@ video drivers that implement it (D3D8/9/10/11/12/GL) - MENU/RGUI: D3D8/D3D9: Hookup Menu Linear Filter - MENU/XMB: Disable XMB shadow icons by default for PowerPC and ARM for performance reasons. - MENU/XMB: Left/right thumbnails are now automatically scaled according to layout. -- MENU/XMB: Add Left Thumbnails (additional to the right). +- MENU/XMB: Add Left Thumbnails (additional to the right). - MENU/XMB: Fixed left/right tab regression. - MENU/XMB: Fix scaling of tall images that were cut on bottom previously. - MENU/XMB: Menu scale factor setting now changes texts length, image scaling and margins. diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 7341519c4b..624674b829 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -6417,6 +6417,10 @@ MSG_HASH( "
  • reiniciar RetroArch si actualizaste algo con el \"Actualizador en línea\"
  • \n" "Por último, el contenido debe coincidir las bases de datos existente de aquí. Si aún no funciona, considere enviar un reporte de error." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + "Mostrar intefaz de escritorio" + ) #endif MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index ae6b760e09..6cfc4fb91c 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3839,6 +3839,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, "
  • have \"Databases\" updated via Online Updater
  • \n" "
  • restart RetroArch if any of the above was just done
  • \n" "Finally, the content must match existing databases from here. If it is still not working, consider submitting a bug report.") +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + "Show Desktop UI" + ) #endif MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, "Don't show this again") diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 5991b04d77..6135befeed 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -88,6 +88,9 @@ enum ACTION_OK_SET_PATH_VIDEO_FILTER, ACTION_OK_SET_PATH_OVERLAY, ACTION_OK_SET_DIRECTORY, +#ifdef HAVE_QT + ACTION_OK_SHOW_WIMP, +#endif ACTION_OK_LOAD_CHEAT_FILE_APPEND }; @@ -820,11 +823,11 @@ int generic_action_ok_displaylist_push(const char *path, case ACTION_OK_DL_DEFERRED_CORE_LIST_SET: info.directory_ptr = idx; menu->scratchpad.unsigned_var = (unsigned)idx; - info_path = + info_path = settings->paths.directory_libretro; info_label = msg_hash_to_str( MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET); - info.enum_idx = + info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET; dl_type = DISPLAYLIST_GENERIC; break; @@ -1525,7 +1528,7 @@ static int action_ok_file_load(const char *path, if (filebrowser_get_type() == FILEBROWSER_SELECT_FILE_SUBSYSTEM) { - /* TODO/FIXME - this path is triggered when we try to load a + /* TODO/FIXME - this path is triggered when we try to load a * file from an archive while inside the load subsystem * action */ menu_handle_t *menu = NULL; @@ -1676,7 +1679,7 @@ static int action_ok_playlist_entry_collection(const char *path, core_info.inf->display_name, NULL, NULL); - } + } else strlcpy(new_core_path, core_path, sizeof(new_core_path)); @@ -1750,7 +1753,7 @@ static int action_ok_playlist_entry(const char *path, core_info.inf->display_name, NULL, NULL); - + } else if (!string_is_empty(core_path)) strlcpy(new_core_path, core_path, sizeof(new_core_path)); @@ -1813,9 +1816,9 @@ static int action_ok_playlist_entry_start_content(const char *path, if (!core_info_find(&core_info, new_core_path)) found_associated_core = false; - /* TODO: figure out if this should refer to + /* TODO: figure out if this should refer to * the inner or outer entry_path. */ - /* TODO: make sure there's only one entry_path + /* TODO: make sure there's only one entry_path * in this function. */ if (!found_associated_core) return action_ok_file_load_with_detect_core(entry_path, @@ -2111,7 +2114,7 @@ static void menu_input_st_string_cb_rename_entry(void *userdata, NULL); } - + menu_input_dialog_end(); } @@ -2719,7 +2722,7 @@ static int action_ok_cheat_add_bottom(const char *path, cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); msg[0] = '\0'; - strlcpy(msg, + strlcpy(msg, msg_hash_to_str(MSG_CHEAT_ADD_BOTTOM_SUCCESS), sizeof(msg)); msg[sizeof(msg) - 1] = 0; @@ -3167,7 +3170,6 @@ static void cb_generic_dir_download(void *task_data, void *user_data, const char *err) { file_transfer_t *transf = (file_transfer_t*)user_data; - if (transf) { generic_action_ok_network(transf->path, transf->path, 0, 0, 0, @@ -3521,15 +3523,17 @@ int (func_name)(const char *path, const char *label, unsigned type, size_t idx, return generic_action_ok_command(cmd); \ } -default_action_ok_cmd_func(action_ok_cheat_apply_changes,CMD_EVENT_CHEATS_APPLY) -default_action_ok_cmd_func(action_ok_quit, CMD_EVENT_QUIT) -default_action_ok_cmd_func(action_ok_save_new_config, CMD_EVENT_MENU_SAVE_CONFIG) -default_action_ok_cmd_func(action_ok_resume_content, CMD_EVENT_RESUME) -default_action_ok_cmd_func(action_ok_restart_content, CMD_EVENT_RESET) -default_action_ok_cmd_func(action_ok_screenshot, CMD_EVENT_TAKE_SCREENSHOT) -default_action_ok_cmd_func(action_ok_disk_cycle_tray_status, CMD_EVENT_DISK_EJECT_TOGGLE ) -default_action_ok_cmd_func(action_ok_shader_apply_changes, CMD_EVENT_SHADERS_APPLY_CHANGES ) - +default_action_ok_cmd_func(action_ok_cheat_apply_changes, CMD_EVENT_CHEATS_APPLY) +default_action_ok_cmd_func(action_ok_quit, CMD_EVENT_QUIT) +default_action_ok_cmd_func(action_ok_save_new_config, CMD_EVENT_MENU_SAVE_CONFIG) +default_action_ok_cmd_func(action_ok_resume_content, CMD_EVENT_RESUME) +default_action_ok_cmd_func(action_ok_restart_content, CMD_EVENT_RESET) +default_action_ok_cmd_func(action_ok_screenshot, CMD_EVENT_TAKE_SCREENSHOT) +default_action_ok_cmd_func(action_ok_disk_cycle_tray_status, CMD_EVENT_DISK_EJECT_TOGGLE) +default_action_ok_cmd_func(action_ok_shader_apply_changes, CMD_EVENT_SHADERS_APPLY_CHANGES) +#ifdef HAVE_QT +default_action_ok_cmd_func(action_ok_show_wimp, CMD_EVENT_UI_COMPANION_TOGGLE) +#endif static int action_ok_reset_core_association(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) @@ -3944,7 +3948,7 @@ void netplay_refresh_rooms_menu(file_list_t *list) char country[PATH_MAX_LENGTH] = {0}; if (*netplay_room_list[i].country) - string_add_between_pairs(country, netplay_room_list[i].country, + string_add_between_pairs(country, netplay_room_list[i].country, sizeof(country)); /* Uncomment this to debug mismatched room parameters*/ @@ -4739,6 +4743,11 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_XMB_MAIN_MENU_ENABLE_SETTINGS: BIND_ACTION_OK(cbs, action_ok_enable_settings); break; +#ifdef HAVE_QT + case MENU_ENUM_LABEL_SHOW_WIMP: + BIND_ACTION_OK(cbs, action_ok_show_wimp); + break; +#endif case MENU_ENUM_LABEL_QUIT_RETROARCH: BIND_ACTION_OK(cbs, action_ok_quit); break; diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 6584de207f..ceccd0aa8e 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2359,6 +2359,9 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, return xmb->textures.list[XMB_TEXTURE_RECORD]; case MENU_ENUM_LABEL_ONSCREEN_DISPLAY_SETTINGS: return xmb->textures.list[XMB_TEXTURE_OSD]; +#ifdef HAVE_QT + case MENU_ENUM_LABEL_SHOW_WIMP: +#endif case MENU_ENUM_LABEL_USER_INTERFACE_SETTINGS: return xmb->textures.list[XMB_TEXTURE_UI]; case MENU_ENUM_LABEL_POWER_MANAGEMENT_SETTINGS: @@ -5263,6 +5266,13 @@ static int xmb_list_push(void *data, void *userdata, entry.enum_idx = MENU_ENUM_LABEL_ADD_CONTENT_LIST; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); +#ifdef HAVE_QT + if (settings->bools.desktop_menu_enable) + { + entry.enum_idx = MENU_ENUM_LABEL_SHOW_WIMP; + menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); + } +#endif #if defined(HAVE_NETWORKING) { settings_t *settings = config_get_ptr(); @@ -5307,7 +5317,6 @@ static int xmb_list_push(void *data, void *userdata, entry.enum_idx = MENU_ENUM_LABEL_HELP_LIST; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); } - #if !defined(IOS) if (settings->bools.menu_show_quit_retroarch) { diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 962eedebbf..1801b78e16 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4857,7 +4857,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) string_is_equal(core_path, path_get(RARCH_PATH_CORE))) { strlcpy(new_path_entry, core_path, sizeof(new_path_entry)); - snprintf(new_entry, sizeof(new_entry), "%s (%s)", + snprintf(new_entry, sizeof(new_entry), "%s (%s)", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE), core_name); new_lbl_entry[0] = '\0'; @@ -5538,7 +5538,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_HELP, PARSE_ONLY_BOOL, false); - +#ifdef HAVE_QT + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_SHOW_WIMP, + PARSE_ONLY_UINT, false); +#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH, PARSE_ONLY_BOOL, false); @@ -6291,11 +6295,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SCREEN_RESOLUTION, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, PARSE_ONLY_UINT, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_PAL60_ENABLE, @@ -6908,7 +6912,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) { settings_t *settings = config_get_ptr(); - if (settings->bools.quick_menu_show_save_core_overrides + if (settings->bools.quick_menu_show_save_core_overrides && !settings->bools.kiosk_mode_enable) { menu_entries_append_enum(info->list, @@ -6919,7 +6923,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) count++; } - if (settings->bools.quick_menu_show_save_content_dir_overrides + if (settings->bools.quick_menu_show_save_content_dir_overrides && !settings->bools.kiosk_mode_enable) { menu_entries_append_enum(info->list, @@ -6930,7 +6934,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) count++; } - if (settings->bools.quick_menu_show_save_game_overrides + if (settings->bools.quick_menu_show_save_game_overrides && !settings->bools.kiosk_mode_enable) { menu_entries_append_enum(info->list, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 4fb276be24..40f65a60a2 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2468,7 +2468,16 @@ static bool setting_append_list( &subgroup_info, parent_group); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); - +#ifdef HAVE_QT + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_SHOW_WIMP, + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + &group_info, + &subgroup_info, + parent_group); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_UI_COMPANION_TOGGLE); +#endif #if !defined(IOS) /* Apple rejects iOS apps that let you forcibly quit them. */ CONFIG_ACTION( @@ -3497,7 +3506,7 @@ static bool setting_append_list( case SETTINGS_LIST_CHEAT_SEARCH: if ( ! cheat_manager_state.cheats ) break ; - + START_GROUP(list, list_info, &group_info, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS), parent_group); parent_group = msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS); @@ -3764,9 +3773,9 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_NONE); - - - CONFIG_BOOL( + + + CONFIG_BOOL( list, list_info, &settings->bools.crt_switch_resolution, MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, @@ -3780,18 +3789,18 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_ADVANCED - ); - + ); + CONFIG_UINT( - list, list_info, - &settings->uints.crt_switch_resolution_super, - MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, - MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, - crt_switch_resolution_super, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, + list, list_info, + &settings->uints.crt_switch_resolution_super, + MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, + crt_switch_resolution_super, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); diff --git a/msg_hash.h b/msg_hash.h index 8857983952..c00d899ca2 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1496,6 +1496,9 @@ enum msg_hash_enums MENU_LABEL(BUILDBOT_ASSETS_URL), MENU_LABEL(CORE_SET_SUPPORTS_NO_CONTENT_ENABLE), MENU_LABEL(CLOSE_CONTENT), +#ifdef HAVE_QT + MENU_LABEL(SHOW_WIMP), +#endif MENU_LABEL(QUIT_RETROARCH), MENU_LABEL(SHUTDOWN), MENU_LABEL(REBOOT), From d2e4832ebe2cbbc8aa9dba887e05d9d27d76bf16 Mon Sep 17 00:00:00 2001 From: alfrix Date: Fri, 17 Aug 2018 20:43:08 -0300 Subject: [PATCH 02/17] QT fix focus (bparker) --- ui/drivers/ui_qt.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index 067cf7b661..d410aca90f 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -607,6 +607,8 @@ static void ui_companion_qt_toggle(void *data, bool force) #endif if (settings->bools.ui_companion_toggle || force) { + win_handle->qtWindow->activateWindow(); + win_handle->qtWindow->raise(); video_driver_show_mouse(); win_handle->qtWindow->show(); From b915fd095de639e85f047fa22fb5458955b24906 Mon Sep 17 00:00:00 2001 From: alfrix Date: Sat, 18 Aug 2018 15:14:41 -0300 Subject: [PATCH 03/17] Fix focus for windows platforms (Tatsuya) --- ui/drivers/ui_qt.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index d410aca90f..e17954bf5a 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -607,6 +607,9 @@ static void ui_companion_qt_toggle(void *data, bool force) #endif if (settings->bools.ui_companion_toggle || force) { + if (settings->bools.video_fullscreen) + command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL); + win_handle->qtWindow->activateWindow(); win_handle->qtWindow->raise(); video_driver_show_mouse(); From 70d045818083762220e3f18caf474b11ece51655 Mon Sep 17 00:00:00 2001 From: alfrix Date: Sat, 18 Aug 2018 17:43:29 -0300 Subject: [PATCH 04/17] Add sublabel for 'Show desktop ui' --- intl/msg_hash_es.h | 4 ++++ intl/msg_hash_us.h | 4 ++++ menu/cbs/menu_cbs_sublabel.c | 9 ++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 624674b829..aa35a784ed 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -6421,6 +6421,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_SHOW_WIMP, "Mostrar intefaz de escritorio" ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_WIMP, + "Abre la interfaz de escritorio si fue cerrada" + ) #endif MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 6cfc4fb91c..ddc55482b6 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3843,6 +3843,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_SHOW_WIMP, "Show Desktop UI" ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_WIMP, + "Open the desktop UI if it was closed" + ) #endif MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, "Don't show this again") diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index d9fea4d60f..25ef29af8a 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -461,7 +461,9 @@ default_sublabel_macro(action_bind_sublabel_midi_output, default_sublabel_macro(action_bind_sublabel_midi_volume, MENU_ENUM_SUBLABEL_MIDI_VOLUME) default_sublabel_macro(action_bind_sublabel_onscreen_overlay_settings_list, MENU_ENUM_SUBLABEL_ONSCREEN_OVERLAY_SETTINGS) default_sublabel_macro(action_bind_sublabel_onscreen_notifications_settings_list, MENU_ENUM_SUBLABEL_ONSCREEN_NOTIFICATIONS_SETTINGS) - +#ifdef HAVE_QT +default_sublabel_macro(action_bind_sublabel_show_wimp, MENU_ENUM_SUBLABEL_SHOW_WIMP) +#endif static int action_bind_sublabel_cheevos_entry( file_list_t *list, @@ -1942,6 +1944,11 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_onscreen_notifications_settings_list); break; +#ifdef HAVE_QT + case MENU_ENUM_LABEL_SHOW_WIMP: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_show_wimp); + break; +#endif default: case MSG_UNKNOWN: return -1; From e0d99d7da234587a6fb45e683e381feb6c37ca80 Mon Sep 17 00:00:00 2001 From: alfrix Date: Sat, 18 Aug 2018 22:22:40 -0300 Subject: [PATCH 05/17] Change UI to menu --- intl/msg_hash_es.h | 4 ++-- intl/msg_hash_us.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index aa35a784ed..d90679a1cf 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -6419,11 +6419,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SHOW_WIMP, - "Mostrar intefaz de escritorio" + "Mostrar el menú de escritorio" ) MSG_HASH( MENU_ENUM_SUBLABEL_SHOW_WIMP, - "Abre la interfaz de escritorio si fue cerrada" + "Abre el menú de escritorio si fue cerrado" ) #endif MSG_HASH( diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index ddc55482b6..6413c47bbb 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3841,11 +3841,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, "Finally, the content must match existing databases from here. If it is still not working, consider submitting a bug report.") MSG_HASH( MENU_ENUM_LABEL_VALUE_SHOW_WIMP, - "Show Desktop UI" + "Show Desktop Menu" ) MSG_HASH( MENU_ENUM_SUBLABEL_SHOW_WIMP, - "Open the desktop UI if it was closed" + "Opens the desktop menu if it was closed" ) #endif MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, From b0146abd11609e142ff952be399342781dd48d4c Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sat, 18 Aug 2018 23:08:55 -0400 Subject: [PATCH 06/17] add fullpath and use_thread parameters to take_screenshot() --- cheevos/cheevos.c | 4 +- command.c | 2 +- tasks/task_save.c | 2 +- tasks/task_screenshot.c | 135 +++++++++++++++++++++++----------------- tasks/tasks_internal.h | 2 +- 5 files changed, 84 insertions(+), 61 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index d65ed9ec32..0e21e3687a 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1674,7 +1674,7 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) shotname[sizeof(shotname) - 1] = '\0'; if (take_screenshot(shotname, true, - video_driver_cached_frame_has_valid_framebuffer())) + video_driver_cached_frame_has_valid_framebuffer(), false, true)) CHEEVOS_LOG("[CHEEVOS]: got a screenshot for cheevo %u\n", cheevo->id); else CHEEVOS_LOG("[CHEEVOS]: failed to get screenshot for cheevo %u\n", cheevo->id); @@ -2080,7 +2080,7 @@ void cheevos_populate_menu(void *data) cheevo_t *cheevo = cheevos_locals.core.cheevos; end = cheevo + cheevos_locals.core.count; - if(settings->bools.cheevos_enable && settings->bools.cheevos_hardcore_mode_enable + if(settings->bools.cheevos_enable && settings->bools.cheevos_hardcore_mode_enable && cheevos_loaded) { if (!cheevos_hardcore_paused) diff --git a/command.c b/command.c index 55b2cf94e6..7cb6a22d37 100644 --- a/command.c +++ b/command.c @@ -1954,7 +1954,7 @@ bool command_event(enum event_command cmd, void *data) break; case CMD_EVENT_TAKE_SCREENSHOT: if (!take_screenshot(path_get(RARCH_PATH_BASENAME), false, - video_driver_cached_frame_has_valid_framebuffer())) + video_driver_cached_frame_has_valid_framebuffer(), false, true)) return false; break; case CMD_EVENT_UNLOAD_CORE: diff --git a/tasks/task_save.c b/tasks/task_save.c index 556da1fde0..1b5d93be4e 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -1010,7 +1010,7 @@ static void save_state_cb(void *task_data, char *path = strdup(state->path); if (state->thumbnail_enable) - take_screenshot(path, true, state->has_valid_framebuffer); + take_screenshot(path, true, state->has_valid_framebuffer, false, true); free(path); } diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index 42cc5d8d72..80c3b90cee 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -70,39 +70,17 @@ struct screenshot_task_state uint8_t *out_buffer; const void *frame; char filename[PATH_MAX_LENGTH]; - char shotname[256]; void *userbuf; struct scaler_ctx scaler; }; -/** - * task_screenshot_handler: - * @task : the task being worked on - * - * Saves a screenshot to disk. - **/ -static void task_screenshot_handler(retro_task_t *task) +static bool screenshot_dump_direct(screenshot_task_state_t *state) { + struct scaler_ctx *scaler = (struct scaler_ctx*)&state->scaler; + bool ret = false; #ifdef HAVE_RBMP enum rbmp_source_type bmp_type = RBMP_SOURCE_TYPE_DONT_CARE; -#endif - screenshot_task_state_t *state = (screenshot_task_state_t*)task->state; - struct scaler_ctx *scaler = (struct scaler_ctx*)&state->scaler; - bool ret = false; - - if (task_get_progress(task) == 100) - { - task_set_finished(task, true); - - if (state->userbuf) - free(state->userbuf); - - free(state); - return; - } - -#ifdef HAVE_RBMP - (void)bmp_type; + (void)bmp_type; #endif #if defined(HAVE_RPNG) @@ -146,6 +124,33 @@ static void task_screenshot_handler(retro_task_t *task) bmp_type); #endif + return ret; +} + +/** + * task_screenshot_handler: + * @task : the task being worked on + * + * Saves a screenshot to disk. + **/ +static void task_screenshot_handler(retro_task_t *task) +{ + screenshot_task_state_t *state = (screenshot_task_state_t*)task->state; + bool ret = false; + + if (task_get_progress(task) == 100) + { + task_set_finished(task, true); + + if (state->userbuf) + free(state->userbuf); + + free(state); + return; + } + + ret = screenshot_dump_direct(state); + #ifdef HAVE_IMAGEVIEWER if ( ret && !state->silence && @@ -178,7 +183,9 @@ static bool screenshot_dump( int pitch, bool bgr24, void *userbuf, bool savestate, bool is_idle, - bool is_paused) + bool is_paused, + bool fullpath, + bool use_thread) { char screenshot_path[PATH_MAX_LENGTH]; uint8_t *buf = NULL; @@ -187,14 +194,22 @@ static bool screenshot_dump( screenshot_task_state_t *state = (screenshot_task_state_t*) calloc(1, sizeof(*state)); const char *screenshot_dir = settings->paths.directory_screenshot; + char shotname[256]; + shotname[0] = '\0'; screenshot_path[0] = '\0'; - if (string_is_empty(screenshot_dir) || settings->bools.screenshots_in_content_dir) + /* If fullpath is true, name_base already contains a static path + filename to save the screenshot to. */ + if (fullpath) + strlcpy(state->filename, name_base, sizeof(state->filename)); + else { - fill_pathname_basedir(screenshot_path, name_base, - sizeof(screenshot_path)); - screenshot_dir = screenshot_path; + if (string_is_empty(screenshot_dir) || settings->bools.screenshots_in_content_dir) + { + fill_pathname_basedir(screenshot_path, name_base, + sizeof(screenshot_path)); + screenshot_dir = screenshot_path; + } } state->is_idle = is_idle; @@ -209,20 +224,23 @@ static bool screenshot_dump( state->history_list_enable = settings->bools.history_list_enable; state->pixel_format_type = video_driver_get_pixel_format(); - if (savestate) - snprintf(state->filename, - sizeof(state->filename), "%s.png", name_base); - else + if (!fullpath) { - if (settings->bools.auto_screenshot_filename) - fill_str_dated_filename(state->shotname, path_basename(name_base), - IMG_EXT, sizeof(state->shotname)); + if (savestate) + snprintf(state->filename, + sizeof(state->filename), "%s.png", name_base); else - snprintf(state->shotname, sizeof(state->shotname), - "%s.png", path_basename(name_base)); + { + if (settings->bools.auto_screenshot_filename) + fill_str_dated_filename(shotname, path_basename(name_base), + IMG_EXT, sizeof(shotname)); + else + snprintf(shotname, sizeof(shotname), + "%s.png", path_basename(name_base)); - fill_pathname_join(state->filename, screenshot_dir, - state->shotname, sizeof(state->filename)); + fill_pathname_join(state->filename, screenshot_dir, + shotname, sizeof(state->filename)); + } } #if defined(HAVE_RPNG) @@ -241,17 +259,22 @@ static bool screenshot_dump( task->state = state; task->handler = task_screenshot_handler; - if (!savestate) - task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); + if (use_thread) + return screenshot_dump_direct(state); + else + { + if (!savestate) + task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); - task_queue_push(task); + task_queue_push(task); + } return true; } #if !defined(VITA) static bool take_screenshot_viewport(const char *name_base, bool savestate, - bool is_idle, bool is_paused) + bool is_idle, bool is_paused, bool fullpath, bool use_thread) { struct video_viewport vp; uint8_t *buffer = NULL; @@ -280,7 +303,7 @@ static bool take_screenshot_viewport(const char *name_base, bool savestate, /* Data read from viewport is in bottom-up order, suitable for BMP. */ if (!screenshot_dump(name_base, buffer, vp.width, vp.height, - vp.width * 3, true, buffer, savestate, is_idle, is_paused)) + vp.width * 3, true, buffer, savestate, is_idle, is_paused, fullpath, use_thread)) goto error; return true; @@ -293,7 +316,7 @@ error: #endif static bool take_screenshot_raw(const char *name_base, void *userbuf, - bool savestate, bool is_idle, bool is_paused) + bool savestate, bool is_idle, bool is_paused, bool fullpath, bool use_thread) { size_t pitch; unsigned width, height; @@ -306,14 +329,14 @@ static bool take_screenshot_raw(const char *name_base, void *userbuf, */ if (!screenshot_dump(name_base, (const uint8_t*)data + (height - 1) * pitch, - width, height, (int)(-pitch), false, userbuf, savestate, is_idle, is_paused)) + width, height, (int)(-pitch), false, userbuf, savestate, is_idle, is_paused, fullpath, use_thread)) return false; return true; } static bool take_screenshot_choice(const char *name_base, bool savestate, - bool is_paused, bool is_idle, bool has_valid_framebuffer) + bool is_paused, bool is_idle, bool has_valid_framebuffer, bool fullpath, bool use_thread) { size_t old_pitch; unsigned old_width, old_height; @@ -335,14 +358,14 @@ static bool take_screenshot_choice(const char *name_base, bool savestate, if (!is_idle) video_driver_cached_frame(); #if defined(VITA) - return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused); + return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused, fullpath, use_thread); #else - return take_screenshot_viewport(name_base, savestate, is_idle, is_paused); + return take_screenshot_viewport(name_base, savestate, is_idle, is_paused, fullpath, use_thread); #endif } if (!has_valid_framebuffer) - return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused); + return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused, fullpath, use_thread); if (!video_driver_supports_read_frame_raw()) return false; @@ -359,14 +382,14 @@ static bool take_screenshot_choice(const char *name_base, bool savestate, if (frame_data) { video_driver_set_cached_frame_ptr(frame_data); - if (take_screenshot_raw(name_base, frame_data, savestate, is_idle, is_paused)) + if (take_screenshot_raw(name_base, frame_data, savestate, is_idle, is_paused, fullpath, use_thread)) ret = true; } return ret; } -bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebuffer) +bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebuffer, bool fullpath, bool use_thread) { bool is_paused = false; bool is_idle = false; @@ -377,7 +400,7 @@ bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebu runloop_get_status(&is_paused, &is_idle, &is_slowmotion, &is_perfcnt_enable); ret = take_screenshot_choice(name_base, silence, is_paused, is_idle, - has_valid_framebuffer); + has_valid_framebuffer, fullpath, use_thread); if (is_paused && !is_idle) video_driver_cached_frame(); diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index fe9bd41122..a2632e4ac8 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -223,7 +223,7 @@ void task_file_load_handler(retro_task_t *task); bool task_audio_mixer_load_handler(retro_task_t *task); -bool take_screenshot(const char *path, bool silence, bool has_valid_framebuffer); +bool take_screenshot(const char *path, bool silence, bool has_valid_framebuffer, bool fullpath, bool use_thread); bool event_load_save_files(void); From b1dde87ce59d8bbbc045b6983e28ae386f362bad Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sat, 18 Aug 2018 23:09:40 -0400 Subject: [PATCH 07/17] add --max-frames-ss and --max-frames-ss-path parameters for taking a screenshot after max_frames is reached --- retroarch.c | 246 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 145 insertions(+), 101 deletions(-) diff --git a/retroarch.c b/retroarch.c index de1298a024..42c8fa24b6 100644 --- a/retroarch.c +++ b/retroarch.c @@ -165,7 +165,9 @@ enum RA_OPT_VERSION, RA_OPT_EOF_EXIT, RA_OPT_LOG_FILE, - RA_OPT_MAX_FRAMES + RA_OPT_MAX_FRAMES, + RA_OPT_MAX_FRAMES_SCREENSHOT, + RA_OPT_MAX_FRAMES_SCREENSHOT_PATH }; enum runloop_state @@ -187,86 +189,88 @@ typedef struct runloop_ctx_msg_info } runloop_ctx_msg_info_t; static jmp_buf error_sjlj_context; -static enum rarch_core_type current_core_type = CORE_TYPE_PLAIN; -static enum rarch_core_type explicit_current_core_type = CORE_TYPE_PLAIN; -static char error_string[255] = {0}; +static enum rarch_core_type current_core_type = CORE_TYPE_PLAIN; +static enum rarch_core_type explicit_current_core_type = CORE_TYPE_PLAIN; +static char error_string[255] = {0}; static char runtime_shader_preset[255] = {0}; #ifdef HAVE_THREAD_STORAGE static sthread_tls_t rarch_tls; -const void *MAGIC_POINTER = (void*)(uintptr_t)0x0DEFACED; +const void *MAGIC_POINTER = (void*)(uintptr_t)0x0DEFACED; #endif static retro_bits_t has_set_libretro_device; -static bool has_set_core = false; -static bool has_set_username = false; +static bool has_set_core = false; +static bool has_set_username = false; #ifdef HAVE_DISCORD -static bool discord_is_inited = false; +static bool discord_is_inited = false; #endif -static bool rarch_is_inited = false; -static bool rarch_error_on_init = false; -static bool rarch_block_config_read = false; -static bool rarch_force_fullscreen = false; -static bool has_set_verbosity = false; -static bool has_set_libretro = false; -static bool has_set_libretro_directory = false; -static bool has_set_save_path = false; -static bool has_set_state_path = false; -static bool has_set_netplay_mode = false; -static bool has_set_netplay_ip_address = false; -static bool has_set_netplay_ip_port = false; -static bool has_set_netplay_stateless_mode = false; -static bool has_set_netplay_check_frames = false; -static bool has_set_ups_pref = false; -static bool has_set_bps_pref = false; -static bool has_set_ips_pref = false; +static bool rarch_is_inited = false; +static bool rarch_error_on_init = false; +static bool rarch_block_config_read = false; +static bool rarch_force_fullscreen = false; +static bool has_set_verbosity = false; +static bool has_set_libretro = false; +static bool has_set_libretro_directory = false; +static bool has_set_save_path = false; +static bool has_set_state_path = false; +static bool has_set_netplay_mode = false; +static bool has_set_netplay_ip_address = false; +static bool has_set_netplay_ip_port = false; +static bool has_set_netplay_stateless_mode = false; +static bool has_set_netplay_check_frames = false; +static bool has_set_ups_pref = false; +static bool has_set_bps_pref = false; +static bool has_set_ips_pref = false; -static bool rarch_is_sram_load_disabled = false; -static bool rarch_is_sram_save_disabled = false; -static bool rarch_use_sram = false; -static bool rarch_ups_pref = false; -static bool rarch_bps_pref = false; -static bool rarch_ips_pref = false; -static bool rarch_patch_blocked = false; -static bool rarch_first_start = true; +static bool rarch_is_sram_load_disabled = false; +static bool rarch_is_sram_save_disabled = false; +static bool rarch_use_sram = false; +static bool rarch_ups_pref = false; +static bool rarch_bps_pref = false; +static bool rarch_ips_pref = false; +static bool rarch_patch_blocked = false; +static bool rarch_first_start = true; -static bool runloop_force_nonblock = false; -static bool runloop_paused = false; -static bool runloop_idle = false; -static bool runloop_exec = false; -static bool runloop_slowmotion = false; -static bool runloop_fastmotion = false; -static bool runloop_shutdown_initiated = false; -static bool runloop_core_shutdown_initiated = false; -static bool runloop_perfcnt_enable = false; -static bool runloop_overrides_active = false; -static bool runloop_remaps_core_active = false; -static bool runloop_remaps_game_active = false; -static bool runloop_remaps_content_dir_active = false; -static bool runloop_game_options_active = false; -static bool runloop_missing_bios = false; -static bool runloop_autosave = false; +static bool runloop_force_nonblock = false; +static bool runloop_paused = false; +static bool runloop_idle = false; +static bool runloop_exec = false; +static bool runloop_slowmotion = false; +static bool runloop_fastmotion = false; +static bool runloop_shutdown_initiated = false; +static bool runloop_core_shutdown_initiated = false; +static bool runloop_perfcnt_enable = false; +static bool runloop_overrides_active = false; +static bool runloop_remaps_core_active = false; +static bool runloop_remaps_game_active = false; +static bool runloop_remaps_content_dir_active = false; +static bool runloop_game_options_active = false; +static bool runloop_missing_bios = false; +static bool runloop_autosave = false; #ifdef HAVE_DYNAMIC -static bool core_set_on_cmdline = false; +static bool core_set_on_cmdline = false; #endif static rarch_system_info_t runloop_system; static struct retro_frame_time_callback runloop_frame_time; -static retro_keyboard_event_t runloop_key_event = NULL; -static retro_keyboard_event_t runloop_frontend_key_event = NULL; -static core_option_manager_t *runloop_core_options = NULL; +static retro_keyboard_event_t runloop_key_event = NULL; +static retro_keyboard_event_t runloop_frontend_key_event = NULL; +static core_option_manager_t *runloop_core_options = NULL; #ifdef HAVE_THREADS -static slock_t *_runloop_msg_queue_lock = NULL; +static slock_t *_runloop_msg_queue_lock = NULL; #endif -static msg_queue_t *runloop_msg_queue = NULL; +static msg_queue_t *runloop_msg_queue = NULL; -static unsigned runloop_pending_windowed_scale = 0; -static unsigned runloop_max_frames = 0; -static unsigned fastforward_after_frames = 0; +static unsigned runloop_pending_windowed_scale = 0; +static unsigned runloop_max_frames = 0; +static bool runloop_max_frames_screenshot = false; +static char runloop_max_frames_screenshot_path[PATH_MAX_LENGTH] = {0}; +static unsigned fastforward_after_frames = 0; -static retro_usec_t runloop_frame_time_last = 0; -static retro_time_t frame_limit_minimum_time = 0.0; -static retro_time_t frame_limit_last_time = 0.0; +static retro_usec_t runloop_frame_time_last = 0; +static retro_time_t frame_limit_minimum_time = 0.0; +static retro_time_t frame_limit_last_time = 0.0; extern bool input_driver_flushing_input; @@ -593,7 +597,11 @@ static void retroarch_print_help(const char *arg0) "Not relevant for all platforms."); puts(" --max-frames=NUMBER\n" " Runs for the specified number of frames, " - "then exits.\n"); + "then exits."); + puts(" --max-frames-ss\n" + " Takes a screenshot at the end of max-frames."); + puts(" --max-frames-ss-path=FILE\n" + " Path to save the screenshot to at the end of max-frames.\n"); } #define FFMPEG_RECORD_ARG "r:" @@ -629,48 +637,50 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) const struct option opts[] = { #ifdef HAVE_DYNAMIC - { "libretro", 1, NULL, 'L' }, + { "libretro", 1, NULL, 'L' }, #endif - { "menu", 0, NULL, RA_OPT_MENU }, - { "help", 0, NULL, 'h' }, - { "save", 1, NULL, 's' }, - { "fullscreen", 0, NULL, 'f' }, - { "record", 1, NULL, 'r' }, - { "recordconfig", 1, NULL, RA_OPT_RECORDCONFIG }, - { "size", 1, NULL, RA_OPT_SIZE }, - { "verbose", 0, NULL, 'v' }, - { "config", 1, NULL, 'c' }, - { "appendconfig", 1, NULL, RA_OPT_APPENDCONFIG }, - { "nodevice", 1, NULL, 'N' }, - { "dualanalog", 1, NULL, 'A' }, - { "device", 1, NULL, 'd' }, - { "savestate", 1, NULL, 'S' }, - { "bsvplay", 1, NULL, 'P' }, - { "bsvrecord", 1, NULL, 'R' }, - { "sram-mode", 1, NULL, 'M' }, + { "menu", 0, NULL, RA_OPT_MENU }, + { "help", 0, NULL, 'h' }, + { "save", 1, NULL, 's' }, + { "fullscreen", 0, NULL, 'f' }, + { "record", 1, NULL, 'r' }, + { "recordconfig", 1, NULL, RA_OPT_RECORDCONFIG }, + { "size", 1, NULL, RA_OPT_SIZE }, + { "verbose", 0, NULL, 'v' }, + { "config", 1, NULL, 'c' }, + { "appendconfig", 1, NULL, RA_OPT_APPENDCONFIG }, + { "nodevice", 1, NULL, 'N' }, + { "dualanalog", 1, NULL, 'A' }, + { "device", 1, NULL, 'd' }, + { "savestate", 1, NULL, 'S' }, + { "bsvplay", 1, NULL, 'P' }, + { "bsvrecord", 1, NULL, 'R' }, + { "sram-mode", 1, NULL, 'M' }, #ifdef HAVE_NETWORKING - { "host", 0, NULL, 'H' }, - { "connect", 1, NULL, 'C' }, - { "stateless", 0, NULL, RA_OPT_STATELESS }, - { "check-frames", 1, NULL, RA_OPT_CHECK_FRAMES }, - { "port", 1, NULL, RA_OPT_PORT }, + { "host", 0, NULL, 'H' }, + { "connect", 1, NULL, 'C' }, + { "stateless", 0, NULL, RA_OPT_STATELESS }, + { "check-frames", 1, NULL, RA_OPT_CHECK_FRAMES }, + { "port", 1, NULL, RA_OPT_PORT }, #if defined(HAVE_NETWORK_CMD) - { "command", 1, NULL, RA_OPT_COMMAND }, + { "command", 1, NULL, RA_OPT_COMMAND }, #endif #endif - { "nick", 1, NULL, RA_OPT_NICK }, - { "ups", 1, NULL, 'U' }, - { "bps", 1, NULL, RA_OPT_BPS }, - { "ips", 1, NULL, RA_OPT_IPS }, - { "no-patch", 0, NULL, RA_OPT_NO_PATCH }, - { "detach", 0, NULL, 'D' }, - { "features", 0, NULL, RA_OPT_FEATURES }, - { "subsystem", 1, NULL, RA_OPT_SUBSYSTEM }, - { "max-frames", 1, NULL, RA_OPT_MAX_FRAMES }, - { "eof-exit", 0, NULL, RA_OPT_EOF_EXIT }, - { "version", 0, NULL, RA_OPT_VERSION }, + { "nick", 1, NULL, RA_OPT_NICK }, + { "ups", 1, NULL, 'U' }, + { "bps", 1, NULL, RA_OPT_BPS }, + { "ips", 1, NULL, RA_OPT_IPS }, + { "no-patch", 0, NULL, RA_OPT_NO_PATCH }, + { "detach", 0, NULL, 'D' }, + { "features", 0, NULL, RA_OPT_FEATURES }, + { "subsystem", 1, NULL, RA_OPT_SUBSYSTEM }, + { "max-frames", 1, NULL, RA_OPT_MAX_FRAMES }, + { "max-frames-ss", 0, NULL, RA_OPT_MAX_FRAMES_SCREENSHOT }, + { "max-frames-ss-path", 1, NULL, RA_OPT_MAX_FRAMES_SCREENSHOT_PATH }, + { "eof-exit", 0, NULL, RA_OPT_EOF_EXIT }, + { "version", 0, NULL, RA_OPT_VERSION }, #ifdef HAVE_FILE_LOGGER - { "log-file", 1, NULL, RA_OPT_LOG_FILE }, + { "log-file", 1, NULL, RA_OPT_LOG_FILE }, #endif { NULL, 0, NULL, 0 } }; @@ -1088,6 +1098,14 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) runloop_max_frames = (unsigned)strtoul(optarg, NULL, 10); break; + case RA_OPT_MAX_FRAMES_SCREENSHOT: + runloop_max_frames_screenshot = true; + break; + + case RA_OPT_MAX_FRAMES_SCREENSHOT_PATH: + strlcpy(runloop_max_frames_screenshot_path, optarg, sizeof(runloop_max_frames_screenshot_path)); + break; + case RA_OPT_SUBSYSTEM: path_set(RARCH_PATH_SUBSYSTEM, optarg); break; @@ -2631,6 +2649,32 @@ static enum runloop_state runloop_check_state( if (time_to_exit(trig_quit_key)) { + if ((runloop_max_frames != 0) && (frame_count >= runloop_max_frames)) + { + if (runloop_max_frames_screenshot) + { + const char *screenshot_path = NULL; + bool fullpath = false; + + if (string_is_empty(runloop_max_frames_screenshot_path)) + screenshot_path = path_get(RARCH_PATH_BASENAME); + else + { + fullpath = true; + screenshot_path = runloop_max_frames_screenshot_path; + } + + RARCH_LOG("Taking a screenshot before exiting...\n"); + + /* Take a screenshot before we exit. */ + if (!take_screenshot(screenshot_path, false, + video_driver_cached_frame_has_valid_framebuffer(), fullpath, false)) + { + RARCH_ERR("Could not take a screenshot before exiting.\n"); + } + } + } + if (runloop_exec) runloop_exec = false; @@ -2712,7 +2756,7 @@ static enum runloop_state runloop_check_state( } else { - if ( global->menu.prev_action == action && + if ( global->menu.prev_action == action && global->menu.noop_press_time < 200000) /* 250ms */ { global->menu.action_start_time = global->menu.prev_start_time ; @@ -3444,7 +3488,7 @@ int runloop_iterate(unsigned *sleep_ms) end: { retro_time_t to_sleep_ms; - + if (settings->bools.vrr_runloop_enable) { struct retro_system_av_info *av_info = @@ -3469,7 +3513,7 @@ int runloop_iterate(unsigned *sleep_ms) if (!settings->floats.fastforward_ratio && runloop_fastmotion) return 0; - frame_limit_minimum_time = + frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f / (av_info->timing.fps * (runloop_fastmotion ? settings->floats.fastforward_ratio : 1.0f))); } From a309400305b1bee49c3a4350c9e6ed62d7f9b6a5 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Sun, 19 Aug 2018 15:54:56 +0200 Subject: [PATCH 08/17] name gridLayoutWidget --- ui/drivers/qt/ui_qt_window.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 7134bcc2c2..a29da9f841 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -370,6 +370,7 @@ MainWindow::MainWindow(QWidget *parent) : m_gridWidget->setLayout(new QVBoxLayout()); m_gridLayout = new FlowLayout(m_gridLayoutWidget); + m_gridLayoutWidget->setObjectName("gridLayoutWidget"); m_gridScrollArea->setAlignment(Qt::AlignCenter); m_gridScrollArea->setFrameShape(QFrame::NoFrame); From c051bae1bd015a5efd241905daa1d3ebf8bf992a Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Sun, 19 Aug 2018 15:56:19 +0200 Subject: [PATCH 09/17] Update ui_qt_themes.h --- ui/drivers/qt/ui_qt_themes.h | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index 1844930c45..d92b163be0 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -34,22 +34,18 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QTextEdit, LogTextEdit { background-color:rgb(25,25,25); } - QSpinBox, QCheckBox { + QSpinBox, QDoubleSpinBox, QCheckBox { background-color:rgb(25,25,25); } QCheckBox:checked, QCheckBox:unchecked { background-color:rgb(53,53,53); } - QDialog#shaderParamsDialog { + QWidget#shaderParamsWidget { background-color:rgb(25,25,25); } - QDialog#shaderParamsDialog QGroupBox, QDialog#shaderParamsDialog QGroupBox QLabel, - QDialog#shaderParamsDialog QGroupBox QSlider, QDialog#shaderParamsDialog QGroupBox QCheckBox:checked, - QDialog#shaderParamsDialog QGroupBox QCheckBox:unchecked { - background-color:rgb(53,53,53); - } QDialog#shaderParamsDialog QGroupBox { - border-top-left-radius: 0px; + background-color:rgb(53,53,53); + border-top-left-radius:0px; } QDialog#shaderParamsDialog QGroupBox::title { margin-left:0px; @@ -58,7 +54,7 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgb(53,53,53),stop:1 rgba(125,125,125,127)); border:1px solid rgba(25,25,25,75); border-top:1px solid rgba(175,175,175,50%); - border-bottom: none transparent; + border-bottom:none transparent; } QToolTip { color:white; @@ -224,7 +220,7 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( } QComboBox { min-height:20px; - padding:1px 18px 1px 3px; + padding:1px 6px 1px 6px; } QComboBox::focus { background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(100,100,100,25)); @@ -238,6 +234,7 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( } QComboBox::drop-down { background-color:transparent; + width:0px; } QComboBox::selected:on, QComboBox::selected:off { background-color:%1; @@ -262,6 +259,10 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( padding:1px 3px 1px 3px; outline:none; } + QPushButton::disabled, QToolButton::disabled { + color:grey; + background-color:rgb(25,25,25); + } QPushButton::focus, QToolButton::focus { background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(100,100,100,25)); border:1px solid %1; @@ -277,8 +278,8 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( border:1px solid %1; border-radius:4px; } - QPushButton[flat="true"] { - background-color: transparent; + QPushButton[flat=\"true\"] { + background-color:transparent; } QRadioButton::indicator { width:18px; @@ -428,7 +429,7 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( background-color:rgb(40,40,40); border:3px solid %1; } - QScrollArea QWidget { - background:rgb(25,25,25); + QWidget#gridLayoutWidget { + background-color:rgb(25,25,25); } )"); From 9e9fb5803e8e72217f342ddb8807402d5eccd90e Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Sun, 19 Aug 2018 16:00:19 +0200 Subject: [PATCH 10/17] Update ui_qt_themes.h --- ui/drivers/qt/ui_qt_themes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index d92b163be0..803cf8a37a 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -278,7 +278,7 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( border:1px solid %1; border-radius:4px; } - QPushButton[flat=\"true\"] { + QPushButton[flat="true"] { background-color:transparent; } QRadioButton::indicator { From 821ffc9962ff96bbdb942f88411f14185d46ad6a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 19 Aug 2018 16:12:54 +0200 Subject: [PATCH 11/17] Clang scan-build error fix --- libretro-common/formats/png/rpng_encode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libretro-common/formats/png/rpng_encode.c b/libretro-common/formats/png/rpng_encode.c index 3500c3aaf4..42df8116aa 100644 --- a/libretro-common/formats/png/rpng_encode.c +++ b/libretro-common/formats/png/rpng_encode.c @@ -150,7 +150,10 @@ static unsigned count_sad(const uint8_t *data, size_t size) size_t i; unsigned cnt = 0; for (i = 0; i < size; i++) - cnt += abs((int8_t)data[i]); + { + if (data[i]) + cnt += abs((int8_t)data[i]); + } return cnt; } From f6dc3345e9df0142c7a9fef0369b1ee7133138b2 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 19 Aug 2018 11:05:25 -0400 Subject: [PATCH 12/17] Qt: use native path separators for folder scan from file browser, fixes #7084 --- ui/drivers/qt/ui_qt_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index a29da9f841..28c3afd91c 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -840,7 +840,7 @@ void MainWindow::onFileBrowserTreeContextMenuRequested(const QPoint&) QList actions; QScopedPointer scanAction; QDir dir; - QString currentDirString = m_dirModel->filePath(m_dirTree->currentIndex()); + QString currentDirString = QDir::toNativeSeparators(m_dirModel->filePath(m_dirTree->currentIndex())); settings_t *settings = config_get_ptr(); QByteArray dirArray; const char *fullpath = NULL; From d571bfaf176c3ac7617c3157fdad1ca8e47af3ef Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 19 Aug 2018 11:46:33 -0400 Subject: [PATCH 13/17] Qt: use native path separators for file browser content --- ui/drivers/qt/ui_qt_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 28c3afd91c..9e64b80a69 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -1399,7 +1399,7 @@ void MainWindow::selectBrowserDir(QString path) QString fileName = dirList.at(i); QTableWidgetItem *item = new QTableWidgetItem(fileName); QHash hash; - QString filePath(dir.absoluteFilePath(fileName)); + QString filePath(QDir::toNativeSeparators(dir.absoluteFilePath(fileName))); QFileInfo fileInfo(filePath); hash["path"] = filePath; From 5ba4103f6e72310d9375f0c6caa5ffa2252c18f2 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Sun, 19 Aug 2018 12:49:47 -0400 Subject: [PATCH 14/17] pkg: Add MAME 2003 Plus --- pkg/ctr/Makefile.cores | 8 ++++++++ pkg/ctr/assets/mame2003_plus.png | Bin 0 -> 1275 bytes pkg/ctr/assets/mame2003_plus_banner.png | Bin 0 -> 38848 bytes 3 files changed, 8 insertions(+) create mode 100644 pkg/ctr/assets/mame2003_plus.png create mode 100644 pkg/ctr/assets/mame2003_plus_banner.png diff --git a/pkg/ctr/Makefile.cores b/pkg/ctr/Makefile.cores index 8fabdb8bd7..391fe18045 100644 --- a/pkg/ctr/Makefile.cores +++ b/pkg/ctr/Makefile.cores @@ -139,6 +139,14 @@ else ifeq ($(LIBRETRO), mame2003) APP_BANNER = pkg/ctr/assets/mame2003_banner.png APP_BIG_TEXT_SECTION = 1 +else ifeq ($(LIBRETRO), mame2003_plus) + APP_TITLE = MAME-2003-PLUS + APP_PRODUCT_CODE = RARCH-MAME2003-PLUS + APP_UNIQUE_ID = 0xBAC22 + APP_ICON = pkg/ctr/assets/mame2003_plus.png + APP_BANNER = pkg/ctr/assets/mame2003_plus_banner.png + APP_BIG_TEXT_SECTION = 1 + else ifeq ($(LIBRETRO), mednafen_pce_fast) APP_TITLE = Mednafen/Beetle PCE FAST APP_AUTHOR = Ryphecha diff --git a/pkg/ctr/assets/mame2003_plus.png b/pkg/ctr/assets/mame2003_plus.png new file mode 100644 index 0000000000000000000000000000000000000000..86509ec99998985126fb4dc30ece70dfb4140792 GIT binary patch literal 1275 zcmV3N)n2w7Na%BB1FZ-xMXW~<4GkHODB zpQG7oqI=p!|7Hl2=sbW?H88lmUMUlTD3pQ_L}4xWOikwtS(!|v`vZWgDv3*4L(3JR z@9SV5%k*E@Jz?E>9LHX*4gl!2dpP`X$U*4)I^O>M7QJ>a(|^&8vhGQg&eqCAeE)bj zf@vABrw%&Do!s>kZ=t4TU_2aU+;bf-aW5}weJ?$3mii*~|mkC70(m6rvxW@rhc1>JQCJ1IUnL3IrVYgDrojTL01Iof& z@p%xED8RCejkzZ=c1s?q1XulGc6(zHJQm=}8$#0*5I<{J+VVW{i`OX&ksdQGKF__6 z?_cBO>;eI0P#G(JrHoVp&kOF{K0PC&SQ+=YLZ)kSRDEV(FtV3EMmMS^M*lh+o5zdL%ea>T007aH@2vyWrO-45 z%$_~S$+E0_8GtlIQ9Pvhjr<>A_6&`x2~AUy_gz60plJ#kRr9wK&pELDL-QDaXb5@Q l0NbB@k3NNfXzRdZ#(z}=Xy*pYBSQcH002ovPDHLkV1hG7MlS#W literal 0 HcmV?d00001 diff --git a/pkg/ctr/assets/mame2003_plus_banner.png b/pkg/ctr/assets/mame2003_plus_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..6b73ffe5fddc478e18bde646a7cbce63e1df62b7 GIT binary patch literal 38848 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 Date: Sun, 19 Aug 2018 16:26:16 -0400 Subject: [PATCH 15/17] Qt: add load/save/remove/apply buttons to top of shaders dialog --- intl/msg_hash_ja.h | 14 ++ intl/msg_hash_us.h | 14 ++ msg_hash.h | 7 + ui/drivers/qt/shaderparamsdialog.cpp | 343 ++++++++++++++++++++++++++- ui/drivers/qt/shaderparamsdialog.h | 10 + 5 files changed, 382 insertions(+), 6 deletions(-) diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index d4c8627c33..88adc933c0 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3760,3 +3760,17 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, "下へ移動") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, "上へ移動") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD, + "ロード") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SAVE, + "保存") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_REMOVE, + "取り除く") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_APPLY, + "適用") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + "パスを追加") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + "すべてのパスを取り除く") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + "シェーダーパスはありません。") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 0815a52aaf..8bb57653c9 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -4270,3 +4270,17 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, "Move Down") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, "Move Up") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD, + "Load") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SAVE, + "Save") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_REMOVE, + "Remove") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_APPLY, + "Apply") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + "Add Pass") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + "Clear All Passes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + "No shader passes.") diff --git a/msg_hash.h b/msg_hash.h index a696ee5ca0..5ea9620d1c 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1985,6 +1985,13 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER, MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, + MENU_ENUM_LABEL_VALUE_QT_LOAD, + MENU_ENUM_LABEL_VALUE_QT_SAVE, + MENU_ENUM_LABEL_VALUE_QT_REMOVE, + MENU_ENUM_LABEL_VALUE_QT_APPLY, + MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, MENU_LABEL(MIDI_INPUT), MENU_LABEL(MIDI_OUTPUT), diff --git a/ui/drivers/qt/shaderparamsdialog.cpp b/ui/drivers/qt/shaderparamsdialog.cpp index 23f2fc8c95..4d549ce309 100644 --- a/ui/drivers/qt/shaderparamsdialog.cpp +++ b/ui/drivers/qt/shaderparamsdialog.cpp @@ -11,18 +11,33 @@ #include #include #include +#include +#include #include "shaderparamsdialog.h" #include "../ui_qt.h" extern "C" { #include +#include +#include #include "../../../command.h" +#include "../../../configuration.h" +#include "../../../retroarch.h" +#include "../../../paths.h" #ifdef HAVE_MENU #include "../../../menu/menu_shader.h" #endif } +enum +{ + SHADER_PRESET_SAVE_CORE = 0, + SHADER_PRESET_SAVE_GAME, + SHADER_PRESET_SAVE_PARENT, + SHADER_PRESET_SAVE_NORMAL +}; + ShaderParamsDialog::ShaderParamsDialog(QWidget *parent) : QDialog(parent) ,m_layout(NULL) @@ -375,13 +390,265 @@ void ShaderParamsDialog::onShaderPassMoveUpClicked() command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL); } +void ShaderParamsDialog::onShaderLoadPresetClicked() +{ +#ifdef HAVE_MENU + QString path; + QByteArray pathArray; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + const char *pathData = NULL; + settings_t *settings = config_get_ptr(); + enum rarch_shader_type type = RARCH_SHADER_NONE; + + if (!settings) + return; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader) + return; + + path = QFileDialog::getOpenFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET), settings->paths.directory_video_shader); + + if (path.isEmpty()) + return; + + pathArray = path.toUtf8(); + pathData = pathArray.constData(); + + type = video_shader_parse_type(pathData, RARCH_SHADER_NONE); + + menu_shader_manager_set_preset(menu_shader, type, pathData); +#endif +} + +void ShaderParamsDialog::onShaderAddPassClicked() +{ +#ifdef HAVE_MENU + QString path; + QByteArray pathArray; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + struct video_shader_pass *shader_pass = NULL; + const char *pathData = NULL; + settings_t *settings = config_get_ptr(); + + if (!settings) + return; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader) + return; + + path = QFileDialog::getOpenFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET), settings->paths.directory_video_shader); + + if (path.isEmpty()) + return; + + pathArray = path.toUtf8(); + pathData = pathArray.constData(); + + if (menu_shader->passes < GFX_MAX_SHADERS) + menu_shader_manager_increment_amount_passes(); + else + return; + + shader_pass = &menu_shader->pass[menu_shader->passes - 1]; + + if (!shader_pass) + return; + + strlcpy(shader_pass->source.path, pathData, sizeof(shader_pass->source.path)); + + video_shader_resolve_parameters(NULL, menu_shader); + + command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL); +#endif +} + +void ShaderParamsDialog::onShaderSavePresetAsClicked() +{ +#ifdef HAVE_MENU + settings_t *settings = config_get_ptr(); + QString path; + QByteArray pathArray; + const char *pathData = NULL; + + path = QFileDialog::getSaveFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS), settings->paths.directory_video_shader); + + if (path.isEmpty()) + return; + + pathArray = path.toUtf8(); + pathData = pathArray.constData(); + + saveShaderPreset(pathData, SHADER_PRESET_SAVE_NORMAL); +#endif +} + +void ShaderParamsDialog::saveShaderPreset(const char *path, unsigned action_type) +{ + char directory[PATH_MAX_LENGTH]; + char file[PATH_MAX_LENGTH]; + char tmp[PATH_MAX_LENGTH]; + settings_t *settings = config_get_ptr(); + const char *core_name = NULL; + rarch_system_info_t *info = runloop_get_system_info(); + + directory[0] = file[0] = tmp[0] = '\0'; + + if (info) + core_name = info->info.library_name; + + if (!string_is_empty(core_name)) + { + fill_pathname_join( + tmp, + settings->paths.directory_video_shader, + "presets", + sizeof(tmp)); + fill_pathname_join( + directory, + tmp, + core_name, + sizeof(directory)); + } + + if (!filestream_exists(directory)) + path_mkdir(directory); + + switch (action_type) + { + case SHADER_PRESET_SAVE_CORE: + if (!string_is_empty(core_name)) + fill_pathname_join(file, directory, core_name, sizeof(file)); + break; + case SHADER_PRESET_SAVE_GAME: + { + const char *game_name = path_basename(path_get(RARCH_PATH_BASENAME)); + fill_pathname_join(file, directory, game_name, sizeof(file)); + break; + } + case SHADER_PRESET_SAVE_PARENT: + { + fill_pathname_parent_dir_name(tmp, path_get(RARCH_PATH_BASENAME), sizeof(tmp)); + fill_pathname_join(file, directory, tmp, sizeof(file)); + break; + } + case SHADER_PRESET_SAVE_NORMAL: + default: + if (!string_is_empty(path)) + strlcpy(file, path, sizeof(file)); + break; + } + + if (menu_shader_manager_save_preset(file, false, true)) + runloop_msg_queue_push( + msg_hash_to_str(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY), + 1, 100, true); + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_ERROR_SAVING_SHADER_PRESET), + 1, 100, true); +} + +void ShaderParamsDialog::onShaderSaveCorePresetClicked() +{ + saveShaderPreset(NULL, SHADER_PRESET_SAVE_CORE); +} + +void ShaderParamsDialog::onShaderSaveParentPresetClicked() +{ + saveShaderPreset(NULL, SHADER_PRESET_SAVE_PARENT); +} + +void ShaderParamsDialog::onShaderSaveGamePresetClicked() +{ + saveShaderPreset(NULL, SHADER_PRESET_SAVE_GAME); +} + +void ShaderParamsDialog::onShaderClearAllPassesClicked() +{ +#ifdef HAVE_MENU + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader) + return; + + while (menu_shader->passes > 0) + menu_shader_manager_decrement_amount_passes(); + + onShaderApplyClicked(); +#endif +} + +void ShaderParamsDialog::onShaderRemovePassClicked() +{ +#ifdef HAVE_MENU + QAction *action = qobject_cast(sender()); + QVariant passVariant; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + int pass = 0; + int i; + bool ok = false; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader || menu_shader->passes == 0 || !action) + return; + + passVariant = action->data(); + + if (!passVariant.isValid()) + return; + + pass = passVariant.toInt(&ok); + + if (!ok) + return; + + if (pass < 0 || pass > static_cast(menu_shader->passes)) + return; + + /* move selected pass to the bottom */ + for (i = pass; i < static_cast(menu_shader->passes) - 1; i++) + { + std::swap(menu_shader->pass[i], menu_shader->pass[i + 1]); + } + + menu_shader_manager_decrement_amount_passes(); + + onShaderApplyClicked(); +#endif +} + +void ShaderParamsDialog::onShaderApplyClicked() +{ + command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL); +} + void ShaderParamsDialog::reload() { + QPushButton *loadButton = NULL; + QPushButton *saveButton = NULL; + QPushButton *removeButton = NULL; + QPushButton *applyButton = NULL; + QHBoxLayout *topButtonLayout = NULL; + QMenu *loadMenu = NULL; + QMenu *saveMenu = NULL; + QMenu *removeMenu = NULL; struct video_shader *menu_shader = NULL; struct video_shader *video_shader = NULL; const char *shader_path = NULL; int i; unsigned j; + bool hasPasses = false; getShaders(&menu_shader, &video_shader); @@ -409,6 +676,56 @@ void ShaderParamsDialog::reload() else setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS)); + loadButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_LOAD), this); + saveButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SAVE), this); + removeButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_REMOVE), this); + applyButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_APPLY), this); + + loadMenu = new QMenu(loadButton); + loadMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET), this, SLOT(onShaderLoadPresetClicked())); + loadMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS), this, SLOT(onShaderAddPassClicked())); + + loadButton->setMenu(loadMenu); + + saveMenu = new QMenu(saveButton); + saveMenu->addAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS)) + "...", this, SLOT(onShaderSavePresetAsClicked())); + saveMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE), this, SLOT(onShaderSaveCorePresetClicked())); + saveMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT), this, SLOT(onShaderSaveParentPresetClicked())); + saveMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME), this, SLOT(onShaderSaveGamePresetClicked())); + + saveButton->setMenu(saveMenu); + + removeMenu = new QMenu(removeButton); + + /* When there are no passes, at least on first startup, it seems video_shader erroneously shows 1 pass, with an empty source file. + * So we use menu_shader instead for that. + */ + if (menu_shader) + { + for (i = 0; i < static_cast(menu_shader->passes); i++) + { + QFileInfo fileInfo(menu_shader->pass[i].source.path); + QString shaderBasename = fileInfo.completeBaseName(); + QAction *action = removeMenu->addAction(shaderBasename, this, SLOT(onShaderRemovePassClicked())); + + action->setData(i); + } + } + + removeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES), this, SLOT(onShaderClearAllPassesClicked())); + + removeButton->setMenu(removeMenu); + + connect(applyButton, SIGNAL(clicked()), this, SLOT(onShaderApplyClicked())); + + topButtonLayout = new QHBoxLayout(); + topButtonLayout->addWidget(loadButton); + topButtonLayout->addWidget(saveButton); + topButtonLayout->addWidget(removeButton); + topButtonLayout->addWidget(applyButton); + + m_layout->addLayout(topButtonLayout); + /* NOTE: We assume that parameters are always grouped in order by the pass number, e.g., all parameters for pass 0 come first, then params for pass 1, etc. */ for (i = 0; i < static_cast(video_shader->passes); i++) { @@ -417,20 +734,26 @@ void ShaderParamsDialog::reload() QFileInfo fileInfo(video_shader->pass[i].source.path); QString shaderBasename = fileInfo.completeBaseName(); QHBoxLayout *filterScaleHBoxLayout = NULL; - QComboBox *filterComboBox = new QComboBox(); - QComboBox *scaleComboBox = new QComboBox(); + QComboBox *filterComboBox = new QComboBox(this); + QComboBox *scaleComboBox = new QComboBox(this); QToolButton *moveDownButton = NULL; QToolButton *moveUpButton = NULL; unsigned j = 0; + /* Sometimes video_shader shows 1 pass with no source file, when there are really 0 passes. */ + if (shaderBasename.isEmpty()) + continue; + + hasPasses = true; + filterComboBox->setProperty("pass", i); scaleComboBox->setProperty("pass", i); - moveDownButton = new QToolButton(); + moveDownButton = new QToolButton(this); moveDownButton->setText("↓"); moveDownButton->setProperty("pass", i); - moveUpButton = new QToolButton(); + moveUpButton = new QToolButton(this); moveUpButton->setText("↑"); moveUpButton->setProperty("pass", i); @@ -488,9 +811,9 @@ void ShaderParamsDialog::reload() filterScaleHBoxLayout = new QHBoxLayout(); filterScaleHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred)); - filterScaleHBoxLayout->addWidget(new QLabel(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILTER)) + ":")); + filterScaleHBoxLayout->addWidget(new QLabel(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILTER)) + ":", this)); filterScaleHBoxLayout->addWidget(filterComboBox); - filterScaleHBoxLayout->addWidget(new QLabel(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCALE)) + ":")); + filterScaleHBoxLayout->addWidget(new QLabel(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCALE)) + ":", this)); filterScaleHBoxLayout->addWidget(scaleComboBox); filterScaleHBoxLayout->addSpacerItem(new QSpacerItem(20, 0, QSizePolicy::Preferred, QSizePolicy::Preferred)); @@ -513,6 +836,14 @@ void ShaderParamsDialog::reload() } } + if (!hasPasses) + { + QLabel *noParamsLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES), this); + noParamsLabel->setAlignment(Qt::AlignCenter); + + m_layout->addWidget(noParamsLabel); + } + m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); end: diff --git a/ui/drivers/qt/shaderparamsdialog.h b/ui/drivers/qt/shaderparamsdialog.h index 8bd7ed8f3c..5e2afdb9a2 100644 --- a/ui/drivers/qt/shaderparamsdialog.h +++ b/ui/drivers/qt/shaderparamsdialog.h @@ -29,11 +29,21 @@ private slots: void onScaleComboBoxIndexChanged(int index); void onShaderPassMoveDownClicked(); void onShaderPassMoveUpClicked(); + void onShaderLoadPresetClicked(); + void onShaderAddPassClicked(); + void onShaderSavePresetAsClicked(); + void onShaderSaveCorePresetClicked(); + void onShaderSaveParentPresetClicked(); + void onShaderSaveGamePresetClicked(); + void onShaderClearAllPassesClicked(); + void onShaderRemovePassClicked(); + void onShaderApplyClicked(); private: QString getFilterLabel(unsigned filter); void addShaderParam(struct video_shader_parameter *param, int parameter, QFormLayout *form); void clearLayout(QLayout *layout); void getShaders(struct video_shader **menu_shader, struct video_shader **video_shader); + void saveShaderPreset(const char *path, unsigned action_type); QVBoxLayout *m_layout; protected: From 8380ad61f9595f4783a7efd2bf3ab2b76552fb40 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 19 Aug 2018 18:54:13 -0400 Subject: [PATCH 16/17] Qt: add missing paintEvent overrides for stylesheet correctness --- ui/drivers/qt/shaderparamsdialog.cpp | 14 +++++ ui/drivers/qt/shaderparamsdialog.h | 2 + ui/drivers/qt/ui_qt_window.cpp | 78 ++++++++++++++++++++++++++++ ui/drivers/qt/viewoptionsdialog.cpp | 13 +++++ ui/drivers/qt/viewoptionsdialog.h | 2 + ui/drivers/ui_qt.h | 10 ++++ 6 files changed, 119 insertions(+) diff --git a/ui/drivers/qt/shaderparamsdialog.cpp b/ui/drivers/qt/shaderparamsdialog.cpp index 4d549ce309..bfbf9bf532 100644 --- a/ui/drivers/qt/shaderparamsdialog.cpp +++ b/ui/drivers/qt/shaderparamsdialog.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -1152,3 +1153,16 @@ void ShaderParamsDialog::onShaderParamDoubleSpinBoxValueChanged(double value) } } } + +void ShaderParamsDialog::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QDialog::paintEvent(event); +} diff --git a/ui/drivers/qt/shaderparamsdialog.h b/ui/drivers/qt/shaderparamsdialog.h index 5e2afdb9a2..73c6f82423 100644 --- a/ui/drivers/qt/shaderparamsdialog.h +++ b/ui/drivers/qt/shaderparamsdialog.h @@ -5,6 +5,7 @@ class QCloseEvent; class QResizeEvent; +class QPaintEvent; class QVBoxLayout; class QFormLayout; class QLayout; @@ -49,6 +50,7 @@ private: protected: void closeEvent(QCloseEvent *event); void resizeEvent(QResizeEvent *event); + void paintEvent(QPaintEvent *event); }; #endif diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 9e64b80a69..7d980f7093 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -191,6 +191,19 @@ void TreeView::selectionChanged(const QItemSelection &selected, const QItemSelec emit itemsSelected(list); } +void TreeView::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QTreeView::paintEvent(event); +} + TableWidget::TableWidget(QWidget *parent) : QTableWidget(parent) { @@ -212,12 +225,38 @@ void TableWidget::keyPressEvent(QKeyEvent *event) QTableWidget::keyPressEvent(event); } +void TableWidget::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QTableWidget::paintEvent(event); +} + CoreInfoLabel::CoreInfoLabel(QString text, QWidget *parent) : QLabel(text, parent) { setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); } +void CoreInfoLabel::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QLabel::paintEvent(event); +} + CoreInfoWidget::CoreInfoWidget(CoreInfoLabel *label, QWidget *parent) : QWidget(parent) ,m_label(label) @@ -238,6 +277,19 @@ void CoreInfoWidget::resizeEvent(QResizeEvent *event) m_scrollArea->resize(event->size()); } +void CoreInfoWidget::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QWidget::paintEvent(event); +} + LogTextEdit::LogTextEdit(QWidget *parent) : QPlainTextEdit(parent) { @@ -253,6 +305,19 @@ void LogTextEdit::appendMessage(const QString& text) verticalScrollBar()->setValue(verticalScrollBar()->maximum()); } +void LogTextEdit::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QPlainTextEdit::paintEvent(event); +} + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) ,m_loadCoreWindow(new LoadCoreWindow(this)) @@ -2947,6 +3012,19 @@ void MainWindow::onShowInfoMessage(QString msg) showMessageBox(msg, MainWindow::MSGBOX_TYPE_INFO, Qt::ApplicationModal, false); } +void MainWindow::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QMainWindow::paintEvent(event); +} + static void* ui_window_qt_init(void) { ui_window.qtWindow = new MainWindow(); diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp index a293b01a00..fc265b6af0 100644 --- a/ui/drivers/qt/viewoptionsdialog.cpp +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "viewoptionsdialog.h" #include "../ui_qt.h" @@ -216,3 +217,15 @@ void ViewOptionsDialog::hideDialog() reject(); } +void ViewOptionsDialog::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QDialog::paintEvent(event); +} diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h index 7b5c7c71fe..1ceb70f313 100644 --- a/ui/drivers/qt/viewoptionsdialog.h +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -44,6 +44,8 @@ private: QCheckBox *m_suggestLoadedCoreFirstCheckBox; QSpinBox *m_allPlaylistsListMaxCountSpinBox; QSpinBox *m_allPlaylistsGridMaxCountSpinBox; +protected: + void paintEvent(QPaintEvent *event); }; #endif diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index 0b8debb3b9..c04ae44173 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -153,6 +153,8 @@ signals: protected slots: void columnCountChanged(int oldCount, int newCount); void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); +protected: + void paintEvent(QPaintEvent *event); }; class TableWidget : public QTableWidget @@ -165,6 +167,8 @@ signals: void deletePressed(); protected: void keyPressEvent(QKeyEvent *event); +protected: + void paintEvent(QPaintEvent *event); }; class AppHandler : public QObject @@ -186,6 +190,8 @@ class CoreInfoLabel : public QLabel Q_OBJECT public: CoreInfoLabel(QString text = QString(), QWidget *parent = 0); +protected: + void paintEvent(QPaintEvent *event); }; class CoreInfoWidget : public QWidget @@ -196,6 +202,7 @@ public: QSize sizeHint() const; protected: void resizeEvent(QResizeEvent *event); + void paintEvent(QPaintEvent *event); private: CoreInfoLabel *m_label; QScrollArea *m_scrollArea; @@ -208,6 +215,8 @@ public: LogTextEdit(QWidget *parent = 0); public slots: void appendMessage(const QString& text); +protected: + void paintEvent(QPaintEvent *event); }; class MainWindow : public QMainWindow @@ -450,6 +459,7 @@ private: protected: void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event); + void paintEvent(QPaintEvent *event); }; Q_DECLARE_METATYPE(ThumbnailWidget) From 3ad54bc9ca970b315ce844f3f38c0c398d110430 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 19 Aug 2018 19:27:06 -0400 Subject: [PATCH 17/17] Qt: revert paintEvent changes, only keep one for ShaderParamsDialog --- ui/drivers/qt/shaderparamsdialog.cpp | 26 +++++----- ui/drivers/qt/shaderparamsdialog.h | 1 - ui/drivers/qt/ui_qt_window.cpp | 78 ---------------------------- ui/drivers/qt/viewoptionsdialog.cpp | 13 ----- ui/drivers/qt/viewoptionsdialog.h | 2 - ui/drivers/ui_qt.h | 10 ---- 6 files changed, 13 insertions(+), 117 deletions(-) diff --git a/ui/drivers/qt/shaderparamsdialog.cpp b/ui/drivers/qt/shaderparamsdialog.cpp index bfbf9bf532..1891efccfa 100644 --- a/ui/drivers/qt/shaderparamsdialog.cpp +++ b/ui/drivers/qt/shaderparamsdialog.cpp @@ -91,6 +91,19 @@ void ShaderParamsDialog::closeEvent(QCloseEvent *event) emit closed(); } +void ShaderParamsDialog::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QDialog::paintEvent(event); +} + QString ShaderParamsDialog::getFilterLabel(unsigned filter) { QString filterString; @@ -1153,16 +1166,3 @@ void ShaderParamsDialog::onShaderParamDoubleSpinBoxValueChanged(double value) } } } - -void ShaderParamsDialog::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QDialog::paintEvent(event); -} diff --git a/ui/drivers/qt/shaderparamsdialog.h b/ui/drivers/qt/shaderparamsdialog.h index 73c6f82423..9e74d20c20 100644 --- a/ui/drivers/qt/shaderparamsdialog.h +++ b/ui/drivers/qt/shaderparamsdialog.h @@ -5,7 +5,6 @@ class QCloseEvent; class QResizeEvent; -class QPaintEvent; class QVBoxLayout; class QFormLayout; class QLayout; diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 7d980f7093..9e64b80a69 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -191,19 +191,6 @@ void TreeView::selectionChanged(const QItemSelection &selected, const QItemSelec emit itemsSelected(list); } -void TreeView::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QTreeView::paintEvent(event); -} - TableWidget::TableWidget(QWidget *parent) : QTableWidget(parent) { @@ -225,38 +212,12 @@ void TableWidget::keyPressEvent(QKeyEvent *event) QTableWidget::keyPressEvent(event); } -void TableWidget::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QTableWidget::paintEvent(event); -} - CoreInfoLabel::CoreInfoLabel(QString text, QWidget *parent) : QLabel(text, parent) { setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); } -void CoreInfoLabel::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QLabel::paintEvent(event); -} - CoreInfoWidget::CoreInfoWidget(CoreInfoLabel *label, QWidget *parent) : QWidget(parent) ,m_label(label) @@ -277,19 +238,6 @@ void CoreInfoWidget::resizeEvent(QResizeEvent *event) m_scrollArea->resize(event->size()); } -void CoreInfoWidget::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QWidget::paintEvent(event); -} - LogTextEdit::LogTextEdit(QWidget *parent) : QPlainTextEdit(parent) { @@ -305,19 +253,6 @@ void LogTextEdit::appendMessage(const QString& text) verticalScrollBar()->setValue(verticalScrollBar()->maximum()); } -void LogTextEdit::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QPlainTextEdit::paintEvent(event); -} - MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) ,m_loadCoreWindow(new LoadCoreWindow(this)) @@ -3012,19 +2947,6 @@ void MainWindow::onShowInfoMessage(QString msg) showMessageBox(msg, MainWindow::MSGBOX_TYPE_INFO, Qt::ApplicationModal, false); } -void MainWindow::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QMainWindow::paintEvent(event); -} - static void* ui_window_qt_init(void) { ui_window.qtWindow = new MainWindow(); diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp index fc265b6af0..a293b01a00 100644 --- a/ui/drivers/qt/viewoptionsdialog.cpp +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include "viewoptionsdialog.h" #include "../ui_qt.h" @@ -217,15 +216,3 @@ void ViewOptionsDialog::hideDialog() reject(); } -void ViewOptionsDialog::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QDialog::paintEvent(event); -} diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h index 1ceb70f313..7b5c7c71fe 100644 --- a/ui/drivers/qt/viewoptionsdialog.h +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -44,8 +44,6 @@ private: QCheckBox *m_suggestLoadedCoreFirstCheckBox; QSpinBox *m_allPlaylistsListMaxCountSpinBox; QSpinBox *m_allPlaylistsGridMaxCountSpinBox; -protected: - void paintEvent(QPaintEvent *event); }; #endif diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index c04ae44173..0b8debb3b9 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -153,8 +153,6 @@ signals: protected slots: void columnCountChanged(int oldCount, int newCount); void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); -protected: - void paintEvent(QPaintEvent *event); }; class TableWidget : public QTableWidget @@ -167,8 +165,6 @@ signals: void deletePressed(); protected: void keyPressEvent(QKeyEvent *event); -protected: - void paintEvent(QPaintEvent *event); }; class AppHandler : public QObject @@ -190,8 +186,6 @@ class CoreInfoLabel : public QLabel Q_OBJECT public: CoreInfoLabel(QString text = QString(), QWidget *parent = 0); -protected: - void paintEvent(QPaintEvent *event); }; class CoreInfoWidget : public QWidget @@ -202,7 +196,6 @@ public: QSize sizeHint() const; protected: void resizeEvent(QResizeEvent *event); - void paintEvent(QPaintEvent *event); private: CoreInfoLabel *m_label; QScrollArea *m_scrollArea; @@ -215,8 +208,6 @@ public: LogTextEdit(QWidget *parent = 0); public slots: void appendMessage(const QString& text); -protected: - void paintEvent(QPaintEvent *event); }; class MainWindow : public QMainWindow @@ -459,7 +450,6 @@ private: protected: void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event); - void paintEvent(QPaintEvent *event); }; Q_DECLARE_METATYPE(ThumbnailWidget)