The Battle for Wesnoth  1.19.0-dev
mouse_action.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2024
3  by Tomasz Sniatowski <kailoran@gmail.com>
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 #pragma once
17 
19 #include "theme.hpp"
23 
24 class CKey;
25 
26 namespace editor {
27 
28 /**
29  * A mouse action receives events from the controller, and responds to them by creating
30  * an appropriate editor_action object. Mouse actions may store some temporary data
31  * such as the last clicked hex for better handling of click-drag. They should *not* modify
32  * the map or trigger refreshes, but may set brush locations and similar overlays that
33  * should be visible around the mouse cursor, hence the display references are not const.
34  */
36 {
37 public:
40  , key_(key)
41  , toolbar_button_(nullptr)
42  , palette_(palette)
43  {
44  }
45 
46  virtual ~mouse_action() {}
47 
48  virtual bool has_context_menu() const;
49 
50  /**
51  * Mouse move (not a drag). Never changes anything (other than temporary highlights and similar)
52  */
53  virtual void move(editor_display& disp, const map_location& hex);
54 
55  /**
56  * Unconditionally update the brush highlights for the current tool when hex is the center location
57  */
58  void update_brush_highlights(editor_display& disp, const map_location& hex);
59 
60  /**
61  * Locations that would be affected by a click, used by move to update highlights. Defaults to highlight the mouseover hex.
62  * Maybe also used for actually performing the action in click() or drag().
63  */
64  virtual std::set<map_location> affected_hexes(editor_display& disp, const map_location& hex);
65 
66  /**
67  * A click, possibly the beginning of a drag. Must be overridden.
68  */
69  virtual std::unique_ptr<editor_action> click_left(editor_display& disp, int x, int y) = 0;
70 
71  /**
72  * A click, possibly the beginning of a drag. Must be overridden.
73  */
74  virtual std::unique_ptr<editor_action> click_right(editor_display& disp, int x, int y) = 0;
75 
76  /**
77  * Drag operation. A click should have occurred earlier. Defaults to no action.
78  */
79  virtual std::unique_ptr<editor_action> drag_left(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
80 
81  /**
82  * Drag operation. A click should have occurred earlier. Defaults to no action.
83  */
84  virtual std::unique_ptr<editor_action> drag_right(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
85 
86  /**
87  * The end of dragging. Defaults to no action.
88  */
89  virtual std::unique_ptr<editor_action> drag_end_left(editor_display& disp, int x, int y);
90 
91  virtual std::unique_ptr<editor_action> drag_end_right(editor_display& disp, int x, int y);
92 
93  virtual std::unique_ptr<editor_action> up_left(editor_display& disp, int x, int y);
94 
95  virtual std::unique_ptr<editor_action> up_right(editor_display& disp, int x, int y);
96 
97  /**
98  * Function called by the controller on a key event for the current mouse action.
99  * Defaults to starting position processing.
100  */
101  virtual std::unique_ptr<editor_action> key_event(editor_display& disp, const SDL_Event& e);
102 
103  /**
104  * Helper variable setter - pointer to a toolbar menu/button used for highlighting
105  * the current action. Should always be nullptr or point to a valid menu.
106  */
107  void set_toolbar_button(const theme::menu* value) { toolbar_button_ = value; }
108 
109  /**
110  * Getter for the (possibly nullptr) associated menu/button.
111  */
112  const theme::menu* toolbar_button() const { return toolbar_button_; }
113 
114  /**
115  * Getter for the associated palette.
116  */
118 
119  /** Whether we need the brush bar, is used to grey it out.*/
120  virtual bool supports_brushes() const { return false; }
121 
122  /**
123  * Set the mouse overlay for this action. Defaults to an empty overlay.
124  */
125  virtual void set_mouse_overlay(editor_display& disp);
126 
127 
128 protected:
129  bool has_alt_modifier() const;
130  bool has_shift_modifier() const;
131  bool has_ctrl_modifier() const;
132 
133  /**
134  * Helper function for derived classes that need a active-terrain mouse overlay
135  */
137  const t_translation::terrain_code & fg,
138  const t_translation::terrain_code & bg);
139 
140  /**
141  * The hex previously used in move operations
142  */
144 
145  /**
146  * Key presses, used for modifiers (alt, shift) in some operations
147  */
148  const CKey& key_;
149 
150 private:
151  /**
152  * Pointer to an associated menu/button, if such exists
153  */
155 
156  /**
157  * Pointer to an associated palette, if such exists
158  */
160 };
161 
162 /**
163  * A brush-drag mouse action base class which adds brush and drag processing to a basic mouse action
164  */
166 {
167 public:
168  brush_drag_mouse_action(common_palette& palette, const brush* const * const brush, const CKey& key)
169  : mouse_action(palette, key)
171  , brush_(brush)
172  {
173  }
174 
175  /**
176  * The affected hexes of a brush action are the result of projecting the current brush on the mouseover hex
177  */
178  std::set<map_location> affected_hexes(editor_display& disp, const map_location& hex);
179 
180  /**
181  * The actual action function which is called by click() and drag(). Derived classes override this instead of click() and drag().
182  */
183  virtual std::unique_ptr<editor_action> click_perform_left(editor_display& disp, const std::set<map_location>& hexes) = 0;
184 
185  /**
186  * The actual action function which is called by click() and drag(). Derived classes override this instead of click() and drag().
187  */
188  virtual std::unique_ptr<editor_action> click_perform_right(editor_display& disp, const std::set<map_location>& hexes) = 0;
189 
190  /**
191  * Calls click_perform_left()
192  */
193  std::unique_ptr<editor_action> click_left(editor_display& disp, int x, int y);
194 
195  /**
196  * Calls click_perform_right()
197  */
198  std::unique_ptr<editor_action> click_right(editor_display& disp, int x, int y);
199 
200  /**
201  * Calls click_perform() for every new hex the mouse is dragged into.
202  * @todo partial actions support and merging of many drag actions into one
203  */
204  std::unique_ptr<editor_action> drag_left(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
205 
206  /**
207  * Calls click_perform for every new hex the mouse is dragged into.
208  * @todo partial actions support and merging of many drag actions into one
209  */
210  std::unique_ptr<editor_action> drag_right(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
211 
212  /**
213  * End of dragging.
214  * @todo partial actions (the entire drag should end up as one action)
215  */
216  std::unique_ptr<editor_action> drag_end(editor_display& disp, int x, int y);
217 
218 protected:
219  /** Brush accessor */
220  const brush& get_brush();
221 
222  /**
223  * The previous hex dragged into.
224  * @todo keep a set of all "visited" locations to reduce action count in long drags that hit the same hexes multiple times?
225  */
227 
228 private:
229  /**
230  * Template helper gathering actions common for both drag_right and drag_left.
231  * The drags differ only in the worker function called, which should be
232  * passed as the template parameter. This exists only to avoid copy-pasting code.
233  */
234  template <std::unique_ptr<editor_action> (brush_drag_mouse_action::*perform_func)(editor_display&, const std::set<map_location>&)>
235  std::unique_ptr<editor_action> drag_generic(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
236 
237  /**
238  * Current brush handle. Currently a pointer-to-pointer with full constness.
239  * The mouse action does not modify the brush, does not modify the pointer
240  * to the current brush, and we allow setting this pointr only once, hence
241  * the three "consts".
242  */
243  const brush* const * const brush_;
244 };
245 
246 /**
247  * Brush paint mouse action. Uses keyboard modifiers for one-layer painting.
248  */
250 {
251 public:
253  const brush* const * const brush, const CKey& key, terrain_palette& palette)
256  {
257  }
258 
259  /**
260  * Handle terrain sampling before calling generic handler
261  */
262  std::unique_ptr<editor_action> click_left(editor_display& disp, int x, int y) override;
263 
264  /**
265  * Handle terrain sampling before calling generic handler
266  */
267  std::unique_ptr<editor_action> click_right(editor_display& disp, int x, int y) override;
268 
269  /**
270  * Create an appropriate editor_action and return it
271  */
272  std::unique_ptr<editor_action> click_perform_left(editor_display& disp, const std::set<map_location>& hexes) override;
273 
274  /**
275  * Create an appropriate editor_action and return it
276  */
277  std::unique_ptr<editor_action> click_perform_right(editor_display& disp, const std::set<map_location>& hexes) override;
278 
279  void set_mouse_overlay(editor_display& disp) override;
280 
281  virtual bool supports_brushes() const override { return true; }
282 
283 protected:
284 
286 
287 };
288 
289 
290 
291 /**
292  * Paste action. No dragging capabilities.
293  */
295 {
296 public:
298  : mouse_action(palette, key), paste_(paste)
299  {
300  }
301 
302  virtual bool has_context_menu() const override;
303 
304  /**
305  * Show an outline of where the paste will go
306  */
307  std::set<map_location> affected_hexes(editor_display& disp, const map_location& hex) override;
308 
309  /**
310  * Return a paste with offset action
311  */
312  std::unique_ptr<editor_action> click_left(editor_display& disp, int x, int y) override;
313 
314  /**
315  * Right click does nothing for now
316  */
317  std::unique_ptr<editor_action> click_right(editor_display& disp, int x, int y) override;
318 
319  virtual void set_mouse_overlay(editor_display& disp) override;
320 
321 protected:
322  /**
323  * Reference to the buffer used for pasting (e.g. the clipboard)
324  */
326 };
327 
328 /**
329  * Fill action. No dragging capabilities. Uses keyboard modifiers for one-layer painting.
330  */
332 {
333 public:
338  {
339  }
340 
341  /**
342  * Tiles that will be painted to, possibly use modifier keys here
343  */
344  std::set<map_location> affected_hexes(editor_display& disp, const map_location& hex) override;
345 
346  /**
347  * Left / right click fills with the respective terrain
348  */
349  std::unique_ptr<editor_action> click_left(editor_display& disp, int x, int y) override;
350 
351  /**
352  * Left / right click fills with the respective terrain
353  */
354  std::unique_ptr<editor_action> click_right(editor_display& disp, int x, int y) override;
355 
356  virtual void set_mouse_overlay(editor_display& disp) override;
357 
358 protected:
360 };
361 
362 /**
363  * Set starting position action.
364  */
366 {
367 public:
370  {
371  }
372 
373  /**
374  * Left click displays a player-number-selector dialog and then creates an action
375  * or returns nullptr if cancel was pressed or there would be no change.
376  * Do this on mouse up to avoid drag issue.
377  */
378  std::unique_ptr<editor_action> up_left(editor_display& disp, int x, int y) override;
379 
380  std::unique_ptr<editor_action> click_left(editor_display& disp, int x, int y) override;
381  /**
382  * Right click only erases the starting position if there is one.
383  * Do this on mouse up to avoid drag issue,
384  */
385  std::unique_ptr<editor_action> up_right(editor_display& disp, int x, int y) override;
386 
387  std::unique_ptr<editor_action> click_right(editor_display& disp, int x, int y) override;
388 
389  virtual void set_mouse_overlay(editor_display& disp) override;
390 
391 private:
392  bool click_;
394 };
395 
396 
397 
398 } //end namespace editor
Base class for editor actions.
Class that keeps track of all the keys on the keyboard.
Definition: key.hpp:29
A brush-drag mouse action base class which adds brush and drag processing to a basic mouse action.
std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y)
Calls click_perform_left()
std::unique_ptr< editor_action > drag_right(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Calls click_perform for every new hex the mouse is dragged into.
const brush *const *const brush_
Current brush handle.
virtual std::unique_ptr< editor_action > click_perform_right(editor_display &disp, const std::set< map_location > &hexes)=0
The actual action function which is called by click() and drag().
const brush & get_brush()
Brush accessor.
std::unique_ptr< editor_action > drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Calls click_perform() for every new hex the mouse is dragged into.
std::unique_ptr< editor_action > drag_end(editor_display &disp, int x, int y)
End of dragging.
std::unique_ptr< editor_action > drag_generic(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Template helper gathering actions common for both drag_right and drag_left.
map_location previous_drag_hex_
The previous hex dragged into.
std::set< map_location > affected_hexes(editor_display &disp, const map_location &hex)
The affected hexes of a brush action are the result of projecting the current brush on the mouseover ...
virtual std::unique_ptr< editor_action > click_perform_left(editor_display &disp, const std::set< map_location > &hexes)=0
The actual action function which is called by click() and drag().
brush_drag_mouse_action(common_palette &palette, const brush *const *const brush, const CKey &key)
std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y)
Calls click_perform_right()
The brush class represents a single brush – a set of relative locations around a "hotspot",...
Definition: brush.hpp:27
Base class for all editor actions.
Definition: action_base.hpp:42
List of starting locations and location ids.
A map fragment – a collection of locations and information abut them.
terrain_palette & terrain_palette_
std::set< map_location > affected_hexes(editor_display &disp, const map_location &hex) override
Tiles that will be painted to, possibly use modifier keys here.
std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y) override
Left / right click fills with the respective terrain.
std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y) override
Left / right click fills with the respective terrain.
mouse_action_fill(const CKey &key, terrain_palette &terrain_palette)
virtual void set_mouse_overlay(editor_display &disp) override
Set the mouse overlay for this action.
Brush paint mouse action.
std::unique_ptr< editor_action > click_perform_right(editor_display &disp, const std::set< map_location > &hexes) override
Create an appropriate editor_action and return it.
virtual bool supports_brushes() const override
Whether we need the brush bar, is used to grey it out.
mouse_action_paint(const brush *const *const brush, const CKey &key, terrain_palette &palette)
std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y) override
Handle terrain sampling before calling generic handler.
terrain_palette & terrain_palette_
void set_mouse_overlay(editor_display &disp) override
Set the mouse overlay for this action.
std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y) override
Handle terrain sampling before calling generic handler.
std::unique_ptr< editor_action > click_perform_left(editor_display &disp, const std::set< map_location > &hexes) override
Create an appropriate editor_action and return it.
virtual bool has_context_menu() const override
std::set< map_location > affected_hexes(editor_display &disp, const map_location &hex) override
Show an outline of where the paste will go.
std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y) override
Return a paste with offset action.
virtual void set_mouse_overlay(editor_display &disp) override
Set the mouse overlay for this action.
std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y) override
Right click does nothing for now.
const map_fragment & paste_
Reference to the buffer used for pasting (e.g.
mouse_action_paste(const map_fragment &paste, const CKey &key, common_palette &palette)
Set starting position action.
std::unique_ptr< editor_action > up_right(editor_display &disp, int x, int y) override
Right click only erases the starting position if there is one.
std::unique_ptr< editor_action > up_left(editor_display &disp, int x, int y) override
Left click displays a player-number-selector dialog and then creates an action or returns nullptr if ...
std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y) override
A click, possibly the beginning of a drag.
std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y) override
A click, possibly the beginning of a drag.
virtual void set_mouse_overlay(editor_display &disp) override
Set the mouse overlay for this action.
mouse_action_starting_position(const CKey &key, location_palette &palette)
A mouse action receives events from the controller, and responds to them by creating an appropriate e...
virtual std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
const theme::menu * toolbar_button_
Pointer to an associated menu/button, if such exists.
bool has_shift_modifier() const
virtual std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
void update_brush_highlights(editor_display &disp, const map_location &hex)
Unconditionally update the brush highlights for the current tool when hex is the center location.
virtual std::unique_ptr< editor_action > drag_end_right(editor_display &disp, int x, int y)
virtual bool has_context_menu() const
void set_terrain_mouse_overlay(editor_display &disp, const t_translation::terrain_code &fg, const t_translation::terrain_code &bg)
Helper function for derived classes that need a active-terrain mouse overlay.
mouse_action(common_palette &palette, const CKey &key)
virtual std::set< map_location > affected_hexes(editor_display &disp, const map_location &hex)
Locations that would be affected by a click, used by move to update highlights.
virtual std::unique_ptr< editor_action > up_left(editor_display &disp, int x, int y)
bool has_ctrl_modifier() const
const CKey & key_
Key presses, used for modifiers (alt, shift) in some operations.
map_location previous_move_hex_
The hex previously used in move operations.
void set_toolbar_button(const theme::menu *value)
Helper variable setter - pointer to a toolbar menu/button used for highlighting the current action.
virtual void move(editor_display &disp, const map_location &hex)
Mouse move (not a drag).
virtual std::unique_ptr< editor_action > up_right(editor_display &disp, int x, int y)
virtual std::unique_ptr< editor_action > key_event(editor_display &disp, const SDL_Event &e)
Function called by the controller on a key event for the current mouse action.
common_palette & palette_
Pointer to an associated palette, if such exists.
virtual std::unique_ptr< editor_action > drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
const theme::menu * toolbar_button() const
Getter for the (possibly nullptr) associated menu/button.
common_palette & get_palette()
Getter for the associated palette.
virtual std::unique_ptr< editor_action > drag_right(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
virtual void set_mouse_overlay(editor_display &disp)
Set the mouse overlay for this action.
virtual bool supports_brushes() const
Whether we need the brush bar, is used to grey it out.
bool has_alt_modifier() const
virtual std::unique_ptr< editor_action > drag_end_left(editor_display &disp, int x, int y)
The end of dragging.
Palette where the terrain to be drawn can be selected.
std::vector< color_t > palette(const color_range &cr)
Creates a reference color palette from a color range.
Definition: color_range.cpp:84
Manage the empty-palette in the editor.
Definition: action.cpp:31
Encapsulates the map of the game.
Definition: location.hpp:38
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:49
Definitions related to theme-support.
#define e