* Handle viewport scrolling with the mouse. * @return State of handling the event. */
| 2438 | * @return State of handling the event. |
| 2439 | */ |
| 2440 | static EventState HandleViewportScroll() |
| 2441 | { |
| 2442 | bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == SWS_SCROLL_MAP && _cursor.wheel_moved; |
| 2443 | |
| 2444 | if (!_scrolling_viewport) return ES_NOT_HANDLED; |
| 2445 | |
| 2446 | /* When we don't have a last scroll window we are starting to scroll. |
| 2447 | * When the last scroll window and this are not the same we went |
| 2448 | * outside of the window and should not left-mouse scroll anymore. */ |
| 2449 | if (_last_scroll_window == nullptr) _last_scroll_window = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); |
| 2450 | |
| 2451 | if (_last_scroll_window == nullptr || !((_settings_client.gui.scroll_mode != VSM_MAP_LMB && _right_button_down) || scrollwheel_scrolling || (_settings_client.gui.scroll_mode == VSM_MAP_LMB && _left_button_down))) { |
| 2452 | _cursor.fix_at = false; |
| 2453 | _scrolling_viewport = false; |
| 2454 | _last_scroll_window = nullptr; |
| 2455 | return ES_NOT_HANDLED; |
| 2456 | } |
| 2457 | |
| 2458 | if (_last_scroll_window == GetMainWindow() && _last_scroll_window->viewport->follow_vehicle != VehicleID::Invalid()) { |
| 2459 | /* If the main window is following a vehicle, then first let go of it! */ |
| 2460 | const Vehicle *veh = Vehicle::Get(_last_scroll_window->viewport->follow_vehicle); |
| 2461 | ScrollMainWindowTo(veh->x_pos, veh->y_pos, veh->z_pos, true); // This also resets follow_vehicle |
| 2462 | return ES_NOT_HANDLED; |
| 2463 | } |
| 2464 | |
| 2465 | Point delta; |
| 2466 | if (scrollwheel_scrolling) { |
| 2467 | /* We are using scrollwheels for scrolling */ |
| 2468 | /* Use the integer part for movement */ |
| 2469 | delta.x = static_cast<int>(_cursor.h_wheel); |
| 2470 | delta.y = static_cast<int>(_cursor.v_wheel); |
| 2471 | /* Keep the fractional part so that subtle movement is accumulated */ |
| 2472 | float temp; |
| 2473 | _cursor.v_wheel = std::modf(_cursor.v_wheel, &temp); |
| 2474 | _cursor.h_wheel = std::modf(_cursor.h_wheel, &temp); |
| 2475 | } else { |
| 2476 | if (_settings_client.gui.scroll_mode != VSM_VIEWPORT_RMB_FIXED) { |
| 2477 | delta.x = -_cursor.delta.x; |
| 2478 | delta.y = -_cursor.delta.y; |
| 2479 | } else { |
| 2480 | delta.x = _cursor.delta.x; |
| 2481 | delta.y = _cursor.delta.y; |
| 2482 | } |
| 2483 | } |
| 2484 | |
| 2485 | /* Create a scroll-event and send it to the window */ |
| 2486 | if (delta.x != 0 || delta.y != 0) _last_scroll_window->OnScroll(delta); |
| 2487 | |
| 2488 | _cursor.delta.x = 0; |
| 2489 | _cursor.delta.y = 0; |
| 2490 | _cursor.wheel_moved = false; |
| 2491 | return ES_HANDLED; |
| 2492 | } |
| 2493 | |
| 2494 | /** |
| 2495 | * Check if a window can be made relative top-most window, and if so do |
no test coverage detected