* Handle a mouse event from the video driver */
| 2964 | * Handle a mouse event from the video driver |
| 2965 | */ |
| 2966 | void HandleMouseEvents() |
| 2967 | { |
| 2968 | /* World generation is multithreaded and messes with companies. |
| 2969 | * But there is no company related window open anyway, so _current_company is not used. */ |
| 2970 | assert(HasModalProgress() || IsLocalCompany()); |
| 2971 | |
| 2972 | static std::chrono::steady_clock::time_point double_click_time = {}; |
| 2973 | static Point double_click_pos = {0, 0}; |
| 2974 | |
| 2975 | /* Mouse event? */ |
| 2976 | MouseClick click = MC_NONE; |
| 2977 | if (_left_button_down && !_left_button_clicked) { |
| 2978 | click = MC_LEFT; |
| 2979 | if (std::chrono::steady_clock::now() <= double_click_time + TIME_BETWEEN_DOUBLE_CLICK && |
| 2980 | double_click_pos.x != 0 && abs(_cursor.pos.x - double_click_pos.x) < MAX_OFFSET_DOUBLE_CLICK && |
| 2981 | double_click_pos.y != 0 && abs(_cursor.pos.y - double_click_pos.y) < MAX_OFFSET_DOUBLE_CLICK) { |
| 2982 | click = MC_DOUBLE_LEFT; |
| 2983 | } |
| 2984 | double_click_time = std::chrono::steady_clock::now(); |
| 2985 | double_click_pos = _cursor.pos; |
| 2986 | _left_button_clicked = true; |
| 2987 | } else if (_right_button_clicked) { |
| 2988 | _right_button_clicked = false; |
| 2989 | click = MC_RIGHT; |
| 2990 | } |
| 2991 | |
| 2992 | int mousewheel = 0; |
| 2993 | if (_cursor.wheel) { |
| 2994 | mousewheel = _cursor.wheel; |
| 2995 | _cursor.wheel = 0; |
| 2996 | } |
| 2997 | |
| 2998 | static std::chrono::steady_clock::time_point hover_time = {}; |
| 2999 | static Point hover_pos = {0, 0}; |
| 3000 | |
| 3001 | if (_settings_client.gui.hover_delay_ms > 0) { |
| 3002 | if (!_cursor.in_window || click != MC_NONE || mousewheel != 0 || _left_button_down || _right_button_down || |
| 3003 | hover_pos.x == 0 || abs(_cursor.pos.x - hover_pos.x) >= MAX_OFFSET_HOVER || |
| 3004 | hover_pos.y == 0 || abs(_cursor.pos.y - hover_pos.y) >= MAX_OFFSET_HOVER) { |
| 3005 | hover_pos = _cursor.pos; |
| 3006 | hover_time = std::chrono::steady_clock::now(); |
| 3007 | _mouse_hovering = false; |
| 3008 | } else if (!_mouse_hovering) { |
| 3009 | if (std::chrono::steady_clock::now() > hover_time + std::chrono::milliseconds(_settings_client.gui.hover_delay_ms)) { |
| 3010 | click = MC_HOVER; |
| 3011 | _mouse_hovering = true; |
| 3012 | hover_time = std::chrono::steady_clock::now(); |
| 3013 | } |
| 3014 | } |
| 3015 | } |
| 3016 | |
| 3017 | if (click == MC_LEFT && _newgrf_debug_sprite_picker.mode == SPM_WAIT_CLICK) { |
| 3018 | /* Mark whole screen dirty, and wait for the next realtime tick, when drawing is finished. */ |
| 3019 | Blitter *blitter = BlitterFactory::GetCurrentBlitter(); |
| 3020 | _newgrf_debug_sprite_picker.clicked_pixel = blitter->MoveTo(_screen.dst_ptr, _cursor.pos.x, _cursor.pos.y); |
| 3021 | _newgrf_debug_sprite_picker.sprites.clear(); |
| 3022 | _newgrf_debug_sprite_picker.mode = SPM_REDRAW; |
| 3023 | MarkWholeScreenDirty(); |
no test coverage detected