summary refs log tree commit diff
path: root/include/SuggestionsPopup.hpp
blob: e949ce7c6830701a82bd228a017ba95b4558833e (plain) (blame)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#pragma once

#include <QHBoxLayout>
#include <QLabel>
#include <QPoint>
#include <QWidget>

#include "Avatar.h"
#include "AvatarProvider.h"
#include "Cache.h"
#include "ChatPage.h"

class Avatar;
struct SearchResult;

class PopupItem : public QWidget
{
        Q_OBJECT

        Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor)
        Q_PROPERTY(bool hovering READ hovering WRITE setHovering)

public:
        PopupItem(QWidget *parent);

        QString selectedText() const { return QString(); }
        QColor hoverColor() const { return hoverColor_; }
        void setHoverColor(QColor &color) { hoverColor_ = color; }

        bool hovering() const { return hovering_; }
        void setHovering(const bool hover) { hovering_ = hover; };

protected:
        void paintEvent(QPaintEvent *event) override;
        void mousePressEvent(QMouseEvent *event) override;

signals:
        void clicked(const QString &text);

protected:
        QHBoxLayout *topLayout_;

        Avatar *avatar_;

        QColor hoverColor_;

        //! Set if the item is currently being hovered during tab completion (cycling).
        bool hovering_;
};

class UserItem : public PopupItem
{
        Q_OBJECT

public:
        UserItem(QWidget *parent, const QString &user_id);
        QString selectedText() const { return userId_; }

private:
        QLabel *userName_;
        QString userId_;
};

class RoomItem : public PopupItem
{
        Q_OBJECT

public:
        RoomItem(QWidget *parent, const RoomSearchResult &res);
        QString selectedText() const { return roomId_; }

private:
        QLabel *roomName_;
        QString roomId_;
        RoomSearchResult info_;
};

class SuggestionsPopup : public QWidget
{
        Q_OBJECT

public:
        explicit SuggestionsPopup(QWidget *parent = nullptr);

        template<class Item>
        void selectHoveredSuggestion()
        {
                const auto item = layout_->itemAt(selectedItem_);
                if (!item)
                        return;

                const auto &widget = qobject_cast<Item *>(item->widget());
                emit itemSelected(
                  Cache::displayName(ChatPage::instance()->currentRoom(), widget->selectedText()));

                resetSelection();
        }

public slots:
        void addUsers(const QVector<SearchResult> &users);
        void addRooms(const std::vector<RoomSearchResult> &rooms);

        //! Move to the next available suggestion item.
        void selectNextSuggestion();
        //! Move to the previous available suggestion item.
        void selectPreviousSuggestion();
        //! Remove hovering from all items.
        void resetHovering();
        //! Set hovering to the item in the given layout position.
        void setHovering(int pos);

protected:
        void paintEvent(QPaintEvent *event) override;

signals:
        void itemSelected(const QString &user);

private:
        void hoverSelection();
        void resetSelection() { selectedItem_ = -1; }
        void selectFirstItem() { selectedItem_ = 0; }
        void selectLastItem() { selectedItem_ = layout_->count() - 1; }
        void removeItems()
        {
                QLayoutItem *item;
                while ((item = layout_->takeAt(0)) != 0) {
                        delete item->widget();
                        delete item;
                }
        }

        QVBoxLayout *layout_;

        //! Counter for tab completion (cycling).
        int selectedItem_ = -1;
};