| 2856 | } |
| 2857 | |
| 2858 | static void MouseLoop(MouseClick click, int mousewheel) |
| 2859 | { |
| 2860 | /* World generation is multithreaded and messes with companies. |
| 2861 | * But there is no company related window open anyway, so _current_company is not used. */ |
| 2862 | assert(HasModalProgress() || IsLocalCompany()); |
| 2863 | |
| 2864 | HandlePlacePresize(); |
| 2865 | UpdateTileSelection(); |
| 2866 | |
| 2867 | if (VpHandlePlaceSizingDrag() == ES_HANDLED) return; |
| 2868 | if (HandleMouseDragDrop() == ES_HANDLED) return; |
| 2869 | if (HandleWindowDragging() == ES_HANDLED) return; |
| 2870 | if (HandleActiveWidget() == ES_HANDLED) return; |
| 2871 | if (HandleViewportScroll() == ES_HANDLED) return; |
| 2872 | |
| 2873 | HandleMouseOver(); |
| 2874 | |
| 2875 | bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == SWS_SCROLL_MAP && _cursor.wheel_moved; |
| 2876 | if (click == MC_NONE && mousewheel == 0 && !scrollwheel_scrolling) return; |
| 2877 | |
| 2878 | int x = _cursor.pos.x; |
| 2879 | int y = _cursor.pos.y; |
| 2880 | Window *w = FindWindowFromPt(x, y); |
| 2881 | if (w == nullptr) return; |
| 2882 | |
| 2883 | if (click != MC_HOVER && !MaybeBringWindowToFront(w)) return; |
| 2884 | Viewport *vp = IsPtInWindowViewport(w, x, y); |
| 2885 | |
| 2886 | /* Don't allow any action in a viewport if either in menu or when having a modal progress window */ |
| 2887 | if (vp != nullptr && (_game_mode == GM_MENU || HasModalProgress())) return; |
| 2888 | |
| 2889 | if (mousewheel != 0) { |
| 2890 | /* Send mousewheel event to window, unless we're scrolling a viewport or the map */ |
| 2891 | if (!scrollwheel_scrolling || (vp == nullptr && w->window_class != WC_SMALLMAP)) { |
| 2892 | if (NWidgetCore *nwid = w->nested_root->GetWidgetFromPos(x - w->left, y - w->top); nwid != nullptr) { |
| 2893 | w->OnMouseWheel(mousewheel, nwid->GetIndex()); |
| 2894 | } |
| 2895 | } |
| 2896 | |
| 2897 | /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ |
| 2898 | if (vp == nullptr) DispatchMouseWheelEvent(w, w->nested_root->GetWidgetFromPos(x - w->left, y - w->top), mousewheel); |
| 2899 | } |
| 2900 | |
| 2901 | if (vp != nullptr) { |
| 2902 | if (scrollwheel_scrolling && !w->flags.Test(WindowFlag::DisableVpScroll)) { |
| 2903 | _scrolling_viewport = true; |
| 2904 | _cursor.fix_at = true; |
| 2905 | return; |
| 2906 | } |
| 2907 | |
| 2908 | switch (click) { |
| 2909 | case MC_DOUBLE_LEFT: |
| 2910 | case MC_LEFT: |
| 2911 | if (HandleViewportClicked(*vp, x, y)) return; |
| 2912 | if (!w->flags.Test(WindowFlag::DisableVpScroll) && |
| 2913 | _settings_client.gui.scroll_mode == VSM_MAP_LMB) { |
| 2914 | _scrolling_viewport = true; |
| 2915 | _cursor.fix_at = false; |
no test coverage detected