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