Mana
Loading...
Searching...
No Matches
setup_players.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2008-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "gui/setup_players.h"
23
24#include "configuration.h"
25
26#include "gui/widgets/button.h"
29#include "gui/widgets/label.h"
30#include "gui/widgets/layout.h"
32#include "gui/widgets/table.h"
33
34#include "utils/dtor.h"
35#include "utils/gettext.h"
36
37#include <string>
38#include <vector>
39
40#define COLUMNS_NR 2 // name plus listbox
41#define NAME_COLUMN 0
42#define RELATION_CHOICE_COLUMN 1
43
44#define ROW_HEIGHT 12
45// The following column widths really shouldn't be hardcoded but should scale with the size of the widget... except
46// that, right now, the widget doesn't exactly scale either.
47#define NAME_COLUMN_WIDTH 230
48#define RELATION_CHOICE_COLUMN_WIDTH 80
49
50#define WIDGET_AT(row, column) (((row) * COLUMNS_NR) + column)
51
52static const char *table_titles[COLUMNS_NR] =
53{
54 N_("Name"),
55 N_("Relation")
56};
57
58static const char *RELATION_NAMES[RELATIONS_NR] =
59{
60 N_("Neutral"),
61 N_("Friend"),
62 N_("Disregarded"),
63 N_("Ignored")
64};
65
66class PlayerRelationListModel : public gcn::ListModel
67{
68public:
70
71 int getNumberOfElements() override
72 {
73 return RELATIONS_NR;
74 }
75
76 std::string getElementAt(int i) override
77 {
78 if (i >= getNumberOfElements() || i < 0)
79 return "";
80 return gettext(RELATION_NAMES[i]);
81 }
82};
83
85{
86public:
92
94 {
96 delete mListModel;
97 }
98
99 int getRows() const override
100 {
101 return mPlayers.size();
102 }
103
104 int getColumns() const override
105 {
106 return COLUMNS_NR;
107 }
108
109 int getRowHeight() const override
110 {
111 return ROW_HEIGHT;
112 }
113
114 int getColumnWidth(int index) const override
115 {
116 if (index == NAME_COLUMN)
117 return NAME_COLUMN_WIDTH;
118 else
120 }
121
123 {
125
126 freeWidgets();
127
129
130 // set up widgets
131 for (const auto &name : mPlayers)
132 {
133 gcn::Widget *widget = new Label(name);
134 mWidgets.push_back(widget);
135
136 gcn::DropDown *choicebox = new DropDown(mListModel);
137 choicebox->setSelected(static_cast<int>(player_relations.getRelation(name)));
138 mWidgets.push_back(choicebox);
139 }
140
142 }
143
144 virtual void updateModelInRow(int row)
145 {
146 auto *choicebox = static_cast<gcn::DropDown *>(
149 static_cast<PlayerRelation>(
150 choicebox->getSelected()));
151 }
152
153
154 gcn::Widget *getElementAt(int row, int column) const override
155 {
156 return mWidgets[WIDGET_AT(row, column)];
157 }
158
159 virtual void freeWidgets()
160 {
161 mPlayers.clear();
162
164 mWidgets.clear();
165 }
166
167 const std::string &getPlayerAt(int index) const
168 {
169 return mPlayers[index];
170 }
171
172protected:
173 std::vector<std::string> mPlayers;
174 std::vector<gcn::Widget *> mWidgets;
176};
177
181class IgnoreChoicesListModel : public gcn::ListModel
182{
183public:
185
186 int getNumberOfElements() override
187 {
189 }
190
191 std::string getElementAt(int i) override
192 {
193 if (i >= getNumberOfElements())
194 return _("???");
195
196 return player_relations.getPlayerIgnoreStrategies()[i]->mDescription;
197 }
198};
199
200#define ACTION_DELETE "delete"
201#define ACTION_TABLE "table"
202#define ACTION_STRATEGY "strategy"
203
205 mShowGender(config.showGender),
206 mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)),
207 mPlayerTableModel(new PlayerTableModel),
208 mPlayerTable(new GuiTable(mPlayerTableModel)),
209 mPlayerTitleTable(new GuiTable(mPlayerTableTitleModel)),
210 mPlayerScrollArea(new ScrollArea(mPlayerTable)),
211 mDefaultTrading(new CheckBox(_("Allow trading"),
212 player_relations.getDefault() & PlayerPermissions::TRADE)),
213 mDefaultWhisper(new CheckBox(_("Allow whispers"),
214 player_relations.getDefault() & PlayerPermissions::WHISPER)),
215 mDeleteButton(new Button(_("Delete"), ACTION_DELETE, this)),
216 mWhisperTabCheckBox(new CheckBox(_("Put all whispers in tabs"), config.whisperTab)),
217 mShowGenderCheckBox(new CheckBox(_("Show gender"), config.showGender)),
218 mEnableChatLogCheckBox(new CheckBox(_("Enable Chat log"), config.enableChatLog))
219{
220 setName(_("Players"));
221
222 mPlayerTable->setOpaque(false);
223
227 mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf));
228
231
232 for (int i = 0; i < COLUMNS_NR; i++)
233 {
235 new Label(gettext(table_titles[i])));
236 }
237
239
240 mPlayerScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
241 mPlayerTable->setActionEventId(ACTION_TABLE);
243 mPlayerTable->addActionListener(this);
244
245 gcn::Label *ignore_action_label = new Label(_("When ignoring:"));
246
247 mShowGenderCheckBox->setActionEventId("showgender");
248 mShowGenderCheckBox->addActionListener(this);
249 mIgnoreActionChoicesBox->setActionEventId(ACTION_STRATEGY);
250 mIgnoreActionChoicesBox->addActionListener(this);
251
252 int ignoreStrategyIndex = 0; // safe default
253
254 if (auto ignoreStrategy = player_relations.getPlayerIgnoreStrategy())
255 {
257 ignoreStrategy->mShortName);
258 if (ignoreStrategyIndex < 0)
259 ignoreStrategyIndex = 0;
260 }
261 mIgnoreActionChoicesBox->setSelected(ignoreStrategyIndex);
262 mIgnoreActionChoicesBox->adjustHeight();
263
264 reset();
265
266 // Do the layout
267 place(0, 0, mPlayerTitleTable, 4);
268 place(0, 1, mPlayerScrollArea, 4, 4).setPadding(2);
269 place(0, 5, mDeleteButton);
270 place(0, 6, mShowGenderCheckBox, 2);
272 place(2, 5, ignore_action_label);
274 place(0, 8, mDefaultTrading);
275 place(0, 9, mDefaultWhisper);
276 place(0, 10, mWhisperTabCheckBox, 4);
277
279}
280
286
287
289{
290 // We now have to search through the list of ignore choices to find the
291 // current selection. We could use an index into the table of config
292 // options in player_relations instead of strategies to sidestep this.
293 const auto &strategies = player_relations.getPlayerIgnoreStrategies();
294 auto i = std::find(strategies.begin(), strategies.end(),
296
297 int selection = i == strategies.end() ? 0 : i - strategies.begin();
298 mIgnoreActionChoicesBox->setSelected(selection);
299}
300
302{
304
305 unsigned int old_default_relations = player_relations.getDefault() &
308 player_relations.setDefault(old_default_relations
309 | (mDefaultTrading->isSelected() ?
311 | (mDefaultWhisper->isSelected() ?
313
314 config.whisperTab = mWhisperTabCheckBox->isSelected();
316
318}
319
328
329void Setup_Players::action(const gcn::ActionEvent &event)
330{
331 if (event.getId() == ACTION_TABLE)
332 {
333 // temporarily eliminate ourselves: we are fully aware of this change,
334 // so there is no need for asynchronous updates. (In fact, thouse
335 // might destroy the widet that triggered them, which would be rather
336 // embarrassing.)
338
339 int row = mPlayerTable->getSelectedRow();
340 if (row >= 0)
342
344 }
345 else if (event.getId() == ACTION_DELETE)
346 {
347 int player_index = mPlayerTable->getSelectedRow();
348 if (player_index < 0)
349 return;
350
351 const std::string &name = mPlayerTableModel->getPlayerAt(player_index);
353 }
354 else if (event.getId() == ACTION_STRATEGY)
355 {
358 mIgnoreActionChoicesBox->getSelected()];
359
361 }
362 else if (event.getId() == "showgender")
363 {
365 }
366}
367
Button widget.
Definition button.h:38
Check box widget.
Definition checkbox.h:32
LayoutCell & place(int x, int y, gcn::Widget *wg, int w=1, int h=1)
Adds a widget to the container and sets it at given cell.
Definition container.cpp:46
A drop down box from which you can select different values.
Definition dropdown.h:34
A table, with rows and columns made out of sub-widgets.
Definition table.h:47
void setOpaque(bool opaque)
Sets the table to be opaque, that is sets the table to display its background.
Definition table.h:125
int getSelectedRow() const
Definition table.cpp:149
void setLinewiseSelection(bool linewise)
Toggle whether to use linewise selection mode, in which the table selects an entire line at a time,...
Definition table.cpp:159
Class for choosing one of the various ‘what to do when ignoring a player’ options.
std::string getElementAt(int i) override
int getNumberOfElements() override
Label widget.
Definition label.h:34
LayoutCell & setPadding(int p)
Sets the padding around the cell content.
Definition layout.h:179
Ignore strategy: describes how we should handle ignores.
std::string getElementAt(int i) override
~PlayerRelationListModel() override
int getNumberOfElements() override
void store()
Save configuration to our config file.
std::vector< std::string > getPlayers() const
Retrieves a sorted vector of all players for which we have any relations recorded.
PlayerRelation getRelation(const std::string &name) const
Updates the relationship with this player.
unsigned int getDefault() const
Retrieves the default permissions.
void removeListener(PlayerRelationsListener *listener)
void addListener(PlayerRelationsListener *listener)
std::vector< PlayerIgnoreStrategy * > & getPlayerIgnoreStrategies()
Retrieves all known player ignore strategies.
void setDefault(unsigned int permissions)
Sets the default permissions.
PlayerIgnoreStrategy * getPlayerIgnoreStrategy() const
Return the current player ignore strategy.
int getPlayerIgnoreStrategyIndex(const std::string &shortName)
For a given ignore strategy short name, find the appropriate index in the ignore strategies vector.
void setPlayerIgnoreStrategy(PlayerIgnoreStrategy *strategy)
Sets the strategy to call when ignoring players.
void setRelation(const std::string &name, PlayerRelation relation)
Updates the relationship with this player.
void removePlayer(const std::string &name)
Deletes the information recorded for a player.
int getRowHeight() const override
Determines the height for each row.
int getColumns() const override
Determines the number of columns in each row.
std::vector< gcn::Widget * > mWidgets
gcn::Widget * getElementAt(int row, int column) const override
Retrieves the widget stored at the specified location within the table.
int getRows() const override
Determines the number of rows (lines) in the table.
~PlayerTableModel() override
virtual void updateModelInRow(int row)
const std::string & getPlayerAt(int index) const
virtual void freeWidgets()
PlayerRelationListModel * mListModel
std::vector< std::string > mPlayers
int getColumnWidth(int index) const override
Determines the width of each individual column.
A scroll area.
Definition scrollarea.h:38
void setName(const std::string &name)
Sets the name displayed on the tab.
Definition setuptab.h:54
StaticTableModel * mPlayerTableTitleModel
PlayerTableModel * mPlayerTableModel
gcn::Button * mDeleteButton
gcn::DropDown * mIgnoreActionChoicesBox
gcn::CheckBox * mWhisperTabCheckBox
gcn::CheckBox * mEnableChatLogCheckBox
GuiTable * mPlayerTitleTable
GuiTable * mPlayerTable
void cancel() override
Called when the Cancel button is pressed in the setup window.
gcn::CheckBox * mDefaultWhisper
void action(const gcn::ActionEvent &event) override
gcn::CheckBox * mDefaultTrading
~Setup_Players() override
void playerRelationsUpdated() override
void apply() override
Called when the Apply button is pressed in the setup window.
gcn::CheckBox * mShowGenderCheckBox
gcn::ScrollArea * mPlayerScrollArea
gcn::ListModel * mIgnoreActionChoicesModel
virtual void set(int row, int column, gcn::Widget *widget)
Inserts a widget into the table model.
virtual void fixColumnWidth(int column, int width)
Fixes the column width for a given column; this overrides dynamic width inference.
A model for a regular table of widgets.
Definition tablemodel.h:50
void signalAfterUpdate()
Tells all listeners that the table has seen an update.
void signalBeforeUpdate()
Tells all listeners that the table is about to see an update.
Config config
Global settings (config.xml)
Definition client.cpp:97
void setConfigValue(T Config::*member, const T &value)
Sets the given Config member and sends a change event.
void delete_all(Container &c)
Definition dtor.h:46
#define gettext(s)
Definition gettext.h:37
#define N_(s)
Definition gettext.h:39
#define _(s)
Definition gettext.h:38
PlayerRelationsManager player_relations
PlayerRelation
constexpr unsigned int RELATIONS_NR
#define WIDGET_AT(row, column)
#define ACTION_TABLE
#define COLUMNS_NR
#define RELATION_CHOICE_COLUMN
#define NAME_COLUMN
#define NAME_COLUMN_WIDTH
#define RELATION_CHOICE_COLUMN_WIDTH
#define ACTION_STRATEGY
#define ROW_HEIGHT
#define ACTION_DELETE
bool enableChatLog
bool whisperTab
bool showGender