1 /*   udvgraph.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:  udvgraph.c
27 *
28 * Author:  Patrick Durand
29 *
30 * Version Creation Date:   5/3/99
31 *
32 * $Revision: 6.50 $
33 *
34 * File Description: mouse management, graphic engine of the sequence viewer
35 *                   part of this code is also used for the WWW Entrez viewer
36 *                   (WWW_UDV define)
37 * Modifications:
38 * --------------------------------------------------------------------------
39 * $Log: udvgraph.c,v $
40 * Revision 6.50  2006/07/13 17:13:18  bollin
41 * use Uint4 instead of Uint2 for itemID values
42 *
43 * Revision 6.49  2002/08/23 18:47:52  kans
44 * protect against dereferencing NULL prot
45 *
46 * Revision 6.48  2000/06/27 20:46:38  hurwitz
47 * fixed bugs with select rectangle, added select row option
48 *
49 * Revision 6.47  2000/04/13 13:58:02  durand
50 * allowed udv to display reverse complement sequence
51 *
52 * Revision 6.46  2000/04/11 11:52:10  durand
53 * added code to load editor after a double-click
54 *
55 * Revision 6.45  2000/04/05 20:52:35  hurwitz
56 * added GUI control for shifting left and right alignment boundaries
57 *
58 * Revision 6.44  2000/04/05 12:02:55  durand
59 * minor changes in the drawing of graphic elements
60 *
61 * Revision 6.43  2000/04/03 22:26:31  hurwitz
62 * can now shift a row with click and drag
63 *
64 * Revision 6.42  2000/03/28 21:03:14  hurwitz
65 * added gui control to re-order rows
66 *
67 * Revision 6.41  2000/03/06 14:56:38  durand
68 * fixed problems with mouse selection between udv and cn3d
69 *
70 * Revision 6.40  2000/03/06 14:00:48  durand
71 * first release of the Summary viewer done
72 *
73 * Revision 6.39  2000/03/01 20:22:57  durand
74 * update deselect/select code to allow UDV sending correct message to Cn3D
75 *
76 * Revision 6.38  2000/02/28 19:17:24  lewisg
77 * eliminate mouseup message for feature selection
78 *
79 * Revision 6.37  2000/02/16 22:38:30  durand
80 * fixed some wierd behaviours of features selections
81 *
82 * Revision 6.36  2000/02/15 22:40:58  lewisg
83 * add ability to launch udv so that it colors by row, fixes to colormgr, track rows from viewmgr, fix visual c projects
84 *
85 * Revision 6.35  2000/02/11 15:40:28  durand
86 * replaced ObjMgrSendMsg by ObjMgrSelect calls for features selection
87 *
88 * Revision 6.34  2000/02/08 20:41:19  durand
89 * create the image map for a sequence without feature
90 *
91 * Revision 6.33  2000/01/08 00:47:54  lewisg
92 * fixes to selection, update, color
93 *
94 * Revision 6.32  2000/01/05 21:06:36  durand
95 * update mouse click actions and DrawSequence function for a better use from ddv and cn3d
96 *
97 * Revision 6.31  1999/12/29 22:55:03  lewisg
98 * get rid of seqalign id
99 *
100 * Revision 6.30  1999/12/15 23:17:47  lewisg
101 * make cn3d launch udv, fix launching of non-autonomous udv, add mouseup message
102 *
103 * Revision 6.29  1999/12/02 13:48:16  durand
104 * fix a bug for Entrez sequence viewer
105 *
106 * Revision 6.28  1999/11/29 15:17:54  durand
107 * designed a new GUI; fixed problems under Win95 and Linux
108 *
109 * Revision 6.27  1999/11/19 15:01:48  durand
110 * speed up mouse selection ; avoid sequence flashing during selection ; update menu functionalities
111 *
112 * Revision 6.26  1999/11/18 14:54:22  durand
113 * add a new function to create an image map given a ParaG structure - Entrez sequence viewer only
114 *
115 * Revision 6.25  1999/11/09 23:26:25  kans
116 * include jzmisc.h for swap prototype
117 *
118 * Revision 6.24  1999/11/09 21:06:58  durand
119 * add sequence selection manager
120 *
121 * Revision 6.23  1999/11/05 14:54:27  durand
122 * update logo position
123 *
124 * Revision 6.22  1999/11/02 13:38:18  durand
125 * update selection code for Entrez sequence viewer
126 *
127 * Revision 6.21  1999/10/14 16:14:25  kans
128 * added include for asn2ff6.h for GetProductSeqId and GetGINumFromSip
129 *
130 * Revision 6.20  1999/10/14 13:34:33  durand
131 * use BioseqFind to get product (CDS display)
132 *
133 * Revision 6.19  1999/10/13 17:08:17  durand
134 * use smaller font for WWW release of the viewer
135 *
136 * Revision 6.18  1999/10/02 15:11:15  durand
137 * update the code to be used by wwwudv
138 *
139 * Revision 6.17  1999/09/29 20:09:51  durand
140 * modify some parts of the code to be used by the cgi-bin release of UDV
141 *
142 * Revision 6.16  1999/09/27 14:10:31  durand
143 * switch to ddvcolor to allow UDV working from Cn3D (LG and PD)
144 *
145 * Revision 6.15  1999/09/20 21:57:41  durand
146 * switch UDV_draw_double_cursor from static to NLM_EXTERN
147 *
148 * Revision 6.14  1999/09/13 20:37:17  durand
149 * update UDV_Draw_scale for DDV
150 *
151 * Revision 6.13  1999/09/07 23:03:10  durand
152 * update UDV_Draw_scale to deal with discontinuous SEqAlign
153 *
154 * Revision 6.12  1999/07/30 20:08:57  durand
155 * updates for the new Entrez graphical viewer
156 *
157 * Revision 6.11  1999/07/19 20:35:35  durand
158 * switch ScalePositionfrom from Boolean to Uint1 in UDV_Draw_scale
159 *
160 * Revision 6.10  1999/06/29 14:59:52  durand
161 * update udv_draw_scale for DDV
162 *
163 * Revision 6.9  1999/06/16 13:07:00  durand
164 * update UDV functions to be used by DDV
165 *
166 * Revision 6.8  1999/06/08 13:52:35  durand
167 * update UDV data structures for the MSA editor
168 *
169 * Revision 6.7  1999/06/07 15:39:43  durand
170 * add LOG line to keep track of the history
171 *
172 *
173 *
174 * ==========================================================================
175 */
176 
177 #include <udviewer.h>
178 #include <udvdef.h>
179 #include <ddvcolor.h>
180 #include <asn2ff6.h>
181 #include <jzmisc.h>
182 #include <viewmgr.h>
183 
184 static RecT  UDV_calc_RCdraw(Int4 StartLine,Int4 nLines, RecT rcP,
185 		Int2 decal_gauche,Int4 decal_haut,Int2 LineHeight);
186 #ifndef WWW_UDV
187 static void UDV_draw_panel(PaneL p,ViewerDialogDataPtr vdp,RecT PNTR MyUpdateRect,
188 	Boolean bSelect);
189 #endif /*WWW_UDV*/
190 
191 /*****************************************************************************
192 
193 Function: LogoFontCreate()
194 
195 Purpose: create a simple set of fonts for the logo
196 
197 Return value: none
198 
199 *****************************************************************************/
200 #ifndef WWW_UDV
LogoFontCreate(FonT PNTR f1,FonT PNTR f2,FonT PNTR f3)201 NLM_EXTERN void LogoFontCreate(FonT PNTR f1,FonT PNTR f2,FonT PNTR f3)
202 {
203 
204 #ifdef WIN_MAC
205 		  *f1 = ParseFont ("Geneva,10");
206 		  *f2 = ParseFont ("Times,14,b");
207 		  *f3 = ParseFont ("Times,14,b,i");
208 #endif
209 
210 #ifdef WIN_MSWIN
211 		  *f1 = ParseFont ("Arial,16");
212 		  *f2 = ParseFont ("Times New Roman,20,b");
213 		  *f3 = ParseFont ("Times New Roman,20,b,i");
214 #endif
215 
216 #ifdef WIN_MOTIF
217 		  *f1 = ParseFont ("Helvetica,20,b");
218 		  *f2 = ParseFont ("Times,24,b");
219 		  *f3 = ParseFont ("Times,24,b,i");
220 #endif
221 
222 }
223 #endif /*WWW_UDV*/
224 
225 /*****************************************************************************
226 
227 Function: UDV_FontCreate()
228 
229 Purpose: create a simple set of fonts for the viewer
230 
231 Return value: handle to the font
232 
233 *****************************************************************************/
UDV_InitFont(UDVFontDataPtr udvfp)234 NLM_EXTERN FonT UDV_InitFont(UDVFontDataPtr udvfp)
235 {
236 
237 #ifdef WIN_MAC
238 		udvfp->hFnt = ParseFont ("Monaco, 9");
239 #endif
240 
241 #ifdef WIN_MSWIN
242 		udvfp->hFnt = ParseFont ("Courier, 7");
243 #endif
244 
245 #ifdef WIN_MOTIF
246 		udvfp->hFnt = ParseFont ("fixed, 12");
247 #endif
248 
249 #ifdef WWW_UDV
250 		udvfp->hFnt = ParseFont ("fixed, 10");
251 #endif
252 
253 	return(udvfp->hFnt);
254 }
255 
256 /*****************************************************************************
257 
258 Function: UDV_FontDim()
259 
260 Purpose: computes cxChar and cyChar
261 
262 Return value: none
263 
264 *****************************************************************************/
UDV_FontDim(Int2Ptr cxChar,Int2Ptr cyChar)265 NLM_EXTERN void  UDV_FontDim(Int2Ptr cxChar,Int2Ptr cyChar)
266 {
267 	*cxChar=MaxCharWidth();
268 	*cyChar=LineHeight();
269 }
270 
271 
272 /*****************************************************************************
273 
274 Function: UDV_ComputeLineHeight()
275 
276 Purpose: compute the height of a single data line
277 
278 Return value: the height
279 
280 *****************************************************************************/
UDV_ComputeLineHeight(Int2 cyChar)281 NLM_EXTERN Int2 UDV_ComputeLineHeight(Int2 cyChar)
282 {
283 	/*return(3*cyChar/2);*/
284 	return(cyChar);
285 }
286 
287 /*****************************************************************************
288 
289 Function: UDV_ComputePanelSize()
290 
291 Purpose: computes cxClient and cyClient
292          rc is the UDV panel
293 
294 Return value: none
295 
296 *****************************************************************************/
UDV_ComputePanelSize(RecT rc,Int2Ptr cxClient,Int2Ptr cyClient)297 NLM_EXTERN void  UDV_ComputePanelSize(RecT rc,Int2Ptr cxClient,
298 			Int2Ptr cyClient)
299 {
300 
301 	InsetRect (&rc, (Int2)VIEWER_HORZ_MARGIN, (Int2)VIEWER_VERT_MARGIN);
302 	*cxClient=rc.right-rc.left+1;
303 	*cyClient=rc.bottom-rc.top+1;
304 
305 }
306 
307 /*****************************************************************************
308 
309 Function: UDV_ComputeBlockByLine()
310 
311 Purpose: computes the number of Ten-letter blocks as well as the number of
312 		letters displayed on one line of the viewer
313 
314 Return value: none (results are in nCharByLine & nBlockByLine)
315 
316 *****************************************************************************/
UDV_ComputeBlockByLine(Int2 cxClient,Int2 cxName,Int2 cxLeftScale,Int2 cxChar,Int2Ptr nCharByLine,Int2Ptr nBlockByLine)317 NLM_EXTERN void  UDV_ComputeBlockByLine(Int2 cxClient,Int2 cxName,
318 			Int2 cxLeftScale,Int2 cxChar,Int2Ptr nCharByLine,
319 			Int2Ptr nBlockByLine)
320 {
321 Int2 cx, cxWin,i,LB;
322 
323 	LB=LETTER_BLOCK_WIDTH+1;/*+1: inter-block space*/
324 	cxWin=cxClient-cxName-cxLeftScale-2*VIEWER_HORZ_MARGIN;
325 	i=1;
326 	while(TRUE){/*count number of blocks within panel*/
327 		cx=i*LB*cxChar;
328 		if (cx>cxWin){
329 			i--;
330 			break;
331 		}
332 		i++;
333 	}
334 
335 	*nCharByLine=i*LETTER_BLOCK_WIDTH;
336 	*nBlockByLine=i;
337 }
338 
339 /*****************************************************************************
340 
341 Function: UDV_Init_GraphData()
342 
343 Purpose: Init Graphical values for the UnDViewer. Called one times at the
344 		start of the soft.
345 
346 Return value: none (results are in GrDataPtr)
347 
348 *****************************************************************************/
UDV_Init_ScaleData(UnDViewerGraphDataPtr GrDataPtr)349 NLM_EXTERN void  UDV_Init_ScaleData(UnDViewerGraphDataPtr GrDataPtr)
350 {
351 	/*display options*/
352 	GrDataPtr->udv_panel.ShowFeatures=TRUE;
353 	GrDataPtr->udv_panel.ShowScale=TRUE;
354 	GrDataPtr->DisplayOptions=DDV_DISP_VERT;
355 
356 	/*scale option*/
357 	GrDataPtr->udv_scale.ScalePosition=(Int2)SCALE_POS_BOTH;
358 	GrDataPtr->udv_scale.ShowMajorTick=TRUE;
359 	GrDataPtr->udv_scale.ShowMMinorTick=TRUE;
360 	GrDataPtr->udv_scale.MajorTickEvery=(Int2)SCALE_MAJOR_TICK_EVERY;
361 	GrDataPtr->udv_scale.MinorTickEvery=(Int2)SCALE_MINOR_TICK_EVERY;
362 /*	GrDataPtr->udv_scale.ScaleColor=(Uint4)SCALE_LETTER_COLOR;
363 	GrDataPtr->udv_scale.TickMajColor=(Uint4)SCALE_MAJTICK_COLOR;
364 	GrDataPtr->udv_scale.TickMinColor=(Uint4)SCALE_MINTICK_COLOR;*/
365 	GrDataPtr->udv_scale.cxLeftScale=(Int2)SCALE_WIDTH_IF_LEFT*
366 					GrDataPtr->udv_font.cxChar;
367 
368 
369 }
370 
371 /*****************************************************************************
372 
373 Function: UDV_Init_GraphData()
374 
375 Purpose: Init Graphical values for the UnDViewer. Called one times at the
376 		start of the soft.
377 
378 Return value: none (results are in GrDataPtr)
379 
380 *****************************************************************************/
381 #ifndef WWW_UDV
UDV_Init_GraphData(PaneL p,UnDViewerGraphDataPtr GrDataPtr)382 NLM_EXTERN void  UDV_Init_GraphData(PaneL p,UnDViewerGraphDataPtr GrDataPtr)
383 {
384 RecT rc;
385 
386 	UDV_Init_ScaleData(GrDataPtr);
387 	/*Panel Size & Lines to display*/
388 	if (p!=NULL){/*Vibrant viewer*/
389 		ObjectRect(p,&rc);
390 		UDV_ComputePanelSize(rc,&GrDataPtr->udv_panel.cxClient,
391 			&GrDataPtr->udv_panel.cyClient);
392 		GrDataPtr->udv_panel.cxName=PANEL_NAME_WIDTH*GrDataPtr->udv_font.cxChar;
393 		UDV_ComputeBlockByLine(GrDataPtr->udv_panel.cxClient,
394 			GrDataPtr->udv_panel.cxName,
395 			GrDataPtr->udv_scale.cxLeftScale,GrDataPtr->udv_font.cxChar,
396 			&GrDataPtr->udv_panel.nCharByLine,
397 			&GrDataPtr->udv_panel.nBlockByLine);
398 	}
399 
400 }
401 #endif
402 /*****************************************************************************
403 
404 Function: UDV_BuildFeatColorTable()
405 
406 Purpose: build a simple colour table to draw Nuc/Prot features
407 
408 Return value: a pointer to a colout table (each colour is encoded as an Uint4)
409 
410 *****************************************************************************/
UDV_BuildFeatColorTable(void)411 NLM_EXTERN Uint4Ptr  UDV_BuildFeatColorTable(void)
412 {
413 Uint4Ptr pClr;
414 Uint1 i;
415 
416 	pClr=(Uint4Ptr)MemNew(FEATDEF_MAX*sizeof(Uint4));
417 	if (!pClr) return(NULL);
418 	for (i=0;i<FEATDEF_MAX;i++)
419 		pClr[i]=GetColorRGB(0,0,0);
420 
421 	/*Warning: values are one-based*/
422 	pClr[FEATDEF_GENE]=GetColorRGB(128,128,128);			/*gray*/
423 
424 	pClr[FEATDEF_precursor_RNA]=GetColorRGB(0,0,255);/*blue*/
425 	pClr[FEATDEF_misc_RNA]=GetColorRGB(0,0,255);
426 	pClr[FEATDEF_preRNA]=GetColorRGB(0,0,255);
427 	pClr[FEATDEF_mRNA]=GetColorRGB(0,0,255);
428 	pClr[FEATDEF_tRNA]=GetColorRGB(0,0,255);
429 	pClr[FEATDEF_rRNA]=GetColorRGB(0,0,255);
430 	pClr[FEATDEF_snRNA]=GetColorRGB(0,0,255);
431 	pClr[FEATDEF_scRNA]=GetColorRGB(0,0,255);
432 	pClr[FEATDEF_otherRNA]=GetColorRGB(0,0,255);
433 	pClr[FEATDEF_prim_transcript]=GetColorRGB(0,0,255);
434 
435 	pClr[FEATDEF_CDS]=GetColorRGB(255,150,255);	/*pink*/
436 	pClr[FEATDEF_exon]=GetColorRGB(255,150,255);
437 	pClr[FEATDEF_intron]=GetColorRGB(255,150,255);
438 
439 	pClr[FEATDEF_PROT]=GetColorRGB(0,128,0);		/*dk green*/
440 	pClr[FEATDEF_mat_peptide]=GetColorRGB(0,128,0);
441 	pClr[FEATDEF_sig_peptide]=GetColorRGB(0,128,0);
442 	pClr[FEATDEF_transit_peptide]=GetColorRGB(0,128,0);
443 	pClr[FEATDEF_preprotein]=GetColorRGB(0,128,0);
444 	pClr[FEATDEF_mat_peptide_aa]=GetColorRGB(0,128,0);
445 	pClr[FEATDEF_sig_peptide_aa]=GetColorRGB(0,128,0);
446 	pClr[FEATDEF_transit_peptide_aa]=GetColorRGB(0,128,0);
447 
448 
449 	pClr[FEATDEF_SITE]=GetColorRGB(255,0,0);		/*red*/
450 
451 	pClr[FEATDEF_REGION]=GetColorRGB(210,154,14);		/*orange*/
452 	pClr[FEATDEF_mutation]=GetColorRGB(210,154,14);
453 	pClr[FEATDEF_variation]=GetColorRGB(210,154,14);
454 
455 	pClr[FEATDEF_PSEC_STR]=GetColorRGB(104,201,220); /*cyan*/
456 
457 	pClr[FEATDEF_HET]=GetColorRGB(128,128,0);	/*yellow*/
458 
459 	pClr[FEATDEF_BOND]=GetColorRGB(255,92,255);	/*pink*/
460 
461 	return(pClr);
462 }
463 
464 /*****************************************************************************
465 
466 Function: UDV_Build_Other_Colors()
467 
468 Purpose: create the colors for font, rulers,...
469 
470 Return value: none (results stored in GrData)
471 
472 *****************************************************************************/
UDV_Build_Other_Colors(UnDViewerGraphDataPtr GrDataPtr)473 NLM_EXTERN void UDV_Build_Other_Colors(UnDViewerGraphDataPtr GrDataPtr)
474 {
475 	/*font*/
476 	GrDataPtr->udv_font.UseDefaultColorLetter=TRUE;
477 	GrDataPtr->udv_font.LetterColor=(Uint4)FONT_DEF_COLOR;
478 	/*ruler*/
479 	GrDataPtr->udv_scale.ScaleColor=(Uint4)SCALE_LETTER_COLOR;
480 	GrDataPtr->udv_scale.TickMajColor=(Uint4)SCALE_MAJTICK_COLOR;
481 	GrDataPtr->udv_scale.TickMinColor=(Uint4)SCALE_MINTICK_COLOR;
482 }
483 
484 /*****************************************************************************
485 
486 Function: UDV_Build_NA_LayoutPalette()
487 
488 Purpose: build a simple layout table to draw colour Nuc sequence
489 
490 Return value: none (results store in GrData)
491 
492 *****************************************************************************/
UDV_Build_NA_LayoutPalette(UnDViewerGraphDataPtr GrData)493 NLM_EXTERN void  UDV_Build_NA_LayoutPalette(UnDViewerGraphDataPtr GrData)
494 {
495 
496 	GrData->NA_LayoutPal[NA_A_LAYOUT].LetClr=GetColorRGB(0,192,0);
497 	GrData->NA_LayoutPal[NA_A_LAYOUT].bkClr=0;
498 	GrData->NA_LayoutPal[NA_A_LAYOUT].AspLet=LAYOUT_LOWER_CASE;
499 
500 	GrData->NA_LayoutPal[NA_G_LAYOUT].LetClr=GetColorRGB(192,192,0);
501 	GrData->NA_LayoutPal[NA_G_LAYOUT].bkClr=0;
502 	GrData->NA_LayoutPal[NA_G_LAYOUT].AspLet=LAYOUT_LOWER_CASE;
503 
504 	GrData->NA_LayoutPal[NA_C_LAYOUT].LetClr=GetColorRGB(0,0,255);
505 	GrData->NA_LayoutPal[NA_C_LAYOUT].bkClr=0;
506 	GrData->NA_LayoutPal[NA_C_LAYOUT].AspLet=LAYOUT_LOWER_CASE;
507 
508 	GrData->NA_LayoutPal[NA_T_LAYOUT].LetClr=GetColorRGB(255,0,0);
509 	GrData->NA_LayoutPal[NA_T_LAYOUT].bkClr=0;
510 	GrData->NA_LayoutPal[NA_T_LAYOUT].AspLet=LAYOUT_LOWER_CASE;
511 
512 	GrData->NA_LayoutPal[NA_U_LAYOUT].LetClr=GetColorRGB(192,0,192);
513 	GrData->NA_LayoutPal[NA_U_LAYOUT].bkClr=0;
514 	GrData->NA_LayoutPal[NA_U_LAYOUT].AspLet=LAYOUT_LOWER_CASE;
515 }
516 
517 /*****************************************************************************
518 
519 Function: UDV_Build_AA_LayoutPalette()
520 
521 Purpose: build a simple layout table to draw colour Prot sequence
522 
523 Return value: none (results store in GrData)
524 
525 *****************************************************************************/
UDV_Build_AA_LayoutPalette(UnDViewerGraphDataPtr GrData)526 NLM_EXTERN void  UDV_Build_AA_LayoutPalette(UnDViewerGraphDataPtr GrData)
527 {
528 RGBColoR LetClr[26]={{0,0,0},	/* A */
529 					{0,0,0},	/* B */
530 					{0,0,0},	/* C */
531 					{255,0,0},	/* D */
532 					{255,0,0},	/* E */
533 					{0,192,0},	/* F */
534 					{0,0,0},	/* G */
535 					{0,0,0},	/* H */
536 					{0,192,0},	/* I */
537 					{0,0,0},	/* J */
538 					{0,0,255},	/* K */
539 					{0,192,0},	/* L */
540 					{0,192,0},	/* M */
541 					{255,0,0},	/* N */
542 					{0,0,0},	/* O */
543 					{255,0,0},	/* P */
544 					{255,0,0},	/* Q */
545 					{0,0,255},	/* R */
546 					{0,0,0},	/* S */
547 					{0,0,0},	/* T */
548 					{0,0,0},	/* U */
549 					{0,192,0},	/* V */
550 					{0,192,0},	/* W */
551 					{0,0,0},	/* X */
552 					{0,192,0},	/* Y */
553 					{0,0,0},	/* Z */
554 					};
555 
556 RGBColoR BkClr[26]={{255,255,255},	/* A */
557 					{255,255,255},	/* B */
558 					{255,255,255},	/* C */
559 					{255,255,255},	/* D */
560 					{255,255,255},	/* E */
561 					{255,255,255},	/* F */
562 					{255,255,255},	/* G */
563 					{255,255,255},	/* H */
564 					{255,255,255},	/* I */
565 					{255,255,255},	/* J */
566 					{255,255,255},	/* K */
567 					{255,255,255},	/* L */
568 					{255,255,255},	/* M */
569 					{255,255,255},	/* N */
570 					{255,255,255},	/* O */
571 					{255,255,255},	/* P */
572 					{255,255,255},	/* Q */
573 					{255,255,255},	/* R */
574 					{255,255,255},	/* S */
575 					{255,255,255},	/* T */
576 					{255,255,255},	/* U */
577 					{255,255,255},	/* V */
578 					{255,255,255},	/* W */
579 					{255,255,255},	/* X */
580 					{255,255,255},	/* Y */
581 					{255,255,255},	/* Z */
582 					};
583 Uint1 i;
584 
585 	for(i=0;i<26;i++){
586 		GrData->AA_LayoutPal[i].LetClr=GetColorRGB(LetClr[i].red,
587 													LetClr[i].green,
588 													LetClr[i].blue);
589 		GrData->AA_LayoutPal[i].bkClr=GetColorRGB(BkClr[i].red,
590 													BkClr[i].green,
591 													BkClr[i].blue);
592 		GrData->AA_LayoutPal[i].AspLet=LAYOUT_UPPER_CASE;
593 	}
594 }
595 
596 /*******************************************************************************
597 
598   Function : UDV_GetCurrentDispRange()
599 
600   Purpose : get first,last position of the sequence on the screen
601 
602   Return value : -
603 
604 *******************************************************************************/
605 #ifndef WWW_UDV
UDV_GetCurrentDispRange(ViewerDialogDataPtr vdp,Int4Ptr from_bsp,Int4Ptr to_bsp,Int4Ptr from_line,Int4Ptr to_line)606 NLM_EXTERN void	UDV_GetCurrentDispRange(ViewerDialogDataPtr vdp,
607 		Int4Ptr from_bsp,Int4Ptr to_bsp,Int4Ptr from_line,Int4Ptr to_line)
608 {
609 ValNodePtr vnp,vnp2;
610 ParaGPtr   pgp;
611 Int4       from_row,to_row;
612 
613 	*from_bsp=0;
614 	*to_bsp=0;
615 	if (vdp==NULL) return;
616 
617 	/*rows displayed in the screen*/
618 	from_row=vdp->udv_graph.udv_vscrl.ScrollPos;
619 	if (vdp->udv_graph.udv_vscrl.ScrollPage==0){
620 		to_row=vdp->udv_graph.udv_panel.nTotLines;
621 	}
622 	else{
623 		to_row=from_row+vdp->udv_graph.udv_vscrl.ScrollPage;
624 		if (to_row>vdp->udv_graph.udv_panel.nTotLines)
625 			to_row=vdp->udv_graph.udv_panel.nTotLines;
626 	}
627 	/*find the ParaG where from_row is Located*/
628 	vnp=vdp->ParaG;
629 	while(vnp){
630 		if (vnp->data.ptrvalue){
631 			pgp=(ParaGPtr)vnp->data.ptrvalue;
632 			if ((pgp->StartLine<=from_row)&&((pgp->StartLine+pgp->nLines)>=from_row)){
633 					break;
634 			}
635 		}
636 		vnp=vnp->next;
637 	}
638 	*from_bsp=pgp->StartLetter;
639 	/*find the ParaG where to_row is Located*/
640 	vnp2=vnp;
641 	while(vnp2){
642 		if (vnp2->data.ptrvalue){
643 			pgp=(ParaGPtr)vnp2->data.ptrvalue;
644 			if ((pgp->StartLine<=to_row)&&((pgp->StartLine+pgp->nLines)>=to_row)){
645 					break;
646 			}
647 		}
648 		vnp2=vnp2->next;
649 	}
650 	*to_bsp=pgp->StopLetter;
651 
652 	if (from_line) *from_line=from_row;
653 	if (to_line) *to_line=to_row;
654 }
655 #endif
656 
657 /*******************************************************************************
658 
659   Function : UDV_InvalRegion()
660 
661   Purpose : invalidate a specific region of a sequence within a ParaG
662 
663   Return value : -
664 
665 *******************************************************************************/
666 #ifndef WWW_UDV
UDV_InvalRegion(PaneL UnDViewer,UnDViewerGraphDataPtr GrData,ParaGPtr pgp,Int4 start_inval,Int4 stop_inval,Boolean IsSelect)667 NLM_EXTERN void UDV_InvalRegion(PaneL UnDViewer,UnDViewerGraphDataPtr GrData,
668 		ParaGPtr pgp,Int4 start_inval,Int4 stop_inval,Boolean IsSelect)
669 {
670 Int4 				decal_haut,StartLine;
671 RecT 				rc,rcP;
672 Int2				decal_gauche,left_pos,right_pos;
673 ViewerDialogDataPtr vdp;
674 WindoW              temport;
675 
676 	/*get some usefull data...*/
677 	vdp = (ViewerDialogDataPtr) GetObjectExtra (UnDViewer);
678 
679 	if (vdp == NULL) return;
680 
681     temport=SavePort(ParentWindow(UnDViewer));
682 	Select(UnDViewer);
683 	ObjectRect(UnDViewer,&rcP);
684 
685 	StartLine=pgp->StartLine;
686 	if (GrData->udv_scale.ShowMajorTick) StartLine++;
687 	if (GrData->udv_scale.ScalePosition==SCALE_POS_TOP ||
688 			GrData->udv_scale.ScalePosition==SCALE_POS_BOTH) StartLine++;
689 
690 	decal_haut=GrData->udv_vscrl.ScrollPos*
691 			GrData->udv_font.LineHeight-VIEWER_VERT_MARGIN;
692 	decal_gauche=GrData->udv_panel.cxName+rcP.left+
693 			GrData->udv_scale.cxLeftScale;
694 
695 	left_pos=(Int2)(start_inval-pgp->StartLetter);
696 	left_pos+=(left_pos/LETTER_BLOCK_WIDTH);
697 	right_pos=(Int2)(stop_inval-pgp->StartLetter);
698 	right_pos+=(right_pos/LETTER_BLOCK_WIDTH);
699 	rc.top=(Int2)(StartLine*GrData->udv_font.LineHeight+rcP.top-decal_haut);
700 	rc.bottom=(Int2)(rc.top+GrData->udv_font.LineHeight)+GrData->udv_font.LineHeight/3;
701 	rc.left=decal_gauche+left_pos*GrData->udv_font.cxChar;
702 	rc.right=decal_gauche+right_pos*GrData->udv_font.cxChar+2*GrData->udv_font.cxChar;
703 	if (!IsSelect){
704 		InvalRect(&rc);
705 	}
706 	else{
707 		UDV_draw_panel(UnDViewer,vdp,&rc,IsSelect);
708 	}
709     RestorePort(temport);
710 }
711 #endif
712 
713 
714 /*****************************************************************************
715 
716 Function: UDV_calc_pos()
717 
718 Purpose: get the bsp_coord given some data (current ParaG,...)
719 
720 Parameters:	GrData; graphical data object
721 			pt; mouse position
722 			rcClip; region where pgp is included
723 			pgp; ParaG data
724 			szPos; used to put pos as a string
725 
726 Return value: pos (1-based value)
727 
728 *****************************************************************************/
UDV_calc_pos(UnDViewerGraphDataPtr GrData,PoinT * pt,RecT * rcClip,ParaGPtr pgp,CharPtr szPos)729 static Int4  UDV_calc_pos(UnDViewerGraphDataPtr GrData,PoinT * pt,
730 		RecT * rcClip,ParaGPtr pgp,CharPtr szPos)
731 {
732 Int2 xMargin,i,max;
733 Int4 pos,start,stop;
734 
735 
736 	xMargin=rcClip->left+GrData->udv_font.cxChar;
737 
738 	pos=(Int4)((pt->x-xMargin+GrData->udv_font.cxChar/2)/
739 		GrData->udv_font.cxChar);
740 	max=GrData->udv_panel.nBlockByLine+1;
741 	for (i=0;i<max;i++){
742 		start=i*LETTER_BLOCK_WIDTH+i;
743 		stop=start+LETTER_BLOCK_WIDTH;
744 		if (pos>=start && pos<stop) {pos=pos-i; break;}
745 		if (pos==stop) {pos=pos-i-1; break;}
746 	}
747 	pos+=pgp->StartLetter;
748 	if (pos<pgp->StartLetter) pos=pgp->StartLetter;
749 	if (pos>pgp->StopLetter) pos=pgp->StopLetter;
750 	pos++;
751 
752 	if (szPos!=NULL) sprintf(szPos,"%d",pos);
753 
754 	return(pos);
755 }
756 
757 /*****************************************************************************
758 
759 Function: UDV_find_item()
760 
761 Purpose: find if a feature is selected (generally in reponse to ObjMgr)
762 
763 Parameters: ParaG; list to check
764 			bsp; identifier of the sequence
765 			entityID,
766 			itemID; identifiers of the feature
767 			szFeatureName; name of the feature, if found (return value)
768 			pgpFeat; ParaG where the feature is located
769 			nLineDecal; line number within ParaG where the feature is located
770 			isp; identifier of the feature (eID, iID, iType)
771 
772 Return value: TRUE if feature has been found in the ParaG list
773 
774 *****************************************************************************/
775 #ifndef WWW_UDV
UDV_find_item(ValNodePtr ParaG,BioseqPtr bsp,Uint2 entityID,Uint4 itemID,Uint2 itemType,CharPtr szFeatureName,ParaGPtr PNTR pgpFeat,Uint2Ptr nLineDecal,UDV_Item_SelectPtr isp)776 static Boolean  UDV_find_item(ValNodePtr ParaG,BioseqPtr bsp,
777 		Uint2 entityID,Uint4 itemID,Uint2 itemType,CharPtr szFeatureName,
778 		ParaGPtr PNTR pgpFeat,Uint2Ptr nLineDecal,UDV_Item_SelectPtr isp)
779 {
780 ParaGPtr pgp;				/*data to check*/
781 Uint2 j;					/*little counter*/
782 ValNodePtr vnp,vnp2;		/*use to scan features*/
783 Uint4 iID;
784 Uint2 idx;				/*used to retrieve a desired Feature*/
785 SeqMgrFeatContext context;	/*used to retrieve feature data*/
786 Char szBuf[255]={""};		/*feature name */
787 Char szTmp[255]={""};		/*feature name */
788 Boolean bFound=FALSE;		/*TRUE if feature found*/
789 
790 	if (ParaG){
791 		for(vnp=ParaG ; vnp!=NULL ; vnp=vnp->next){
792 			if (vnp->data.ptrvalue){
793 				pgp=(ParaGPtr)vnp->data.ptrvalue;
794 				/*look through features*/
795 				for(j=0,vnp2=pgp->pFeatList;j<pgp->nFeat;j++,vnp2=vnp2->next){
796 					if (vnp2 == NULL) break;
797 
798 					UDV_BigDecodeIdxFeat ((Uint8)vnp2->data.bigintvalue, &iID,&idx,
799 							NULL,NULL);
800 					if (iID==itemID){
801 						if (!SeqMgrGetDesiredFeature(entityID,
802 							bsp,iID,idx,NULL,&context)) {
803 							break;
804 						}
805 						FeatDefLabel (context.sfp, szBuf, sizeof (szBuf) - 1,
806 							OM_LABEL_BOTH);
807 						if (context.numivals>1){
808 							sprintf(szTmp,"%s [from %d to %d in %d segments]. ",
809 								szBuf,context.left+1,context.right+1,
810 								context.numivals);
811 						}
812 						else{
813 							sprintf(szTmp,"%s [from %d to %d]. ",
814 								szBuf,context.left+1,context.right+1);
815 						}
816 						StringCpy(szBuf,szTmp);
817 						sprintf(szTmp,"Length = %d. ",
818 							context.right-context.left+1);
819 						StringCat(szBuf,szTmp);
820 
821 						if (context.sfp->comment) {
822 							sprintf(szTmp,"Note: %s. ",context.sfp->comment);
823 							StringCat(szBuf,szTmp);
824 						}
825 						/*store szBuf in szFeatureName*/
826 						if (szFeatureName)
827 							StringCpy(szFeatureName,szBuf);
828 						*pgpFeat=pgp;
829 						*nLineDecal+=j;
830 						isp->eIDsel=entityID;
831 						isp->iIDsel=itemID;
832 						isp->iTypeSel=itemType;
833 						bFound=TRUE;
834 						break;
835 					}
836 				}
837 			}
838 			if (bFound) break;
839 		}
840 	}
841 	return(bFound);
842 }
843 #endif /*WWW_UDV*/
844 
845 /*****************************************************************************
846 
847 Function: UDV_click_item()
848 
849 Purpose: find whether the user has clicked on a feature or not (retrieve
850 	values which will be sent to ObjMgr)
851 
852 Parameters: GrData; graphical data object
853 			pt; mouse position
854 			rc; ParaG region
855 			pgp: ParaG data
856 			bsp_i; bsp data
857 			entityID,
858 			itemID,
859 			itemType; identifiers of the features
860 			index; index as defined by the Feature Index for a specific feature
861 
862 Return value: TRUE if  the user has clicked within a feat
863 
864 *****************************************************************************/
865 #ifndef WWW_UDV
UDV_click_item(UnDViewerGraphDataPtr GrData,PoinT pt,RecT rc,ParaGPtr pgp,BspInfo bsp_i,Uint2Ptr entityID,Uint4Ptr itemID,Uint2Ptr itemType,Uint2Ptr index)866 static Boolean  UDV_click_item(UnDViewerGraphDataPtr GrData,PoinT pt,
867 		RecT rc,ParaGPtr pgp,BspInfo bsp_i,Uint2Ptr entityID,
868 		Uint4Ptr itemID,Uint2Ptr itemType,Uint2Ptr index)
869 {
870 Boolean InFeat=FALSE;		/*TRUE if the user has clicked within a feat*/
871 ValNodePtr vnp;				/*use to scan features*/
872 Int2 i,j,yDecal=0/*1*/;			/*use to find a feat region*/
873 Int4 pos,OccupyTo;			/*position (# of letters) of the mouse*/
874 Uint4 iID;
875 Uint2 idx;				/*used to retrieve a desired Feature*/
876 SeqMgrFeatContext context;	/*used to retrieve feature data*/
877 Boolean IsTransNeeded=FALSE;
878 
879 	if (pgp->pFeatList==NULL) return(InFeat);
880 
881 	/*go at the bottom of the sequence*/
882 	if (GrData->udv_scale.ScalePosition==SCALE_POS_TOP ||
883 					GrData->udv_scale.ScalePosition==SCALE_POS_BOTH) yDecal++;
884 	if (GrData->udv_scale.ShowMajorTick) yDecal++;
885 
886 	yDecal=rc.top+yDecal*GrData->udv_font.LineHeight;
887 	OccupyTo=pgp->StopLetter;
888 
889 	for(j=0,vnp=pgp->pFeatList;j<pgp->nFeat;j++,vnp=vnp->next){
890 		if (vnp == NULL) break;
891 		i=1;
892 		/*get desired feature given iID and idx*/
893 		UDV_BigDecodeIdxFeat ((Uint8)vnp->data.bigintvalue, &iID,&idx,NULL,NULL);
894 		if (!SeqMgrGetDesiredFeature(bsp_i.bsp_entityID,bsp_i.bsp,
895             iID,idx,NULL,&context)) {
896 			break;
897 		}
898 		else{
899 			/*CDS occupies 1 or 2 lines*/
900 			if (context.sfp->data.choice==SEQFEAT_CDREGION){
901 				if (UDV_IsTranslationNeeded(&context,pgp)) i=2;
902 				else i=1;
903 			}
904 			else i=1;
905 
906 			if (context.left<=OccupyTo)
907 				yDecal+=GrData->udv_font.LineHeight;
908 
909 			if (pt.y>=yDecal && pt.y<=yDecal+i*GrData->udv_font.LineHeight){
910 				/*pos is a 1-based value*/
911 				if(pt.x<GrData->udv_panel.cxName-2)
912 					pos=context.left;
913 				else pos=UDV_calc_pos(GrData,&pt,&rc,pgp,NULL)-1;
914 				/*HET feature correction for the ends*/
915 				if(context.featdeftype== FEATDEF_HET){
916 					context.right=context.ivals[2*context.numivals-1];
917 				}
918 
919 				if (pos>=context.left && pos<=context.right) {
920 					*entityID=bsp_i.bsp_entityID;
921 					*itemID=iID;
922 					*itemType=OBJ_SEQFEAT;
923 					*index=context.index;
924 					InFeat=TRUE;
925 					break;
926 				}
927 			}
928 			OccupyTo=context.right;
929 		}
930 	}
931 	return(InFeat);
932 }
933 #endif /*WWW_UDV*/
934 
935 
936 /*****************************************************************************
937 
938 Function: UDV_draw_vert_cursor()
939 
940 Purpose: draw a vertical cursor to track position of a feature
941 
942 Parameters:	rcClip; draw only when the mouse is within rcClip
943 			pos; new position to draw
944 
945 Return value: none
946 
947 *****************************************************************************/
UDV_draw_vert_cursor(RecT rcClip,PoinT pos)948 static void UDV_draw_vert_cursor(RecT rcClip,PoinT pos)
949 {
950 	if (PtInRect(pos,&rcClip)){
951 		Dotted();
952 		MoveTo(pos.x,rcClip.top);
953 		LineTo(pos.x,rcClip.bottom);
954 		Solid();
955 	}
956 }
957 
958 /*****************************************************************************
959 
960 Function: UDV_draw_horz_cursor()
961 
962 Purpose: draw a horizontal cursor to track position of a feature
963 
964 Parameters:	GrData; graphical data object
965 			rcClip; draw only when the mouse is within rcClip
966 			pos; new position to draw
967 
968 Return value: none
969 
970 *****************************************************************************/
UDV_draw_horz_cursor(UnDViewerGraphDataPtr GrData,RecT rcClip,PoinT pos)971 static void 	UDV_draw_horz_cursor(UnDViewerGraphDataPtr GrData,
972 			RecT rcClip,PoinT pos)
973 {
974 
975 	if (PtInRect(pos,&rcClip)){
976 		PoinT arrow[3];
977 		Dotted();
978 		MoveTo((Int2)(rcClip.left-GrData->udv_scale.cxLeftScale),pos.y);
979 		LineTo(pos.x,pos.y);
980 		Solid();
981 		arrow[0].x=rcClip.left-GrData->udv_scale.cxLeftScale;
982 		arrow[0].y=pos.y;
983 		arrow[1].x=arrow[0].x+GrData->udv_font.cxChar/2;
984 		arrow[1].y=pos.y-GrData->udv_font.cxChar/2;
985 		arrow[2].x=arrow[1].x;
986 		arrow[2].y=pos.y+GrData->udv_font.cxChar/2;
987 		PaintPoly(3,arrow);
988 	}
989 }
990 
991 /*****************************************************************************
992 
993 Function: UDV_draw_double_cursor()
994 
995 Purpose: draw a double vertical cursor to modify the cxName value (i.e. the
996 		width of the region where names are drawn)
997 
998 Parameters:	rcClip; draw only when the mouse is within rcClip
999 			pos; new position to draw
1000 
1001 Return value: none
1002 
1003 *****************************************************************************/
UDV_draw_double_cursor(RecT rcClip,PoinT pos)1004 NLM_EXTERN void UDV_draw_double_cursor(RecT rcClip,PoinT pos)
1005 {
1006 	if (PtInRect(pos,&rcClip)){
1007 		Dotted();
1008 		MoveTo(pos.x,rcClip.top);
1009 		LineTo(pos.x,rcClip.bottom);
1010 		MoveTo((Int2)(pos.x+3),rcClip.top);
1011 		LineTo((Int2)(pos.x+3),rcClip.bottom);
1012 		Solid();
1013 	}
1014 }
1015 
UDV_draw_horizontal_line(RecT rcClip,Int4 VPos)1016 NLM_EXTERN void UDV_draw_horizontal_line(RecT rcClip, Int4 VPos) {
1017 /*****************************************************************************
1018 *  draw a line from the left side of the rectangle to the right, at VPos.
1019 *****************************************************************************/
1020   MoveTo(rcClip.left, VPos);
1021   LineTo(rcClip.right, VPos);
1022 }
1023 
UDV_draw_rectangle(RecT rcClip,Boolean DotIt)1024 NLM_EXTERN void UDV_draw_rectangle(RecT rcClip, Boolean DotIt) {
1025 /*****************************************************************************
1026 *  draw a rectangle around the perimeter of rcClip.
1027 *  no pixel is drawn twice.
1028 *  if DotIt is TRUE, make the rectangle dotted.
1029 *****************************************************************************/
1030   if (DotIt) Dotted();
1031   MoveTo(rcClip.left,    rcClip.top);
1032   LineTo(rcClip.right,   rcClip.top);
1033   MoveTo(rcClip.right,   rcClip.top+1);
1034   LineTo(rcClip.right,   rcClip.bottom);
1035   MoveTo(rcClip.right-1, rcClip.bottom);
1036   LineTo(rcClip.left,    rcClip.bottom);
1037   MoveTo(rcClip.left,    rcClip.bottom-1);
1038   LineTo(rcClip.left,    rcClip.top+1);
1039   if (DotIt) Solid();
1040 }
1041 
UDV_draw_vertical_bar(RecT rcClip,Int4 HPos,Boolean DotIt)1042 NLM_EXTERN void UDV_draw_vertical_bar(RecT rcClip, Int4 HPos, Boolean DotIt) {
1043 /*****************************************************************************
1044 *  draw a thick vertical bar.
1045 *  if DotIt is true, just draw a dotted outline.
1046 *****************************************************************************/
1047   if (DotIt) Dotted();
1048   if (!DotIt) LtGray();
1049   MoveTo(HPos-2, rcClip.top);
1050   LineTo(HPos-2, rcClip.bottom);
1051   if (!DotIt) {
1052     MoveTo(HPos,   rcClip.top);
1053     LineTo(HPos,   rcClip.bottom);
1054     MoveTo(HPos+1, rcClip.top);
1055     LineTo(HPos+1, rcClip.bottom);
1056     Black();
1057   }
1058   MoveTo(HPos+2, rcClip.top);
1059   LineTo(HPos+2, rcClip.bottom);
1060   if (DotIt) Solid();
1061 }
1062 
UDV_draw_horizontal_bar(Int4 VPos,Int4 LeftHPos,Int4 RightHPos)1063 NLM_EXTERN void UDV_draw_horizontal_bar(Int4 VPos, Int4 LeftHPos, Int4 RightHPos) {
1064 /*****************************************************************************
1065 *  draw a thick horizontal bar.
1066 *****************************************************************************/
1067   LtGray();
1068   MoveTo(LeftHPos-2,  VPos);
1069   LineTo(RightHPos+2, VPos);
1070   White();
1071   MoveTo(LeftHPos-1,  VPos+1);
1072   LineTo(RightHPos+1, VPos+1);
1073   LtGray();
1074   MoveTo(LeftHPos,    VPos+2);
1075   LineTo(RightHPos,   VPos+2);
1076   MoveTo(LeftHPos+1,  VPos+3);
1077   LineTo(RightHPos-1, VPos+3);
1078   Black();
1079   MoveTo(LeftHPos+2,  VPos+4);
1080   LineTo(RightHPos-2, VPos+4);
1081 }
1082 
1083 
1084 /*****************************************************************************
1085 
1086 Function: UDV_deselect_feature()
1087 
1088 Purpose: deselect a feature.
1089 
1090 Return value: none
1091 
1092 *****************************************************************************/
1093 #ifndef WWW_UDV
UDV_deselect_feature(ViewerDialogDataPtr vdp)1094 NLM_EXTERN void UDV_deselect_feature(ViewerDialogDataPtr vdp)
1095 {
1096 RecT rcP;
1097 WindoW temport;
1098 
1099 	vdp->Old_Item_select.eIDsel=(Uint2)-1;
1100 	vdp->Old_Item_select.iIDsel=(Uint2)-1;
1101 	vdp->Old_Item_select.iTypeSel=(Uint2)-1;
1102 	/*redraw the panel*/
1103 	vdp->Item_select.eIDsel=(Uint2)-1;
1104 	vdp->Item_select.iIDsel=(Uint2)-1;
1105 	vdp->Item_select.iTypeSel=(Uint2)-1;
1106 	temport=SavePort((WindoW)ParentWindow(vdp->UnDViewer));
1107 	Select(vdp->UnDViewer);
1108 	ObjectRect(vdp->UnDViewer,&rcP);
1109 	InvalRect(&rcP);
1110 	RestorePort(temport);
1111 }
1112 #endif /*WWW_UDV*/
1113 
1114 /*****************************************************************************
1115 
1116 Function: UDV_select_feature()
1117 
1118 Purpose: select a feature. This function is generally called in reponse to a
1119 	message from ObjMgr.
1120 
1121 Parameters:	p; UDV panel
1122             vdp; main data struct
1123 			entityID, itemID; the feature
1124 			bRepos; move the undviewer panel if true. When the user clicks on
1125 			this panel, this value is false. When the user clicks on the Feature
1126 			Dialog Box, this value is TRUE in order to show to the nice user
1127 			the start of the clicked feature.
1128 
1129 Return value: none
1130 
1131 *****************************************************************************/
1132 #ifndef WWW_UDV
UDV_select_feature(PaneL p,ViewerDialogDataPtr vdp,Uint2 entityID,Uint4 itemID,Boolean bRepos)1133 NLM_EXTERN void UDV_select_feature(PaneL p,ViewerDialogDataPtr vdp,
1134 			Uint2 entityID,Uint4 itemID,Boolean bRepos)
1135 {
1136 ParaGPtr pgp_select;	/*selected pgp*/
1137 Char 	 szFeatName[500]; /*used to modify the InfoPanel Text*/
1138 WindoW 	 temport;	/*to allow a safe draw*/
1139 Uint2 	 nLineDecal=0;
1140 Int4 	 decal;
1141 Boolean	 ShowTop=FALSE,
1142 		 ShowTick=FALSE;
1143 RecT     rcP;
1144 
1145 	if (vdp == NULL) return;
1146 
1147 	vdp->Old_Item_select=vdp->Item_select;
1148 	/*compute the position (number of lines) of the first feature within the ParaG
1149 	by taking into account the scale*/
1150 	if (vdp->udv_graph.udv_panel.ShowScale){
1151 		if (vdp->udv_graph.udv_scale.ScalePosition==SCALE_POS_LEFT)
1152 			ShowTop=FALSE;
1153 		else ShowTop=TRUE;
1154 
1155 		if (vdp->udv_graph.udv_scale.ShowMajorTick)
1156 			ShowTick=TRUE;
1157 		else ShowTick=FALSE;
1158 	}
1159 	else{
1160 		ShowTop=FALSE;
1161 		ShowTick=FALSE;
1162 	}
1163 	nLineDecal=1;
1164 	if (ShowTop) nLineDecal++;
1165 	if (ShowTick) nLineDecal++;
1166 
1167 	if (UDV_find_item(vdp->ParaG,vdp->bsp_i.bsp,
1168 		entityID,itemID,OBJ_SEQFEAT,szFeatName,&pgp_select,&nLineDecal,
1169 		&vdp->Item_select)){
1170 			decal=pgp_select->StartLine+(Int4)nLineDecal;
1171 			if ((decal<vdp->udv_graph.udv_vscrl.ScrollPos ||
1172 				decal>(vdp->udv_graph.udv_vscrl.ScrollPage+
1173 				vdp->udv_graph.udv_vscrl.ScrollPos)) && bRepos){
1174 				Int4 CurPos;
1175 
1176 				CurPos=decal;
1177 				UnDViewerVScrlUpdate(p,FALSE,CurPos);
1178 				/*create new buffer*/
1179 				UDV_create_buffer(&vdp->udv_graph,vdp->ParaG,&vdp->bsp_i,NULL,
1180 					vdp->bDisplayRevComp);
1181 				/*redraw the panel*/
1182 				temport=SavePort((WindoW)ParentWindow(p));
1183 				Select(p);
1184 				ObjectRect(p,&rcP);
1185 				InvalRect(&rcP);
1186 				RestorePort(temport);
1187 			}
1188 			else {
1189 				/*redraw the panel*/
1190 				temport=SavePort((WindoW)ParentWindow(p));
1191 				Select(p);
1192 				ObjectRect(p,&rcP);
1193 				InvalRect(&rcP);
1194 				RestorePort(temport);
1195 			}
1196 
1197 			vdp->Old_Item_select.eIDsel=(Uint2)-1;
1198 			vdp->Old_Item_select.iIDsel=(Uint2)-1;
1199 			vdp->Old_Item_select.iTypeSel=(Uint2)-1;
1200 	}
1201 	if (vdp->InfoPanel) {/*InfoPanel doesn't exist for slave viewer*/
1202 		/*use only for the Autonomous version of the viewer*/
1203 		SetTitle(vdp->InfoPanel,szFeatName);
1204 	}
1205 }
1206 #endif /*WWW_UDV*/
1207 
1208 /*****************************************************************************
1209 
1210 Function: UDV_SendBSPSelectMsg()
1211 
1212 Purpose: send a Msg to select a piece of sequence
1213 
1214 Parameters:
1215 
1216 Note: this function MUST be called by external software using this viewer
1217 
1218 
1219 Return value: none
1220 
1221 *****************************************************************************/
1222 #ifndef WWW_UDV
UDV_SendBSPSelectMsg(ViewerDialogDataPtr vdp,Int4 bsp_coord,ParaGPtr cur_pgp,PoinT * pt)1223 static void UDV_SendBSPSelectMsg(ViewerDialogDataPtr vdp,Int4 bsp_coord,
1224 		ParaGPtr cur_pgp,PoinT * pt)
1225 {
1226 Int4        first_bsp_coord, bsp_coord_old,old_pos;
1227 Uint1       direction;/*use to tell ObjMgr the direction of the mouse (left,right)*/
1228 SeqLocPtr   slp;/*to send an AlsoSelectMsg*/
1229 Uint2       bsp_eID,bsp_iID;
1230 Boolean     bDeselectAll=TRUE;
1231 
1232 	if (ctrlKey || shftKey)
1233 		bDeselectAll=FALSE;
1234 
1235 	/*is the mouse going to the left or to the right ?*/
1236 	/*don't forget to check the strand...  ;-) */
1237 	bsp_coord_old=vdp->UDV_ms.old_col;
1238 	first_bsp_coord=vdp->UDV_ms.first_col;
1239 
1240 	if (vdp->UDV_ms.oldPos.x<pt->x)
1241 		direction=Seq_strand_plus;
1242 	else
1243 		direction=Seq_strand_minus;
1244 
1245 	/*save the new position*/
1246 	vdp->UDV_ms.oldPos=vdp->UDV_ms.newPos=*pt;
1247 	vdp->UDV_ms.old_col=bsp_coord;
1248 	vdp->UDV_ms.old_pgp=cur_pgp;
1249 
1250 	/*when udv displays a reverse/complement sequence, bsp_coords are
1251 	actually display coords. So, I have to convert them.*/
1252 	if (vdp->bDisplayRevComp){
1253 		bsp_coord=UDV_RevertBioSeqCoord(bsp_coord,vdp->bsp_i.bspLength);
1254 		first_bsp_coord=UDV_RevertBioSeqCoord(first_bsp_coord,vdp->bsp_i.bspLength);
1255 	}
1256 	/*'from' (first_bsp_coord) always less than 'to' (bsp_coord)*/
1257 	if (first_bsp_coord>bsp_coord)
1258 		swap(&first_bsp_coord,&bsp_coord);
1259 
1260 	/*now, we can send the Select message*/
1261 	/* first_pgp, old_pgp & cur_pgp have the same sip...
1262 	they are on a same row; I can use one of them*/
1263 	bsp_eID=ObjMgrGetEntityIDForPointer((Pointer)vdp->bsp_i.bsp);
1264 	bsp_iID = GetItemIDGivenPointer (bsp_eID,
1265 			OBJ_BIOSEQ, (Pointer) vdp->bsp_i.bsp);
1266 	if (bsp_eID!=0 && bsp_iID!=0){
1267 		if (dblClick){
1268 			UDV_LoadSpecificEditor(vdp->bvp,bsp_eID,bsp_iID,OBJ_BIOSEQ);
1269 			return;
1270 		}
1271 
1272 		if (shftKey){
1273 			slp=UDV_GetClosetSeqLocGivenBspPos(vdp->bsp_i.bsp->id,bsp_eID,
1274 				bsp_iID, bsp_coord, &old_pos, TRUE);
1275 		}
1276 		else{
1277 			slp = SeqLocIntNew (first_bsp_coord, bsp_coord, direction,
1278 				vdp->bsp_i.bsp->id);
1279 		}
1280 		if (slp){
1281 			ObjMgrAlsoSelect (bsp_eID, bsp_iID,
1282 					OBJ_BIOSEQ,OM_REGION_SEQLOC, slp);
1283 		}
1284 	}
1285 }
1286 #endif /*WWW_UDV*/
1287 
1288 /*****************************************************************************
1289 
1290 Function: UDV_AutoSelectAllSeq()
1291 
1292 Purpose: send a Msg to select/deselect the full sequnce
1293 
1294 Return value: none
1295 
1296 *****************************************************************************/
1297 #ifndef WWW_UDV
UDV_AutoSelectAllSeq(ViewerDialogDataPtr vdp,Boolean bSelect)1298 static void UDV_AutoSelectAllSeq(ViewerDialogDataPtr vdp,Boolean bSelect)
1299 {
1300 SeqLocPtr   slp;
1301 Uint2       bsp_eID;
1302 Uint4       bsp_iID;
1303 
1304 	slp = SeqLocIntNew (0, vdp->bsp_i.bspLength-1, Seq_strand_plus,
1305 			vdp->bsp_i.bsp->id);
1306 	bsp_eID=ObjMgrGetEntityIDForPointer((Pointer)vdp->bsp_i.bsp);
1307 	bsp_iID = GetItemIDGivenPointer (bsp_eID,
1308 			OBJ_BIOSEQ, (Pointer) vdp->bsp_i.bsp);
1309 	if (bsp_eID!=0 && bsp_iID!=0 && slp){
1310 		if (bSelect)
1311 			ObjMgrSelect (bsp_eID, bsp_iID,
1312 				OBJ_BIOSEQ,OM_REGION_SEQLOC, slp);
1313 		else
1314 			ObjMgrDeSelect (bsp_eID, bsp_iID,
1315 				OBJ_BIOSEQ,OM_REGION_SEQLOC, slp);
1316 	}
1317 	else{
1318 		if (slp) SeqLocFree(slp);
1319 	}
1320 }
1321 #endif /*WWW_UDV*/
1322 
1323 #ifndef WWW_UDV
UDV_SelectFeatInFeatDlg(ViewerMainPtr vmp,Uint2 entityID,Uint4 itemID)1324 NLM_EXTERN void UDV_SelectFeatInFeatDlg(ViewerMainPtr vmp, Uint2 entityID, Uint4 itemID)
1325 {
1326 FLMDataPtr	pflm;
1327 
1328 	if (!vmp->hFeatDlg) return;
1329 
1330 	pflm=(FLMDataPtr)GetObjectExtra(vmp->hFeatDlg);
1331 	if (pflm){
1332 		Int1 Choice;
1333 		ScanFeatForSelect 	sffs;
1334 		Boolean SeqFeatListAvail[SEQFEAT_MAX];
1335 
1336 		Choice=pflm->SeqFeatClass[GetValue(pflm->pop)-1];
1337 		sffs.eID=entityID;
1338 		sffs.iID=itemID;
1339 		sffs.index=0;
1340 		sffs.compteur=0;
1341 		MemSet(sffs.SeqFeatListAvail,0,
1342 				sizeof(sffs.SeqFeatListAvail));
1343 		if (Choice==0){/*0 means All*/
1344 			MemSet(SeqFeatListAvail,1,
1345 					sizeof(SeqFeatListAvail));
1346 		}
1347 		else{/*otherwise search only a particular feat.*/
1348 			MemSet(SeqFeatListAvail,0,
1349 					sizeof(SeqFeatListAvail));
1350 			SeqFeatListAvail[Choice]=TRUE;
1351 		}
1352 		SeqMgrExploreFeatures (vmp->vdp->bsp_i.bsp,
1353 			(Pointer) &sffs,UDV_FeaturesListBoxFind,
1354 			NULL, SeqFeatListAvail, NULL);
1355 		if (sffs.index>0)
1356 			OwnerDrawLbox_SelectItem(pflm->lbox,sffs.index);
1357 	}
1358 }
1359 #endif /*WWW_UDV*/
1360 
1361 
1362 
1363 /*****************************************************************************
1364 
1365 Function: UDV_ClickProc()
1366 
1367 Purpose: manage Mouse-Click; this function is designed for the autonomous viewer
1368 		to manage the InfoPanel and the Features List Dialog Box
1369 		DON'T USE FOR EXTERNAL SOFTWARE...
1370 
1371 Parameters:	p; panel handle (currently unused)
1372 			pt; new mouse position
1373 
1374 Return value: none
1375 
1376 *****************************************************************************/
1377 #ifndef WWW_UDV
UDV_ClickProc(PaneL p,PoinT pt)1378 NLM_EXTERN void UDV_ClickProc(PaneL p, PoinT pt)
1379 {
1380 ViewerDialogDataPtr vdp;
1381 ValNodePtr 			vnp;
1382 ViewerMainPtr		vmp;
1383 ParaGPtr 			pgp=NULL;
1384 RecT 				rc,rcP;
1385 Int4 				decal_top,pos,decal,limit,dec,dec2;
1386 Boolean 			bFind=FALSE;
1387 Int2				decal_left;
1388 
1389 	/*get some usefull data...*/
1390 	vdp = (ViewerDialogDataPtr) GetObjectExtra (p);
1391 	if (vdp == NULL) return;
1392 
1393 	/*Select(p);*/
1394 	dec=vdp->udv_graph.udv_panel.cxName+
1395 			vdp->udv_graph.udv_scale.cxLeftScale+
1396 			vdp->udv_graph.udv_font.cxChar;
1397 	dec2=dec+(vdp->udv_graph.udv_panel.nCharByLine+
1398 		vdp->udv_graph.udv_panel.nBlockByLine)*
1399 		vdp->udv_graph.udv_font.cxChar;
1400 	/*is the mouse located in the ParaG or Name region ?*/
1401 	if (pt.x>=dec && pt.x<=dec2){
1402 		ObjectRect(p,&rcP);
1403 		decal_top=vdp->udv_graph.udv_vscrl.ScrollPos*
1404 				vdp->udv_graph.udv_font.LineHeight-VIEWER_VERT_MARGIN;
1405 		decal_left=vdp->udv_graph.udv_panel.cxName+rcP.left+
1406 				vdp->udv_graph.udv_scale.cxLeftScale;
1407 		if (vdp->udv_graph.udv_vscrl.ScrollPage>0)
1408 			limit=decal_top+vdp->udv_graph.udv_vscrl.ScrollPage*
1409 				vdp->udv_graph.udv_font.LineHeight+rcP.top;
1410 		else
1411 			limit=decal_top+vdp->udv_graph.udv_panel.nTotLines*
1412 				vdp->udv_graph.udv_font.LineHeight+rcP.top;
1413 		/*look for the ParaG*/
1414 		if (vdp->ParaG){
1415 			for(vnp=vdp->ParaG ; vnp!=NULL ; vnp=vnp->next){
1416 				if (vnp->data.ptrvalue){
1417 					pgp=(ParaGPtr)vnp->data.ptrvalue;
1418 
1419 					/*Compute rect*/
1420 					decal=pgp->StartLine*
1421 							vdp->udv_graph.udv_font.LineHeight+rcP.top;
1422 					if (decal>limit) break;
1423 					if (decal>=decal_top){
1424 						rc=UDV_calc_RCdraw(pgp->StartLine,pgp->nLines,rcP,
1425 							decal_left,decal_top,
1426 							vdp->udv_graph.udv_font.LineHeight);
1427 						if (PtInRect(pt,&rc)){
1428 							vdp->UDV_ms.rcClip=rc;
1429 							bFind=TRUE;
1430 							break;
1431 						}
1432 					}
1433 				}
1434 			}
1435 		}
1436 		if (bFind){
1437 			Boolean ClickFeat=FALSE;
1438 			Uint2 entityID;
1439 			Uint4 itemID;
1440 			Uint2 itemType;
1441 			Uint2 index;
1442 			/*the user clicked on a feature ?*/
1443 			if (vdp->udv_graph.udv_panel.ShowFeatures &&
1444 				vdp->UDV_ms.Action_type==MS_ACTION_FEAT_NOTHING){
1445 				ClickFeat=UDV_click_item(&vdp->udv_graph,pt,rc,pgp,vdp->bsp_i,
1446 					&entityID,&itemID,&itemType,&index);
1447 				if (ClickFeat) {
1448 					if (dblClick){
1449 						UDV_LoadSpecificEditor(vdp->bvp,entityID,itemID,itemType);
1450 					}
1451 					else{
1452 						ObjMgrDeSelectAll();
1453 						ObjMgrSelect(entityID,itemID,OBJ_SEQFEAT,0,NULL);
1454 						/*this line if for Cn3D only*/
1455 						ObjMgrSendMsg(OM_MSG_MOUSEUP, entityID, itemID, OBJ_BIOSEQ);
1456 						if (vdp->Parent)
1457 							vmp=(ViewerMainPtr)GetObjectExtra(vdp->Parent);
1458 						if (vmp && vmp->hFeatDlg){/*update Features List Dlg if needed;
1459 							to do : convert this Feature ListBox to a real Viewer able
1460 							to play with ObjMgr*/
1461 							UDV_SelectFeatInFeatDlg(vmp,entityID,itemID);
1462 						}
1463 					}
1464 				}
1465 			}
1466 			/*click outside a feature*/
1467 			if (!ClickFeat){/*disable old feat select, then select letters*/
1468 				/*prepare the deselection*/
1469 				vdp->Old_Item_select=vdp->Item_select;
1470 				vdp->Item_select.eIDsel=(Uint2)-1;
1471 				vdp->Item_select.iIDsel=(Uint2)-1;
1472 				vdp->Item_select.iTypeSel=(Uint2)-1;
1473 				/*draw viewer: do the deselection*/
1474 				UDV_draw_viewer(p);
1475 				/*feat select is now invalidated*/
1476 				vdp->Item_select=vdp->Old_Item_select;
1477 
1478 				/*deselect letters ?*/
1479 				if (!(ctrlKey || shftKey))
1480 					ObjMgrDeSelectAll ();
1481 
1482 				pos=UDV_calc_pos(&vdp->udv_graph,&pt,&vdp->UDV_ms.rcClip,
1483 					pgp,NULL)-1;
1484 				vdp->UDV_ms.newPos=pt;
1485 				vdp->UDV_ms.Action_type=MS_ACTION_SELECT_SEQ;
1486 				vdp->UDV_ms.first_col=pos;
1487 				vdp->UDV_ms.first_pgp=pgp;
1488 				UDV_SendBSPSelectMsg(vdp, pos, pgp, &pt);
1489 			}
1490 		}
1491 	}else
1492 	/*is the mouse located on the 3D line (between Name list region and ParaG) ?*/
1493 	if (pt.x>=vdp->udv_graph.udv_panel.cxName &&
1494 		pt.x<=vdp->udv_graph.udv_panel.cxName+3){
1495 			ObjectRect(p,&rc);
1496 			rc.left=5*vdp->udv_graph.udv_font.cxChar; /*min value*/
1497 			rc.right=2*PANEL_NAME_WIDTH*vdp->udv_graph.udv_font.cxChar;/*max val*/
1498 			pt.x=vdp->udv_graph.udv_panel.cxName;
1499 			vdp->UDV_ms.oldPos=pt;
1500 			vdp->UDV_ms.newPos=pt;
1501 			vdp->UDV_ms.rcClip=rc;
1502 			vdp->UDV_ms.Action_type=MS_ACTION_RESIZE_WIN;
1503 			InvertMode();
1504 			UDV_draw_double_cursor(vdp->UDV_ms.rcClip,
1505 				vdp->UDV_ms.oldPos);
1506 			CrossCursor();
1507 	}
1508 	else{
1509 		WindoW temport;
1510 		Uint2 bsp_eID,bsp_iID;
1511 			/*deselect the sequence*/
1512 			ObjMgrDeSelectAll ();
1513 			/*deselection of a the feature*/
1514 			memset(&vdp->Item_select,(Uint2)-1,sizeof(vdp->Item_select));
1515 			memset(&vdp->Old_Item_select,(Uint2)-1,sizeof(vdp->Old_Item_select));
1516 			temport=SavePort((WindoW)p);
1517 			Select(p);
1518 			ObjectRect(p,&rc);
1519 			InvalRect(&rc);
1520 			RestorePort(temport);
1521 			if (vdp->InfoPanel){
1522 				SetTitle(vdp->InfoPanel,"Ready !");
1523 			}
1524 			/*this line if for Cn3D only*/
1525             bsp_eID=ObjMgrGetEntityIDForPointer((Pointer)vdp->bsp_i.bsp);
1526 	        bsp_iID = GetItemIDGivenPointer (bsp_eID,
1527 			                        OBJ_BIOSEQ, (Pointer) vdp->bsp_i.bsp);
1528 			ObjMgrSendMsg(OM_MSG_MOUSEUP, bsp_eID, bsp_iID, OBJ_BIOSEQ);
1529 	}
1530 }
1531 #endif /*WWW_UDV*/
1532 
1533 
1534 /*****************************************************************************
1535 
1536 Function: UDV_ManageDragHoldActions()
1537 
1538 Purpose: manage Mouse-Drag and Mouse-Hold for sequence letters selection ONLY
1539 
1540 Parameters:	p; panel handle (currently unused)
1541 			vdp; viewer data struct
1542 			pt; new position
1543 
1544 Return value: none
1545 
1546 *****************************************************************************/
1547 #ifndef WWW_UDV
UDV_ManageDragHoldActions(PaneL p,ViewerDialogDataPtr vdp,PoinT pt,Boolean bHold)1548 void UDV_ManageDragHoldActions(PaneL p, ViewerDialogDataPtr vdp,PoinT pt,
1549 	Boolean bHold)
1550 {
1551 ValNodePtr 			vnp;
1552 ParaGPtr 			pgp=NULL;
1553 RecT 				rc,rcP;
1554 Int4 				decal_top,pos,nLines,decal,limit;
1555 Boolean 			bFind=FALSE;
1556 Int2				decal_left;
1557 
1558 	/*does the mouse located in the ParaG or Name region ?*/
1559 	if ((pt.x>(vdp->udv_graph.udv_panel.cxName+
1560 			vdp->udv_graph.udv_scale.cxLeftScale+
1561 			vdp->udv_graph.udv_font.cxChar))){
1562 
1563 		ObjectRect(p,&rcP);
1564 		decal_top=vdp->udv_graph.udv_vscrl.ScrollPos*
1565 				vdp->udv_graph.udv_font.LineHeight-VIEWER_VERT_MARGIN;
1566 		decal_left=vdp->udv_graph.udv_panel.cxName+rcP.left+
1567 				vdp->udv_graph.udv_scale.cxLeftScale;
1568 		if (vdp->udv_graph.udv_vscrl.ScrollPage>0)
1569 			limit=decal_top+vdp->udv_graph.udv_vscrl.ScrollPage*
1570 				vdp->udv_graph.udv_font.LineHeight+rcP.top;
1571 		else
1572 			limit=decal_top+vdp->udv_graph.udv_panel.nTotLines*
1573 				vdp->udv_graph.udv_font.LineHeight+rcP.top;
1574 		/*look for the ParaG*/
1575 		if (vdp->ParaG){
1576 			nLines=0;
1577 			if (vdp->udv_graph.udv_scale.ShowMajorTick) nLines++;
1578 			if (vdp->udv_graph.udv_scale.ScalePosition==SCALE_POS_TOP ||
1579 					vdp->udv_graph.udv_scale.ScalePosition==SCALE_POS_BOTH) nLines++;
1580 			for(vnp=vdp->ParaG ; vnp!=NULL ; vnp=vnp->next){
1581 				if (vnp->data.ptrvalue){
1582 					pgp=(ParaGPtr)vnp->data.ptrvalue;
1583 					/*Compute rect; because drag is allowed only for selection
1584 					of letters, restrict the RecT on the sequence*/
1585 					decal=pgp->StartLine*
1586 							vdp->udv_graph.udv_font.LineHeight+rcP.top;
1587 					if (decal>limit) break;
1588 					if (decal>=decal_top){
1589 						rc=UDV_calc_RCdraw(pgp->StartLine+nLines,1,rcP,
1590 							decal_left,decal_top,
1591 							vdp->udv_graph.udv_font.LineHeight);
1592 						if (PtInRect(pt,&rc)){
1593 							vdp->UDV_ms.rcClip=rc;
1594 							bFind=TRUE;
1595 							break;
1596 						}
1597 					}
1598 				}
1599 			}
1600 		}
1601 		if (bHold){/*vertical auto-scroll, if needed (only on Hold mouse action)*/
1602 			BaR vsb;
1603 			Int4 old_pos;
1604 
1605 				vsb = GetSlateVScrollBar ((SlatE) vdp->UnDViewer);
1606 				old_pos=GetBarValue(vsb);
1607 				if (pt.y>=rcP.bottom-15){
1608 					SetValue(vsb,old_pos+2);
1609 				}
1610 				else if (pt.y<=rcP.top+15){
1611 					SetValue(vsb,old_pos-2);
1612 				}
1613 		}
1614 		if (bFind){
1615 			pos=UDV_calc_pos(&vdp->udv_graph,&pt,&vdp->UDV_ms.rcClip,
1616 				pgp,NULL)-1;
1617 			if (vdp->UDV_ms.old_col==pos)
1618 				return;
1619 			UDV_SendBSPSelectMsg(vdp, pos, pgp, &pt);
1620 		}
1621 	}
1622 }
1623 #endif /*WWW_UDV*/
1624 
1625 /*****************************************************************************
1626 
1627 Function: UDV_DragMouse()
1628 
1629 Purpose: manage Mouse-Drag
1630 
1631 Parameters:	p; panel handle (currently unused)
1632 			vdp; viewer data struct
1633 			pt; new position
1634 
1635 Note: this function MUST be called by external software using this viewer
1636 
1637 Return value: none
1638 
1639 *****************************************************************************/
1640 #ifndef WWW_UDV
UDV_DragMouse(PaneL p,ViewerDialogDataPtr vdp,PoinT pt)1641 NLM_EXTERN void UDV_DragMouse(PaneL p, ViewerDialogDataPtr vdp,PoinT pt)
1642 {
1643 
1644 	if (vdp == NULL) return;
1645 
1646 	switch(vdp->UDV_ms.Action_type){
1647 		case MS_ACTION_FEAT_NOTHING:
1648 			break;
1649 		case MS_ACTION_SELECT_SEQ:
1650 			UDV_ManageDragHoldActions(p,vdp,pt,FALSE);
1651 			break;
1652 		case MS_ACTION_RESIZE_WIN:
1653 			InvertMode();
1654 			UDV_draw_double_cursor(vdp->UDV_ms.rcClip,
1655 				vdp->UDV_ms.oldPos);
1656 			vdp->UDV_ms.newPos=pt;
1657 			UDV_draw_double_cursor(vdp->UDV_ms.rcClip,
1658 				vdp->UDV_ms.newPos);
1659 			vdp->UDV_ms.oldPos=vdp->UDV_ms.newPos;
1660 			Update();
1661 			break;
1662 	}
1663 }
1664 #endif /*WWW_UDV*/
1665 
1666 /*****************************************************************************
1667 
1668 Function: UDV_DragProc()
1669 
1670 Purpose: manage Mouse-Drag
1671 
1672 Parameters:	p; panel handle (currently unused)
1673 			pt; new position
1674 
1675 Return value: none
1676 
1677 *****************************************************************************/
1678 #ifndef WWW_UDV
UDV_DragProc(PaneL p,PoinT pt)1679 NLM_EXTERN void UDV_DragProc(PaneL p, PoinT pt)
1680 {
1681 ViewerDialogDataPtr vdp;
1682 
1683 	/*get some usefull data...*/
1684 	vdp = (ViewerDialogDataPtr) GetObjectExtra (p);
1685 
1686 	UDV_DragMouse(p,vdp,pt);
1687 }
1688 #endif /*WWW_UDV*/
1689 
1690 /*****************************************************************************
1691 
1692 Function: UDV_ReleaseMouse()
1693 
1694 Purpose: manage Mouse-Release
1695 
1696 Parameters:	p; panel handle (currently unused)
1697 			vdp; viewer data struct
1698 			pt; new position
1699 
1700 Note: this function MUST be called by external software using this viewer
1701 
1702 Return value: none
1703 
1704 *****************************************************************************/
1705 #ifndef WWW_UDV
UDV_ReleaseMouse(PaneL p,ViewerDialogDataPtr vdp,PoinT pt)1706 NLM_EXTERN void UDV_ReleaseMouse(PaneL p,ViewerDialogDataPtr vdp, PoinT pt)
1707 {
1708 Uint2       bsp_eID;
1709 Uint4       bsp_iID;
1710 
1711 	if (vdp == NULL) return;
1712 
1713 	switch(vdp->UDV_ms.Action_type){
1714 		case MS_ACTION_FEAT_NOTHING:
1715             bsp_eID=ObjMgrGetEntityIDForPointer((Pointer)vdp->bsp_i.bsp);
1716 	        bsp_iID = GetItemIDGivenPointer (bsp_eID,
1717 			                        OBJ_BIOSEQ, (Pointer) vdp->bsp_i.bsp);
1718 			break;
1719 		case MS_ACTION_SELECT_SEQ:
1720             bsp_eID=ObjMgrGetEntityIDForPointer((Pointer)vdp->bsp_i.bsp);
1721 	        bsp_iID = GetItemIDGivenPointer (bsp_eID,
1722 			                        OBJ_BIOSEQ, (Pointer) vdp->bsp_i.bsp);
1723             ObjMgrSendMsg(OM_MSG_MOUSEUP, bsp_eID, bsp_iID, OBJ_BIOSEQ);
1724 			break;
1725 		case MS_ACTION_RESIZE_WIN:
1726 			InvertMode();
1727 			UDV_draw_double_cursor(vdp->UDV_ms.rcClip,
1728 				vdp->UDV_ms.oldPos);
1729 			/*redraw panel with new 'cxName' value*/
1730 			if (PtInRect(vdp->UDV_ms.newPos,&vdp->UDV_ms.rcClip)){
1731 				RecT rc;
1732 
1733 				ObjectRect(p,&rc);
1734 				rc.left=0;/*for obscure reasons, not == 0*/
1735 				rc.top=0;
1736 				vdp->udv_graph.udv_panel.cxName=vdp->UDV_ms.newPos.x;
1737 				UDV_resize_viewer( p, vdp);
1738 				InvalRect(&rc);
1739 			}
1740 			break;
1741 	}
1742 
1743   ClearUDV_mouse_select(&(vdp->UDV_ms));
1744 	vdp->UDV_ms.Action_type=MS_ACTION_FEAT_NOTHING;
1745 	ArrowCursor();
1746 }
1747 #endif /*WWW_UDV*/
1748 
1749 /*****************************************************************************
1750 
1751 Function: UDV_ReleaseProc()
1752 
1753 Purpose: manage Mouse-Release
1754 
1755 Parameters:	p; panel handle (currently unused)
1756 			pt; new position
1757 
1758 Return value: none
1759 
1760 *****************************************************************************/
1761 #ifndef WWW_UDV
UDV_ReleaseProc(PaneL p,PoinT pt)1762 NLM_EXTERN void UDV_ReleaseProc(PaneL p, PoinT pt)
1763 {
1764 ViewerDialogDataPtr vdp;
1765 
1766 	/*get some usefull data...*/
1767 	vdp = (ViewerDialogDataPtr) GetObjectExtra (p);
1768 
1769 	UDV_ReleaseMouse(p,vdp,pt);
1770 }
1771 #endif /*WWW_UDV*/
1772 
1773 
1774 /*****************************************************************************
1775 
1776 Function: UDV_HoldProc()
1777 
1778 Purpose: manage Mouse-Hold
1779 
1780 Parameters:	p; panel handle (currently unused)
1781 			pt; new position
1782 
1783 Return value: none
1784 
1785 *****************************************************************************/
1786 #ifndef WWW_UDV
UDV_HoldProc(PaneL p,PoinT pt)1787 NLM_EXTERN void UDV_HoldProc(PaneL p, PoinT pt)
1788 {
1789 ViewerDialogDataPtr vdp;
1790 
1791 	/*get some usefull data...*/
1792 	vdp = (ViewerDialogDataPtr) GetObjectExtra (p);
1793 
1794 	if (vdp==NULL) return;
1795 
1796 	switch(vdp->UDV_ms.Action_type){
1797 		case MS_ACTION_FEAT_NOTHING:
1798 			break;
1799 		case MS_ACTION_SELECT_SEQ:
1800 			UDV_ManageDragHoldActions(p,vdp,pt,TRUE);
1801 			break;
1802 		case MS_ACTION_RESIZE_WIN:
1803 			break;
1804 		default:
1805 			break;
1806 	}
1807 }
1808 #endif
1809 
1810 /*******************************************************************************
1811 
1812   Function : UDV_draw_helixDNA()
1813 
1814   Purpose : draw a little peace of a DNA helix for the NCBI logo
1815 
1816   Parameters :	x,y; start position of the helix
1817   				cxChar,cyChar; size of the current font
1818 				bEnd; if True; draw half an helix
1819 
1820   Return value : none
1821 
1822 *******************************************************************************/
UDV_draw_helixDNA(Int2 x,Int2 y,Int2 cxChar,Int2 cyChar,Boolean bEnd)1823 static void UDV_draw_helixDNA(Int2 x,Int2 y,Int2 cxChar,Int2 cyChar,
1824 		Boolean bEnd)
1825 {
1826 
1827 Int2 cxChar_2,cyChar_2;
1828 PoinT box[4];
1829 
1830 	cxChar_2=cxChar/2;
1831 	cyChar_2=cyChar/2;
1832 	SetColor(GetColorRGB(0,0,255));
1833 	/*1*/
1834 	box[0].x=x+cxChar_2;
1835 	box[0].y=y+2*cyChar;
1836 	box[1].x=x;
1837 	box[1].y=box[0].y-cyChar;
1838 	box[2].x=x+cxChar;
1839 	box[2].y=box[1].y;
1840 	box[3].x=box[2].x+cxChar_2;
1841 	box[3].y=box[0].y;
1842 
1843 	PaintPoly(4,box);
1844 
1845 	SetColor(GetColorRGB(0,0,128));
1846 	/*2*/
1847 	box[0].x=box[3].x;
1848 	box[0].y=box[3].y;
1849 	box[1].x=box[2].x;
1850 	box[1].y=box[2].y;
1851 	box[2].x=box[1].x+2*cxChar+cxChar_2;
1852 	box[2].y=box[0].y-5*cyChar;
1853 	box[3].x=box[2].x+cxChar_2;
1854 	box[3].y=box[2].y+cyChar;
1855 	PaintPoly(4,box);
1856 
1857 	if (!bEnd){
1858 		SetColor(GetColorRGB(0,0,255));
1859 		/*3*/
1860 		box[0].x=box[3].x;
1861 		box[0].y=box[3].y;
1862 		box[1].x=box[2].x;
1863 		box[1].y=box[2].y;
1864 		box[2].x=box[1].x+cxChar;
1865 		box[2].y=box[1].y;
1866 		box[3].x=box[2].x+cxChar_2;
1867 		box[3].y=box[0].y;
1868 		PaintPoly(4,box);
1869 	}
1870 
1871 	SetColor(GetColorRGB(128,0,128));
1872 	/*4*/
1873 	box[0].x=x;
1874 	box[0].y=y-2*cyChar;
1875 	box[1].x=x+cxChar_2;
1876 	box[1].y=box[0].y-cyChar;
1877 	box[2].x=box[0].x+cxChar;
1878 	box[2].y=box[0].y;
1879 	PaintPoly(3,box);
1880 
1881 	if (!bEnd){
1882 		SetColor(GetColorRGB(192,92,192));
1883 		/*5*/
1884 		box[0].x=box[1].x;
1885 		box[0].y=box[1].y;
1886 		box[1].x=box[0].x+cxChar;
1887 		box[1].y=box[0].y;
1888 		box[2].x=box[1].x+3*cxChar;
1889 		box[2].y=box[0].y+5*cyChar;
1890 		box[3].x=box[2].x-cxChar;
1891 		box[3].y=box[2].y;
1892 		PaintPoly(4,box);
1893 
1894 		SetColor(GetColorRGB(128,0,128));
1895 		/*7*/
1896 		box[0].x=box[2].x;
1897 		box[0].y=box[2].y;
1898 		box[1].x=box[0].x-cxChar_2;
1899 		box[1].y=box[0].y-cyChar;
1900 		box[2].x=box[1].x+2*cxChar;
1901 		box[2].y=box[1].y-3*cyChar;
1902 		box[3].x=box[2].x+cxChar;
1903 		box[3].y=box[2].y;
1904 		PaintPoly(4,box);
1905 
1906 		SetColor(GetColorRGB(0,0,255));
1907 		/*8*/
1908 		box[0].x=x+4*cxChar;
1909 		box[0].y=y-2*cyChar;
1910 		box[1].x=box[0].x+cxChar;
1911 		box[1].y=box[0].y;
1912 		box[2].x=box[0].x+2*cxChar+cxChar_2+cxChar_2;
1913 		box[2].y=box[0].y+3*cyChar;
1914 		box[3].x=box[2].x-cxChar;
1915 		box[3].y=box[2].y;
1916 		PaintPoly(4,box);
1917 	}
1918 	Black();
1919 }
1920 
1921 /*******************************************************************************
1922 
1923   Function : draw_logo()
1924 
1925   Purpose : draw the NCBI logo for the main window
1926 
1927   Parameters :	rcP; where to put the logo
1928   				f1,f2,f3; the fonts used to display the logo text
1929 
1930   Return value : none
1931 
1932 *******************************************************************************/
1933 #ifndef WWW_UDV
draw_logo(RecT rcP,FonT f1,FonT f2,FonT f3,CharPtr szTxt0,CharPtr szTxt4)1934 static void  draw_logo(RecT rcP,FonT f1,FonT f2,FonT f3,CharPtr szTxt0,
1935 	CharPtr szTxt4)
1936 {
1937 Char szTxt1[]="01101011";
1938 Char szTxt2[]="National Center for";
1939 Char szTxt3[]="Biotechnology Information";
1940 Int2 pos,cxChar=7,cyChar=13,cxGlobal,cyGlobal;
1941 Int2 w1,w2,w3,y,x;
1942 RecT rcL;
1943 
1944 	/*some computation for positionning*/
1945 	SelectFont(f1);
1946 	w1=StringWidth(szTxt1);
1947 	SelectFont(f2);
1948 	w2=StringWidth(szTxt2);
1949 	w3=StringWidth(szTxt3);
1950 	cxGlobal=22*cxChar+w1+w2;
1951 	cyGlobal=10*cyChar;
1952 	x=(rcP.right-rcP.left)/2;
1953 	y=(rcP.bottom-rcP.top)/2;
1954 	rcL.left=rcP.left+x-(cxGlobal/2);
1955 	rcL.top=rcP.top+y-(6*cyChar)/2;
1956 	rcL.right=rcL.left+cxGlobal;
1957 	rcL.bottom=rcL.top+6*cyChar;
1958 
1959 	/*double DNA helix*/
1960 	UDV_draw_helixDNA(rcL.left,rcL.bottom,cxChar,cyChar,FALSE);
1961 	UDV_draw_helixDNA((Int2)(rcL.left+6*cxChar),rcL.bottom,cxChar,cyChar,FALSE);
1962 	UDV_draw_helixDNA((Int2)(rcL.left+12*cxChar),rcL.bottom,cxChar,cyChar,TRUE);
1963 
1964 	/*Undviewer*/
1965 	SelectFont(f3);
1966 	Blue();
1967 	MoveTo((Int2)(rcL.left+2*cxChar),(Int2)(rcL.bottom-6*cyChar));
1968 	PaintString(szTxt0);
1969 
1970 	Black();
1971 	MoveTo((Int2)(rcL.left+StringWidth(szTxt0)+3*cxChar),(Int2)(rcL.bottom-6*cyChar));
1972 	SelectFont(f1);
1973 	PaintString(szTxt4);
1974 
1975 	/*01101011*/
1976 	pos=rcL.left+13*cxChar;
1977 	SelectFont(f1);
1978 	Black();
1979 	MoveTo(pos,rcL.bottom);
1980 	PaintString(szTxt1);
1981 	pos+=w1;
1982 
1983 	/*NCBI*/
1984 	SelectFont(f2);
1985 	pos+=(w3/2+2*cxChar);
1986 
1987 	MoveTo((Int2)(pos-w2/2),(Int2)(rcL.bottom-cyChar));
1988 	PaintString(szTxt2);
1989 	MoveTo((Int2)(pos-w3/2),(Int2)(rcL.bottom+cyChar));
1990 	PaintString(szTxt3);
1991 }
1992 #endif /*WWW_UDV*/
1993 
1994 /*******************************************************************************
1995 
1996   Function : UDV_draw_select()
1997 
1998   Purpose : draw a rect around a selected item
1999 
2000   Parameters :	rc; rect coordinates
2001 
2002   Return value : none
2003 
2004 *******************************************************************************/
UDV_draw_select(RecT rc)2005 static void  UDV_draw_select(RecT rc)
2006 {
2007 	Dotted();
2008 	FrameRect(&rc);
2009 	Solid();
2010 }
2011 
2012 /*******************************************************************************
2013 
2014   Function : UDV_draw_ss_cont()
2015 
2016   Purpose : complete the end(s) of secondary structure to highlight the case
2017   			of a truncation at ParaG ends
2018 
2019   Parameters :	start; draw the arrow from...
2020 				stop;... to.
2021 				StartLetter; beginning of a ParaG (zero-based value)
2022 				cxChar; width of a letter
2023 				xMargin; draw in the ParaG on the right a this value
2024 				y2; vertical position to draw the sequence
2025 				ContinueRight; draw on the right only if TRUE
2026 				ContinueLeft; draw on the left only if TRUE
2027 
2028   Return value : none
2029 
2030 *******************************************************************************/
UDV_draw_ss_cont(Int4 start,Int4 stop,Int4 StartLetter,Int2 cxChar,Int2 xMargin,Int2 y2,Boolean ContinueRight,Boolean ContinueLeft)2031 static void  UDV_draw_ss_cont(Int4 start,Int4 stop,Int4 StartLetter,
2032 		Int2 cxChar,Int2 xMargin,Int2 y2,Boolean ContinueRight,
2033 		Boolean ContinueLeft)
2034 {
2035 Int2 x;
2036 
2037 	if (ContinueRight || ContinueLeft){
2038 		Dotted();
2039 		Red();
2040 	}
2041 	if (ContinueLeft){
2042 		x=(((start-StartLetter)+(start-StartLetter)/
2043 			LETTER_BLOCK_WIDTH)*cxChar)+xMargin-cxChar/2;
2044 
2045 		MoveTo(x,y2);
2046 		LineTo((Int2)(x-2*cxChar),y2);
2047 	}
2048 	if (ContinueRight){
2049 		Int4 stop2;
2050 		stop2=stop+((stop-start)/LETTER_BLOCK_WIDTH);
2051 		x=(((stop2-StartLetter)+(stop2-StartLetter)/
2052 			LETTER_BLOCK_WIDTH)*cxChar)+xMargin;
2053 
2054 		MoveTo(x,y2);
2055 		LineTo((Int2)(x+2*cxChar),y2);
2056 	}
2057 
2058 	if (ContinueRight || ContinueLeft){
2059 		Solid();
2060 		Black();
2061 	}
2062 }
2063 /*******************************************************************************
2064 
2065   Function : UDV_draw_struc_strand()
2066 
2067   Purpose : draw the strand (prot struct only) as an arrow
2068 
2069   Parameters :	start; draw the arrow from...
2070 				stop;... to.
2071 				StartLetter; beginning of a ParaG (zero-based value)
2072 				y; vertical position to draw the sequence
2073 				cxChar; width of a letter
2074 				cyChar; height of a letter
2075 				LineHeight; height of a feature line
2076 				xMargin; draw in the ParaG on the right a this value
2077 				clr; color
2078 				ContinueRight; draw on the right only if TRUE
2079 				ContinueLeft; draw on the left only if TRUE
2080 
2081   Return value : none
2082 
2083 *******************************************************************************/
UDV_draw_struc_strand(Int4 start,Int4 stop,Int4 StartLetter,Int2 y,Int2 cxChar,Int2 cyChar,Int2 LineHeight,Int2 xMargin,Uint4 clr,Boolean ContinueLeft,Boolean ContinueRight)2084 static void  UDV_draw_struc_strand(Int4 start,Int4 stop,Int4 StartLetter,
2085 			Int2 y,Int2 cxChar,Int2 cyChar,Int2 LineHeight,Int2 xMargin,
2086 			Uint4 clr,Boolean ContinueLeft,Boolean ContinueRight)
2087 {
2088 PoinT box[7];
2089 Int2 y2,x,cxChar_2,cyChar_2,cyChar_4;
2090 
2091 	y2=y-LineHeight/2;
2092 	cxChar_2=cxChar/2;
2093 	cyChar_4=cyChar/4;
2094 	cyChar_2=cyChar/2;
2095 
2096 	/*ContinueRight || ContinueLef: draw thin line to highlight continuous
2097 	secondary structure at ParaG ends*/
2098 	if (ContinueLeft || ContinueRight)
2099 		UDV_draw_ss_cont(start,stop,StartLetter,cxChar,xMargin,y2,ContinueRight,
2100 		ContinueLeft);
2101 	if (start!=stop){
2102 		x=(((start-StartLetter)+(start-StartLetter)/
2103 			LETTER_BLOCK_WIDTH)*cxChar)+xMargin+cxChar_2;
2104 
2105 		box[0].x=x-cxChar_2;
2106 		box[0].y=y2-cyChar_4;
2107 		box[6].x=box[0].x;
2108 		box[6].y=y2+cyChar_4;
2109 
2110 		/*3d effect*/
2111 		DkGray();
2112 		MoveTo((Int2)(box[0].x-1),(Int2)(box[0].y+1));
2113 		LineTo((Int2)(box[6].x-1),(Int2)(box[6].y+1));
2114 		MoveTo((Int2)(box[0].x-2),(Int2)(box[0].y+2));
2115 		LineTo((Int2)(box[6].x-2),(Int2)(box[6].y+2));
2116 
2117 		/*stop+=((stop-start)/LETTER_BLOCK_WIDTH);*/
2118 		x=(((stop-StartLetter)+(stop-StartLetter)/
2119 			LETTER_BLOCK_WIDTH)*cxChar)+xMargin;
2120 		x-=cxChar_2;
2121 
2122 		box[1].x=x-cxChar_2;
2123 		box[1].y=box[0].y;
2124 		box[2].x=box[1].x;
2125 		box[2].y=y2-cyChar_2;
2126 		box[3].x=x+cxChar_2;
2127 		box[3].y=y2;
2128 		box[4].x=box[1].x;
2129 		box[4].y=y2+cyChar_2;
2130 		box[5].x=box[1].x;
2131 		box[5].y=box[6].y;
2132 
2133 		/*3d effect*/
2134 		MoveTo((Int2)(box[6].x-1),(Int2)(box[6].y+1));
2135 		LineTo((Int2)(box[5].x),(Int2)(box[5].y+1));
2136 		LineTo((Int2)(box[4].x),(Int2)(box[4].y+1));
2137 		MoveTo((Int2)(box[6].x-2),(Int2)(box[6].y+2));
2138 		LineTo((Int2)(box[5].x-1),(Int2)(box[5].y+2));
2139 		LineTo((Int2)(box[4].x-1),(Int2)(box[4].y+2));
2140 
2141 		MoveTo(box[4].x,(Int2)(box[4].y+2));
2142 		LineTo(box[3].x,(Int2)(box[3].y+2));
2143 
2144 		if (clr!=(Uint4)-1) SetColor(clr);
2145 		else Black();
2146 		/*draw*/
2147 		PaintPoly(7,box);
2148 	}
2149 	else{/*if start==stop, draw only the end of the arrow*/
2150 		stop+=((stop-start)/LETTER_BLOCK_WIDTH);
2151 		x=(((stop-StartLetter)+(stop-StartLetter)/
2152 			LETTER_BLOCK_WIDTH)*cxChar)+xMargin/*-cxChar_2*/;
2153 
2154 		box[0].x=x-cxChar_2;
2155 		box[0].y=y2-cyChar_2;
2156 		box[1].x=x+cxChar_2;
2157 		box[1].y=y2;
2158 		box[2].x=box[0].x;
2159 		box[2].y=y2+cyChar_2;
2160 
2161 		/*3d effect*/
2162 		DkGray();
2163 		MoveTo((Int2)(box[0].x-1),(Int2)(box[0].y+1));
2164 		LineTo((Int2)(box[2].x-1),(Int2)(box[2].y+1));
2165 		MoveTo((Int2)(box[0].x-2),(Int2)(box[0].y+2));
2166 		LineTo((Int2)(box[2].x-2),(Int2)(box[2].y+2));
2167 		MoveTo((Int2)(box[2].x),(Int2)(box[2].y+2));
2168 		LineTo((Int2)(box[1].x),(Int2)(box[1].y+2));
2169 
2170 		if (clr!=(Uint4)-1) SetColor(clr);
2171 		else Black();
2172 		/*draw*/
2173 		PaintPoly(3,box);
2174 	}
2175 	Black();
2176 }
2177 
2178 
2179 /*******************************************************************************
2180 
2181   Function : UDV_draw_struc_helix()
2182 
2183   Purpose : draw the helix (prot struct only) as an helix
2184 
2185   Parameters :	start; draw the arrow from...
2186 				stop;... to.
2187 				StartLetter; beginning of a ParaG (zero-based value)
2188 				y; vertical position to draw the sequence
2189 				cxChar; width of a letter
2190 				cyChar; height of a letter
2191 				LineHeight; height of a feature line
2192 				xMargin; draw in the ParaG on the right a this value
2193 				clr; color
2194 				ContinueRight; draw on the right only if TRUE
2195 				ContinueLeft; draw on the left only if TRUE
2196 
2197   Return value : none
2198 
2199 *******************************************************************************/
UDV_draw_struc_helix(Int4 start,Int4 stop,Int4 StartLetter,Int2 y,Int2 cxChar,Int2 cyChar,Int2 LineHeight,Int2 xMargin,Uint4 clr,Boolean ContinueLeft,Boolean ContinueRight)2200 static void  UDV_draw_struc_helix(Int4 start,Int4 stop,Int4 StartLetter,
2201 			Int2 y,Int2 cxChar,Int2 cyChar,Int2 LineHeight,Int2 xMargin,
2202 			Uint4 clr,Boolean ContinueLeft,Boolean ContinueRight)
2203 {
2204 PoinT box[4],pt0,pt2;
2205 Int4 i;
2206 Int2 y2,x,xDecal,cxChar_2,cyChar_2,cxChar_4;
2207 Int1 status=DRAW_HELIX_DOWN;
2208 Boolean bContPrev=FALSE;
2209 
2210 	cxChar_2=cxChar/2;
2211 	cxChar_4=cxChar/4;
2212 	cyChar_2=cyChar/2;
2213 
2214 	y2=y-LineHeight/2;
2215 
2216 	/*ContinueRight || ContinueLef: draw thin line to highlight continuous
2217 	secondary structure at ParaG ends*/
2218 	if (ContinueLeft || ContinueRight)
2219 		UDV_draw_ss_cont(start,stop,StartLetter,cxChar,xMargin,y2,ContinueRight,
2220 		ContinueLeft);
2221 
2222 	/*stop+=((stop-start)/LETTER_BLOCK_WIDTH);*/
2223 	stop+=((stop-StartLetter)/LETTER_BLOCK_WIDTH)-
2224 		((start-StartLetter)/LETTER_BLOCK_WIDTH);
2225 
2226 	xDecal=((start-StartLetter)+((start-StartLetter)/LETTER_BLOCK_WIDTH))
2227 			*cxChar+xMargin;
2228 	for(i=start;i<=stop;i++){
2229 		x=(i-start)*cxChar+xDecal;
2230 		switch(status){
2231 			case DRAW_HELIX_DOWN:
2232 				/*compute polygon*/
2233 				box[0].x=x;
2234 				box[0].y=y2+cyChar_2;
2235 				box[1].x=x-cxChar_2;
2236 				box[1].y=y2;
2237 				box[2].x=x+cxChar_4;
2238 				box[2].y=y2;
2239 				box[3].x=x+cxChar_2+cxChar_4;
2240 				box[3].y=box[0].y;
2241 				/*set color*/
2242 				if (clr!=(Uint4)-1) SetColor(clr);
2243 				else LtGray();
2244 				/*draw*/
2245 				PaintPoly(4,box);
2246 				if (bContPrev){
2247 					box[1]=pt0;
2248 					box[3]=box[2];
2249 					box[2]=pt2;
2250 					bContPrev=FALSE;
2251 					PaintPoly(4,box);
2252 				}
2253 				/*after DRAW_HELIX_DOWN will trace a DRAW_HELIX_MIDDLE*/
2254 				status=DRAW_HELIX_MIDDLE;
2255 				break;
2256 			case DRAW_HELIX_MIDDLE:
2257 				/*compute polygon*/
2258 				box[0].x=x-cxChar_4;
2259 				box[0].y=y2+cyChar_2;
2260 				box[1].x=x-cxChar+cxChar_4;
2261 				box[1].y=y2;
2262 				box[2].x=x+cxChar_2-cxChar_4;
2263 				box[2].y=y2-cyChar_2;
2264 				box[3].x=x+cxChar-cxChar_4;
2265 				box[3].y=y2;
2266 				/*set color: always dark gray*/
2267 				DkGray();
2268 				/*draw*/
2269 				PaintPoly(4,box);
2270 				/*after DRAW_HELIX_MIDDLE will trace a DRAW_HELIX_UP*/
2271 				status=DRAW_HELIX_UP;
2272 				break;
2273 			case DRAW_HELIX_UP:
2274 				/*compute polygon*/
2275 				box[0].x=x-cxChar_4;
2276 				box[0].y=y2;
2277 				box[1].x=x-cxChar_2-cxChar_4;
2278 				box[1].y=y2-cyChar_2;
2279 				box[2].x=x;
2280 				box[2].y=box[1].y;
2281 				box[3].x=x+cxChar_2;
2282 				box[3].y=y2;
2283 				/*set color: always dark gray*/
2284 				if (clr!=(Uint4)-1) SetColor(clr);
2285 				else LtGray();
2286 				/*draw*/
2287 				PaintPoly(4,box);
2288 				/*after DRAW_HELIX_UP will trace a DRAW_HELIX_DOWN*/
2289 				status=DRAW_HELIX_DOWN;
2290 				bContPrev=TRUE;
2291 				pt0=box[0];
2292 				pt2=box[2];
2293 				break;
2294 		}
2295 	}
2296 	Black();
2297 }
2298 
2299 /*******************************************************************************
2300 
2301   Function : UDV_draw_CDS_minus()
2302 
2303   Purpose : draw the translation of a CDS located on a MINUS strand
2304 
2305   Parameters : context; feature data (see explore.h for a def of the structure)
2306   				start; draw the sequence from...
2307 				stop;... to.
2308 				StartLetter; beginning of a ParaG (zero-based value)
2309 				GrData; graphical data
2310 				y; vertical position to draw the sequence
2311 				i; order number of the exon (if CDS is exon-encoded)
2312 				xMargin; draw in the ParaG on the right a this value
2313 				UseDefClr; TRUE: draw the sequence using the DefClr value
2314 					Otherwise use GrData->AA_LayoutPal[] values
2315 
2316   Return value : none
2317 
2318 *******************************************************************************/
UDV_draw_CDS_minus(SeqMgrFeatContextPtr context,Int4 start,Int4 stop,Int4 StartLetter,UnDViewerGraphDataPtr GrData,Int2 y,Int2 i,Int2 xMargin,Boolean UseDefClr,Uint4 DefClr)2319 static void  UDV_draw_CDS_minus(SeqMgrFeatContextPtr context,Int4 start,
2320 			Int4 stop,Int4 StartLetter,UnDViewerGraphDataPtr GrData,Int2 y,
2321 			Int2 i,Int2 xMargin,Boolean UseDefClr,Uint4 DefClr)
2322 {
2323 CharPtr      	str=NULL;
2324 Int4			il=0,
2325 				pos=0,
2326 				n=0,
2327 				stop_prot=0;
2328 Int2 			nCompt=0,
2329 				decal=0,
2330 				x_prot=0,
2331 				y_prot=0,
2332 				numivals2=0,
2333 				cxChar_2;
2334 ByteStorePtr	bs=NULL;
2335 SeqIdPtr sip=NULL;
2336 Int4 gi=0;
2337 Boolean bGiForProductOk=FALSE;
2338 BioseqPtr prot;
2339 
2340 	/*retrieve the protein sequence; need to be optimized in future release*/
2341 	if (context->sfp->product){
2342 		prot=BioseqFind(SeqLocId(context->sfp->product));
2343 		sip=(SeqIdPtr)GetProductSeqId(context->sfp->product);
2344 		if (sip && prot){
2345 			CharPtr str2;
2346 			gi = GetGINumFromSip(sip);
2347 			if (gi>0) bGiForProductOk=TRUE;
2348 			str2=UDV_Read_Sequence (sip,0,prot->length-1,
2349 				TRUE,prot->length-1);
2350 			if (!str2) return;
2351 			str=str2;
2352 		}
2353 	}
2354 	else{
2355 		bs = ProteinFromCdRegion (context->sfp, TRUE);
2356 		if (bs){
2357 			str = (CharPtr) BSMerge (bs, NULL);
2358 			BSFree (bs);
2359 		}
2360 	}
2361 
2362 	if (!str) return;
2363 
2364 	/*count the lenght of the intron(s)*/
2365 	numivals2=context->numivals*2;
2366 	if (i>0){
2367 		for(nCompt=i;nCompt>0;nCompt-=2){
2368 			il+=(context->ivals[nCompt-2]-
2369 				context->ivals[nCompt+1]-1);
2370 		}
2371 	}
2372 
2373 	pos=context->ivals[1]-il-stop;
2374 	/*place the current position within the correct translation frame*/
2375 	if (pos % 3){
2376 		if (!((pos-1) % 3)){
2377 			pos=(pos-1)/3;
2378 			decal=-1;
2379 		}
2380 		else if (!((pos+1) % 3)){
2381 			pos=(pos+1)/3;
2382 			decal=1;
2383 		}
2384 	}else {
2385 		pos=pos/3;
2386 		decal=0;
2387 	}
2388 
2389 	n=pos;
2390 	stop_prot=stop-decal-1; /*-1 == middle of the codon*/
2391 	cxChar_2=GrData->udv_font.cxChar/2;
2392 
2393 	/*vertical pos: just below the CDS colour box (pos: y)*/
2394 	y_prot=y+GrData->udv_font.LineHeight-GrData->udv_font.cyChar/2;
2395 	/*NOTICE : I draw from right to left; whereas normally I draw always
2396 		from left to right*/
2397 	if (UseDefClr) SetColor(DefClr);
2398 
2399 	while(stop_prot>=start){
2400 		x_prot=((stop_prot-StartLetter)+
2401 				((stop_prot-StartLetter)/LETTER_BLOCK_WIDTH))*
2402 				GrData->udv_font.cxChar+xMargin-cxChar_2;
2403 		if (!UseDefClr){
2404 			if (str[n]>='A' && str[n]<='Z'){
2405 				SetColor(GrData->AA_LayoutPal[str[n]-'A'].LetClr);
2406 			}
2407 			else{
2408 				Black();
2409 			}
2410 		}
2411 		MoveTo(x_prot,y_prot);
2412 		PaintChar(str[n]);
2413 		stop_prot-=3;
2414 		n++;
2415 	}
2416 
2417 	if (str){
2418 		MemFree (str);
2419 	}
2420 	Black();
2421 }
2422 
2423 
2424 /*******************************************************************************
2425 
2426   Function : UDV_draw_CDS_plus()
2427 
2428   Purpose : draw the translation of a CDS located on a PLUS strand
2429 
2430   Parameters : context; feature data (see explore.h for a def of the structure)
2431   				start; draw the sequence from...
2432 				stop;... to.
2433 				StartLetter; beginning of a ParaG (zero-based value)
2434 				GrData; graphical data
2435 				y; vertical position to draw the sequence
2436 				i; order number of the exon (if CDS is exon-encoded)
2437 				xMargin; draw in the ParaG on the right a this value
2438 				UseDefClr; TRUE: draw the sequence using the DefClr value
2439 					Otherwise use GrData->AA_LayoutPal[] values
2440 
2441   Return value : none
2442 
2443 *******************************************************************************/
UDV_draw_CDS_plus(SeqMgrFeatContextPtr context,Int4 start,Int4 stop,Int4 StartLetter,UnDViewerGraphDataPtr GrData,Int2 y,Int2 i,Int2 xMargin,Boolean UseDefClr,Uint4 DefClr)2444 static void  UDV_draw_CDS_plus(SeqMgrFeatContextPtr context,Int4 start,
2445 			Int4 stop,Int4 StartLetter,UnDViewerGraphDataPtr GrData,Int2 y,
2446 			Int2 i,Int2 xMargin,Boolean UseDefClr,Uint4 DefClr)
2447 {
2448 CharPtr      	str=NULL;
2449 Int4			il=0,
2450 				pos=0,
2451 				n=0,
2452 				start_prot=0;
2453 Int2 			n2=0,
2454 				nCompt=0,
2455 				decal=0,
2456 				x_prot=0,
2457 				y_prot=0,
2458 				numivals2=0;
2459 ByteStorePtr	bs=NULL;
2460 Char szBuf[SZBUF_SIZE]={""};
2461 Boolean bGiForProductOk=FALSE;
2462 SeqIdPtr sip=NULL;
2463 Int4 gi=0;
2464 BioseqPtr prot;
2465 
2466 	/*retrieve the protein sequence; need to be optimized in future release*/
2467 	if (context->sfp->product){
2468 		prot=BioseqFind(SeqLocId(context->sfp->product));
2469 		sip=(SeqIdPtr)GetProductSeqId(context->sfp->product);
2470 		if (sip && prot){
2471 			CharPtr str2;
2472 			gi = GetGINumFromSip(sip);
2473 			if (gi>0) bGiForProductOk=TRUE;
2474 			str2=UDV_Read_Sequence (sip,0,prot->length-1,
2475 				TRUE,prot->length-1);
2476 			if (!str2) return;
2477 			str=str2;
2478 		}
2479 	}
2480 	else{
2481 		bs = ProteinFromCdRegion (context->sfp, TRUE);
2482 		if (bs){
2483 			str = (CharPtr) BSMerge (bs, NULL);
2484 			BSFree (bs);
2485 		}
2486 	}
2487 
2488 	if (!str) return;
2489 	MemSet(szBuf,' ',SZBUF_SIZE-1);
2490 
2491 	/*count the lenght of the intron(s)*/
2492 	numivals2=context->numivals*2;
2493 	if (i>0 && i<numivals2){
2494 		for(nCompt=2;nCompt<i+2;nCompt+=2){
2495 			il+=(context->ivals[nCompt]-
2496 				context->ivals[nCompt-1]-1);
2497 		}
2498 	}
2499 
2500 	pos=start-il-context->ivals[0];
2501 
2502 	/*place the current position within the correct translation frame*/
2503 	if (pos % 3){
2504 		if (!((pos-1) % 3)){
2505 			pos=(pos-1)/3;
2506 			decal=-1;
2507 		}
2508 		else if (!((pos+1) % 3)){
2509 			pos=(pos+1)/3;
2510 			decal=1;
2511 		}
2512 	}else {
2513 		pos=pos/3;
2514 		decal=0;
2515 	}
2516 
2517 	n=pos;
2518 	start_prot=start+decal+1;
2519 
2520 	/*vertical pos: just below the CDS colour box (pos: y)*/
2521 	y_prot=y+GrData->udv_font.LineHeight-GrData->udv_font.cyChar/2;
2522 	x_prot=((start_prot-StartLetter)+
2523 			((start_prot-StartLetter)/LETTER_BLOCK_WIDTH))*
2524 			GrData->udv_font.cxChar+xMargin-GrData->udv_font.cxChar/2;
2525 
2526 	if (UseDefClr) SetColor(DefClr);
2527 	nCompt=start_prot-StartLetter+(start_prot-StartLetter)/LETTER_BLOCK_WIDTH;
2528 	while(start_prot<=stop){
2529 		n2=start_prot-StartLetter+(start_prot-StartLetter)/LETTER_BLOCK_WIDTH
2530 			-nCompt;
2531 		if (n2<SZBUF_SIZE-1){
2532 			szBuf[n2]=str[n];
2533 		}
2534 		start_prot+=3;
2535 		n++;
2536 	}
2537 
2538 	MoveTo(x_prot,y_prot);
2539 	PaintString(szBuf);
2540 	if (str){
2541 		MemFree (str);
2542 	}
2543 	Black();
2544 }
2545 
2546 
2547 /*******************************************************************************
2548 
2549   Function : UDV_draw_big_arrow_feat()
2550 
2551   Purpose : draw a single feature as an arrow
2552 
2553   Parameters :  start_x; draw from...
2554   				stop_x; ...to
2555 				y: vertical position
2556 				cxChar; width of a character
2557 				cyChar; height of a character
2558 				LineHeight; height of a line in a ParaG
2559 				start_nat; start is a box, arrow or nothing ?
2560  				stop_nat; stop is a box, arrow or nothing ?
2561 				clr; colour
2562 
2563   Return value : none
2564 
2565 *******************************************************************************/
UDV_draw_big_arrow_feat(Int2 start_x,Int2 y,Int2 cxChar,Int2 cyChar,Uint4 clr)2566 static void  UDV_draw_big_arrow_feat(Int2 start_x,Int2 y,
2567 			Int2 cxChar,Int2 cyChar,Uint4 clr)
2568 {
2569 PoinT arrow[3];
2570 
2571 	if (clr!=(Uint4)-1) SetColor(clr);
2572 	else Black();
2573 	y-=3;
2574 	arrow[0].x=start_x-cxChar/2;
2575 	arrow[0].y=y;
2576 	arrow[1].x=start_x+cxChar/2;
2577 	arrow[1].y=y;
2578 	arrow[2].x=start_x;
2579 	arrow[2].y=y-(2*cyChar)/3;
2580 
2581 	PaintPoly(3,arrow);
2582 	Black();
2583 }
2584 
2585 /*******************************************************************************
2586 
2587   Function : UDV_draw_big_arrow_bond()
2588 
2589   Purpose : draw a bond feature as an arrow with a connected line
2590 
2591   Parameters :  start_x; draw from...
2592   				stop_x; ...to
2593 				y: vertical position
2594 				cxChar; width of a character
2595 				cyChar; height of a character
2596 				LineHeight; height of a line in a ParaG
2597 				start_nat; start is a box, arrow or nothing ?
2598  				stop_nat; stop is a box, arrow or nothing ?
2599 				clr; colour
2600 
2601   Return value : none
2602 
2603 *******************************************************************************/
UDV_draw_big_arrow_bond(Int2 start_x,Int2 y,Int2 cxChar,Int2 cyChar,Uint4 clr,Int1 What)2604 static void  UDV_draw_big_arrow_bond(Int2 start_x,Int2 y,
2605 			Int2 cxChar,Int2 cyChar,Uint4 clr,Int1 What)
2606 {
2607 PoinT arrow[3];
2608 
2609 	if (clr!=(Uint4)-1) SetColor(clr);
2610 	else Black();
2611 	/*y-=3;*/
2612 
2613 	arrow[0].x=start_x;
2614 	arrow[0].y=y;
2615 	if (What==BOND_LEFT) arrow[1].x=start_x+cxChar/2;
2616 	else arrow[1].x=start_x-cxChar/2;
2617 	arrow[1].y=y-cyChar/3;
2618 	arrow[2].x=start_x;
2619 	arrow[2].y=y-(2*cyChar)/3;
2620 	PaintPoly(3,arrow);
2621 	Black();
2622 }
2623 
2624 
2625 /*******************************************************************************
2626 
2627   Function : UDV_draw_big_line_feat()
2628 
2629   Purpose : draw a single feature as a box
2630 
2631   Parameters :  start_x; draw from...
2632   				stop_x; ...to
2633 				y: vertical position
2634 				cxChar; width of a character
2635 				cyChar; height of a character
2636 				LineHeight; height of a line in a ParaG
2637 				start_nat; start is a box, arrow or nothing ?
2638  				stop_nat; stop is a box, arrow or nothing ?
2639 				clr; colour
2640 
2641   Return value : none
2642 
2643 *******************************************************************************/
UDV_draw_big_line_feat(Int2 start_x,Int2 stop_x,Int2 y,Int2 cxChar,Int2 LineHeight,Int2 start_nat,Int2 stop_nat,Uint4 clr)2644 static void  UDV_draw_big_line_feat(Int2 start_x,Int2 stop_x,Int2 y,
2645 			Int2 cxChar,Int2 LineHeight,Int2 start_nat,Int2 stop_nat,
2646 			Uint4 clr)
2647 {
2648 RecT rcLine,rcBox;
2649 Int2 y2,x2,l2,l3,l6;
2650 PoinT arrow[3];
2651 
2652 	y2=y-LineHeight/2;
2653 	l2=LineHeight/2;
2654 	l3=LineHeight/3;
2655 	l6=LineHeight/6;
2656 
2657 	if (clr!=(Uint4)-1) SetColor(clr);
2658 	else Black();
2659 
2660 	/*start end : box, arrow or nothing*/
2661 	if (start_nat==FEATURE_START_BOX){
2662 		x2=start_x;
2663 		rcBox.left=x2-2;
2664   		rcBox.top=y2-l3;
2665 		rcBox.right=x2+2;
2666 		rcBox.bottom=y2+l3;
2667 		start_x=rcBox.right;
2668 		PaintRect(&rcBox);
2669 	}
2670 	else if (start_nat==FEATURE_START_ARROW){
2671 		arrow[0].x=start_x;
2672 		arrow[0].y=y2;
2673 		arrow[1].x=start_x+cxChar;
2674 		arrow[1].y=y2-l2;
2675 		arrow[2].x=arrow[1].x;
2676 		arrow[2].y=y2+l2;
2677 		start_x=arrow[2].x;
2678 		PaintPoly(3,arrow);
2679 	}
2680 	else if (start_nat==FEATURE_START_ARROW_END){
2681 		arrow[0].x=start_x;
2682 		arrow[0].y=y2;
2683 		arrow[1].x=start_x+cxChar;
2684 		arrow[1].y=y2-l2;
2685 		arrow[2].x=arrow[1].x;
2686 		arrow[2].y=y2+l2;
2687 		start_x=arrow[2].x;
2688 		PaintPoly(3,arrow);
2689 		MoveTo(arrow[0].x,arrow[1].y);
2690 		LineTo(arrow[0].x,arrow[2].y);
2691 	}
2692 
2693 	/*stop end : box, arrow or nothing*/
2694 	if (stop_nat==FEATURE_START_BOX){
2695 		x2=stop_x;
2696 		rcBox.left=stop_x-2;
2697 		rcBox.top=y2-l3;
2698 		rcBox.right=x2+2;
2699 		rcBox.bottom=y2+l3;
2700 		stop_x=rcBox.left;
2701 		PaintRect(&rcBox);
2702 	}
2703 	else if (stop_nat==FEATURE_START_ARROW){
2704 		arrow[0].x=stop_x;
2705 		arrow[0].y=y2;
2706 		arrow[1].x=stop_x-cxChar;
2707 		arrow[1].y=y2-l2;
2708 		arrow[2].x=arrow[1].x;
2709 		arrow[2].y=y2+l2;
2710 		stop_x=arrow[2].x;
2711 		PaintPoly(3,arrow);
2712 	}
2713 	else if (stop_nat==FEATURE_START_ARROW_END){
2714 		arrow[0].x=stop_x;
2715 		arrow[0].y=y2;
2716 		arrow[1].x=stop_x-cxChar;
2717 		arrow[1].y=y2-l2;
2718 		arrow[2].x=arrow[1].x;
2719 		arrow[2].y=y2+l2;
2720 		stop_x=arrow[2].x;
2721 		PaintPoly(3,arrow);
2722 		MoveTo(arrow[0].x,arrow[1].y);
2723 		LineTo(arrow[0].x,arrow[2].y);
2724 	}
2725 
2726 	if (start_x>=stop_x) return;
2727 	rcLine.left=start_x;
2728 	rcLine.top=y2-_max_(2,l6);
2729 	rcLine.right=stop_x;
2730 	rcLine.bottom=y2+_max_(2,l6);
2731 	PaintRect(&rcLine);
2732 	Black();
2733 }
2734 
2735 /*******************************************************************************
2736 
2737   Function : UDV_draw_thin_line()
2738 
2739   Purpose : draw a thin black line (generally used to delineate the introns)
2740 
2741   Parameters : 	start_x; draw from...
2742   				stop_x; ...to
2743 				y: vertical position
2744 				LineHeight; height of a line in a ParaG
2745 
2746   Return value : none
2747 
2748 *******************************************************************************/
UDV_draw_thin_line(Int2 start_x,Int2 stop_x,Int2 y,Int2 LineHeight,Uint4 clr)2749 static void  UDV_draw_thin_line(Int2 start_x,Int2 stop_x,Int2 y,
2750 					Int2 LineHeight,Uint4 clr)
2751 {
2752 Int2 y2;
2753 
2754 	y2=y-LineHeight/2;
2755 
2756 	if (clr!=(Uint4)-1) SetColor(clr);
2757 	else LtGray();
2758 
2759 	MoveTo(start_x,y2);
2760 	LineTo(stop_x,y2);
2761 
2762 	Black();
2763 }
2764 
2765 /*******************************************************************************
2766 
2767   Function : UDV_Draw_features()
2768 
2769   Purpose : I thing the name of the function is meaningfull...
2770 
2771   Parameters : 	GrData; graphical data (font size, etc)
2772   				bsp_i ; general data of the Bioseq
2773 				UseDefClr; TRUE: draw the sequence using the DefClr value
2774 					Otherwise use GrData->AA_LayoutPal[] values
2775 				pgp; data of the ParaG
2776 				rc; rectangle containing this ParaG
2777   				pClr; colour table [FEATDEF_MAX size]
2778 				is; item to select, if needed
2779 				old_is; old item to deselect, if needed
2780 
2781   Note : don't try to understand this function alone... if you want to keep
2782          a good health !
2783 
2784   Return value : none
2785 
2786 *******************************************************************************/
UDV_Draw_features(UnDViewerGraphDataPtr GrData,BspInfoPtr bsp_i,Boolean UseDefClr,Uint4 DefClr,ParaGPtr pgp,RecT PNTR rc,Uint4Ptr pClr,UDV_Item_Select * is,UDV_Item_Select * old_is,Uint4 DisplayType)2787 NLM_EXTERN void  UDV_Draw_features(UnDViewerGraphDataPtr GrData,
2788 					BspInfoPtr bsp_i,Boolean UseDefClr,Uint4 DefClr,
2789 					ParaGPtr pgp,RecT PNTR rc,Uint4Ptr pClr,
2790 					UDV_Item_Select * is,UDV_Item_Select * old_is,
2791 					Uint4 DisplayType)
2792 {
2793 Int2 y,ybase;				/*text position*/
2794 Int2 xMargin;				/*initial margins*/
2795 Int2 nTicks=0,nLet=0;		/*y decal*/
2796 ValNodePtr vnp;				/*Features list of itemID and index values*/
2797 Uint4 iID;
2798 Uint2 idx,lineID;		/*used to retrieve a desired Feature*/
2799 /*Uint8 index_g;			merged value containing itemID, index and lineID*/
2800 SeqMgrFeatContextPtr context;	/*used to retrieve feature data*/
2801 SeqMgrFeatContext context2;	/*used to retrieve feature data*/
2802 Int4 start,stop/*,OccupyTo*/;	/*limit of the feature to draw*/
2803 Int2 start_x,stop_x,stop_x2,		/*id. but in pixels*/
2804 	start_nat,stop_nat;		/*ends of the feature : box, arrow*/
2805 Int2 i,numivals2,i_decal,j;	/*counters*/
2806 Uint4	clr;				/*color used to draw feature*/
2807 Boolean b_draw_line,bCDS,b_connect_left,b_connect_right,
2808 		b_end_left,b_end_right,bDraw;
2809 Int2 idx1,idx2,idx3,idx4,idx5,idx6,nLines=0;
2810 BioseqPtr parent;
2811 SeqMgrSegmentContext contextPart;
2812 
2813 	if (!pgp->pFeatList) return;
2814 
2815 	/*compute position*/
2816 	if (GrData->udv_scale.ShowMajorTick) nTicks++;
2817 	if (GrData->udv_scale.ScalePosition==SCALE_POS_TOP ||
2818 					GrData->udv_scale.ScalePosition==SCALE_POS_BOTH) nLet++;
2819 
2820 	xMargin=rc->left+GrData->udv_font.cxChar;
2821 	ybase=rc->top+(nTicks+nLet+1/*2*/)*GrData->udv_font.LineHeight;
2822 	/*OccupyTo=pgp->StopLetter;*/
2823 
2824 	/*the current bsp is just a segment ?*/
2825 	parent=SeqMgrGetParentOfPart(bsp_i->bsp,&contextPart);
2826 	context=NULL;
2827 
2828 	/*draw : loop on all features in a ParaG*/
2829 	for(j=0,vnp=pgp->pFeatList;j<pgp->nFeat;j++,vnp=vnp->next){
2830 		if (vnp == NULL) break;
2831 		/*index_g=(Uint8)vnp->data.bigintvalue;*/
2832 		UDV_BigDecodeIdxFeat ((Uint8)vnp->data.bigintvalue, &iID,&idx,&lineID,NULL);
2833 		/*get desired feature given iID and idx*/
2834 		if (!SeqMgrGetDesiredFeature(bsp_i->bsp_entityID,
2835 				(parent!=NULL ? parent : bsp_i->bsp),
2836                 iID,idx,NULL,&context2)) continue;
2837 
2838 
2839 		if (context) {
2840 			MemFree(context->ivals);
2841 			context=(SeqMgrFeatContextPtr)MemFree(context);
2842 		}
2843 		context=UDV_ConvertFeatContext(&context2,contextPart.cumOffset,
2844 			bsp_i->bsp->length);
2845 		if (!context) continue;
2846 		/*depending on the strand, various things are possible :*/
2847 			/*PLUS/MINUS : if region (start!=stop)-> draw big box, with arrow*/
2848 
2849 			/*UNKNOWN : if region (start!=stop)-> draw big box, without arrow*/
2850 
2851 			/*PLUS/MINUS/UNKNOWN : if single letter (start==stop)-> draw
2852 			vertical arrow*/
2853 
2854 		/*HET feature correction for the ends*/
2855 		if(context->featdeftype== FEATDEF_HET){
2856 			context->right=context->ivals[2*context->numivals-1];
2857 		}
2858 
2859 		/*temporary situation; will be modified in the future*/
2860 		if (context->strand>Seq_strand_minus ||
2861 			context->strand==Seq_strand_unknown) context->strand=Seq_strand_plus;
2862 
2863 		/*strand PLUS*/
2864 		if (context->strand==Seq_strand_plus){
2865 			numivals2=context->numivals*2;
2866 			i=0;
2867 			i_decal=2;
2868 		}
2869 
2870 		/*strand MINUS*/
2871 		if (context->strand==Seq_strand_minus){
2872 			numivals2=2*context->numivals-2;
2873 			i=numivals2;
2874 			i_decal=-2;
2875 		}
2876 
2877 		bCDS=FALSE;
2878 		/*if (_max_(context->ivals[i],pgp->StartLetter)<=OccupyTo){
2879 			nLines++;
2880 		}*/
2881 		nLines=lineID;
2882 		bDraw=FALSE;
2883 		while (TRUE){
2884 			b_connect_left=FALSE;
2885 			b_connect_right=FALSE;
2886 			b_end_left=FALSE;
2887 			b_end_right=FALSE;
2888 			b_draw_line=FALSE;
2889 
2890 			/*colour*/
2891 			if (pClr){
2892 				clr=pClr[context->featdeftype];
2893 			}
2894 			else clr=(Uint4)-1;
2895 
2896 			/*if ivals.stop > end ParaG -> end of drawing*/
2897 			if (context->ivals[i]>pgp->StopLetter) break;
2898 			/*if ivals.stop<= start ParaG : not yet in the current ParaG*/
2899 
2900 			if (context->ivals[i+1]<pgp->StartLetter) {
2901 				if (context->strand==Seq_strand_plus ||
2902 						context->strand==Seq_strand_unknown){
2903 					if (numivals2>2 && i+2<numivals2){
2904 					/*stop ParaG < start next ivals -> inter-region: fill
2905 					the ParaG with a thin line; this is the case
2906 					for coding region: draw thin line to delineate the introns*/
2907 						if (context->ivals[i+2]>pgp->StopLetter){
2908 							b_draw_line=TRUE;
2909 						}
2910 					}
2911 				}
2912 				if (context->strand==Seq_strand_minus){
2913 					if (numivals2>2 && i-2>-1){
2914 					/*stop ParaG < start next ivals -> inter-region: fill
2915 					the ParaG with a thin line; this is the case
2916 					for coding region: draw thin line to delineate the introns*/
2917 						if (context->ivals[i-2]>pgp->StopLetter){
2918 							b_draw_line=TRUE;
2919 						}
2920 					}
2921 				}
2922 				if (b_draw_line){
2923 					start=0;
2924 					/*nLines++;*/
2925 					stop=pgp->StopLetter-pgp->StartLetter;
2926 					start_x=start*GrData->udv_font.cxChar+xMargin;
2927 					stop_x=(stop+(stop/LETTER_BLOCK_WIDTH))*
2928 						GrData->udv_font.cxChar+xMargin;
2929 					y=ybase+nLines*GrData->udv_font.LineHeight;
2930 					UDV_draw_thin_line(start_x,stop_x,y,
2931 							GrData->udv_font.LineHeight,clr);
2932 					/*OccupyTo=pgp->StopLetter;*/
2933 					bDraw=TRUE;
2934 				}
2935 				if (context->strand==Seq_strand_plus ||
2936 						context->strand==Seq_strand_unknown){
2937 					i=i+i_decal;
2938 					if (i>numivals2-2) break;
2939 					else continue;
2940 				}
2941 				if (context->strand==Seq_strand_minus){
2942 					i=i+i_decal;
2943 					if (i<0) break;
2944 					else continue;
2945 				}
2946 			}
2947 
2948 			/*compute the limits of the feature within ParaG*/
2949 			start=_max_(context->ivals[i],pgp->StartLetter);
2950 			stop=_min_(context->ivals[i+1],pgp->StopLetter);
2951 			bDraw=TRUE;
2952 			/*are there connections; exons/introns for example*/
2953 				/*on the left*/
2954 			if (context->strand==Seq_strand_plus ||
2955 						context->strand==Seq_strand_unknown){
2956 				if (numivals2>2 && i>0){
2957 					if (start>pgp->StartLetter){
2958 						idx1=i-1;
2959 						idx2=1;
2960 						idx3=-2;
2961 						b_connect_left=TRUE;
2962 						b_end_left=TRUE;
2963 					}
2964 					else if(start==pgp->StartLetter){
2965 						b_end_left=TRUE;
2966 					}
2967 				}
2968 			}
2969 			if (context->strand==Seq_strand_minus){
2970 				if (numivals2>2 && i<numivals2-1){
2971 					if (start>pgp->StartLetter){
2972 						idx1=i+3;
2973 						idx2=3;
2974 						idx3=0;
2975 						b_connect_left=TRUE;
2976 						b_end_left=TRUE;
2977 					}
2978 					else if(start==pgp->StartLetter){
2979 						b_end_left=TRUE;
2980 					}
2981 				}
2982 			}
2983 				/*on the right*/
2984 			if (context->strand==Seq_strand_plus ||
2985 						context->strand==Seq_strand_unknown){
2986 				if (numivals2>2 && i+2<numivals2){
2987 					if (stop<pgp->StopLetter){
2988 						idx4=i+2;
2989 						idx5=1;
2990 						idx6=-2;
2991 						b_connect_right=TRUE;
2992 						b_end_right=TRUE;
2993 					}
2994 					else if(stop==pgp->StopLetter){
2995 						b_end_right=TRUE;
2996 					}
2997 				}
2998 			}
2999 			if (context->strand==Seq_strand_minus){
3000 				if (numivals2>2 && i>0){
3001 					if (stop<pgp->StopLetter){
3002 						idx4=i-2;
3003 						idx5=3;
3004 						idx6=0;
3005 						b_connect_right=TRUE;
3006 						b_end_right=TRUE;
3007 					}
3008 					else if(stop==pgp->StopLetter){
3009 						b_end_right=TRUE;
3010 					}
3011 				}
3012 			}
3013 			/*compute the 'nature' of start & stop: box, arrow or nothing*/
3014 			/*I use only Seq_strand_minus or Seq_strand_plus !!!!*/
3015 			if (context->strand==Seq_strand_plus ||
3016 				context->strand==Seq_strand_minus){
3017 				if (context->ivals[i]==start){
3018 					if (context->strand==Seq_strand_plus){
3019 						if (b_end_left) start_nat=FEATURE_START_NOTHING;
3020 						else start_nat=FEATURE_START_BOX;
3021 					}
3022 					else {
3023 						if (b_end_left) start_nat=FEATURE_START_ARROW;
3024 						else start_nat=FEATURE_START_ARROW_END;
3025 					}
3026 				}
3027 				else{
3028 					if (context->strand==Seq_strand_plus)
3029 						start_nat=FEATURE_START_NOTHING;
3030 					else
3031 						start_nat=FEATURE_START_ARROW;
3032 				}
3033 
3034 				if (context->ivals[i+1]==stop){
3035 					if (context->strand==Seq_strand_minus){
3036 						if (b_end_right) stop_nat=FEATURE_START_NOTHING;
3037 						else stop_nat=FEATURE_START_BOX;
3038 					}
3039 					else{
3040 						if (b_end_right) stop_nat=FEATURE_START_ARROW;
3041 						else stop_nat=FEATURE_START_ARROW_END;
3042 					}
3043 				}
3044 				else{
3045 					if (context->strand==Seq_strand_plus)
3046 						stop_nat=FEATURE_START_ARROW;
3047 					else
3048 						stop_nat=FEATURE_START_NOTHING;
3049 				}
3050 			}
3051 			else{
3052 				start_nat=FEATURE_START_NOTHING;
3053 				stop_nat=FEATURE_START_NOTHING;
3054 			}
3055 
3056 			/*compute limits of the drawing... zero based values from the left
3057 				of ParaG rc*/
3058 			start_x=((start-pgp->StartLetter)+
3059 				((start-pgp->StartLetter)/LETTER_BLOCK_WIDTH))*
3060 				GrData->udv_font.cxChar+xMargin;
3061 			stop_x=((stop-pgp->StartLetter)+((stop-pgp->StartLetter)/
3062 				LETTER_BLOCK_WIDTH))*GrData->udv_font.cxChar+xMargin;
3063 			stop_x2=stop_x;/*use below to display a label; wwwudv only*/
3064 
3065 			y=ybase+nLines*GrData->udv_font.LineHeight;
3066 			/*draw feature*/
3067 			if (start!=stop || (start==stop && context->left!=context->right)
3068 				/*|| context->strand!=Seq_strand_unknown*/){
3069 				switch(context->featdeftype){
3070 					case FEATDEF_HET:
3071 						if (clr!=(Uint4)-1) SetColor(clr);
3072 						MoveTo(start_x-GrData->udv_font.cxChar/2,y);
3073 						PaintChar('H');
3074 						b_connect_left=FALSE;
3075 						b_connect_right=FALSE;
3076 						break;
3077 					case FEATDEF_BOND:
3078 						UDV_draw_thin_line(start_x,stop_x,y,
3079 							GrData->udv_font.LineHeight,clr);
3080 						if (pgp->StartLetter<=context->left &&
3081 							pgp->StopLetter>=context->left){
3082 							UDV_draw_big_arrow_bond(start_x,y,
3083 								GrData->udv_font.cxChar,
3084 								GrData->udv_font.cyChar,
3085 								clr,BOND_LEFT);
3086 						}
3087 						if (pgp->StartLetter<=context->right &&
3088 							pgp->StopLetter>=context->right){
3089 							UDV_draw_big_arrow_bond(stop_x,y,
3090 								GrData->udv_font.cxChar,
3091 								GrData->udv_font.cyChar,
3092 								clr,BOND_RIGHT);
3093 						}
3094 						break;
3095 					case FEATDEF_PSEC_STR:
3096 						if (context->sfp){
3097 							Boolean ContinueLeft=FALSE;
3098 							Boolean ContinueRight=FALSE;
3099 
3100 							if (context->sfp->data.value.intvalue==1){/*helix*/
3101 								if (start!=context->left) ContinueLeft=TRUE;
3102 								if (stop!=context->right)ContinueRight=TRUE;
3103 								UDV_draw_struc_helix( start, stop,
3104 									pgp->StartLetter,
3105 									y,GrData->udv_font.cxChar,
3106 									GrData->udv_font.cyChar,
3107 									GrData->udv_font.LineHeight,xMargin,clr,
3108 									ContinueLeft,ContinueRight);
3109 							}
3110 							if (context->sfp->data.value.intvalue==2){/*sheet*/
3111 								if (start!=context->left) ContinueLeft=TRUE;
3112 								if (stop!=context->right)ContinueRight=TRUE;
3113 								UDV_draw_struc_strand( start, stop,
3114 									pgp->StartLetter,
3115 									y,GrData->udv_font.cxChar,
3116 									GrData->udv_font.cyChar,
3117 									GrData->udv_font.LineHeight,xMargin,clr,
3118 									ContinueLeft,ContinueRight);
3119 							}
3120 						}
3121 						break;
3122 					case FEATDEF_CDS:
3123 						bCDS=TRUE;
3124 						if (context->strand==Seq_strand_plus)
3125 							UDV_draw_CDS_plus(context,start,stop,
3126 								pgp->StartLetter,
3127 								GrData,y,i,xMargin, UseDefClr, DefClr);
3128 						if (context->strand==Seq_strand_minus)
3129 							UDV_draw_CDS_minus(context,start,stop,
3130 								pgp->StartLetter,
3131 								GrData,y,i,xMargin, UseDefClr, DefClr);
3132 						/*nLines++;*/
3133 						/*WARNING: do not add anything between FEATDEF_CDS
3134 						and the following default case because after the
3135 						translation, I must draw a box*/
3136 					default:
3137 						UDV_draw_big_line_feat(start_x,stop_x,y,
3138 							GrData->udv_font.cxChar,
3139 							GrData->udv_font.LineHeight,
3140 							start_nat,stop_nat,clr);
3141 						break;
3142 				}
3143 			}
3144 			else{/*feature is one letter long*/
3145 				UDV_draw_big_arrow_feat(start_x,y,GrData->udv_font.cxChar,
3146 					GrData->udv_font.cyChar,clr);
3147 			}
3148 			/*select feature, if needed*/
3149 			if (old_is && old_is->eIDsel!=(Uint2)-1){
3150 				if (old_is->iIDsel==iID){
3151 					RecT rcSel;
3152 
3153 					rcSel.left=start_x-5;
3154 					rcSel.top=y-GrData->udv_font.LineHeight+1;
3155 					rcSel.right=stop_x+5;
3156 					if (!bCDS) rcSel.bottom=y;
3157 					else rcSel.bottom=y+GrData->udv_font.LineHeight;
3158 					White();
3159 					UDV_draw_select(rcSel);
3160 				}
3161 			}
3162 			if (is && is->eIDsel!=(Uint2)-1){
3163 				if (is->iIDsel==iID){
3164 					RecT rcSel;
3165 
3166 					rcSel.left=start_x-5;
3167 					rcSel.top=y-GrData->udv_font.LineHeight+1;
3168 					rcSel.right=stop_x+5;
3169 					if (!bCDS) rcSel.bottom=y;
3170 					else rcSel.bottom=y+GrData->udv_font.LineHeight-2;
3171 					Red();
3172 					UDV_draw_select(rcSel);
3173 				}
3174 			}
3175 			Black();
3176 
3177 			/*draw thin line if needed; used to connect exons/introns for
3178 			example*/
3179 			if (b_connect_left){
3180 				Int4 start2,stop2;
3181 				stop2=start;
3182 				start2=_max_(pgp->StartLetter,context->ivals[idx1]);
3183 				start_x=(start2-pgp->StartLetter+
3184 					((start2-pgp->StartLetter)/LETTER_BLOCK_WIDTH))*
3185 					GrData->udv_font.cxChar+xMargin;
3186 				stop_x=(stop2-pgp->StartLetter+
3187 					((stop2-pgp->StartLetter)/
3188 					LETTER_BLOCK_WIDTH))*GrData->udv_font.cxChar+xMargin;
3189 				UDV_draw_thin_line((Int2)(start_x+idx2),(Int2)(stop_x+idx3),y,
3190 						GrData->udv_font.LineHeight,clr);
3191 			}
3192 
3193 			if (b_connect_right){
3194 				Int4 start2,stop2;
3195 				start2=stop;
3196 				stop2=_min_(pgp->StopLetter,context->ivals[idx4]);
3197 				start_x=(start2-pgp->StartLetter+
3198 					((start2-pgp->StartLetter)/LETTER_BLOCK_WIDTH))*
3199 					GrData->udv_font.cxChar+xMargin;
3200 				stop_x=(stop2-pgp->StartLetter+
3201 					((stop2-pgp->StartLetter)/
3202 					LETTER_BLOCK_WIDTH))*GrData->udv_font.cxChar+xMargin;
3203 				UDV_draw_thin_line((Int2)(start_x+idx5),(Int2)(stop_x+idx6),y,
3204 					GrData->udv_font.LineHeight,clr);
3205 				/*OccupyTo=stop2;*/
3206 			}
3207 
3208 			/*if (context->sfp && context->sfp->data.choice==SEQFEAT_CDREGION)
3209 					y+=GrData->udv_font.LineHeight;		*/
3210 
3211 			if (context->strand==Seq_strand_plus ||
3212 						context->strand==Seq_strand_unknown){
3213 				i=i+i_decal;
3214 				if (i>numivals2-2) break;
3215 			}
3216 			if (context->strand==Seq_strand_minus){
3217 				i=i+i_decal;
3218 				if (i<0) break;
3219 			}
3220 		}
3221 		if (bDraw && (DisplayType&DDV_DISP_LABEL)){
3222 			if (pClr){
3223 				SetColor(pClr[context->featdeftype]);
3224 			}
3225 			else Magenta();
3226 			MoveTo(_max_(stop_x2,stop_x)+GrData->udv_font.cxChar,y);
3227 			PaintString(context->label);
3228 			Black();
3229 		}
3230 	}
3231 	Black();
3232 }
3233 
3234 /*******************************************************************************
3235 
3236   Function : UDV_Draw_features_MAP()
3237 
3238   Purpose : create an image map
3239 
3240   Parameters : 	GrData; graphical data (font size, etc)
3241   				bsp_i ; general data of the Bioseq
3242 				pgp; data of the ParaG
3243 				rc; rectangle containing this ParaG
3244 				vnpp_map; to put the image map info
3245 
3246   Note : this is a light version of UDV_Draw_features()
3247 
3248   Return value : TRUE if success
3249 
3250 *******************************************************************************/
UDV_Draw_features_MAP(UnDViewerGraphDataPtr GrData,BspInfoPtr bsp_i,ParaGPtr pgp,RecT PNTR rc,Uint2 entityID,ValNodePtr PNTR vnpp_map)3251 NLM_EXTERN Boolean UDV_Draw_features_MAP(UnDViewerGraphDataPtr GrData,
3252 					BspInfoPtr bsp_i,ParaGPtr pgp,RecT PNTR rc,Uint2 entityID,
3253 					ValNodePtr PNTR vnpp_map)
3254 {
3255 BioseqPtr parent;
3256 UDVMapInfoPtr umip;
3257 SeqMgrSegmentContext contextPart;
3258 SeqMgrFeatContextPtr context;	/*used to retrieve feature data*/
3259 SeqMgrFeatContext context2;	/*used to retrieve feature data*/
3260 ValNodePtr vnp,vnp_map;		/*Features list of itemID and index values*/
3261 Int4 start,stop;			/*limit of the feature to draw*/
3262 Int2 y,ybase;				/*text position*/
3263 Int2 xMargin;				/*initial margins*/
3264 Int2 nTicks=0,nLet=0;		/*y decal*/
3265 Uint4 iID;
3266 Uint2 idx,lineID;		/*used to retrieve a desired Feature*/
3267 Int2 start_x,stop_x;		/*ends of the feature : box, arrow*/
3268 Int2 i,numivals2,i_decal,j;	/*counters*/
3269 
3270 	vnp_map=NULL;
3271 
3272 	/*compute position*/
3273 	if (GrData->udv_scale.ShowMajorTick) nTicks++;
3274 	if (GrData->udv_scale.ScalePosition==SCALE_POS_TOP ||
3275 					GrData->udv_scale.ScalePosition==SCALE_POS_BOTH) nLet++;
3276 
3277 	xMargin=rc->left+GrData->udv_font.cxChar;
3278 	ybase=rc->top+(nTicks+nLet+1)*GrData->udv_font.LineHeight;
3279 
3280 	/*the current bsp is just a segment ?*/
3281 	parent=SeqMgrGetParentOfPart(bsp_i->bsp,&contextPart);
3282 	context=NULL;
3283 
3284 	/*descriptor node for the sequence itself*/
3285 	/*map rect*/
3286 	umip=(UDVMapInfoPtr)MemNew(sizeof(UDVMapInfo));
3287 	if (umip==NULL){
3288 		if (vnp_map) ValNodeFreeData(vnp_map);
3289 		return(FALSE);
3290 	}
3291 	umip->left=xMargin-5;
3292 	umip->bottom=ybase;
3293 	umip->top=umip->bottom-GrData->udv_font.LineHeight+1;
3294 	umip->right=((pgp->StopLetter-pgp->StartLetter)+((pgp->StopLetter-pgp->StartLetter)/
3295 				LETTER_BLOCK_WIDTH))*GrData->udv_font.cxChar+xMargin+5;
3296 	umip->Type=OBJ_BIOSEQ;
3297 	umip->data.uintvalue=(Uint4)entityID;
3298 	ValNodeAddPointer(vnpp_map,0,(Pointer)umip);
3299 
3300 	if (!pgp->pFeatList) return(TRUE);
3301 
3302 	/*draw : loop on all features in a ParaG*/
3303 	for(j=0,vnp=pgp->pFeatList;j<pgp->nFeat;j++,vnp=vnp->next){
3304 		if (vnp == NULL) break;
3305 		/*index_g=(Uint8)vnp->data.bigintvalue;*/
3306 		UDV_BigDecodeIdxFeat ((Uint8)vnp->data.bigintvalue, &iID,&idx,&lineID,NULL);
3307 		/*get desired feature given iID and idx*/
3308 		if (!SeqMgrGetDesiredFeature(bsp_i->bsp_entityID,
3309 				(parent!=NULL ? parent : bsp_i->bsp),
3310                 iID,idx,NULL,&context2)) continue;
3311 
3312 
3313 		if (context) {
3314 			MemFree(context->ivals);
3315 			context=(SeqMgrFeatContextPtr)MemFree(context);
3316 		}
3317 		context=UDV_ConvertFeatContext(&context2,contextPart.cumOffset,
3318 			bsp_i->bsp->length);
3319 		if (!context) continue;
3320 		/*depending on the strand, various things are possible :*/
3321 			/*PLUS/MINUS : if region (start!=stop)-> draw big box, with arrow*/
3322 
3323 			/*UNKNOWN : if region (start!=stop)-> draw big box, without arrow*/
3324 
3325 			/*PLUS/MINUS/UNKNOWN : if single letter (start==stop)-> draw
3326 			vertical arrow*/
3327 
3328 		/*HET feature correction for the ends*/
3329 		if(context->featdeftype== FEATDEF_HET){
3330 			context->right=context->ivals[2*context->numivals-1];
3331 		}
3332 
3333 		/*temporary situation; will be modified in the future*/
3334 		if (context->strand>Seq_strand_minus ||
3335 			context->strand==Seq_strand_unknown) context->strand=Seq_strand_plus;
3336 
3337 		/*strand PLUS*/
3338 		if (context->strand==Seq_strand_plus){
3339 			numivals2=context->numivals*2;
3340 			i=0;
3341 			i_decal=2;
3342 		}
3343 
3344 		/*strand MINUS*/
3345 		if (context->strand==Seq_strand_minus){
3346 			numivals2=2*context->numivals-2;
3347 			i=numivals2;
3348 			i_decal=-2;
3349 		}
3350 
3351 		while (TRUE){
3352 			/*if ivals.stop > end ParaG -> end */
3353 			if (context->ivals[i]>pgp->StopLetter) break;
3354 			/*skip if not yet in the ParaG*/
3355 			if (context->ivals[i+1]<pgp->StartLetter) {
3356 				if (context->strand==Seq_strand_plus ||
3357 						context->strand==Seq_strand_unknown){
3358 					i=i+i_decal;
3359 					if (i>numivals2-2) break;
3360 					else continue;
3361 				}
3362 				if (context->strand==Seq_strand_minus){
3363 					i=i+i_decal;
3364 					if (i<0) break;
3365 					else continue;
3366 				}
3367 			}
3368 			/*compute the limits of the feature within ParaG*/
3369 			start=_max_(context->ivals[i],pgp->StartLetter);
3370 			stop=_min_(context->ivals[i+1],pgp->StopLetter);
3371 
3372 			/*compute limits of the drawing... zero based values from the left
3373 				of ParaG rc*/
3374 			start_x=((start-pgp->StartLetter)+
3375 				((start-pgp->StartLetter)/LETTER_BLOCK_WIDTH))*
3376 				GrData->udv_font.cxChar+xMargin;
3377 			stop_x=((stop-pgp->StartLetter)+((stop-pgp->StartLetter)/
3378 				LETTER_BLOCK_WIDTH))*GrData->udv_font.cxChar+xMargin;
3379 
3380 			y=ybase+lineID*GrData->udv_font.LineHeight;
3381 
3382 			/*map rect*/
3383 			umip=(UDVMapInfoPtr)MemNew(sizeof(UDVMapInfo));
3384 			if (umip==NULL){
3385 				if (vnp_map) ValNodeFreeData(vnp_map);
3386 				return(FALSE);
3387 			}
3388 			umip->left=start_x-5;
3389 			umip->top=y-GrData->udv_font.LineHeight+1;
3390 			umip->right=stop_x+5;
3391 			if (context->featdeftype==FEATDEF_CDS)
3392 				umip->bottom=y+GrData->udv_font.LineHeight;
3393 			else
3394 				umip->bottom=y;
3395 
3396 			/*map nodes list*/
3397 			umip->Type=OBJ_SEQFEAT;
3398 			umip->data.uintvalue=UDV_EncodeIdxFeat(iID,idx);
3399 			ValNodeAddPointer(vnpp_map,0,(Pointer)umip);
3400 
3401 			if (context->strand==Seq_strand_plus ||
3402 						context->strand==Seq_strand_unknown){
3403 				i=i+i_decal;
3404 				if (i>numivals2-2) break;
3405 			}
3406 			if (context->strand==Seq_strand_minus){
3407 				i=i+i_decal;
3408 				if (i<0) break;
3409 			}
3410 		}
3411 	}
3412 	return(TRUE);
3413 }
3414 
3415 /*******************************************************************************
3416 
3417   Function : UDV_Draw_features_label()
3418 
3419   Purpose : draw the labels of each feature located in a ParaG
3420 
3421   Parameters :	GrData; graphical data (font size, etc)
3422   				bsp_i ; general data of the Bioseq
3423 				pgp; data of the ParaG
3424 				rc; rectangle containing this ParaG
3425   				pClr; colour table [FEATDEF_MAX size]
3426 				is; item to select, if needed
3427 				old_is; old item to select, if needed
3428 
3429   Return value : none
3430 
3431 *******************************************************************************/
3432 #ifndef WWW_UDV
UDV_Draw_features_label(UnDViewerGraphDataPtr GrData,BspInfoPtr bsp_i,ParaGPtr pgp,RecT PNTR rc,Uint4Ptr pClr,UDV_Item_Select is,UDV_Item_Select old_is)3433 static void  UDV_Draw_features_label(UnDViewerGraphDataPtr GrData,
3434 					BspInfoPtr bsp_i,ParaGPtr pgp,RecT PNTR rc,Uint4Ptr pClr,
3435 					UDV_Item_Select is,UDV_Item_Select old_is)
3436 {
3437 Int2 x,y;					/*text position*/
3438 Int2 xMargin;				/*initial margins*/
3439 Int2 nTicks=0,nLet=0;		/*y decal*/
3440 Char szBuf[51]={""};		/*name to draw*/
3441 ValNodePtr vnp;				/*Features list of itemID and index values*/
3442 Uint4 iID;
3443 Uint2 idx;				/*used to retrieve a desired Feature*/
3444 /*Uint4 index_g;			merged value containing itemID and index*/
3445 SeqMgrFeatContext context;	/*used to retrieve feature data*/
3446 Uint2 j;					/*counter*/
3447 
3448 	if (!pgp->pFeatList) return;
3449 
3450 	/*compute position*/
3451 	if (GrData->udv_scale.ShowMajorTick) nTicks++;
3452 	if (GrData->udv_scale.ScalePosition==SCALE_POS_TOP ||
3453 					GrData->udv_scale.ScalePosition==SCALE_POS_BOTH) nLet++;
3454 
3455 	xMargin=rc->left-2*GrData->udv_font.cxChar-GrData->udv_scale.cxLeftScale;
3456 	y=rc->top+(nTicks+nLet+2)*GrData->udv_font.LineHeight;
3457 
3458 	/*draw : loop on all features in a ParaG*/
3459 	for(j=0,vnp=pgp->pFeatList;j<pgp->nFeat;j++,vnp=vnp->next){
3460 		if (vnp == NULL) break;
3461 
3462 		UDV_BigDecodeIdxFeat ((Uint8)vnp->data.bigintvalue, &iID,&idx,NULL,NULL);
3463 
3464 		/*get desired feature given iID and idx*/
3465 		if (!SeqMgrGetDesiredFeature(bsp_i->bsp_entityID,bsp_i->bsp,
3466                                 iID,idx,NULL,&context)) continue;
3467 
3468 		if (context.sfp){
3469 			/*copy name*/
3470 			if (FeatDefLabel (context.sfp, szBuf, sizeof (szBuf) - 1,
3471 						OM_LABEL_BOTH)){
3472 
3473 				/*draw name*/
3474 				x=xMargin-StringWidth(szBuf);
3475 				MoveTo(x,y);
3476 				if (pClr){
3477 					SetColor(pClr[context.featdeftype]);
3478 				}
3479 				PaintString (szBuf);
3480 				/*select if needed*/
3481 				if (old_is.eIDsel!=(Uint2)-1){
3482 					if (old_is.iIDsel==iID){
3483 						RecT rcSel;
3484 
3485 						rcSel.left=x-3;
3486 						rcSel.top=y-GrData->udv_font.cyChar+1;
3487 						rcSel.right=rcSel.left+StringWidth(szBuf)+4;
3488 						rcSel.bottom=y+2;
3489 						White();
3490 						UDV_draw_select(rcSel);
3491 					}
3492 				}
3493 				if (is.eIDsel!=(Uint2)-1){
3494 					if (is.iIDsel==iID){
3495 						RecT rcSel;
3496 
3497 						rcSel.left=x-3;
3498 						rcSel.top=y-GrData->udv_font.cyChar+1;
3499 						rcSel.right=rcSel.left+StringWidth(szBuf)+4;
3500 						rcSel.bottom=y+2;
3501 						Red();
3502 						UDV_draw_select(rcSel);
3503 
3504 					}
3505 				}
3506 				Black();
3507 				y+=GrData->udv_font.LineHeight;
3508 
3509 			}
3510 			if (context.sfp->data.choice==SEQFEAT_CDREGION){
3511 				if (UDV_IsTranslationNeeded(&context,pgp))
3512 					y+=GrData->udv_font.LineHeight;
3513 			}
3514 		}
3515 	}
3516 	Black();
3517 }
3518 #endif /*WWW_UDV*/
3519 
3520 
3521 /*******************************************************************************
3522 
3523   Function : UDV_Draw_sequence_name()
3524 
3525   Purpose : draw the name of the sequence (on the left of it) of a ParaG
3526 
3527   Parameters : GrData; graphical data (font size, etc)
3528   				bsp_i ; general data of the Bioseq
3529 				rc; rectangle containing this ParaG
3530 
3531   Return value : none
3532 
3533 *******************************************************************************/
3534 #ifndef WWW_UDV
UDV_Draw_sequence_name(UnDViewerGraphDataPtr GrData,BspInfoPtr bsp_i,RecT PNTR rc)3535 static void  UDV_Draw_sequence_name(UnDViewerGraphDataPtr GrData,
3536 					BspInfoPtr bsp_i,RecT PNTR rc)
3537 {
3538 Int2 x,y,hdecal;			/*text position*/
3539 Int2 nTicks=0,nLet=0;	/*y decal*/
3540 
3541 	/*compute position*/
3542 	if (GrData->udv_scale.ShowMajorTick) nTicks++;
3543 	if (GrData->udv_scale.ScalePosition==SCALE_POS_TOP ||
3544 					GrData->udv_scale.ScalePosition==SCALE_POS_BOTH) nLet++;
3545 
3546 	hdecal=nTicks+nLet+1;
3547 
3548 	/*draw name*/
3549 	x=rc->left-2*GrData->udv_font.cxChar-GrData->udv_scale.cxLeftScale-
3550 				StringWidth(bsp_i->bspAccNum);
3551 	y=rc->top+hdecal*GrData->udv_font.LineHeight;
3552 	MoveTo(x,y);
3553 	PaintString (bsp_i->bspAccNum);
3554 }
3555 #endif /*WWW_UDV*/
3556 
3557 
3558 /*******************************************************************************
3559 
3560   Function : UDV_Draw_sequence()
3561 
3562   Purpose : draw the Bioseq' sequence of a ParaG
3563 
3564   Parameters : 	GrData; graphical data (font size, etc)
3565 				vnp_color; colours table
3566   				bsp_i ; general data of the Bioseq
3567 				IsNuc;True if nuc sequence
3568 				UseDefClr; TRUE: draw the sequence using the DefClr value
3569 					Otherwise use GrData->AA_LayoutPal[] values
3570 				pgp; data of the ParaG
3571 				rc; rectangle containing this ParaG
3572 			    start_decal; buffer start letter (0-based)
3573 				StartLetter; ParaG start letter (0-based)
3574 				szSequence; sequence buffer
3575                 Row; the row to draw if we are drawing the row of a seqalign
3576 
3577   Return value : none
3578 
3579 *******************************************************************************/
UDV_Draw_sequence(UnDViewerGraphDataPtr GrData,DDV_ColorGlobal * svpp,Boolean UseDefClr,Uint4 DefClr,ParaGPtr pgp,RecT PNTR rc,Int4 start_decal,Int4 StartLetter,CharPtr szSequence,SeqId * sip,ValNodePtr vnp_bsp,Boolean bSelect,Int4 Row,Int4 bspLength,Boolean bDisplayRevComp)3580 NLM_EXTERN void  UDV_Draw_sequence(UnDViewerGraphDataPtr GrData,
3581                     DDV_ColorGlobal *svpp ,Boolean UseDefClr,Uint4 DefClr,
3582 					ParaGPtr pgp,RecT PNTR rc,Int4 start_decal,Int4 StartLetter,
3583 					CharPtr szSequence, SeqId *sip,ValNodePtr vnp_bsp,
3584 					Boolean bSelect, Int4 Row,Int4 bspLength,Boolean bDisplayRevComp)
3585 {
3586 Int4 pos,taille,stop,bsp_pos,	/*scale start at...(used to draw text)*/
3587 	 bsp_pos_goto;
3588 Int2 x,y,ldecal,hdecal;	/*text position*/
3589 Int2 xMargin;			/*initial margins*/
3590 Int2 nTicks=0,nLet=0;	/*y decal*/
3591 Uint1 residue;			/*letter and sequence length to retrieve*/
3592 Uint2 nCompt=0,nCompt2=0;
3593 CharPtr szBuf;
3594 DDV_ColorCell  *rgb,*highlighClr;
3595 Uint4 blackColor = GetColorRGB(0,0,0),newColor,curColor,hlClr;
3596 RecT  rcSel;
3597 
3598     if(Row >= 0) sip = NULL;  /* draw by row instead of by bioseq */
3599 
3600 	/*alloc a buffer*/
3601 	taille=pgp->StopLetter-pgp->StartLetter+
3602 		(pgp->StopLetter-pgp->StartLetter)/LETTER_BLOCK_WIDTH+5;
3603 	szBuf=(CharPtr)MemNew(taille*sizeof(Char));
3604 	if (!szBuf) return;
3605 	MemSet(szBuf,0,taille*sizeof(Char));
3606 
3607 	/*scale or not... to be or not to be ?*/
3608 	if (GrData->udv_scale.ShowMajorTick) nTicks++;
3609 	if (GrData->udv_scale.ScalePosition==SCALE_POS_TOP ||
3610 					GrData->udv_scale.ScalePosition==SCALE_POS_BOTH) nLet++;
3611 
3612 	pos=pgp->StartLetter+1;	/*remember : StartLetter is zero based*/
3613 	xMargin=rc->left+GrData->udv_font.cxChar;
3614 	y=rc->top;
3615 	/*xDecal=xMargin;*/
3616 	ldecal=GrData->udv_font.cxChar/2;
3617 	hdecal=nTicks+nLet+1;
3618 
3619 	if (UseDefClr) SetColor(DefClr);
3620 	newColor=(Uint4)-1;
3621 	stop=pgp->StopLetter+2;
3622 	y=y+hdecal*GrData->udv_font.LineHeight;
3623 	x=xMargin-ldecal;
3624 
3625 
3626 	bsp_pos_goto=GrData->GotoLetter-1;
3627 	bsp_pos=start_decal+(StartLetter-start_decal);
3628 
3629 #ifndef WWW_UDV
3630 	/* -A- Draw the selection; this code is not used by Entrez cgi-bin viewer*/
3631 	if (bSelect){
3632 		if (svpp==NULL){
3633 			Yellow();
3634 		}
3635 		else{
3636 	    	highlighClr =
3637     	    	DDV_SearchColorCellbyName(svpp->pvnSpecialColors, "Highlight");
3638 			if (highlighClr)
3639 				hlClr = GetColorRGB (highlighClr->rgb[0], highlighClr->rgb[1],highlighClr->rgb[2]);
3640 			else
3641 				hlClr = GetColorRGB (255,255,0);
3642 			SetColor(hlClr);
3643 		}
3644 		while(pos<stop){
3645 			if(UDV_IsLetterSelected(vnp_bsp,bsp_pos,bspLength,bDisplayRevComp)&&
3646 					bsp_pos!=bsp_pos_goto ){
3647 				rcSel.left=x+((bsp_pos-pgp->StartLetter)+
3648 					(bsp_pos-pgp->StartLetter)/LETTER_BLOCK_WIDTH)*
3649 					GrData->udv_font.cxChar-1;
3650 				rcSel.top=y-GrData->udv_font.LineHeight;
3651 				rcSel.bottom=y;
3652 				rcSel.right=rcSel.left+GrData->udv_font.cxChar;
3653 				PaintRect(&rcSel);
3654 			}
3655 			bsp_pos++;
3656 			pos++;
3657 		}
3658 	}
3659 
3660 
3661 #endif
3662 
3663 	pos=pgp->StartLetter+1;
3664 	/* -B- Draw the highlight  GoTo letter*/
3665 	if (bsp_pos_goto>=pgp->StartLetter && bsp_pos_goto<=pgp->StopLetter){
3666 		rcSel.left=x+((bsp_pos_goto-pgp->StartLetter)+
3667 			(bsp_pos_goto-pgp->StartLetter)/LETTER_BLOCK_WIDTH)*
3668 			GrData->udv_font.cxChar-1;
3669 		rcSel.top=y-GrData->udv_font.LineHeight;
3670 		rcSel.bottom=y;
3671 		rcSel.right=rcSel.left+GrData->udv_font.cxChar;
3672 		Red();
3673 		PaintRect(&rcSel);
3674 	}
3675 
3676 	/* -C- Draw the letters*/
3677 	if (svpp==NULL){/*means we don't use the Color Manager*/
3678 		while(pos<stop){
3679 			residue=(Uint1)szSequence[StartLetter-start_decal+(nCompt++)];
3680 			szBuf[nCompt2++]=residue;
3681 
3682 			/*each LETTER_BLOCK_WIDTH, add a blank column*/
3683 			if (!(pos % LETTER_BLOCK_WIDTH)) {
3684 				szBuf[nCompt2]=' ';
3685 				nCompt2++;
3686 			}
3687 			pos++;
3688 		}
3689 		Black();
3690 		MoveTo(x,y);
3691 		PaintString(szBuf);
3692 	}
3693 	else{ /*use The Color Manager*/
3694 		while(pos<stop){
3695 			/*retrieve colour*/
3696 			bsp_pos=start_decal+(StartLetter-start_decal)+nCompt;
3697 			rgb=DDV_GetColor(svpp, sip, Row, bsp_pos);
3698 			if(rgb != NULL ){
3699 			   curColor = GetColorRGB (rgb->rgb[0], rgb->rgb[1],rgb->rgb[2]);
3700 			}
3701 			else curColor=blackColor;
3702 			/*new colour?*/
3703 			if (curColor!=newColor){
3704 				if (szBuf[0]!='\0'){/*something to draw ?*/
3705 					szBuf[nCompt2]='\0';/*CLOSE THE STRING*/
3706 					MoveTo(x,y);
3707 					SetColor(newColor);
3708 					PaintString(szBuf);
3709 				}
3710 				newColor=curColor;
3711 				x+=(nCompt2*GrData->udv_font.cxChar);
3712 				nCompt2=0;
3713 				szBuf[nCompt2]='\0';
3714 			}
3715 			residue=(Uint1)szSequence[StartLetter-start_decal+(nCompt++)];
3716 			szBuf[nCompt2++]=residue;
3717 
3718 			/*each LETTER_BLOCK_WIDTH, add a blank column*/
3719 			if (!(pos % LETTER_BLOCK_WIDTH)) {
3720 				szBuf[nCompt2]=' ';
3721 				nCompt2++;
3722 			}
3723 			pos++;
3724 		}
3725 		if (szBuf[0]!='\0'){/*something to draw ?*/
3726 			szBuf[nCompt2]='\0';/*CLOSE THE STRING*/
3727 			MoveTo(x,y);
3728 			SetColor(newColor);
3729 			PaintString(szBuf);
3730 		}
3731 	}
3732 	Black();
3733 	MemFree(szBuf);
3734 }
3735 
3736 /*******************************************************************************
3737 
3738   Function : UDV_Draw_scale()
3739 
3740   Purpose : draw the numerical scale of a ParaG
3741 
3742   Parameters : 	GrData; graphical data (font size, etc)
3743 				ShowMajorTick;TRUE = show major ticks ( | )
3744 				ShowMMinorTick;TRUE = show minor ticks ( . )
3745 				ScalePosition; left, top, ...
3746 				StartLetter; start scale at...
3747 				StopLetter; ...and stop at
3748 				rc; rectangle containing this ParaG
3749 				LeftDecal;adjust position on the left, if needed
3750 				ScaleMaxVal;  scale length
3751 				UseBlockDisp; use the 10 by 10 letters block display
3752 
3753   Return value : none
3754 
3755 *******************************************************************************/
UDV_Draw_scale(UnDViewerGraphDataPtr GrData,Boolean ShowMajorTick,Boolean ShowMMinorTick,Uint1 ScalePosition,Int4 StartLetter,Int4 StopLetter,RecT PNTR rc,Int2 LeftDecal,Int4 ScaleMaxVal,Int4 AlignPos,Boolean UseBlockDisp,Int2 ColWidth,Uint4 DisplayType)3756 NLM_EXTERN void UDV_Draw_scale(UnDViewerGraphDataPtr GrData,
3757 		Boolean ShowMajorTick,Boolean ShowMMinorTick,Uint1 ScalePosition,
3758 		Int4 StartLetter,Int4 StopLetter,RecT PNTR rc,Int2 LeftDecal,
3759 		Int4 ScaleMaxVal,Int4 AlignPos,Boolean UseBlockDisp,Int2 ColWidth,
3760 		Uint4 DisplayType)
3761 {
3762 Int4 pos,AliPos,stop;				/*scale start at...(used to draw text)*/
3763 Int2 x,y,y2,y3,y4,xDecal;	/*text position*/
3764 Int2 xMargin,yMargin;	/*initial margins*/
3765 Char szBuf[15]={""};	/*scale value*/
3766 Int2 nTicks=0,nLet=0;	/*y decal*/
3767 Int2 cxChar_2,cyChar_4;
3768 
3769 	if (ShowMajorTick) nTicks++;
3770 	if (ScalePosition==SCALE_POS_TOP ||
3771 					ScalePosition==SCALE_POS_BOTH) nLet++;
3772 
3773 	pos=StartLetter+1;	/*remember : StartLetter is zero based*/
3774 	xMargin=rc->left+LeftDecal;
3775 	yMargin=rc->top;
3776 	y=yMargin;
3777 	xDecal=xMargin;
3778 	cxChar_2=GrData->udv_font.cxChar/2;
3779 	cyChar_4=GrData->udv_font.cyChar/4;
3780 	y2=(Int2)(y+GrData->udv_font.LineHeight);
3781 	AliPos=AlignPos+1;/*switch to 1-based value*/
3782 	ScaleMaxVal++;
3783 
3784 	if (DisplayType&DDV_DISP_VERT)
3785 		stop=StopLetter+2;
3786 	else
3787 		stop=StopLetter+1;
3788 
3789 	if ((ScalePosition==SCALE_POS_TOP ||
3790 					ScalePosition==SCALE_POS_BOTH)){
3791 		while(pos<stop){
3792 			if (/*(pos==StartLetter+1) ||*/ !(AliPos % LETTER_BLOCK_WIDTH)
3793 					&& AliPos!=ScaleMaxVal){
3794 				if (DisplayType&DDV_DISP_REVERTCOORD)
3795 					sprintf(szBuf,"%d",UDV_RevertBioSeqCoord(AliPos,ScaleMaxVal));
3796 				else
3797 					sprintf(szBuf,"%d",AliPos);
3798 
3799 				SetColor(GrData->udv_scale.ScaleColor);
3800 				/*scale on top or both*/
3801 				if(ShowMajorTick){/*center text on the tick*/
3802 					x=xDecal-(StringWidth(szBuf))/2;
3803 				}
3804 				else{/*align text right on pos*/
3805 					x=xDecal-StringWidth(szBuf)+cxChar_2;
3806 				}
3807 				if (ScalePosition==SCALE_POS_TOP ||
3808 							pos!=StartLetter+1){
3809 					MoveTo(x,y2);
3810 					PaintString (szBuf);
3811 				}
3812 			}
3813 
3814 			if (AliPos==ScaleMaxVal){/*end sequence only*/
3815 				if (ScalePosition==SCALE_POS_TOP ||
3816 						ScalePosition==SCALE_POS_BOTH){
3817 					/*scale on top or both*/
3818 					if(ShowMajorTick){
3819 						/*center text on the tick*/
3820 						if (DisplayType&DDV_DISP_REVERTCOORD)
3821 							sprintf(szBuf,"%d",UDV_RevertBioSeqCoord(AliPos,ScaleMaxVal));
3822 						else
3823 							sprintf(szBuf,"%d",AliPos);
3824 						x=xDecal-(StringWidth(szBuf))/2;
3825 						MoveTo(x,(Int2)(y2+GrData->udv_font.cyChar));
3826 						SetColor(GrData->udv_scale.ScaleColor);
3827 						PaintString (szBuf);
3828 					}
3829 					/*else {
3830 						x=xDecal-StringWidth(szBuf)+GrData->udv_font.cxChar;
3831 						MoveTo(x,y2);
3832 					}*/
3833 				}
3834 			}
3835 
3836 			xDecal+=ColWidth;
3837 
3838 			/*each LETTER_BLOCK_WIDTH, add a blank column*/
3839 			if (!(AliPos % LETTER_BLOCK_WIDTH)&&UseBlockDisp) xDecal+=ColWidth;
3840 			pos++;AliPos++;
3841 		}
3842 	}
3843 
3844 	/*scale on left only*/
3845 	pos=StartLetter+1;	/*remember : StartLetter is zero based*/
3846 	y=yMargin;
3847 	xDecal=xMargin;
3848 	y2=(Int2)(y+(nTicks+nLet+1)*GrData->udv_font.LineHeight);
3849 	AliPos=AlignPos+1;/*switch to 1-based value*/
3850 	if ((ScalePosition==SCALE_POS_LEFT ||
3851 		ScalePosition==SCALE_POS_BOTH)){
3852 		/*scale on the left; must be located on the BioSeq line*/
3853 		SetColor(GrData->udv_scale.ScaleColor);
3854 		if (DisplayType&DDV_DISP_REVERTCOORD)
3855 			sprintf(szBuf,"%d",UDV_RevertBioSeqCoord(AliPos,ScaleMaxVal));
3856 		else
3857 			sprintf(szBuf,"%d",AliPos);
3858 		x=rc->left-GrData->udv_font.cxChar-StringWidth(szBuf);
3859 		MoveTo(x,y2);
3860 		PaintString (szBuf);
3861 	}
3862 
3863 	/*Major ticks*/
3864 	pos=StartLetter+1;	/*remember : StartLetter is zero based*/
3865 	y=yMargin;
3866 	xDecal=xMargin;
3867 	y2=(Int2)(y+((nLet+1)*GrData->udv_font.LineHeight)-cyChar_4);
3868 	y3=(Int2)(y+(nLet*GrData->udv_font.LineHeight)+cyChar_4);
3869 	y4=(Int2)(y+(nLet*GrData->udv_font.LineHeight)+GrData->udv_font.cyChar);
3870 	if ((ScalePosition==SCALE_POS_TOP ||
3871 		ScalePosition==SCALE_POS_BOTH) &&
3872 		ShowMajorTick){
3873 
3874 		while(pos<StopLetter+1){
3875 			if (AliPos!=ScaleMaxVal &&
3876 				!(AliPos % LETTER_BLOCK_WIDTH)){
3877 				SetColor(GrData->udv_scale.TickMajColor);
3878 				x=xDecal;
3879 				MoveTo(x,y3);
3880 				LineTo(x,y2);
3881 			}
3882 			/*Minor ticks; only shown if Major present*/
3883 			if (ShowMMinorTick &&
3884 				!(AliPos % (LETTER_BLOCK_WIDTH/2)) &&
3885 					(AliPos % LETTER_BLOCK_WIDTH)){
3886 				SetColor(GrData->udv_scale.TickMinColor);
3887 				x=xDecal;
3888 				MoveTo(x,y4-2);
3889 				LineTo(x,y2-2);
3890 			}
3891 
3892 			xDecal+=ColWidth;
3893 
3894 			/*each LETTER_BLOCK_WIDTH, add a blank column*/
3895 			if (!(AliPos % LETTER_BLOCK_WIDTH)&&UseBlockDisp) xDecal+=ColWidth;
3896 			AliPos++;pos++;
3897 		}
3898 	}
3899 	Black();
3900 }
3901 
3902 /*******************************************************************************
3903 
3904   Function : UDV_calc_decalRC()
3905 
3906   Purpose : compute the y decal for ParaG RecT correct positionning on
3907   		the viewer panel
3908 
3909   Parameters :	ParaG; list of pgp
3910   				ScrollPos; actual position of the Vscroll bar
3911 				SrollMax; max value of the Vscroll bar
3912 				ScrollPage; size of a scroll page by page
3913 				nTotLines; total lines for all the pgp
3914 				LineHeight; height of a single line (pixel unit)
3915 				vnp; first ParaG to draw in the panel
3916 				stop; value to be used to stop the draw
3917 
3918   Return value : y decal value (pixel unit)
3919 
3920 *******************************************************************************/
UDV_calc_decalRC(ValNodePtr ParaG,Int4 ScrollPos,Int4 ScrollMax,Int4 ScrollPage,Int4 nTotLines,Int2 LineHeight,ValNodePtr PNTR vnp,Int4Ptr stop)3921 static Int4  UDV_calc_decalRC(ValNodePtr ParaG,Int4 ScrollPos,
3922 		Int4 ScrollMax,Int4 ScrollPage,Int4 nTotLines,Int2 LineHeight,
3923 		ValNodePtr PNTR vnp,Int4Ptr stop)
3924 {
3925 ValNodePtr vnp2;
3926 Int4 decal=0;
3927 ParaGPtr pgp;
3928 
3929 	/*find the ParaG where ScrollPos is Located*/
3930 	for(*vnp=ParaG ; *vnp != NULL ; *vnp=(*vnp)->next){
3931 		if ((*vnp)->data.ptrvalue){
3932 			pgp=(ParaGPtr)(*vnp)->data.ptrvalue;
3933 			if ((ScrollPos>=pgp->StartLine) &&
3934 				(ScrollPos<=(pgp->StartLine+pgp->nLines))){
3935 					break;
3936 			}
3937 		}
3938 	}
3939 
3940 	if (ScrollMax){
3941 		*stop=MIN(nTotLines,ScrollPos+ScrollPage);
3942 		for(vnp2=(*vnp) ; vnp2 != NULL ; vnp2=vnp2->next){
3943 			pgp=(ParaGPtr)vnp2->data.ptrvalue;
3944 			if (pgp->StartLine+pgp->nLines>=(*stop)){
3945 				break;
3946 			}
3947 		}
3948 	}
3949 	else{
3950 		*stop=nTotLines;
3951 	}
3952 
3953 	decal=ScrollPos*LineHeight-VIEWER_VERT_MARGIN;
3954 
3955 	return(decal);
3956 }
3957 
3958 /*******************************************************************************
3959 
3960   Function : UDV_calc_RCdraw()
3961 
3962   Purpose : compute the RC of a ParaG to be drawn
3963 
3964   Parameters :	rc_pgp; absolute position of a ParaG
3965   				decal; y decal to place rc_pgp within the viewer panel
3966 					(this value is calculated by UDV_calc_decalRC())
3967 
3968   Return value : position of the ParaG within the viewer panel
3969 
3970 *******************************************************************************/
UDV_calc_RCdraw(Int4 StartLine,Int4 nLines,RecT rcP,Int2 decal_gauche,Int4 decal_haut,Int2 LineHeight)3971 static RecT  UDV_calc_RCdraw(Int4 StartLine,Int4 nLines, RecT rcP,
3972 		Int2 decal_gauche,Int4 decal_haut,Int2 LineHeight)
3973 {
3974 RecT rc;
3975 
3976 	rc.top=(Int2)(StartLine*LineHeight+rcP.top-decal_haut);
3977 	rc.bottom=(Int2)(rc.top+nLines*LineHeight);
3978 	rc.left=decal_gauche;
3979 	rc.right=rcP.right-VIEWER_HORZ_MARGIN;
3980 
3981 	return(rc);
3982 }
3983 
3984 /*******************************************************************************
3985 
3986   Function : UDV_draw_empty_panel()
3987 
3988   Purpose : draw a emplty window
3989 
3990   Parameters :	rectangle to fill
3991   				GrDate; graphical data
3992 
3993   Return value : none
3994 
3995 *******************************************************************************/
3996 #ifndef WWW_UDV
UDV_draw_empty_panel(RecT rc,UnDViewerGraphDataPtr GrData,Boolean ShowText)3997 static void  UDV_draw_empty_panel(RecT rc,UnDViewerGraphDataPtr GrData,
3998 	Boolean ShowText)
3999 {
4000 	White();
4001 	PaintRect(&rc);
4002 
4003 	if (!ShowText) return;
4004 	Black();
4005 	SelectFont(GrData->udv_font.hFnt);
4006 
4007 	MoveTo((Int2)(rc.left+5),(Int2)(rc.top+GrData->udv_font.cyChar));
4008 	PaintString("Window");
4009 	MoveTo((Int2)(rc.left+5),(Int2)(rc.top+2*GrData->udv_font.cyChar));
4010 	PaintString("too small");
4011 	MoveTo((Int2)(rc.left+5),(Int2)(rc.top+3*GrData->udv_font.cyChar));
4012 	PaintString("to draw.");
4013 }
4014 #endif /*WWW_UDV*/
4015 
4016 /*******************************************************************************
4017 
4018   Function : UDV_draw_panel()
4019 
4020   Purpose :  draw the panel of UnD viewer
4021 
4022   Parameters :	handle of the panel
4023 
4024   Note : this function can be used as a callback by external software using
4025   		UnD-Viewer
4026 
4027   Return value : none
4028 
4029 *******************************************************************************/
4030 #ifndef WWW_UDV
UDV_draw_panel(PaneL p,ViewerDialogDataPtr vdp,RecT PNTR MyUpdateRect,Boolean bSelect)4031 static void UDV_draw_panel(PaneL p,ViewerDialogDataPtr vdp,RecT PNTR MyUpdateRect,
4032 	Boolean bSelect)
4033 {
4034 Uint4               DisplayStyle;
4035 Int4 				decal_haut,from_row,to_row,nTotRow,nLinesDraw;
4036 ValNodePtr 			vnp,vnp2,vnp_bsp;
4037 ParaGPtr 			pgp;
4038 RecT 				rc,rcP,rcP_old;
4039 Int2				decal_gauche;
4040 DDV_ColorGlobal     *svpp=NULL;
4041 ValNodePtr          vnp_seqinfo=NULL;
4042 SelStructPtr        ssp;/*used to get the selected region(s)*/
4043 Uint2               bsp_eID;
4044 Uint4               bsp_iID;
4045 ViewerMainPtr 	    vmp;
4046 Int4                Row = -1;
4047 
4048 	/*restrict panel drawing area: 'add' little margins*/
4049 	ObjectRect(p,&rcP);
4050 	rcP_old=rcP;
4051 	InsetRect(&rcP,4,4);
4052 	ClipRect(&rcP);
4053 
4054 
4055 	if (vdp == NULL) {
4056 		ResetClip();
4057 		return;
4058 	}
4059 
4060 	if (vdp->Parent){
4061 		vmp=(ViewerMainPtr)GetObjectExtra(vdp->Parent);
4062 		if (vmp->Show_logo){
4063 			UDV_Logo_onDraw(p);
4064 			return;
4065 		}
4066 	}
4067 
4068 	if (vdp->ParaG == NULL) {
4069 		UDV_draw_empty_panel(rcP,&vdp->udv_graph,FALSE);
4070 		ResetClip();
4071 		return;
4072 	}
4073 
4074 	if (vdp->udv_graph.udv_panel.nBlockByLine<1) {
4075 		UDV_draw_empty_panel(rcP,&vdp->udv_graph,TRUE);
4076 		ResetClip();
4077 		return;
4078 	}
4079 
4080 	decal_haut=vdp->udv_graph.udv_vscrl.ScrollPos*vdp->udv_graph.udv_font.LineHeight-
4081 			VIEWER_VERT_MARGIN;
4082 
4083 	from_row=(MyUpdateRect->top-rcP.top)/vdp->udv_graph.udv_font.LineHeight-1;
4084 	to_row=(MyUpdateRect->bottom-rcP.top)/vdp->udv_graph.udv_font.LineHeight+1;
4085 	if (from_row<0 && to_row<0) return;
4086 	if (from_row<0) from_row=0;
4087 	if (to_row<0) to_row=0;
4088 	from_row+=vdp->udv_graph.udv_vscrl.ScrollPos;
4089 	to_row+=vdp->udv_graph.udv_vscrl.ScrollPos;
4090 	if (from_row>vdp->udv_graph.udv_panel.nTotLines)
4091 		from_row=vdp->udv_graph.udv_panel.nTotLines;
4092 	if (to_row>vdp->udv_graph.udv_panel.nTotLines)
4093 		to_row=vdp->udv_graph.udv_panel.nTotLines;
4094 	nTotRow=to_row-from_row;
4095 
4096 	/*find the ParaG where ScrollPos is Located*/
4097 	vnp=vdp->ParaG;
4098 	while(vnp){
4099 		if (vnp->data.ptrvalue){
4100 			pgp=(ParaGPtr)vnp->data.ptrvalue;
4101 			if ((pgp->StartLine<=to_row)&&((pgp->StartLine+pgp->nLines)>=from_row)){
4102 					break;
4103 			}
4104 		}
4105 		vnp=vnp->next;
4106 	}
4107 
4108 	/*retrieve the colours table for the bsp*/
4109 #ifndef WWW_UDV
4110     if(vdp->vgp != NULL) {
4111         if(vdp->vgp->MasterViewer == SAMVIEWDDV)
4112             svpp = vdp->vgp->pCGlobal;
4113             Row = ViewMgr_GetRow(svpp, vdp->userkey);
4114     }
4115     if(svpp == NULL)
4116 	    svpp = (DDV_ColorGlobal *)DDV_GetColorGlobalEx((void *)vdp->bsp_i.bsp);
4117 #endif
4118 
4119 #ifdef WWW_UDV
4120 	svpp = NULL;
4121 #endif
4122 
4123 	/*draw ParaG until out of panel*/
4124 	SelectFont(vdp->udv_graph.udv_font.hFnt);
4125 
4126 	/*3D border to resize the cxName field*/
4127 	LtGray();
4128 
4129 	MoveTo((Int2)(vdp->udv_graph.udv_panel.cxName-1),rcP.top);
4130 	LineTo((Int2)(vdp->udv_graph.udv_panel.cxName-1),rcP.bottom);
4131 
4132 	LtGray();
4133 	MoveTo((Int2)(vdp->udv_graph.udv_panel.cxName+1),rcP.top);
4134 	LineTo((Int2)(vdp->udv_graph.udv_panel.cxName+1),rcP.bottom);
4135 	LtGray();
4136 	MoveTo((Int2)(vdp->udv_graph.udv_panel.cxName+2),rcP.top);
4137 	LineTo((Int2)(vdp->udv_graph.udv_panel.cxName+2),rcP.bottom);
4138 
4139 	Black();
4140 	MoveTo((Int2)(vdp->udv_graph.udv_panel.cxName+3),rcP.top);
4141 	LineTo((Int2)(vdp->udv_graph.udv_panel.cxName+3),rcP.bottom);
4142 
4143 	decal_gauche=vdp->udv_graph.udv_panel.cxName+rcP_old.left+
4144 			vdp->udv_graph.udv_scale.cxLeftScale;
4145 	nLinesDraw=0;
4146 
4147 	/*get selected regions*/
4148 	ssp=ObjMgrGetSelected();
4149 	vnp_bsp=NULL;
4150 	bsp_eID=ObjMgrGetEntityIDForPointer((Pointer)vdp->bsp_i.bsp);
4151 	bsp_iID = GetItemIDGivenPointer (bsp_eID,
4152 			OBJ_BIOSEQ, (Pointer) vdp->bsp_i.bsp);
4153 	if (bsp_eID!=0 && bsp_iID!=0){
4154 		vnp_bsp=UDV_GetSelectedRegions(ssp,bsp_eID,bsp_iID);
4155 	}
4156 
4157 	if (vdp->bDisplayRevComp)
4158 		DisplayStyle=DDV_DISP_VERT|DDV_DISP_REVERTCOORD;
4159 	else
4160 		DisplayStyle=DDV_DISP_VERT;
4161 
4162 	for(vnp2=vnp ; vnp2 != NULL ; vnp2=vnp2->next){
4163 		if (vnp2->data.ptrvalue){
4164 			pgp=(ParaGPtr)vnp2->data.ptrvalue;
4165 
4166 			rc=UDV_calc_RCdraw(pgp->StartLine,pgp->nLines,rcP_old,
4167 					decal_gauche,decal_haut,vdp->udv_graph.udv_font.LineHeight);
4168 
4169 		/*ruler*/
4170 			if (vdp->udv_graph.udv_panel.ShowScale)
4171 				UDV_Draw_scale(&vdp->udv_graph,
4172 					vdp->udv_graph.udv_scale.ShowMajorTick,
4173 					vdp->udv_graph.udv_scale.ShowMMinorTick,
4174 					(Uint1) vdp->udv_graph.udv_scale.ScalePosition,
4175 					pgp->StartLetter,pgp->StopLetter,&rc,
4176 					vdp->udv_graph.udv_font.cxChar,
4177 					vdp->bsp_i.bspLength,pgp->StartLetter,
4178 					TRUE,
4179 					vdp->udv_graph.udv_font.cxChar,DisplayStyle);
4180 		/*Sequence*/
4181 			if (vdp->bsp_i.SeqBuf)
4182 				UDV_Draw_sequence(&vdp->udv_graph,svpp,
4183 					vdp->udv_graph.udv_font.UseDefaultColorLetter,
4184 					vdp->udv_graph.udv_font.LetterColor,
4185 					pgp,&rc,vdp->bsp_i.StartBuf,pgp->StartLetter,
4186 					vdp->bsp_i.SeqBuf,vdp->bsp_i.bsp->id,vnp_bsp,bSelect,Row,
4187 					vdp->bsp_i.bspLength,vdp->bDisplayRevComp);
4188 		/*Sequence name*/
4189 			UDV_Draw_sequence_name(&vdp->udv_graph,&vdp->bsp_i,&rc);
4190 		/*Features*/
4191 			if (vdp->udv_graph.udv_panel.ShowFeatures){
4192 				UDV_Draw_features(&vdp->udv_graph,&vdp->bsp_i,
4193 					vdp->udv_graph.udv_font.UseDefaultColorLetter,
4194 					vdp->udv_graph.udv_font.LetterColor,pgp,&rc,
4195 					vdp->udv_graph.pClr,&(vdp->Item_select),&(vdp->Old_Item_select),
4196 					DDV_DISP_VERT);
4197 				/*Feature names
4198 					UDV_Draw_features_label(&vdp->udv_graph,&vdp->bsp_i,pgp,
4199 						&rc,
4200 						vdp->udv_graph.pClr,vdp->Item_select,
4201 						vdp->Old_Item_select);*/
4202 			}
4203 			/*nLinesDraw+=pgp->nLines;
4204 			if (nLinesDraw>nTotRow) break;*/
4205 			if ((pgp->StartLine+pgp->nLines)>to_row) break;
4206 			/*if (pgp->StartLine > stop) break;*/
4207 		}
4208 	}
4209 
4210 	ResetClip();
4211 }
4212 #endif /*WWW_UDV*/
4213 
4214 /*******************************************************************************
4215 
4216   Function : UDV_draw_viewer()
4217 
4218   Purpose :  draw the panel of UnD viewer
4219 
4220   Parameters :	handle of the panel
4221 
4222   Note : this function is called when clickfeat; this is not a callback
4223 
4224   Return value : none
4225 
4226 *******************************************************************************/
4227 #ifndef WWW_UDV
UDV_draw_viewer(PaneL p)4228 NLM_EXTERN void  UDV_draw_viewer (PaneL p)
4229 {
4230 ViewerDialogDataPtr vdp;
4231 
4232 	/*get some usefull data...*/
4233 	vdp = (ViewerDialogDataPtr) GetObjectExtra (p);
4234 
4235 	if (vdp==NULL) return;
4236 
4237 	UDV_draw_panel(p,vdp,&updateRect,TRUE);
4238 }
4239 #endif /*WWW_UDV*/
4240 
4241 
4242 /*******************************************************************************
4243 
4244   Function : UDV_Logo_onDraw()
4245 
4246   Purpose : draw the software logo
4247 
4248   Parameters :	handle of the panel
4249 
4250   Return value : none
4251 
4252 *******************************************************************************/
4253 #ifndef WWW_UDV
UDV_Logo_onDraw(PaneL p)4254 NLM_EXTERN void UDV_Logo_onDraw (PaneL p)
4255 {
4256 RecT 				rcP;
4257 UDVLogoDataPtr		ldp;
4258 
4259 	/*get some usefull data...*/
4260 	ldp = (UDVLogoDataPtr) GetAppProperty ("UDVLogoData");
4261 
4262 	if (ldp==NULL) return;
4263 
4264 	Select (p);
4265 	/*restrict panel drawing area: 'add' little margins*/
4266 	ObjectRect(p,&rcP);
4267 	InsetRect(&rcP,4,4);
4268 	ClipRect(&rcP);
4269 
4270 	White();
4271 	PaintRect(&rcP);
4272 	if (ldp->f1 && ldp->f2 && ldp->f3) draw_logo(rcP,ldp->f1,ldp->f2,ldp->f3,
4273 			ldp->szTitle,ldp->szDesc);
4274 	ResetClip();
4275 
4276 	/*3D border*/
4277 }
4278 #endif /*WWW_UDV*/
4279 
4280