summaryrefslogtreecommitdiff
path: root/src/components/channeltabswitcherhandy.hpp
blob: 561d4639f23d069cca7f6378a99a429a4cbc438f (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
#pragma once
// perhaps this should be conditionally included within cmakelists?
#ifdef WITH_LIBHANDY
    #include <gtkmm/box.h>
    #include <unordered_map>
    #include <handy.h>
    #include "discord/snowflake.hpp"
    #include "state.hpp"

class ChannelData;

// thin wrapper over c api
// HdyTabBar + invisible HdyTabView since it needs one
class ChannelTabSwitcherHandy : public Gtk::Box {
public:
    ChannelTabSwitcherHandy();

    // no-op if already added
    void AddChannelTab(Snowflake id);
    // switches to existing tab if it exists
    void ReplaceActiveTab(Snowflake id);
    TabsState GetTabsState();
    void UseTabsState(const TabsState &state);

    void GoBackOnCurrent();
    void GoForwardOnCurrent();

    [[nodiscard]] int GetNumberOfTabs() const;

private:
    void CheckUnread(Snowflake id);
    void ClearPage(HdyTabPage *page);
    void OnPageIconLoad(HdyTabPage *page, const Glib::RefPtr<Gdk::Pixbuf> &pb);
    void CheckPageIcon(HdyTabPage *page, const ChannelData &data);
    void AppendPageHistory(HdyTabPage *page, Snowflake channel);
    void AdvanceOnCurrent(size_t by);

    HdyTabBar *m_tab_bar;
    Gtk::Widget *m_tab_bar_wrapped;
    HdyTabView *m_tab_view;
    Gtk::Widget *m_tab_view_wrapped;

    std::unordered_map<Snowflake, HdyTabPage *> m_pages;
    std::unordered_map<HdyTabPage *, Snowflake> m_pages_rev;
    // need to hold a reference to the pixbuf data
    std::unordered_map<HdyTabPage *, Glib::RefPtr<Gdk::Pixbuf>> m_page_icons;

    struct PageHistory {
        std::vector<Snowflake> Visited;
        size_t CurrentVisitedIndex;
    };

    std::unordered_map<HdyTabPage *, PageHistory> m_page_history;

    friend void selected_page_notify_cb(HdyTabView *, GParamSpec *, ChannelTabSwitcherHandy *);
    friend gboolean close_page_cb(HdyTabView *, HdyTabPage *, ChannelTabSwitcherHandy *);

public:
    using type_signal_channel_switched_to = sigc::signal<void, Snowflake>;

    type_signal_channel_switched_to signal_channel_switched_to();

private:
    type_signal_channel_switched_to m_signal_channel_switched_to;
};
#endif