1 /* odlbox.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: odlbox.c
27 *
28 * Author: Patrick Durand
29 *
30 * Version Creation Date: 5/3/99
31 *
32 * $Revision: 6.4 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * $Log: odlbox.c,v $
39 * Revision 6.4 2008/04/29 13:43:50 kans
40 * fixes for warnings caught by mingw cross-compiler
41 *
42 * Revision 6.3 1999/06/07 15:41:31 durand
43 * add LOG line to keep track of the history
44 *
45 *
46 *
47 * ==========================================================================
48 */
49
50 #include <ncbi.h>
51 #include <vibrant.h>
52
53 #include <odlbox.h>
54
55 typedef struct rect4 {/*a new rect type for very big listbox*/
56 Int4 left;
57 Int4 top;
58 Int4 right;
59 Int4 bottom;
60 } RecT4, PNTR Rect4Ptr;
61
62 typedef struct lbvscroll {/*vertical Scroll Bar data*/
63 Int4 ScrollMax; /*Size of the vertical Scroll Bar*/
64 /*also equal number of data lines displayed within
65 the listbox*/
66 Int4 ScrollPos; /*Current position within the vertical Scroll Bar*/
67 Int4 ScrollPage; /*Page decal of the vertical Scroll Bar*/
68 Int4 nTotLines; /*total number of line*/
69 Int2 cxClient; /*size of the client lbox window*/
70 Int2 cyClient;
71 RecT rcP;
72 } LBVScroll, PNTR LBVScrollPtr;
73
74 typedef struct lbentrydata {/*data attached to each list box entry*/
75 Pointer pUserData; /*a 'stuff' provided by the user*/
76 RecT4 rc; /*the position of the entry*/
77 Boolean Selected; /*TRUE: item is selected*/
78 } LBEntryData, PNTR LBEntryDataPtr;
79
80 typedef struct mainlbdata { /*list box main data*/
81 WindoW Parent; /*parent of the list box*/
82 Int4 nEntry; /*number of entry in this list box*/
83 Int4 CurEntry;/*current selected entry (zero-based)*/
84 LBEntryDataPtr CurEntryData;
85 ValNodePtr LBData; /*private list box data ;
86 LBData->data.ptrvalue is of LBEntryDataPtr type*/
87 LBVScroll vscroll;/*Vertical scrollbar data*/
88 OwnerDrawLboxFunc MsgFunc;/*Message Loop provided by the user*/
89 FonT f; /*user Font*/
90 Int2 cxChar;
91 Int2 cyChar;
92 /*internal use only*/
93 ValNodePtr LBDataTmp;
94 Int4 decal;
95 } MainLBData, PNTR MainLBDataPtr;
96
97 /*******************************************************************************
98
99 Function : LBCleanupDataProc()
100
101 Purpose : List Box personnal CleanupExtraProc Callback
102
103 Parameters : g; handle of the dialog box
104 data; to erase
105
106 Return value : none
107
108 *******************************************************************************/
LBCleanupDataProc(GraphiC g,VoidPtr data)109 static void LBCleanupDataProc (GraphiC g, VoidPtr data)
110 {
111 MainLBDataPtr lbdata;
112 ValNodePtr vnp;
113
114 lbdata=(MainLBDataPtr)data;
115 if (lbdata==NULL) return;
116
117 /*delete list of user data*/
118 if (lbdata->nEntry>0){
119 for(vnp=lbdata->LBData ; vnp!=NULL ; vnp=vnp->next){
120 if (vnp->data.ptrvalue) MemFree(vnp->data.ptrvalue);
121 }
122 ValNodeFree(lbdata->LBData);
123 }
124
125 MemFree (lbdata);
126 }
127
128 /*******************************************************************************
129
130 Function : LB_calc_RCdraw()
131
132 Purpose : compute the RC of an entry to be drawn
133
134 Parameters : rc_entry; absolute position of an entry
135 decal; y decal to place rc_entry within the listbox panel
136
137 Return value : position of the entry within the listbox panel
138
139 *******************************************************************************/
LB_calc_RCdraw(RecT4 rc_entry,Int4 decal)140 static RecT LB_calc_RCdraw(RecT4 rc_entry,Int4 decal)
141 {
142 RecT rc;
143
144 rc.top=(Int2)(rc_entry.top-decal);
145 rc.bottom=(Int2)(rc_entry.bottom-decal);
146 rc.left=(Int2)rc_entry.left;
147 rc.right=(Int2)rc_entry.right;
148
149 return(rc);
150 }
151
152 /*****************************************************************************
153
154 Function: LB_ChangSel()
155
156 Purpose: manage ChangSelection
157
158 Parameters: p; panel handle (currently unused)
159 lbdata; list box data block
160 CurEntry,CurEntryData; new item selected
161
162 Return value: none
163
164 *****************************************************************************/
LB_ChangSel(WindoW p,MainLBDataPtr lbdata,Int4 CurEntry,LBEntryDataPtr CurEntryData,Boolean SendSelectMessage)165 static void LB_ChangSel(WindoW p,MainLBDataPtr lbdata,Int4 CurEntry,
166 LBEntryDataPtr CurEntryData,Boolean SendSelectMessage)
167 {
168 MIData mid;
169 Int4 decal=lbdata->vscroll.ScrollPos*stdLineHeight;
170 WindoW temport;
171
172 temport=SavePort(p);
173 Select(p);
174 mid.rcP=lbdata->vscroll.rcP;
175 mid.f=lbdata->f;
176 mid.cxChar=lbdata->cxChar;
177 mid.cyChar=lbdata->cyChar;
178 mid.Parent=lbdata->Parent;
179 InsetRect(&mid.rcP,2,4);
180 ClipRect(&mid.rcP);
181 /*deselect previous entry, if needed*/
182 if (lbdata->CurEntry!=(Int4)-1){
183 /*mid.rcP=lbdata->vscroll.rcP;*/
184 mid.Data=lbdata->CurEntryData->pUserData;
185 mid.rcItem=LB_calc_RCdraw(lbdata->CurEntryData->rc,decal);
186 mid.Selected=FALSE;
187 lbdata->CurEntryData->Selected=FALSE;
188 /*send message to draw an entry*/
189 (*lbdata->MsgFunc)((WindoW)p,ODLB_DrawItem,(Pointer)&mid);
190 }
191 /*select the new entry*/
192 lbdata->CurEntry=CurEntry;
193 lbdata->CurEntryData=CurEntryData;
194 /*mid.rcP=lbdata->vscroll.rcP;*/
195 mid.Data=CurEntryData->pUserData;
196 mid.rcItem=LB_calc_RCdraw(CurEntryData->rc,decal);
197 mid.Selected=TRUE;
198 CurEntryData->Selected=TRUE;
199 /*send message to draw an entry; then send a SelectItem msg*/
200 (*lbdata->MsgFunc)((WindoW)p,ODLB_DrawItem,(Pointer)&mid);
201 if (SendSelectMessage){
202 (*lbdata->MsgFunc)((WindoW)p,ODLB_SelectItem,(Pointer)&mid);
203 }
204 ResetClip();
205 RestorePort(temport);
206 }
207
208 /*****************************************************************************
209
210 Function: LB_OnClick()
211
212 Purpose: manage Mouse-Click
213
214 Parameters: p; list-box handle
215 pt; new mouse position
216
217 Return value: none
218
219 *****************************************************************************/
LB_OnClick(PaneL p,PoinT pt)220 static void LB_OnClick(PaneL p, PoinT pt)
221 {
222 Int4 limit,decal=0,i=1;
223 ValNodePtr vnp;
224 LBEntryDataPtr lbdp;
225 RecT rc;
226 MainLBDataPtr lbdata;
227 Boolean bFind=FALSE;
228
229 /*get some usefull data...*/
230 lbdata = (MainLBDataPtr) GetObjectExtra (p);
231 if (lbdata==NULL) return;
232
233 decal=lbdata->vscroll.ScrollPos*stdLineHeight;
234 limit=(Int4)lbdata->vscroll.rcP.top+decal;
235 /*find the first entry located at the top of the listbox*/
236 for(vnp=lbdata->LBData ; vnp != NULL ; vnp=vnp->next){
237 if (vnp->data.ptrvalue){
238 lbdp=(LBEntryDataPtr)vnp->data.ptrvalue;
239 if (lbdp->rc.bottom>limit){
240 rc=LB_calc_RCdraw(lbdp->rc,decal);
241 if (PtInRect(pt,&rc)){
242 bFind=TRUE;
243 break;
244 }
245 }
246 i++;
247 }
248 }
249
250 /*if item found in the listbox*/
251 if (bFind){
252 LB_ChangSel((WindoW)p, lbdata,i,lbdp,TRUE);
253 }
254 }
255
256 /*****************************************************************************
257
258 Function: UDV_ReleaseProc()
259
260 Purpose: manage Mouse-Release
261
262 Parameters: p; panel handle (currently unused)
263 pt; new position
264
265 Return value: none
266
267 *****************************************************************************/
LB_OnRelease(PaneL p,PoinT pt)268 static void LB_OnRelease(PaneL p, PoinT pt)
269 {
270 }
271
272 /*******************************************************************************
273
274 Function : LB_DrawEmpty()
275
276 Purpose : draw a emplty window
277
278 Parameters : rectangle to fill
279
280 Return value : none
281
282 *******************************************************************************/
LB_DrawEmpty(RecT rc)283 static void LB_DrawEmpty(RecT rc)
284 {
285 White();
286 PaintRect(&rc);
287 Black();
288 }
289
290 /*******************************************************************************
291
292 Function : LB_calc_decalRC()
293
294 Purpose : compute the y decal for LB entry RecT correct positionning on
295 the listbox panel
296
297 Parameters : lbdata; list of entries
298 ScrollPos; actual position of the Vscroll bar
299 vnp; first entry to draw in the panel
300 rcP; rc de la listbox
301
302 Return value : y decal value (pixel unit)
303
304 *******************************************************************************/
LB_calc_decalRC(ValNodePtr lbdata,Int4 ScrollPos,ValNodePtr PNTR vnp,RecT rcP)305 static Int4 LB_calc_decalRC(ValNodePtr lbdata,Int4 ScrollPos,
306 ValNodePtr PNTR vnp,RecT rcP)
307 {
308 Int4 decal,limit;
309 LBEntryDataPtr lbdp;
310
311 decal=ScrollPos*stdLineHeight;
312 limit=(Int4)rcP.top+decal;
313 /*find the first entry located at the top of the listbox*/
314 for(*vnp=lbdata ; *vnp != NULL ; *vnp=(*vnp)->next){
315 if ((*vnp)->data.ptrvalue){
316 lbdp=(LBEntryDataPtr)(*vnp)->data.ptrvalue;
317 if (lbdp->rc.bottom>limit){
318 break;
319 }
320 }
321 }
322
323 return(decal);
324 }
325
326
327 /*******************************************************************************
328
329 Function : LB_onDraw()
330
331 Purpose : draw the panel of the listbox ; if fact, call the User OnDraw
332 function
333
334 Parameters : handle of the panel
335
336 Return value : none
337
338 *******************************************************************************/
LB_onDraw(PaneL p)339 static void LB_onDraw(PaneL p)
340 {
341 Int4 decal=0;
342 ValNodePtr vnp,vnp2;
343 LBEntryDataPtr lbdp;
344 RecT rc,rcP;
345 MainLBDataPtr lbdata;
346 MIData mid;
347 WindoW temport;
348
349 /*get some usefull data...*/
350 lbdata = (MainLBDataPtr) GetObjectExtra (p);
351 if (lbdata==NULL) return;
352
353 temport=SavePort(ParentWindow(p));
354
355 Select (p);
356
357 /*restrict panel drawing area: 'add' little margins*/
358 ObjectRect(p,&rcP);
359 InsetRect(&rcP,2,4);
360 ClipRect(&rcP);
361
362
363 if (lbdata->LBData==NULL) {
364 LB_DrawEmpty(rcP);
365 ResetClip();
366 return;
367 }
368
369
370 decal=LB_calc_decalRC(lbdata->LBData,lbdata->vscroll.ScrollPos,&vnp,rcP);
371
372 if (vnp==NULL){
373 LB_DrawEmpty(rcP);
374 ResetClip();
375 return;
376 }
377
378 mid.rcP=lbdata->vscroll.rcP;
379 mid.f=lbdata->f;
380 mid.cxChar=lbdata->cxChar;
381 mid.cyChar=lbdata->cyChar;
382 mid.Parent=lbdata->Parent;
383
384 for(vnp2=vnp ; vnp2 != NULL ; vnp2=vnp2->next){
385 if (vnp2->data.ptrvalue){
386 lbdp=(LBEntryDataPtr)vnp2->data.ptrvalue;
387
388 rc=LB_calc_RCdraw(lbdp->rc,decal);
389
390 /*send message to draw an entry*/
391 mid.rcItem=rc;
392 mid.Data=lbdp->pUserData;
393 mid.Selected=lbdp->Selected;
394 (*lbdata->MsgFunc)((WindoW)p,ODLB_DrawItem,(Pointer)&mid);
395 /*end ?*/
396 if (rc.bottom >= rcP.bottom) break;
397 }
398 }
399
400 ResetClip();
401 RestorePort(temport);
402 }
403
404 /*******************************************************************************
405
406 Function : LB_onVScroll()
407
408 Purpose : Owner Draw list box Vertical Scroll Bar Callback
409
410 Parameters : sb; handle of the scroll
411 s; pane;
412 newval; new value of the thumb
413 oldval; old value of the thumb
414
415 Return value : none
416
417 *******************************************************************************/
LB_onVScroll(BaR sb,SlatE s,Int4 newval,Int4 oldval)418 static void LB_onVScroll (BaR sb, SlatE s, Int4 newval,
419 Int4 oldval)
420 {
421 RecT rcP;
422 WindoW temport;
423 Int4 n;
424 Boolean IsGoUp=FALSE;
425 MainLBDataPtr lbdata;
426
427 /*get some usefull data...*/
428 lbdata = (MainLBDataPtr) GetObjectExtra (s);
429 if (lbdata==NULL) return;
430
431 lbdata->vscroll.ScrollPos=newval;
432
433 temport=SavePort((WindoW)s);
434 Select(s);
435 ObjectRect((PaneL)s,&rcP);
436 InsetRect(&rcP,2,4);
437 ClipRect(&rcP);
438
439 if (oldval>newval){
440 n=oldval-newval;
441 IsGoUp=TRUE;
442 }
443 else {
444 n=newval-oldval;
445 IsGoUp=FALSE;
446 }
447
448 if (n<lbdata->vscroll.ScrollPage){/*Line UP/Down*/
449 /*move and redraw*/
450 ScrollRect (&rcP, 0, (Int2)((oldval-newval)*stdLineHeight));
451 }
452 else{/*Page Up/Down*/
453 /*redraw*/
454 /*rcP.left=0;
455 rcP.top=0;*/
456 InvalRect(&rcP);
457 }
458 ResetClip();
459 RestorePort(temport);
460 /*Update ();*/
461 }
462
463 /*******************************************************************************
464
465 Function : OwnerDrawLbox_VScrlUpdatePage()
466
467 Purpose : compute PageUp & Down (VScroll)
468
469 Parameters : PageUpDn; initialize here
470 cyClient; height of UnDviewer panel
471
472 Return value : none
473
474 *******************************************************************************/
OwnerDrawLbox_VScrlUpdatePage(Int4Ptr PageUpDn,Int2 cyClient)475 static void OwnerDrawLbox_VScrlUpdatePage(Int4Ptr PageUpDn,
476 Int2 cyClient)
477 {
478 *PageUpDn=(Int4)(cyClient/stdLineHeight);
479 }
480
481 /*******************************************************************************
482
483 Function : OwnerDrawLbox_VScrlUpdate()
484
485 Purpose : update the UnDviewer VScroll bar
486
487 Parameters : p; handel of the UnDviewer panel
488 bInit; TRUE only when the UnDviewer is created (soft. start up)
489 CurPos ; new position
490
491 Return value : none
492
493 *******************************************************************************/
OwnerDrawLbox_VScrlUpdate(PaneL p,Boolean bInit,Int4 CurPos)494 static void OwnerDrawLbox_VScrlUpdate(PaneL p,
495 Boolean bInit,Int4 CurPos)
496 {
497 MainLBDataPtr lbdata;
498 BaR vsb;
499
500 if (p==NULL) return;
501
502 /*get some usefull data...*/
503 lbdata = (MainLBDataPtr) GetObjectExtra (p);
504 if (lbdata==NULL) return;
505
506 /*current scroll status*/
507 vsb = GetSlateVScrollBar ((SlatE) p);
508
509 if (bInit) CurPos=0;
510
511 /*given curpos (lineNumber) retrieve letter number*/
512 /*compute new values*/
513 OwnerDrawLbox_VScrlUpdatePage(&(lbdata->vscroll.ScrollPage),
514 lbdata->vscroll.cyClient);
515
516 if (lbdata->vscroll.nTotLines>lbdata->vscroll.ScrollPage){
517 lbdata->vscroll.ScrollMax=lbdata->vscroll.nTotLines-
518 lbdata->vscroll.ScrollPage;
519 }
520 else{
521 lbdata->vscroll.ScrollMax=0;
522 lbdata->vscroll.ScrollPos=0;
523 lbdata->vscroll.ScrollPage=0;
524 }
525
526 if (CurPos<0) CurPos=0;
527
528 if (CurPos>=lbdata->vscroll.ScrollMax)
529 lbdata->vscroll.ScrollPos=lbdata->vscroll.ScrollMax;
530 else lbdata->vscroll.ScrollPos=CurPos;
531
532 /*update scroll*/
533 CorrectBarMax(vsb,lbdata->vscroll.ScrollMax);
534 CorrectBarValue(vsb,lbdata->vscroll.ScrollPos);
535 CorrectBarPage(vsb,lbdata->vscroll.ScrollPage,
536 lbdata->vscroll.ScrollPage);
537 }
538
539
540 /*******************************************************************************
541
542 Function : OwnerDrawLbox_ResetLBContent()
543
544 Purpose : delete actual data of the list box
545
546 Parameters : lbox; handle of the list box
547
548 Return value : none
549
550 *******************************************************************************/
OwnerDrawLbox_ResetLBContent(WindoW lbox)551 NLM_EXTERN void OwnerDrawLbox_ResetLBContent(WindoW lbox)
552 {
553 MainLBDataPtr lbdata;
554 ValNodePtr vnp;
555 WindoW temport;
556 BaR vsb;
557
558 lbdata=(MainLBDataPtr)GetObjectExtra (lbox);
559 if (lbdata==NULL) return;
560
561 /*delete list of user data*/
562 if (lbdata->nEntry>0){
563 for(vnp=lbdata->LBData ; vnp!=NULL ; vnp=vnp->next){
564 if (vnp->data.ptrvalue) MemFree(vnp->data.ptrvalue);
565 }
566 ValNodeFree(lbdata->LBData);
567 lbdata->LBData=NULL;
568 }
569 /*init lbox internal data*/
570 lbdata->nEntry=0;
571 lbdata->CurEntry=-1;
572 lbdata->CurEntryData=NULL;
573 lbdata->vscroll.ScrollMax=0;
574 lbdata->vscroll.ScrollPos=0;
575 lbdata->vscroll.ScrollPage=0;
576 lbdata->vscroll.nTotLines=0;
577 lbdata->LBDataTmp=NULL;
578 lbdata->decal=0;
579
580 /*reinit scrollbar and redraw an empty listbox*/
581 vsb = GetSlateVScrollBar ((SlatE)lbox);
582 CorrectBarMax(vsb,0);
583 CorrectBarValue(vsb,0);
584 CorrectBarPage(vsb,0,0);
585 temport=SavePort(lbox);
586 Select(lbox);
587 InvalRect(&lbdata->vscroll.rcP);
588 RestorePort(temport);
589 }
590
591 /*******************************************************************************
592
593 Function : OwnerDrawLbox_GetCurData()
594
595 Purpose : retrieve the current data of the selected item in an owner
596 draw listbox
597
598 Parameters : lbox; handle of the list box
599
600 Return value : current item data
601
602 *******************************************************************************/
OwnerDrawLbox_GetCurData(WindoW lbox)603 NLM_EXTERN Pointer OwnerDrawLbox_GetCurData(WindoW lbox)
604 {
605 MainLBDataPtr lbdata;
606
607 /*retrieve lbox data*/
608 lbdata = (MainLBDataPtr) GetObjectExtra (lbox);
609 if (lbdata == NULL) return(NULL);/*oups*/
610
611 return(lbdata->CurEntryData->pUserData);
612 }
613
614 /*******************************************************************************
615
616 Function : OwnerDrawLbox_GetData()
617
618 Purpose : retrieve the current data of the selected item in an owner
619 draw listbox
620
621 Parameters : lbox; handle of the list box
622 item; data to retrieve (one based value)
623
624 Return value : current item data
625
626 *******************************************************************************/
OwnerDrawLbox_GetData(WindoW lbox,Int4 item)627 NLM_EXTERN Pointer OwnerDrawLbox_GetData(WindoW lbox,Int4 item)
628 {
629 MainLBDataPtr lbdata;
630 ValNodePtr vnp;
631 Int4 i=1;
632 Boolean bFound=FALSE;
633
634 /*retrieve lbox data*/
635 lbdata = (MainLBDataPtr) GetObjectExtra (lbox);
636 if (lbdata == NULL) return(NULL);/*oups*/
637
638 /*scan list of user data*/
639 if (lbdata->nEntry>0){
640 for(vnp=lbdata->LBData ; vnp!=NULL ; vnp=vnp->next){
641 if (i==item) {
642 bFound=TRUE;
643 break;
644 }
645 i++;
646 }
647 }
648
649 if (!bFound) return(NULL);
650
651 return((Pointer)vnp->data.ptrvalue);
652 }
653
654 /*******************************************************************************
655
656 Function : OwnerDrawLbox_GetNentry()
657
658 Purpose : retrieve the number of entries of aa owner draw listbox
659
660 Parameters : lbox; handle of the list box
661
662 Return value : current item data
663
664 *******************************************************************************/
OwnerDrawLbox_GetNentry(WindoW lbox)665 NLM_EXTERN Int4 OwnerDrawLbox_GetNentry(WindoW lbox)
666 {
667 MainLBDataPtr lbdata;
668
669 /*retrieve lbox data*/
670 lbdata = (MainLBDataPtr) GetObjectExtra (lbox);
671 if (lbdata == NULL) return(0);/*oups*/
672
673 return(lbdata->nEntry);
674 }
675
676 /*******************************************************************************
677
678 Function : OwnerDrawLbox_GetCurSel()
679
680 Purpose : retrieve the current selected item in an owner draw listbox
681
682 Parameters : lbox; handle of the list box
683
684 Return value : current item selected in the list box (Zero-based value)
685
686 *******************************************************************************/
OwnerDrawLbox_GetCurSel(WindoW lbox)687 NLM_EXTERN Int4 OwnerDrawLbox_GetCurSel(WindoW lbox)
688 {
689 MainLBDataPtr lbdata;
690
691 /*retrieve lbox data*/
692 lbdata = (MainLBDataPtr) GetObjectExtra (lbox);
693 if (lbdata == NULL) return((Int4)-1);/*oups*/
694
695 return(lbdata->CurEntry);
696 }
697
698 /*******************************************************************************
699
700 Function : OwnerDrawLbox_SelectItem()
701
702 Purpose : select an item in an owner draw listbox
703
704 Parameters : lbox; handle of the list box
705 item; item to select (One-based value)
706
707 Return value : none
708
709 *******************************************************************************/
OwnerDrawLbox_SelectItem(WindoW lbox,Int4 item)710 NLM_EXTERN void OwnerDrawLbox_SelectItem(WindoW lbox,Int4 item)
711 {
712 MainLBDataPtr lbdata;
713 ValNodePtr vnp;
714 Int4 i=1,decal,NewPos;
715 Boolean bFound=FALSE;
716 LBEntryDataPtr lbdp;
717 RecT rc;
718
719 /*retrieve lbox data*/
720 lbdata = (MainLBDataPtr) GetObjectExtra (lbox);
721 if (lbdata == NULL) return;/*oups*/
722
723 /*scan list of user data*/
724 if (lbdata->nEntry>0){
725 for(vnp=lbdata->LBData ; vnp!=NULL ; vnp=vnp->next){
726 if (i==item) {
727 bFound=TRUE;
728 break;
729 }
730 i++;
731 }
732 }
733
734 if (!bFound) return;
735 lbdp=(LBEntryDataPtr)vnp->data.ptrvalue;
736 /*scroll*/
737 decal=lbdata->vscroll.ScrollPos*stdLineHeight;
738 rc=LB_calc_RCdraw(lbdp->rc,decal);
739 if (!RectInRect(&rc,&lbdata->vscroll.rcP)){
740 WindoW temport;
741 NewPos=(lbdp->rc.top-lbdata->vscroll.rcP.top)/stdLineHeight;
742 OwnerDrawLbox_VScrlUpdate((PaneL)lbox,FALSE,NewPos);
743 temport=SavePort(lbox);
744 Select(lbox);
745 InvalRect(&lbdata->vscroll.rcP);
746 RestorePort(temport);
747 }
748 LB_ChangSel(lbox,lbdata,item,lbdp,FALSE);
749 }
750
751 /*******************************************************************************
752
753 Function : OwnerDrawLbox_AddItem()
754
755 Purpose : add a user item to an owner draw listbox
756
757 Parameters : lbox; handle of the list box
758 item; data to add to the list
759
760 Return value : TRUE if success, FALSE if any errors
761
762 *******************************************************************************/
OwnerDrawLbox_AddItem(WindoW lbox,Pointer item)763 NLM_EXTERN Boolean OwnerDrawLbox_AddItem(WindoW lbox,Pointer item)
764 {
765 MainLBDataPtr lbdata;
766 LBEntryDataPtr lbdp;
767 MIData mid;
768
769 /*retrieve lbox data*/
770 lbdata = (MainLBDataPtr) GetObjectExtra (lbox);
771 if (lbdata == NULL) return(FALSE);/*oups*/
772
773 /*ask the user for the item size*/
774 MemSet(&mid.rcItem,0,sizeof(RecT));
775 mid.Data=item;
776 mid.rcP=lbdata->vscroll.rcP;
777 mid.Selected=FALSE;
778 mid.f=lbdata->f;
779 mid.cxChar=lbdata->cxChar;
780 mid.cyChar=lbdata->cyChar;
781 mid.Parent=lbdata->Parent;
782 if (!(*lbdata->MsgFunc)(lbox,ODLB_MeasureItem,(Pointer)&mid)) {
783 /*if message isn't managed by the user, compute a default size*/
784 mid.rcItem.left=lbdata->vscroll.rcP.left;
785 mid.rcItem.top=0;
786 mid.rcItem.right=lbdata->vscroll.rcP.right;
787 mid.rcItem.bottom=stdLineHeight;
788 }
789
790 /*create new data block for the user data*/
791 lbdp=(LBEntryDataPtr)MemNew(sizeof(LBEntryData));
792 if (lbdp==NULL) return(FALSE);/*oups II, the return*/
793 MemSet(lbdp,0,sizeof(LBEntryData));
794 lbdp->pUserData=item;
795
796 /*add the item to the ValNodeList*/
797 if (lbdata->nEntry==0){
798 lbdata->LBData=ValNodeAddPointer(NULL,0,(VoidPtr)lbdp);
799 if (lbdata->LBData==NULL) {
800 MemFree(lbdp);
801 return(FALSE);/*oups III, the ultimate adventure*/
802 }
803 lbdata->LBDataTmp=lbdata->LBData;
804 /*position of the new element*/
805 lbdp->rc.left=(Int4)mid.rcItem.left;
806 lbdp->rc.right=(Int4)mid.rcItem.right;
807 lbdp->rc.top=(Int4)(mid.rcItem.top+lbdata->vscroll.rcP.top);
808 lbdp->rc.bottom=(Int4)(lbdp->rc.top+mid.rcItem.bottom);
809 }
810 else{
811 lbdata->LBDataTmp=ValNodeAddPointer(&lbdata->LBDataTmp,0,(VoidPtr)lbdp);
812 if (!lbdata->LBDataTmp){
813 MemFree(lbdp);
814 return(FALSE); /*oups IV, the resurrection*/
815 }
816 /*compute correct pos for the new item*/
817 lbdp->rc.left=(Int4)mid.rcItem.left;
818 lbdp->rc.right=(Int4)mid.rcItem.right;
819 lbdp->rc.top=(Int4)(mid.rcItem.top+lbdata->decal);
820 lbdp->rc.bottom=(Int4)(lbdp->rc.top+mid.rcItem.bottom);
821 }
822 /*decal in the list box*/
823 lbdata->decal=lbdp->rc.bottom+1;
824
825 /*ok*/
826 lbdata->nEntry++;
827
828 /*update the scroll, but do not move it; stay on pos 0*/
829 lbdata->vscroll.nTotLines=lbdata->decal/stdLineHeight+1;
830 OwnerDrawLbox_VScrlUpdate((PaneL)lbox,TRUE,0);
831
832 /*ask the user to draw, only if needed*/
833 /* if (lbdp->rc.bottom<=(Int4)lbdata->vscroll.rcP.bottom){
834 mid.rcItem.top=(Int2)lbdp->rc.top;
835 mid.rcItem.bottom=(Int2)lbdp->rc.bottom;
836 mid.Data=item;
837 mid.rcP=lbdata->vscroll.rcP;
838 mid.f=lbdata->f;
839 mid.cxChar=lbdata->cxChar;
840 mid.cyChar=lbdata->cyChar;
841 (*lbdata->MsgFunc)(lbox,ODLB_DrawItem,(Pointer)&mid);
842 }*/
843
844 return(TRUE);
845 }
846
847 /*******************************************************************************
848
849 Function : OwnerDrawLbox_MoveWindow()
850
851 Purpose : move/resize an owner draw listbox
852
853 Parameters : lbox ; do you think it's what ?
854 x ; pos on x
855 y ; pos on y
856 cx ; width of the ListBox
857 cy ; height of the ListBox
858
859 Return value : -
860
861 *******************************************************************************/
OwnerDrawLbox_MoveWindow(WindoW lbox,Int2 x,Int2 y,Int2 cx,Int2 cy)862 NLM_EXTERN void OwnerDrawLbox_MoveWindow(WindoW lbox,
863 Int2 x,Int2 y, Int2 cx,Int2 cy)
864 {
865 MainLBDataPtr lbdata;
866 LBEntryDataPtr lbdp;
867 MIData mid;
868 ValNodePtr vnp;
869 RecT rcP;
870
871 Int4 oldDecal,oldCurPos = 0;
872 Boolean bFirst=TRUE,bFirst2=FALSE;
873
874 /*retrieve lbox data*/
875 lbdata = (MainLBDataPtr) GetObjectExtra (lbox);
876 if (lbdata == NULL) return;
877
878 /*compute new listbox size*/
879 Select(lbox);
880 rcP.left=x;
881 rcP.top=y;
882 rcP.right=x+cx;
883 rcP.bottom=y+cy;
884 lbdata->vscroll.rcP=rcP;
885 lbdata->vscroll.rcP.right-=3*lbdata->cxChar;
886 lbdata->vscroll.rcP.top+=1;
887 lbdata->vscroll.cxClient=cx;
888 lbdata->vscroll.cyClient=cy;
889 mid.rcP=lbdata->vscroll.rcP;
890 mid.f=lbdata->f;
891 mid.cxChar=lbdata->cxChar;
892 mid.cyChar=lbdata->cyChar;
893 mid.Parent=lbdata->Parent;
894 oldDecal=lbdata->vscroll.ScrollPos*stdLineHeight;
895 lbdata->decal=lbdata->vscroll.rcP.top;
896 /*resize all the items*/
897 for(vnp=lbdata->LBData ; vnp!=NULL ; vnp=vnp->next){
898 lbdp=(LBEntryDataPtr)vnp->data.ptrvalue;
899 if (lbdp){
900 if (bFirst){/*retrieve the first displayed item of the list*/
901 if ((lbdp->rc.top-lbdata->vscroll.rcP.top)>=oldDecal){
902 bFirst2=TRUE;
903 bFirst=FALSE;
904 }
905 }
906 mid.Data=lbdp->pUserData;
907 if (!(*lbdata->MsgFunc)(lbox,ODLB_MeasureItem,(Pointer)&mid)) {
908 /*if message isn't managed by the user, compute a default size*/
909 mid.rcItem.left=lbdata->vscroll.rcP.left;
910 mid.rcItem.top=0;
911 mid.rcItem.right=lbdata->vscroll.rcP.right;
912 mid.rcItem.bottom=stdLineHeight;
913 }
914 /*compute correct pos for the new item*/
915 lbdp->rc.left=(Int4)mid.rcItem.left;
916 lbdp->rc.right=(Int4)mid.rcItem.right;
917 lbdp->rc.top=(Int4)(mid.rcItem.top+lbdata->decal);
918 lbdp->rc.bottom=(Int4)(lbdp->rc.top+mid.rcItem.bottom);
919 if (bFirst2){/*compute oldCurPos*/
920 oldCurPos=(lbdp->rc.top-lbdata->vscroll.rcP.top)/stdLineHeight;
921 bFirst2=FALSE;
922 }
923 /*decal in the list box*/
924 lbdata->decal=lbdp->rc.bottom+1;
925 }
926 }
927
928 /*update the scroll*/
929 lbdata->vscroll.nTotLines=lbdata->decal/stdLineHeight+1;
930 OwnerDrawLbox_VScrlUpdate((PaneL)lbox,FALSE,oldCurPos);
931
932 /*move/resize and redraw window*/
933 SetPosition(lbox, &rcP);
934 AdjustPrnt(lbox, &rcP, FALSE);
935 }
936
937 /*******************************************************************************
938
939 Function : OwnerDrawLbox_Create()
940
941 Purpose : Create an owner draw listbox
942
943 Parameters : Parent ; handle of the parent window for the listbox
944 x ; pos on x
945 y ; pos on y
946 cx ; width of the ListBox
947 cy ; height of the ListBox
948 MsgFunc ; Message loop of the ListBox
949
950 Return value : WindoW if success, NULL if any errors
951
952 *******************************************************************************/
OwnerDrawLbox_Create(WindoW Parent,Int2 x,Int2 y,Int2 cx,Int2 cy,OwnerDrawLboxFunc MsgFunc,FonT f,Int2 cxChar,Int2 cyChar)953 NLM_EXTERN WindoW OwnerDrawLbox_Create(WindoW Parent,
954 Int2 x,Int2 y, Int2 cx,Int2 cy, OwnerDrawLboxFunc MsgFunc,FonT f,
955 Int2 cxChar,Int2 cyChar)
956 {
957 MainLBDataPtr lbdata;
958 PaneL p;
959 RecT rcP;
960
961 /*create the listbox as an AutonomousPanel4*/
962 p=AutonomousPanel4(Parent,10,10,LB_onDraw,
963 LB_onVScroll,NULL,0,NULL,NULL);
964 /*create mouse action for the listbox*/
965 SetPanelClick(p,LB_OnClick,NULL,NULL,LB_OnRelease);
966
967 if (p==NULL) return(NULL);/*isn't it !*/
968
969 /*use x,y,cx,cy provided by the user*/
970 Select(p);
971 rcP.left=x;
972 rcP.top=y;
973 rcP.right=x+cx;
974 rcP.bottom=y+cy;
975 SetPosition(p, &rcP);
976 AdjustPrnt(p, &rcP, FALSE);
977
978 /*Allocate the data structure and attach it to the list box*/
979 lbdata=(MainLBDataPtr)MemNew(sizeof(MainLBData));
980 if (lbdata==NULL) {
981 Remove(p);
982 return(NULL);
983 }
984 MemSet(lbdata,0,sizeof(MainLBData));
985 lbdata->CurEntry=-1;
986 lbdata->Parent=Parent;
987 lbdata->MsgFunc=(OwnerDrawLboxFunc)MsgFunc;
988 lbdata->vscroll.cxClient=cx;
989 lbdata->vscroll.cyClient=cy;
990 rcP.top+=1;
991 rcP.right-=3*cxChar;
992 lbdata->vscroll.rcP=rcP;
993 lbdata->f=f;
994 lbdata->cxChar=cxChar;
995 lbdata->cyChar=cyChar;
996 SetObjectExtra (p, (Pointer) lbdata, LBCleanupDataProc);
997
998 /*yes !*/
999 return((WindoW)p);
1000 }
1001
1002