00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "controller_base.hpp"
00018
00019 #include "dialogs.hpp"
00020 #include "display.hpp"
00021 #include "foreach.hpp"
00022 #include "game_preferences.hpp"
00023 #include "log.hpp"
00024 #include "mouse_handler_base.hpp"
00025
00026 static lg::log_domain log_display("display");
00027 #define ERR_DP LOG_STREAM(err, log_display)
00028
00029 controller_base::controller_base(
00030 int ticks, const config& game_config, CVideo& ) :
00031 game_config_(game_config),
00032 ticks_(ticks),
00033 key_(),
00034 browse_(false),
00035 scrolling_(false),
00036 joystick_manager_()
00037 {
00038 }
00039
00040 controller_base::~controller_base()
00041 {
00042 }
00043
00044 int controller_base::get_ticks() {
00045 return ticks_;
00046 }
00047
00048 void controller_base::handle_event(const SDL_Event& event)
00049 {
00050 if(gui::in_dialog()) {
00051 return;
00052 }
00053
00054 switch(event.type) {
00055 case SDL_KEYDOWN:
00056
00057
00058 if(have_keyboard_focus()) {
00059 process_keydown_event(event);
00060 hotkey::key_event(get_display(), event.key,this);
00061 } else {
00062 process_focus_keydown_event(event);
00063 break;
00064 }
00065
00066 case SDL_KEYUP:
00067 process_keyup_event(event);
00068 break;
00069 case SDL_JOYBUTTONDOWN:
00070 process_keydown_event(event);
00071 hotkey::button_event(get_display(), event.jbutton,this);
00072 break;
00073 case SDL_JOYHATMOTION:
00074 process_keydown_event(event);
00075 hotkey::hat_event(get_display(), event.jhat, this);
00076 break;
00077 case SDL_MOUSEMOTION:
00078
00079 SDL_Event new_event;
00080 if(SDL_PeepEvents(&new_event,1,SDL_GETEVENT,
00081 SDL_EVENTMASK(SDL_MOUSEMOTION)) > 0) {
00082 while(SDL_PeepEvents(&new_event,1,SDL_GETEVENT,
00083 SDL_EVENTMASK(SDL_MOUSEMOTION)) > 0) {};
00084 get_mouse_handler_base().mouse_motion_event(new_event.motion, browse_);
00085 } else {
00086 get_mouse_handler_base().mouse_motion_event(event.motion, browse_);
00087 }
00088 break;
00089 case SDL_MOUSEBUTTONDOWN:
00090 case SDL_MOUSEBUTTONUP:
00091 get_mouse_handler_base().mouse_press(event.button, browse_);
00092 post_mouse_press(event);
00093 if (get_mouse_handler_base().get_show_menu()){
00094 show_menu(get_display().get_theme().context_menu()->items(),event.button.x,event.button.y,true);
00095 }
00096 break;
00097 case SDL_ACTIVEEVENT:
00098 if (event.active.type == SDL_APPMOUSEFOCUS && event.active.gain == 0) {
00099 if (get_mouse_handler_base().is_dragging()) {
00100
00101
00102
00103 int x, y;
00104 Uint8 mouse_flags = SDL_GetMouseState(&x, &y);
00105 if ((mouse_flags & SDL_BUTTON_LEFT) == 0) {
00106 get_mouse_handler_base().mouse_press(event.button, browse_);
00107 post_mouse_press(event);
00108 }
00109 }
00110 }
00111 break;
00112 default:
00113 break;
00114 }
00115 }
00116
00117 bool controller_base::have_keyboard_focus()
00118 {
00119 return true;
00120 }
00121
00122 void controller_base::process_focus_keydown_event(const SDL_Event& ) {
00123
00124 }
00125
00126 void controller_base::process_keydown_event(const SDL_Event& ) {
00127
00128 }
00129
00130 void controller_base::process_keyup_event(const SDL_Event& ) {
00131
00132 }
00133
00134 void controller_base::post_mouse_press(const SDL_Event& ) {
00135
00136 }
00137
00138 bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double x_axis, double y_axis)
00139 {
00140 bool mouse_in_window = (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0
00141 || preferences::get("scroll_when_mouse_outside", true);
00142 bool keyboard_focus = have_keyboard_focus();
00143 int scroll_speed = preferences::scroll_speed();
00144 int dx = 0, dy = 0;
00145 int scroll_threshold = (preferences::mouse_scroll_enabled())
00146 ? preferences::mouse_scroll_threshold() : 0;
00147 foreach (const theme::menu& m, get_display().get_theme().menus()) {
00148 if (point_in_rect(mousex, mousey, m.get_location())) {
00149 scroll_threshold = 0;
00150 }
00151 }
00152 if ((key[SDLK_UP] && keyboard_focus) ||
00153 (mousey < scroll_threshold && mouse_in_window))
00154 {
00155 dy -= scroll_speed;
00156 }
00157 if ((key[SDLK_DOWN] && keyboard_focus) ||
00158 (mousey > get_display().h() - scroll_threshold && mouse_in_window))
00159 {
00160 dy += scroll_speed;
00161 }
00162 if ((key[SDLK_LEFT] && keyboard_focus) ||
00163 (mousex < scroll_threshold && mouse_in_window))
00164 {
00165 dx -= scroll_speed;
00166 }
00167 if ((key[SDLK_RIGHT] && keyboard_focus) ||
00168 (mousex > get_display().w() - scroll_threshold && mouse_in_window))
00169 {
00170 dx += scroll_speed;
00171 }
00172 if ((mouse_flags & SDL_BUTTON_MMASK) != 0 && preferences::middle_click_scrolls()) {
00173 const SDL_Rect& rect = get_display().map_outside_area();
00174 if (point_in_rect(mousex, mousey,rect)) {
00175
00176
00177
00178
00179 const double xdisp = ((1.0*mousex / rect.w) - 0.5);
00180 const double ydisp = ((1.0*mousey / rect.h) - 0.5);
00181
00182 int speed = 4 * scroll_speed;
00183 dx += round_double(xdisp * speed);
00184 dy += round_double(ydisp * speed);
00185 }
00186 }
00187
00188 dx += round_double( x_axis * scroll_speed);
00189 dy += round_double( y_axis * scroll_speed);
00190
00191 return get_display().scroll(dx, dy);
00192 }
00193
00194 void controller_base::play_slice(bool is_delay_enabled)
00195 {
00196 CKey key;
00197 events::pump();
00198 events::raise_process_event();
00199 events::raise_draw_event();
00200
00201 slice_before_scroll();
00202 const theme::menu* const m = get_display().menu_pressed();
00203 if(m != NULL) {
00204 const SDL_Rect& menu_loc = m->location(get_display().screen_area());
00205 show_menu(m->items(),menu_loc.x+1,menu_loc.y + menu_loc.h + 1,false);
00206
00207 return;
00208 }
00209
00210 bool was_scrolling = scrolling_;
00211
00212 std::pair<double, double> values = joystick_manager_.get_scroll_axis_pair();
00213 const double joystickx = values.first;
00214 const double joysticky = values.second;
00215
00216 int mousex, mousey;
00217 Uint8 mouse_flags = SDL_GetMouseState(&mousex, &mousey);
00218
00219
00220
00221
00222
00223
00224
00225 scrolling_ = handle_scroll(key, mousex, mousey, mouse_flags, joystickx, joysticky);
00226
00227 map_location highlighted_hex = get_display().mouseover_hex();
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 if (joystick_manager_.update_highlighted_hex(highlighted_hex)
00241 && get_display().get_map().on_board(highlighted_hex)) {
00242 get_mouse_handler_base().mouse_motion(0,0, true, true, highlighted_hex);
00243 get_display().scroll_to_tile(highlighted_hex, display::ONSCREEN_WARP, false, true);
00244 scrolling_ = true;
00245 }
00246
00247 get_display().draw();
00248
00249
00250
00251 if (is_delay_enabled && (SDL_GetAppState() & SDL_APPACTIVE) == 0) {
00252 get_display().delay(200);
00253 }
00254
00255 if (!scrolling_ && was_scrolling) {
00256
00257 get_mouse_handler_base().mouse_update(browse_, highlighted_hex);
00258 }
00259 slice_end();
00260 }
00261
00262 void controller_base::slice_before_scroll()
00263 {
00264
00265 }
00266
00267 void controller_base::slice_end()
00268 {
00269
00270 }
00271
00272 void controller_base::show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu)
00273 {
00274 std::vector<std::string> items = items_arg;
00275 hotkey::HOTKEY_COMMAND command;
00276 std::vector<std::string>::iterator i = items.begin();
00277 while(i != items.end()) {
00278 command = hotkey::get_hotkey(*i).get_id();
00279 if(!can_execute_command(command)
00280 || (context_menu && !in_context_menu(command))) {
00281 i = items.erase(i);
00282 continue;
00283 }
00284 ++i;
00285 }
00286 if(items.empty())
00287 return;
00288 command_executor::show_menu(items, xloc, yloc, context_menu, get_display());
00289 }
00290
00291 bool controller_base::in_context_menu(hotkey::HOTKEY_COMMAND ) const
00292 {
00293 return true;
00294 }
00295
00296 const config& controller_base::get_theme(const config& game_config, std::string theme_name)
00297 {
00298 if (theme_name.empty()) theme_name = preferences::theme();
00299
00300 if (const config &c = game_config.find_child("theme", "name", theme_name))
00301 return c;
00302
00303 ERR_DP << "Theme '" << theme_name << "' not found. Trying the default theme.\n";
00304
00305 if (const config &c = game_config.find_child("theme", "name", "Default"))
00306 return c;
00307
00308 ERR_DP << "Default theme not found.\n";
00309
00310 static config empty;
00311 return empty;
00312 }