aboutsummaryrefslogtreecommitdiff
path: root/src/Tabs.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-04-19 16:13:55 +0200
committerdec05eba <dec05eba@protonmail.com>2021-04-19 16:13:55 +0200
commit5465c09cd108e37720dbad139de98bdcf5dfe8bf (patch)
tree47db7d4a488bca6711fe9a8cbc47f53a74f3fc67 /src/Tabs.cpp
parent7f0bdeddb79c308ab082a124441f1d69d665dbfc (diff)
Move tab code to separate class, fix upload time missing for certain manga plugins, fix touch room click messed up
Diffstat (limited to 'src/Tabs.cpp')
-rw-r--r--src/Tabs.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/Tabs.cpp b/src/Tabs.cpp
new file mode 100644
index 0000000..464ba4e
--- /dev/null
+++ b/src/Tabs.cpp
@@ -0,0 +1,200 @@
+#include "../include/Tabs.hpp"
+#include "../include/ResourceLoader.hpp"
+#include "../include/Utils.hpp"
+#include <SFML/Window/Event.hpp>
+#include <SFML/Graphics/RenderWindow.hpp>
+#include <SFML/OpenGL.hpp>
+#include <cmath>
+
+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 float tab_min_width = 250.0f;
+ static const float tab_margin_x = 10.0f;
+
+ // static
+ float Tabs::get_height() {
+ return tab_height;
+ }
+
+ // static
+ float Tabs::get_shade_height() {
+ return tab_height + std::floor(10.0f * get_ui_scale());
+ }
+
+ Tabs::Tabs(sf::Color shade_color) : background(sf::Vector2f(1.0f, 1.0f), 10.0f, 10), shade_color(shade_color) {
+ background.setFillColor(tab_selected_color);
+ 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));
+ return tab_texts.size() - 1;
+ }
+
+ 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 < 0.0f)
+ 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_offset--;
+
+ if(on_change_tab)
+ on_change_tab(selected_tab);
+ }
+ }
+ }
+ }
+
+ void Tabs::draw(sf::RenderWindow &window, sf::Vector2f pos, float width) {
+ if(width - tab_margin_x < 0.0f || tab_texts.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)));
+ 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);
+ background.setSize(sf::Vector2f(tab_background_width, tab_height));
+
+ shade.setSize(sf::Vector2f(width, get_shade_height()));
+ shade.setPosition(std::floor(pos.x), std::floor(pos.y));
+ window.draw(shade);
+
+ 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);
+ if(overflow_last < 0.0f)
+ scroll_fixed -= overflow_last;
+
+ float overflow = (scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width) - (width - tab_margin_x);
+ float underflow = scroll_fixed + tab_index_to_x_offset(selected_tab);
+ if(overflow > 0.0f)
+ scroll_fixed -= overflow;
+ else if(underflow < 0.0f)
+ scroll_fixed -= underflow;
+
+ bool tabs_cutoff_left = false;
+ bool tabs_cutoff_right = false;
+ const auto start_pos = pos;
+
+ pos.x += scroll_fixed;
+ for(size_t i = 0; i < tab_texts.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) {
+ tabs_cutoff_right = true;
+ break;
+ } else if(background_pos_x + tab_background_width - start_pos.x <= tab_margin_x) {
+ tabs_cutoff_left = true;
+ continue;
+ }
+
+ if((int)index == selected_tab) {
+ background.setPosition(background_pos_x, std::floor(pos.y));
+ window.draw(background);
+ }
+
+ sf::Text &tab_text = tab_texts[index];
+ 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);
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(text_pos_x, (int)window_size.y - (int)tab_text_y - (int)tab_height, tab_background_width, tab_height);
+ window.draw(tab_text);
+ glDisable(GL_SCISSOR_TEST);
+ }
+
+ float lw = std::floor(25.0f * get_ui_scale());
+ float lh = background.getSize().y;
+
+ float line_offset_y = std::floor(lw * 0.35f);
+
+ if(tabs_cutoff_left) {
+ sf::Vertex gradient_points[4];
+ gradient_points[0].position = sf::Vector2f(start_pos.x + tab_margin_x, start_pos.y);
+ gradient_points[1].position = sf::Vector2f(start_pos.x + tab_margin_x + lw, start_pos.y);
+ gradient_points[2].position = sf::Vector2f(start_pos.x + tab_margin_x + lw, start_pos.y + lh);
+ gradient_points[3].position = sf::Vector2f(start_pos.x + tab_margin_x, start_pos.y + lh);
+
+ gradient_points[0].color = shade_color;
+ gradient_points[1].color = sf::Color(shade_color.r, shade_color.g, shade_color.b, 10);
+ gradient_points[2].color = sf::Color(shade_color.r, shade_color.g, shade_color.b, 10);
+ gradient_points[3].color = shade_color;
+
+ window.draw(gradient_points, 4, sf::Quads);
+
+ sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_ui_scale()), std::floor(2.0f * get_ui_scale())));
+ line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f);
+
+ line.rotate(-45.0f);
+ line.setPosition(std::floor(start_pos.x + line.getLocalBounds().width), std::floor(pos.y + background.getSize().y * 0.5f - lh * 0.5f + line_offset_y));
+ window.draw(line);
+
+ line.rotate(-90.0f);
+ line.setPosition(std::floor(start_pos.x + line.getLocalBounds().width), std::floor(pos.y + background.getSize().y * 0.5f - lh * 0.5f + line_offset_y + std::floor(7.0f * get_ui_scale())));
+ window.draw(line);
+ }
+
+ if(tabs_cutoff_right) {
+ sf::Vertex gradient_points[4];
+ gradient_points[0].position = sf::Vector2f(start_pos.x + width - lw - tab_margin_x, start_pos.y);
+ gradient_points[1].position = sf::Vector2f(start_pos.x + width, start_pos.y);
+ gradient_points[2].position = sf::Vector2f(start_pos.x + width, start_pos.y + lh);
+ gradient_points[3].position = sf::Vector2f(start_pos.x + width - lw - tab_margin_x, start_pos.y + lh);
+
+ gradient_points[0].color = sf::Color(shade_color.r, shade_color.g, shade_color.b, 10);
+ gradient_points[1].color = shade_color;
+ gradient_points[2].color = shade_color;
+ gradient_points[3].color = sf::Color(shade_color.r, shade_color.g, shade_color.b, 10);
+
+ window.draw(gradient_points, 4, sf::Quads);
+
+ sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_ui_scale()), std::floor(2.0f * get_ui_scale())));
+ line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f);
+
+ line.rotate(45.0f);
+ line.setPosition(std::floor(start_pos.x + width - lw*0.75f + line.getLocalBounds().width), std::floor(pos.y + background.getSize().y * 0.5f - lh * 0.5f + line_offset_y));
+ window.draw(line);
+
+ line.rotate(-90.0f);
+ line.setPosition(std::floor(start_pos.x + width - lw*0.75f + line.getLocalBounds().width), std::floor(pos.y + background.getSize().y * 0.5f - lh * 0.5f + line_offset_y + std::floor(7.0f * get_ui_scale())));
+ window.draw(line);
+ }
+ }
+
+ void Tabs::set_text(int index, const std::string &text) {
+ if(index < 0 || index >= (int)tab_texts.size()) return;
+ tab_texts[index].setString(sf::String::fromUtf8(text.begin(), text.end()));
+ }
+
+ void Tabs::set_selected(int index) {
+ if(tab_texts.empty()) {
+ selected_tab = 0;
+ } else {
+ selected_tab = std::min(std::max(index, 0), (int)tab_texts.size() - 1);
+ }
+ }
+
+ int Tabs::get_selected() const {
+ return selected_tab;
+ }
+
+ float Tabs::tab_index_to_x_offset(int index) {
+ return std::floor(index*width_per_tab + tab_margin_x);
+ }
+} \ No newline at end of file