4 |
4 |
5 #include "stdafx.h" |
5 #include "stdafx.h" |
6 #include <stdarg.h> |
6 #include <stdarg.h> |
7 #include "openttd.h" |
7 #include "openttd.h" |
8 #include "debug.h" |
8 #include "debug.h" |
9 #include "functions.h" |
|
10 #include "map.h" |
|
11 #include "player.h" |
9 #include "player.h" |
12 #include "window.h" |
10 #include "gfx_func.h" |
13 #include "gfx.h" |
|
14 #include "viewport.h" |
|
15 #include "console.h" |
11 #include "console.h" |
|
12 #include "viewport_func.h" |
16 #include "variables.h" |
13 #include "variables.h" |
17 #include "table/sprites.h" |
14 #include "table/sprites.h" |
18 #include "genworld.h" |
15 #include "genworld.h" |
19 #include "helpers.hpp" |
|
20 #include "blitter/factory.hpp" |
16 #include "blitter/factory.hpp" |
|
17 #include "window_gui.h" |
|
18 #include "zoom_func.h" |
|
19 #include "core/alloc_func.hpp" |
|
20 #include "map_func.h" |
|
21 #include "vehicle_base.h" |
21 |
22 |
22 /* delta between mouse cursor and upper left corner of dragged window */ |
23 /* delta between mouse cursor and upper left corner of dragged window */ |
23 static Point _drag_delta; |
24 static Point _drag_delta; |
24 |
25 |
25 static Window _windows[25]; |
26 static Window _windows[MAX_NUMBER_OF_WINDOWS]; |
26 Window *_z_windows[lengthof(_windows)]; |
27 Window *_z_windows[lengthof(_windows)]; |
27 Window **_last_z_window; ///< always points to the next free space in the z-array |
28 Window **_last_z_window; ///< always points to the next free space in the z-array |
28 |
29 |
29 void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...) |
30 void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...) |
30 { |
31 { |
31 va_list wdg_list; |
32 va_list wdg_list; |
32 |
33 |
33 va_start(wdg_list, widgets); |
34 va_start(wdg_list, widgets); |
34 |
35 |
35 while (widgets != WIDGET_LIST_END) { |
36 while (widgets != WIDGET_LIST_END) { |
36 SetWindowWidgetDisabledState(w, widgets, disab_stat); |
37 SetWidgetDisabledState(widgets, disab_stat); |
37 widgets = va_arg(wdg_list, int); |
38 widgets = va_arg(wdg_list, int); |
38 } |
39 } |
39 |
40 |
40 va_end(wdg_list); |
41 va_end(wdg_list); |
41 } |
42 } |
42 |
43 |
43 void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...) |
44 void CDECL Window::SetWidgetsHiddenState(bool hidden_stat, int widgets, ...) |
44 { |
45 { |
45 va_list wdg_list; |
46 va_list wdg_list; |
46 |
47 |
47 va_start(wdg_list, widgets); |
48 va_start(wdg_list, widgets); |
48 |
49 |
49 while (widgets != WIDGET_LIST_END) { |
50 while (widgets != WIDGET_LIST_END) { |
50 SetWindowWidgetHiddenState(w, widgets, hidden_stat); |
51 SetWidgetHiddenState(widgets, hidden_stat); |
51 widgets = va_arg(wdg_list, int); |
52 widgets = va_arg(wdg_list, int); |
52 } |
53 } |
53 |
54 |
54 va_end(wdg_list); |
55 va_end(wdg_list); |
55 } |
56 } |
56 |
57 |
57 void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...) |
58 void CDECL Window::SetWidgetsLoweredState(bool lowered_stat, int widgets, ...) |
58 { |
59 { |
59 va_list wdg_list; |
60 va_list wdg_list; |
60 |
61 |
61 va_start(wdg_list, widgets); |
62 va_start(wdg_list, widgets); |
62 |
63 |
63 while (widgets != WIDGET_LIST_END) { |
64 while (widgets != WIDGET_LIST_END) { |
64 SetWindowWidgetLoweredState(w, widgets, lowered_stat); |
65 SetWidgetLoweredState(widgets, lowered_stat); |
65 widgets = va_arg(wdg_list, int); |
66 widgets = va_arg(wdg_list, int); |
66 } |
67 } |
67 |
68 |
68 va_end(wdg_list); |
69 va_end(wdg_list); |
69 } |
70 } |
70 |
71 |
71 void RaiseWindowButtons(Window *w) |
72 void Window::RaiseButtons() |
72 { |
73 { |
73 uint i; |
74 uint i; |
74 |
75 |
75 for (i = 0; i < w->widget_count; i++) { |
76 for (i = 0; i < this->widget_count; i++) { |
76 if (IsWindowWidgetLowered(w, i)) { |
77 if (this->IsWidgetLowered(i)) { |
77 RaiseWindowWidget(w, i); |
78 this->RaiseWidget(i); |
78 InvalidateWidget(w, i); |
79 this->InvalidateWidget(i); |
79 } |
80 } |
80 } |
81 } |
81 } |
82 } |
82 |
83 |
83 void HandleButtonClick(Window *w, byte widget) |
84 void Window::InvalidateWidget(byte widget_index) const |
84 { |
85 { |
85 LowerWindowWidget(w, widget); |
86 const Widget *wi = &this->widget[widget_index]; |
86 w->flags4 |= 5 << WF_TIMEOUT_SHL; |
87 |
87 InvalidateWidget(w, widget); |
88 /* Don't redraw the window if the widget is invisible or of no-type */ |
88 } |
89 if (wi->type == WWT_EMPTY || IsWidgetHidden(widget_index)) return; |
89 |
90 |
|
91 SetDirtyBlocks(this->left + wi->left, this->top + wi->top, this->left + wi->right + 1, this->top + wi->bottom + 1); |
|
92 } |
|
93 |
|
94 void Window::HandleButtonClick(byte widget) |
|
95 { |
|
96 this->LowerWidget(widget); |
|
97 this->flags4 |= 5 << WF_TIMEOUT_SHL; |
|
98 this->InvalidateWidget(widget); |
|
99 } |
90 |
100 |
91 static void StartWindowDrag(Window *w); |
101 static void StartWindowDrag(Window *w); |
92 static void StartWindowSizing(Window *w); |
102 static void StartWindowSizing(Window *w); |
93 |
103 |
94 static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) |
104 static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) |
103 if (w->desc_flags & WDF_DEF_WIDGET) { |
113 if (w->desc_flags & WDF_DEF_WIDGET) { |
104 e.we.click.widget = GetWidgetFromPos(w, x, y); |
114 e.we.click.widget = GetWidgetFromPos(w, x, y); |
105 if (e.we.click.widget < 0) return; // exit if clicked outside of widgets |
115 if (e.we.click.widget < 0) return; // exit if clicked outside of widgets |
106 |
116 |
107 /* don't allow any interaction if the button has been disabled */ |
117 /* don't allow any interaction if the button has been disabled */ |
108 if (IsWindowWidgetDisabled(w, e.we.click.widget)) return; |
118 if (w->IsWidgetDisabled(e.we.click.widget)) return; |
109 |
119 |
110 wi = &w->widget[e.we.click.widget]; |
120 wi = &w->widget[e.we.click.widget]; |
111 |
121 |
112 if (wi->type & WWB_MASK) { |
122 if (wi->type & WWB_MASK) { |
113 /* special widget handling for buttons*/ |
123 /* special widget handling for buttons*/ |
114 switch (wi->type) { |
124 switch (wi->type) { |
115 case WWT_PANEL | WWB_PUSHBUTTON: /* WWT_PUSHBTN */ |
125 case WWT_PANEL | WWB_PUSHBUTTON: /* WWT_PUSHBTN */ |
116 case WWT_IMGBTN | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */ |
126 case WWT_IMGBTN | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */ |
117 case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */ |
127 case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */ |
118 HandleButtonClick(w, e.we.click.widget); |
128 w->HandleButtonClick(e.we.click.widget); |
119 break; |
129 break; |
120 } |
130 } |
121 } else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) { |
131 } else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) { |
122 ScrollbarClickHandler(w, wi, e.we.click.pt.x, e.we.click.pt.y); |
132 ScrollbarClickHandler(w, wi, e.we.click.pt.x, e.we.click.pt.y); |
123 } |
133 } |
1632 e.event = WE_KEYPRESS; |
1642 e.event = WE_KEYPRESS; |
1633 e.we.keypress.key = GB(key, 0, 16); |
1643 e.we.keypress.key = GB(key, 0, 16); |
1634 e.we.keypress.keycode = GB(key, 16, 16); |
1644 e.we.keypress.keycode = GB(key, 16, 16); |
1635 e.we.keypress.cont = true; |
1645 e.we.keypress.cont = true; |
1636 |
1646 |
|
1647 /* |
|
1648 * The Unicode standard defines an area called the private use area. Code points in this |
|
1649 * area are reserved for private use and thus not portable between systems. For instance, |
|
1650 * Apple defines code points for the arrow keys in this area, but these are only printable |
|
1651 * on a system running OS X. We don't want these keys to show up in text fields and such, |
|
1652 * and thus we have to clear the unicode character when we encounter such a key. |
|
1653 */ |
|
1654 if (e.we.keypress.key >= 0xE000 && e.we.keypress.key <= 0xF8FF) e.we.keypress.key = 0; |
|
1655 |
|
1656 /* |
|
1657 * If both key and keycode is zero, we don't bother to process the event. |
|
1658 */ |
|
1659 if (e.we.keypress.key == 0 && e.we.keypress.keycode == 0) return; |
|
1660 |
1637 /* check if we have a query string window open before allowing hotkeys */ |
1661 /* check if we have a query string window open before allowing hotkeys */ |
1638 if (FindWindowById(WC_QUERY_STRING, 0) != NULL || |
1662 if (FindWindowById(WC_QUERY_STRING, 0) != NULL || |
1639 FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL || |
1663 FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL || |
1640 FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL || |
1664 FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL || |
1641 FindWindowById(WC_CONSOLE, 0) != NULL || |
1665 FindWindowById(WC_CONSOLE, 0) != NULL || |
1642 FindWindowById(WC_SAVELOAD, 0) != NULL) { |
1666 FindWindowById(WC_SAVELOAD, 0) != NULL || |
|
1667 FindWindowById(WC_COMPANY_PASSWORD_WINDOW, 0) != NULL) { |
1643 query_open = true; |
1668 query_open = true; |
1644 } |
1669 } |
1645 |
1670 |
1646 /* Call the event, start with the uppermost window. */ |
1671 /* Call the event, start with the uppermost window. */ |
1647 for (wz = _last_z_window; wz != _z_windows;) { |
1672 for (wz = _last_z_window; wz != _z_windows;) { |
1923 const Window *w = *wz; |
1949 const Window *w = *wz; |
1924 if (w->window_class == cls && w->window_number == number) SetWindowDirty(w); |
1950 if (w->window_class == cls && w->window_number == number) SetWindowDirty(w); |
1925 } |
1951 } |
1926 } |
1952 } |
1927 |
1953 |
1928 void InvalidateWidget(const Window *w, byte widget_index) |
|
1929 { |
|
1930 const Widget *wi = &w->widget[widget_index]; |
|
1931 |
|
1932 /* Don't redraw the window if the widget is invisible or of no-type */ |
|
1933 if (wi->type == WWT_EMPTY || IsWindowWidgetHidden(w, widget_index)) return; |
|
1934 |
|
1935 SetDirtyBlocks(w->left + wi->left, w->top + wi->top, w->left + wi->right + 1, w->top + wi->bottom + 1); |
|
1936 } |
|
1937 |
|
1938 void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index) |
1954 void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index) |
1939 { |
1955 { |
1940 Window* const *wz; |
1956 Window* const *wz; |
1941 |
1957 |
1942 FOR_ALL_WINDOWS(wz) { |
1958 FOR_ALL_WINDOWS(wz) { |
1943 const Window *w = *wz; |
1959 const Window *w = *wz; |
1944 if (w->window_class == cls && w->window_number == number) { |
1960 if (w->window_class == cls && w->window_number == number) { |
1945 InvalidateWidget(w, widget_index); |
1961 w->InvalidateWidget(widget_index); |
1946 } |
1962 } |
1947 } |
1963 } |
1948 } |
1964 } |
1949 |
1965 |
1950 void InvalidateWindowClasses(WindowClass cls) |
1966 void InvalidateWindowClasses(WindowClass cls) |