Freeciv21
Develop your civilization from humble roots to a global empire
unithudselector.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can redistribute it
4  and/or modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation, either version 3 of the
6  License, or (at your option) any later version. You should have received
7  a copy of the GNU General Public License along with Freeciv21. If not,
8  see https://www.gnu.org/licenses/.
9  */
10 #include "unithudselector.h"
11 #include "client_main.h"
12 #include "control.h"
13 #include "dialogs.h"
14 #include "hudwidget.h"
15 #include "tileset/tilespec.h"
16 
17 // Qt
18 #include <QComboBox>
19 #include <QDialogButtonBox>
20 #include <QGroupBox>
21 #include <QHeaderView>
22 #include <QKeyEvent>
23 #include <QPainter>
24 #include <QRadioButton>
25 #include <QVBoxLayout>
26 
31 {
32  QHBoxLayout *hbox, *hibox;
33  Unit_type_id utype_id;
34  QGroupBox *no_name;
35  QVBoxLayout *groupbox_layout;
36 
37  hide();
38  struct unit *punit = head_of_units_in_focus();
39 
40  setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
41  | Qt::FramelessWindowHint);
42  main_layout = new QVBoxLayout(this);
43 
44  unit_sel_type = new QComboBox();
45 
47  {
48  utype_id = utype_index(utype);
49  if (has_player_unit_type(utype_id)) {
50  unit_sel_type->addItem(utype_name_translation(utype), utype_id);
51  }
52  }
54 
55  if (punit) {
56  int i;
57  i = unit_sel_type->findText(utype_name_translation(punit->utype));
58  unit_sel_type->setCurrentIndex(i);
59  }
60  no_name = new QGroupBox();
61  no_name->setTitle(_("Unit type"));
62  this_type = new QRadioButton(_("Selected type"), no_name);
63  this_type->setChecked(true);
64  any_type = new QRadioButton(_("All types"), no_name);
65  connect(unit_sel_type, qOverload<int>(&QComboBox::currentIndexChanged),
66  this, qOverload<int>(&unit_hud_selector::select_units));
67  connect(this_type, &QRadioButton::toggled, this,
68  qOverload<bool>(&unit_hud_selector::select_units));
69  connect(any_type, &QRadioButton::toggled, this,
70  qOverload<bool>(&unit_hud_selector::select_units));
71  groupbox_layout = new QVBoxLayout;
72  groupbox_layout->addWidget(unit_sel_type);
73  groupbox_layout->addWidget(this_type);
74  groupbox_layout->addWidget(any_type);
75  no_name->setLayout(groupbox_layout);
76  hibox = new QHBoxLayout;
77  hibox->addWidget(no_name);
78 
79  no_name = new QGroupBox();
80  no_name->setTitle(_("Unit activity"));
81  any_activity = new QRadioButton(_("Any activity"), no_name);
82  any_activity->setChecked(true);
83  fortified = new QRadioButton(_("Fortified"), no_name);
84  idle = new QRadioButton(_("Idle"), no_name);
85  sentried = new QRadioButton(_("Sentried"), no_name);
86  connect(any_activity, &QRadioButton::toggled, this,
87  qOverload<bool>(&unit_hud_selector::select_units));
88  connect(idle, &QRadioButton::toggled, this,
89  qOverload<bool>(&unit_hud_selector::select_units));
90  connect(fortified, &QRadioButton::toggled, this,
91  qOverload<bool>(&unit_hud_selector::select_units));
92  connect(sentried, &QRadioButton::toggled, this,
93  qOverload<bool>(&unit_hud_selector::select_units));
94  groupbox_layout = new QVBoxLayout;
95  groupbox_layout->addWidget(any_activity);
96  groupbox_layout->addWidget(idle);
97  groupbox_layout->addWidget(fortified);
98  groupbox_layout->addWidget(sentried);
99  no_name->setLayout(groupbox_layout);
100  hibox->addWidget(no_name);
101  main_layout->addLayout(hibox);
102 
103  no_name = new QGroupBox();
104  no_name->setTitle(_("Unit HP and MP"));
105  any = new QRadioButton(_("Any unit"), no_name);
106  full_hp = new QRadioButton(_("Full HP"), no_name);
107  full_mp = new QRadioButton(_("Full MP"), no_name);
108  full_hp_mp = new QRadioButton(_("Full HP and MP"), no_name);
109  full_hp_mp->setChecked(true);
110  connect(any, &QRadioButton::toggled, this,
111  qOverload<bool>(&unit_hud_selector::select_units));
112  connect(full_hp, &QRadioButton::toggled, this,
113  qOverload<bool>(&unit_hud_selector::select_units));
114  connect(full_mp, &QRadioButton::toggled, this,
115  qOverload<bool>(&unit_hud_selector::select_units));
116  connect(full_hp_mp, &QRadioButton::toggled, this,
117  qOverload<bool>(&unit_hud_selector::select_units));
118  groupbox_layout = new QVBoxLayout;
119  groupbox_layout->addWidget(any);
120  groupbox_layout->addWidget(full_hp);
121  groupbox_layout->addWidget(full_mp);
122  groupbox_layout->addWidget(full_hp_mp);
123  no_name->setLayout(groupbox_layout);
124  hibox = new QHBoxLayout;
125  hibox->addWidget(no_name);
126 
127  no_name = new QGroupBox();
128  no_name->setTitle(_("Location"));
129  anywhere = new QRadioButton(_("Anywhere"), no_name);
130  this_tile = new QRadioButton(_("Current tile"), no_name);
131  this_continent = new QRadioButton(_("Current continent"), no_name);
132  main_continent = new QRadioButton(_("Main continent"), no_name);
133  groupbox_layout = new QVBoxLayout;
134 
135  if (punit) {
136  this_tile->setChecked(true);
137  } else {
138  this_tile->setDisabled(true);
139  this_continent->setDisabled(true);
140  main_continent->setChecked(true);
141  }
142 
143  groupbox_layout->addWidget(this_tile);
144  groupbox_layout->addWidget(this_continent);
145  groupbox_layout->addWidget(main_continent);
146  groupbox_layout->addWidget(anywhere);
147 
148  no_name->setLayout(groupbox_layout);
149  hibox->addWidget(no_name);
150  main_layout->addLayout(hibox);
151 
152  select = new QPushButton(_("Select"));
153  cancel = new QPushButton(_("Cancel"));
154  connect(anywhere, &QRadioButton::toggled, this,
155  qOverload<bool>(&unit_hud_selector::select_units));
156  connect(this_tile, &QRadioButton::toggled, this,
157  qOverload<bool>(&unit_hud_selector::select_units));
158  connect(this_continent, &QRadioButton::toggled, this,
159  qOverload<bool>(&unit_hud_selector::select_units));
160  connect(main_continent, &QRadioButton::toggled, this,
161  qOverload<bool>(&unit_hud_selector::select_units));
162  connect(select, &QAbstractButton::clicked, this,
164  connect(cancel, &QAbstractButton::clicked, this,
166  hbox = new QHBoxLayout;
167  hbox->addWidget(cancel);
168  hbox->addWidget(select);
169 
170  result_label.setAlignment(Qt::AlignCenter);
171  main_layout->addWidget(&result_label, Qt::AlignHCenter);
172  main_layout->addLayout(hbox);
173  setLayout(main_layout);
174 }
175 
180 {
181  QPoint p;
182 
183  p = QPoint((parentWidget()->width() - sizeHint().width()) / 2,
184  (parentWidget()->height() - sizeHint().height()) / 2);
185  p = parentWidget()->mapToGlobal(p);
186  move(p);
187  setVisible(true);
188  show();
189  select_units();
190 }
191 
196 
201 {
202  const struct player *pplayer;
203 
204  pplayer = client_player();
205 
206  unit_list_iterate(pplayer->units, punit)
207  {
208  if (activity_filter(punit) && hp_filter(punit) && island_filter(punit)
209  && type_filter(punit)) {
210  unit_focus_add(punit);
211  }
212  }
214  close();
215 }
216 
220 void unit_hud_selector::uhs_cancel() { close(); }
221 
226 {
227  int num = 0;
228  const struct player *pplayer;
229 
230  pplayer = client_player();
231 
232  unit_list_iterate(pplayer->units, punit)
233  {
234  if (activity_filter(punit) && hp_filter(punit) && island_filter(punit)
235  && type_filter(punit)) {
236  num++;
237  }
238  }
240  result_label.setText(QString(PL_("%1 unit", "%1 units", num)).arg(num));
241 }
242 
247 
252 {
253  if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)) {
254  uhs_select();
255  }
256  if (event->key() == Qt::Key_Escape) {
257  close();
258  event->accept();
259  }
260  QWidget::keyPressEvent(event);
261 }
262 
267 {
268  return (punit->activity == ACTIVITY_FORTIFIED && fortified->isChecked())
269  || (punit->activity == ACTIVITY_SENTRY && sentried->isChecked())
270  || (punit->activity == ACTIVITY_IDLE && idle->isChecked())
271  || any_activity->isChecked();
272 }
273 
278 {
279  return any->isChecked()
280  || (full_mp->isChecked()
281  && punit->moves_left >= punit->utype->move_rate)
282  || (full_hp->isChecked() && punit->hp >= punit->utype->hp)
283  || (full_hp_mp->isChecked() && punit->hp >= punit->utype->hp
284  && punit->moves_left >= punit->utype->move_rate);
285 }
286 
291 {
292  int island = -1;
293  struct unit *cunit = head_of_units_in_focus();
294 
295  if (this_tile->isChecked() && cunit) {
296  if (punit->tile == cunit->tile) {
297  return true;
298  }
299  }
300 
301  if (main_continent->isChecked()
304  } else if (this_continent->isChecked() && cunit) {
305  island = cunit->tile->continent;
306  }
307 
308  if (island > -1) {
309  if (punit->tile->continent == island) {
310  return true;
311  }
312  }
313 
314  return anywhere->isChecked();
315 }
316 
321 {
322  QVariant qvar;
323  Unit_type_id utype_id;
324 
325  if (this_type->isChecked()) {
326  qvar = unit_sel_type->currentData();
327  utype_id = qvar.toInt();
328  return utype_id == utype_index(punit->utype);
329  }
330  return any_type->isChecked();
331 }
QRadioButton * this_continent
QComboBox * unit_sel_type
QRadioButton * sentried
QVBoxLayout * main_layout
QRadioButton * anywhere
QRadioButton * main_continent
QRadioButton * full_hp_mp
QPushButton * cancel
bool island_filter(struct unit *punit)
Filter by location.
bool type_filter(struct unit *punit)
Filter by type.
unit_hud_selector(QWidget *parent)
Constructor for unit_hud_selector.
void uhs_select()
Selects and closes widget.
~unit_hud_selector() override
Unit_hud_selector destructor.
QRadioButton * full_mp
void select_units(int x=0)
Shows number of selected units on label.
QRadioButton * fortified
QRadioButton * this_tile
QRadioButton * any_type
QRadioButton * any_activity
QPushButton * select
QRadioButton * any
bool activity_filter(struct unit *punit)
Filter by activity.
bool hp_filter(struct unit *punit)
Filter by hp/mp.
QRadioButton * full_hp
QRadioButton * this_type
void show_me()
Shows and moves to center unit_hud_selector.
void uhs_cancel()
Closes current widget.
QRadioButton * idle
void keyPressEvent(QKeyEvent *event) override
Key press event for unit_hud_selector.
struct player * client_player()
Either controlling or observing.
void unit_focus_add(struct unit *punit)
Adds this unit to the list of units in focus.
Definition: control.cpp:534
struct unit * head_of_units_in_focus()
Return head of focus units list.
Definition: control.cpp:387
enum event_type event
Definition: events.cpp:68
int Unit_type_id
Definition: fc_types.h:299
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
bool has_player_unit_type(Unit_type_id utype)
Returns true if player has any unit of unit_type.
Definition: hudwidget.cpp:51
struct city * player_primary_capital(const struct player *pplayer)
Locate the player's primary capital city, (nullptr Otherwise)
Definition: player.cpp:1247
struct tile * tile
Definition: city.h:293
Definition: player.h:231
struct unit_list * units
Definition: player.h:264
Continent_id continent
Definition: tile.h:46
int move_rate
Definition: unittype.h:481
int hp
Definition: unittype.h:489
Definition: unit.h:134
enum unit_activity activity
Definition: unit.h:154
int moves_left
Definition: unit.h:147
int hp
Definition: unit.h:148
struct tile * tile
Definition: unit.h:136
const struct unit_type * utype
Definition: unit.h:135
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27
const char * utype_name_translation(const struct unit_type *punittype)
Return the (translated) name of the unit type.
Definition: unittype.cpp:1256
Unit_type_id utype_index(const struct unit_type *punittype)
Return the unit type index.
Definition: unittype.cpp:82
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define unit_type_iterate_end
Definition: unittype.h:791