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