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