aboutsummaryrefslogtreecommitdiff
path: root/src/Body.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Body.cpp')
-rw-r--r--src/Body.cpp113
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;