Freeciv21
Develop your civilization from humble roots to a global empire
unit_quick_menu.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2023 Louis Moureaux <m_louis30@yahoo.com>
3  * SPDX-FileCopyrightText: Copyright (c) 1996-2022 Freeciv21 and Freeciv
4  * contributors
5  *
6  * SPDX-License-Identifier: GPLv3-or-later
7  */
8 
9 #include "unit_quick_menu.h"
10 #include "actions.h"
11 #include "citydlg.h"
12 #include "client_main.h"
13 #include "control.h"
14 #include "dialogs.h"
15 #include "game.h"
16 #include "page_game.h"
17 #include "qtg_cxxside.h"
18 #include "unit.h"
19 #include "unitlist.h"
20 
21 #include <QMenu>
22 #include <algorithm>
23 
24 namespace freeciv {
25 
26 namespace /* anonymous */ {
27 
32 template <class Callback>
33 auto unit_action_helper(const std::vector<int> &unit_ids, Callback &&cb)
34 {
35  return [unit_ids, cb] {
36  // Check playable units
37  if (!can_client_issue_orders()) {
38  return;
39  }
40 
41  auto units = std::vector<unit *>();
42  for (const auto id : unit_ids) {
43  const auto unit = game_unit_by_number(id);
44  // Maybe some units died
45  if (unit && unit_owner(unit) == client_player()) {
46  units.push_back(unit);
47  }
48  }
49 
50  cb(units);
51  };
52 }
53 
57 template <class RetType> using unit_callback_type = RetType (*)(unit *);
58 
64 template <class RetType>
65 auto unit_action_helper(const std::vector<int> &unit_ids,
66  unit_callback_type<RetType> cb)
67 {
68  return unit_action_helper(unit_ids, [cb](auto units) {
69  std::for_each(units.begin(), units.end(), cb);
70  });
71 }
72 
78 template <class Callback>
79 void add_units_action(QMenu *menu, const QString &text,
80  const std::vector<int> &unit_ids, bool enabled,
81  Callback &&cb)
82 {
83  auto action = menu->addAction(text, unit_action_helper(unit_ids, cb));
84  action->setEnabled(enabled && can_client_issue_orders());
85 }
86 
90 void activate_callback(const std::vector<unit *> &units)
91 {
92  unit_focus_set(nullptr); // Clear
93  for (const auto unit : units) {
95  }
96 
97  if (!units.empty()) {
98  queen()->city_overlay->dont_focus = true;
100  }
101 }
102 
106 void load_callback(const std::vector<unit *> &units)
107 {
108  for (const auto unit : units) {
110  }
111 }
112 
113 } // anonymous namespace
114 
119 void add_quick_unit_actions(QMenu *menu, const std::vector<unit *> &units)
120 {
121  // Get unit IDs (don't store pointers that could be deleted)
122  std::vector<int> unit_ids;
123  std::transform(units.begin(), units.end(), std::back_inserter(unit_ids),
124  [](auto u) { return u->id; });
125 
126  add_units_action(menu, _("Activate Unit"), unit_ids, true,
127  activate_callback);
128 
129  add_units_action(menu, _("Sentry Unit"), unit_ids,
130  can_units_do_activity(units, ACTIVITY_SENTRY),
132 
133  add_units_action(menu, action_id_name_translation(ACTION_FORTIFY),
134  unit_ids,
135  units_can_do_action(units, ACTION_FORTIFY, true),
137 
138  add_units_action(menu, action_id_name_translation(ACTION_DISBAND_UNIT),
139  unit_ids,
140  units_can_do_action(units, ACTION_DISBAND_UNIT, true),
142 
143  add_units_action(menu, action_id_name_translation(ACTION_HOME_CITY),
144  unit_ids,
145  units_can_do_action(units, ACTION_HOME_CITY, true),
147 
148  add_units_action(menu, action_id_name_translation(ACTION_TRANSPORT_BOARD),
149  unit_ids, units_can_load(units), load_callback);
150 
151  add_units_action(menu, action_id_name_translation(ACTION_TRANSPORT_ALIGHT),
152  unit_ids, units_can_unload(units), request_unit_unload);
153 
154  add_units_action(menu, action_id_name_translation(ACTION_TRANSPORT_UNLOAD),
155  unit_ids, units_are_occupied(units),
157 
158  add_units_action(menu, action_id_name_translation(ACTION_UPGRADE_UNIT),
159  unit_ids, units_can_upgrade(units), popup_upgrade_dialog);
160 }
161 
162 } // namespace freeciv
const QString action_id_name_translation(action_id act_id)
Get the action name used when displaying the action in the UI.
Definition: actions.cpp:1373
void popdown_city_dialog()
Closes the city overlay.
Definition: citydlg.cpp:2264
bool dont_focus
Definition: citydlg.h:300
city_dialog * city_overlay
Definition: page_game.h:83
struct player * client_player()
Either controlling or observing.
bool can_client_issue_orders()
Returns TRUE iff the client can issue orders (such as giving unit commands).
void request_unit_fortify(struct unit *punit)
Try to fortify unit.
Definition: control.cpp:2077
void unit_focus_add(struct unit *punit)
Adds this unit to the list of units in focus.
Definition: control.cpp:534
void unit_focus_set(struct unit *punit)
Sets the focus unit directly.
Definition: control.cpp:479
struct unit * request_unit_unload_all(struct unit *punit)
Returns one of the unit of the transporter which can have focus next.
Definition: control.cpp:1364
void request_unit_change_homecity(struct unit *punit)
Send request to change unit homecity to server.
Definition: control.cpp:1872
void request_unit_unload(struct unit *pcargo)
Send a request to the server that the cargo be unloaded from its current transporter.
Definition: control.cpp:1962
void request_unit_sentry(struct unit *punit)
Try to sentry unit.
Definition: control.cpp:2066
void popup_upgrade_dialog(const std::vector< unit * > &punits)
Popup dialog for upgrade units.
Definition: dialogs.cpp:3759
bool request_transport(struct unit *pcargo, struct tile *ptile)
Unit wants to get into some transport on given tile.
Definition: dialogs.cpp:3827
void popup_disband_dialog(const std::vector< unit * > &punits)
Pops up a dialog to confirm disband of the unit(s).
Definition: dialogs.cpp:3395
#define _(String)
Definition: fcintl.h:50
struct unit * game_unit_by_number(int id)
Find unit out of all units in game: now uses fast idex method, instead of looking through all units o...
Definition: game.cpp:112
Definition: path.cpp:10
void add_quick_unit_actions(QMenu *menu, const std::vector< unit * > &units)
Adds a small set of common unit actions to a menu.
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
Definition: unit.h:134
#define unit_tile(_pu)
Definition: unit.h:371
#define unit_owner(_pu)
Definition: unit.h:370
bool units_can_load(const std::vector< unit * > &units)
Returns TRUE iff any of these units can load.
Definition: unitlist.cpp:247
bool units_can_do_action(const std::vector< unit * > &units, action_id act_id, bool can_do)
If has_flag is true, returns true iff any of the units are able to do the specified action.
Definition: unitlist.cpp:218
bool units_are_occupied(const std::vector< unit * > &units)
Return TRUE iff any of the units is a transporter that is occupied.
Definition: unitlist.cpp:233
bool units_can_unload(const std::vector< unit * > &units)
Return TRUE iff any of these units can unload.
Definition: unitlist.cpp:261
bool can_units_do_activity(const std::vector< unit * > &units, enum unit_activity activity)
Returns TRUE if any of the units can do the activity.
Definition: unitlist.cpp:104
bool units_can_upgrade(const std::vector< unit * > &units)
Return TRUE iff any of the units can be upgraded to another unit type (for money)
Definition: unitlist.cpp:294