aboutsummaryrefslogtreecommitdiff
path: root/include/ImageViewer.hpp
blob: b587b827e98da1ab7e18314228c5d75cad692f76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#pragma once

#include "Path.hpp"
#include <string>
#include <vector>
#include <mglpp/graphics/Texture.hpp>
#include <mglpp/graphics/Sprite.hpp>
#include <mglpp/graphics/Text.hpp>
#include <mglpp/system/Clock.hpp>
#include <thread>
#include <memory>

namespace mgl {
    class Window;
}

namespace QuickMedia {
    enum class ImageStatus {
        WAITING,
        LOADING,
        FAILED_TO_LOAD,
        LOADED,
        APPLIED_TO_TEXTURE
    };

    struct ImageData {
        mgl::Texture texture;
        mgl::Sprite sprite;
        ImageStatus image_status;
        std::unique_ptr<mgl::Image> image;
        bool visible_on_screen;
        float prev_height = 0.0f;
    };

    struct PageSize {
        mgl::vec2d size;
        mgl::vec2d prev_size;
        bool loaded;
    };

    enum class ImageViewerAction {
        NONE,
        RETURN,
        SWITCH_TO_SINGLE_IMAGE_MODE,
        PREVIOUS_CHAPTER,
        NEXT_CHAPTER
    };

    class ImageViewer {
    public:
        ImageViewer(mgl::Window *window, int num_pages, const std::string &content_title, const std::string &chapter_title, int current_page, const Path &chapter_cache_dir, bool *fit_image_to_window);
        ~ImageViewer();
        ImageViewerAction draw();
        // Returns page as 1 indexed
        int get_focused_page() const;
        int get_num_pages() const { return num_pages; }
    private:
        void scroll_to_page(int page);
        void load_image_async(const Path &path, std::shared_ptr<ImageData> image_data);
        bool render_page(mgl::Window &window, int page, double offset_y);
        mgl::vec2d get_page_size(int page);
    private:
        mgl::Window *window;

        int current_page;
        int num_pages;

        std::string content_title;
        std::string chapter_title;
        Path chapter_cache_dir;

        double scroll = 0.0;
        double scroll_speed = 0.0;
        double min_page_top_dist;
        int page_closest_to_top;
        int focused_page;
        int prev_focused_page = -1;

        mgl::Clock frame_timer;
        mgl::Text page_text;

        std::vector<std::shared_ptr<ImageData>> image_data;
        std::vector<PageSize> page_size;

        mgl::vec2d window_size;
        bool window_size_set = false;
        bool middle_mouse_scrolling = false;
        double autoscroll_start_y = 0.0;

        // TODO: Fix
        //sf::Cursor default_cursor;
        //sf::Cursor size_vertical_cursor;

        bool has_default_cursor;
        bool has_size_vertical_cursor;

        bool up_pressed = false;
        bool down_pressed = false;

        std::thread image_loader_thread;
        bool loading_image = false;

        bool *fit_image_to_window;

        mgl::vec2d prev_size_first_page;
        mgl::vec2d prev_size_last_page;
    };
}