aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Body.cpp699
-rw-r--r--src/Entry.cpp2
-rw-r--r--src/QuickMedia.cpp60
-rw-r--r--src/RoundedRectangle.cpp13
-rw-r--r--src/SearchBar.cpp5
-rw-r--r--src/Tabs.cpp92
-rw-r--r--src/plugins/Fourchan.cpp4
-rw-r--r--src/plugins/Page.cpp4
-rw-r--r--src/plugins/Soundcloud.cpp6
-rw-r--r--src/plugins/Youtube.cpp2
10 files changed, 585 insertions, 302 deletions
diff --git a/src/Body.cpp b/src/Body.cpp
index ffd9337..c0d2a74 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -29,6 +29,16 @@ struct BodySpacing {
float embedded_item_font_size = 0.0f;
};
+static const int card_width = 250.0f * QuickMedia::get_ui_scale();
+static const int card_height = 350.0f * QuickMedia::get_ui_scale();
+
+static const int min_column_spacing = 10 * QuickMedia::get_ui_scale();
+static const int card_padding_x = 20 * QuickMedia::get_ui_scale();
+static const int card_padding_y = 20 * QuickMedia::get_ui_scale();
+static const int card_image_text_padding = 10 * QuickMedia::get_ui_scale();
+static const sf::Vector2i card_max_image_size(card_width - card_padding_x * 2, (card_height - card_padding_y * 2) / 2);
+static const int num_columns_switch_to_list = 1;
+
static BodySpacing body_spacing[2];
static bool themes_initialized = false;
@@ -76,6 +86,10 @@ namespace QuickMedia {
themes_initialized = true;
}
+ static sf::Vector2f to_vec2f(const sf::Vector2i &vec) {
+ return sf::Vector2f(vec.x, vec.y);
+ }
+
BodyItem::BodyItem(std::string _title) :
visible(true),
dirty(false),
@@ -162,7 +176,7 @@ namespace QuickMedia {
num_visible_items(0),
top_cut_off(false),
bottom_cut_off(false),
- item_background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(55, 60, 68), rounded_rectangle_shader),
+ item_background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(60, 65, 73), rounded_rectangle_shader),
reaction_background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(33, 37, 44), rounded_rectangle_shader),
rounded_rectangle_mask_shader(rounded_rectangle_mask_shader)
{
@@ -188,10 +202,10 @@ namespace QuickMedia {
// TODO: For plugins with different sized body items this can be weird, because after scrolling down thumbnails could load and they could move items up/down until we see items we haven't seen
bool Body::select_previous_page() {
if(!selected_item_fits_in_body)
- return select_previous_item(false);
+ return select_previous_item(false, true);
for(int i = 0; i < num_visible_items - 1; ++i) {
- if(!select_previous_item(false))
+ if(!select_previous_item(false, true))
return false;
}
return true;
@@ -201,44 +215,62 @@ namespace QuickMedia {
// TODO: For plugins with different sized body items this can be weird, because after scrolling down thumbnails could load and they could move items up/down until we see items we haven't seen
bool Body::select_next_page() {
if(!selected_item_fits_in_body)
- return select_next_item(false);
+ return select_next_item(false, true);
for(int i = 0; i < num_visible_items - 1; ++i) {
- if(!select_next_item(false))
+ if(!select_next_item(false, true))
return false;
}
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 ignore_columns) {
if(items.empty())
return false;
- if(scroll_page_if_large_item && !selected_item_fits_in_body && !selected_line_top_visible) {
+ if(num_columns == 1 && scroll_page_if_large_item && !selected_item_fits_in_body && !selected_line_top_visible) {
selected_scrolled += 128.0f;
return true;
}
- const int new_selected_item = get_previous_visible_item(selected_item);
- if(new_selected_item == -1)
- return false;
+ int new_selected_item = selected_item;
+ for(int i = 0; i < (ignore_columns ? 1 : num_columns); ++i) {
+ const int prev = new_selected_item;
+ new_selected_item = get_previous_visible_item(new_selected_item);
+ if(new_selected_item == -1) {
+ if(i == 0)
+ return false;
+
+ new_selected_item = prev;
+ break;
+ }
+ }
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 ignore_columns) {
if(items.empty())
return false;
- if(scroll_page_if_large_item && !selected_item_fits_in_body && !selected_line_bottom_visible) {
+ if(num_columns == 1 && scroll_page_if_large_item && !selected_item_fits_in_body && !selected_line_bottom_visible) {
selected_scrolled -= 128.0f;
return true;
}
- const int new_selected_item = get_next_visible_item(selected_item);
- if(new_selected_item == -1)
- return false;
+ int new_selected_item = selected_item;
+ for(int i = 0; i < (ignore_columns ? 1 : num_columns); ++i) {
+ const int prev = new_selected_item;
+ new_selected_item = get_next_visible_item(new_selected_item);
+ if(new_selected_item == -1) {
+ if(i == 0)
+ return false;
+
+ new_selected_item = prev;
+ break;
+ }
+ }
selected_item = new_selected_item;
return true;
@@ -388,6 +420,8 @@ namespace QuickMedia {
bool Body::on_event(const sf::RenderWindow &window, const sf::Event &event, bool keyboard_navigation) {
if(keyboard_navigation && event.type == sf::Event::KeyPressed && !event.key.alt) {
+ const bool rendering_card_view = card_view && card_view_enabled;
+
if(event.key.code == sf::Keyboard::Up || (event.key.control && event.key.code == sf::Keyboard::K)) {
render_selected_item_bg = true;
bool top_reached = select_previous_item(true);
@@ -400,6 +434,24 @@ namespace QuickMedia {
if(!bottom_reached && on_bottom_reached)
on_bottom_reached();
return true;
+ } else if(rendering_card_view && selected_column > 0 && (event.key.code == sf::Keyboard::Left || (event.key.control && event.key.code == sf::Keyboard::H))) {
+ render_selected_item_bg = true;
+ const int new_selected_item = get_previous_visible_item(selected_item);
+ if(new_selected_item != -1) {
+ selected_item = new_selected_item;
+ } else if(on_top_reached) {
+ on_top_reached();
+ }
+ return true;
+ } else if(rendering_card_view && selected_column + 1 < num_columns && (event.key.code == sf::Keyboard::Right || (event.key.control && event.key.code == sf::Keyboard::L))) {
+ render_selected_item_bg = true;
+ const int new_selected_item = get_next_visible_item(selected_item);
+ if(new_selected_item != -1) {
+ selected_item = new_selected_item;
+ } else if(on_bottom_reached) {
+ on_bottom_reached();
+ }
+ return true;
} else if(event.key.code == sf::Keyboard::Home) {
render_selected_item_bg = true;
select_first_item(false);
@@ -468,12 +520,14 @@ namespace QuickMedia {
if(!show_drop_shadow)
return;
+ const sf::Color color(21, 25, 30);
const float height = 5.0f;
+
sf::Vertex gradient_points[4];
- gradient_points[0] = sf::Vertex(body_pos + sf::Vector2f(0.0f, 0.0f), sf::Color(21, 25, 30));
- gradient_points[1] = sf::Vertex(body_pos + sf::Vector2f(body_size.x, 0.0f), sf::Color(21, 25, 30));
- gradient_points[2] = sf::Vertex(body_pos + sf::Vector2f(body_size.x, height), sf::Color(0, 0, 0, 0));
- gradient_points[3] = sf::Vertex(body_pos + sf::Vector2f(0.0f, height), sf::Color(0, 0, 0, 0));
+ gradient_points[0] = sf::Vertex(body_pos + sf::Vector2f(0.0f, 0.0f), color);
+ gradient_points[1] = sf::Vertex(body_pos + sf::Vector2f(body_size.x, 0.0f), color);
+ gradient_points[2] = sf::Vertex(body_pos + sf::Vector2f(body_size.x, height), sf::Color(color.r, color.g, color.b, 0));
+ gradient_points[3] = sf::Vertex(body_pos + sf::Vector2f(0.0f, height), sf::Color(color.r, color.g, color.b, 0));
window.draw(gradient_points, 4, sf::Quads);
}
@@ -490,7 +544,9 @@ namespace QuickMedia {
items_dirty = DirtyState::FALSE;
}
- bool body_size_changed = std::abs(size.x - body_size.x) > 0.1f || std::abs(size.y - body_size.y) > 0.1f;
+ const bool rendering_card_view = card_view && card_view_enabled;
+
+ const bool body_size_changed = std::abs(size.x - body_size.x) > 0.1f || std::abs(size.y - body_size.y) > 0.1f;
if(body_size_changed)
body_size = size;
@@ -498,11 +554,14 @@ namespace QuickMedia {
const float scissor_y = pos.y;
pos.y = 0.0f;
- pos.x += body_spacing[body_theme].body_padding_horizontal;
+ if(!rendering_card_view)
+ pos.x += body_spacing[body_theme].body_padding_horizontal;
+
if(attach_side == AttachSide::TOP)
pos.y += body_spacing[body_theme].body_padding_vertical;
- size.x = std::max(0.0f, size.x - body_spacing[body_theme].body_padding_horizontal * 2.0f);
+ if(!rendering_card_view)
+ size.x = std::max(0.0f, size.x - body_spacing[body_theme].body_padding_horizontal * 2.0f);
float frame_time = frame_timer.restart().asSeconds();
if(frame_time > 0.01666f)
@@ -532,6 +591,8 @@ namespace QuickMedia {
selected_item_fits_in_body = true;
top_cut_off = false;
bottom_cut_off = false;
+ num_columns = 1;
+ selected_column = 0;
const int selected_item_diff = selected_item - prev_selected_item;
prev_selected_item = selected_item;
@@ -618,19 +679,23 @@ namespace QuickMedia {
if(swiping_enabled && grabbed_left_side)
pos.x += body_swipe_x;
- const int selected_prev_item = get_previous_visible_item(selected_item);
- const bool selected_merge_with_previous = selected_prev_item != -1 && body_item_merge_handler && body_item_merge_handler(items[selected_prev_item].get(), items[selected_item].get());
- get_item_height(items[selected_item].get(), size.x, true, true, selected_merge_with_previous, selected_item);
- selected_item_fits_in_body = items[selected_item]->last_loaded_height < size.y;
- if(selected_item_fits_in_body)
- selected_scrolled = 0.0f;
+ if(!rendering_card_view) {
+ const int selected_prev_item = get_previous_visible_item(selected_item);
+ const bool selected_merge_with_previous = selected_prev_item != -1 && body_item_merge_handler && body_item_merge_handler(items[selected_prev_item].get(), items[selected_item].get());
+ get_item_height(items[selected_item].get(), size.x, true, true, selected_merge_with_previous, selected_item);
+ selected_item_fits_in_body = items[selected_item]->last_loaded_height < size.y;
+ if(selected_item_fits_in_body)
+ selected_scrolled = 0.0f;
+ }
const sf::Vector2u window_size = window.getSize();
const sf::View prev_view = window.getView();
- sf::View new_view(sf::FloatRect(0.0f, 0.0f, window_size.x, size.y));
- new_view.setViewport(sf::FloatRect(0.0f, scissor_y / (float)window_size.y, 1.0f, size.y / (float)window_size.y));
- window.setView(new_view);
+ if(!rendering_card_view) {
+ sf::View new_view(sf::FloatRect(0.0f, 0.0f, window_size.x, size.y));
+ new_view.setViewport(sf::FloatRect(0.0f, scissor_y / (float)window_size.y, 1.0f, size.y / (float)window_size.y));
+ window.setView(new_view);
+ }
bool instant_move = body_size_changed;
if(target_y_set == TargetSetState::SET) {
@@ -640,155 +705,25 @@ namespace QuickMedia {
const float speed = 30.0f;
- const float item_background_height_diff = item_background_target_height - item_background_prev_height;
- const float item_background_height_speed = instant_move ? 1000.0f : speed;
- const float item_background_new_height = item_background_prev_height + (item_background_height_diff * std::min(1.0f, frame_time * item_background_height_speed));
- item_background.set_size(sf::Vector2f(size.x, item_background_new_height));
- item_background_prev_height = item_background_new_height;
+ const sf::Vector2f item_background_size_diff = item_background_target_size - item_background_prev_size;
+ const float item_background_size_speed = instant_move ? 1000.0f : speed;
+ const sf::Vector2f item_background_new_size = item_background_prev_size + (item_background_size_diff * std::min(1.0f, frame_time * item_background_size_speed));
+ item_background_prev_size = item_background_new_size;
- const float item_background_pos_diff = item_background_target_pos_y - item_background_prev_pos_y;
+ const sf::Vector2f item_background_pos_diff = item_background_target_pos - item_background_prev_pos;
const float item_background_move_speed = instant_move ? 1000.0f : speed;
- float item_background_new_pos_y = item_background_prev_pos_y + (item_background_pos_diff * std::min(1.0f, frame_time * item_background_move_speed));
+ sf::Vector2f item_background_new_pos = item_background_prev_pos + (item_background_pos_diff * std::min(1.0f, frame_time * item_background_move_speed));
if(selected_item_fits_in_body) {
- item_background_new_pos_y = std::min(item_background_new_pos_y, size.y - item_background_new_height - body_spacing[body_theme].spacing_y);
- item_background_new_pos_y = std::max(item_background_new_pos_y, 0.0f);
+ item_background_new_pos.y = std::min(item_background_new_pos.y, size.y - item_background_new_size.y - body_spacing[body_theme].spacing_y);
+ item_background_new_pos.y = std::max(item_background_new_pos.y, 0.0f);
}
- item_background.set_position(sf::Vector2f(pos.x, item_background_new_pos_y));
- item_background_prev_pos_y = item_background_new_pos_y;
+ item_background_prev_pos = item_background_new_pos;
- if(prev_num_visible_items > 0 && render_selected_item_bg && body_theme == BODY_THEME_MINIMAL) {
- item_background.set_color(sf::Color(55, 60, 68));
- item_background.set_band(0.0f, 0.0f);
- item_background.draw(window);
- }
-
- int index;
- if(attach_side == AttachSide::TOP) {
- if(page_scroll > 0.0)
- page_scroll = 0.0;
- pos.y += page_scroll;
- index = get_next_visible_item(-1);
-
- if(pos.y + selected_scrolled > 0.0f)
- selected_scrolled = 0.0f;
+ float body_total_height = 0.0f;
+ if(rendering_card_view) {
+ draw_card_view(window, pos, size, window_size, scissor_y);
} else {
- if(page_scroll < 0.0)
- page_scroll = 0.0;
- pos.y += size.y;
- pos.y += page_scroll;
- index = get_previous_visible_item(num_items);
-
- if(pos.y + selected_scrolled < size.y)
- selected_scrolled = 0.0f;
- }
-
- pos.y += selected_scrolled;
- const float pos_y_start = pos.y;
-
- BodyItem *prev_body_item = nullptr;
- const double height_move_speed = 1000.0f;
-
- // TODO: Improve performance. Skip items that are obviously not visible or anywhere near the body. Limit loop to 100-200 items around the selected item
- while(index != -1) {
- BodyItem *item = items[index].get();
- assert(item->visible);
-
- int prev_index;
- if(attach_side == AttachSide::BOTTOM) {
- prev_index = get_previous_visible_item(index);
- if(prev_index == -1)
- prev_body_item = nullptr;
- else
- prev_body_item = items[prev_index].get();
- }
-
- const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item, item);
- if(attach_side == AttachSide::TOP && merge_with_previous)
- pos.y -= body_spacing[body_theme].spacing_y;
-
- get_item_height(item, size.x, false, true, merge_with_previous, index);
- const float item_height_diff = item->last_loaded_height - item->current_loaded_height;
- const float add_height = item_height_diff * std::min(1.0, frame_time * height_move_speed);
- item->current_loaded_height += add_height;
- //page_scroll += add_height;
-
- float top_y;
- if(attach_side == AttachSide::TOP)
- top_y = pos.y;
- else
- top_y = pos.y - (item->current_loaded_height + body_spacing[body_theme].spacing_y);
-
- if(top_y < 0.0f) {
- top_cut_off = true;
- if(index == selected_item)
- selected_line_top_visible = false;
- }
-
- if(top_y + item->current_loaded_height > size.y) {
- bottom_cut_off = true;
- if(index == selected_item)
- selected_line_bottom_visible = false;
- }
-
- const bool is_item_visible_in_body = top_y + item->current_loaded_height >= 0.0f && top_y <= size.y;
- if(is_item_visible_in_body || index == selected_item) {
- get_item_height(item, size.x, true, true, merge_with_previous, index);
- const float item_height_diff = item->last_loaded_height - item->current_loaded_height;
- const float add_height = item_height_diff * std::min(1.0, frame_time * height_move_speed);
- item->current_loaded_height += add_height;
- if(attach_side == AttachSide::BOTTOM)
- pos.y -= (item->current_loaded_height + body_spacing[body_theme].spacing_y);
- //page_scroll += add_height;
-
- //const float top_y_clamped = clamp(pos.y, 0.0f, size.y);
- //const float bottom_y_clamped = std::min(pos.y + item->current_loaded_height, size.y);
-
- //float offset_y = 0.0f;
- //if(pos.y < 0.0f)
- // offset_y = pos.y;
- //else if(pos.y > size.y)
- // offset_y = size.y - pos.y;
-
- //sf::View new_view(sf::FloatRect(0.0f, 0.0f, window_size.x, scissor_y + bottom_y_clamped));
- //new_view.setViewport(sf::FloatRect(0.0f, (scissor_y + top_y_clamped) / (float)window_size.y, 1.0f, (scissor_y + bottom_y_clamped) / (float)window_size.y));
- //window.setView(new_view);
-
- draw_item(window, item, pos/*sf::Vector2f(pos.x, offset_y)*/, size, item->current_loaded_height, index, content_progress, true, merge_with_previous);
- handle_item_render(item, pos, size, item->current_loaded_height, index);
- ++num_visible_items;
-
- if(first_visible_item == -1 || index < first_visible_item)
- first_visible_item = index;
- if(last_visible_item == -1 || index > last_visible_item)
- last_visible_item = index;
-
- if(attach_side == AttachSide::TOP)
- pos.y += (item->current_loaded_height + body_spacing[body_theme].spacing_y);
- } else {
- if(attach_side == AttachSide::TOP)
- pos.y += (item->current_loaded_height + body_spacing[body_theme].spacing_y);
- else
- pos.y -= (item->current_loaded_height + body_spacing[body_theme].spacing_y);
-
- if(item->keep_alive_frames == 0) {
- clear_body_item_cache(item);
- // TODO: Make sure the embedded item is not referencing another item in the |items| list
- if(item->embedded_item)
- clear_body_item_cache(item->embedded_item.get());
- } else {
- --item->keep_alive_frames;
- }
- }
-
- if(attach_side == AttachSide::BOTTOM && merge_with_previous)
- pos.y += body_spacing[body_theme].spacing_y;
-
- if(attach_side == AttachSide::TOP) {
- prev_body_item = item;
- index = get_next_visible_item(index);
- } else {
- index = prev_index;
- }
+ body_total_height = draw_list_view(window, pos, size, prev_num_visible_items, content_progress);
}
window.setView(prev_view);
@@ -797,14 +732,15 @@ namespace QuickMedia {
// TODO: Move up where scroll is limited? then we wont delay this by 1 frame creating a small scroll overflow only in the opposite direction of attach side.
// Also take |selected_scrolled| into consideration
// Limit scroll in the opposide direction of attach side, since the scroll is already limited for the attach side above (with a simple check)
- if(attach_side == AttachSide::TOP) {
- const float body_total_height = pos.y - pos_y_start;
- if(top_cut_off && !bottom_cut_off && body_total_height > (size.y - body_spacing[body_theme].body_padding_vertical))
- page_scroll = -(body_total_height - (size.y - body_spacing[body_theme].body_padding_vertical));
- } else {
- const float body_total_height = pos_y_start - pos.y;
- if(bottom_cut_off && !top_cut_off && body_total_height > size.y)
- page_scroll = (body_total_height - size.y);
+ if(!rendering_card_view) {
+ if(attach_side == AttachSide::TOP) {
+ if(top_cut_off && !bottom_cut_off && body_total_height > (size.y - body_spacing[body_theme].body_padding_vertical))
+ page_scroll = -(body_total_height - (size.y - body_spacing[body_theme].body_padding_vertical));
+ } else {
+ body_total_height = -body_total_height;
+ if(bottom_cut_off && !top_cut_off && body_total_height > size.y)
+ page_scroll = (body_total_height - size.y);
+ }
}
mouse_left_clicked = false;
@@ -818,8 +754,8 @@ namespace QuickMedia {
if(is_touch_enabled())
return;
- const float item_target_top_diff = item_background_target_pos_y - selected_scrolled - body_spacing[body_theme].body_padding_vertical;
- const float item_target_bottom_diff = (item_background_target_pos_y - selected_scrolled + item_background_target_height + body_spacing[body_theme].spacing_y) - size.y;
+ const float item_target_top_diff = item_background_target_pos.y - selected_scrolled - body_spacing[body_theme].body_padding_vertical;
+ const float item_target_bottom_diff = (item_background_target_pos.y - selected_scrolled + item_background_target_size.y + body_spacing[body_theme].spacing_y) - size.y;
if(item_target_top_diff < 0.0f || !selected_item_fits_in_body) {
//extra_scroll_target -= item_target_top_diff;
stuck_direction = StuckDirection::TOP;
@@ -855,10 +791,12 @@ namespace QuickMedia {
body_item->dirty = false;
// TODO: Find a way to optimize fromUtf8
sf::String str = sf::String::fromUtf8(body_item->get_title().begin(), body_item->get_title().end());
- if(body_item->title_text)
+ if(body_item->title_text) {
body_item->title_text->setString(std::move(str));
- else
+ body_item->title_text->setMaxWidth(width);
+ } else {
body_item->title_text = std::make_unique<Text>(std::move(str), false, std::floor(16 * get_ui_scale()), width, title_mark_urls);
+ }
body_item->title_text->setFillColor(body_item->get_title_color());
body_item->title_text->updateGeometry();
}
@@ -866,10 +804,12 @@ namespace QuickMedia {
if(body_item->dirty_description) {
body_item->dirty_description = false;
sf::String str = sf::String::fromUtf8(body_item->get_description().begin(), body_item->get_description().end());
- if(body_item->description_text)
+ if(body_item->description_text) {
body_item->description_text->setString(std::move(str));
- else
+ body_item->description_text->setMaxWidth(width);
+ } else {
body_item->description_text = std::make_unique<Text>(std::move(str), false, std::floor(14 * get_ui_scale()), width, true);
+ }
body_item->description_text->setFillColor(body_item->get_description_color());
body_item->description_text->updateGeometry();
}
@@ -877,10 +817,12 @@ namespace QuickMedia {
if(body_item->dirty_author) {
body_item->dirty_author = false;
sf::String str = sf::String::fromUtf8(body_item->get_author().begin(), body_item->get_author().end());
- if(body_item->author_text)
+ if(body_item->author_text) {
body_item->author_text->setString(std::move(str));
- else
+ body_item->author_text->setMaxWidth(width);
+ } else {
body_item->author_text = std::make_unique<Text>(std::move(str), true, std::floor(14 * get_ui_scale()), width);
+ }
body_item->author_text->setFillColor(body_item->get_author_color());
body_item->author_text->updateGeometry();
}
@@ -907,10 +849,11 @@ namespace QuickMedia {
*/
strftime(time_str, sizeof(time_str) - 1, "%a %b %d %H:%M", &message_tm);
- if(body_item->timestamp_text)
+ if(body_item->timestamp_text) {
body_item->timestamp_text->setString(time_str);
- else
+ } else {
body_item->timestamp_text = std::make_unique<sf::Text>(time_str, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(10 * get_ui_scale()));
+ }
body_item->timestamp_text->setFillColor(sf::Color(185, 190, 198, 100));
}
@@ -940,7 +883,7 @@ namespace QuickMedia {
sf::Vector2i Body::get_item_thumbnail_size(BodyItem *item) const {
sf::Vector2i content_size;
- sf::Vector2i thumbnail_max_size_scaled(std::floor(thumbnail_max_size.x * get_ui_scale()), std::floor(thumbnail_max_size.y * get_ui_scale()));
+ sf::Vector2i thumbnail_max_size_scaled = card_view_enabled ? card_max_image_size : sf::Vector2i(thumbnail_max_size.x * get_ui_scale(), thumbnail_max_size.y * get_ui_scale());
if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
content_size = clamp_to_size(sf::Vector2i(std::floor(item->thumbnail_size.x * get_ui_scale()), std::floor(item->thumbnail_size.y * get_ui_scale())), thumbnail_max_size_scaled);
else
@@ -966,11 +909,8 @@ namespace QuickMedia {
return -1;
}
- static sf::Vector2f to_vec2f(const sf::Vector2i &vec) {
- 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, bool is_embedded) {
+ // TODO: What about when |card_view| is used?
item->keep_alive_frames = 3;
get_item_height(item, size.x, true, false, false, -1);
draw_item(window, item, pos, size, size.y + body_spacing[body_theme].spacing_y, -1, Json::Value::nullSingleton(), include_embedded_item);
@@ -992,9 +932,9 @@ namespace QuickMedia {
return "";
}
- void Body::handle_item_render(BodyItem *item, const sf::Vector2f pos, const sf::Vector2f size, const float item_height, int item_index) {
+ void Body::handle_item_render(const sf::Vector2f pos, const float item_width, const float item_height, int item_index) {
if(body_item_select_callback && mouse_left_clicked && !clicked_body_item && click_counts && std::abs(mouse_scroll_accel.y) < 5.0f) {
- sf::FloatRect item_box(pos + body_pos, sf::Vector2f(size.x, item_height));
+ sf::FloatRect item_box(pos + body_pos, sf::Vector2f(item_width, item_height));
if(item_box.contains(mouse_click_pos) && item_box.contains(mouse_release_pos) && mouse_press_pixels_moved_abs <= 25.0) {
clicked_body_item = items[item_index];
set_selected_item(item_index, false);
@@ -1002,23 +942,341 @@ namespace QuickMedia {
}
if(item_index == selected_item) {
- item_background_target_pos_y = pos.y;
- item_background_target_height = item_height;
+ item_background_target_pos = pos;
+ item_background_target_size = sf::Vector2f(item_width, item_height);
if(target_y_set == TargetSetState::NOT_SET)
target_y_set = TargetSetState::SET;
}
}
- static sf::Color interpolate_colors(sf::Color source, sf::Color target, double progress) {
- int diff_r = (int)target.r - (int)source.r;
- int diff_g = (int)target.g - (int)source.g;
- int diff_b = (int)target.b - (int)source.b;
- int diff_a = (int)target.a - (int)source.a;
- return sf::Color(
- source.r + diff_r * progress,
- source.g + diff_g * progress,
- source.b + diff_b * progress,
- source.a + diff_a * progress);
+ float Body::draw_list_view(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const int prev_num_visible_items, const Json::Value &content_progress) {
+ const int num_items = items.size();
+
+ if(prev_num_visible_items > 0 && render_selected_item_bg && body_theme == BODY_THEME_MINIMAL) {
+ item_background.set_position(sf::Vector2f(pos.x, item_background_prev_pos.y));
+ item_background.set_size(item_background_prev_size);
+ item_background.set_color(sf::Color(60, 65, 73));
+ item_background.set_band(sf::Vector2f(0.0f, 0.0f), sf::Vector2f(0.0f, 0.0f));
+ item_background.draw(window);
+ }
+
+ int index;
+ if(attach_side == AttachSide::TOP) {
+ if(page_scroll > 0.0)
+ page_scroll = 0.0;
+ pos.y += page_scroll;
+ index = get_next_visible_item(-1);
+
+ if(pos.y + selected_scrolled > 0.0f)
+ selected_scrolled = 0.0f;
+ } else {
+ if(page_scroll < 0.0)
+ page_scroll = 0.0;
+ pos.y += size.y;
+ pos.y += page_scroll;
+ index = get_previous_visible_item(num_items);
+
+ if(pos.y + selected_scrolled < size.y)
+ selected_scrolled = 0.0f;
+ }
+
+ pos.y += selected_scrolled;
+ const float pos_y_start = pos.y;
+
+ BodyItem *prev_body_item = nullptr;
+
+ // TODO: Improve performance. Skip items that are obviously not visible or anywhere near the body. Limit loop to 100-200 items around the selected item
+ while(index != -1) {
+ BodyItem *item = items[index].get();
+ assert(item->visible);
+
+ int prev_index;
+ if(attach_side == AttachSide::BOTTOM) {
+ prev_index = get_previous_visible_item(index);
+ if(prev_index == -1)
+ prev_body_item = nullptr;
+ else
+ prev_body_item = items[prev_index].get();
+ }
+
+ const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item, item);
+ if(attach_side == AttachSide::TOP && merge_with_previous)
+ pos.y -= body_spacing[body_theme].spacing_y;
+
+ get_item_height(item, size.x, false, true, merge_with_previous, index);
+ item->current_loaded_height = item->last_loaded_height;
+
+ float top_y;
+ if(attach_side == AttachSide::TOP)
+ top_y = pos.y;
+ else
+ top_y = pos.y - (item->current_loaded_height + body_spacing[body_theme].spacing_y);
+
+ if(top_y < 0.0f) {
+ top_cut_off = true;
+ if(index == selected_item)
+ selected_line_top_visible = false;
+ }
+
+ if(top_y + item->current_loaded_height > size.y) {
+ bottom_cut_off = true;
+ if(index == selected_item)
+ selected_line_bottom_visible = false;
+ }
+
+ const bool is_item_visible_in_body = top_y + item->current_loaded_height >= 0.0f && top_y <= size.y;
+ if(is_item_visible_in_body || index == selected_item) {
+ get_item_height(item, size.x, true, true, merge_with_previous, index);
+ item->current_loaded_height = item->last_loaded_height;
+ if(attach_side == AttachSide::BOTTOM)
+ pos.y -= (item->current_loaded_height + body_spacing[body_theme].spacing_y);
+ //page_scroll += add_height;
+
+ //const float top_y_clamped = clamp(pos.y, 0.0f, size.y);
+ //const float bottom_y_clamped = std::min(pos.y + item->current_loaded_height, size.y);
+
+ //float offset_y = 0.0f;
+ //if(pos.y < 0.0f)
+ // offset_y = pos.y;
+ //else if(pos.y > size.y)
+ // offset_y = size.y - pos.y;
+
+ //sf::View new_view(sf::FloatRect(0.0f, 0.0f, window_size.x, scissor_y + bottom_y_clamped));
+ //new_view.setViewport(sf::FloatRect(0.0f, (scissor_y + top_y_clamped) / (float)window_size.y, 1.0f, (scissor_y + bottom_y_clamped) / (float)window_size.y));
+ //window.setView(new_view);
+
+ draw_item(window, item, pos/*sf::Vector2f(pos.x, offset_y)*/, size, item->current_loaded_height, index, content_progress, true, merge_with_previous);
+ handle_item_render(pos, size.x, item->current_loaded_height, index);
+ ++num_visible_items;
+
+ if(first_visible_item == -1 || index < first_visible_item)
+ first_visible_item = index;
+ if(last_visible_item == -1 || index > last_visible_item)
+ last_visible_item = index;
+
+ if(attach_side == AttachSide::TOP)
+ pos.y += (item->current_loaded_height + body_spacing[body_theme].spacing_y);
+ } else {
+ if(attach_side == AttachSide::TOP)
+ pos.y += (item->current_loaded_height + body_spacing[body_theme].spacing_y);
+ else
+ pos.y -= (item->current_loaded_height + body_spacing[body_theme].spacing_y);
+
+ if(item->keep_alive_frames == 0) {
+ clear_body_item_cache(item);
+ // TODO: Make sure the embedded item is not referencing another item in the |items| list
+ if(item->embedded_item)
+ clear_body_item_cache(item->embedded_item.get());
+ } else {
+ --item->keep_alive_frames;
+ }
+ }
+
+ if(attach_side == AttachSide::BOTTOM && merge_with_previous)
+ pos.y += body_spacing[body_theme].spacing_y;
+
+ if(attach_side == AttachSide::TOP) {
+ prev_body_item = item;
+ index = get_next_visible_item(index);
+ } else {
+ index = prev_index;
+ }
+ }
+
+ return pos.y - pos_y_start;
+ }
+
+ void Body::draw_card_view(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, sf::Vector2u window_size, float scissor_y) {
+ num_columns = size.x / card_width;
+
+ int space_left_column = size.x - (num_columns * card_width);
+ int space_left_column_each = 0;
+ // TODO: Spacing for 1 column
+ if(num_columns > 1) {
+ space_left_column_each = space_left_column / (2 + num_columns - 1);
+ if(space_left_column_each < min_column_spacing) {
+ num_columns = (size.x + min_column_spacing) / (card_width + min_column_spacing);
+ //space_left_column_each = min_column_spacing;
+ space_left_column = size.x - (num_columns * card_width);
+ space_left_column_each = num_columns <= 1 ? 0 : space_left_column / (2 + num_columns - 1);
+ }
+ }
+
+ if(num_columns <= num_columns_switch_to_list) {
+ num_columns = 1;
+ card_view_enabled = false;
+ draw(window, body_pos, body_size);
+ card_view_enabled = true;
+ return;
+ }
+
+ const int space_left_row_each = space_left_column_each;
+
+ //item_background.set_band_color(sf::Color(60, 65, 73));
+ //item_background.set_band(item_background_prev_pos_y - pos.y, item_background_prev_height);
+
+ if(page_scroll > 0.0)
+ page_scroll = 0.0;
+
+ int item_index = 0;
+ int drawn_column_index = 0;
+ int num_visible_rows = 1;
+ const int num_items = items.size();
+ sf::Vector2f pos_offset(space_left_column_each, page_scroll);
+
+ while(item_index < num_items) {
+ BodyItem *item = items[item_index].get();
+
+ if(pos_offset.y + card_height <= -body_spacing[body_theme].body_padding_vertical) {
+ top_cut_off = true;
+ if(item_index == selected_item)
+ selected_line_top_visible = false;
+ }
+
+ if(pos_offset.y >= size.y) {
+ bottom_cut_off = true;
+ if(item_index == selected_item)
+ selected_line_bottom_visible = false;
+ }
+
+ if(item_index == selected_item)
+ selected_column = drawn_column_index;
+
+ handle_item_render(pos + pos_offset, card_width, card_height, item_index);
+
+ if(item->visible && pos_offset.y + card_height > -body_spacing[body_theme].body_padding_vertical && pos_offset.y < size.y) {
+ sf::View new_view(sf::FloatRect(0.0f, 0.0f, window_size.x, size.y));
+ new_view.setViewport(sf::FloatRect(0.0f, scissor_y / (float)window_size.y, 1.0f, size.y / (float)window_size.y));
+ window.setView(new_view);
+
+ item_background.set_position(pos + pos_offset);
+ item_background.set_size(sf::Vector2f(card_width, card_height));
+ item_background.set_color(sf::Color(33, 37, 44));
+ item_background.set_band(item_background_prev_pos - (pos + pos_offset), item_background_prev_size);
+ item_background.set_band_color(sf::Color(60, 65, 73));
+ item_background.draw(window);
+
+ {
+ get_item_height(item, card_max_image_size.x);
+ sf::Vector2i thumbnail_size = get_item_thumbnail_size(item);
+ std::shared_ptr<ThumbnailData> item_thumbnail;
+ if(draw_thumbnails && !item->thumbnail_url.empty())
+ item_thumbnail = AsyncImageLoader::get_instance().get_thumbnail(item->thumbnail_url, item->thumbnail_is_local, thumbnail_size);
+
+ float image_height = 0.0f;
+ if(item_thumbnail && item_thumbnail->loading_state == LoadingState::APPLIED_TO_TEXTURE && item_thumbnail->texture.getNativeHandle() != 0) {
+ image.setTexture(item_thumbnail->texture, true);
+ auto image_size = image.getTexture()->getSize();
+ sf::Vector2f image_size_f(image_size.x, image_size.y);
+ sf::Vector2f content_size = to_vec2f(thumbnail_size);
+ auto new_image_size = clamp_to_size(image_size_f, content_size);
+ auto image_scale = get_ratio(image_size_f, new_image_size);
+ image.setScale(image_scale);
+ image.setPosition(pos + pos_offset + sf::Vector2f(card_padding_x, card_padding_y) + sf::Vector2f(card_max_image_size.x * 0.5f, 0.0f) - sf::Vector2f(new_image_size.x * 0.5f, 0.0f));
+ image_height = new_image_size.y;
+ if(thumbnail_mask_shader && item->thumbnail_mask_type == ThumbnailMaskType::CIRCLE) {
+ thumbnail_mask_shader->setUniform("resolution", new_image_size);
+ window.draw(image, thumbnail_mask_shader);
+ } else if(rounded_rectangle_mask_shader) {
+ rounded_rectangle_mask_shader->setUniform("radius", 10.0f);
+ rounded_rectangle_mask_shader->setUniform("resolution", new_image_size);
+ window.draw(image, rounded_rectangle_mask_shader);
+ } else {
+ window.draw(image);
+ }
+ } else if(!item->thumbnail_url.empty()) {
+ sf::Vector2f content_size = to_vec2f(thumbnail_size);
+ sf::Vector2f loading_icon_size(loading_icon.getTexture()->getSize().x, loading_icon.getTexture()->getSize().y);
+ auto new_loading_icon_size = clamp_to_size(loading_icon_size, content_size);
+ loading_icon.setPosition(pos + pos_offset + sf::Vector2f(card_padding_x, card_padding_y) + to_vec2f(card_max_image_size) * 0.5f);
+ loading_icon.setScale(get_ratio(loading_icon_size, new_loading_icon_size));
+ loading_icon.setRotation(elapsed_time_sec * 400.0);
+ window.draw(loading_icon);
+ image_height = content_size.y;
+ }
+
+ const float text_padding = item_thumbnail ? card_image_text_padding : 0.0f;
+
+ sf::Vector2f text_pos = sf::Vector2f(pos.x, scissor_y + body_spacing[body_theme].body_padding_vertical) + pos_offset + sf::Vector2f(card_padding_x, card_padding_y) + sf::Vector2f(0.0f, image_height + text_padding);
+ const float text_height = (card_height - card_padding_y * 2.0f) - image_height - text_padding;
+
+ const float underflow_text = text_pos.y - scissor_y;
+ const float underflow_height = underflow_text < 0.0f ? text_height + underflow_text : text_height;
+ sf::View new_view(sf::FloatRect(0.0f, 0.0f, window_size.x, underflow_height));
+ new_view.setViewport(sf::FloatRect(0.0f, std::max(text_pos.y, scissor_y) / (float)window_size.y, 1.0f, underflow_height / (float)window_size.y));
+ window.setView(new_view);
+
+ text_pos.y = std::min(0.0f, underflow_text);
+ float text_offset_y = 0.0f;
+ if(item->author_text) {
+ item->author_text->setPosition(text_pos);
+ item->author_text->setMaxWidth(card_max_image_size.x);
+ item->author_text->draw(window);
+ text_offset_y += item->author_text->getHeight();
+ }
+
+ if(item->title_text) {
+ item->title_text->setPosition(text_pos + sf::Vector2f(0.0f, text_offset_y));
+ item->title_text->setMaxWidth(card_max_image_size.x);
+ item->title_text->draw(window);
+ text_offset_y += item->title_text->getHeight();
+ }
+
+ if(item->description_text) {
+ item->description_text->setPosition(text_pos + sf::Vector2f(0.0f, text_offset_y));
+ item->description_text->setMaxWidth(card_max_image_size.x);
+ item->description_text->draw(window);
+ text_offset_y += item->description_text->getHeight();
+ }
+
+ const float gradient_height = 5.0f;
+ if(text_offset_y >= text_height - gradient_height) {
+ const sf::Vector2f card_bottom(text_pos.x, text_height);
+ const sf::Color color = item_index == selected_item ? sf::Color(60, 65, 73) : sf::Color(33, 37, 44);
+
+ sf::Vertex gradient_points[4];
+ gradient_points[0] = sf::Vertex(card_bottom + sf::Vector2f(0.0f, -gradient_height), sf::Color(color.r, color.g, color.b, 0));
+ gradient_points[1] = sf::Vertex(card_bottom + sf::Vector2f(card_max_image_size.x, -gradient_height), sf::Color(color.r, color.g, color.b, 0));
+ gradient_points[2] = sf::Vertex(card_bottom + sf::Vector2f(card_max_image_size.x, 0.0f), color);
+ gradient_points[3] = sf::Vertex(card_bottom + sf::Vector2f(0.0f, 0.0f), color);
+ window.draw(gradient_points, 4, sf::Quads);
+ }
+ }
+
+ ++num_visible_items;
+ if(first_visible_item == -1 || item_index < first_visible_item)
+ first_visible_item = item_index;
+ if(last_visible_item == -1 || item_index > last_visible_item)
+ last_visible_item = item_index;
+ } else {
+ if(item->keep_alive_frames == 0) {
+ clear_body_item_cache(item);
+ // TODO: Make sure the embedded item is not referencing another item in the |items| list
+ if(item->embedded_item)
+ clear_body_item_cache(item->embedded_item.get());
+ } else {
+ --item->keep_alive_frames;
+ }
+ }
+
+ if(item->visible) {
+ pos_offset.x += card_width + space_left_column_each;
+ ++drawn_column_index;
+
+ if(drawn_column_index == num_columns) {
+ drawn_column_index = 0;
+ ++num_visible_rows;
+ pos_offset.x = space_left_column_each;
+ pos_offset.y += card_height + space_left_row_each;
+ }
+ }
+
+ ++item_index;
+ }
+
+ /*const float body_total_height = num_visible_rows * (card_height + space_left_row_each);
+ if(top_cut_off && !bottom_cut_off && body_total_height > size.y)
+ page_scroll = -(body_total_height - (size.y - body_spacing[body_theme].body_padding_vertical));*/
}
void Body::draw_item(sf::RenderWindow &window, BodyItem *item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress, bool include_embedded_item, bool merge_with_previous) {
@@ -1040,8 +1298,8 @@ namespace QuickMedia {
item_background.set_size(sf::Vector2f(size.x, item_height));
item_background.set_position(item_pos);
item_background.set_color(sf::Color(33, 37, 44));
- item_background.set_band(item_background_prev_pos_y - pos.y, item_background_prev_height);
- item_background.set_band_color(sf::Color(55, 60, 68));
+ item_background.set_band(item_background_prev_pos - pos, item_background_prev_size);
+ item_background.set_band_color(sf::Color(60, 65, 73));
item_background.draw(window);
}
@@ -1103,12 +1361,13 @@ namespace QuickMedia {
text_offset_x += body_spacing[body_theme].image_padding_x + thumbnail_size.x;
}
+ const float text_max_width = size.x - text_offset_x - body_spacing[body_theme].image_padding_x;
const float text_offset_y = std::floor(6.0f * get_ui_scale());
const float timestamp_text_y = std::floor(item_pos.y + padding_y - text_offset_y);
if(item->author_text && !merge_with_previous) {
item->author_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - text_offset_y));
- item->author_text->setMaxWidth(size.x - text_offset_x - body_spacing[body_theme].image_padding_x);
+ item->author_text->setMaxWidth(text_max_width);
item->author_text->draw(window);
sf::Vector2f replies_text_pos = item->author_text->getPosition() + sf::Vector2f(0.0f, 5.0f);
@@ -1153,7 +1412,7 @@ namespace QuickMedia {
//window.draw(title_text);
if(item->title_text) {
item->title_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - text_offset_y));
- item->title_text->setMaxWidth(size.x - text_offset_x - body_spacing[body_theme].image_padding_x);
+ item->title_text->setMaxWidth(text_max_width);
item->title_text->draw(window);
item_pos.y += item->title_text->getHeight() - 2.0f + std::floor(3.0f * get_ui_scale());
}
@@ -1161,7 +1420,7 @@ namespace QuickMedia {
if(item->description_text) {
float height_offset = 0.0f;
item->description_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - text_offset_y) + height_offset);
- item->description_text->setMaxWidth(size.x - text_offset_x - body_spacing[body_theme].image_padding_x);
+ item->description_text->setMaxWidth(text_max_width);
item->description_text->draw(window);
item_pos.y += item->description_text->getHeight() - 2.0f;
}
@@ -1173,7 +1432,7 @@ namespace QuickMedia {
// TODO: Fix first row wrap-around
for(int i = 0; i < item->reactions.size(); ++i) {
auto &reaction = item->reactions[i];
- reaction.text->setMaxWidth(size.x - text_offset_x - body_spacing[body_theme].image_padding_x);
+ reaction.text->setMaxWidth(text_max_width);
reaction.text->updateGeometry();
reaction_max_height = std::max(reaction_max_height, reaction.text->getHeight());
reaction.text->setPosition(std::floor(item_pos.x + text_offset_x + reaction_offset_x + body_spacing[body_theme].reaction_background_padding_x), std::floor(item_pos.y + padding_y - 4.0f + body_spacing[body_theme].reaction_background_padding_y));
@@ -1251,8 +1510,10 @@ namespace QuickMedia {
// image_height = content_size.y;
}
+ const float text_max_width = (card_view && card_view_enabled) ? width : (width - text_offset_x - body_spacing[body_theme].image_padding_x);
+
if(load_texture)
- update_dirty_state(item, width - text_offset_x - body_spacing[body_theme].image_padding_x);
+ update_dirty_state(item, text_max_width);
float item_height = 0.0f;
if(item->title_text) {
@@ -1277,7 +1538,7 @@ namespace QuickMedia {
float reaction_max_height = 0.0f;
for(int i = 0; i < item->reactions.size(); ++i) {
auto &reaction = item->reactions[i];
- reaction.text->setMaxWidth(width - text_offset_x - body_spacing[body_theme].image_padding_x);
+ reaction.text->setMaxWidth(text_max_width);
reaction.text->updateGeometry();
reaction_max_height = std::max(reaction_max_height, reaction.text->getHeight());
reaction_offset_x += reaction.text->getWidth() + body_spacing[body_theme].reaction_background_padding_x * 2.0f + body_spacing[body_theme].reaction_spacing_x;
diff --git a/src/Entry.cpp b/src/Entry.cpp
index 7e1b6d9..28e3034 100644
--- a/src/Entry.cpp
+++ b/src/Entry.cpp
@@ -16,7 +16,7 @@ namespace QuickMedia {
draw_background(true),
text("", false, std::floor(16 * get_ui_scale()), 0.0f),
width(0.0f),
- background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(55, 60, 68), rounded_rectangle_shader),
+ background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(60, 65, 73), rounded_rectangle_shader),
placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale())),
mouse_left_inside(false)
{
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 9670f68..2926637 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -1056,7 +1056,7 @@ namespace QuickMedia {
}
if(strcmp(plugin_name, "launcher") == 0) {
- auto pipe_body = create_body(true);
+ auto pipe_body = create_body();
pipe_body->items.push_back(create_launcher_body_item("4chan", "4chan", resources_root + "icons/4chan_launcher.png"));
pipe_body->items.push_back(create_launcher_body_item("Manga (all)", "manga", ""));
pipe_body->items.push_back(create_launcher_body_item("Mangadex", "mangadex", resources_root + "icons/mangadex_launcher.png"));
@@ -1074,33 +1074,33 @@ namespace QuickMedia {
pipe_body->items.push_back(create_launcher_body_item("YouTube (audio only)", "youtube-audio", resources_root + "icons/yt_launcher.png"));
tabs.push_back(Tab{std::move(pipe_body), std::make_unique<PipePage>(this, "Select plugin to launch"), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "manganelo") == 0) {
- tabs.push_back(Tab{create_body(), std::make_unique<ManganeloSearchPage>(this), create_search_bar("Search...", 400)});
+ tabs.push_back(Tab{create_body(false, true), std::make_unique<ManganeloSearchPage>(this), create_search_bar("Search...", 400)});
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA);
tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "manganelos") == 0) {
auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "http://manganelos.com/");
add_manganelos_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)});
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA);
tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "mangatown") == 0) {
auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "https://www.mangatown.com/");
add_mangatown_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)});
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA);
tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "mangakatana") == 0) {
auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "https://mangakatana.com/", false);
add_mangakatana_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)});
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA);
tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "mangadex") == 0) {
- tabs.push_back(Tab{create_body(), std::make_unique<MangadexSearchPage>(this), create_search_bar("Search...", 400)});
+ tabs.push_back(Tab{create_body(false, true), std::make_unique<MangadexSearchPage>(this), create_search_bar("Search...", 400)});
upgrade_legacy_mangadex_ids(this, tabs.back().page.get());
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA);
@@ -1108,7 +1108,7 @@ namespace QuickMedia {
} else if(strcmp(plugin_name, "readm") == 0) {
auto search_page = std::make_unique<MangaGenericSearchPage>(this, plugin_name, "https://readm.org/");
add_readm_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 400)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 400)});
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::MANGA);
tabs.push_back(Tab{create_body(), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
@@ -1172,33 +1172,33 @@ namespace QuickMedia {
tabs.push_back(Tab{std::move(pipe_body), std::make_unique<PipePage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "youtube") == 0) {
start_tab_index = 1;
- tabs.push_back(Tab{create_body(), std::make_unique<YoutubeSubscriptionsPage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
- tabs.push_back(Tab{create_body(), std::make_unique<YoutubeSearchPage>(this), create_search_bar("Search...", 350)});
+ tabs.push_back(Tab{create_body(false, true), std::make_unique<YoutubeSubscriptionsPage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ tabs.push_back(Tab{create_body(false, true), std::make_unique<YoutubeSearchPage>(this), create_search_bar("Search...", 350)});
auto recommended_page = std::make_unique<YoutubeRecommendedPage>(this);
- tabs.push_back(Tab{create_body(), std::move(recommended_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ tabs.push_back(Tab{create_body(false, true), std::move(recommended_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
- auto history_body = create_body();
+ auto history_body = create_body(false, true);
auto history_page = std::make_unique<HistoryPage>(this, tabs.front().page.get(), HistoryType::YOUTUBE);
tabs.push_back(Tab{std::move(history_body), std::move(history_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "pornhub") == 0) {
auto search_page = std::make_unique<MediaGenericSearchPage>(this, "https://www.pornhub.com/", sf::Vector2i(320/1.5f, 180/1.5f));
add_pornhub_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 500)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 500)});
} else if(strcmp(plugin_name, "spankbang") == 0) {
auto search_page = std::make_unique<MediaGenericSearchPage>(this, "https://spankbang.com/", sf::Vector2i(500/2.5f, 281/2.5f));
add_spankbang_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 500)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 500)});
} else if(strcmp(plugin_name, "xvideos") == 0) {
auto search_page = std::make_unique<MediaGenericSearchPage>(this, "https://www.xvideos.com/", sf::Vector2i(352/1.5f, 198/1.5f));
add_xvideos_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 500)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 500)});
} else if(strcmp(plugin_name, "xhamster") == 0) {
auto search_page = std::make_unique<MediaGenericSearchPage>(this, "https://xhamster.com/", sf::Vector2i(240, 135));
add_xhamster_handlers(search_page.get());
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 500)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 500)});
} else if(strcmp(plugin_name, "soundcloud") == 0) {
- tabs.push_back(Tab{create_body(), std::make_unique<SoundcloudSearchPage>(this), create_search_bar("Search...", 500)});
+ tabs.push_back(Tab{create_body(false, true), std::make_unique<SoundcloudSearchPage>(this), create_search_bar("Search...", 500)});
no_video = true;
} else if(strcmp(plugin_name, "matrix") == 0) {
assert(!matrix);
@@ -1418,8 +1418,9 @@ namespace QuickMedia {
body_size = sf::Vector2f(body_width, window_size.y - search_bottom - tab_h);
}
- std::unique_ptr<Body> Program::create_body(bool plain_text_list) {
+ std::unique_ptr<Body> Program::create_body(bool plain_text_list, bool prefer_card_view) {
auto body = std::make_unique<Body>(plain_text_list ? BODY_THEME_MINIMAL : BODY_THEME_MODERN_SPACIOUS, loading_icon, &rounded_rectangle_shader, &rounded_rectangle_mask_shader);
+ body->card_view = prefer_card_view;
body->thumbnail_mask_shader = &circle_mask_shader;
return body;
}
@@ -1592,7 +1593,7 @@ namespace QuickMedia {
Tabs ui_tabs(&rounded_rectangle_shader);
for(auto &tab : tabs) {
- ui_tabs.add_tab(tab.page->get_title());
+ ui_tabs.add_tab(tab.page->get_title(), tab.body.get());
}
ui_tabs.set_selected(start_tab_index);
@@ -2607,18 +2608,18 @@ namespace QuickMedia {
std::vector<Tab> tabs;
if(search_page) {
- tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", search_delay)});
+ tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", search_delay)});
}
if(comments_page) {
tabs.push_back(Tab{create_body(), std::move(comments_page), nullptr});
}
if(related_videos_page) {
- auto related_videos_body = create_body();
+ auto related_videos_body = create_body(false, true);
related_videos_body->items = related_videos;
tabs.push_back(Tab{std::move(related_videos_body), std::move(related_videos_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
}
if(channels_page) {
- tabs.push_back(Tab{create_body(), std::move(channels_page), create_search_bar("Search...", 350)});
+ tabs.push_back(Tab{create_body(false, true), std::move(channels_page), create_search_bar("Search...", 350)});
}
bool page_changed = false;
@@ -3915,14 +3916,9 @@ namespace QuickMedia {
bool redraw = true;
sf::Event event;
- auto body = create_body();
-
while (current_page == PageType::CHAT_LOGIN && window.isOpen()) {
while (window.pollEvent(event)) {
- if(body->on_event(window, event))
- idle_active_handler();
- else
- event_idle_handler(event);
+ event_idle_handler(event);
if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
@@ -3939,6 +3935,7 @@ namespace QuickMedia {
}
focused_input = (focused_input + 1) % num_inputs;
inputs[focused_input]->caret_visible = true;
+ idle_active_handler();
}
inputs[focused_input]->on_event(event);
}
@@ -3961,7 +3958,6 @@ namespace QuickMedia {
}
window.clear(back_color);
- body->draw(window, body_pos, body_size);
background.draw(window);
for(int i = 0; i < num_inputs; ++i) {
inputs[i]->update();
@@ -4156,9 +4152,9 @@ namespace QuickMedia {
}
Tabs ui_tabs(&rounded_rectangle_shader, is_touch_enabled() ? sf::Color::Transparent : back_color);
- const int PINNED_TAB_INDEX = ui_tabs.add_tab("Pinned messages (0)");
- const int MESSAGES_TAB_INDEX = ui_tabs.add_tab("Messages");
- const int USERS_TAB_INDEX = ui_tabs.add_tab("Users (0)");
+ const int PINNED_TAB_INDEX = ui_tabs.add_tab("Pinned messages (0)", tabs[0].body.get());
+ const int MESSAGES_TAB_INDEX = ui_tabs.add_tab("Messages", tabs[1].body.get());
+ const int USERS_TAB_INDEX = ui_tabs.add_tab("Users (0)", tabs[2].body.get());
ui_tabs.set_selected(MESSAGES_TAB_INDEX);
matrix_chat_page->chat_body = tabs[MESSAGES_TAB_INDEX].body.get();
@@ -6591,7 +6587,7 @@ namespace QuickMedia {
auto search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER);
Tabs ui_tabs(&rounded_rectangle_shader);
- const int tab_path_index = ui_tabs.add_tab(file_manager_start_dir);
+ const int tab_path_index = ui_tabs.add_tab(file_manager_start_dir, file_manager_body.get());
search_bar->onTextUpdateCallback = [&file_manager_body](const std::string &text) {
file_manager_body->filter_search_fuzzy(text);
diff --git a/src/RoundedRectangle.cpp b/src/RoundedRectangle.cpp
index 494a254..afd733f 100644
--- a/src/RoundedRectangle.cpp
+++ b/src/RoundedRectangle.cpp
@@ -5,7 +5,7 @@
namespace QuickMedia {
RoundedRectangle::RoundedRectangle(sf::Vector2f size, float radius, sf::Color color, sf::Shader *rounded_rectangle_shader) :
- radius(radius), pos(0.0f, 0.0f), size(size), rounded_rectangle_shader(rounded_rectangle_shader), band_y(0.0f), band_height(0.0f), band_color(sf::Color::Transparent)
+ radius(radius), pos(0.0f, 0.0f), size(size), rounded_rectangle_shader(rounded_rectangle_shader), band_color(sf::Color::Transparent)
{
assert(rounded_rectangle_shader);
vertices[0].color = color;
@@ -47,9 +47,9 @@ namespace QuickMedia {
return size;
}
- void RoundedRectangle::set_band(float y, float height) {
- band_y = y;
- band_height = height;
+ void RoundedRectangle::set_band(sf::Vector2f pos, sf::Vector2f size) {
+ band_pos = pos;
+ band_size = size;
}
void RoundedRectangle::set_band_color(sf::Color color) {
@@ -57,9 +57,10 @@ namespace QuickMedia {
}
void RoundedRectangle::draw(sf::RenderTarget &target) {
+ // TODO: Remove these for optimizations. Also do the same in other places where setUniform is called
rounded_rectangle_shader->setUniform("radius", radius);
- rounded_rectangle_shader->setUniform("band_y", band_y);
- rounded_rectangle_shader->setUniform("band_height", band_height);
+ rounded_rectangle_shader->setUniform("band_pos", band_pos);
+ rounded_rectangle_shader->setUniform("band_size", band_size);
rounded_rectangle_shader->setUniform("band_color", sf::Glsl::Vec4(band_color.r/255.0f, band_color.g/255.0f, band_color.b/255.0f, band_color.a/255.0f));
rounded_rectangle_shader->setUniform("resolution", size);
target.draw(vertices, 4, sf::Quads, rounded_rectangle_shader);
diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp
index f7e732a..91ad2e8 100644
--- a/src/SearchBar.cpp
+++ b/src/SearchBar.cpp
@@ -11,7 +11,7 @@
// TODO: Use a seperate placeholder sf::Text instead of switching the text to placeholder text....
static const sf::Color text_placeholder_color(255, 255, 255, 100);
-static const sf::Color front_color(55, 60, 68);
+static const sf::Color front_color(60, 65, 73);
static const float background_margin_horizontal = 10.0f + std::floor(5.0f * QuickMedia::get_ui_scale());
static const float padding_top_default = std::floor(10.0f * QuickMedia::get_ui_scale());
static const float padding_bottom_default = std::floor(15.0f * QuickMedia::get_ui_scale());
@@ -106,6 +106,9 @@ namespace QuickMedia {
if(!editable)
return;
+ if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
+ return;
+
if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Backspace)
backspace_pressed = true;
else if(event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Backspace)
diff --git a/src/Tabs.cpp b/src/Tabs.cpp
index b671262..e1a0d86 100644
--- a/src/Tabs.cpp
+++ b/src/Tabs.cpp
@@ -1,4 +1,5 @@
#include "../include/Tabs.hpp"
+#include "../include/Body.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/Utils.hpp"
#include <SFML/Window/Event.hpp>
@@ -9,7 +10,7 @@
namespace QuickMedia {
static const float tab_text_size = std::floor(16.0f * QuickMedia::get_ui_scale());
static const float tab_height = tab_text_size + std::floor(10.0f * QuickMedia::get_ui_scale());
- static const sf::Color tab_selected_color(55, 60, 68);
+ static const sf::Color tab_selected_color(60, 65, 73);
static const sf::Color arrow_color(255, 255, 255, 175);
static const float tab_min_width = 250.0f;
static const float tab_margin_x = 10.0f;
@@ -28,45 +29,64 @@ namespace QuickMedia {
shade.setFillColor(shade_color);
}
- int Tabs::add_tab(const std::string &title) {
- tab_texts.push_back(sf::Text(title, *FontLoader::get_font(FontLoader::FontType::LATIN), tab_text_size));
- tab_labels_utf8.push_back(title);
- return tab_texts.size() - 1;
+ int Tabs::add_tab(const std::string &title, Body *body) {
+ assert(body);
+ tabs.push_back({ sf::Text(title, *FontLoader::get_font(FontLoader::FontType::LATIN), tab_text_size), title, body} );
+ return tabs.size() - 1;
+ }
+
+ void Tabs::move_selected_tab(int new_tab) {
+ const int tab_diff = new_tab - selected_tab;
+
+ if(tab_diff > 0) {
+ while(selected_tab < new_tab) {
+ ++selected_tab;
+ const float scroll_fixed = scroll + (tab_offset * width_per_tab);
+ if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width > container_width - tab_margin_x)
+ --tab_offset;
+ }
+ } else if(tab_diff < 0) {
+ while(selected_tab > new_tab) {
+ --selected_tab;
+ const float scroll_fixed = scroll + (tab_offset * width_per_tab);
+ if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width < tab_margin_x)
+ ++tab_offset;
+ }
+ } else {
+ return;
+ }
+
+ if(on_change_tab)
+ on_change_tab(selected_tab);
}
void Tabs::on_event(sf::Event &event) {
- if(event.type == sf::Event::KeyPressed) {
- if(event.key.code == sf::Keyboard::Left || (event.key.control && event.key.code == sf::Keyboard::H)) {
- if(selected_tab > 0) {
- --selected_tab;
- float scroll_fixed = scroll + (tab_offset * width_per_tab);
- if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width < tab_margin_x)
- tab_offset++;
-
- if(on_change_tab)
- on_change_tab(selected_tab);
- }
- } else if(event.key.code == sf::Keyboard::Right || (event.key.control && event.key.code == sf::Keyboard::L)) {
- if(selected_tab < (int)tab_texts.size() - 1) {
- ++selected_tab;
- float scroll_fixed = scroll + (tab_offset * width_per_tab);
- if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width > container_width - tab_margin_x)
- tab_offset--;
-
- if(on_change_tab)
- on_change_tab(selected_tab);
- }
+ if(event.type == sf::Event::KeyPressed && !tabs.empty()) {
+ if(((!tabs[selected_tab].body->can_move_left() || event.key.alt) && (event.key.code == sf::Keyboard::Left || (event.key.control && event.key.code == sf::Keyboard::H)))
+ || (event.key.code == sf::Keyboard::Tab && event.key.shift))
+ {
+ if(selected_tab > 0)
+ move_selected_tab(selected_tab - 1);
+ } else if(((!tabs[selected_tab].body->can_move_right() || event.key.alt) && (event.key.code == sf::Keyboard::Right || (event.key.control && event.key.code == sf::Keyboard::L)))
+ || (event.key.code == sf::Keyboard::Tab && !event.key.shift))
+ {
+ if(selected_tab < (int)tabs.size() - 1)
+ move_selected_tab(selected_tab + 1);
+ } else if(event.key.control && event.key.code >= sf::Keyboard::Num1 && event.key.code <= sf::Keyboard::Num9) {
+ const int tab_target = event.key.code - sf::Keyboard::Num1;
+ if(tab_target < (int)tabs.size())
+ move_selected_tab(tab_target);
}
}
}
void Tabs::draw(sf::RenderWindow &window, sf::Vector2f pos, float width) {
- if(width - tab_margin_x < 0.0f || tab_texts.empty()) return;
+ if(width - tab_margin_x < 0.0f || tabs.empty()) return;
auto window_size = window.getSize();
container_width = width;
- const int num_visible_tabs = std::min((int)tab_texts.size(), std::max(1, (int)(width / tab_min_width)));
+ const int num_visible_tabs = std::min((int)tabs.size(), std::max(1, (int)(width / tab_min_width)));
width_per_tab = std::floor(width / num_visible_tabs);
const float tab_text_y = std::floor(pos.y + tab_height*0.5f - (tab_text_size + 5.0f*get_ui_scale())*0.5f);
tab_background_width = std::floor(width_per_tab - tab_margin_x*2.0f);
@@ -80,7 +100,7 @@ namespace QuickMedia {
float scroll_fixed = scroll + (tab_offset * width_per_tab);
- float overflow_last = (scroll_fixed + tab_index_to_x_offset(tab_texts.size() - 1) + tab_background_width) - (width - tab_margin_x);
+ float overflow_last = (scroll_fixed + tab_index_to_x_offset(tabs.size() - 1) + tab_background_width) - (width - tab_margin_x);
if(overflow_last < 0.0f)
scroll_fixed -= overflow_last;
@@ -96,7 +116,7 @@ namespace QuickMedia {
const auto start_pos = pos;
pos.x += scroll_fixed;
- for(size_t i = 0; i < tab_texts.size(); ++i) {
+ for(size_t i = 0; i < tabs.size(); ++i) {
const int index = i;
const float background_pos_x = std::floor(pos.x + tab_index_to_x_offset(i));
if(background_pos_x - start_pos.x >= width - tab_margin_x) {
@@ -112,7 +132,7 @@ namespace QuickMedia {
background.draw(window);
}
- sf::Text &tab_text = tab_texts[index];
+ sf::Text &tab_text = tabs[index].text;
float text_pos_x = std::floor(pos.x + i*width_per_tab + width_per_tab*0.5f - tab_text.getLocalBounds().width*0.5f);
text_pos_x = std::max(text_pos_x, background_pos_x);
tab_text.setPosition(text_pos_x, tab_text_y);
@@ -183,16 +203,16 @@ namespace QuickMedia {
}
void Tabs::set_text(int index, const std::string &text) {
- if(index < 0 || index >= (int)tab_texts.size() || text == tab_labels_utf8[index]) return;
- tab_texts[index].setString(sf::String::fromUtf8(text.begin(), text.end()));
- tab_labels_utf8[index] = text;
+ if(index < 0 || index >= (int)tabs.size() || text == tabs[index].label_utf8) return;
+ tabs[index].text.setString(sf::String::fromUtf8(text.begin(), text.end()));
+ tabs[index].label_utf8 = text;
}
void Tabs::set_selected(int index) {
- if(tab_texts.empty()) {
+ if(tabs.empty()) {
selected_tab = 0;
} else {
- selected_tab = std::min(std::max(index, 0), (int)tab_texts.size() - 1);
+ selected_tab = std::min(std::max(index, 0), (int)tabs.size() - 1);
}
}
diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp
index d2f81a9..52024e1 100644
--- a/src/plugins/Fourchan.cpp
+++ b/src/plugins/Fourchan.cpp
@@ -167,7 +167,7 @@ namespace QuickMedia {
}
PluginResult FourchanBoardsPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
- result_tabs.push_back(Tab{create_body(false), std::make_unique<FourchanThreadListPage>(program, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ result_tabs.push_back(Tab{create_body(false, true), std::make_unique<FourchanThreadListPage>(program, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
return PluginResult::OK;
}
@@ -262,6 +262,8 @@ namespace QuickMedia {
if(author.isString())
author_str = author.asString();
+ author_str += " #" + std::to_string(post_num.asInt64());
+
std::string comment_text;
extract_comment_pieces(sub_begin, sub_end - sub_begin,
[&comment_text](const CommentPiece &cp) {
diff --git a/src/plugins/Page.cpp b/src/plugins/Page.cpp
index 9eb874f..8605d82 100644
--- a/src/plugins/Page.cpp
+++ b/src/plugins/Page.cpp
@@ -29,8 +29,8 @@ namespace QuickMedia {
return DownloadResult::OK;
}
- std::unique_ptr<Body> Page::create_body(bool plain_text_list) {
- return program->create_body(plain_text_list);
+ std::unique_ptr<Body> Page::create_body(bool plain_text_list, bool prefer_card_view) {
+ return program->create_body(plain_text_list, prefer_card_view);
}
std::unique_ptr<SearchBar> Page::create_search_bar(const std::string &placeholder_text, int search_delay) {
diff --git a/src/plugins/Soundcloud.cpp b/src/plugins/Soundcloud.cpp
index 9c2d5f4..f4d01b6 100644
--- a/src/plugins/Soundcloud.cpp
+++ b/src/plugins/Soundcloud.cpp
@@ -253,7 +253,7 @@ namespace QuickMedia {
if(url == "track") {
SoundcloudPlaylist *playlist = static_cast<SoundcloudPlaylist*>(submit_body_item->extra.get());
- auto body = create_body();
+ auto body = create_body(false, true);
body->items = playlist->tracks;
result_tabs.push_back(Tab{std::move(body), std::make_unique<SoundcloudPlaylistPage>(program, playlist, title), nullptr});
} else if(url.find("/stream/users/") != std::string::npos) {
@@ -263,7 +263,7 @@ namespace QuickMedia {
DownloadResult result = download_json(json_root, query_url, {}, true);
if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
- auto body = create_body();
+ auto body = create_body(false, true);
std::string next_href;
PluginResult pr = parse_user_page(json_root, body->items, next_href);
if(pr != PluginResult::OK) return pr;
@@ -283,7 +283,7 @@ namespace QuickMedia {
if(!url_json.isString())
return PluginResult::ERR;
- result_tabs.push_back(Tab{create_body(), std::make_unique<SoundcloudAudioPage>(program, url_json.asString()), nullptr});
+ result_tabs.push_back(Tab{nullptr, std::make_unique<SoundcloudAudioPage>(program, url_json.asString()), nullptr});
}
return PluginResult::OK;
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index f7b36d6..9b7c5ba 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -648,7 +648,7 @@ namespace QuickMedia {
if(strncmp(url.c_str(), "https://www.youtube.com/channel/", 32) == 0) {
// TODO: Make all pages (for all services) lazy fetch in a similar manner!
- result_tabs.push_back(Tab{create_body(), std::make_unique<YoutubeChannelPage>(program, url, "", title), create_search_bar("Search...", 350)});
+ result_tabs.push_back(Tab{create_body(false, true), std::make_unique<YoutubeChannelPage>(program, url, "", title), create_search_bar("Search...", 350)});
} else {
result_tabs.push_back(Tab{nullptr, std::make_unique<YoutubeVideoPage>(program, url), nullptr});
}