The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
mouse_action.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2017 by Tomasz Sniatowski <kailoran@gmail.com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
19 #include "theme.hpp"
24 
25 class CKey;
26 
27 namespace editor {
28 
29 /**
30  * A mouse action receives events from the controller, and responds to them by creating
31  * an appropriate editor_action object. Mouse actions may store some temporary data
32  * such as the last clicked hex for better handling of click-drag. They should *not* modify
33  * the map or trigger refreshes, but may set brush locations and similar overlays that
34  * should be visible around the mouse cursor, hence the display references are not const.
35  */
37 {
38 public:
41  , key_(key)
42  , toolbar_button_(nullptr)
43  , palette_(palette)
44  {
45  }
46 
47  virtual ~mouse_action() {}
48 
49  virtual bool has_context_menu() const;
50 
51  /**
52  * Mouse move (not a drag). Never changes anything (other than temporary highlights and similar)
53  */
54  virtual void move(editor_display& disp, const map_location& hex);
55 
56  /**
57  * Unconditionally update the brush highlights for the current tool when hex is the center location
58  */
59  void update_brush_highlights(editor_display& disp, const map_location& hex);
60 
61  /**
62  * Locations that would be affected by a click, used by move to update highlights. Defaults to highlight the mouseover hex.
63  * Maybe also used for actually performing the action in click() or drag().
64  */
65  virtual std::set<map_location> affected_hexes(editor_display& disp, const map_location& hex);
66 
67  /**
68  * A click, possibly the beginning of a drag. Must be overridden.
69  */
70  virtual editor_action* click_left(editor_display& disp, int x, int y) = 0;
71 
72  /**
73  * A click, possibly the beginning of a drag. Must be overridden.
74  */
75  virtual editor_action* click_right(editor_display& disp, int x, int y) = 0;
76 
77  /**
78  * Drag operation. A click should have occurred earlier. Defaults to no action.
79  */
80  virtual editor_action* drag_left(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
81 
82  /**
83  * Drag operation. A click should have occurred earlier. Defaults to no action.
84  */
85  virtual editor_action* drag_right(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
86 
87  /**
88  * The end of dragging. Defaults to no action.
89  */
90  virtual editor_action* drag_end_left(editor_display& disp, int x, int y);
91 
92  virtual editor_action* drag_end_right(editor_display& disp, int x, int y);
93 
94  virtual editor_action* up_left(editor_display& disp, int x, int y);
95 
96  virtual editor_action* up_right(editor_display& disp, int x, int y);
97 
98  /**
99  * Function called by the controller on a key event for the current mouse action.
100  * Defaults to starting position processing.
101  */
102  virtual editor_action* key_event(editor_display& disp, const SDL_Event& e);
103 
104  /**
105  * Helper variable setter - pointer to a toolbar menu/button used for highlighting
106  * the current action. Should always be nullptr or point to a valid menu.
107  */
108  void set_toolbar_button(const theme::menu* value) { toolbar_button_ = value; }
109 
110  /**
111  * Getter for the (possibly nullptr) associated menu/button.
112  */
113  const theme::menu* toolbar_button() const { return toolbar_button_; }
114 
115  /**
116  * Getter for the associated palette.
117  */
119 
120  /** Whether we need the brush bar, is used to grey it out.*/
121  virtual bool supports_brushes() const { return false; }
122 
123  /**
124  * Set the mouse overlay for this action. Defaults to an empty overlay.
125  */
126  virtual void set_mouse_overlay(editor_display& disp);
127 
128 
129 protected:
130  bool has_alt_modifier() const;
131  bool has_shift_modifier() const;
132  bool has_ctrl_modifier() const;
133 
134  /**
135  * Helper function for derived classes that need a active-terrain mouse overlay
136  */
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 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 editor_action* click_perform_right(editor_display& disp, const std::set<map_location>& hexes) = 0;
189 
190  /**
191  * Calls click_perform_left()
192  */
193  editor_action* click_left(editor_display& disp, int x, int y);
194 
195  /**
196  * Calls click_perform_right()
197  */
198  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  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  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  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 <editor_action* (brush_drag_mouse_action::*perform_func)(editor_display&, const std::set<map_location>&)>
235  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)
254  : brush_drag_mouse_action(palette, brush, key)
255  , terrain_palette_(palette)
256  {
257  }
258 
259  /**
260  * Handle terrain sampling before calling generic handler
261  */
262  editor_action* click_left(editor_display& disp, int x, int y) override;
263 
264  /**
265  * Handle terrain sampling before calling generic handler
266  */
267  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  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  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  editor_action* click_left(editor_display& disp, int x, int y) override;
313 
314  /**
315  * Right click does nothing for now
316  */
317  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:
336  : mouse_action(terrain_palette, key)
337  , terrain_palette_(terrain_palette)
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);
345 
346  /**
347  * Left / right click fills with the respective terrain
348  */
349  editor_action* click_left(editor_display& disp, int x, int y);
350 
351  /**
352  * Left / right click fills with the respective terrain
353  */
354  editor_action* click_right(editor_display& disp, int x, int y);
355 
356  virtual void set_mouse_overlay(editor_display& disp);
357 
358 protected:
360 };
361 
362 /**
363  * Set starting position action.
364  */
366 {
367 public:
369  : mouse_action(palette, key), click_(false), location_palette_(palette)
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  editor_action* up_left(editor_display& disp, int x, int y);
379 
380  editor_action* click_left(editor_display& disp, int x, int y);
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  editor_action* up_right(editor_display& disp, int x, int y);
386 
387  editor_action* click_right(editor_display& disp, int x, int y);
388 
389  virtual void set_mouse_overlay(editor_display& disp);
390 
391 private:
392  bool click_;
394 };
395 
396 
397 
398 } //end namespace editor
Brush paint mouse action.
editor_action * drag_end(editor_display &disp, int x, int y)
End of dragging.
editor_action * click_left(editor_display &disp, int x, int y)
A click, possibly the beginning of a drag.
terrain_palette & terrain_palette_
virtual void set_mouse_overlay(editor_display &disp)
Set the mouse overlay for this action.
virtual 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().
virtual editor_action * click_left(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
bool has_shift_modifier() const
virtual void set_mouse_overlay(editor_display &disp)
Set the mouse overlay for this action.
const CKey & key_
Key presses, used for modifiers (alt, shift) in some operations.
A map fragment – a collection of locations and information abut them.
editor_action * click_perform_right(editor_display &disp, const std::set< map_location > &hexes) override
Create an appropriate editor_action and return it.
editor_action * click_right(editor_display &disp, int x, int y)
A click, possibly the beginning of a drag.
virtual bool has_context_menu() const
const brush & get_brush()
Brush accessor.
map_location previous_move_hex_
The hex previously used in move operations.
const theme::menu * toolbar_button() const
Getter for the (possibly nullptr) associated menu/button.
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:85
void set_mouse_overlay(editor_display &disp) override
Set the mouse overlay for this action.
mouse_action_fill(const CKey &key, terrain_palette &terrain_palette)
Palette where the terrain to be drawn can be selected.
virtual bool supports_brushes() const
Whether we need the brush bar, is used to grey it out.
common_palette & palette_
Pointer to an associated palette, if such exists.
editor_action * up_left(editor_display &disp, int x, int y)
Left click displays a player-number-selector dialog and then creates an action or returns nullptr if ...
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:55
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 editor_action * drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
bool has_ctrl_modifier() const
editor_action * click_left(editor_display &disp, int x, int y) override
Return a paste with offset action.
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.
virtual editor_action * up_left(editor_display &disp, int x, int y)
virtual 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.
const map_fragment & paste_
Reference to the buffer used for pasting (e.g.
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)
common_palette & get_palette()
Getter for the associated palette.
virtual editor_action * drag_right(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
editor_action * click_left(editor_display &disp, int x, int y)
Left / right click fills with the respective terrain.
editor_action * up_right(editor_display &disp, int x, int y)
Right click only erases the starting position if there is one.
virtual editor_action * click_right(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
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:25
editor_action * click_left(editor_display &disp, int x, int y)
Calls click_perform_left()
virtual editor_action * up_right(editor_display &disp, int x, int y)
Manage the empty-palette in the editor.
Definition: action.cpp:29
editor_action * click_right(editor_display &disp, int x, int y) override
Handle terrain sampling before calling generic handler.
terrain_palette & terrain_palette_
Encapsulates the map of the game.
Definition: location.hpp:40
virtual bool has_context_menu() const override
virtual bool supports_brushes() const override
Whether we need the brush bar, is used to grey it out.
virtual void set_mouse_overlay(editor_display &disp) override
Set the mouse overlay for this action.
void set_toolbar_button(const theme::menu *value)
Helper variable setter - pointer to a toolbar menu/button used for highlighting the current action...
bool has_alt_modifier() const
Base class for all editor actions.
Definition: action_base.hpp:40
std::set< map_location > affected_hexes(editor_display &disp, const map_location &hex)
Tiles that will be painted to, possibly use modifier keys here.
Definitions related to theme-support.
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.
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.
virtual void set_mouse_overlay(editor_display &disp)
Set the mouse overlay for this action.
editor_action * click_left(editor_display &disp, int x, int y) override
Handle terrain sampling before calling generic handler.
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.
const theme::menu * toolbar_button_
Pointer to an associated menu/button, if such exists.
virtual editor_action * drag_end_left(editor_display &disp, int x, int y)
The end of dragging.
editor_action * click_right(editor_display &disp, int x, int y)
Left / right click fills with the respective terrain.
virtual void move(editor_display &disp, const map_location &hex)
Mouse move (not a drag).
Set starting position action.
mouse_action(common_palette &palette, const CKey &key)
std::set< map_location > affected_hexes(editor_display &disp, const map_location &hex) override
Show an outline of where the paste will go.
editor_action * click_right(editor_display &disp, int x, int y)
Calls click_perform_right()
editor_action * click_perform_left(editor_display &disp, const std::set< map_location > &hexes) override
Create an appropriate editor_action and return it.
#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.
editor_action * click_right(editor_display &disp, int x, int y) override
Right click does nothing for now.
virtual 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().
Class that keeps track of all the keys on the keyboard.
Definition: key.hpp:27
virtual editor_action * drag_end_right(editor_display &disp, int x, int y)
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 ...