1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/tdgtlist.c,v 1.8 2011/05/16 16:22:00 william Exp $
19 */
20
21 #define _INCLUDE_FROM_TDGTLIST_C_
22
23 #include "tgifdefs.h"
24 #include "patchlvl.h"
25
26 #include "auxtext.e"
27 #include "choose.e"
28 #include "color.e"
29 #include "cursor.e"
30 #include "dialog.e"
31 #include "drawing.e"
32 #include "font.e"
33 #include "mainloop.e"
34 #include "menu.e"
35 #include "msg.e"
36 #include "pattern.e"
37 #include "raster.e"
38 #include "rect.e"
39 #include "scroll.e"
40 #include "setup.e"
41 #include "strtbl.e"
42 #include "tdgtlist.e"
43 #include "tidget.e"
44 #include "util.e"
45
46 static void RedrawTdgtList ARGS_DECL((TidgetInfo *pti));
47 static int TdgtListEventHandler ARGS_DECL((TidgetInfo *pti, XEvent *input,
48 TidgetInfo *handling_pti));
49 static int IsTdgtListEvent ARGS_DECL((TidgetInfo *pti, XEvent *input,
50 TidgetInfo **ppti_handler_tidget_return));
51 static void DestroyTdgtList ARGS_DECL((TidgetInfo *pti));
52 static void MapTdgtList ARGS_DECL((TidgetInfo *pti));
53 static void TdgtListMoveResize ARGS_DECL((TidgetInfo *pti, int x, int y,
54 int w, int h));
55 static int TdgtListSendCmd ARGS_DECL((TidgetInfo *pti, int cmd_type,
56 int cmd_arg, void *pv_cmd_userdata));
57
58 static int gnListFontHeight=0;
59 static int gnListFontWidth=0;
60 static int gnListFontAsc=0;
61 static int gnListFontDes=0;
62 static XFontStruct *gnListFontPtr=NULL;
63
64 /* --------------------- Utility Functions --------------------- */
65
66 static
FreeListItemInfo(pListItemInfo)67 void FreeListItemInfo(pListItemInfo)
68 ListItemInfo *pListItemInfo;
69 {
70 UtilFree(pListItemInfo->buf);
71 free(pListItemInfo);
72 }
73
74 /* --------------------- RedrawTdgtList() --------------------- */
75
76 static
RedrawTdgtListItem(pTdgtList,index,pListItemInfo)77 void RedrawTdgtListItem(pTdgtList, index, pListItemInfo)
78 TdgtList *pTdgtList;
79 int index;
80 ListItemInfo *pListItemInfo;
81 {
82 ListInfo *pListInfo=(&pTdgtList->list_info);
83 int len=0, top=0, end=0, checkbox_cols=0, text_left=0, box_offset=0, box_w=0;
84 int selected=(index==pListInfo->marked_index);
85 int length=ListLength(&pListInfo->list);
86 XGCValues values;
87
88 if (!pTdgtList->can_select) selected = FALSE;
89 top = gnListFontAsc+1;
90 if (pListInfo->first_index+pListInfo->num_visible_lines > length) {
91 end = length;
92 } else {
93 end = pListInfo->first_index + pListInfo->num_visible_lines;
94 }
95 if (pListInfo->p_check_array != NULL &&
96 pListInfo->p_check_array->num_cols > 0) {
97 checkbox_cols = pListInfo->p_check_array->num_cols;
98 text_left = checkbox_cols*ROW_HEIGHT;
99 box_offset = 1;
100 box_w = (ROW_HEIGHT-((box_offset+1)<<1));
101 }
102 if (pTdgtList->multicolor) {
103 if (selected) {
104 } else {
105 char *buf=NULL;
106 XFontStruct *font_ptr=NULL;
107 int font_asc=0;
108 TidgetDrawMsgStringFunc *pf_draw_string_func=NULL;
109
110 len = strlen(pListItemInfo->nick_name)+strlen(pListItemInfo->buf)+8;
111 buf = (char*)malloc(len*sizeof(char));
112 if (buf == NULL) FailAllocMessage();
113 if (*pListItemInfo->nick_name == '\0') {
114 sprintf(buf, "%s", pListItemInfo->buf);
115 } else {
116 sprintf(buf, "%s : %s", pListItemInfo->nick_name,
117 pListItemInfo->buf);
118 }
119 TidgetGetFontInfoGivenStyle(pListItemInfo->font_style, &font_ptr,
120 NULL, NULL, &font_asc, NULL);
121
122 values.foreground = myBgPixel;
123 values.background = myFgPixel;
124 values.function = GXcopy;
125 values.fill_style = FillSolid;
126 XChangeGC(mainDisplay, gTidgetManager.gc,
127 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
128 XFillRectangle(mainDisplay, pTdgtList->dsp_win,
129 revNameGC, 0,
130 (index-pListInfo->first_index)*ROW_HEIGHT,
131 ITEM_LEN*defaultFontWidth, ROW_HEIGHT);
132
133 switch (pListItemInfo->font_style) {
134 case STYLE_NR:
135 if (msgFontPtr != NULL) {
136 XSetFont(mainDisplay, gTidgetManager.gc, msgFontPtr->fid);
137 }
138 pf_draw_string_func = DrawMsgString;
139 break;
140 case STYLE_BR:
141 if (boldMsgFontPtr != NULL) {
142 XSetFont(mainDisplay, gTidgetManager.gc, boldMsgFontPtr->fid);
143 }
144 pf_draw_string_func = DrawBoldMsgString;
145 break;
146 case STYLE_NI:
147 if (italicMsgFontPtr != NULL) {
148 XSetFont(mainDisplay, gTidgetManager.gc, italicMsgFontPtr->fid);
149 }
150 pf_draw_string_func = DrawItalicMsgString;
151 break;
152 case STYLE_BI:
153 if (boldItalicMsgFontPtr != NULL) {
154 XSetFont(mainDisplay, gTidgetManager.gc,
155 boldItalicMsgFontPtr->fid);
156 }
157 pf_draw_string_func = DrawBoldItalicMsgString;
158 break;
159 }
160 values.foreground = ((pListItemInfo->color_index == INVALID) ?
161 myFgPixel : colorPixels[pListItemInfo->color_index]);
162 values.background = myBgPixel;
163 values.function = GXcopy;
164 values.fill_style = FillSolid;
165 XChangeGC(mainDisplay, gTidgetManager.gc,
166 GCForeground |GCBackground | GCFunction | GCFillStyle, &values);
167
168 (pf_draw_string_func)(mainDisplay, pTdgtList->dsp_win,
169 gTidgetManager.gc, text_left,
170 (index-pListInfo->first_index)*ROW_HEIGHT+top, buf, strlen(buf));
171
172 TidgetManagerResetGC();
173
174 free(buf);
175 }
176 } else {
177 if (selected) {
178 values.foreground = myFgPixel;
179 values.background = myBgPixel;
180 } else {
181 values.foreground = myBgPixel;
182 values.background = myFgPixel;
183 }
184 values.function = GXcopy;
185 values.fill_style = FillSolid;
186 XChangeGC(mainDisplay, gTidgetManager.gc,
187 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
188 XFillRectangle(mainDisplay, pTdgtList->dsp_win, gTidgetManager.gc, 0,
189 (index-pListInfo->first_index)*ROW_HEIGHT,
190 ITEM_LEN*defaultFontWidth, ROW_HEIGHT);
191 len = strlen(pListInfo->entries[index]);
192 DrawMsgString(mainDisplay, pTdgtList->dsp_win, gTidgetManager.gc,
193 text_left, (index-pListInfo->first_index)*ROW_HEIGHT+top,
194 pListInfo->entries[index], len);
195 TidgetManagerResetGC();
196 }
197 if (checkbox_cols > 0) {
198 int col=0, cur_x=0;
199
200 if (selected) {
201 values.foreground = myFgPixel;
202 values.background = myBgPixel;
203 } else {
204 values.foreground = myBgPixel;
205 values.background = myFgPixel;
206 }
207 values.function = GXcopy;
208 values.fill_style = FillSolid;
209 XChangeGC(mainDisplay, gTidgetManager.gc,
210 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
211 for (col=0; col < pListInfo->p_check_array->num_cols; col++) {
212 DrawCheckbox(mainDisplay, pTdgtList->dsp_win, gTidgetManager.gc,
213 cur_x+box_offset,
214 (index-pListInfo->first_index)*ROW_HEIGHT+top-box_w,
215 box_w, box_w, pListInfo->p_check_array->value[col][index]);
216 cur_x += ROW_HEIGHT;
217 }
218 TidgetManagerResetGC();
219 }
220 }
221
222 static
RedrawTdgtListScrollWindow(pTdgtList)223 void RedrawTdgtListScrollWindow(pTdgtList)
224 TdgtList *pTdgtList;
225 {
226 ListInfo *pListInfo=(&pTdgtList->list_info);
227 double frac=(double)0, start_frac=(double)0;
228 int block_h=0, block_start=0;
229 int length=ListLength(&pListInfo->list);
230
231 start_frac = (length > 0) ? (double)((double)(pListInfo->first_index) /
232 (double)length) : ((double)0.0);
233 /* starting pixel */
234 block_start = (int)(pTdgtList->scr_area_h * start_frac);
235
236 if (length > pListInfo->num_visible_lines) {
237 frac = (double)((double)pListInfo->num_visible_lines / (double)(length));
238 } else {
239 frac = 1.0;
240 }
241 if (pListInfo->first_index+pListInfo->num_visible_lines >= length) {
242 block_h = pTdgtList->scr_area_h - block_start;
243 } else {
244 block_h = (int)(pTdgtList->scr_area_h * frac);
245 }
246 TgDrawScrollBar(mainDisplay, pTdgtList->scr_win, VERT_SCROLLBAR,
247 0, 0, scrollBarW, pTdgtList->scr_area_h, start_frac,
248 pListInfo->num_visible_lines, length);
249 }
250
251 static
RedrawTdgtListDspWindow(pTdgtList)252 void RedrawTdgtListDspWindow(pTdgtList)
253 TdgtList *pTdgtList;
254 {
255 ListInfo *pListInfo=(&pTdgtList->list_info);
256 int length=ListLength(&pListInfo->list);
257 int i=0, end=0;
258 XGCValues values;
259
260 if (pListInfo->first_index+pListInfo->num_visible_lines > length) {
261 end = length;
262 } else {
263 end = pListInfo->first_index + pListInfo->num_visible_lines;
264 }
265 values.foreground = myBgPixel;
266 values.background = myFgPixel;
267 values.function = GXcopy;
268 values.fill_style = FillSolid;
269 XChangeGC(mainDisplay, gTidgetManager.gc,
270 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
271 XFillRectangle(mainDisplay, pTdgtList->dsp_win, gTidgetManager.gc, 0, 0,
272 pTdgtList->dsp_win_info.w, pTdgtList->dsp_win_info.h);
273 TidgetManagerResetGC();
274
275 if (pTdgtList->multicolor) {
276 CVListElem *pElem=NULL;
277
278 for (i=0, pElem=ListFirst(&pListInfo->list);
279 i < pListInfo->first_index && pElem != NULL;
280 i++, pElem=ListNext(&pListInfo->list, pElem)) {
281 }
282 for (i=pListInfo->first_index; i < end && pElem != NULL;
283 i++, pElem=ListNext(&pListInfo->list, pElem)) {
284 ListItemInfo *pListItemInfo=(ListItemInfo*)(pElem->obj);
285
286 RedrawTdgtListItem(pTdgtList, i, pListItemInfo);
287 }
288 } else {
289 for (i=pListInfo->first_index; i < end; i++) {
290 RedrawTdgtListItem(pTdgtList, i, NULL);
291 }
292 }
293 }
294
295 static
RedrawTdgtListBaseWindow(pTdgtList)296 void RedrawTdgtListBaseWindow(pTdgtList)
297 TdgtList *pTdgtList;
298 {
299 if (threeDLook) {
300 struct BBRec bbox;
301
302 SetBBRec(&bbox, 0, 0, pTdgtList->pti->tci.win_info.w,
303 pTdgtList->pti->tci.win_info.h);
304 TgDrawThreeDButton(mainDisplay, pTdgtList->pti->tci.win,
305 gTidgetManager.gc, &bbox, TGBS_LOWRED, 2, FALSE);
306 TidgetManagerResetGC();
307 }
308 }
309
310 static
RedrawTdgtList(pti)311 void RedrawTdgtList(pti)
312 TidgetInfo *pti;
313 {
314 TdgtList *pTdgtList=(TdgtList*)(pti->tidget);
315
316 XEvent ev;
317
318 RedrawTdgtListScrollWindow(pTdgtList);
319 RedrawTdgtListDspWindow(pTdgtList);
320 RedrawTdgtListBaseWindow(pTdgtList);
321
322 while (XCheckWindowEvent(mainDisplay, pTdgtList->pti->tci.win, ExposureMask,
323 &ev)) ;
324 }
325
326 /* --------------------- TdgtListEventHandler() --------------------- */
327
328 static
TdgtListScrollItemCallback(pv_userdata)329 int TdgtListScrollItemCallback(pv_userdata)
330 void *pv_userdata;
331 /* returns TRUE to cancel scrolling */
332 {
333 TdgtList *pTdgtList=((TdgtList*)pv_userdata);
334 ListInfo *pListInfo=(&pTdgtList->list_info);
335 int num_visible_lines=pListInfo->num_visible_lines;
336 int length=ListLength(&pListInfo->list);
337
338 if (pTdgtList->scr_dir == SCRL_UP) {
339 if (pListInfo->first_index == 0) return FALSE;
340 pListInfo->first_index--;
341 } else {
342 if (length <= num_visible_lines ||
343 pListInfo->first_index+num_visible_lines == length) {
344 return FALSE;
345 }
346 pListInfo->first_index++;
347 }
348 RedrawTdgtList(pTdgtList->pti);
349 XSync(mainDisplay, False);
350
351 return FALSE;
352 }
353
354 static
TdgtListScrollPageCallback(pv_userdata)355 int TdgtListScrollPageCallback(pv_userdata)
356 void *pv_userdata;
357 /* returns TRUE to cancel scrolling */
358 {
359 TdgtList *pTdgtList=((TdgtList*)pv_userdata);
360 ListInfo *pListInfo=(&pTdgtList->list_info);
361 int num_visible_lines=pListInfo->num_visible_lines;
362 int length=ListLength(&pListInfo->list);
363
364 if (pTdgtList->scr_dir == SCRL_UP) {
365 if (pListInfo->first_index == 0) return FALSE;
366 pListInfo->first_index -= num_visible_lines;
367 if (pListInfo->first_index < 0) pListInfo->first_index = 0;
368 } else {
369 if (length <= num_visible_lines ||
370 pListInfo->first_index+num_visible_lines == length) {
371 return FALSE;
372 }
373 pListInfo->first_index += num_visible_lines;
374 if (pListInfo->first_index+num_visible_lines >= length) {
375 pListInfo->first_index = length-num_visible_lines;
376 }
377 }
378 RedrawTdgtList(pTdgtList->pti);
379 XSync(mainDisplay, False);
380
381 return FALSE;
382 }
383
384 static
DoTdgtListBtnScroll(pTdgtList,scroll_page,scr_dir,pbbox)385 int DoTdgtListBtnScroll(pTdgtList, scroll_page, scr_dir, pbbox)
386 TdgtList *pTdgtList;
387 int scroll_page, scr_dir;
388 struct BBRec *pbbox;
389 /* returns TRUE if done scrolling */
390 {
391 ListInfo *pListInfo=(&pTdgtList->list_info);
392 int num_visible_lines=pListInfo->num_visible_lines;
393 int length=ListLength(&pListInfo->list);
394 ScrollBtnCallbackInfo sbci;
395
396 pTdgtList->scr_dir = scr_dir;
397 memset(&sbci, 0, sizeof(ScrollBtnCallbackInfo));
398
399 if (scroll_page) {
400 sbci.ms = 200;
401 sbci.pv_userdata = pTdgtList;
402 sbci.pf_scroll_btn_callback = TdgtListScrollPageCallback;
403 if (TgPressButtonLoop(mainDisplay, pTdgtList->scr_win, NULL,
404 &sbci)) {
405 if (scr_dir == SCRL_UP) {
406 if (pListInfo->first_index == 0) return TRUE;
407 pListInfo->first_index -= num_visible_lines;
408 if (pListInfo->first_index < 0) pListInfo->first_index = 0;
409 } else {
410 if (length <= num_visible_lines ||
411 pListInfo->first_index+num_visible_lines == length) {
412 return TRUE;
413 }
414 pListInfo->first_index += num_visible_lines;
415 if (pListInfo->first_index+num_visible_lines >= length) {
416 pListInfo->first_index = length-num_visible_lines;
417 }
418 }
419 }
420 } else {
421 sbci.ms = 50;
422 sbci.pv_userdata = pTdgtList;
423 sbci.pf_scroll_btn_callback = TdgtListScrollItemCallback;
424 if (TgPressButtonLoop(mainDisplay, pTdgtList->scr_win, pbbox, &sbci)) {
425 if (scr_dir == SCRL_UP) {
426 if (pListInfo->first_index == 0) return TRUE;
427 pListInfo->first_index--;
428 } else {
429 if (length <= num_visible_lines ||
430 pListInfo->first_index+num_visible_lines == length) {
431 return TRUE;
432 }
433 pListInfo->first_index++;
434 }
435 }
436 }
437 return FALSE;
438 }
439
440 static
DoDragInTdgtList(pTdgtList,button_ev,btn_y,btn_offset)441 void DoDragInTdgtList(pTdgtList, button_ev, btn_y, btn_offset)
442 TdgtList *pTdgtList;
443 XButtonEvent *button_ev;
444 int btn_y, btn_offset;
445 {
446 ListInfo *pListInfo=(&pTdgtList->list_info);
447 int length=ListLength(&pListInfo->list);
448 int num_visible_lines=pListInfo->num_visible_lines;
449 double frac=(double)0, start_frac=(double)0;
450 int block_h=0, block_start=0, done=FALSE;
451
452 if (length <= num_visible_lines) return;
453
454 frac = (double)((double)num_visible_lines / (double)(length));
455 block_h = (int)(pTdgtList->scr_area_h * frac);
456
457 if (length > pListInfo->num_visible_lines) {
458 frac = (double)((double)pListInfo->num_visible_lines / (double)(length));
459 block_h = (int)(((double)(pTdgtList->scr_area_h-(scrollBarW<<1))) * frac);
460 } else {
461 frac = 1.0;
462 block_h = pTdgtList->scr_area_h-(scrollBarW<<1);
463 }
464 if (threeDLook) {
465 block_start = button_ev->y+btn_offset;;
466 start_frac = (double)((double)(block_start-scrollBarW) /
467 (double)(pTdgtList->scr_area_h-(scrollBarW<<1)));
468 if (block_start+block_h >= pTdgtList->scr_area_h-scrollBarW) {
469 pListInfo->first_index = length - num_visible_lines;
470 } else {
471 pListInfo->first_index = (int)(length * start_frac);
472 }
473 } else {
474 block_start = button_ev->y;
475 start_frac = (double)((double)(block_start) /
476 (double)(pTdgtList->scr_area_h));
477 if (block_start+block_h >= pTdgtList->scr_area_h) {
478 pListInfo->first_index = length - num_visible_lines;
479 } else {
480 pListInfo->first_index = (int)(length * start_frac);
481 }
482 }
483 RedrawTdgtList(pTdgtList->pti);
484
485 XGrabPointer(mainDisplay, pTdgtList->scr_win, False,
486 PointerMotionMask | ButtonReleaseMask, GrabModeAsync,
487 GrabModeAsync, None, handCursor, CurrentTime);
488
489 while (!done) {
490 XEvent ev;
491
492 XNextEvent(mainDisplay, &ev);
493
494 if (ev.type == Expose || ev.type == VisibilityNotify) {
495 ExposeEventHandler(&ev, TRUE);
496 } else if (ev.type == ButtonRelease) {
497 XUngrabPointer(mainDisplay, CurrentTime);
498 if (debugNoPointerGrab) XSync(mainDisplay, False);
499 done = TRUE;
500 } else if (ev.type == MotionNotify) {
501 int new_name_first=0, y=ev.xmotion.y;
502
503 if (threeDLook) {
504 y += btn_offset;
505 start_frac = (double)(((double)(y-scrollBarW)) /
506 ((double)(pTdgtList->scr_area_h-(scrollBarW<<1))));
507
508 if (y <= scrollBarW) {
509 new_name_first = 0;
510 } else if (y+block_h >= pTdgtList->scr_area_h-scrollBarW) {
511 new_name_first = length - num_visible_lines;
512 } else {
513 new_name_first = (int)(length * start_frac);
514 }
515 } else {
516 start_frac = (double)(((double)y) /
517 ((double)pTdgtList->scr_area_h));
518
519 if (y <= 0) {
520 new_name_first = 0;
521 } else if (y+block_h >= pTdgtList->scr_area_h) {
522 new_name_first = length - num_visible_lines;
523 } else {
524 new_name_first = (int)(length * start_frac);
525 }
526 }
527 if (pListInfo->first_index != new_name_first) {
528 pListInfo->first_index = new_name_first;
529 RedrawTdgtList(pTdgtList->pti);
530 }
531 while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ;
532 }
533 }
534 }
535
536 static
TdgtListScrollHandler(pTdgtList,button_ev)537 void TdgtListScrollHandler(pTdgtList, button_ev)
538 TdgtList *pTdgtList;
539 XButtonEvent *button_ev;
540 {
541 ListInfo *pListInfo=(&pTdgtList->list_info);
542 int length=ListLength(&pListInfo->list);
543 int do_drag=FALSE, btn_offset=0;
544
545 if (!threeDLook && button_ev->button == Button3 &&
546 button_ev->type == ButtonPress) {
547 if (DoTdgtListBtnScroll(pTdgtList,
548 ((button_ev->state & (ShiftMask|ControlMask)) != 0),
549 SCRL_UP, NULL)) {
550 return;
551 }
552 } else if (!threeDLook && button_ev->button == Button1 &&
553 button_ev->type == ButtonPress) {
554 if (DoTdgtListBtnScroll(pTdgtList,
555 ((button_ev->state & (ShiftMask|ControlMask)) != 0),
556 SCRL_DN, NULL)) {
557 return;
558 }
559 } else if (button_ev->button == Button1 && button_ev->type == ButtonPress) {
560 if (button_ev->y < scrollBarW ||
561 button_ev->y >= pTdgtList->scr_area_h-scrollBarW) {
562 int which=INVALID;
563 struct BBRec bbox;
564
565 if (button_ev->y < scrollBarW) {
566 which = SCRL_UP;
567 SetBBRec(&bbox, 0, 0, scrollBarW, scrollBarW);
568 } else {
569 which = SCRL_DN;
570 SetBBRec(&bbox, 0, pTdgtList->scr_area_h-scrollBarW, scrollBarW,
571 pTdgtList->scr_area_h);
572 }
573 if (DoTdgtListBtnScroll(pTdgtList, FALSE, which, &bbox)) {
574 return;
575 }
576 } else {
577 double start_frac=(double)0;
578 int hit=0;
579
580 start_frac = (length > 0) ?
581 (double)((double)(pListInfo->first_index) / (double)length) :
582 ((double)0.0);
583 hit = TgGetScrollHit(button_ev->x, button_ev->y, VERT_SCROLLBAR,
584 scrollBarW, pTdgtList->scr_area_h, start_frac,
585 pListInfo->num_visible_lines, length, &btn_offset);
586 if (hit == 0) {
587 do_drag = TRUE;
588 } else {
589 if (DoTdgtListBtnScroll(pTdgtList, TRUE,
590 (hit < 0 ? SCRL_UP : SCRL_DN), NULL)) {
591 return;
592 }
593 }
594 }
595 } else if (!threeDLook && button_ev->button == Button2 &&
596 button_ev->type == ButtonPress) {
597 do_drag = TRUE;
598 }
599 if (do_drag) {
600 DoDragInTdgtList(pTdgtList, button_ev, button_ev->y, btn_offset);
601 } else {
602 RedrawTdgtList(pTdgtList->pti);
603 }
604 }
605
606 static
TdgtListDspHandler(pTdgtList,button_ev)607 int TdgtListDspHandler(pTdgtList, button_ev)
608 TdgtList *pTdgtList;
609 XButtonEvent *button_ev;
610 {
611 if (enableMouseWheel &&
612 (button_ev->button == Button4 || button_ev->button == Button5)) {
613 int which=INVALID;
614 struct BBRec bbox;
615
616 if (button_ev->button == Button4) {
617 which = SCRL_UP;
618 SetBBRec(&bbox, 0, 0, scrollBarW, scrollBarW);
619 } else if (button_ev->button == Button5) {
620 which = SCRL_DN;
621 SetBBRec(&bbox, 0, pTdgtList->scr_area_h-scrollBarW, scrollBarW,
622 pTdgtList->scr_area_h);
623 }
624 if (which != INVALID) {
625 DoTdgtListBtnScroll(pTdgtList, FALSE, which, &bbox);
626 RedrawTdgtList(pTdgtList->pti);
627 }
628 return INVALID;
629 } else if (button_ev->button != Button1) {
630 return INVALID;
631 }
632 return INVALID;
633 }
634
635 static
TdgtListControlChar(pTdgtList,key_ev,key_sym)636 int TdgtListControlChar(pTdgtList, key_ev, key_sym)
637 TdgtList *pTdgtList;
638 XKeyEvent *key_ev;
639 KeySym key_sym;
640 {
641 ListInfo *pListInfo=(&pTdgtList->list_info);
642 int length=ListLength(&pListInfo->list);
643 int num_visible_lines=pListInfo->num_visible_lines;
644 int i=0;
645
646 if (key_ev->state & ControlMask) {
647 switch (key_sym) {
648 case XK_Left: return (BAD);
649 case XK_KP_Left: return (BAD);
650 case XK_Up: key_sym = ((unsigned long)'b')&0xff; break;
651 case XK_KP_Up: key_sym = ((unsigned long)'b')&0xff; break;
652 case XK_Right: return (BAD);
653 case XK_KP_Right: return (BAD);
654 case XK_Down: key_sym = ((unsigned long)'f')&0xff; break;
655 case XK_KP_Down: key_sym = ((unsigned long)'f')&0xff; break;
656 case XK_Page_Up: key_sym = ((unsigned long)'b')&0xff; break;
657 case XK_KP_Page_Up: key_sym = ((unsigned long)'b')&0xff; break;
658 case XK_Page_Down: key_sym = ((unsigned long)'f')&0xff; break;
659 case XK_KP_Page_Down: key_sym = ((unsigned long)'f')&0xff; break;
660 }
661 } else {
662 switch (key_sym) {
663 case XK_Left: return BAD;
664 case XK_KP_Left: return BAD;
665 case XK_Up: key_sym = ((unsigned long)'k')&0xff; break;
666 case XK_KP_Up: key_sym = ((unsigned long)'k')&0xff; break;
667 case XK_Right: return BAD;
668 case XK_KP_Right: return BAD;
669 case XK_Down: key_sym = ((unsigned long)'j')&0xff; break;
670 case XK_KP_Down: key_sym = ((unsigned long)'j')&0xff; break;
671 case XK_Page_Up: key_sym = ((unsigned long)'b')&0xff; break;
672 case XK_KP_Page_Up: key_sym = ((unsigned long)'b')&0xff; break;
673 case XK_Page_Down: key_sym = ((unsigned long)'f')&0xff; break;
674 case XK_KP_Page_Down: key_sym = ((unsigned long)'f')&0xff; break;
675 }
676 }
677 switch (key_sym&0xff) {
678 case 'w': /* erase */
679 case 'y':
680 return INVALID;
681 case 'n': /* down one */
682 case 'j':
683 if (pTdgtList->can_select) {
684 /*
685 * i = (pni->marked_index < length-1) ?
686 * pni->marked_index+1 : length-1;
687 */
688 } else {
689 if (length > num_visible_lines) {
690 if (pListInfo->first_index+num_visible_lines < length) {
691 pListInfo->first_index++;
692 }
693 }
694 }
695 break;
696 case 'p': /* up one */
697 case 'k':
698 if (pTdgtList->can_select) {
699 /*
700 * i = (pni->marked_index>0) ? pni->marked_index-1 : 0;
701 */
702 } else {
703 if (length > num_visible_lines) {
704 if (pListInfo->first_index > 0) {
705 pListInfo->first_index--;
706 }
707 }
708 }
709 break;
710 case 'd': /* down one page */
711 case 'f':
712 if (pTdgtList->can_select) {
713 /*
714 * if (pni->marked_index==INVALID) {
715 * i = (length <= num_visible_lines) ? length-1 :
716 * num_visible_lines;
717 * } else if (pni->marked_index < length-num_visible_lines) {
718 * i = pni->marked_index+num_visible_lines;
719 * } else {
720 * i = length-1;
721 * }
722 */
723 } else {
724 if (length > num_visible_lines) {
725 if (pListInfo->first_index+num_visible_lines < length) {
726 pListInfo->first_index += num_visible_lines;
727 if (pListInfo->first_index + num_visible_lines > length) {
728 pListInfo->first_index = length - num_visible_lines;
729 }
730 }
731 }
732 }
733 break;
734 case 'u': /* up one page */
735 case 'b':
736 if (pTdgtList->can_select) {
737 /*
738 * i = (pni->marked_index > (num_visible_lines-1)) ?
739 * pni->marked_index-num_visible_lines : 0;
740 */
741 } else {
742 pListInfo->first_index -= num_visible_lines;
743 if (pListInfo->first_index < 0) pListInfo->first_index = 0;
744 }
745 break;
746 default: return BAD;
747 }
748 return i;
749 }
750
751 static
SpecialKeyInTdgtList(pTdgtList,key_ev,key_sym,pn_changing,pn_selected_btn_index)752 void SpecialKeyInTdgtList(pTdgtList, key_ev, key_sym, pn_changing,
753 pn_selected_btn_index)
754 TdgtList *pTdgtList;
755 XKeyEvent *key_ev;
756 KeySym key_sym;
757 int *pn_changing, *pn_selected_btn_index;
758 {
759 ListInfo *pListInfo=(&pTdgtList->list_info);
760 int saved_first=pListInfo->first_index;
761 int saved_marked=pListInfo->marked_index;
762 int rc=TdgtListControlChar(pTdgtList, key_ev, key_sym);
763
764 if (rc == BAD || rc == INVALID) return;
765
766 if (saved_first != pListInfo->first_index ||
767 saved_marked != pListInfo->marked_index) {
768 RedrawTdgtList(pTdgtList->pti);
769 }
770 }
771
772 static XComposeStatus c_stat;
773
774 static
KeyPressInTdgtList(pTdgtList,key_ev,pn_changing,pn_selected_btn_index)775 int KeyPressInTdgtList(pTdgtList, key_ev, pn_changing, pn_selected_btn_index)
776 TdgtList *pTdgtList;
777 XKeyEvent *key_ev;
778 int *pn_changing, *pn_selected_btn_index;
779 {
780 ListInfo *pListInfo=(&pTdgtList->list_info);
781 int length=ListLength(&pListInfo->list);
782 char buf[80];
783 KeySym key_sym;
784 int has_ch=FALSE;
785
786 has_ch = XLookupString(key_ev, buf, sizeof(buf), &key_sym, &c_stat);
787 TranslateKeys(buf, &key_sym);
788
789 if ((key_ev->state & ControlMask) && key_sym == XK_j) {
790 SpecialKeyInTdgtList(pTdgtList, key_ev, key_sym, pn_changing,
791 pn_selected_btn_index);
792 } else if (CharIsCRorLF(key_ev, buf, key_sym, &has_ch)) {
793 if (pTdgtList->can_select) {
794 /*
795 * if (pni->def_btn_id != INVALID) {
796 * *pn_changing = FALSE;
797 * *pn_selected_btn_index = GetBtnIndexFromBtnId(pni->def_btn_id);
798 * }
799 */
800 } else {
801 return FALSE;
802 }
803 } else if (CharIsESC(key_ev, buf, key_sym, &has_ch)) {
804 if (pTdgtList->can_select) {
805 /*
806 * *pn_changing = FALSE;
807 * *pn_selected_btn_index = GetBtnIndexFromBtnId(BUTTON_CANCEL);
808 */
809 }
810 } else if (CharIsBSorDEL(key_ev, buf, key_sym, &has_ch, FALSE)) {
811 if (pTdgtList->can_select) {
812 /*
813 * if (pni->edit_style == NAMES_SELECT_FILE &&
814 * (pni->faking_dot_dot || pni->pop_from_root)) {
815 * *pn_changing = FALSE;
816 * *pn_selected_btn_index = INVALID;
817 * } else {
818 * BackSpaceInNames(pn_changing, pn_selected_btn_index);
819 * }
820 */
821 }
822 } else if (CharIsTAB(key_ev, buf, key_sym, &has_ch)) {
823 if (pTdgtList->can_select) {
824 /* should tab out of focus?! */
825 }
826 } else if (length != 0 && ((key_sym>'\040' && key_sym<='\177' &&
827 (key_ev->state & ControlMask)) || key_sym==XK_Up ||
828 key_sym==XK_Down || key_sym==XK_KP_Up || key_sym==XK_KP_Down ||
829 key_sym==XK_Page_Up || key_sym==XK_KP_Page_Up ||
830 key_sym==XK_Page_Down || key_sym==XK_KP_Page_Down)) {
831 SpecialKeyInTdgtList(pTdgtList, key_ev, key_sym, pn_changing,
832 pn_selected_btn_index);
833 } else if (key_sym>='\040' && key_sym<='\177' && length != 0) {
834 if (pTdgtList->can_select) {
835 /*
836 * CharInNames(buf, pn_changing, pn_selected_btn_index);
837 */
838 }
839 return FALSE;
840 }
841 return TRUE;
842 }
843
844 static
ButtonPressInTdgtList(pTdgtList,button_ev,pn_changing,pn_selected_btn_index)845 void ButtonPressInTdgtList(pTdgtList, button_ev, pn_changing,
846 pn_selected_btn_index)
847 TdgtList *pTdgtList;
848 XButtonEvent *button_ev;
849 int *pn_changing, *pn_selected_btn_index;
850 {
851 if (button_ev->window == pTdgtList->scr_win) {
852 TdgtListScrollHandler(pTdgtList, button_ev);
853 } else if (button_ev->window == pTdgtList->dsp_win) {
854 int double_clicked=(TdgtListDspHandler(pTdgtList, button_ev)!=INVALID);
855
856 if (double_clicked) {
857 /* do something here */
858 }
859 if (pTdgtList->can_select) {
860 /* do something here */
861 }
862 }
863 }
864
865 static
TdgtListEventHandler(pti,input,handling_pti)866 int TdgtListEventHandler(pti, input, handling_pti)
867 TidgetInfo *pti, *handling_pti;
868 XEvent *input;
869 {
870 TdgtList *pTdgtList=(TdgtList*)(pti->tidget);
871
872 if (pti != handling_pti) return FALSE;
873
874 if (input->type == Expose) {
875 RedrawTdgtList(pTdgtList->pti);
876 } else if (input->type == KeyPress) {
877 if (pTdgtList->can_select) {
878 /* KeyPressInTdgtList(pTdgtList, &changing, &selected_btn_index); */
879 } else {
880 return KeyPressInTdgtList(pTdgtList, &input->xkey, NULL, NULL);
881 }
882 } else if (input->type == ButtonPress) {
883 if (pTdgtList->can_select) {
884 /* ButtonPressInTdgtList(pTdgtList, &changing, &selected_btn_index); */
885 } else {
886 ButtonPressInTdgtList(pTdgtList, &input->xbutton, NULL, NULL);
887 }
888 }
889 return TRUE;
890 }
891
892 /* --------------------- IsTdgtListEvent() --------------------- */
893
894 static
IsTdgtListEvent(pti,input,ppti_handler_tidget_return)895 int IsTdgtListEvent(pti, input, ppti_handler_tidget_return)
896 TidgetInfo *pti, **ppti_handler_tidget_return;
897 XEvent *input;
898 {
899 TdgtList *pTdgtList=(TdgtList*)(pti->tidget);
900
901 if (input->xany.window == pTdgtList->pti->tci.win ||
902 input->xany.window == pTdgtList->dsp_win ||
903 input->xany.window == pTdgtList->scr_win) {
904 *ppti_handler_tidget_return = pti;
905 return TRUE;
906 }
907 return FALSE;
908 }
909
910 /* --------------------- DestroyTdgtList() --------------------- */
911
912 static
DestroyTdgtList(pti)913 void DestroyTdgtList(pti)
914 TidgetInfo *pti;
915 {
916 TdgtList *pTdgtList=(TdgtList*)(pti->tidget);
917
918 TdgtListReset(pTdgtList);
919
920 free(pTdgtList);
921 }
922
923 /* --------------------- MapTdgtList() --------------------- */
924
925 static
MapTdgtList(pti)926 void MapTdgtList(pti)
927 TidgetInfo *pti;
928 {
929 TdgtList *pTdgtList=(TdgtList*)(pti->tidget);
930
931 #ifdef MAPBEFORESELECT
932 XMapWindow(mainDisplay, pTdgtList->pti->tci.win);
933 XSelectInput(mainDisplay, pTdgtList->pti->tci.win, ExposureMask);
934
935 XMapWindow(mainDisplay, pTdgtList->dsp_win);
936 XSelectInput(mainDisplay, pTdgtList->dsp_win, KeyPressMask |
937 ButtonPressMask | ExposureMask);
938
939 XMapWindow(mainDisplay, pTdgtList->scr_win);
940 XSelectInput(mainDisplay, pTdgtList->scr_win, KeyPressMask |
941 ButtonPressMask | ExposureMask);
942 #else
943 XSelectInput(mainDisplay, pTdgtList->pti->tci.win, ExposureMask);
944 XMapWindow(mainDisplay, pTdgtList->pti->tci.win);
945
946 XSelectInput(mainDisplay, pTdgtList->dsp_win, KeyPressMask |
947 ButtonPressMask | ExposureMask);
948 XMapWindow(mainDisplay, pTdgtList->dsp_win);
949
950 XSelectInput(mainDisplay, pTdgtList->scr_win, KeyPressMask |
951 ButtonPressMask | ExposureMask);
952 XMapWindow(mainDisplay, pTdgtList->scr_win);
953 #endif
954 }
955
956 /* --------------------- TdgtListMoveResize() --------------------- */
957
958 static
TdgtListMoveResize(pti,x,y,w,h)959 void TdgtListMoveResize(pti, x, y, w, h)
960 TidgetInfo *pti;
961 int x, y, w, h;
962 {
963 TdgtList *pTdgtList=(TdgtList*)(pti->tidget);
964
965 pTdgtList->pti->tci.win_info.x = x;
966 pTdgtList->pti->tci.win_info.y = y;
967 pTdgtList->pti->tci.win_info.w = w;
968 pTdgtList->pti->tci.win_info.h = h;
969
970 pTdgtList->pti->tci.content_w =
971 w-(windowPadding<<1)-pTdgtList->pti->tci.h_pad;
972 pTdgtList->pti->tci.content_h =
973 h-(windowPadding<<1)-pTdgtList->pti->tci.v_pad;
974 XMoveResizeWindow(mainDisplay, pTdgtList->pti->tci.win, x, y, w, h);
975
976 pTdgtList->dsp_win_info.x = windowPadding;
977 pTdgtList->dsp_win_info.y = windowPadding;
978 pTdgtList->dsp_win_info.w = w-(windowPadding<<1)-scrollBarW;
979 pTdgtList->dsp_win_info.h = h-(windowPadding<<1);
980 XMoveResizeWindow(mainDisplay, pTdgtList->dsp_win, pTdgtList->dsp_win_info.x,
981 pTdgtList->dsp_win_info.y, pTdgtList->dsp_win_info.w,
982 pTdgtList->dsp_win_info.h);
983
984 pTdgtList->scr_win_info.x = w-windowPadding-scrollBarW;
985 pTdgtList->scr_win_info.y = windowPadding;
986 pTdgtList->scr_win_info.w = scrollBarW;
987 pTdgtList->scr_win_info.h = h-(windowPadding<<1);
988 XMoveResizeWindow(mainDisplay, pTdgtList->scr_win, pTdgtList->scr_win_info.x,
989 pTdgtList->scr_win_info.y, pTdgtList->scr_win_info.w,
990 pTdgtList->scr_win_info.h);
991 }
992
993 /* --------------------- TdgtListSendCmd() --------------------- */
994
995 static
TdgtListSendCmd(pti,cmd_type,cmd_arg,pv_cmd_userdata)996 int TdgtListSendCmd(pti, cmd_type, cmd_arg, pv_cmd_userdata)
997 TidgetInfo *pti;
998 int cmd_type, cmd_arg;
999 void *pv_cmd_userdata;
1000 {
1001 TdgtList *pTdgtList=(TdgtList*)(pti->tidget);
1002
1003 if (pTdgtList != NULL) {
1004 }
1005 return FALSE;
1006 }
1007
1008 /* --------------------- TdgtListReset() --------------------- */
1009
TdgtListReset(pTdgtList)1010 void TdgtListReset(pTdgtList)
1011 TdgtList *pTdgtList;
1012 {
1013 ListInfo *pListInfo=(&pTdgtList->list_info);
1014 CVListElem *pElem=NULL;
1015
1016 TdgtListCleanUpEntries(pTdgtList);
1017
1018 for (pElem=ListFirst(&pListInfo->list); pElem != NULL;
1019 pElem=ListNext(&pListInfo->list, pElem)) {
1020 ListItemInfo *pListItemInfo=(ListItemInfo*)(pElem->obj);
1021
1022 FreeListItemInfo(pListItemInfo);
1023 }
1024 ListUnlinkAll(&pListInfo->list);
1025 }
1026
1027 /* --------------------- CreateTdgtList() --------------------- */
1028
1029 static
TdgtListCalcHeight(num_visible_lines,pn_content_h)1030 void TdgtListCalcHeight(num_visible_lines, pn_content_h)
1031 int num_visible_lines, *pn_content_h;
1032 {
1033 int h=(num_visible_lines*ROW_HEIGHT);
1034
1035 if (pn_content_h != NULL) *pn_content_h = h;
1036 }
1037
CreateTdgtList(parent_win,parent_tidgetinfo,ctl_id,x,y,w,h_pad,v_pad,num_visible_lines,can_select,multicolor,auto_scroll_on_insert)1038 TdgtList *CreateTdgtList(parent_win, parent_tidgetinfo, ctl_id, x, y, w, h_pad,
1039 v_pad, num_visible_lines, can_select, multicolor, auto_scroll_on_insert)
1040 Window parent_win;
1041 TidgetInfo *parent_tidgetinfo;
1042 int ctl_id, x, y, w, h_pad, v_pad, num_visible_lines, auto_scroll_on_insert;
1043 {
1044 int bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel), h=0, content_h=0;
1045 TdgtList *pTdgtList=NULL;
1046
1047 TdgtListCalcHeight(num_visible_lines, &content_h);
1048
1049 h = content_h + (windowPadding<<1) + (v_pad<<1);
1050
1051 pTdgtList = (TdgtList*)malloc(sizeof(TdgtList));
1052 if (pTdgtList == NULL) FailAllocMessage();
1053 memset(pTdgtList, 0, sizeof(TdgtList));
1054
1055 pTdgtList->pti = NewTidgetInfo(parent_tidgetinfo, TIDGET_TYPE_LIST,
1056 pTdgtList, ctl_id, NULL);
1057 if ((pTdgtList->pti->tci.win=XCreateSimpleWindow(mainDisplay, parent_win,
1058 x, y, w, h, brdrW, myBorderPixel, bg_pixel)) == 0) {
1059 FailToCreateWindowMessage("CreateTdgtList()", NULL, TRUE);
1060 }
1061 XSelectInput(mainDisplay, pTdgtList->pti->tci.win, ExposureMask);
1062 SetTidgetInfoBasic(pTdgtList->pti, TIDGET_TYPE_LIST, pTdgtList, parent_win,
1063 x, y, w, h, h_pad, v_pad, TGBS_LOWRED, NULL);
1064 TidgetSetCallbacks(pTdgtList->pti,
1065 RedrawTdgtList, TdgtListEventHandler, IsTdgtListEvent, DestroyTdgtList,
1066 MapTdgtList, TdgtListMoveResize, TdgtListSendCmd);
1067
1068 CVListInit(&pTdgtList->list_info.list);
1069
1070 /* Note: scrollBarW accounts for windowPadding */
1071 if ((pTdgtList->dsp_win=XCreateSimpleWindow(mainDisplay,
1072 pTdgtList->pti->tci.win, windowPadding, windowPadding,
1073 w-(windowPadding<<1)-scrollBarW, h-(windowPadding<<1), brdrW,
1074 myBorderPixel, bg_pixel)) == 0) {
1075 FailToCreateWindowMessage("CreateTdgtList()", NULL, TRUE);
1076 }
1077 XSelectInput(mainDisplay, pTdgtList->dsp_win, KeyPressMask |
1078 ButtonPressMask | ExposureMask);
1079 pTdgtList->dsp_win_info.x = windowPadding;
1080 pTdgtList->dsp_win_info.y = windowPadding;
1081 pTdgtList->dsp_win_info.w = w-(windowPadding<<1)-scrollBarW;
1082 pTdgtList->dsp_win_info.h = h-(windowPadding<<1);
1083
1084 if ((pTdgtList->scr_win=XCreateSimpleWindow(mainDisplay,
1085 pTdgtList->pti->tci.win, w-windowPadding-scrollBarW, windowPadding,
1086 scrollBarW, h-(windowPadding<<1), brdrW, myBorderPixel, bg_pixel)) ==
1087 0) {
1088 FailToCreateWindowMessage("CreateTdgtList()", NULL, TRUE);
1089 }
1090 XSelectInput(mainDisplay, pTdgtList->scr_win, KeyPressMask |
1091 ButtonPressMask | ExposureMask);
1092 pTdgtList->scr_win_info.x = w-windowPadding-scrollBarW;
1093 pTdgtList->scr_win_info.y = windowPadding;
1094 pTdgtList->scr_win_info.w = scrollBarW;
1095 pTdgtList->scr_win_info.h = h-(windowPadding<<1);
1096
1097 pTdgtList->list_info.num_visible_lines = num_visible_lines;
1098 pTdgtList->can_select = can_select;
1099 pTdgtList->multicolor = (colorDisplay ? multicolor : FALSE);
1100 pTdgtList->auto_scroll_on_insert = auto_scroll_on_insert;
1101
1102 pTdgtList->scr_area_h = num_visible_lines*ROW_HEIGHT;
1103
1104 return pTdgtList;
1105 }
1106
1107 /* --------------------- TdgtListCleanUpEntries() --------------------- */
1108
TdgtListCleanUpEntries(pTdgtList)1109 int TdgtListCleanUpEntries(pTdgtList)
1110 TdgtList *pTdgtList;
1111 {
1112 ListInfo *pListInfo=(&pTdgtList->list_info);
1113 int length=ListLength(&pListInfo->list);
1114
1115 if (pListInfo->entries != NULL) {
1116 int i=0;
1117
1118 for (i=0; i < length; i++) {
1119 UtilFree(pListInfo->entries[i]);
1120 }
1121 free(pListInfo->entries);
1122 pListInfo->entries = NULL;
1123 }
1124 return TRUE;
1125 }
1126
1127 /* --------------------- TdgtListUpdateEntries() --------------------- */
1128
TdgtListUpdateEntries(pTdgtList)1129 int TdgtListUpdateEntries(pTdgtList)
1130 TdgtList *pTdgtList;
1131 {
1132 ListInfo *pListInfo=(&pTdgtList->list_info);
1133 CVListElem *pElem=NULL;
1134 int length=ListLength(&pListInfo->list), index=0;
1135
1136 if (pListInfo->entries != NULL) {
1137 TdgtListCleanUpEntries(pTdgtList);
1138 }
1139 pListInfo->entries = (char**)malloc(length*sizeof(char*));
1140 if (pListInfo->entries == NULL) FailAllocMessage();
1141 memset(pListInfo->entries, 0, length*sizeof(char*));
1142
1143 for (pElem=ListFirst(&pListInfo->list); pElem != NULL;
1144 pElem=ListNext(&pListInfo->list, pElem), index++) {
1145 ListItemInfo *pListItemInfo=(ListItemInfo*)(pElem->obj);
1146
1147 pListInfo->entries[index] = UtilStrDup(pListItemInfo->buf);
1148 if (pListInfo->entries[index] == NULL) FailAllocMessage();
1149 }
1150 return TRUE;
1151 }
1152
1153 /* --------------------- TdgtListScrollToBottom() --------------------- */
1154
TdgtListScrollToBottom(pTdgtList)1155 int TdgtListScrollToBottom(pTdgtList)
1156 TdgtList *pTdgtList;
1157 {
1158 ListInfo *pListInfo=(&pTdgtList->list_info);
1159 int length=ListLength(&pListInfo->list);
1160
1161 if (pListInfo->num_visible_lines < length) {
1162 pListInfo->first_index = length - pListInfo->num_visible_lines;
1163 } else {
1164 pListInfo->first_index = 0;
1165 }
1166 return TRUE;
1167 }
1168
1169 /* --------------------- TdgtListInsertString() --------------------- */
1170
TdgtListInsertString(pTdgtList,buf)1171 int TdgtListInsertString(pTdgtList, buf)
1172 TdgtList *pTdgtList;
1173 char *buf;
1174 {
1175 ListInfo *pListInfo=(&pTdgtList->list_info);
1176 ListItemInfo *pListItemInfo=(ListItemInfo*)malloc(sizeof(ListItemInfo));
1177
1178 if (pListItemInfo == NULL) FailAllocMessage();
1179 memset(pListItemInfo, 0, sizeof(ListItemInfo));
1180
1181 *pListItemInfo->nick_name = '\0';
1182 pListItemInfo->color_index = colorIndex;
1183 pListItemInfo->font_style = STYLE_NR;
1184 pListItemInfo->buf = UtilStrDup(buf);
1185 if (pListItemInfo->buf == NULL) FailAllocMessage();
1186
1187 TdgtListCleanUpEntries(pTdgtList);
1188 ListAppend(&pListInfo->list, pListItemInfo);
1189
1190 if (pTdgtList->auto_scroll_on_insert) {
1191 TdgtListScrollToBottom(pTdgtList);
1192 }
1193 TdgtListUpdateEntries(pTdgtList);
1194 RedrawTdgtList(pTdgtList->pti);
1195
1196 return TRUE;
1197 }
1198
TdgtListInsertListItemInfo(pTdgtList,pListItemInfo)1199 int TdgtListInsertListItemInfo(pTdgtList, pListItemInfo)
1200 TdgtList *pTdgtList;
1201 ListItemInfo *pListItemInfo;
1202 {
1203 ListInfo *pListInfo=(&pTdgtList->list_info);
1204
1205 TdgtListCleanUpEntries(pTdgtList);
1206 ListAppend(&pListInfo->list, pListItemInfo);
1207
1208 if (pTdgtList->auto_scroll_on_insert) {
1209 TdgtListScrollToBottom(pTdgtList);
1210 }
1211 TdgtListUpdateEntries(pTdgtList);
1212 RedrawTdgtList(pTdgtList->pti);
1213
1214 return TRUE;
1215 }
1216
TdgtListSetAutoScrollOnInsert(pTdgtList,auto_scroll_on_insert)1217 int TdgtListSetAutoScrollOnInsert(pTdgtList, auto_scroll_on_insert)
1218 TdgtList *pTdgtList;
1219 int auto_scroll_on_insert;
1220 {
1221 pTdgtList->auto_scroll_on_insert = auto_scroll_on_insert;
1222 return TRUE;
1223 }
1224
TdgtListGetAutoScrollOnInsert(pTdgtList)1225 int TdgtListGetAutoScrollOnInsert(pTdgtList)
1226 TdgtList *pTdgtList;
1227 {
1228 return pTdgtList->auto_scroll_on_insert;
1229 }
1230
1231 /* --------------------- Init & Clean Up --------------------- */
1232
InitTdgtList()1233 int InitTdgtList()
1234 {
1235 if (msgFontSet == NULL && msgFontPtr == NULL) {
1236 gnListFontHeight = defaultFontHeight;
1237 gnListFontWidth = defaultFontWidth;
1238 gnListFontAsc = defaultFontAsc;
1239 gnListFontDes = defaultFontDes;
1240 gnListFontPtr = defaultFontPtr;
1241 } else {
1242 gnListFontHeight = msgFontHeight;
1243 gnListFontWidth = msgFontWidth;
1244 gnListFontAsc = msgFontAsc;
1245 gnListFontDes = msgFontDes;
1246 gnListFontPtr = msgFontPtr;
1247 }
1248 return TRUE;
1249 }
1250
CleanUpTdgtList()1251 void CleanUpTdgtList()
1252 {
1253 gnListFontHeight = gnListFontWidth = gnListFontAsc = gnListFontDes = 0;
1254 gnListFontPtr = NULL;
1255 }
1256
1257