From 9ba59929c23c71a5231670a50c3fcb1165111c90 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 22 Mar 2021 10:40:21 +0100 Subject: Fix touch scroll clamping to selected item, making it appear laggy. Fix emoji offset for non 1.0 scaling --- src/Body.cpp | 173 +++++++++++++++++++++++++++++++---------------------- src/Entry.cpp | 21 ++++++- src/QuickMedia.cpp | 56 +++++++++++------ src/SearchBar.cpp | 15 +++++ src/Text.cpp | 2 +- src/Utils.cpp | 30 ++++++++++ 6 files changed, 203 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/Body.cpp b/src/Body.cpp index 667232e..a34fb7d 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -136,10 +136,6 @@ namespace QuickMedia { item_background.setFillColor(sf::Color(55, 60, 68)); sf::Vector2f loading_icon_size(loading_icon.getTexture()->getSize().x, loading_icon.getTexture()->getSize().y); loading_icon.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f); - const char *qm_enable_touch = getenv("QM_ENABLE_TOUCH"); - if(qm_enable_touch && qm_enable_touch[0] == '1') { - experimental_use_touch = true; - } } // TODO: Make this work with wraparound enabled? @@ -168,10 +164,12 @@ namespace QuickMedia { return true; } - bool Body::select_previous_item(bool scroll_page_if_large_item) { + bool Body::select_previous_item(bool scroll_page_if_large_item, bool reset_select_scroll) { if(items.empty()) return false; + clamp_selected_item_to_body_count = 1; + if(scroll_page_if_large_item && !selected_line_top_visible) { page_scroll += 128.0f; return true; @@ -195,18 +193,22 @@ namespace QuickMedia { break; } - // selected_scrolled = 0.0f; + if(reset_select_scroll) + selected_scrolled = 0.0f; if(selected_item == new_selected_item) return false; + selected_item = new_selected_item; return true; } - bool Body::select_next_item(bool scroll_page_if_large_item) { + bool Body::select_next_item(bool scroll_page_if_large_item, bool reset_select_scroll) { if(items.empty()) return false; + clamp_selected_item_to_body_count = 1; + if(scroll_page_if_large_item && !selected_line_bottom_visible) { page_scroll -= 128.0f; return true; @@ -230,10 +232,12 @@ namespace QuickMedia { break; } - //selected_scrolled = 0.0f; + if(reset_select_scroll) + selected_scrolled = 0.0f; if(selected_item == new_selected_item) return false; + selected_item = new_selected_item; return true; } @@ -246,6 +250,7 @@ namespace QuickMedia { if(reset_prev_selected_item) prev_selected_item = selected_item; clamp_selection(); + clamp_selected_item_to_body_count = 1; //page_scroll = 0.0f; } @@ -262,22 +267,22 @@ namespace QuickMedia { } void Body::select_first_item() { - if(selected_item != 0) - selected_scrolled = 0.0f; + selected_scrolled = 0.0f; selected_item = 0; prev_selected_item = selected_item; page_scroll = 0.0f; clamp_selection(); + clamp_selected_item_to_body_count = 1; } void Body::select_last_item() { int new_selected_item = std::max(0, (int)items.size() - 1); - if(selected_item != new_selected_item) - selected_scrolled = 0.0f; + selected_scrolled = 0.0f; selected_item = new_selected_item; //prev_selected_item = selected_item; //page_scroll = 0.0f; clamp_selection(); + clamp_selected_item_to_body_count = 1; } void Body::clear_items() { @@ -287,6 +292,7 @@ namespace QuickMedia { selected_item = 0; prev_selected_item = selected_item; page_scroll = 0.0f; + clamp_selected_item_to_body_count = 1; } void Body::prepend_items(BodyItems new_items) { @@ -376,25 +382,11 @@ namespace QuickMedia { } bool Body::on_event(const sf::RenderWindow &window, const sf::Event &event) { - if(!experimental_use_touch) - return false; + if(event.type == sf::Event::Resized) + clamp_selected_item_to_body_count = 1; - if(!mouse_state_set) { - mouse_state_set = true; - mouse_left_pressed = sf::Mouse::isButtonPressed(sf::Mouse::Left); - if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { - auto mpos = sf::Mouse::getPosition(window); - if(sf::FloatRect(body_pos, body_size).contains(sf::Vector2f(mpos.x, mpos.y))) { - mouse_left_pressed = true; - mouse_pos_raw = sf::Mouse::getPosition(window); - mouse_pos = sf::Vector2f(mouse_pos_raw.x, mouse_pos_raw.y); - prev_mouse_pos = mouse_pos; - mouse_click_pos = mouse_pos; - mouse_press_pixels_moved_abs = 0.0; - return true; - } - } - } + if(!is_touch_enabled()) + return false; if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left && !mouse_left_pressed && sf::FloatRect(body_pos, body_size).contains(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) { mouse_left_pressed = true; @@ -404,6 +396,7 @@ namespace QuickMedia { prev_mouse_pos = mouse_pos; mouse_click_pos = mouse_pos; mouse_press_pixels_moved_abs = 0.0; + has_scrolled_with_input = true; return true; } else if(event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left && mouse_left_pressed) { mouse_left_pressed = false; @@ -437,7 +430,14 @@ namespace QuickMedia { elapsed_time_sec = draw_timer.getElapsedTime().asSeconds(); - if(experimental_use_touch) { + bool keep_selected_inside_body = clamp_selected_item_to_body_count > 0 || offset_to_top > 0.1f || offset_to_bottom > 0.1f; + if(has_scrolled_with_input) { + clamp_selected_item_to_body_count--; + if(clamp_selected_item_to_body_count < 0) + clamp_selected_item_to_body_count = 0; + } + + if(is_touch_enabled()) { float frame_time = frame_timer.restart().asSeconds(); if(frame_time > 2.0f) frame_time = 2.0f; @@ -461,6 +461,20 @@ namespace QuickMedia { } } + if(mouse_scroll_accel.y > 0.1 && first_fully_visible_item == -1) { + keep_selected_inside_body = true; + } else if(mouse_scroll_accel.y < -0.1 && last_fully_visible_item == -1) { + keep_selected_inside_body = true; + } + + if(mouse_scroll_accel.y > 0.1 && first_fully_visible_item != -1) { + selected_item = first_fully_visible_item; + clamp_selection(); + } else if(mouse_scroll_accel.y < -0.1 && last_fully_visible_item != -1) { + selected_item = last_fully_visible_item; + clamp_selection(); + } + if(!mouse_left_pressed) { const float scroll_deaccel = 1.02f; double deaccel = scroll_deaccel * (1.0 + frame_time); @@ -475,21 +489,8 @@ namespace QuickMedia { if(fabs(mouse_scroll_accel.y) < 0.0001) mouse_scroll_accel.y = 0.0; } - - if(selected_item != -1) { - if(selected_scrolled <= -selected_item_height) { - selected_scrolled += selected_item_height; - select_next_item(false); - } else if(selected_scrolled >= selected_item_height) { - selected_scrolled -= selected_item_height; - select_previous_item(false); - } - } } - //item_background.setFillColor(front_color); - //item_background.setOutlineThickness(1.0f); - //item_background.setOutlineColor(sf::Color(13, 15, 17)); item_separator.setFillColor(line_separator_color); num_visible_items = 0; first_fully_visible_item = -1; @@ -505,6 +506,7 @@ namespace QuickMedia { if(body_item->embedded_item) clear_body_item_cache(body_item->embedded_item.get()); } + first_item_fully_visible = true; last_item_fully_visible = true; items_cut_off = false; offset_to_top = 0.0f; @@ -558,37 +560,42 @@ namespace QuickMedia { selected_line_top_visible = pos.y - start_y + page_scroll >= 0.0f; selected_line_bottom_visible = pos.y - start_y + page_scroll + selected_item_height <= size.y; - if(pos.y - start_y + page_scroll >= size.y && !selected_item_fits_on_screen) - page_scroll = 0.0f; - else if(pos.y - start_y + page_scroll + selected_item_height <= 0.0f && !selected_item_fits_on_screen) - page_scroll = size.y - selected_item_height; + if(keep_selected_inside_body) { + if(pos.y - start_y + page_scroll >= size.y && !selected_item_fits_on_screen) + page_scroll = 0.0f; + else if(pos.y - start_y + page_scroll + selected_item_height <= 0.0f && !selected_item_fits_on_screen) + page_scroll = size.y - selected_item_height; + } selected_line_top_visible |= selected_item_fits_on_screen; selected_line_bottom_visible |= selected_item_fits_on_screen; - if(items_cut_off) { - if(offset_to_top > 0.0f) - page_scroll -= offset_to_top; - else if(offset_to_bottom > 0.0f) - page_scroll += offset_to_bottom; - } else { - if(attach_side == AttachSide::TOP) - page_scroll -= offset_to_top; - else if(attach_side == AttachSide::BOTTOM) - page_scroll += offset_to_bottom; - } + if(keep_selected_inside_body) { + if(items_cut_off) { + if(offset_to_top > 0.0f) + page_scroll -= offset_to_top; + else if(offset_to_bottom > 0.0f) + page_scroll += offset_to_bottom; + } else { + if(attach_side == AttachSide::TOP) + page_scroll -= offset_to_top; + else if(attach_side == AttachSide::BOTTOM) + page_scroll += offset_to_bottom; + } - if(page_scroll > size.y - selected_item_height && selected_item_fits_on_screen) { - //fprintf(stderr, "top!\n"); - page_scroll = size.y - selected_item_height; - } else if(page_scroll < 0.0f && selected_line_top_visible && selected_item_fits_on_screen) { - //fprintf(stderr, "bottom!\n"); - page_scroll = 0.0f; + if(page_scroll > size.y - selected_item_height && selected_item_fits_on_screen) { + //fprintf(stderr, "top!\n"); + page_scroll = size.y - selected_item_height; + } else if(page_scroll < 0.0f && selected_line_top_visible && selected_item_fits_on_screen) { + //fprintf(stderr, "bottom!\n"); + page_scroll = 0.0f; + } } - page_scroll = std::floor(page_scroll); + //page_scroll = std::floor(page_scroll); pos.y += page_scroll; + bool first_item_fully_visible = true; bool last_item_fully_visible_set = false; bool items_cut_off_set = false; @@ -610,6 +617,7 @@ namespace QuickMedia { if(prev_pos.y < start_y) { items_cut_off = true; items_cut_off_set = true; + first_item_fully_visible = false; } if(prev_pos.y + item_height + spacing_y <= start_y) @@ -621,7 +629,9 @@ namespace QuickMedia { draw_item(window, item.get(), prev_pos, size, item_height, i, content_progress); glDisable(GL_SCISSOR_TEST); ++num_visible_items; - first_fully_visible_item = i; + + if(first_item_fully_visible) + first_fully_visible_item = i; } offset_to_top = prev_pos.y - start_y; @@ -634,10 +644,14 @@ namespace QuickMedia { if(!item->visible) continue; - if(after_pos.y < start_y) + if(after_pos.y < start_y) { items_cut_off = true; + first_item_fully_visible = false; + } if(after_pos.y - start_y >= size.y) { + if(first_fully_visible_item == -1) + first_item_fully_visible = false; last_item_fully_visible = false; items_cut_off = true; last_item_fully_visible_set = true; @@ -664,6 +678,9 @@ namespace QuickMedia { } else { last_fully_visible_item = i; } + + if(first_item_fully_visible && first_fully_visible_item == -1) + first_fully_visible_item = i; } if(first_fully_visible_item == -1) @@ -795,15 +812,19 @@ namespace QuickMedia { return sf::Vector2f(vec.x, vec.y); } - void Body::draw_item(sf::RenderWindow &window, BodyItem *item, sf::Vector2f pos, sf::Vector2f size, bool include_embedded_item) { + void Body::draw_item(sf::RenderWindow &window, BodyItem *item, sf::Vector2f pos, sf::Vector2f size, bool include_embedded_item, bool is_embedded) { update_dirty_state(item, size.x); item->last_drawn_time = draw_timer.getElapsedTime().asMilliseconds(); sf::Vector2u window_size = window.getSize(); get_item_height(item, size.x, true, false); - glEnable(GL_SCISSOR_TEST); - glScissor(pos.x, (int)window_size.y - (int)pos.y - (int)size.y, size.x, size.y); + if(!is_embedded) { + glEnable(GL_SCISSOR_TEST); + glScissor(pos.x, (int)window_size.y - (int)pos.y - (int)size.y, size.x, size.y); + } draw_item(window, item, pos, size, size.y + spacing_y, -1, Json::Value::nullSingleton(), include_embedded_item); - glDisable(GL_SCISSOR_TEST); + if(!is_embedded) { + glDisable(GL_SCISSOR_TEST); + } } // TODO: Better message? maybe fallback to the reply message, or message status (such as message redacted) @@ -958,7 +979,7 @@ namespace QuickMedia { if(item->embedded_item) { sf::Vector2f embedded_item_pos(std::floor(item_pos.x + text_offset_x + border_width + padding_x), std::floor(item_pos.y + embedded_item_padding_y + 4.0f)); sf::Vector2f embedded_item_size(embedded_item_width, embedded_item_height); - draw_item(window, item->embedded_item.get(), embedded_item_pos, embedded_item_size, false); + draw_item(window, item->embedded_item.get(), embedded_item_pos, embedded_item_size, false, true); } else { embedded_item_load_text.setString(embedded_item_status_to_string(item->embedded_item_status)); embedded_item_load_text.setPosition(std::floor(item_pos.x + text_offset_x + border_width + padding_x), std::floor(item_pos.y + embedded_item_height * 0.5f - (embedded_item_font_size + 5.0f) * 0.5f + 4.0f)); @@ -1178,4 +1199,10 @@ namespace QuickMedia { } return true; } + + void Body::set_page_scroll(float scroll) { + selected_scrolled = 0.0f; + page_scroll = scroll; + clamp_selected_item_to_body_count = 1; + } } diff --git a/src/Entry.cpp b/src/Entry.cpp index fdd7225..5a6110c 100644 --- a/src/Entry.cpp +++ b/src/Entry.cpp @@ -17,7 +17,8 @@ namespace QuickMedia { text("", false, std::floor(16 * get_ui_scale()), 0.0f), width(0.0f), background(sf::Vector2f(1.0f, 1.0f), 7.0f, 10), - placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale())) + placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale())), + mouse_left_inside(false) { text.setEditable(true); background.setFillColor(sf::Color(55, 60, 68)); @@ -25,7 +26,24 @@ namespace QuickMedia { } void Entry::process_event(sf::Event &event) { + if(is_touch_enabled() && event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) { + sf::FloatRect box(background.getPosition(), background.getSize()); + if(box.contains(event.mouseButton.x, event.mouseButton.y)) + mouse_left_inside = true; + else + mouse_left_inside = false; + } else if(is_touch_enabled() && event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left) { + sf::FloatRect box(background.getPosition(), background.getSize()); + if(mouse_left_inside && box.contains(event.mouseButton.x, event.mouseButton.y)) + show_virtual_keyboard(); + mouse_left_inside = false; + } + + if(!text.isEditable()) + return; + text.processEvent(event); + if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter && !event.key.shift) { if(on_submit_callback) { auto u8 = text.getString().toUtf8(); @@ -43,6 +61,7 @@ namespace QuickMedia { background.setSize(sf::Vector2f(width, get_height())); if(draw_background) window.draw(background); + if(text.getString().isEmpty() && !text.isEditable()) { window.draw(placeholder); //sf::Vector2f placeholder_pos = placeholder.getPosition(); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 61b2d1b..03f1e0d 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1146,6 +1146,8 @@ namespace QuickMedia { tab.body->clear_cache(); } + hide_virtual_keyboard(); + if(new_tabs.size() == 1 && new_tabs[0].page->get_type() == PageTypez::MANGA_IMAGES) { select_episode(selected_item, false); Body *chapters_body = tabs[selected_tab].body.get(); @@ -1189,15 +1191,19 @@ namespace QuickMedia { body_set_selected_item(tabs[selected_tab].body.get(), selected_item); current_page = PageType::CHAT; current_chat_room = matrix->get_room_by_id(selected_item->url); + while(window.isOpen()) { bool move_room = chat_page(static_cast(new_tabs[0].page.get()), current_chat_room, tabs, selected_tab, tab_associated_data[selected_tab]); if(!move_room) break; + BodyItem *selected_item = tabs[selected_tab].body->get_selected(); if(!selected_item) break; + current_chat_room = matrix->get_room_by_id(selected_item->url); } + tabs[selected_tab].body->body_item_select_callback = [&submit_handler](BodyItem *body_item) { submit_handler(); }; @@ -1206,15 +1212,19 @@ namespace QuickMedia { } else { page_loop(new_tabs); } + for(Tab &tab : tabs) { tab.page->on_navigate_to_page(tab.body.get()); } + if(content_storage_json.isObject()) { const Json::Value &chapters_json = content_storage_json["chapters"]; if(chapters_json.isObject()) json_chapters = &chapters_json; } + redraw = true; + hide_virtual_keyboard(); }; for(size_t i = 0; i < tabs.size(); ++i) { @@ -2758,8 +2768,8 @@ namespace QuickMedia { } event_idle_handler(event); + comment_input.process_event(event); if(navigation_stage == NavigationStage::REPLYING && !frame_skip_text_entry) { - comment_input.process_event(event); // To prevent pressing enter in comment_input text submit from also immediately sending captcha solution.. is there no better solution? if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter) break; @@ -3259,7 +3269,7 @@ namespace QuickMedia { pinned_tab.body->thumbnail_max_size = CHAT_MESSAGE_THUMBNAIL_MAX_SIZE; pinned_tab.body->thumbnail_mask_shader = &circle_mask_shader; pinned_tab.body->attach_side = AttachSide::BOTTOM; - //pinned_tab.body->line_separator_color = sf::Color::Transparent; + pinned_tab.body->line_separator_color = sf::Color::Transparent; pinned_tab.text = sf::Text("Pinned messages", *FontLoader::get_font(FontLoader::FontType::LATIN), tab_text_size); tabs.push_back(std::move(pinned_tab)); @@ -3268,7 +3278,7 @@ namespace QuickMedia { messages_tab.body->thumbnail_max_size = CHAT_MESSAGE_THUMBNAIL_MAX_SIZE; messages_tab.body->thumbnail_mask_shader = &circle_mask_shader; messages_tab.body->attach_side = AttachSide::BOTTOM; - //messages_tab.body->line_separator_color = sf::Color::Transparent; + messages_tab.body->line_separator_color = sf::Color::Transparent; messages_tab.text = sf::Text("Messages", *FontLoader::get_font(FontLoader::FontType::LATIN), tab_text_size); tabs.push_back(std::move(messages_tab)); @@ -3312,6 +3322,9 @@ namespace QuickMedia { const float room_name_total_height = room_name_text_height + room_name_text_padding_y * 2.0f; const float room_avatar_height = 32.0f; + sf::Text room_label(room_tabs[room_selected_tab].page->get_title(), *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD), std::floor(18 * get_ui_scale())); + room_label.setPosition(15.0f, room_name_text_padding_y + 4.0f); + sf::Sprite room_avatar_sprite; auto room_avatar_thumbnail_data = std::make_shared(); @@ -3323,7 +3336,7 @@ namespace QuickMedia { bool setting_read_marker = false; bool redraw = true; - bool draw_room_list = true; + bool draw_room_list = show_room_side_panel; // TODO: Optimize with hash map? auto find_body_item_by_event_id = [](std::shared_ptr *body_items, size_t num_body_items, const std::string &event_id, size_t *index_result = nullptr) -> std::shared_ptr { @@ -4312,9 +4325,12 @@ namespace QuickMedia { base_event_handler(event, PageType::EXIT, tabs[selected_tab].body.get(), nullptr, false, false); event_idle_handler(event); + chat_input.process_event(event); - if(draw_room_list) - room_tabs[room_selected_tab].body->on_event(window, event); + if(draw_room_list) { + if(room_tabs[room_selected_tab].body->on_event(window, event)) + idle_active_handler(); + } if(event.type == sf::Event::KeyPressed && event.key.control && event.key.alt && (chat_state == ChatState::NAVIGATING || chat_state == ChatState::URL_SELECTION)) { if(event.key.code == sf::Keyboard::Up || (event.key.control && event.key.code == sf::Keyboard::K)) { @@ -4584,8 +4600,6 @@ namespace QuickMedia { typing_state_queue.push(false); } } - //chat_input.on_event(event); - chat_input.process_event(event); } } frame_skip_text_entry = false; @@ -4831,14 +4845,6 @@ namespace QuickMedia { window.clear(back_color); - if(draw_room_list) { - sf::RectangleShape room_list_background(this->body_size); - room_list_background.setPosition(this->body_pos); - room_list_background.setFillColor(sf::Color(31, 35, 41)); - window.draw(room_list_background); - room_tabs[room_selected_tab].body->draw(window, this->body_pos, this->body_size, Json::Value::nullSingleton()); - } - const float width_per_tab = body_size.x / tabs.size(); tab_background.setSize(sf::Vector2f(std::floor(width_per_tab - tab_margin_x * 2.0f), tab_height)); @@ -4848,8 +4854,8 @@ namespace QuickMedia { 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) + room_name_padding_y; - tab_shade.setSize(sf::Vector2f(window_size.x, tab_shade_height)); - window.draw(tab_shade); + //tab_shade.setSize(sf::Vector2f(window_size.x, tab_shade_height)); + //window.draw(tab_shade); if(selected_tab == MESSAGES_TAB_INDEX || selected_tab == PINNED_TAB_INDEX) { float room_name_text_offset_x = 0.0f; @@ -4865,6 +4871,18 @@ namespace QuickMedia { window.draw(room_name_text); } + if(draw_room_list) { + sf::RectangleShape room_list_background(sf::Vector2f(this->body_size.x, window_size.y)); + //room_list_background.setPosition(this->body_pos); + room_list_background.setFillColor(sf::Color(31, 35, 41)); + glEnable(GL_SCISSOR_TEST); + glScissor(0.0f, 0.0f, this->body_size.x, window_size.y); + window.draw(room_list_background); + window.draw(room_label); + room_tabs[room_selected_tab].body->draw(window, sf::Vector2f(0.0f, tab_y), sf::Vector2f(this->body_size.x, window_size.y - tab_y), Json::Value::nullSingleton()); + glDisable(GL_SCISSOR_TEST); + } + int i = 0; for(ChatTab &tab : tabs) { if(i == selected_tab) { @@ -4957,7 +4975,7 @@ namespace QuickMedia { } if(selected_tab == MESSAGES_TAB_INDEX && current_room) { - window.draw(chat_input_shade); + //window.draw(chat_input_shade); chat_input.draw(window); //chat_input.draw(window, false); window.draw(logo_sprite); } diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp index 26b00a4..df7d951 100644 --- a/src/SearchBar.cpp +++ b/src/SearchBar.cpp @@ -39,6 +39,7 @@ namespace QuickMedia { input_masked(input_masked), typing(false), backspace_pressed(false), + mouse_left_inside(false), vertical_pos(0.0f) { text.setFillColor(text_placeholder_color); @@ -97,10 +98,24 @@ namespace QuickMedia { auto clipboard = sf::Clipboard::getString().toUtf8(); append_text(std::string(clipboard.begin(), clipboard.end())); } + if(event.type == sf::Event::TextEntered && event.text.unicode != 8 && event.text.unicode != 127) // 8 = backspace, 127 = del onTextEntered(event.text.unicode); else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Backspace) onTextEntered(8); + + if(is_touch_enabled() && event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) { + sf::FloatRect box(background.getPosition(), background.getSize()); + if(box.contains(event.mouseButton.x, event.mouseButton.y)) + mouse_left_inside = true; + else + mouse_left_inside = false; + } else if(is_touch_enabled() && event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left) { + sf::FloatRect box(background.getPosition(), background.getSize()); + if(mouse_left_inside && box.contains(event.mouseButton.x, event.mouseButton.y)) + show_virtual_keyboard(); + mouse_left_inside = false; + } } void SearchBar::update() { diff --git a/src/Text.cpp b/src/Text.cpp index 32ba360..ee6bd55 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -383,7 +383,7 @@ namespace QuickMedia vertices[vertices_index].append({ vertexBottomRight, sf::Color::White, textureBottomRight }); vertices[vertices_index].append({ vertexTopRight, sf::Color::White, textureTopRight }); - glyphPos.x += emoji_rec.width + characterSpacing; + glyphPos.x += std::floor(emoji_rec.width * get_ui_scale()) + characterSpacing; vertices_linear.push_back({vertices_index, vertexStart, 0, codePoint}); } continue; diff --git a/src/Utils.cpp b/src/Utils.cpp index 2c3bfb7..2a36d27 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -7,6 +7,8 @@ namespace QuickMedia { static float scale = 1.0f; static bool scale_set = false; + static bool qm_enable_touch = false; + static bool qm_enable_touch_set = false; static const int XFT_DPI_DEFAULT = 96; // Returns 96 on error @@ -55,4 +57,32 @@ namespace QuickMedia { scale_set = true; return scale; } + + void show_virtual_keyboard() { + if(!is_touch_enabled()) + return; + + fprintf(stderr, "Show virtual keyboard\n"); + system("busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true"); + } + + void hide_virtual_keyboard() { + if(!is_touch_enabled()) + return; + + fprintf(stderr, "Hide virtual keyboard\n"); + system("busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false"); + } + + bool is_touch_enabled() { + if(qm_enable_touch_set) + return qm_enable_touch; + + const char *qm_enable_touch_env = getenv("QM_ENABLE_TOUCH"); + if(qm_enable_touch_env && qm_enable_touch_env[0] == '1') + qm_enable_touch = true; + + qm_enable_touch_set = true; + return qm_enable_touch; + } } \ No newline at end of file -- cgit v1.2.3