From 04e852c45a3f309d5e139b0ca059b32277c250e4 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 6 Apr 2021 06:16:47 +0200 Subject: Create a unified launcher for quickmedia --- src/Body.cpp | 2 +- src/QuickMedia.cpp | 182 +++++++++++++++++++++++++++++++-------------------- src/Text.cpp | 19 ++++-- src/plugins/Pipe.cpp | 6 +- 4 files changed, 128 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/Body.cpp b/src/Body.cpp index 61d319a..1e45dcb 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -800,7 +800,7 @@ namespace QuickMedia { if(body_item->description_text) body_item->description_text->setString(std::move(str)); else - body_item->description_text = std::make_unique(std::move(str), false, std::floor(14 * get_ui_scale()), width); + body_item->description_text = std::make_unique(std::move(str), false, std::floor(14 * get_ui_scale()), width, true); body_item->description_text->setFillColor(body_item->get_description_color()); body_item->description_text->updateGeometry(); } diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 8a500fe..c7d63d7 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -56,6 +56,32 @@ static int FPS_IDLE = 2; static const double IDLE_TIMEOUT_SEC = 2.0; static const sf::Vector2i AVATAR_THUMBNAIL_SIZE(std::floor(32 * QuickMedia::get_ui_scale()), std::floor(32 * QuickMedia::get_ui_scale())); +static const std::pair valid_plugins[] = { + std::make_pair("launcher", nullptr), + std::make_pair("manganelo", "manganelo_logo.png"), + std::make_pair("mangatown", "mangatown_logo.png"), + std::make_pair("mangadex", "mangadex_logo.png"), + std::make_pair("youtube", "yt_logo_rgb_dark_small.png"), + std::make_pair("spotify", "spotify_logo.png"), + std::make_pair("soundcloud", "soundcloud_logo.png"), + std::make_pair("pornhub", "pornhub_logo.png"), + std::make_pair("4chan", "4chan_logo.png"), + std::make_pair("nyaa.si", "nyaa_si_logo.png"), + std::make_pair("matrix", "matrix_logo.png"), + std::make_pair("mastodon", "pleroma_logo.png"), + std::make_pair("pleroma", "pleroma_logo.png"), + std::make_pair("file-manager", nullptr), + std::make_pair("stdin", nullptr) +}; + +static const char* get_plugin_logo_name(const char *plugin_name) { + for(const auto &valid_plugin : valid_plugins) { + if(strcmp(plugin_name, valid_plugin.first) == 0) + return valid_plugin.second; + } + return nullptr; +} + // Prevent writing to broken pipe from exiting the program static void sigpipe_handler(int) { @@ -449,7 +475,7 @@ namespace QuickMedia { static void usage() { fprintf(stderr, "usage: quickmedia [--no-video] [--use-system-mpv-config] [--dir ]\n"); fprintf(stderr, "OPTIONS:\n"); - fprintf(stderr, " plugin The plugin to use. Should be either 4chan, manganelo, mangatown, mangadex, pornhub, youtube, spotify, soundcloud, nyaa.si, matrix, file-manager or pipe\n"); + fprintf(stderr, " plugin The plugin to use. Should be either launcher, 4chan, manganelo, mangatown, mangadex, pornhub, youtube, spotify, soundcloud, nyaa.si, matrix, file-manager or stdin\n"); fprintf(stderr, " --no-video Only play audio when playing a video. Disabled by default\n"); fprintf(stderr, " --use-system-mpv-config Use system mpv config instead of no config. Disabled by default\n"); fprintf(stderr, " --upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default\n"); @@ -458,70 +484,44 @@ namespace QuickMedia { fprintf(stderr, "EXAMPLES:\n"); fprintf(stderr, " quickmedia manganelo\n"); fprintf(stderr, " quickmedia --upscale-images-always manganelo\n"); + fprintf(stderr, " echo -e \"hello\\nworld\" | quickmedia stdin\n"); } static bool is_manga_plugin(const char *plugin_name) { return strcmp(plugin_name, "manganelo") == 0 || strcmp(plugin_name, "mangatown") == 0 || strcmp(plugin_name, "mangadex") == 0; } + static std::shared_ptr create_launcher_body_item(const char *title, const char *plugin_name, const std::string &thumbnail_url) { + auto body_item = BodyItem::create(title); + body_item->url = plugin_name; + body_item->thumbnail_url = thumbnail_url; + body_item->thumbnail_is_local = true; + body_item->thumbnail_size.x = 32; + body_item->thumbnail_size.y = 32; + return body_item; + } + int Program::run(int argc, char **argv) { if(argc < 2) { usage(); return -1; } - std::string plugin_logo_path; const char *start_dir = nullptr; std::vector tabs; for(int i = 1; i < argc; ++i) { if(!plugin_name) { - if(strcmp(argv[i], "manganelo") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/manganelo_logo.png"; - } else if(strcmp(argv[i], "mangatown") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/mangatown_logo.png"; - } else if(strcmp(argv[i], "mangadex") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/mangadex_logo.png"; - } else if(strcmp(argv[i], "youtube") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/yt_logo_rgb_dark_small.png"; - } else if(strcmp(argv[i], "spotify") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/spotify_logo.png"; - no_video = true; - } else if(strcmp(argv[i], "soundcloud") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/soundcloud_logo.png"; - no_video = true; - } else if(strcmp(argv[i], "pornhub") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/pornhub_logo.png"; - plugin_name = argv[i]; - } else if(strcmp(argv[i], "4chan") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/4chan_logo.png"; - } else if(strcmp(argv[i], "nyaa.si") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/nyaa_si_logo.png"; - } else if(strcmp(argv[i], "matrix") == 0) { - plugin_name = argv[i]; - matrix = new Matrix(); - plugin_logo_path = resources_root + "images/matrix_logo.png"; - } else if(strcmp(argv[i], "mastodon") == 0 || strcmp(argv[i], "pleroma") == 0) { - plugin_name = argv[i]; - plugin_logo_path = resources_root + "images/pleroma_logo.png"; - } else if(strcmp(argv[i], "file-manager") == 0) { - plugin_name = argv[i]; - } else if(strcmp(argv[i], "pipe") == 0) { - plugin_name = argv[i]; + for(const auto &valid_plugin : valid_plugins) { + if(strcmp(argv[i], valid_plugin.first) == 0) { + plugin_name = argv[i]; + break; + } } } if(strcmp(argv[i], "--no-video") == 0) { - no_video = true; + force_no_video = true; } else if(strcmp(argv[i], "--use-system-mpv-config") == 0) { use_system_mpv_config = true; } else if(strcmp(argv[i], "--upscale-images") == 0) { @@ -605,18 +605,65 @@ namespace QuickMedia { return -1; } + load_plugin_by_name(tabs, start_dir); + + while(!tabs.empty() || matrix) { + if(matrix) { + if(matrix->load_cached_session() == PluginResult::OK) { + current_page = PageType::CHAT; + } else { + fprintf(stderr, "Failed to load session cache, redirecting to login page\n"); + current_page = PageType::CHAT_LOGIN; + chat_login_page(); + } + after_matrix_login_page(); + return exit_code; + } + + page_loop(tabs); + tabs.clear(); + + if(strcmp(plugin_name, "launcher") == 0) { + plugin_name = pipe_selected_text.c_str(); + load_plugin_by_name(tabs, start_dir); + } + } + + return exit_code; + } + + void Program::load_plugin_by_name(std::vector &tabs, const char *start_dir) { + if(!plugin_name || plugin_name[0] == '\0') + return; + window.setTitle("QuickMedia - " + std::string(plugin_name)); + const char *plugin_logo_name = get_plugin_logo_name(plugin_name); + std::string plugin_logo_path; + if(plugin_logo_name) + plugin_logo_path = resources_root + "images/" + plugin_logo_name; + no_video = force_no_video; + plugin_logo = sf::Texture(); if(!plugin_logo_path.empty()) { - if(!plugin_logo.loadFromFile(plugin_logo_path)) { + if(!plugin_logo.loadFromFile(plugin_logo_path)) fprintf(stderr, "Failed to load plugin logo, path: %s\n", plugin_logo_path.c_str()); - return -2; - } plugin_logo.generateMipmap(); plugin_logo.setSmooth(true); } - if(strcmp(plugin_name, "manganelo") == 0) { + if(strcmp(plugin_name, "launcher") == 0) { + auto pipe_body = create_body(); + pipe_body->items.push_back(create_launcher_body_item("4chan", "4chan", resources_root + "icons/4chan_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Mangadex", "mangadex", resources_root + "icons/mangadex_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Manganelo", "manganelo", resources_root + "icons/manganelo_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Mangatown", "mangatown", resources_root + "icons/mangatown_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Matrix", "matrix", resources_root + "icons/matrix_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Nyaa.si", "nyaa.si", resources_root + "icons/nyaa_si_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Soundcloud", "soundcloud", resources_root + "icons/soundcloud_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Spotify", "spotify", resources_root + "icons/spotify_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("YouTube", "youtube", resources_root + "icons/yt_launcher.png")); + tabs.push_back(Tab{std::move(pipe_body), std::make_unique(this, "Select plugin to launch"), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + } else if(strcmp(plugin_name, "manganelo") == 0) { auto search_body = create_body(); tabs.push_back(Tab{std::move(search_body), std::make_unique(this), create_search_bar("Search...", 200)}); @@ -654,12 +701,13 @@ namespace QuickMedia { auto file_manager_page = std::make_unique(this); if(start_dir && !file_manager_page->set_current_directory(start_dir)) { fprintf(stderr, "Invalid directory provided with --dir: %s\n", start_dir); - return -3; + exit_code = -3; + return; } auto file_manager_body = create_body(); file_manager_page->get_files_in_directory(file_manager_body->items); tabs.push_back(Tab{std::move(file_manager_body), std::move(file_manager_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); - } else if(strcmp(plugin_name, "pipe") == 0) { + } else if(strcmp(plugin_name, "stdin") == 0) { auto pipe_body = create_body(); PipePage::load_body_items_from_stdin(pipe_body->items); tabs.push_back(Tab{std::move(pipe_body), std::make_unique(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); @@ -681,32 +729,19 @@ namespace QuickMedia { } else if(strcmp(plugin_name, "spotify") == 0) { auto search_body = create_body(); tabs.push_back(Tab{std::move(search_body), std::make_unique(this), create_search_bar("Search...", 250)}); + no_video = true; } else if(strcmp(plugin_name, "soundcloud") == 0) { auto search_body = create_body(); tabs.push_back(Tab{std::move(search_body), std::make_unique(this), create_search_bar("Search...", 500)}); + no_video = true; } else if(strcmp(plugin_name, "mastodon") == 0 || strcmp(plugin_name, "pleroma") == 0) { auto pleroma = std::make_shared(); auto search_body = create_body(); tabs.push_back(Tab{std::move(search_body), std::make_unique(this, pleroma), create_search_bar("Search...", 350)}); + } else if(strcmp(plugin_name, "matrix") == 0) { + assert(!matrix); + matrix = new Matrix(); } - - if(!tabs.empty()) { - page_loop(tabs); - return exit_code; - } - - if(matrix) { - if(matrix->load_cached_session() == PluginResult::OK) { - current_page = PageType::CHAT; - } else { - fprintf(stderr, "Failed to load session cache, redirecting to login page\n"); - current_page = PageType::CHAT_LOGIN; - chat_login_page(); - } - after_matrix_login_page(); - } - - return exit_code; } void Program::base_event_handler(sf::Event &event, PageType previous_page, Body *body, SearchBar *search_bar, bool handle_keypress, bool handle_searchbar) { @@ -986,6 +1021,10 @@ namespace QuickMedia { go_to_previous_page = true; } + void Program::set_pipe_selected_text(const std::string &text) { + pipe_selected_text = text; + } + void Program::page_loop_render(sf::RenderWindow &window, std::vector &tabs, int selected_tab, TabAssociatedData &tab_associated_data, const Json::Value *json_chapters) { if(tabs[selected_tab].search_bar) tabs[selected_tab].search_bar->draw(window, false); @@ -1101,6 +1140,7 @@ namespace QuickMedia { return; std::vector new_tabs; + auto prev_selected_item = tabs[selected_tab].page->submit_body_item; tabs[selected_tab].page->submit_body_item = selected_item; PluginResult submit_result = tabs[selected_tab].page->submit(selected_item ? selected_item->get_title() : search_text, selected_item ? selected_item->url : "", new_tabs); if(submit_result != PluginResult::OK) { @@ -1126,12 +1166,12 @@ namespace QuickMedia { tabs[selected_tab].body = std::move(new_tabs[0].body); else loop_running = false; - tabs[selected_tab].page->submit_body_item = nullptr; + tabs[selected_tab].page->submit_body_item = prev_selected_item; return; } if(new_tabs.empty()) { - tabs[selected_tab].page->submit_body_item = nullptr; + tabs[selected_tab].page->submit_body_item = prev_selected_item; return; } @@ -1224,7 +1264,7 @@ namespace QuickMedia { json_chapters = &chapters_json; } - tabs[selected_tab].page->submit_body_item = nullptr; + tabs[selected_tab].page->submit_body_item = prev_selected_item; redraw = true; hide_virtual_keyboard(); }; diff --git a/src/Text.cpp b/src/Text.cpp index a9f1147..2abc276 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -29,15 +29,16 @@ namespace QuickMedia Text::Text(bool bold_font) : Text("", bold_font, 0, 0.0f) {} - Text::Text(sf::String _str, bool bold_font, unsigned int _characterSize, float _maxWidth) : + Text::Text(sf::String _str, bool bold_font, unsigned int characterSize, float maxWidth, bool highlight_urls) : bold_font(bold_font), - characterSize(_characterSize), - maxWidth(_maxWidth), + characterSize(characterSize), + maxWidth(maxWidth), color(sf::Color::White), dirty(true), dirtyText(false), dirtyCaret(false), editable(false), + highlight_urls(highlight_urls), caretMoveDirection(CaretMoveDirection::NONE), num_lines(1), lineSpacing(0.0f), @@ -324,10 +325,14 @@ namespace QuickMedia dirtyText = false; splitTextByFont(); // TODO: Optimize - auto u8 = str.toUtf8(); - std::string *u8_str = (std::string*)&u8; - url_ranges = extract_urls(*u8_str); - convert_utf8_to_utf32_ranges(*u8_str, url_ranges); + if(highlight_urls) { + auto u8 = str.toUtf8(); + std::string *u8_str = (std::string*)&u8; + url_ranges = extract_urls(*u8_str); + convert_utf8_to_utf32_ranges(*u8_str, url_ranges); + } else { + url_ranges.clear(); + } dirty = true; } diff --git a/src/plugins/Pipe.cpp b/src/plugins/Pipe.cpp index 5d7d269..4fa8cf3 100644 --- a/src/plugins/Pipe.cpp +++ b/src/plugins/Pipe.cpp @@ -1,10 +1,12 @@ #include "../../plugins/Pipe.hpp" +#include "../../include/QuickMedia.hpp" #include #include namespace QuickMedia { - PluginResult PipePage::submit(const std::string &title, const std::string&, std::vector &result_tabs) { - puts(title.c_str()); + PluginResult PipePage::submit(const std::string &title, const std::string &url, std::vector&) { + puts(!url.empty() ? url.c_str() : title.c_str()); + program->set_pipe_selected_text(!url.empty() ? url : title); return PluginResult::OK; } -- cgit v1.2.3