-
-
Notifications
You must be signed in to change notification settings - Fork 988
/
controller_base.hpp
209 lines (168 loc) · 5.53 KB
/
controller_base.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
Copyright (C) 2006 - 2018 by Joerg Hinrichs <joerg.hinrichs@alice-dsl.de>
wesnoth playlevel Copyright (C) 2003 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/**
* @file
* controller_base framework:
* controller_base is roughly analogous to a "dialog" class in a GUI toolkit
* which is appropriate for deriving wesnoth game modes, e.g. single player
* mode, multiplayer mode, replay mode, editor mode.
*
* It provides implementation details for:
* - play_slice, which is essentially one pass of the "main loop" of
* the application, pumping and dispatching SDL events, raising draw
* events, handling scrolling, sound sources, and some joystick issues
* It also handles displaying menus (Menu, Action).
*
* - showing context menus (much is delegated to command executor though)
*
* Other than this it functions as an abstract interface, enforcing that
* controllers derive from events::sdl_handler, hotkey_command_executor,
* and provide some accessors needed for event handling.
*/
#pragma once
#include "events.hpp"
#include "hotkey/hotkey_command.hpp"
#include "key.hpp"
#include "quit_confirmation.hpp"
class display;
class plugins_context;
namespace events
{
class mouse_handler_base;
}
namespace hotkey
{
class command_executor;
}
namespace soundsource
{
class manager;
}
class controller_base : public events::sdl_handler, public events::pump_monitor
{
public:
controller_base(const config& game_config);
virtual ~controller_base();
virtual void play_slice(bool is_delay_enabled = true);
static const config& get_theme(const config& game_config, std::string theme_name);
void apply_keyboard_scroll(int x, int y);
void set_scroll_up(bool on)
{
scroll_up_ = on;
}
void set_scroll_down(bool on)
{
scroll_down_ = on;
}
void set_scroll_left(bool on)
{
scroll_left_ = on;
}
void set_scroll_right(bool on)
{
scroll_right_ = on;
}
/** Optionally get a command executor to handle context menu events. */
virtual hotkey::command_executor* get_hotkey_command_executor()
{
return nullptr;
}
protected:
virtual bool is_browsing() const
{
return false;
}
/** Get a reference to a mouse handler member a derived class uses. */
virtual events::mouse_handler_base& get_mouse_handler_base() = 0;
/** Get a reference to a display member a derived class uses. */
virtual display& get_display() = 0;
/** Creates and displays the HUD UI that accompanies this controller. */
virtual void initialize_and_show_ui() = 0;
/** Get (optionally) a soundsources manager a derived class uses. */
virtual soundsource::manager* get_soundsource_man()
{
return nullptr;
}
/** Get (optionally) a plugins context a derived class uses. */
virtual plugins_context* get_plugins_context()
{
return nullptr;
}
/**
* Derived classes should override this to return false when arrow keys
* should not scroll the map, hotkeys not processed etc, for example
* when a textbox is active
* @returns true when arrow keys should scroll the map, false otherwise
*/
virtual bool have_keyboard_focus();
virtual std::vector<std::string> additional_actions_pressed()
{
return std::vector<std::string>();
}
/**
* Handle scrolling by keyboard, joystick and moving mouse near map edges
* @see scrolling_, which is set if the display is being scrolled
* @return true when there was any scrolling, false otherwise
*/
bool handle_scroll(int mousex, int mousey, int mouse_flags);
/**
* Process mouse- and keypress-events from SDL.
* Calls various virtual function to allow specialized
* behavior of derived classes.
*/
void handle_event(const SDL_Event& event) override;
void handle_window_event(const SDL_Event& /*event*/) override
{
// No action by default
}
virtual void process(events::pump_info&) override;
/** Process keydown (always). Overridden in derived classes */
virtual void process_keydown_event(const SDL_Event& /*event*/)
{
// No action by default
}
/** Process keyup (always). * Overridden in derived classes */
virtual void process_keyup_event(const SDL_Event& /*event*/)
{
// No action by default
}
virtual void show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool context_menu, display& disp);
virtual void execute_action(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu);
virtual bool in_context_menu(hotkey::HOTKEY_COMMAND command) const;
const config& game_config_;
CKey key_;
bool scrolling_;
bool scroll_up_;
bool scroll_down_;
bool scroll_left_;
bool scroll_right_;
private:
/* A separate class for listening key-up events.
It's needed because otherwise such events might be consumed by a different event context
and the input system would believe that the player is still holding a key (bug #2573) */
class keyup_listener : public events::sdl_handler
{
public:
keyup_listener(controller_base& controller)
: events::sdl_handler(false)
, controller_(controller)
{
join_global();
}
void handle_event(const SDL_Event& event) override;
void handle_window_event(const SDL_Event&) override {}
private:
controller_base& controller_;
};
keyup_listener key_release_listener_;
};