void controller_base::handle_event(const SDL_Event& event) { if (gui2::is_in_dialog()) { return; } int x, y; switch(event.type) { case SDL_FINGERDOWN: case SDL_FINGERMOTION: case SDL_FINGERUP: case SDL_MULTIGESTURE: case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: case SDL_MOUSEMOTION: case SDL_MOUSEWHEEL: base_finger::process_event(event); break; case SDL_KEYDOWN: // Detect key press events, unless there something that has keyboard focus // in which case the key press events should go only to it. if(have_keyboard_focus()) { process_keydown_event(event); // hotkey::key_event(get_display(),event.key,this); } else { process_focus_keydown_event(event); break; } // intentionally fall-through case SDL_KEYUP: process_keyup_event(event); break; case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_LEAVE) { if (get_mouse_handler_base().is_dragging()) { //simulate mouse button up when the app has lost mouse focus //this should be a general fix for the issue when the mouse //is dragged out of the game window and then the button is released Uint8 mouse_flags = SDL_GetMouseState(&x, &y); if ((mouse_flags & SDL_BUTTON_LEFT) == 0) { SDL_Event e; e.type = SDL_MOUSEBUTTONUP; e.button.state = SDL_RELEASED; e.button.button = SDL_BUTTON_LEFT; e.button.x = x; e.button.y = y; get_mouse_handler_base().mouse_press(e.button, multi_gestures() || mouse_motions_ > 0, browse_); post_mouse_press(e.button); } } } break; default: break; } }
bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double x_axis, double y_axis) { bool mouse_in_window = (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0 || preferences::get("scroll_when_mouse_outside", true); bool keyboard_focus = have_keyboard_focus(); int scroll_speed = preferences::scroll_speed(); int dx = 0, dy = 0; int scroll_threshold = (preferences::mouse_scroll_enabled()) ? preferences::mouse_scroll_threshold() : 0; BOOST_FOREACH(const theme::menu& m, get_display().get_theme().menus()) { if (point_in_rect(mousex, mousey, m.get_location())) { scroll_threshold = 0; } } if ((key[SDLK_UP] && keyboard_focus) || (mousey < scroll_threshold && mouse_in_window)) { dy -= scroll_speed; } if ((key[SDLK_DOWN] && keyboard_focus) || (mousey > get_display().h() - scroll_threshold && mouse_in_window)) { dy += scroll_speed; } if ((key[SDLK_LEFT] && keyboard_focus) || (mousex < scroll_threshold && mouse_in_window)) { dx -= scroll_speed; } if ((key[SDLK_RIGHT] && keyboard_focus) || (mousex > get_display().w() - scroll_threshold && mouse_in_window)) { dx += scroll_speed; } if ((mouse_flags & SDL_BUTTON_MMASK) != 0 && preferences::middle_click_scrolls()) { const SDL_Rect& rect = get_display().map_outside_area(); if (point_in_rect(mousex, mousey,rect)) { // relative distance from the center to the border // NOTE: the view is a rectangle, so can be more sensible in one direction // but seems intuitive to use and it's useful since you must // more often scroll in the direction where the view is shorter const double xdisp = ((1.0*mousex / rect.w) - 0.5); const double ydisp = ((1.0*mousey / rect.h) - 0.5); // 4.0 give twice the normal speed when mouse is at border (xdisp=0.5) int speed = 4 * scroll_speed; dx += round_double(xdisp * speed); dy += round_double(ydisp * speed); } } dx += round_double( x_axis * scroll_speed); dy += round_double( y_axis * scroll_speed); return get_display().scroll(dx, dy); }
void controller_base::handle_event(const SDL_Event& event) { if(gui::in_dialog()) { return; } static const hotkey::hotkey_command& quit_hotkey = hotkey::hotkey_command::get_command_by_command(hotkey::HOTKEY_QUIT_GAME); switch(event.type) { case SDL_KEYDOWN: // Detect key press events, unless there something that has keyboard focus // in which case the key press events should go only to it. if(have_keyboard_focus()) { if(event.key.keysym.sym == SDLK_ESCAPE) { hotkey::execute_command(get_display(), quit_hotkey, get_hotkey_command_executor()); break; } process_keydown_event(event); hotkey::key_event(get_display(), event, get_hotkey_command_executor()); } else { process_focus_keydown_event(event); break; } // intentionally fall-through case SDL_KEYUP: process_keyup_event(event); break; case SDL_JOYBUTTONDOWN: process_keydown_event(event); hotkey::jbutton_event(get_display(), event, get_hotkey_command_executor()); break; case SDL_JOYHATMOTION: process_keydown_event(event); hotkey::jhat_event(get_display(), event, get_hotkey_command_executor()); break; case SDL_MOUSEMOTION: // Ignore old mouse motion events in the event queue SDL_Event new_event; if(SDL_PeepEvents(&new_event,1,SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION)) > 0) { while(SDL_PeepEvents(&new_event,1,SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION)) > 0) {}; get_mouse_handler_base().mouse_motion_event(new_event.motion, is_browsing()); } else { get_mouse_handler_base().mouse_motion_event(event.motion, is_browsing()); } break; case SDL_MOUSEBUTTONDOWN: process_keydown_event(event); get_mouse_handler_base().mouse_press(event.button, is_browsing()); if (get_mouse_handler_base().get_show_menu()){ show_menu(get_display().get_theme().context_menu()->items(),event.button.x,event.button.y,true, get_display()); } hotkey::mbutton_event(get_display(), event, get_hotkey_command_executor()); break; case SDL_MOUSEBUTTONUP: get_mouse_handler_base().mouse_press(event.button, is_browsing()); if (get_mouse_handler_base().get_show_menu()){ show_menu(get_display().get_theme().context_menu()->items(),event.button.x,event.button.y,true, get_display()); } break; #if !SDL_VERSION_ATLEAST(2, 0, 0) case SDL_ACTIVEEVENT: if (event.active.state == SDL_APPMOUSEFOCUS && event.active.gain == 0) { if (get_mouse_handler_base().is_dragging()) { //simulate mouse button up when the app has lost mouse focus //this should be a general fix for the issue when the mouse //is dragged out of the game window and then the button is released int x, y; Uint8 mouse_flags = SDL_GetMouseState(&x, &y); if ((mouse_flags & SDL_BUTTON_LEFT) == 0) { get_mouse_handler_base().mouse_press(event.button, is_browsing()); } } } break; #endif #if SDL_VERSION_ATLEAST(2,0,0) case SDL_MOUSEWHEEL: get_mouse_handler_base().mouse_wheel(event.wheel.x, event.wheel.y, is_browsing()); break; #endif default: break; } }
bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double x_axis, double y_axis) { bool mouse_in_window = (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0 || preferences::get("scroll_when_mouse_outside", true); bool keyboard_focus = have_keyboard_focus(); int scroll_speed = preferences::scroll_speed(); int dx = 0, dy = 0; int scroll_threshold = (preferences::mouse_scroll_enabled()) ? preferences::mouse_scroll_threshold() : 0; BOOST_FOREACH(const theme::menu& m, get_display().get_theme().menus()) { if (sdl::point_in_rect(mousex, mousey, m.get_location())) { scroll_threshold = 0; } } if ((key[SDLK_UP] && keyboard_focus) || (mousey < scroll_threshold && mouse_in_window)) { dy -= scroll_speed; } if ((key[SDLK_DOWN] && keyboard_focus) || (mousey > get_display().h() - scroll_threshold && mouse_in_window)) { dy += scroll_speed; } if ((key[SDLK_LEFT] && keyboard_focus) || (mousex < scroll_threshold && mouse_in_window)) { dx -= scroll_speed; } if ((key[SDLK_RIGHT] && keyboard_focus) || (mousex > get_display().w() - scroll_threshold && mouse_in_window)) { dx += scroll_speed; } if ((mouse_flags & SDL_BUTTON_MMASK) != 0 && preferences::middle_click_scrolls()) { const map_location original_loc = get_mouse_handler_base().get_scroll_start(); if (get_mouse_handler_base().scroll_started()) { const SDL_Rect& rect = get_display().map_outside_area(); if (sdl::point_in_rect(mousex, mousey,rect) && get_mouse_handler_base().scroll_started()) { // Scroll speed is proportional from the distance from the first // middle click and scrolling speed preference. const double speed = 0.04 * sqrt(static_cast<double>(scroll_speed)); const double snap_dist = 16; // Snap to horizontal/vertical scrolling const double x_diff = (mousex - original_loc.x); const double y_diff = (mousey - original_loc.y); if (fabs(x_diff) > snap_dist || fabs(y_diff) <= snap_dist) dx += speed * x_diff; if (fabs(y_diff) > snap_dist || fabs(x_diff) <= snap_dist) dy += speed * y_diff; } } else { // Event may fire mouse down out of order with respect to initial click get_mouse_handler_base().set_scroll_start(mousex, mousey); } } dx += round_double( x_axis * scroll_speed); dy += round_double( y_axis * scroll_speed); return get_display().scroll(dx, dy); }
void controller_base::handle_event(const SDL_Event& event) { if(gui::in_dialog()) { return; } switch(event.type) { case SDL_KEYDOWN: // Detect key press events, unless there something that has keyboard focus // in which case the key press events should go only to it. if(have_keyboard_focus()) { process_keydown_event(event); hotkey::key_event(get_display(), event.key,this); } else { process_focus_keydown_event(event); break; } // intentionally fall-through case SDL_KEYUP: process_keyup_event(event); break; case SDL_JOYBUTTONDOWN: process_keydown_event(event); hotkey::jbutton_event(get_display(), event.jbutton, this); break; case SDL_JOYHATMOTION: process_keydown_event(event); hotkey::jhat_event(get_display(), event.jhat, this); break; case SDL_MOUSEMOTION: // Ignore old mouse motion events in the event queue SDL_Event new_event; if(SDL_PeepEvents(&new_event,1,SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION)) > 0) { while(SDL_PeepEvents(&new_event,1,SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION)) > 0) {}; get_mouse_handler_base().mouse_motion_event(new_event.motion, browse_); } else { get_mouse_handler_base().mouse_motion_event(event.motion, browse_); } break; case SDL_MOUSEBUTTONDOWN: process_keydown_event(event); hotkey::mbutton_event(get_display(), event.button, this); // intentionally fall-through case SDL_MOUSEBUTTONUP: get_mouse_handler_base().mouse_press(event.button, browse_); if (get_mouse_handler_base().get_show_menu()){ show_menu(get_display().get_theme().context_menu()->items(),event.button.x,event.button.y,true); } break; case SDL_ACTIVEEVENT: if (event.active.state == SDL_APPMOUSEFOCUS && event.active.gain == 0) { if (get_mouse_handler_base().is_dragging()) { //simulate mouse button up when the app has lost mouse focus //this should be a general fix for the issue when the mouse //is dragged out of the game window and then the button is released int x, y; Uint8 mouse_flags = SDL_GetMouseState(&x, &y); if ((mouse_flags & SDL_BUTTON_LEFT) == 0) { get_mouse_handler_base().mouse_press(event.button, browse_); } } } break; default: break; } }
void controller_base::handle_event(const SDL_Event& event) { if (gui::in_dialog()) { return; } #if (defined(__APPLE__) && TARGET_OS_IPHONE) || defined(ANDROID) if ((event.type == SDL_MOUSEBUTTONDOWN) || (event.type == SDL_FINGERDOWN)) { wait_bh_event_ = true; return; } if (event.type == SDL_MOUSEMOTION) { return; } if (event.type == SDL_MOUSEBUTTONUP) { return; } #endif SDL_Event new_event; int abs_dx, abs_dy; // events::mouse_handler& mouse_handler = get_mouse_handler_base(); switch(event.type) { case SDL_KEYDOWN: // Detect key press events, unless there something that has keyboard focus // in which case the key press events should go only to it. if(have_keyboard_focus()) { process_keydown_event(event); hotkey::key_event(get_display(),event.key,this); } else { process_focus_keydown_event(event); break; } // intentionally fall-through case SDL_KEYUP: process_keyup_event(event); break; case SDL_FINGERMOTION: abs_dx = posix_abs(event.tfinger.dx); abs_dy = posix_abs(event.tfinger.dy); if (abs_dx <= FINGER_HIT_THRESHOLD && abs_dy <= FINGER_HIT_THRESHOLD) { break; } if (abs_dx >= FINGER_MOTION_THRESHOLD && abs_dy >= FINGER_MOTION_THRESHOLD) { if (event.tfinger.dx > 0) { if (event.tfinger.dy > 0) { finger_motion_direction_ = SOUTH_EAST; } else { finger_motion_direction_ = NORTH_EAST; } } else if (event.tfinger.dy >= 0) { finger_motion_direction_ = SOUTH_WEST; } else { finger_motion_direction_ = NORTH_WEST; } finger_motion_scroll_ = true; } else if (abs_dx >= abs_dy && abs_dx >= FINGER_MOTION_THRESHOLD) { // x axis if (event.tfinger.dx > 0) { finger_motion_direction_ = RIGHT; } else { finger_motion_direction_ = LEFT; } finger_motion_scroll_ = true; } else if (abs_dx < abs_dy && abs_dy >= FINGER_MOTION_THRESHOLD) { // y axis if (event.tfinger.dy > 0) { finger_motion_direction_ = DOWN; } else { finger_motion_direction_ = UP; } finger_motion_scroll_ = true; } wait_bh_event_ = false; break; case SDL_MOUSEMOTION: // Ignore old mouse motion events in the event queue if (SDL_PeepEvents(&new_event,1,SDL_GETEVENT, SDL_MOUSEMOTIONMASK) > 0) { while(SDL_PeepEvents(&new_event,1,SDL_GETEVENT, SDL_MOUSEMOTIONMASK) > 0) {}; get_mouse_handler_base().mouse_motion_event(new_event.motion, browse_); } else { get_mouse_handler_base().mouse_motion_event(event.motion, browse_); } break; case SDL_FINGERUP: if (!wait_bh_event_) { break; } // simulate SDL_MOUSEBUTTONDOWN new_event = event; new_event.button.button = SDL_BUTTON_LEFT; new_event.button.state = SDL_PRESSED; new_event.button.x = event.tfinger.x; new_event.button.y = event.tfinger.y; // SDL_SendMouseMotion(NULL, 0, event.tfinger.x, event.tfinger.y); do { get_mouse_handler_base().mouse_press(new_event.button, browse_); post_mouse_press(new_event); if (get_mouse_handler_base().get_show_menu()){ get_display().goto_main_context_menu(); } if (new_event.button.state == SDL_RELEASED) { break; } new_event.button.state = SDL_RELEASED; } while (true); wait_bh_event_ = false; break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: get_mouse_handler_base().mouse_press(event.button, browse_); post_mouse_press(event); if (get_mouse_handler_base().get_show_menu()){ get_display().goto_main_context_menu(); } break; case SDL_ACTIVEEVENT: if (event.active.type == SDL_APPMOUSEFOCUS && event.active.gain == 0) { if (get_mouse_handler_base().is_dragging()) { //simulate mouse button up when the app has lost mouse focus //this should be a general fix for the issue when the mouse //is dragged out of the game window and then the button is released int x, y; Uint8 mouse_flags = SDL_GetMouseState(&x, &y); if ((mouse_flags & SDL_BUTTON_LEFT) == 0) { SDL_Event e; e.type = SDL_MOUSEBUTTONUP; e.button.state = SDL_RELEASED; e.button.button = SDL_BUTTON_LEFT; e.button.x = x; e.button.y = y; get_mouse_handler_base().mouse_press(event.button, browse_); post_mouse_press(event); } } } break; default: break; } }
bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags) { #if (defined(__APPLE__) && TARGET_OS_IPHONE) || defined(ANDROID) // for tablet device. bool mouse_in_window = false; #else // for mouse device. bool mouse_in_window = (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0 || preferences::get("scroll_when_mouse_outside", true); #endif bool keyboard_focus = have_keyboard_focus(); int scroll_speed = preferences::scroll_speed(); int dx = 0, dy = 0; int scroll_threshold = (preferences::mouse_scroll_enabled()) ? preferences::mouse_scroll_threshold() : 0; foreach (const theme::menu& m, get_display().get_theme().menus()) { if (point_in_rect(mousex, mousey, m.get_location())) { scroll_threshold = 0; } } if ((key[SDLK_UP] && keyboard_focus) || (mousey < scroll_threshold && mouse_in_window)) { dy -= scroll_speed; } if ((key[SDLK_DOWN] && keyboard_focus) || (mousey > get_display().h() - scroll_threshold && mouse_in_window)) { dy += scroll_speed; } if ((key[SDLK_LEFT] && keyboard_focus) || (mousex < scroll_threshold && mouse_in_window)) { dx -= scroll_speed; } if ((key[SDLK_RIGHT] && keyboard_focus) || (mousex > get_display().w() - scroll_threshold && mouse_in_window)) { dx += scroll_speed; } if ((mouse_flags & SDL_BUTTON_MMASK) != 0 && preferences::middle_click_scrolls()) { const SDL_Rect& rect = get_display().map_outside_area(); if (point_in_rect(mousex, mousey,rect)) { // relative distance from the center to the border // NOTE: the view is a rectangle, so can be more sensible in one direction // but seems intuitive to use and it's useful since you must // more often scroll in the direction where the view is shorter const double xdisp = ((1.0*mousex / rect.w) - 0.5); const double ydisp = ((1.0*mousey / rect.h) - 0.5); // 4.0 give twice the normal speed when mouse is at border (xdisp=0.5) int speed = 4 * scroll_speed; dx += round_double(xdisp * speed); dy += round_double(ydisp * speed); } } if (finger_motion_scroll_) { if (finger_motion_direction_ == UP) { dy += scroll_speed; } else if (finger_motion_direction_ == DOWN) { dy -= scroll_speed; } else if (finger_motion_direction_ == LEFT) { dx += scroll_speed; } else if (finger_motion_direction_ == RIGHT) { dx -= scroll_speed; } else if (finger_motion_direction_ == NORTH_EAST) { dx -= scroll_speed; dy += scroll_speed; } else if (finger_motion_direction_ == SOUTH_EAST) { dx -= scroll_speed; dy -= scroll_speed; } else if (finger_motion_direction_ == SOUTH_WEST) { dx += scroll_speed; dy -= scroll_speed; } else if (finger_motion_direction_ == NORTH_WEST) { dx += scroll_speed; dy += scroll_speed; } finger_motion_scroll_ = false; } return get_display().scroll(dx, dy); }