49 } |
49 } |
50 |
50 |
51 w->wndproc(w, &e); |
51 w->wndproc(w, &e); |
52 |
52 |
53 if (w->desc_flags & WDF_STD_BTN) { |
53 if (w->desc_flags & WDF_STD_BTN) { |
54 if (e.click.widget == 0) DeleteWindow(w); |
54 if (e.click.widget == 0) { |
55 else { |
55 DeleteWindow(w); |
|
56 } else { |
56 if (e.click.widget == 1) { |
57 if (e.click.widget == 1) { |
57 if (_ctrl_pressed) |
58 StartWindowDrag(w); |
58 StartWindowSizing(w); |
|
59 else |
|
60 StartWindowDrag(w); |
|
61 } |
59 } |
62 } |
60 } |
63 } |
61 } |
64 |
62 |
65 if (w->desc_flags & WDF_STICKY_BUTTON) { |
63 if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) { |
66 if (e.click.widget == 2) { |
64 StartWindowSizing(w); |
67 w->click_state ^= (1 << e.click.widget); |
65 } |
68 w->flags4 ^= WF_STICKY; |
66 |
69 InvalidateWidget(w, e.click.widget); |
67 if (w->desc_flags & WDF_STICKY_BUTTON && wi->type == WWT_STICKYBOX) { |
70 } |
68 w->click_state ^= (1 << e.click.widget); |
|
69 w->flags4 ^= WF_STICKY; |
|
70 InvalidateWidget(w, e.click.widget); |
71 } |
71 } |
72 } else { |
72 } else { |
73 w->wndproc(w, &e); |
73 w->wndproc(w, &e); |
74 } |
74 } |
75 } |
75 } |
308 assert(w < _last_window); |
310 assert(w < _last_window); |
309 |
311 |
310 if (w->window_class != WC_MAIN_WINDOW && w->window_class != WC_MAIN_TOOLBAR && |
312 if (w->window_class != WC_MAIN_WINDOW && w->window_class != WC_MAIN_TOOLBAR && |
311 w->window_class != WC_STATUS_BAR && w->window_class != WC_NEWS_WINDOW) |
313 w->window_class != WC_STATUS_BAR && w->window_class != WC_NEWS_WINDOW) |
312 return w; |
314 return w; |
|
315 } |
|
316 } |
|
317 |
|
318 bool IsWindowOfPrototype(Window *w, const Widget *widget) |
|
319 { |
|
320 return (w->original_widget == widget); |
|
321 } |
|
322 |
|
323 /* Copies 'widget' to 'w->widget' */ |
|
324 void AssignWidgetToWindow(Window *w, const Widget *widget) |
|
325 { |
|
326 w->original_widget = widget; |
|
327 |
|
328 if (widget != NULL) { |
|
329 const Widget *wi = widget; |
|
330 uint index = 1; |
|
331 while (wi->type != WWT_LAST) { |
|
332 wi++; |
|
333 index++; |
|
334 } |
|
335 |
|
336 w->widget = malloc(sizeof(Widget) * index); |
|
337 memcpy(w->widget, widget, sizeof(Widget) * index); |
|
338 } else { |
|
339 w->widget = NULL; |
313 } |
340 } |
314 } |
341 } |
315 |
342 |
316 Window *AllocateWindow( |
343 Window *AllocateWindow( |
317 int x, |
344 int x, |
371 // w->unk22 = 0xFFFF; |
398 // w->unk22 = 0xFFFF; |
372 w->vscroll.pos = 0; |
399 w->vscroll.pos = 0; |
373 w->vscroll.count = 0; |
400 w->vscroll.count = 0; |
374 w->hscroll.pos = 0; |
401 w->hscroll.pos = 0; |
375 w->hscroll.count = 0; |
402 w->hscroll.count = 0; |
376 w->widget = widget; |
403 AssignWidgetToWindow(w, widget); |
|
404 w->resize.width = width; |
|
405 w->resize.height = height; |
|
406 w->resize.step_width = 1; |
|
407 w->resize.step_height = 1; |
377 |
408 |
378 { |
409 { |
379 int i; |
410 int i; |
380 for (i=0;i<lengthof(w->custom);i++) |
411 for (i=0;i<lengthof(w->custom);i++) |
381 w->custom[i] = 0; |
412 w->custom[i] = 0; |
898 w->left = nx; |
929 w->left = nx; |
899 w->top = ny; |
930 w->top = ny; |
900 |
931 |
901 SetWindowDirty(w); |
932 SetWindowDirty(w); |
902 return false; |
933 return false; |
|
934 } else if (w->flags4 & WF_SIZING) { |
|
935 WindowEvent e; |
|
936 int x, y; |
|
937 |
|
938 /* Stop the sizing if the left mouse button was released */ |
|
939 if (!_left_button_down) { |
|
940 w->flags4 &= ~WF_SIZING; |
|
941 break; |
|
942 } |
|
943 |
|
944 x = _cursor.pos.x - _drag_delta.x; |
|
945 y = _cursor.pos.y - _drag_delta.y; |
|
946 |
|
947 /* X and Y has to go by step.. calculate it */ |
|
948 if (w->resize.step_width > 1) |
|
949 x = x - (x % (int)w->resize.step_width); |
|
950 |
|
951 if (w->resize.step_height > 1) |
|
952 y = y - (y % (int)w->resize.step_height); |
|
953 |
|
954 /* Check if we don't go below the minimum set size */ |
|
955 if ((int)w->width + x < (int)w->resize.width) |
|
956 x = w->resize.width - w->width; |
|
957 if ((int)w->height + y < (int)w->resize.height) |
|
958 y = w->resize.height - w->height; |
|
959 |
|
960 /* Window already on size */ |
|
961 if (x == 0 && y == 0) |
|
962 return false; |
|
963 |
|
964 /* Now find the new cursor pos.. this is NOT _cursor, because |
|
965 we move in steps. */ |
|
966 _drag_delta.x += x; |
|
967 _drag_delta.y += y; |
|
968 |
|
969 SetWindowDirty(w); |
|
970 |
|
971 /* Scroll through all the windows and update the widgets if needed */ |
|
972 { |
|
973 Widget *wi = w->widget; |
|
974 bool resize_height = false; |
|
975 bool resize_width = false; |
|
976 |
|
977 while (wi->type != WWT_LAST) { |
|
978 if (wi->resize_flag != RESIZE_NONE) { |
|
979 /* Resize this widget */ |
|
980 if (wi->resize_flag & RESIZE_LEFT) { |
|
981 wi->left += x; |
|
982 resize_width = true; |
|
983 } |
|
984 if (wi->resize_flag & RESIZE_RIGHT) { |
|
985 wi->right += x; |
|
986 resize_width = true; |
|
987 } |
|
988 |
|
989 if (wi->resize_flag & RESIZE_TOP) { |
|
990 wi->top += y; |
|
991 resize_height = true; |
|
992 } |
|
993 if (wi->resize_flag & RESIZE_BOTTOM) { |
|
994 wi->bottom += y; |
|
995 resize_height = true; |
|
996 } |
|
997 } |
|
998 wi++; |
|
999 } |
|
1000 |
|
1001 /* We resized at least 1 widget, so let's rezise the window totally */ |
|
1002 if (resize_width) |
|
1003 w->width = x + w->width; |
|
1004 if (resize_height) |
|
1005 w->height = y + w->height; |
|
1006 } |
|
1007 |
|
1008 e.event = WE_RESIZE; |
|
1009 e.sizing.size.x = x + w->width; |
|
1010 e.sizing.size.y = y + w->height; |
|
1011 e.sizing.diff.x = x; |
|
1012 e.sizing.diff.y = y; |
|
1013 w->wndproc(w, &e); |
|
1014 |
|
1015 SetWindowDirty(w); |
|
1016 return false; |
903 } |
1017 } |
904 } |
1018 } |
905 |
1019 |
906 _dragging_window = false; |
1020 _dragging_window = false; |
907 return false; |
1021 return false; |
909 |
1023 |
910 Window *StartWindowDrag(Window *w) |
1024 Window *StartWindowDrag(Window *w) |
911 { |
1025 { |
912 w->flags4 |= WF_DRAGGING; |
1026 w->flags4 |= WF_DRAGGING; |
913 _dragging_window = true; |
1027 _dragging_window = true; |
|
1028 |
914 _drag_delta.x = w->left - _cursor.pos.x; |
1029 _drag_delta.x = w->left - _cursor.pos.x; |
915 _drag_delta.y = w->top - _cursor.pos.y; |
1030 _drag_delta.y = w->top - _cursor.pos.y; |
|
1031 |
916 w = BringWindowToFront(w); |
1032 w = BringWindowToFront(w); |
917 DeleteWindowById(WC_DROPDOWN_MENU, 0); |
1033 DeleteWindowById(WC_DROPDOWN_MENU, 0); |
918 return w; |
1034 return w; |
919 } |
1035 } |
920 |
1036 |
921 Window *StartWindowSizing(Window *w) |
1037 Window *StartWindowSizing(Window *w) |
922 { |
1038 { |
923 w->flags4 |= WF_SIZING; |
1039 w->flags4 |= WF_SIZING; |
924 _dragging_window = true; |
1040 _dragging_window = true; |
925 _cursorpos_drag_start = _cursor.pos; |
1041 |
|
1042 _drag_delta.x = _cursor.pos.x; |
|
1043 _drag_delta.y = _cursor.pos.y; |
|
1044 |
926 w = BringWindowToFront(w); |
1045 w = BringWindowToFront(w); |
927 DeleteWindowById(WC_DROPDOWN_MENU, 0); |
1046 DeleteWindowById(WC_DROPDOWN_MENU, 0); |
928 return w; |
1047 return w; |
929 } |
1048 } |
930 |
1049 |
1088 |
1207 |
1089 static void HandleKeypress(uint32 key) |
1208 static void HandleKeypress(uint32 key) |
1090 { |
1209 { |
1091 Window *w; |
1210 Window *w; |
1092 WindowEvent we; |
1211 WindowEvent we; |
1093 /* Stores if a window with a textfield for typing is open |
1212 /* Stores if a window with a textfield for typing is open |
1094 * If this is the case, keypress events are only passed to windows with text fields and |
1213 * If this is the case, keypress events are only passed to windows with text fields and |
1095 * to thein this main toolbar. */ |
1214 * to thein this main toolbar. */ |
1096 bool query_open = false; |
1215 bool query_open = false; |
1097 |
1216 |
1098 // Setup event |
1217 // Setup event |
1099 we.keypress.event = WE_KEYPRESS; |
1218 we.keypress.event = WE_KEYPRESS; |
1367 w++; |
1486 w++; |
1368 } |
1487 } |
1369 } |
1488 } |
1370 } |
1489 } |
1371 |
1490 |
1372 /* It is possible that a stickied window gets to a position where the |
1491 /* It is possible that a stickied window gets to a position where the |
1373 * 'close' button is outside the gaming area. You cannot close it then; except |
1492 * 'close' button is outside the gaming area. You cannot close it then; except |
1374 * with this function. It closes all windows calling the standard function, |
1493 * with this function. It closes all windows calling the standard function, |
1375 * then, does a little hacked loop of closing all stickied windows. Note |
1494 * then, does a little hacked loop of closing all stickied windows. Note |
1376 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1495 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1377 void DeleteAllNonVitalWindows(void) |
1496 void DeleteAllNonVitalWindows(void) |