diff options
Diffstat (limited to 'src/Body.cpp')
-rw-r--r-- | src/Body.cpp | 173 |
1 files changed, 100 insertions, 73 deletions
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; + } } |