289 if (w == NULL) return; |
289 if (w == NULL) return; |
290 SetDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height); |
290 SetDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height); |
291 } |
291 } |
292 |
292 |
293 /** Find the Window whose parent pointer points to this window |
293 /** Find the Window whose parent pointer points to this window |
294 * @parent w Window to find child of |
294 * @param w parent Window to find child of |
295 * @return return a Window pointer that is the child of w, or NULL otherwise */ |
295 * @return a Window pointer that is the child of w, or NULL otherwise */ |
296 static Window *FindChildWindow(const Window *w) |
296 static Window *FindChildWindow(const Window *w) |
297 { |
297 { |
298 Window* const *wz; |
298 Window* const *wz; |
299 |
299 |
300 FOR_ALL_WINDOWS(wz) { |
300 FOR_ALL_WINDOWS(wz) { |
575 |
580 |
576 assert(_last_z_window == endof(_z_windows)); |
581 assert(_last_z_window == endof(_z_windows)); |
577 return NULL; |
582 return NULL; |
578 } |
583 } |
579 |
584 |
580 /* Open a new window. |
585 /** Open a new window. |
581 * This function is called from AllocateWindow() or AllocateWindowDesc() |
586 * This function is called from AllocateWindow() or AllocateWindowDesc() |
582 * See descriptions for those functions for usage |
587 * See descriptions for those functions for usage |
583 * See AllocateWindow() for description of arguments. |
588 * See AllocateWindow() for description of arguments. |
584 * Only addition here is window_number, which is the window_number being assigned to the new window |
589 * Only addition here is window_number, which is the window_number being assigned to the new window |
585 */ |
590 * @param x offset in pixels from the left of the screen |
|
591 * @param y offset in pixels from the top of the screen |
|
592 * @param width width in pixels of the window |
|
593 * @param height height in pixels of the window |
|
594 * @param *proc see WindowProc function to call when any messages/updates happen to the window |
|
595 * @param cls see WindowClass class of the window, used for identification and grouping |
|
596 * @param *widget see Widget pointer to the window layout and various elements |
|
597 * @param window_number number being assigned to the new window |
|
598 * @return Window pointer of the newly created window */ |
586 static Window *LocalAllocateWindow( |
599 static Window *LocalAllocateWindow( |
587 int x, int y, int width, int height, |
600 int x, int y, int width, int height, |
588 WindowProc *proc, WindowClass cls, const Widget *widget, int window_number) |
601 WindowProc *proc, WindowClass cls, const Widget *widget, int window_number) |
589 { |
602 { |
590 Window *w = FindFreeWindow(); |
603 Window *w = FindFreeWindow(); |
651 * ones. Finally set all variables and call the WE_CREATE event |
664 * ones. Finally set all variables and call the WE_CREATE event |
652 * @param x offset in pixels from the left of the screen |
665 * @param x offset in pixels from the left of the screen |
653 * @param y offset in pixels from the top of the screen |
666 * @param y offset in pixels from the top of the screen |
654 * @param width width in pixels of the window |
667 * @param width width in pixels of the window |
655 * @param height height in pixels of the window |
668 * @param height height in pixels of the window |
656 * @param *proc @see WindowProc function to call when any messages/updates happen to the window |
669 * @param *proc see WindowProc function to call when any messages/updates happen to the window |
657 * @param cls @see WindowClass class of the window, used for identification and grouping |
670 * @param cls see WindowClass class of the window, used for identification and grouping |
658 * @param *widget @see Widget pointer to the window layout and various elements |
671 * @param *widget see Widget pointer to the window layout and various elements |
659 * @return @see Window pointer of the newly created window |
672 * @return Window pointer of the newly created window */ |
660 */ |
|
661 Window *AllocateWindow( |
673 Window *AllocateWindow( |
662 int x, int y, int width, int height, |
674 int x, int y, int width, int height, |
663 WindowProc *proc, WindowClass cls, const Widget *widget) |
675 WindowProc *proc, WindowClass cls, const Widget *widget) |
664 { |
676 { |
665 return LocalAllocateWindow(x, y, width, height, proc, cls, widget, 0); |
677 return LocalAllocateWindow(x, y, width, height, proc, cls, widget, 0); |
850 } |
862 } |
851 |
863 |
852 /** |
864 /** |
853 * Open a new window. |
865 * Open a new window. |
854 * @param *desc The pointer to the WindowDesc to be created |
866 * @param *desc The pointer to the WindowDesc to be created |
855 * @return @see Window pointer of the newly created window |
867 * @return Window pointer of the newly created window |
856 */ |
868 */ |
857 Window *AllocateWindowDesc(const WindowDesc *desc) |
869 Window *AllocateWindowDesc(const WindowDesc *desc) |
858 { |
870 { |
859 return LocalAllocateWindowDesc(desc, 0); |
871 return LocalAllocateWindowDesc(desc, 0); |
860 } |
872 } |
861 |
873 |
862 /** |
874 /** |
863 * Open a new window. |
875 * Open a new window. |
864 * @param *desc The pointer to the WindowDesc to be created |
876 * @param *desc The pointer to the WindowDesc to be created |
865 * @param window_number the window number of the new window |
877 * @param window_number the window number of the new window |
866 * @return @see Window pointer of the newly created window |
878 * @return see Window pointer of the newly created window |
867 */ |
879 */ |
868 Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number) |
880 Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number) |
869 { |
881 { |
870 Window *w; |
882 Window *w; |
871 |
883 |
1036 WindowEvent e; |
1050 WindowEvent e; |
1037 static Window *last_w = NULL; |
1051 static Window *last_w = NULL; |
1038 |
1052 |
1039 w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); |
1053 w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); |
1040 |
1054 |
1041 // We changed window, put a MOUSEOVER event to the last window |
1055 /* We changed window, put a MOUSEOVER event to the last window */ |
1042 if (last_w != NULL && last_w != w) { |
1056 if (last_w != NULL && last_w != w) { |
1043 e.event = WE_MOUSEOVER; |
1057 e.event = WE_MOUSEOVER; |
1044 e.we.mouseover.pt.x = -1; |
1058 e.we.mouseover.pt.x = -1; |
1045 e.we.mouseover.pt.y = -1; |
1059 e.we.mouseover.pt.y = -1; |
1046 if (last_w->wndproc) last_w->wndproc(last_w, &e); |
1060 if (last_w->wndproc) last_w->wndproc(last_w, &e); |
1047 } |
1061 } |
1048 last_w = w; |
1062 last_w = w; |
1049 |
1063 |
1050 if (w != NULL) { |
1064 if (w != NULL) { |
1051 // send an event in client coordinates. |
1065 /* send an event in client coordinates. */ |
1052 e.event = WE_MOUSEOVER; |
1066 e.event = WE_MOUSEOVER; |
1053 e.we.mouseover.pt.x = _cursor.pos.x - w->left; |
1067 e.we.mouseover.pt.x = _cursor.pos.x - w->left; |
1054 e.we.mouseover.pt.y = _cursor.pos.y - w->top; |
1068 e.we.mouseover.pt.y = _cursor.pos.y - w->top; |
1055 if (w->widget != NULL) { |
1069 if (w->widget != NULL) { |
1056 e.we.mouseover.widget = GetWidgetFromPos(w, e.we.mouseover.pt.x, e.we.mouseover.pt.y); |
1070 e.we.mouseover.widget = GetWidgetFromPos(w, e.we.mouseover.pt.x, e.we.mouseover.pt.y); |
1057 } |
1071 } |
1058 w->wndproc(w, &e); |
1072 w->wndproc(w, &e); |
1059 } |
1073 } |
1060 |
1074 |
1061 // Mouseover never stops execution |
1075 /* Mouseover never stops execution */ |
1062 return true; |
1076 return true; |
1063 } |
1077 } |
1064 |
1078 |
1065 /** Update all the widgets of a window based on their resize flags |
1079 /** Update all the widgets of a window based on their resize flags |
1066 * Both the areas of the old window and the new sized window are set dirty |
1080 * Both the areas of the old window and the new sized window are set dirty |
1156 const Window *v = *vz; |
1170 const Window *v = *vz; |
1157 |
1171 |
1158 if (v == w) continue; // Don't snap at yourself |
1172 if (v == w) continue; // Don't snap at yourself |
1159 |
1173 |
1160 if (y + w->height > v->top && y < v->top + v->height) { |
1174 if (y + w->height > v->top && y < v->top + v->height) { |
1161 // Your left border <-> other right border |
1175 /* Your left border <-> other right border */ |
1162 delta = abs(v->left + v->width - x); |
1176 delta = abs(v->left + v->width - x); |
1163 if (delta <= hsnap) { |
1177 if (delta <= hsnap) { |
1164 nx = v->left + v->width; |
1178 nx = v->left + v->width; |
1165 hsnap = delta; |
1179 hsnap = delta; |
1166 } |
1180 } |
1167 |
1181 |
1168 // Your right border <-> other left border |
1182 /* Your right border <-> other left border */ |
1169 delta = abs(v->left - x - w->width); |
1183 delta = abs(v->left - x - w->width); |
1170 if (delta <= hsnap) { |
1184 if (delta <= hsnap) { |
1171 nx = v->left - w->width; |
1185 nx = v->left - w->width; |
1172 hsnap = delta; |
1186 hsnap = delta; |
1173 } |
1187 } |
1174 } |
1188 } |
1175 |
1189 |
1176 if (w->top + w->height >= v->top && w->top <= v->top + v->height) { |
1190 if (w->top + w->height >= v->top && w->top <= v->top + v->height) { |
1177 // Your left border <-> other left border |
1191 /* Your left border <-> other left border */ |
1178 delta = abs(v->left - x); |
1192 delta = abs(v->left - x); |
1179 if (delta <= hsnap) { |
1193 if (delta <= hsnap) { |
1180 nx = v->left; |
1194 nx = v->left; |
1181 hsnap = delta; |
1195 hsnap = delta; |
1182 } |
1196 } |
1183 |
1197 |
1184 // Your right border <-> other right border |
1198 /* Your right border <-> other right border */ |
1185 delta = abs(v->left + v->width - x - w->width); |
1199 delta = abs(v->left + v->width - x - w->width); |
1186 if (delta <= hsnap) { |
1200 if (delta <= hsnap) { |
1187 nx = v->left + v->width - w->width; |
1201 nx = v->left + v->width - w->width; |
1188 hsnap = delta; |
1202 hsnap = delta; |
1189 } |
1203 } |
1190 } |
1204 } |
1191 |
1205 |
1192 if (x + w->width > v->left && x < v->left + v->width) { |
1206 if (x + w->width > v->left && x < v->left + v->width) { |
1193 // Your top border <-> other bottom border |
1207 /* Your top border <-> other bottom border */ |
1194 delta = abs(v->top + v->height - y); |
1208 delta = abs(v->top + v->height - y); |
1195 if (delta <= vsnap) { |
1209 if (delta <= vsnap) { |
1196 ny = v->top + v->height; |
1210 ny = v->top + v->height; |
1197 vsnap = delta; |
1211 vsnap = delta; |
1198 } |
1212 } |
1199 |
1213 |
1200 // Your bottom border <-> other top border |
1214 /* Your bottom border <-> other top border */ |
1201 delta = abs(v->top - y - w->height); |
1215 delta = abs(v->top - y - w->height); |
1202 if (delta <= vsnap) { |
1216 if (delta <= vsnap) { |
1203 ny = v->top - w->height; |
1217 ny = v->top - w->height; |
1204 vsnap = delta; |
1218 vsnap = delta; |
1205 } |
1219 } |
1206 } |
1220 } |
1207 |
1221 |
1208 if (w->left + w->width >= v->left && w->left <= v->left + v->width) { |
1222 if (w->left + w->width >= v->left && w->left <= v->left + v->width) { |
1209 // Your top border <-> other top border |
1223 /* Your top border <-> other top border */ |
1210 delta = abs(v->top - y); |
1224 delta = abs(v->top - y); |
1211 if (delta <= vsnap) { |
1225 if (delta <= vsnap) { |
1212 ny = v->top; |
1226 ny = v->top; |
1213 vsnap = delta; |
1227 vsnap = delta; |
1214 } |
1228 } |
1215 |
1229 |
1216 // Your bottom border <-> other bottom border |
1230 /* Your bottom border <-> other bottom border */ |
1217 delta = abs(v->top + v->height - y - w->height); |
1231 delta = abs(v->top + v->height - y - w->height); |
1218 if (delta <= vsnap) { |
1232 if (delta <= vsnap) { |
1219 ny = v->top + v->height - w->height; |
1233 ny = v->top + v->height - w->height; |
1220 vsnap = delta; |
1234 vsnap = delta; |
1221 } |
1235 } |
1222 } |
1236 } |
1223 } |
1237 } |
1224 } |
1238 } |
1225 |
1239 |
1226 // Make sure the window doesn't leave the screen |
1240 /* Make sure the window doesn't leave the screen |
1227 // 13 is the height of the title bar |
1241 * 13 is the height of the title bar */ |
1228 nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left); |
1242 nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left); |
1229 ny = clamp(ny, 0, _screen.height - 13); |
1243 ny = clamp(ny, 0, _screen.height - 13); |
1230 |
1244 |
1231 // Make sure the title bar isn't hidden by behind the main tool bar |
1245 /* Make sure the title bar isn't hidden by behind the main tool bar */ |
1232 v = FindWindowById(WC_MAIN_TOOLBAR, 0); |
1246 v = FindWindowById(WC_MAIN_TOOLBAR, 0); |
1233 if (v != NULL) { |
1247 if (v != NULL) { |
1234 int v_bottom = v->top + v->height; |
1248 int v_bottom = v->top + v->height; |
1235 int v_right = v->left + v->width; |
1249 int v_right = v->left + v->width; |
1236 if (ny + t->top >= v->top && ny + t->top < v_bottom) { |
1250 if (ny + t->top >= v->top && ny + t->top < v_bottom) { |
1480 if (bring_to_front) BringWindowToFront(w); |
1494 if (bring_to_front) BringWindowToFront(w); |
1481 return true; |
1495 return true; |
1482 } |
1496 } |
1483 |
1497 |
1484 /** Send a message from one window to another. The receiving window is found by |
1498 /** Send a message from one window to another. The receiving window is found by |
1485 * @param w @see Window pointer pointing to the other window |
1499 * @param w Window pointer pointing to the other window |
1486 * @param msg Specifies the message to be sent |
1500 * @param msg Specifies the message to be sent |
1487 * @param wparam Specifies additional message-specific information |
1501 * @param wparam Specifies additional message-specific information |
1488 * @param lparam Specifies additional message-specific information |
1502 * @param lparam Specifies additional message-specific information |
1489 */ |
1503 */ |
1490 static void SendWindowMessageW(Window *w, uint msg, uint wparam, uint lparam) |
1504 static void SendWindowMessageW(Window *w, uint msg, uint wparam, uint lparam) |
1498 |
1512 |
1499 w->wndproc(w, &e); |
1513 w->wndproc(w, &e); |
1500 } |
1514 } |
1501 |
1515 |
1502 /** Send a message from one window to another. The receiving window is found by |
1516 /** Send a message from one window to another. The receiving window is found by |
1503 * @param wnd_class @see WindowClass class AND |
1517 * @param wnd_class see WindowClass class AND |
1504 * @param wnd_num @see WindowNumber number, mostly 0 |
1518 * @param wnd_num see WindowNumber number, mostly 0 |
1505 * @param msg Specifies the message to be sent |
1519 * @param msg Specifies the message to be sent |
1506 * @param wparam Specifies additional message-specific information |
1520 * @param wparam Specifies additional message-specific information |
1507 * @param lparam Specifies additional message-specific information |
1521 * @param lparam Specifies additional message-specific information |
1508 */ |
1522 */ |
1509 void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam) |
1523 void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam) |
1512 if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam); |
1526 if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam); |
1513 } |
1527 } |
1514 |
1528 |
1515 /** Send a message from one window to another. The message will be sent |
1529 /** Send a message from one window to another. The message will be sent |
1516 * to ALL windows of the windowclass specified in the first parameter |
1530 * to ALL windows of the windowclass specified in the first parameter |
1517 * @param wnd_class @see WindowClass class |
1531 * @param wnd_class see WindowClass class |
1518 * @param msg Specifies the message to be sent |
1532 * @param msg Specifies the message to be sent |
1519 * @param wparam Specifies additional message-specific information |
1533 * @param wparam Specifies additional message-specific information |
1520 * @param lparam Specifies additional message-specific information |
1534 * @param lparam Specifies additional message-specific information |
1521 */ |
1535 */ |
1522 void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam) |
1536 void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam) |
1549 * This is not necessary either, as the only events that |
1563 * This is not necessary either, as the only events that |
1550 * can be handled are the 'close application' events |
1564 * can be handled are the 'close application' events |
1551 */ |
1565 */ |
1552 if (!IsGeneratingWorld()) _current_player = _local_player; |
1566 if (!IsGeneratingWorld()) _current_player = _local_player; |
1553 |
1567 |
1554 // Setup event |
1568 /* Setup event */ |
1555 e.event = WE_KEYPRESS; |
1569 e.event = WE_KEYPRESS; |
1556 e.we.keypress.key = GB(key, 0, 16); |
1570 e.we.keypress.key = GB(key, 0, 16); |
1557 e.we.keypress.keycode = GB(key, 16, 16); |
1571 e.we.keypress.keycode = GB(key, 16, 16); |
1558 e.we.keypress.cont = true; |
1572 e.we.keypress.cont = true; |
1559 |
1573 |
1560 // check if we have a query string window open before allowing hotkeys |
1574 /* check if we have a query string window open before allowing hotkeys */ |
1561 if (FindWindowById(WC_QUERY_STRING, 0) != NULL || |
1575 if (FindWindowById(WC_QUERY_STRING, 0) != NULL || |
1562 FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL || |
1576 FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL || |
1563 FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL || |
1577 FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL || |
1564 FindWindowById(WC_CONSOLE, 0) != NULL || |
1578 FindWindowById(WC_CONSOLE, 0) != NULL || |
1565 FindWindowById(WC_SAVELOAD, 0) != NULL) { |
1579 FindWindowById(WC_SAVELOAD, 0) != NULL) { |
1566 query_open = true; |
1580 query_open = true; |
1567 } |
1581 } |
1568 |
1582 |
1569 // Call the event, start with the uppermost window. |
1583 /* Call the event, start with the uppermost window. */ |
1570 for (wz = _last_z_window; wz != _z_windows;) { |
1584 for (wz = _last_z_window; wz != _z_windows;) { |
1571 Window *w = *--wz; |
1585 Window *w = *--wz; |
1572 |
1586 |
1573 // if a query window is open, only call the event for certain window types |
1587 /* if a query window is open, only call the event for certain window types */ |
1574 if (query_open && |
1588 if (query_open && |
1575 w->window_class != WC_QUERY_STRING && |
1589 w->window_class != WC_QUERY_STRING && |
1576 w->window_class != WC_SEND_NETWORK_MSG && |
1590 w->window_class != WC_SEND_NETWORK_MSG && |
1577 w->window_class != WC_GENERATE_LANDSCAPE && |
1591 w->window_class != WC_GENERATE_LANDSCAPE && |
1578 w->window_class != WC_CONSOLE && |
1592 w->window_class != WC_CONSOLE && |
1683 if (scrollwheel_scrolling) click = 2; // we are using the scrollwheel in a viewport, so we emulate right mouse button |
1697 if (scrollwheel_scrolling) click = 2; // we are using the scrollwheel in a viewport, so we emulate right mouse button |
1684 switch (click) { |
1698 switch (click) { |
1685 case 1: |
1699 case 1: |
1686 DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite); |
1700 DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite); |
1687 if (_thd.place_mode != 0 && |
1701 if (_thd.place_mode != 0 && |
1688 // query button and place sign button work in pause mode |
1702 /* query button and place sign button work in pause mode */ |
1689 _cursor.sprite != SPR_CURSOR_QUERY && |
1703 _cursor.sprite != SPR_CURSOR_QUERY && |
1690 _cursor.sprite != SPR_CURSOR_SIGN && |
1704 _cursor.sprite != SPR_CURSOR_SIGN && |
1691 _pause_game != 0 && |
1705 _pause_game != 0 && |
1692 !_cheats.build_in_pause.value) { |
1706 !_cheats.build_in_pause.value) { |
1693 return; |
1707 return; |
1908 goto restart_search; |
1922 goto restart_search; |
1909 } |
1923 } |
1910 } |
1924 } |
1911 } |
1925 } |
1912 |
1926 |
1913 /* It is possible that a stickied window gets to a position where the |
1927 /** It is possible that a stickied window gets to a position where the |
1914 * 'close' button is outside the gaming area. You cannot close it then; except |
1928 * 'close' button is outside the gaming area. You cannot close it then; except |
1915 * with this function. It closes all windows calling the standard function, |
1929 * with this function. It closes all windows calling the standard function, |
1916 * then, does a little hacked loop of closing all stickied windows. Note |
1930 * then, does a little hacked loop of closing all stickied windows. Note |
1917 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1931 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1918 void DeleteAllNonVitalWindows() |
1932 void DeleteAllNonVitalWindows() |