497 * - Main window (gamefield), Toolbar, Statusbar (always on) |
497 * - Main window (gamefield), Toolbar, Statusbar (always on) |
498 * - News window, Chatbar (when on) |
498 * - News window, Chatbar (when on) |
499 * - Any sticked windows since we wanted to keep these |
499 * - Any sticked windows since we wanted to keep these |
500 * @return w pointer to the window that is going to be deleted |
500 * @return w pointer to the window that is going to be deleted |
501 */ |
501 */ |
502 static Window *FindDeletableWindow(void) |
502 static Window *FindDeletableWindow() |
503 { |
503 { |
504 Window* const *wz; |
504 Window* const *wz; |
505 |
505 |
506 FOR_ALL_WINDOWS(wz) { |
506 FOR_ALL_WINDOWS(wz) { |
507 Window *w = *wz; |
507 Window *w = *wz; |
517 * windows intact (Main window, Toolbar, Statusbar, News Window, Chatbar) |
517 * windows intact (Main window, Toolbar, Statusbar, News Window, Chatbar) |
518 * Start finding an appropiate candidate from the lowest z-values (bottom) |
518 * Start finding an appropiate candidate from the lowest z-values (bottom) |
519 * @see FindDeletableWindow() |
519 * @see FindDeletableWindow() |
520 * @return w Pointer to the window that is being deleted |
520 * @return w Pointer to the window that is being deleted |
521 */ |
521 */ |
522 static Window *ForceFindDeletableWindow(void) |
522 static Window *ForceFindDeletableWindow() |
523 { |
523 { |
524 Window* const *wz; |
524 Window* const *wz; |
525 |
525 |
526 for (wz = _z_windows;; wz++) { |
526 for (wz = _z_windows;; wz++) { |
527 Window *w = *wz; |
527 Window *w = *wz; |
663 WindowProc *proc, WindowClass cls, const Widget *widget) |
663 WindowProc *proc, WindowClass cls, const Widget *widget) |
664 { |
664 { |
665 return LocalAllocateWindow(x, y, width, height, proc, cls, widget, 0); |
665 return LocalAllocateWindow(x, y, width, height, proc, cls, widget, 0); |
666 } |
666 } |
667 |
667 |
668 typedef struct SizeRect { |
668 struct SizeRect { |
669 int left,top,width,height; |
669 int left,top,width,height; |
670 } SizeRect; |
670 }; |
671 |
671 |
672 |
672 |
673 static SizeRect _awap_r; |
673 static SizeRect _awap_r; |
674 |
674 |
675 static bool IsGoodAutoPlace1(int left, int top) |
675 static bool IsGoodAutoPlace1(int left, int top) |
889 } |
889 } |
890 |
890 |
891 return NULL; |
891 return NULL; |
892 } |
892 } |
893 |
893 |
894 void InitWindowSystem(void) |
894 void InitWindowSystem() |
895 { |
895 { |
896 IConsoleClose(); |
896 IConsoleClose(); |
897 |
897 |
898 memset(&_windows, 0, sizeof(_windows)); |
898 memset(&_windows, 0, sizeof(_windows)); |
899 _last_z_window = _z_windows; |
899 _last_z_window = _z_windows; |
900 InitViewports(); |
900 InitViewports(); |
901 _no_scroll = 0; |
901 _no_scroll = 0; |
902 } |
902 } |
903 |
903 |
904 void UnInitWindowSystem(void) |
904 void UnInitWindowSystem() |
905 { |
905 { |
906 Window **wz; |
906 Window **wz; |
907 |
907 |
908 restart_search: |
908 restart_search: |
909 /* Delete all windows, reset z-array. |
909 /* Delete all windows, reset z-array. |
1383 |
1383 |
1384 _scrolling_scrollbar = false; |
1384 _scrolling_scrollbar = false; |
1385 return false; |
1385 return false; |
1386 } |
1386 } |
1387 |
1387 |
1388 static bool HandleViewportScroll(void) |
1388 static bool HandleViewportScroll() |
1389 { |
1389 { |
1390 WindowEvent e; |
1390 WindowEvent e; |
1391 Window *w; |
1391 Window *w; |
1392 |
1392 |
|
1393 bool scrollwheel_scrolling = _patches.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0); |
|
1394 |
1393 if (!_scrolling_viewport) return true; |
1395 if (!_scrolling_viewport) return true; |
1394 |
1396 |
1395 w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); |
1397 w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); |
1396 |
1398 |
1397 if (!_right_button_down || w == NULL) { |
1399 if (!(_right_button_down || scrollwheel_scrolling) || w == NULL) { |
1398 _cursor.fix_at = false; |
1400 _cursor.fix_at = false; |
1399 _scrolling_viewport = false; |
1401 _scrolling_viewport = false; |
1400 return true; |
1402 return true; |
1401 } |
1403 } |
1402 |
1404 |
1404 e.we.scroll.delta.x = -_cursor.delta.x; |
1406 e.we.scroll.delta.x = -_cursor.delta.x; |
1405 e.we.scroll.delta.y = -_cursor.delta.y; |
1407 e.we.scroll.delta.y = -_cursor.delta.y; |
1406 } else { |
1408 } else { |
1407 e.we.scroll.delta.x = _cursor.delta.x; |
1409 e.we.scroll.delta.x = _cursor.delta.x; |
1408 e.we.scroll.delta.y = _cursor.delta.y; |
1410 e.we.scroll.delta.y = _cursor.delta.y; |
|
1411 } |
|
1412 |
|
1413 if (scrollwheel_scrolling) { |
|
1414 /* We are using scrollwheels for scrolling */ |
|
1415 e.we.scroll.delta.x = _cursor.h_wheel; |
|
1416 e.we.scroll.delta.y = _cursor.v_wheel; |
|
1417 _cursor.v_wheel = 0; |
|
1418 _cursor.h_wheel = 0; |
1409 } |
1419 } |
1410 |
1420 |
1411 /* Create a scroll-event and send it to the window */ |
1421 /* Create a scroll-event and send it to the window */ |
1412 e.event = WE_SCROLL; |
1422 e.event = WE_SCROLL; |
1413 w->wndproc(w, &e); |
1423 w->wndproc(w, &e); |
1578 // When there is no toolbar w is null, check for that |
1588 // When there is no toolbar w is null, check for that |
1579 if (w != NULL) w->wndproc(w, &e); |
1589 if (w != NULL) w->wndproc(w, &e); |
1580 } |
1590 } |
1581 } |
1591 } |
1582 |
1592 |
1583 extern void UpdateTileSelection(void); |
1593 extern void UpdateTileSelection(); |
1584 extern bool VpHandlePlaceSizingDrag(void); |
1594 extern bool VpHandlePlaceSizingDrag(); |
1585 |
1595 |
1586 static int _input_events_this_tick = 0; |
1596 static int _input_events_this_tick = 0; |
1587 |
1597 |
1588 static void HandleAutoscroll(void) |
1598 static void HandleAutoscroll() |
1589 { |
1599 { |
1590 Window *w; |
1600 Window *w; |
1591 ViewPort *vp; |
1601 ViewPort *vp; |
1592 int x = _cursor.pos.x; |
1602 int x = _cursor.pos.x; |
1593 int y = _cursor.pos.y; |
1603 int y = _cursor.pos.y; |
1626 void MouseLoop(int click, int mousewheel) |
1636 void MouseLoop(int click, int mousewheel) |
1627 { |
1637 { |
1628 int x,y; |
1638 int x,y; |
1629 Window *w; |
1639 Window *w; |
1630 ViewPort *vp; |
1640 ViewPort *vp; |
|
1641 bool scrollwheel_scrolling = _patches.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0); |
1631 |
1642 |
1632 DecreaseWindowCounters(); |
1643 DecreaseWindowCounters(); |
1633 HandlePlacePresize(); |
1644 HandlePlacePresize(); |
1634 UpdateTileSelection(); |
1645 UpdateTileSelection(); |
1635 if (!VpHandlePlaceSizingDrag()) return; |
1646 if (!VpHandlePlaceSizingDrag()) return; |
1641 if (!HandleMouseOver()) return; |
1652 if (!HandleMouseOver()) return; |
1642 |
1653 |
1643 x = _cursor.pos.x; |
1654 x = _cursor.pos.x; |
1644 y = _cursor.pos.y; |
1655 y = _cursor.pos.y; |
1645 |
1656 |
1646 if (click == 0 && mousewheel == 0) return; |
1657 if (click == 0 && mousewheel == 0 && !scrollwheel_scrolling) return; |
1647 |
1658 |
1648 w = FindWindowFromPt(x, y); |
1659 w = FindWindowFromPt(x, y); |
1649 if (w == NULL) return; |
1660 if (w == NULL) return; |
1650 if (!MaybeBringWindowToFront(w)) return; |
1661 if (!MaybeBringWindowToFront(w)) return; |
1651 vp = IsPtInWindowViewport(w, x, y); |
1662 vp = IsPtInWindowViewport(w, x, y); |
1652 |
1663 |
1653 /* Don't allow any action in a viewport if either in menu of in generating world */ |
1664 /* Don't allow any action in a viewport if either in menu of in generating world */ |
1654 if (vp != NULL && (_game_mode == GM_MENU || IsGeneratingWorld())) return; |
1665 if (vp != NULL && (_game_mode == GM_MENU || IsGeneratingWorld())) return; |
1655 |
1666 |
1656 if (mousewheel != 0) { |
1667 if (mousewheel != 0) { |
1657 WindowEvent e; |
1668 if (_patches.scrollwheel_scrolling == 0) { |
1658 |
1669 /* Scrollwheel is in zoom mode. Make the zoom event. */ |
1659 /* Send WE_MOUSEWHEEL event to window */ |
1670 WindowEvent e; |
1660 e.event = WE_MOUSEWHEEL; |
1671 |
1661 e.we.wheel.wheel = mousewheel; |
1672 /* Send WE_MOUSEWHEEL event to window */ |
1662 w->wndproc(w, &e); |
1673 e.event = WE_MOUSEWHEEL; |
|
1674 e.we.wheel.wheel = mousewheel; |
|
1675 w->wndproc(w, &e); |
|
1676 } |
1663 |
1677 |
1664 /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ |
1678 /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ |
1665 if (vp == NULL) DispatchMouseWheelEvent(w, GetWidgetFromPos(w, x - w->left, y - w->top), mousewheel); |
1679 if (vp == NULL) DispatchMouseWheelEvent(w, GetWidgetFromPos(w, x - w->left, y - w->top), mousewheel); |
1666 } |
1680 } |
1667 |
1681 |
1668 if (vp != NULL) { |
1682 if (vp != NULL) { |
|
1683 if (scrollwheel_scrolling) click = 2; // we are using the scrollwheel in a viewport, so we emulate right mouse button |
1669 switch (click) { |
1684 switch (click) { |
1670 case 1: |
1685 case 1: |
1671 DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite); |
1686 DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite); |
1672 if (_thd.place_mode != 0 && |
1687 if (_thd.place_mode != 0 && |
1673 // query button and place sign button work in pause mode |
1688 // query button and place sign button work in pause mode |
1674 _cursor.sprite != SPR_CURSOR_QUERY && |
1689 _cursor.sprite != SPR_CURSOR_QUERY && |
1675 _cursor.sprite != SPR_CURSOR_SIGN && |
1690 _cursor.sprite != SPR_CURSOR_SIGN && |
1676 _pause != 0 && |
1691 _pause_game != 0 && |
1677 !_cheats.build_in_pause.value) { |
1692 !_cheats.build_in_pause.value) { |
1678 return; |
1693 return; |
1679 } |
1694 } |
1680 |
1695 |
1681 if (_thd.place_mode == 0) { |
1696 if (_thd.place_mode == 0) { |
1693 break; |
1708 break; |
1694 } |
1709 } |
1695 } else { |
1710 } else { |
1696 switch (click) { |
1711 switch (click) { |
1697 case 1: DispatchLeftClickEvent(w, x - w->left, y - w->top); break; |
1712 case 1: DispatchLeftClickEvent(w, x - w->left, y - w->top); break; |
|
1713 default: |
|
1714 if (!scrollwheel_scrolling || w == NULL || w->window_class != WC_SMALLMAP) break; |
|
1715 /* We try to use the scrollwheel to scroll since we didn't touch any of the buttons. |
|
1716 * Simulate a right button click so we can get started. */ |
|
1717 /* fallthough */ |
1698 case 2: DispatchRightClickEvent(w, x - w->left, y - w->top); break; |
1718 case 2: DispatchRightClickEvent(w, x - w->left, y - w->top); break; |
1699 } |
1719 } |
1700 } |
1720 } |
1701 } |
1721 } |
1702 |
1722 |
1703 void HandleMouseEvents(void) |
1723 void HandleMouseEvents() |
1704 { |
1724 { |
1705 int click; |
1725 int click; |
1706 int mousewheel; |
1726 int mousewheel; |
1707 |
1727 |
1708 /* |
1728 /* |
1855 FOR_ALL_WINDOWS(wz) { |
1875 FOR_ALL_WINDOWS(wz) { |
1856 if ((*wz)->window_class == cls) InvalidateThisWindowData(*wz); |
1876 if ((*wz)->window_class == cls) InvalidateThisWindowData(*wz); |
1857 } |
1877 } |
1858 } |
1878 } |
1859 |
1879 |
1860 void CallWindowTickEvent(void) |
1880 void CallWindowTickEvent() |
1861 { |
1881 { |
1862 Window* const *wz; |
1882 Window* const *wz; |
1863 |
1883 |
1864 for (wz = _last_z_window; wz != _z_windows;) { |
1884 for (wz = _last_z_window; wz != _z_windows;) { |
1865 CallWindowEventNP(*--wz, WE_TICK); |
1885 CallWindowEventNP(*--wz, WE_TICK); |
1866 } |
1886 } |
1867 } |
1887 } |
1868 |
1888 |
1869 void DeleteNonVitalWindows(void) |
1889 void DeleteNonVitalWindows() |
1870 { |
1890 { |
1871 Window* const *wz; |
1891 Window* const *wz; |
1872 |
1892 |
1873 restart_search: |
1893 restart_search: |
1874 /* When we find the window to delete, we need to restart the search |
1894 /* When we find the window to delete, we need to restart the search |
1893 /* It is possible that a stickied window gets to a position where the |
1913 /* It is possible that a stickied window gets to a position where the |
1894 * 'close' button is outside the gaming area. You cannot close it then; except |
1914 * 'close' button is outside the gaming area. You cannot close it then; except |
1895 * with this function. It closes all windows calling the standard function, |
1915 * with this function. It closes all windows calling the standard function, |
1896 * then, does a little hacked loop of closing all stickied windows. Note |
1916 * then, does a little hacked loop of closing all stickied windows. Note |
1897 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1917 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1898 void DeleteAllNonVitalWindows(void) |
1918 void DeleteAllNonVitalWindows() |
1899 { |
1919 { |
1900 Window* const *wz; |
1920 Window* const *wz; |
1901 |
1921 |
1902 /* Delete every window except for stickied ones, then sticky ones as well */ |
1922 /* Delete every window except for stickied ones, then sticky ones as well */ |
1903 DeleteNonVitalWindows(); |
1923 DeleteNonVitalWindows(); |
1913 } |
1933 } |
1914 } |
1934 } |
1915 } |
1935 } |
1916 |
1936 |
1917 /* Delete all always on-top windows to get an empty screen */ |
1937 /* Delete all always on-top windows to get an empty screen */ |
1918 void HideVitalWindows(void) |
1938 void HideVitalWindows() |
1919 { |
1939 { |
1920 DeleteWindowById(WC_TOOLBAR_MENU, 0); |
1940 DeleteWindowById(WC_TOOLBAR_MENU, 0); |
1921 DeleteWindowById(WC_MAIN_TOOLBAR, 0); |
1941 DeleteWindowById(WC_MAIN_TOOLBAR, 0); |
1922 DeleteWindowById(WC_STATUS_BAR, 0); |
1942 DeleteWindowById(WC_STATUS_BAR, 0); |
1923 } |
1943 } |