From 4277763df5c1dac8ff389d3bfd138f03acc7f1e2 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 28 Sep 2020 13:32:34 +0200 Subject: Implement text editing with navigation and multilingual fonts --- src/QuickMedia.cpp | 95 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 31 deletions(-) (limited to 'src/QuickMedia.cpp') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index a0d8508..a854613 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -18,6 +18,7 @@ #include "../include/ImageViewer.hpp" #include "../include/ImageUtils.hpp" #include "../include/base64_url.hpp" +#include "../include/Entry.hpp" #include #include @@ -3107,6 +3108,7 @@ namespace QuickMedia { } else if(navigation_stage == NavigationStage::POSTING_COMMENT) { // TODO: Show "Posting..." when posting comment } else if(navigation_stage == NavigationStage::VIEWING_ATTACHED_IMAGE) { + // TODO: Use image instead of data with string. texture->loadFromMemory creates a temporary image anyways that parses the string. std::string image_data; if(downloading_image && load_image_future.valid() && load_image_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { downloading_image = false; @@ -3341,22 +3343,16 @@ namespace QuickMedia { // get_all_room_messages is not needed here because its done in the loop, where the initial timeout is 0ms - SearchBar chat_input(*font, &plugin_logo, "Send a message..."); - chat_input.set_background_color(sf::Color::Transparent); - chat_input.padding_vertical = 10.0f; - - // TODO: Scroll to bottom when receiving new messages, but only if we are already at the bottom? - - // TODO: Filer for rooms and settings - chat_input.onTextUpdateCallback = nullptr; - Page new_page = Page::CHAT; + bool typing_message = false; - // TODO: Show post message immediately, instead of waiting for sync. Otherwise it can take a while until we receive the message, - // which happens when uploading an image. - chat_input.onTextSubmitCallback = [matrix, &tabs, &selected_tab, ¤t_room_id, &new_page](const std::string &text) -> bool { + sf::Sprite logo_sprite(plugin_logo); + + Entry chat_input("Press ctrl+c to begin writing a message...", font.get(), cjk_font.get()); + chat_input.set_editable(false); + chat_input.on_submit_callback = [matrix, &chat_input, &tabs, &selected_tab, ¤t_room_id, &new_page, &typing_message](const sf::String &text) { if(tabs[selected_tab].type == ChatTabType::MESSAGES) { - if(text.empty()) + if(text.isEmpty()) return false; if(text[0] == '/') { @@ -3364,9 +3360,13 @@ namespace QuickMedia { strip(command); if(command == "/upload") { new_page = Page::FILE_MANAGER; + chat_input.set_editable(false); + typing_message = false; return true; } else if(command == "/logout") { new_page = Page::CHAT_LOGIN; + chat_input.set_editable(false); + typing_message = false; return true; } else { fprintf(stderr, "Error: invalid command: %s, expected /upload\n", command.c_str()); @@ -3375,11 +3375,14 @@ namespace QuickMedia { } // TODO: Make asynchronous - if(matrix->post_message(current_room_id, text) != PluginResult::OK) { + if(matrix->post_message(current_room_id, text) == PluginResult::OK) { + chat_input.set_editable(false); + typing_message = false; + return true; + } else { show_notification("QuickMedia", "Failed to post matrix message", Urgency::CRITICAL); return false; } - return true; } return false; }; @@ -3413,6 +3416,9 @@ namespace QuickMedia { sf::RectangleShape more_messages_below_rect; more_messages_below_rect.setFillColor(sf::Color(128, 50, 50)); + sf::RectangleShape chat_input_shade; + chat_input_shade.setFillColor(sf::Color(33, 38, 44)); + sf::Clock start_typing_timer; const double typing_timeout_seconds = 3.0; bool typing = false; @@ -3430,13 +3436,15 @@ namespace QuickMedia { sf::Clock frame_timer; + float prev_chat_height = chat_input.get_height(); + while (current_page == Page::CHAT) { sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds(); while (window.pollEvent(event)) { base_event_handler(event, Page::EXIT, false, false, false); if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus) { redraw = true; - } else if(event.type == sf::Event::KeyPressed) { + } else if(event.type == sf::Event::KeyPressed && !typing_message) { if(event.key.code == sf::Keyboard::Up || event.key.code == sf::Keyboard::PageUp || event.key.code == sf::Keyboard::Home) { bool hit_top = false; switch(event.key.code) { @@ -3511,9 +3519,14 @@ namespace QuickMedia { } } - if(tabs[selected_tab].type == ChatTabType::MESSAGES) { + if(!typing_message && tabs[selected_tab].type == ChatTabType::MESSAGES && event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::C && event.key.control) { + chat_input.set_editable(true); + typing_message = true; + } + + if(typing_message && tabs[selected_tab].type == ChatTabType::MESSAGES) { if(event.type == sf::Event::TextEntered) { - chat_input.onTextEntered(event.text.unicode); + //chat_input.onTextEntered(event.text.unicode); // TODO: Also show typing event when ctrl+v pasting? if(event.text.unicode != 13) { // Return key start_typing_timer.restart(); @@ -3523,8 +3536,12 @@ namespace QuickMedia { } typing = true; } + } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) { + chat_input.set_editable(false); + typing_message = false; } - chat_input.on_event(event); + //chat_input.on_event(event); + chat_input.process_event(event); } else if(tabs[selected_tab].type == ChatTabType::ROOMS && event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Enter) { BodyItem *selected_item = tabs[selected_tab].body->get_selected(); if(selected_item) { @@ -3607,10 +3624,22 @@ namespace QuickMedia { const float tab_shade_height = tab_spacer_height + std::floor(tab_vertical_offset) + tab_height + 10.0f; + const float chat_height = chat_input.get_height(); + if(std::abs(chat_height - prev_chat_height) > 1.0f) { + prev_chat_height = chat_height; + redraw = true; + } if(redraw) { + const float logo_padding_x = 15.0f; + const float chat_input_padding_x = 15.0f; + const float chat_input_padding_y = 15.0f; + + //chat_height += 10.0f; redraw = false; - chat_input.onWindowResize(window_size); - chat_input.set_vertical_position(window_size.y - chat_input.getBottomWithoutShadow()); + chat_input.set_max_width(window_size.x - (logo_padding_x + plugin_logo.getSize().x + chat_input_padding_x * 2.0f)); + chat_input.set_position(sf::Vector2f(logo_padding_x + plugin_logo.getSize().x + chat_input_padding_x, window_size.y - chat_height - chat_input_padding_y)); + //chat_input.onWindowResize(window_size); + //chat_input.set_vertical_position(window_size.y - chat_input.getBottomWithoutShadow()); float body_padding_horizontal = 25.0f; float body_padding_vertical = 5.0f; @@ -3620,15 +3649,17 @@ namespace QuickMedia { body_padding_horizontal = 0.0f; } - float input_bottom = chat_input.getBottomWithoutShadow(); - if(tabs[selected_tab].type != ChatTabType::MESSAGES) - input_bottom = 0.0f; + chat_input_shade.setSize(sf::Vector2f(window_size.x, chat_input.get_height() + chat_input_padding_y * 2.0f)); + chat_input_shade.setPosition(0.0f, window_size.y - chat_input_shade.getSize().y); + body_pos = sf::Vector2f(body_padding_horizontal, body_padding_vertical + tab_shade_height); - body_size = sf::Vector2f(body_width, window_size.y - input_bottom - body_padding_vertical - tab_shade_height); + body_size = sf::Vector2f(body_width, window_size.y - chat_input_shade.getSize().y - body_padding_vertical + tab_shade_height); //get_body_dimensions(window_size, &chat_input, body_pos, body_size, true); more_messages_below_rect.setSize(sf::Vector2f(window_size.x, gradient_height)); - more_messages_below_rect.setPosition(0.0f, std::floor(window_size.y - chat_input.getBottomWithoutShadow() - gradient_height)); + more_messages_below_rect.setPosition(0.0f, std::floor(window_size.y - chat_input_shade.getSize().y - gradient_height)); + + logo_sprite.setPosition(logo_padding_x, window_size.y - chat_input_shade.getSize().y * 0.5f - plugin_logo.getSize().y * 0.5f); } if(!sync_running && sync_timer.getElapsedTime().asMilliseconds() >= sync_min_time_ms) { @@ -3681,16 +3712,12 @@ namespace QuickMedia { fetching_previous_messages_running = false; } - chat_input.update(); + //chat_input.update(); window.clear(back_color); - if(tabs[selected_tab].type == ChatTabType::MESSAGES) - chat_input.draw(window, false); - const float width_per_tab = window_size.x / tabs.size(); tab_background.setSize(sf::Vector2f(std::floor(width_per_tab - tab_margin_x * 2.0f), tab_height)); - tabs[selected_tab].body->draw(window, body_pos, body_size); const float tab_y = tab_spacer_height + std::floor(tab_vertical_offset + tab_height * 0.5f - (tab_text_size + 5.0f) * 0.5f); @@ -3739,6 +3766,12 @@ namespace QuickMedia { window.draw(more_messages_below_rect); } + if(tabs[selected_tab].type == ChatTabType::MESSAGES) { + window.draw(chat_input_shade); + chat_input.draw(window); //chat_input.draw(window, false); + window.draw(logo_sprite); + } + window.display(); } -- cgit v1.2.3