The Battle for Wesnoth  1.19.0+dev
menu_item.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * Declarations for a class that implements WML-defined (right-click) menu items.
19  */
20 
21 #pragma once
22 
23 #include "config.hpp"
25 #include "variable.hpp"
26 
27 #include <optional>
28 
29 class filter_context;
30 class game_data;
31 class game_lua_kernel;
32 struct map_location;
33 
34 namespace game_events
35 {
37 {
38 public:
39  /**
40  * Constructor for reading from a saved config.
41  * This is the reverse of to_config() and corresponds to reading [menu_item].
42  * Handlers are not initialized.
43  */
44  wml_menu_item(const std::string& id, const config& cfg);
45 
46  /**
47  * Constructor for items defined in an event.
48  * This is where default values are defined (the other constructors should have
49  * all values to work with).
50  * @param[in] id The id of the menu item.
51  * @param[in] definition The WML defining this menu item.
52  */
53  wml_menu_item(const std::string& id, const vconfig& definition);
54 
55  /**
56  * Constructor for items modified by an event.
57  * (To avoid problems with a menu item's command changing itself, we make a
58  * new menu item instead of modifying the existing one.)
59  * @param[in] id The id of the menu item.
60  * @param[in] definition The WML defining this menu item.
61  * @param[in] original The previous version of the menu item with this id.
62  */
63  wml_menu_item(const std::string& id, const vconfig& definition, wml_menu_item& original);
64 
65  /** The id of this item. */
66  const std::string& id() const
67  {
68  return item_id_;
69  }
70 
71  /**
72  * The image associated with this menu item.
73  * The returned string will not be empty; a default will be supplied if needed.
74  */
75  const std::string& image() const;
76 
77  /** If true, allow using the menu to trigger this item. */
78  bool use_wml_menu() const
79  {
80  return use_wml_menu_;
81  }
82 
83  /** If true, holding the hotkey will trigger this item repeatedly. */
84  bool hotkey_repeat() const
85  {
86  return default_hotkey_["repeat_on_hold"].to_bool(false);
87  }
88 
89  /**
90  * Returns whether or not *this is applicable given the context.
91  * Assumes game variables x1, y1, and unit have been set.
92  * @param[in] hex The hex where the menu will appear.
93  * @param[in] data Used to check whether to show if selecting is required.
94  * @param[in] context Used to check whether the menu's filter matches.
95  */
96  bool can_show(const map_location& hex, const game_data& data, filter_context& context) const;
97 
98  /**
99  * Causes the event associated with this item to fire.
100  * Also records the event.
101  * This includes recording the previous select event, if applicable.
102  * The undo stack will be cleared if the event mutated the gamestate.
103  *
104  * @param[in] event_hex The location of the event (where the menu was opened).
105  * @param[in] data The game data for the most recent "select" event.
106  */
107  void fire_event(const map_location& event_hex, const game_data& data) const;
108 
109  /** Removes the implicit event handler for an inlined [command]. */
110  void finish_handler();
111 
112  /** Initializes the implicit event handler for an inlined [command]. */
113  void init_handler(game_lua_kernel& lk);
114 
115  /**
116  * The text to put in a menu for this item.
117  */
118  std::string menu_text() const
119  {
120  return description_.str();
121  }
122 
123  /**
124  * The UI action id to be used in theme wml, menu items and hotkeys .
125  */
126  std::string hotkey_id() const
127  {
128  // The space is to prevent accidental hotkey binding.
129  return hotkey_id_;
130  }
131 
132  /**
133  * Writes *this to the provided config.
134  * This is the reverse of the constructor from a config and corresponds to
135  * what will appear in [menu_item].
136  */
137  void to_config(config& cfg) const;
138 
139  bool is_synced() const
140  {
141  return is_synced_;
142  }
143 
144 private:
145  /**
146  * Updates *this based on @a vcfg.
147  * This corresponds to what can appear in [set_menu_item].
148  */
149  void update(const vconfig& vcfg);
150 
151  /** Updates our command to @a new_command. */
152  void update_command(const config& new_command);
153 
154 private:
155  /** The id of this menu item. */
156  const std::string item_id_;
157 
158  /** The name of this item's event(s); based on the item's id. */
159  const std::string event_name_;
160 
161  /** The id for this item's hotkey; based on the item's id. */
162  const std::string hotkey_id_;
163 
164  /** Controls the lifetime of the associate hotkey's hotkey_command. */
165  std::optional<hotkey::wml_hotkey_record> hotkey_record_;
166 
167  /** The image to display in the menu next to this item's description. */
168  std::string image_;
169 
170  /** The text to display in the menu for this item. */
172 
173  /** Whether or not this event says it makes use of the last selected unit. */
175 
176  /**
177  * A condition that must hold in order for this menu item to be visible.
178  * (An empty condition always holds.)
179  *
180  * When used, we need a vconfig instead of a config.
181  */
183 
184  /**
185  * A location filter to be applied to the hex where the menu is invoked.
186  * (An empty filter always passes.)
187  *
188  * When used, we need a vconfig instead of a config.
189  */
191 
192  /** Actions to take when this item is chosen. */
194 
195  /** Config object containing the default hotkey. */
197 
198  /** If true, allow using a hotkey to trigger this item. */
200 
201  /** If true, allow using the menu to trigger this item. */
203 
204  /**
205  * If true, this item will be sent to the clients.
206  * The command shall not change the gamestate if !is_synced_
207  */
209 
210  /** If true, keep this menu item in later scenarios. */
212 };
213 
214 } // end namespace game_events
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
const std::string event_name_
The name of this item's event(s); based on the item's id.
Definition: menu_item.hpp:159
bool needs_select_
Whether or not this event says it makes use of the last selected unit.
Definition: menu_item.hpp:174
config command_
Actions to take when this item is chosen.
Definition: menu_item.hpp:193
void fire_event(const map_location &event_hex, const game_data &data) const
Causes the event associated with this item to fire.
Definition: menu_item.cpp:168
void update(const vconfig &vcfg)
Updates *this based on vcfg.
Definition: menu_item.cpp:269
std::string menu_text() const
The text to put in a menu for this item.
Definition: menu_item.hpp:118
const std::string hotkey_id_
The id for this item's hotkey; based on the item's id.
Definition: menu_item.hpp:162
bool use_hotkey_
If true, allow using a hotkey to trigger this item.
Definition: menu_item.hpp:199
wml_menu_item(const std::string &id, const config &cfg)
Constructor for reading from a saved config.
Definition: menu_item.cpp:70
const std::string item_id_
The id of this menu item.
Definition: menu_item.hpp:156
std::string image_
The image to display in the menu next to this item's description.
Definition: menu_item.hpp:168
void update_command(const config &new_command)
Updates our command to new_command.
Definition: menu_item.cpp:340
vconfig show_if_
A condition that must hold in order for this menu item to be visible.
Definition: menu_item.hpp:182
bool can_show(const map_location &hex, const game_data &data, filter_context &context) const
Returns whether or not *this is applicable given the context.
Definition: menu_item.cpp:147
bool use_wml_menu_
If true, allow using the menu to trigger this item.
Definition: menu_item.hpp:202
const std::string & image() const
The image associated with this menu item.
Definition: menu_item.cpp:140
bool persistent_
If true, keep this menu item in later scenarios.
Definition: menu_item.hpp:211
bool hotkey_repeat() const
If true, holding the hotkey will trigger this item repeatedly.
Definition: menu_item.hpp:84
void init_handler(game_lua_kernel &lk)
Initializes the implicit event handler for an inlined [command].
Definition: menu_item.cpp:209
config default_hotkey_
Config object containing the default hotkey.
Definition: menu_item.hpp:196
vconfig filter_location_
A location filter to be applied to the hex where the menu is invoked.
Definition: menu_item.hpp:190
void finish_handler()
Removes the implicit event handler for an inlined [command].
Definition: menu_item.cpp:196
const std::string & id() const
The id of this item.
Definition: menu_item.hpp:66
bool use_wml_menu() const
If true, allow using the menu to trigger this item.
Definition: menu_item.hpp:78
bool is_synced_
If true, this item will be sent to the clients.
Definition: menu_item.hpp:208
std::optional< hotkey::wml_hotkey_record > hotkey_record_
Controls the lifetime of the associate hotkey's hotkey_command.
Definition: menu_item.hpp:165
void to_config(config &cfg) const
Writes *this to the provided config.
Definition: menu_item.cpp:223
t_string description_
The text to display in the menu for this item.
Definition: menu_item.hpp:171
std::string hotkey_id() const
The UI action id to be used in theme wml, menu items and hotkeys .
Definition: menu_item.hpp:126
const std::string & str() const
Definition: tstring.hpp:190
A variable-expanding proxy for the config class.
Definition: variable.hpp:45
Domain specific events.
std::string_view data
Definition: picture.cpp:194
Encapsulates the map of the game.
Definition: location.hpp:38