Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Portions of this file are copyright Rebirth contributors and licensed as
3
 * described in COPYING.txt.
4
 * Portions of this file are copyright Parallax Software and licensed
5
 * according to the Parallax license below.
6
 * See COPYING.txt for license details.
7
 
8
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9
SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
10
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12
IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14
FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
16
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
18
*/
19
 
20
 
21
#include <stdlib.h>
22
 
23
#include "maths.h"
24
#include "pstypes.h"
25
#include "event.h"
26
#include "gr.h"
27
#include "ui.h"
28
#include "mouse.h"
29
#include "key.h"
30
#include "timer.h"
31
 
32
namespace dcx {
33
 
34
static void gr_draw_sunken_border( short x1, short y1, short x2, short y2 );
35
 
36
void ui_draw_listbox( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox )
37
{
38
        int i, x, y, stop;
39
        int w, h;
40
 
41
        //if (listbox->current_item<0)
42
        //    listbox->current_item=0;
43
        //if (listbox->current_item>=listbox->num_items)
44
        //    listbox->current_item = listbox->num_items-1;
45
        //if (listbox->first_item<0)
46
        //   listbox->first_item=0;
47
        //if (listbox->first_item>(listbox->num_items-listbox->num_items_displayed))
48
        //    listbox->first_item=(listbox->num_items-listbox->num_items_displayed);
49
 
50
#if 0  //ndef OGL
51
        if ((listbox->status!=1) && !listbox->moved )
52
                return;
53
#endif
54
 
55
        gr_set_current_canvas( listbox->canvas );
56
        auto &canvas = *grd_curcanv;
57
 
58
        w = listbox->width;
59
        h = listbox->height;
60
 
61
        gr_rect(canvas, 0, 0, w-1, h-1, CBLACK);
62
 
63
        gr_draw_sunken_border( -2, -2, w+listbox->scrollbar->width+4, h+1);
64
 
65
        stop = listbox->first_item+listbox->num_items_displayed;
66
        if (stop>listbox->num_items) stop = listbox->num_items;
67
 
68
        listbox->status = 0;
69
 
70
        x = y = 0;
71
 
72
        for (i= listbox->first_item; i< stop; i++ )
73
        {
74
                const auto color = (i == listbox->current_item)
75
                        ? CGREY
76
                        : CBLACK;
77
                gr_rect(canvas, x, y, listbox->width - 1, y + h - 1, color);
78
 
79
                if (i !=listbox->current_item)
80
                {
81
                        if ((listbox->current_item == -1) && (dlg->keyboard_focus_gadget == listbox) && (i == listbox->first_item)  )
82
                                gr_set_fontcolor(canvas, CRED, -1);
83
                        else
84
                                gr_set_fontcolor(canvas, CWHITE, -1);
85
                }
86
                else
87
                {
88
                        if (dlg->keyboard_focus_gadget == listbox)
89
                                gr_set_fontcolor(canvas, CRED, -1);
90
                        else
91
                                gr_set_fontcolor(canvas, CBLACK, -1);
92
                }
93
                gr_get_string_size(*canvas.cv_font, listbox->list[i], &w, &h, nullptr);
94
                gr_string(canvas, *canvas.cv_font, x + 2, y, listbox->list[i], w, h);
95
                y += h;
96
        }
97
 
98
        if (stop < listbox->num_items_displayed-1 )
99
        {
100
                gr_rect(canvas, x, y, listbox->width-1, listbox->height-1, CBLACK);
101
        }
102
 
103
        //gr_ubox( -1, -1, listbox->width, listbox->height);
104
}
105
 
106
 
107
static void gr_draw_sunken_border( short x1, short y1, short x2, short y2 )
108
{
109
        const uint8_t cgrey = CGREY;
110
        const uint8_t cbright = CBRIGHT;
111
        Hline(*grd_curcanv, x1 - 1, x2 + 1, y1 - 1, cgrey);
112
        Vline(*grd_curcanv, y1 - 1, y2 + 1, x1 - 1, cgrey);
113
 
114
        Hline(*grd_curcanv, x1 - 1, x2 + 1, y2 + 1, cbright);
115
        Vline(*grd_curcanv, y1, y2 + 1, x2 + 1, cbright);
116
}
117
 
118
 
119
std::unique_ptr<UI_GADGET_LISTBOX> ui_add_gadget_listbox(UI_DIALOG *dlg, short x, short y, short w, short h, short numitems, char **list)
120
{
121
        int th, i;
122
        gr_get_string_size(*grd_curcanv->cv_font, "*", nullptr, &th, nullptr);
123
 
124
        i = h / th;
125
        h = i * th;
126
 
127
        std::unique_ptr<UI_GADGET_LISTBOX> listbox{ui_gadget_add<UI_GADGET_LISTBOX>( dlg, x, y, x+w-1, y+h-1 )};
128
        listbox->list = list;
129
        listbox->width = w;
130
        listbox->height = h;
131
        listbox->num_items = numitems;
132
        listbox->num_items_displayed = i;
133
        listbox->first_item = 0;
134
        listbox->current_item = -1;
135
        listbox->last_scrolled = 0;
136
        listbox->textheight = th;
137
        listbox->dragging = 0;
138
        listbox->selected_item = -1;
139
        listbox->moved = 1;
140
        listbox->scrollbar = ui_add_gadget_scrollbar( dlg, x+w+3, y, 0, h, 0, numitems-i, 0, i );
141
        listbox->scrollbar->parent = listbox.get();
142
        return listbox;
143
}
144
 
145
window_event_result ui_listbox_do( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox,const d_event &event )
146
{
147
        int mitem, oldfakepos, kf;
148
        int keypress = 0;
149
        if (event.type == EVENT_WINDOW_DRAW)
150
        {
151
                ui_draw_listbox( dlg, listbox );
152
                return window_event_result::ignored;
153
        }
154
 
155
        if (event.type == EVENT_KEY_COMMAND)
156
                keypress = event_key_get(event);
157
 
158
        listbox->selected_item = -1;
159
 
160
        listbox->moved = 0;
161
 
162
        if (listbox->num_items < 1 ) {
163
                listbox->current_item = -1;
164
                listbox->first_item = 0;
165
                listbox->old_current_item = listbox->current_item;
166
                listbox->old_first_item = listbox->first_item;
167
                //ui_draw_listbox( dlg, listbox );
168
 
169
                if (dlg->keyboard_focus_gadget == listbox)
170
                {
171
                        dlg->keyboard_focus_gadget = ui_gadget_get_next(listbox);
172
                }
173
 
174
                return window_event_result::ignored;
175
        }
176
 
177
        listbox->old_current_item = listbox->current_item;
178
        listbox->old_first_item = listbox->first_item;
179
 
180
 
181
        if (GADGET_PRESSED(listbox->scrollbar.get()))
182
        {
183
                listbox->moved = 1;
184
 
185
                listbox->first_item = listbox->scrollbar->position;
186
 
187
                if (listbox->current_item<listbox->first_item)
188
                        listbox->current_item = listbox->first_item;
189
 
190
                if (listbox->current_item>(listbox->first_item+listbox->num_items_displayed-1))
191
                        listbox->current_item = listbox->first_item + listbox->num_items_displayed-1;
192
 
193
        }
194
 
195
        if (B1_JUST_RELEASED)
196
                listbox->dragging = 0;
197
 
198
        window_event_result rval = window_event_result::ignored;
199
        if (B1_JUST_PRESSED && ui_mouse_on_gadget( listbox ))
200
        {
201
                listbox->dragging = 1;
202
                rval = window_event_result::handled;
203
        }
204
 
205
        if ( dlg->keyboard_focus_gadget==listbox )
206
        {
207
                if (keypress==KEY_ENTER)   {
208
                        listbox->selected_item = listbox->current_item;
209
                        rval = window_event_result::handled;
210
                }
211
 
212
                kf = 0;
213
 
214
                switch(keypress)
215
                {
216
                        case (KEY_UP):
217
                                listbox->current_item--;
218
                                kf = 1;
219
                                break;
220
                        case (KEY_DOWN):
221
                                listbox->current_item++;
222
                                kf = 1;
223
                                break;
224
                        case (KEY_HOME):
225
                                listbox->current_item=0;
226
                                kf = 1;
227
                                break;
228
                        case (KEY_END):
229
                                listbox->current_item=listbox->num_items-1;
230
                                kf = 1;
231
                                break;
232
                        case (KEY_PAGEUP):
233
                                listbox->current_item -= listbox->num_items_displayed;
234
                                kf = 1;
235
                                break;
236
                        case (KEY_PAGEDOWN):
237
                                listbox->current_item += listbox->num_items_displayed;
238
                                kf = 1;
239
                                break;
240
                }
241
 
242
                if (kf==1)
243
                {
244
                        listbox->moved = 1;
245
                        rval = window_event_result::handled;
246
 
247
                        if (listbox->current_item<0)
248
                                listbox->current_item=0;
249
 
250
                        if (listbox->current_item>=listbox->num_items)
251
                                listbox->current_item = listbox->num_items-1;
252
 
253
                        if (listbox->current_item<listbox->first_item)
254
                                listbox->first_item = listbox->current_item;
255
 
256
                        if (listbox->current_item>=(listbox->first_item+listbox->num_items_displayed))
257
                                listbox->first_item = listbox->current_item-listbox->num_items_displayed+1;
258
 
259
                        if (listbox->num_items <= listbox->num_items_displayed )
260
                                listbox->first_item = 0;
261
                        else
262
                        {
263
                                oldfakepos = listbox->scrollbar->position;
264
                                listbox->scrollbar->position = listbox->first_item;
265
 
266
                                listbox->scrollbar->fake_position = listbox->scrollbar->position-listbox->scrollbar->start;
267
                                listbox->scrollbar->fake_position *= listbox->scrollbar->height-listbox->scrollbar->fake_size;
268
                                listbox->scrollbar->fake_position /= (listbox->scrollbar->stop-listbox->scrollbar->start);
269
 
270
                                if (listbox->scrollbar->fake_position<0)
271
                                {
272
                                        listbox->scrollbar->fake_position = 0;
273
                                }
274
                                if (listbox->scrollbar->fake_position > (listbox->scrollbar->height-listbox->scrollbar->fake_size))
275
                                {
276
                                        listbox->scrollbar->fake_position = (listbox->scrollbar->height-listbox->scrollbar->fake_size);
277
                                }
278
 
279
                                if (oldfakepos != listbox->scrollbar->position )
280
                                        listbox->scrollbar->status = 1;
281
                        }
282
                }
283
        }
284
 
285
 
286
        if (selected_gadget==listbox)
287
        {
288
                if (listbox->dragging)
289
                {
290
                        int x, y, z;
291
 
292
                        mouse_get_pos(&x, &y, &z);
293
                        if (y < listbox->y1)
294
                                mitem = -1;
295
                        else
296
                                mitem = (y - listbox->y1)/listbox->textheight;
297
 
298
                        if ((mitem < 0) && (timer_query() > listbox->last_scrolled + 1))
299
                        {
300
                                listbox->current_item--;
301
                                listbox->last_scrolled = timer_query();
302
                                listbox->moved = 1;
303
                        }
304
 
305
                        if ((mitem >= listbox->num_items_displayed) &&
306
                                 (timer_query() > listbox->last_scrolled + 1))
307
                        {
308
                                listbox->current_item++;
309
                                listbox->last_scrolled = timer_query();
310
                                listbox->moved = 1;
311
                        }
312
 
313
                        if ((mitem>=0) && (mitem<listbox->num_items_displayed))
314
                        {
315
                                listbox->current_item = mitem+listbox->first_item;
316
                                listbox->moved=1;
317
                        }
318
 
319
                        if (listbox->current_item <0 )
320
                                listbox->current_item = 0;
321
 
322
                        if (listbox->current_item >= listbox->num_items )
323
                                listbox->current_item = listbox->num_items-1;
324
 
325
                        if (listbox->current_item<listbox->first_item)
326
                                listbox->first_item = listbox->current_item;
327
 
328
                        if (listbox->current_item>=(listbox->first_item+listbox->num_items_displayed))
329
                                listbox->first_item = listbox->current_item-listbox->num_items_displayed+1;
330
 
331
                        if (listbox->num_items <= listbox->num_items_displayed )
332
                                listbox->first_item = 0;
333
                        else
334
                        {
335
                                oldfakepos = listbox->scrollbar->position;
336
                                listbox->scrollbar->position = listbox->first_item;
337
 
338
                                listbox->scrollbar->fake_position = listbox->scrollbar->position-listbox->scrollbar->start;
339
                                listbox->scrollbar->fake_position *= listbox->scrollbar->height-listbox->scrollbar->fake_size;
340
                                listbox->scrollbar->fake_position /= (listbox->scrollbar->stop-listbox->scrollbar->start);
341
 
342
                                if (listbox->scrollbar->fake_position<0)
343
                                {
344
                                        listbox->scrollbar->fake_position = 0;
345
                                }
346
                                if (listbox->scrollbar->fake_position > (listbox->scrollbar->height-listbox->scrollbar->fake_size))
347
                                {
348
                                        listbox->scrollbar->fake_position = (listbox->scrollbar->height-listbox->scrollbar->fake_size);
349
                                }
350
 
351
                                if (oldfakepos != listbox->scrollbar->position )
352
                                        listbox->scrollbar->status = 1;
353
                        }
354
 
355
                }
356
 
357
                if (B1_DOUBLE_CLICKED )
358
                {
359
                        listbox->selected_item = listbox->current_item;
360
                        rval = window_event_result::handled;
361
                }
362
 
363
        }
364
 
365
        if (listbox->moved || (listbox->selected_item > 0))
366
        {
367
                rval = ui_gadget_send_event(dlg, (listbox->selected_item > 0) ? EVENT_UI_LISTBOX_SELECTED : EVENT_UI_LISTBOX_MOVED, listbox);
368
                if (rval == window_event_result::ignored)
369
                        rval = window_event_result::handled;
370
        }
371
 
372
        return rval;
373
}
374
 
375
void ui_listbox_change(UI_DIALOG *, UI_GADGET_LISTBOX *listbox, uint_fast32_t numitems, const char *const *list)
376
{
377
        int stop, start;
378
        UI_GADGET_SCROLLBAR * scrollbar;
379
 
380
        listbox->list = list;
381
        listbox->num_items = numitems;
382
        listbox->first_item = 0;
383
        listbox->current_item = -1;
384
        listbox->last_scrolled = timer_query();
385
        listbox->dragging = 0;
386
        listbox->selected_item = -1;
387
        listbox->status = 1;
388
        listbox->first_item = 0;
389
        listbox->current_item = listbox->old_current_item = 0;
390
        listbox->moved = 0;
391
 
392
        scrollbar = listbox->scrollbar.get();
393
 
394
        start=0;
395
        stop= numitems - listbox->num_items_displayed;
396
 
397
        if (stop < start) stop = start;
398
 
399
        scrollbar->horz = 0;
400
        scrollbar->start = start;
401
        scrollbar->stop = stop;
402
        scrollbar->fake_length = scrollbar->height;
403
        scrollbar->fake_position =  0;
404
        if (stop!=start)
405
                scrollbar->fake_size = (listbox->num_items_displayed * scrollbar->height)/(stop-start+1+listbox->num_items_displayed);
406
        else
407
                scrollbar->fake_size = scrollbar->height;
408
 
409
        if (scrollbar->fake_size < 7) scrollbar->fake_size = 7;
410
        scrollbar->dragging = 0;
411
        scrollbar->moved=0;
412
        scrollbar->status=1;
413
 
414
 
415
}
416
 
417
}