1 |
|
|
/* |
2 |
|
|
* The ManaPlus Client |
3 |
|
|
* Copyright (C) 2008-2009 The Mana World Development Team |
4 |
|
|
* Copyright (C) 2009-2010 The Mana Developers |
5 |
|
|
* Copyright (C) 2011-2019 The ManaPlus Developers |
6 |
|
|
* Copyright (C) 2019-2021 Andrei Karas |
7 |
|
|
* |
8 |
|
|
* This file is part of The ManaPlus Client. |
9 |
|
|
* |
10 |
|
|
* This program is free software; you can redistribute it and/or modify |
11 |
|
|
* it under the terms of the GNU General Public License as published by |
12 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
13 |
|
|
* any later version. |
14 |
|
|
* |
15 |
|
|
* This program is distributed in the hope that it will be useful, |
16 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 |
|
|
* GNU General Public License for more details. |
19 |
|
|
* |
20 |
|
|
* You should have received a copy of the GNU General Public License |
21 |
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
22 |
|
|
*/ |
23 |
|
|
|
24 |
|
|
#ifndef GUI_WIDGETS_GUITABLE_H |
25 |
|
|
#define GUI_WIDGETS_GUITABLE_H |
26 |
|
|
|
27 |
|
|
#include "localconsts.h" |
28 |
|
|
|
29 |
|
|
#include "enums/simpletypes/opaque.h" |
30 |
|
|
|
31 |
|
|
#include "listeners/keylistener.h" |
32 |
|
|
#include "listeners/mouselistener.h" |
33 |
|
|
#include "listeners/tablemodellistener.h" |
34 |
|
|
|
35 |
|
|
#include "gui/widgets/widget.h" |
36 |
|
|
|
37 |
|
|
class GuiTableActionListener; |
38 |
|
|
class TableModel; |
39 |
|
|
|
40 |
|
|
/** |
41 |
|
|
* A table, with rows and columns made out of sub-widgets. Largely inspired by |
42 |
|
|
* (and can be thought of as a generalisation of) the guichan listbox |
43 |
|
|
* implementation. |
44 |
|
|
* |
45 |
|
|
* Normally you want this within a ScrollArea. |
46 |
|
|
* |
47 |
|
|
* \ingroup GUI |
48 |
|
|
*/ |
49 |
|
|
class GuiTable final : public Widget, |
50 |
|
|
public MouseListener, |
51 |
|
|
public KeyListener, |
52 |
|
|
public TableModelListener |
53 |
|
|
{ |
54 |
|
|
// so that the action listener can call distributeActionEvent |
55 |
|
|
friend class GuiTableActionListener; |
56 |
|
|
|
57 |
|
|
public: |
58 |
|
|
GuiTable(const Widget2 *const widget, |
59 |
|
|
TableModel *const initial_model, |
60 |
|
|
const Opaque opacity); |
61 |
|
|
|
62 |
|
|
A_DELETE_COPY(GuiTable) |
63 |
|
|
|
64 |
|
|
~GuiTable() override final; |
65 |
|
|
|
66 |
|
|
/** |
67 |
|
|
* Sets the table model |
68 |
|
|
* |
69 |
|
|
* Note that actions issued by widgets returned from the model will |
70 |
|
|
* update the table selection, but only AFTER any event handlers |
71 |
|
|
* installed within the widget have been triggered. To be notified |
72 |
|
|
* after such an update, add an action listener to the table instead. |
73 |
|
|
*/ |
74 |
|
|
void setModel(TableModel *const m); |
75 |
|
|
|
76 |
|
|
/** |
77 |
|
|
* Retrieves the active table model |
78 |
|
|
*/ |
79 |
|
|
const TableModel *getModel() const A_WARN_UNUSED RETURNS_NONNULL; |
80 |
|
|
|
81 |
|
|
void setSelected(const int row, const int column); |
82 |
|
|
|
83 |
|
|
int getSelectedRow() const A_WARN_UNUSED; |
84 |
|
|
|
85 |
|
|
int getSelectedColumn() const A_WARN_UNUSED; |
86 |
|
|
|
87 |
|
|
void setSelectedRow(const int selected); |
88 |
|
|
|
89 |
|
|
void setSelectedColumn(const int selected); |
90 |
|
|
|
91 |
|
|
bool isWrappingEnabled() const noexcept2 A_WARN_UNUSED |
92 |
|
|
{ return mWrappingEnabled; } |
93 |
|
|
|
94 |
|
|
void setWrappingEnabled(bool wrappingEnabled) |
95 |
|
|
{ mWrappingEnabled = wrappingEnabled; } |
96 |
|
|
|
97 |
|
|
Rect getChildrenArea() override final A_WARN_UNUSED; |
98 |
|
|
|
99 |
|
|
/** |
100 |
|
|
* Toggle whether to use linewise selection mode, in which the table |
101 |
|
|
* selects an entire line at a time, rather than a single cell. |
102 |
|
|
* |
103 |
|
|
* Note that column information is tracked even in linewise selection |
104 |
|
|
* mode; |
105 |
|
|
* |
106 |
|
|
* this mode therefore only affects visualisation. |
107 |
|
|
* |
108 |
|
|
* Disabled by default. |
109 |
|
|
* |
110 |
|
|
* \param linewise: Whether to enable linewise selection mode |
111 |
|
|
*/ |
112 |
|
|
void setLinewiseSelection(bool linewise) |
113 |
|
4 |
{ mLinewiseMode = linewise; } |
114 |
|
|
|
115 |
|
|
// Inherited from Widget |
116 |
|
|
void draw(Graphics *const graphics) override final A_NONNULL(2); |
117 |
|
|
|
118 |
|
|
void safeDraw(Graphics *const graphics) override final A_NONNULL(2); |
119 |
|
|
|
120 |
|
|
Widget *getWidgetAt(int x, int y) override final A_WARN_UNUSED; |
121 |
|
|
|
122 |
|
|
void moveToTop(Widget *const widget) override final; |
123 |
|
|
|
124 |
|
|
void moveToBottom(Widget *const widget) override final; |
125 |
|
|
|
126 |
|
|
void setFocusHandler(FocusHandler *const focusHandler) override final; |
127 |
|
|
|
128 |
|
|
// Inherited from KeyListener |
129 |
|
|
void keyPressed(KeyEvent& event) override final; |
130 |
|
|
|
131 |
|
|
/** |
132 |
|
|
* Sets the table to be opaque, that is sets the table |
133 |
|
|
* to display its background. |
134 |
|
|
* |
135 |
|
|
* @param opaque True if the table should be opaque, false otherwise. |
136 |
|
|
*/ |
137 |
|
|
void setOpaque(Opaque opaque) |
138 |
|
2 |
{ mOpaque = opaque; } |
139 |
|
|
|
140 |
|
|
/** |
141 |
|
|
* Checks if the table is opaque, that is if the table area displays |
142 |
|
|
* its background. |
143 |
|
|
* |
144 |
|
|
* @return True if the table is opaque, false otherwise. |
145 |
|
|
*/ |
146 |
|
|
bool isOpaque() const noexcept2 A_WARN_UNUSED |
147 |
|
|
{ return mOpaque == Opaque_true; } |
148 |
|
|
|
149 |
|
|
// Inherited from MouseListener |
150 |
|
|
void mousePressed(MouseEvent& event) override final; |
151 |
|
|
|
152 |
|
|
void mouseWheelMovedUp(MouseEvent& event) override final; |
153 |
|
|
|
154 |
|
|
void mouseWheelMovedDown(MouseEvent& event) override final; |
155 |
|
|
|
156 |
|
|
void mouseDragged(MouseEvent& event) override final; |
157 |
|
|
|
158 |
|
|
// Constraints inherited from TableModelListener |
159 |
|
|
void modelUpdated(const bool completed) override final; |
160 |
|
|
|
161 |
|
|
void requestFocus() override; |
162 |
|
|
|
163 |
|
|
void setSelectableGui(bool b) |
164 |
|
2 |
{ mSelectableGui = b; } |
165 |
|
|
|
166 |
|
|
protected: |
167 |
|
|
/** Frees all action listeners on inner widgets. */ |
168 |
|
|
void uninstallActionListeners(); |
169 |
|
|
|
170 |
|
|
/** Installs all action listeners on inner widgets. */ |
171 |
|
|
void installActionListeners(); |
172 |
|
|
|
173 |
|
|
int getRowHeight() const A_WARN_UNUSED; |
174 |
|
|
|
175 |
|
|
int getColumnWidth(const int i) const A_WARN_UNUSED; |
176 |
|
|
|
177 |
|
|
private: |
178 |
|
|
int getRowForY(const int y) const A_WARN_UNUSED; // -1 on error |
179 |
|
|
|
180 |
|
|
int getColumnForX(const int x) const A_WARN_UNUSED; // -1 on error |
181 |
|
|
|
182 |
|
|
void recomputeDimensions(); |
183 |
|
|
|
184 |
|
|
static float mAlpha; |
185 |
|
|
|
186 |
|
|
TableModel *mModel A_NONNULLPOINTER; |
187 |
|
|
|
188 |
|
|
/** If someone moves a fresh widget to the top, we must display it. */ |
189 |
|
|
Widget *mTopWidget; |
190 |
|
|
|
191 |
|
|
/** Vector for compactness; used as a list in practice. */ |
192 |
|
|
STD_VECTOR<GuiTableActionListener *> mActionListeners2; |
193 |
|
|
|
194 |
|
|
/** |
195 |
|
|
* Holds the background color of the table. |
196 |
|
|
*/ |
197 |
|
|
Color mHighlightColor; |
198 |
|
|
|
199 |
|
|
int mSelectedRow; |
200 |
|
|
int mSelectedColumn; |
201 |
|
|
|
202 |
|
|
bool mLinewiseMode; |
203 |
|
|
bool mWrappingEnabled; |
204 |
|
|
Opaque mOpaque; |
205 |
|
|
bool mSelectableGui; |
206 |
|
|
}; |
207 |
|
|
|
208 |
|
|
#endif // GUI_WIDGETS_GUITABLE_H |