0
|
1 |
#include "stdafx.h"
|
|
2 |
#include "ttd.h"
|
|
3 |
#include "window.h"
|
|
4 |
#include "gfx.h"
|
|
5 |
#include "viewport.h"
|
|
6 |
|
|
7 |
static Point HandleScrollbarHittest(Scrollbar *sb, int top, int bottom)
|
|
8 |
{
|
|
9 |
Point pt;
|
|
10 |
int height, count, pos, cap;
|
|
11 |
|
|
12 |
top += 10;
|
|
13 |
bottom -= 9;
|
|
14 |
|
|
15 |
height = (bottom - top);
|
|
16 |
|
|
17 |
pos = sb->pos;
|
|
18 |
count = sb->count;
|
|
19 |
cap = sb->cap;
|
|
20 |
|
|
21 |
if (count != 0) top += height * pos / count;
|
|
22 |
|
|
23 |
if (cap > count) cap = count;
|
|
24 |
if (count != 0)
|
|
25 |
bottom -= (count - pos - cap) * height / count;
|
|
26 |
|
|
27 |
pt.x = top;
|
|
28 |
pt.y = bottom - 1;
|
|
29 |
return pt;
|
|
30 |
}
|
|
31 |
|
|
32 |
/*****************************************************
|
|
33 |
* Special handling for the scrollbar widget type.
|
|
34 |
* Handles the special scrolling buttons and other
|
|
35 |
* scrolling.
|
|
36 |
* Parameters:
|
|
37 |
* w - Window.
|
|
38 |
* wi - Pointer to the scrollbar widget.
|
|
39 |
* x - The X coordinate of the mouse click.
|
|
40 |
* y - The Y coordinate of the mouse click.
|
|
41 |
*/
|
|
42 |
|
|
43 |
void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|
44 |
{
|
|
45 |
int mi, ma, pos;
|
|
46 |
Scrollbar *sb;
|
|
47 |
|
|
48 |
if (wi->type == WWT_SCROLLBAR) {
|
|
49 |
// vertical scroller
|
|
50 |
w->flags4 &= ~WF_HSCROLL;
|
|
51 |
mi = wi->top;
|
|
52 |
ma = wi->bottom;
|
|
53 |
pos = y;
|
|
54 |
sb = &w->vscroll;
|
|
55 |
} else {
|
|
56 |
// horizontal scroller
|
|
57 |
assert(wi->type == WWT_HSCROLLBAR);
|
|
58 |
w->flags4 |= WF_HSCROLL;
|
|
59 |
mi = wi->left;
|
|
60 |
ma = wi->right;
|
|
61 |
pos = x;
|
|
62 |
sb = &w->hscroll;
|
|
63 |
}
|
|
64 |
|
|
65 |
if (pos <= mi+9) {
|
|
66 |
// Pressing the upper button?
|
|
67 |
if (!_demo_mode) {
|
|
68 |
w->flags4 |= WF_SCROLL_UP;
|
|
69 |
if (_scroller_click_timeout == 0) {
|
|
70 |
_scroller_click_timeout = 6;
|
|
71 |
if (sb->pos != 0) sb->pos--;
|
|
72 |
}
|
|
73 |
_left_button_clicked = false;
|
|
74 |
}
|
|
75 |
} else if (pos >= ma-10) {
|
|
76 |
// Pressing the lower button?
|
|
77 |
if (!_demo_mode) {
|
|
78 |
w->flags4 |= WF_SCROLL_DOWN;
|
|
79 |
|
|
80 |
if (_scroller_click_timeout == 0) {
|
|
81 |
_scroller_click_timeout = 6;
|
|
82 |
if ((byte)(sb->pos + sb->cap) < sb->count)
|
|
83 |
sb->pos++;
|
|
84 |
}
|
|
85 |
_left_button_clicked = false;
|
|
86 |
}
|
|
87 |
} else {
|
|
88 |
//
|
|
89 |
Point pt = HandleScrollbarHittest(sb, mi, ma);
|
|
90 |
|
|
91 |
if (pos < pt.x) {
|
|
92 |
sb->pos = max(sb->pos - sb->cap, 0);
|
|
93 |
} else if (pos > pt.y) {
|
|
94 |
sb->pos = min(
|
|
95 |
sb->pos + sb->cap,
|
|
96 |
max(sb->count - sb->cap, 0)
|
|
97 |
);
|
|
98 |
} else {
|
|
99 |
_scrollbar_start_pos = pt.x - mi - 9;
|
|
100 |
_scrollbar_size = ma - mi - 23;
|
|
101 |
w->flags4 |= WF_SCROLL_MIDDLE;
|
|
102 |
_scrolling_scrollbar = true;
|
|
103 |
_cursorpos_drag_start = _cursor.pos;
|
|
104 |
}
|
|
105 |
}
|
|
106 |
|
|
107 |
SetWindowDirty(w);
|
|
108 |
}
|
|
109 |
|
|
110 |
/*****************************************************
|
|
111 |
* Returns the index for the widget located at the given
|
|
112 |
* position relative to the window.
|
|
113 |
* Parameters:
|
|
114 |
* w - Window
|
|
115 |
* x/y - Window client coordinates
|
|
116 |
* Returns:
|
|
117 |
* A widget index, or -1 if no widget was found.
|
|
118 |
*/
|
|
119 |
int GetWidgetFromPos(Window *w, int x, int y)
|
|
120 |
{
|
|
121 |
const Widget *wi;
|
|
122 |
int index, found_index = -1;
|
|
123 |
|
|
124 |
// Go through the widgets and check if we find the widget that the coordinate is
|
|
125 |
// inside.
|
|
126 |
for(index=0,wi=w->widget; wi->type != WWT_LAST; index++, wi++) {
|
|
127 |
if (wi->type == WWT_EMPTY || wi->type == WWT_FRAME)
|
|
128 |
continue;
|
|
129 |
|
|
130 |
if (x >= wi->left &&
|
|
131 |
x < wi->right &&
|
|
132 |
y >= wi->top &&
|
|
133 |
y < wi->bottom && !HASBIT(w->hidden_state,index)) {
|
|
134 |
found_index = index;
|
|
135 |
}
|
|
136 |
}
|
|
137 |
|
|
138 |
// Return the index
|
|
139 |
return found_index;
|
|
140 |
}
|
|
141 |
|
|
142 |
|
|
143 |
void DrawWindowWidgets(Window *w)
|
|
144 |
{
|
|
145 |
const Widget *wi;
|
|
146 |
DrawPixelInfo *dpi = _cur_dpi;
|
|
147 |
Rect r;
|
|
148 |
uint32 dparam_backup[10];
|
|
149 |
uint32 cur_click, cur_disabled, cur_hidden;
|
|
150 |
|
|
151 |
if (w->desc_flags & WDF_RESTORE_DPARAM) COPY_OUT_DPARAM(dparam_backup, 0, lengthof(dparam_backup));
|
|
152 |
|
|
153 |
wi = w->widget;
|
|
154 |
|
|
155 |
cur_click = w->click_state;
|
|
156 |
cur_disabled = w->disabled_state;
|
|
157 |
cur_hidden = w->hidden_state;
|
|
158 |
|
|
159 |
do {
|
|
160 |
if (dpi->left > (r.right=/*w->left + */wi->right) ||
|
|
161 |
dpi->left + dpi->width <= (r.left=wi->left/* + w->left*/) ||
|
|
162 |
dpi->top > (r.bottom=/*w->top +*/ wi->bottom) ||
|
|
163 |
dpi->top + dpi->height <= (r.top = /*w->top +*/ wi->top) ||
|
|
164 |
(cur_hidden&1))
|
|
165 |
continue;
|
|
166 |
|
|
167 |
switch(wi->type&WWT_MASK) {
|
|
168 |
case WWT_PANEL:
|
|
169 |
case WWT_PANEL_2: {
|
|
170 |
int img;
|
|
171 |
|
|
172 |
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color,
|
|
173 |
(cur_click & 1) ? 0x20 : 0);
|
|
174 |
|
|
175 |
if ((img=wi->unkA) != 0) {
|
|
176 |
if ((wi->type&WWT_MASK) == WWT_PANEL_2 && (cur_click&1)) img++;
|
|
177 |
DrawSprite(img, r.left+1, r.top+1);
|
|
178 |
}
|
|
179 |
goto draw_default;
|
|
180 |
}
|
|
181 |
|
|
182 |
case WWT_CLOSEBOX:
|
|
183 |
case WWT_4: {
|
|
184 |
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color,
|
|
185 |
(cur_click & 1) ? 0x20 : 0);
|
|
186 |
}
|
|
187 |
/* fall through */
|
|
188 |
|
|
189 |
case WWT_5: {
|
|
190 |
StringID str = wi->unkA;
|
|
191 |
|
|
192 |
if ((wi->type&WWT_MASK) == WWT_4 && (cur_click&1)) str++;
|
|
193 |
|
|
194 |
DrawStringCentered((r.left + r.right+1)>>1, ((r.top+r.bottom + 1)>>1) - 5, str, 0);
|
|
195 |
goto restore_dparam;
|
|
196 |
}
|
|
197 |
|
|
198 |
case WWT_6: {
|
|
199 |
StringID str;
|
|
200 |
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, 0x60);
|
|
201 |
|
|
202 |
if ((str = wi->unkA) != 0) {
|
|
203 |
DrawString(r.left+2, r.top+1, str, 0);
|
|
204 |
goto restore_dparam;
|
|
205 |
}
|
|
206 |
goto draw_default;
|
|
207 |
}
|
|
208 |
|
|
209 |
case WWT_MATRIX: {
|
|
210 |
int c, d, ctr;
|
|
211 |
int x, amt1, amt2;
|
|
212 |
int color;
|
|
213 |
|
|
214 |
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color,
|
|
215 |
(cur_click & 1) ? 0x20 : 0);
|
|
216 |
|
|
217 |
c = (wi->unkA&0xFF);
|
|
218 |
amt1 = (wi->right - wi->left + 1) / c;
|
|
219 |
|
|
220 |
d = (wi->unkA >> 8);
|
|
221 |
amt2 = (wi->bottom - wi->top + 1) / d;
|
|
222 |
|
|
223 |
color = _color_list[wi->color&0xF].window_color_bgb;
|
|
224 |
|
|
225 |
x = r.left;
|
|
226 |
for(ctr=c; --ctr; ) {
|
|
227 |
x += amt1;
|
|
228 |
GfxFillRect(x, r.top+1, x, r.bottom-1, color);
|
|
229 |
}
|
|
230 |
|
|
231 |
x = r.top;
|
|
232 |
for(ctr=d; --ctr; ) {
|
|
233 |
x += amt2;
|
|
234 |
GfxFillRect(r.left+1, x, r.right-1, x, color);
|
|
235 |
}
|
|
236 |
|
|
237 |
color = _color_list[wi->color&0xF].window_color_1b;
|
|
238 |
|
|
239 |
x = r.left-1;
|
|
240 |
for(ctr=c; --ctr; ) {
|
|
241 |
x += amt1;
|
|
242 |
GfxFillRect(x, r.top+1, x, r.bottom-1, color);
|
|
243 |
}
|
|
244 |
|
|
245 |
x = r.top-1;
|
|
246 |
for(ctr=d; --ctr; ) {
|
|
247 |
x += amt2;
|
|
248 |
GfxFillRect(r.left+1, x, r.right-1, x, color);
|
|
249 |
}
|
|
250 |
|
|
251 |
goto draw_default;
|
|
252 |
}
|
|
253 |
|
|
254 |
// vertical scrollbar
|
|
255 |
case WWT_SCROLLBAR: {
|
|
256 |
Point pt;
|
|
257 |
int c1,c2;
|
|
258 |
|
|
259 |
// draw up/down buttons
|
|
260 |
DrawFrameRect(r.left, r.top, r.right, r.top+9, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == WF_SCROLL_UP ? 0x20 : 0);
|
|
261 |
DrawFrameRect(r.left, r.bottom-9, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == WF_SCROLL_DOWN ? 0x20 : 0);
|
|
262 |
|
|
263 |
// draw icons in up/down buttons
|
|
264 |
DoDrawString("\xA0", r.left+2, r.top, 0x10);
|
|
265 |
DoDrawString("\xAA", r.left+2, r.bottom-9, 0x10);
|
|
266 |
|
|
267 |
c1 = _color_list[wi->color&0xF].window_color_1a;
|
|
268 |
c2 = _color_list[wi->color&0xF].window_color_2;
|
|
269 |
|
|
270 |
// draw "shaded" background
|
|
271 |
GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
|
|
272 |
GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | 0x8000);
|
|
273 |
|
|
274 |
// draw shaded lines
|
|
275 |
GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
|
|
276 |
GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
|
|
277 |
GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
|
|
278 |
GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
|
|
279 |
|
|
280 |
pt = HandleScrollbarHittest(&w->vscroll, r.top, r.bottom);
|
|
281 |
DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == WF_SCROLL_MIDDLE ? 0x20 : 0);
|
|
282 |
break;
|
|
283 |
}
|
|
284 |
|
|
285 |
// horizontal scrollbar
|
|
286 |
case WWT_HSCROLLBAR: {
|
|
287 |
Point pt;
|
|
288 |
int c1,c2;
|
|
289 |
|
|
290 |
DrawFrameRect(r.left, r.top, r.left + 9, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL) ? 0x20 : 0);
|
|
291 |
DrawFrameRect(r.right-9, r.top, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL) ? 0x20 : 0);
|
|
292 |
|
|
293 |
// draw icons in up/down buttons
|
|
294 |
DoDrawString("\xA0", r.left+1, r.top+1, 0x10);
|
|
295 |
DoDrawString("\xAA", r.right-8, r.top+1, 0x10);
|
|
296 |
|
|
297 |
c1 = _color_list[wi->color&0xF].window_color_1a;
|
|
298 |
c2 = _color_list[wi->color&0xF].window_color_2;
|
|
299 |
|
|
300 |
// draw "shaded" background
|
|
301 |
GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c2);
|
|
302 |
GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c1 | 0x8000);
|
|
303 |
|
|
304 |
// draw shaded lines
|
|
305 |
GfxFillRect(r.left+10, r.top+2, r.right-10, r.top+2, c1);
|
|
306 |
GfxFillRect(r.left+10, r.top+3, r.right-10, r.top+3, c2);
|
|
307 |
GfxFillRect(r.left+10, r.top+7, r.right-10, r.top+7, c1);
|
|
308 |
GfxFillRect(r.left+10, r.top+8, r.right-10, r.top+8, c2);
|
|
309 |
|
|
310 |
// draw actual scrollbar
|
|
311 |
pt = HandleScrollbarHittest(&w->hscroll, r.left, r.right);
|
|
312 |
DrawFrameRect(pt.x, r.top, pt.y, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL) ? 0x20 : 0);
|
|
313 |
|
|
314 |
break;
|
|
315 |
}
|
|
316 |
|
|
317 |
case WWT_FRAME: {
|
|
318 |
int c1,c2;
|
|
319 |
int x2 = 0;
|
|
320 |
|
|
321 |
if (wi->unkA != 0) {
|
|
322 |
x2 = DrawString(r.left+6, r.top, wi->unkA, 0);
|
|
323 |
}
|
|
324 |
|
|
325 |
c1 = _color_list[wi->color].window_color_1a;
|
|
326 |
c2 = _color_list[wi->color].window_color_2;
|
|
327 |
|
|
328 |
//Line from upper left corner to start of text
|
|
329 |
GfxFillRect(r.left, r.top+4, r.left+4,r.top+4, c1);
|
|
330 |
GfxFillRect(r.left+1, r.top+5, r.left+4,r.top+5, c2);
|
|
331 |
|
|
332 |
// Line from end of text to upper right corner
|
|
333 |
GfxFillRect(x2, r.top+4, r.right-1,r.top+4,c1);
|
|
334 |
GfxFillRect(x2, r.top+5, r.right-2,r.top+5,c2);
|
|
335 |
|
|
336 |
// Line from upper left corner to bottom left corner
|
|
337 |
GfxFillRect(r.left, r.top+5, r.left, r.bottom-1, c1);
|
|
338 |
GfxFillRect(r.left+1, r.top+6, r.left+1, r.bottom-2, c2);
|
|
339 |
|
|
340 |
//Line from upper right corner to bottom right corner
|
|
341 |
GfxFillRect(r.right-1, r.top+5, r.right-1, r.bottom-2, c1);
|
|
342 |
GfxFillRect(r.right, r.top+4, r.right, r.bottom-1, c2);
|
|
343 |
|
|
344 |
GfxFillRect(r.left+1, r.bottom-1, r.right-1, r.bottom-1, c1);
|
|
345 |
GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2);
|
|
346 |
|
|
347 |
goto restore_dparam;
|
|
348 |
}
|
|
349 |
|
|
350 |
case WWT_CAPTION: {
|
|
351 |
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, 0x10);
|
|
352 |
DrawFrameRect(r.left+1, r.top+1, r.right-1, r.bottom-1, wi->color, (w->caption_color == 0xFF) ? 0x60 : 0x70);
|
|
353 |
|
|
354 |
if (w->caption_color != 0xFF) {
|
|
355 |
GfxFillRect(r.left+2, r.top+2, r.right-2, r.bottom-2, _color_list[_player_colors[w->caption_color]].window_color_1b);
|
|
356 |
}
|
|
357 |
|
|
358 |
DrawStringCentered( (r.left+r.right+1)>>1, r.top+2, wi->unkA, 0x84);
|
|
359 |
restore_dparam:;
|
|
360 |
if (w->desc_flags & WDF_RESTORE_DPARAM) COPY_IN_DPARAM(0, dparam_backup, lengthof(dparam_backup));
|
|
361 |
draw_default:;
|
|
362 |
if (cur_disabled & 1) {
|
|
363 |
GfxFillRect(r.left+1, r.top+1, r.right-1, r.bottom-1, _color_list[wi->color&0xF].unk2 | 0x8000);
|
|
364 |
}
|
|
365 |
}
|
|
366 |
}
|
|
367 |
} while (cur_click>>=1, cur_disabled>>=1, cur_hidden >>= 1, (++wi)->type != WWT_LAST);
|
|
368 |
|
|
369 |
|
|
370 |
if (w->flags4 & WF_WHITE_BORDER_MASK) {
|
|
371 |
//DrawFrameRect(w->left, w->top, w->left + w->width-1, w->top+w->height-1, 0xF, 0x10);
|
|
372 |
DrawFrameRect(0, 0, w->width-1, w->height-1, 0xF, 0x10);
|
|
373 |
}
|
|
374 |
|
|
375 |
}
|