diff options
Diffstat (limited to 'src/Body.cpp')
-rw-r--r-- | src/Body.cpp | 113 |
1 files changed, 88 insertions, 25 deletions
diff --git a/src/Body.cpp b/src/Body.cpp index ffafb90..d7a4456 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -284,6 +284,8 @@ namespace QuickMedia { page_scroll = 0.0f; clamp_selection(); clamp_selected_item_to_body_count = 1; + //item_background_target_pos_y = body_pos.y; + //item_background.set_position(sf::Vector2f(body_pos.x, item_background_target_pos_y)); } void Body::select_last_item() { @@ -294,6 +296,8 @@ namespace QuickMedia { //page_scroll = 0.0f; clamp_selection(); clamp_selected_item_to_body_count = 1; + //item_background_target_pos_y = body_pos.y + body_size.y - item_background.get_size().y; + //item_background.set_position(sf::Vector2f(body_pos.x, item_background_target_pos_y)); } void Body::clear_items() { @@ -304,6 +308,8 @@ namespace QuickMedia { prev_selected_item = selected_item; page_scroll = 0.0f; clamp_selected_item_to_body_count = 1; + //item_background_target_pos_y = body_pos.y; + //item_background.set_position(sf::Vector2f(body_pos.x, item_background_target_pos_y)); } void Body::prepend_items(BodyItems new_items) { @@ -481,6 +487,9 @@ namespace QuickMedia { sf::Vector2f scissor_pos = pos; sf::Vector2f scissor_size = size; const float start_y = pos.y; + float frame_time = frame_timer.restart().asSeconds(); + if(frame_time > 2.0f) + frame_time = 2.0f; body_pos = pos; bool body_size_changed = std::abs(size.x - body_size.x) > 0.1f || std::abs(size.y - body_size.y) > 0.1f; @@ -489,26 +498,33 @@ namespace QuickMedia { elapsed_time_sec = draw_timer.getElapsedTime().asSeconds(); + const bool scroll_past_first = first_item_fully_visible && offset_to_top > 0.1f; + const bool scroll_past_last = last_item_fully_visible && offset_to_bottom > 0.1f; + + if((attach_side == AttachSide::BOTTOM && scroll_past_first) || (attach_side == AttachSide::TOP && scroll_past_last)) + body_size_changed = true; + 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; - } + 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; - const sf::Vector2f mouse_pos_diff(mouse_pos_raw.x - mouse_pos.x, mouse_pos_raw.y - mouse_pos.y); const float move_speed = 25.0f; - mouse_pos.x += (mouse_pos_diff.x * frame_time * move_speed); - mouse_pos.y += (mouse_pos_diff.y * frame_time * move_speed); + mouse_pos.x += (mouse_pos_diff.x * std::min(1.0f, frame_time * move_speed)); + mouse_pos.y += (mouse_pos_diff.y * std::min(1.0f, frame_time * move_speed)); sf::Vector2f mouse_smooth_diff(mouse_pos.x - prev_mouse_pos.x, mouse_pos.y - prev_mouse_pos.y); prev_mouse_pos = mouse_pos; + if(mouse_left_pressed && (scroll_past_first || scroll_past_last)) { + mouse_scroll_accel.x = 0.0f; + mouse_scroll_accel.y = 0.0f; + mouse_pos.x = mouse_pos_raw.x; + mouse_pos.y = mouse_pos_raw.y; + } + if(items_cut_off) { if(mouse_left_pressed) { selected_scrolled += mouse_smooth_diff.y; @@ -531,14 +547,14 @@ namespace QuickMedia { clamp_selection(); // TODO: Cache this if(on_top_reached) { - int first_visible_item = -1; + int first_visible_item_n = -1; for(int i = 0; i <= selected_item; ++i) { if(items[i]->visible) { - first_visible_item = i; + first_visible_item_n = i; break; } } - if(first_visible_item == first_fully_visible_item) + if(first_visible_item_n == first_fully_visible_item) on_top_reached(); } } else if(mouse_scroll_accel.y < -0.1 && last_fully_visible_item != -1) { @@ -546,14 +562,14 @@ namespace QuickMedia { clamp_selection(); // TODO: Cache this if(on_bottom_reached) { - int last_visible_item = -1; + int last_visible_item_n = -1; for(int i = items.size() - 1; i >= selected_item; --i) { if(items[i]->visible) { - last_visible_item = i; + last_visible_item_n = i; break; } } - if(last_visible_item == last_fully_visible_item) + if(last_visible_item_n == last_fully_visible_item) on_bottom_reached(); } } @@ -574,10 +590,28 @@ namespace QuickMedia { } } - item_separator.setFillColor(line_separator_color); + const double scroll_diff = extra_scroll_target - extra_scroll_current; + const double scroll_move_speed = 25.0; + extra_scroll_current += (scroll_diff * std::min(1.0, frame_time * scroll_move_speed)); + + double scroll_smooth_diff = extra_scroll_current - prev_extra_scroll; + prev_extra_scroll = extra_scroll_current; + + selected_scrolled += scroll_smooth_diff; + + bool selected_item_fits_on_screen = selected_item_height <= size.y; + if(selected_item_fits_on_screen && render_selected_item_bg && !first_item_fully_visible && !last_item_fully_visible && items_cut_off && (selected_item == first_visible_item || selected_item == last_visible_item || selected_item == first_fully_visible_item || selected_item == last_fully_visible_item)) { + page_scroll += scroll_smooth_diff; + keep_selected_inside_body = false; + } + + //item_separator.setFillColor(line_separator_color); + const int prev_num_visible_items = num_visible_items; num_visible_items = 0; first_fully_visible_item = -1; last_fully_visible_item = -1; + first_visible_item = -1; + last_visible_item = -1; selected_line_top_visible = true; selected_line_bottom_visible = true; @@ -594,7 +628,8 @@ namespace QuickMedia { offset_to_top = 0.0f; offset_to_bottom = 0.0f; mouse_left_clicked = false; - last_visible_item = -1; + //item_background_target_pos_y = body_pos.y; + //item_background.set_position(sf::Vector2f(body_pos.x, item_background_target_pos_y)); return; } @@ -615,6 +650,7 @@ namespace QuickMedia { int i = prev_selected_item; const int prev_body_item_index = get_previous_visible_item(i); BodyItem *prev_body_item = prev_body_item_index == -1 ? nullptr : items[prev_body_item_index].get(); + double scroll_before = page_scroll; while(num_items_scrolled < selected_int_diff_abs && i < num_items) { if(items[i]->visible) { const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item, items[i].get()); @@ -628,10 +664,13 @@ namespace QuickMedia { ++i; } prev_selected_item = selected_item; + if(selected_item_fits_on_screen) + extra_scroll_target -= (page_scroll - scroll_before); } else if(selected_item_diff < 0) { int num_items_scrolled = 0; int i = prev_selected_item - 1; BodyItem *prev_body_item; + double scroll_before = page_scroll; while(num_items_scrolled < selected_int_diff_abs && i >= 0) { if(items[i]->visible) { const int prev_body_item_index = get_previous_visible_item(i); @@ -646,6 +685,8 @@ namespace QuickMedia { --i; } prev_selected_item = selected_item; + if(selected_item_fits_on_screen) + extra_scroll_target -= (page_scroll - scroll_before); } bool merge_with_previous = false; @@ -669,7 +710,8 @@ namespace QuickMedia { } else if(attach_side == AttachSide::BOTTOM) { if(last_item_fully_visible) { page_scroll += offset_to_bottom; - } else { + } else if(first_item_fully_visible && !last_item_fully_visible && body_size_changed) { + page_scroll -= offset_to_top; //page_scroll = get_offset_to_last_visible_item(size); } } @@ -678,7 +720,7 @@ namespace QuickMedia { selected_item_height = get_item_height(items[selected_item].get(), size.x, true, true, merge_with_previous, selected_item); selected_item_height += spacing_y; - bool selected_item_fits_on_screen = selected_item_height <= size.y; + selected_item_fits_on_screen = selected_item_height <= size.y; 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; @@ -719,6 +761,25 @@ namespace QuickMedia { sf::Vector2u window_size = window.getSize(); + if(prev_num_visible_items > 0) { + const float item_background_prev_pos_y = item_background.get_position().y; + const float item_background_pos_diff = item_background_target_pos_y - item_background_prev_pos_y; + const float item_background_move_speed = 50.0f; + item_background.set_position(sf::Vector2f(pos.x, item_background_prev_pos_y + (item_background_pos_diff * std::min(1.0f, frame_time * item_background_move_speed)))); + + const float item_background_prev_height = item_background.get_size().y; + const float item_background_height_diff = item_background_target_height - item_background_prev_height; + const float item_background_height_speed = 50.0f; + item_background.set_size(sf::Vector2f(size.x, item_background_prev_height + (item_background_height_diff * std::min(1.0f, frame_time * item_background_height_speed)))); + + if(render_selected_item_bg) { + glEnable(GL_SCISSOR_TEST); + glScissor(scissor_pos.x, (int)window_size.y - (int)scissor_pos.y - (int)scissor_size.y, scissor_size.x, scissor_size.y); + item_background.draw(window); + glDisable(GL_SCISSOR_TEST); + } + } + sf::Vector2f prev_pos = pos; int i; for(i = selected_item - 1; i >= 0;) { @@ -753,6 +814,7 @@ namespace QuickMedia { draw_item(window, item.get(), prev_pos, size, item_height, i, content_progress, true, merge_with_previous); glDisable(GL_SCISSOR_TEST); ++num_visible_items; + first_visible_item = i; last_visible_item = i; if(first_item_fully_visible) @@ -810,6 +872,8 @@ namespace QuickMedia { after_pos.y += item_height; after_pos.y += spacing_y; ++num_visible_items; + if(first_visible_item == -1) + first_visible_item = i; last_visible_item = i; int next_body_item_index = get_next_visible_item(i); @@ -1125,10 +1189,9 @@ namespace QuickMedia { //item_separator.setPosition(item_pos + sf::Vector2f(10.0f, std::floor(item_height + spacing_y * 0.5f))); //window.draw(item_separator); - if(render_selected_item_bg && item_index == selected_item) { - item_background.set_position(item_pos); - item_background.set_size(sf::Vector2f(size.x, item_height)); - item_background.draw(window); + if(item_index == selected_item) { + item_background_target_pos_y = item_pos.y; + item_background_target_height = item_height; } float text_offset_x = padding_x; |