0027796: Visualization - allow 3D objects with Graphic3d_TMF_2d flag
[occt.git] / src / AIS / AIS_ColorScale.cxx
1 // Created on: 2015-02-03
2 // Copyright (c) 2015 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <AIS_ColorScale.hxx>
16 #include <AIS_InteractiveContext.hxx>
17 #include <Aspect_TypeOfColorScaleData.hxx>
18 #include <Aspect_TypeOfColorScalePosition.hxx>
19 #include <Aspect_Window.hxx>
20 #include <Geom_Line.hxx>
21 #include <GeomAdaptor_Curve.hxx>
22 #include <Graphic3d_ArrayOfPolygons.hxx>
23 #include <Graphic3d_ArrayOfPolylines.hxx>
24 #include <Graphic3d_AspectFillArea3d.hxx>
25 #include <Graphic3d_AspectText3d.hxx>
26 #include <Graphic3d_GraphicDriver.hxx>
27 #include <Graphic3d_ArrayOfTriangles.hxx>
28 #include <Prs3d_LineAspect.hxx>
29 #include <Prs3d_Root.hxx>
30 #include <Prs3d_ShadingAspect.hxx>
31 #include <Prs3d_Text.hxx>
32 #include <Prs3d_TextAspect.hxx>
33 #include <SelectMgr_EntityOwner.hxx>
34 #include <SelectMgr_Selection.hxx>
35 #include <Select3D_SensitiveBox.hxx>
36 #include <Select3D_SensitiveSegment.hxx>
37 #include <StdPrs_Curve.hxx>
38 #include <V3d_Viewer.hxx>
39 #include <V3d_View.hxx>
40
41
42 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColorScale,AIS_InteractiveObject)
43
44 //=======================================================================
45 //function : AIS_ColorScale
46 //purpose  :
47 //=======================================================================
48 AIS_ColorScale::AIS_ColorScale() :
49 myMin (0.0),
50 myMax (1.0),
51 myTitle (""),
52 myFormat ("%.4g"),
53 myInterval (10),
54 myColorType (Aspect_TOCSD_AUTO),
55 myLabelType (Aspect_TOCSD_AUTO),
56 myAtBorder (Standard_True),
57 myReversed (Standard_False),
58 myIsLogarithmic (Standard_False),
59 myLabelPos (Aspect_TOCSP_RIGHT),
60 myTitlePos (Aspect_TOCSP_CENTER),
61 myXPos (0),
62 myYPos (0),
63 myBreadth (0),
64 myHeight (0),
65 myTextHeight(20)
66 {
67 }
68
69 //=======================================================================
70 //function : GetRange
71 //purpose  :
72 //=======================================================================
73 void AIS_ColorScale::GetRange (Standard_Real& theMin, Standard_Real& theMax) const
74 {
75   theMin = myMin;
76   theMax = myMax;
77 }
78
79 //=======================================================================
80 //function : GetLabel
81 //purpose  :
82 //=======================================================================
83 TCollection_ExtendedString AIS_ColorScale::GetLabel (const Standard_Integer theIndex) const
84 {
85   if (GetLabelType() == Aspect_TOCSD_USER)
86   {
87     if (theIndex <= 0 || theIndex > myLabels.Length())
88     {
89       return "";
90     }
91     return myLabels.Value (theIndex);
92   }
93
94   // value to be shown depends on label position
95   Standard_Real aVal = IsLabelAtBorder() ? GetIntervalValue (theIndex - 1) :
96                        0.5 * (GetIntervalValue (theIndex - 1) + GetIntervalValue (theIndex));
97
98   const TCollection_AsciiString aFormat = Format();
99   Standard_Character aBuf[1024];
100   sprintf (aBuf, aFormat.ToCString(), aVal);
101   return TCollection_ExtendedString (aBuf);
102 }
103
104 //=======================================================================
105 //function : GetIntervalColor
106 //purpose  :
107 //=======================================================================
108 Quantity_Color AIS_ColorScale::GetIntervalColor (const Standard_Integer theIndex) const
109 {
110   if (GetColorType() == Aspect_TOCSD_USER)
111   {
112     if (theIndex <= 0 || theIndex > myColors.Length())
113     {
114       return Quantity_Color();
115     }
116     return myColors.Value (theIndex);
117   }
118
119   return Quantity_Color (HueFromValue (theIndex - 1, 0, GetNumberOfIntervals() - 1), 1.0, 1.0, Quantity_TOC_HLS);
120 }
121
122 //=======================================================================
123 //function : GetLabels
124 //purpose  :
125 //=======================================================================
126 void AIS_ColorScale::GetLabels (TColStd_SequenceOfExtendedString& theLabels) const
127 {
128   theLabels.Clear();
129   for (Standard_Integer i = 1; i <= myLabels.Length(); i++)
130     theLabels.Append (myLabels.Value (i));
131 }
132
133 //=======================================================================
134 //function : GetColors
135 //purpose  :
136 //=======================================================================
137 void AIS_ColorScale::GetColors (Aspect_SequenceOfColor& theColors) const
138 {
139   theColors.Clear();
140   for (Standard_Integer i = 1; i <= myColors.Length(); i++)
141     theColors.Append (myColors.Value (i));
142 }
143
144 //=======================================================================
145 //function : SetMin
146 //purpose  :
147 //=======================================================================
148 void AIS_ColorScale::SetMin (const Standard_Real theMin)
149 {
150   SetRange (theMin, GetMax());
151 }
152
153 //=======================================================================
154 //function : SetMax
155 //purpose  :
156 //=======================================================================
157 void AIS_ColorScale::SetMax (const Standard_Real theMax)
158 {
159   SetRange (GetMin(), theMax);
160 }
161
162 //=======================================================================
163 //function : SetRange
164 //purpose  :
165 //=======================================================================
166 void AIS_ColorScale::SetRange (const Standard_Real theMin, const Standard_Real theMax)
167 {
168   if (myMin == theMin && myMax == theMax)
169     return;
170
171   myMin = Min (theMin, theMax);
172   myMax = Max (theMin, theMax);
173 }
174
175 //=======================================================================
176 //function : SetLabelType
177 //purpose  :
178 //=======================================================================
179 void AIS_ColorScale::SetLabelType (const Aspect_TypeOfColorScaleData theType)
180 {
181   if (myLabelType == theType)
182     return;
183
184   myLabelType = theType;
185 }
186
187 //=======================================================================
188 //function : SetColorType
189 //purpose  :
190 //=======================================================================
191 void AIS_ColorScale::SetColorType (const Aspect_TypeOfColorScaleData theType)
192 {
193   if (myColorType == theType)
194     return;
195
196   myColorType = theType;
197 }
198
199 //=======================================================================
200 //function : SetNumberOfIntervals
201 //purpose  :
202 //=======================================================================
203 void AIS_ColorScale::SetNumberOfIntervals (const Standard_Integer theNum)
204 {
205   if (myInterval == theNum || theNum < 1)
206     return;
207
208   myInterval = theNum;
209 }
210
211 //=======================================================================
212 //function : SetTitle
213 //purpose  :
214 //=======================================================================
215 void AIS_ColorScale::SetTitle (const TCollection_ExtendedString& theTitle)
216 {
217   if (myTitle == theTitle)
218     return;
219
220   myTitle = theTitle;
221 }
222
223 //=======================================================================
224 //function : SetFormat
225 //purpose  :
226 //=======================================================================
227 void AIS_ColorScale::SetFormat (const TCollection_AsciiString& theFormat)
228 {
229   if (myFormat == theFormat)
230     return;
231
232   myFormat = theFormat;
233 }
234
235 //=======================================================================
236 //function : SetLabel
237 //purpose  :
238 //=======================================================================
239 void AIS_ColorScale::SetLabel (const TCollection_ExtendedString& theLabel, const Standard_Integer theIndex)
240 {
241   Standard_Integer i = (theIndex <= 0 ? myLabels.Length() + 1 : theIndex);
242   while (i > myLabels.Length())
243     myLabels.Append (TCollection_ExtendedString());
244   myLabels.SetValue (i, theLabel);
245 }
246
247 //=======================================================================
248 //function : SetIntervalColor
249 //purpose  :
250 //=======================================================================
251 void AIS_ColorScale::SetIntervalColor (const Quantity_Color& theColor, const Standard_Integer theIndex)
252 {
253   Standard_Integer i = (theIndex <= 0 ? myColors.Length() + 1 : theIndex);
254   while (i > myColors.Length())
255     myColors.Append (Quantity_Color());
256   myColors.SetValue (i, theColor);
257 }
258
259 //=======================================================================
260 //function : SetLabels
261 //purpose  :
262 //=======================================================================
263 void AIS_ColorScale::SetLabels (const TColStd_SequenceOfExtendedString& theSeq)
264 {
265   myLabels.Clear();
266   for (Standard_Integer i = 1; i <= theSeq.Length(); i++)
267     myLabels.Append (theSeq.Value (i));
268 }
269
270 //=======================================================================
271 //function : SetColors
272 //purpose  :
273 //=======================================================================
274 void AIS_ColorScale::SetColors (const Aspect_SequenceOfColor& theSeq)
275 {
276   myColors.Clear();
277   for (Standard_Integer i = 1; i <= theSeq.Length(); i++)
278     myColors.Append (theSeq.Value (i));
279 }
280
281 //=======================================================================
282 //function : SetLabelPosition
283 //purpose  :
284 //=======================================================================
285 void AIS_ColorScale::SetLabelPosition (const Aspect_TypeOfColorScalePosition thePos)
286 {
287   if (myLabelPos == thePos)
288     return;
289
290   myLabelPos = thePos;
291 }
292
293 //=======================================================================
294 //function : SetTitlePosition
295 //purpose  :
296 //=======================================================================
297 void AIS_ColorScale::SetTitlePosition (const Aspect_TypeOfColorScalePosition thePos)
298 {
299   if (myTitlePos == thePos)
300     return;
301
302   myTitlePos = thePos;
303 }
304
305 //=======================================================================
306 //function : SetReversed
307 //purpose  :
308 //=======================================================================
309 void AIS_ColorScale::SetReversed (const Standard_Boolean theReverse)
310 {
311   if (myReversed == theReverse)
312     return;
313
314   myReversed = theReverse;
315 }
316
317 //=======================================================================
318 //function : SetLabelAtBorder
319 //purpose  :
320 //=======================================================================
321 void AIS_ColorScale::SetLabelAtBorder (const Standard_Boolean theOn)
322 {
323   if (myAtBorder == theOn)
324     return;
325
326   myAtBorder = theOn;
327 }
328
329 //=======================================================================
330 //function : GetPosition
331 //purpose  :
332 //=======================================================================
333 void AIS_ColorScale::GetPosition (Standard_Real& theX, Standard_Real& theY) const
334 {
335   theX = myXPos;
336   theY = myYPos;
337 }
338
339 //=======================================================================
340 //function : SetPosition
341 //purpose  :
342 //=======================================================================
343 void AIS_ColorScale::SetPosition (const Standard_Integer theX, const Standard_Integer theY)
344 {
345   if (myXPos == theX && myYPos == theY)
346     return;
347
348   myXPos = theX;
349   myYPos = theY;
350 }
351
352 //=======================================================================
353 //function : SetXPosition
354 //purpose  :
355 //=======================================================================
356 void AIS_ColorScale::SetXPosition (const Standard_Integer theX)
357 {
358   SetPosition (theX, GetYPosition());
359 }
360
361 //=======================================================================
362 //function : SetYPosition
363 //purpose  :
364 //=======================================================================
365 void AIS_ColorScale::SetYPosition (const Standard_Integer theY)
366 {
367   SetPosition (GetXPosition(), theY);
368 }
369
370 //=======================================================================
371 //function : GetSize
372 //purpose  :
373 //=======================================================================
374 void AIS_ColorScale::GetSize (Standard_Integer& theBreadth, Standard_Integer& theHeight) const
375 {
376   theBreadth = myBreadth;
377   theHeight = myHeight;
378 }
379
380 //=======================================================================
381 //function : SetSize
382 //purpose  :
383 //=======================================================================
384 void AIS_ColorScale::SetSize (const Standard_Integer theBreadth, const Standard_Integer theHeight)
385 {
386   if (myBreadth == theBreadth && myHeight == theHeight)
387     return;
388
389   myBreadth = theBreadth;
390   myHeight = theHeight;
391 }
392
393 //=======================================================================
394 //function : SetBreadth
395 //purpose  :
396 //=======================================================================
397 void AIS_ColorScale::SetBreadth (const Standard_Integer theWidth)
398 {
399   SetSize (theWidth, GetHeight());
400 }
401
402 //=======================================================================
403 //function : SetHeight
404 //purpose  :
405 //=======================================================================
406 void AIS_ColorScale::SetHeight (const Standard_Integer theHeight)
407 {
408   SetSize (GetBreadth(), theHeight);
409 }
410
411 //=======================================================================
412 //function : SizeHint
413 //purpose  :
414 //=======================================================================
415 void AIS_ColorScale::SizeHint (Standard_Integer& theWidth, Standard_Integer& theHeight) const
416 {
417   Standard_Integer aNum = GetNumberOfIntervals();
418
419   Standard_Integer aSpacer = 5;
420   Standard_Integer aTextWidth = 0;
421   Standard_Integer aTextHeight = TextHeight ("");
422   Standard_Integer aColorWidth = 20;
423
424   if (GetLabelPosition() != Aspect_TOCSP_NONE)
425   {
426     for (Standard_Integer idx = (IsLabelAtBorder() ? 0 : 1); idx <= aNum; idx++)
427       aTextWidth = Max (aTextWidth, TextWidth (GetLabel (idx)));
428   }
429
430   Standard_Integer aScaleWidth = 0;
431   Standard_Integer aScaleHeight = 0;
432
433   aScaleWidth = aColorWidth + aTextWidth + ( aTextWidth ? 3 : 2 ) * aSpacer;
434   aScaleHeight = (Standard_Integer)( 1.5 * ( aNum + (IsLabelAtBorder() ? 2 : 1) ) * aTextHeight );
435
436   Standard_Integer aTitleWidth = 0;
437   Standard_Integer aTitleHeight = 0;
438   if (GetTitle().Length())
439   {
440     aTitleHeight = TextHeight (GetTitle()) + aSpacer;
441     aTitleWidth =  TextWidth (GetTitle()) + 10;
442   }
443
444   theWidth = Max (aTitleWidth, aScaleWidth);
445   theHeight = aScaleHeight + aTitleHeight;
446 }
447
448 //=======================================================================
449 //function : Format
450 //purpose  :
451 //=======================================================================
452 TCollection_AsciiString AIS_ColorScale::Format() const
453 {
454   return GetFormat();
455 }
456
457 //=======================================================================
458 //function : GetIntervalValue
459 //purpose  :
460 //=======================================================================
461 Standard_Real AIS_ColorScale::GetIntervalValue (const Standard_Integer theIndex) const
462 {
463   if (GetNumberOfIntervals() <= 0)
464     return 0.;
465
466   if (IsLogarithmic())
467   {
468     Standard_Real aMin = myMin > 0 ? myMin : 1.0;
469     Standard_Real aDivisor = std::pow (myMax/aMin, 1.0/myInterval);
470     return aMin*std::pow (aDivisor,theIndex);
471   }
472
473   Standard_Real aNum = 0;
474   if (GetNumberOfIntervals() > 0)
475     aNum = GetMin() + theIndex * ( Abs (GetMax() - GetMin()) / GetNumberOfIntervals() );
476   return aNum;
477 }
478
479 //=======================================================================
480 //function : HueFromValue
481 //purpose  :
482 //=======================================================================
483 Standard_Integer AIS_ColorScale::HueFromValue (const Standard_Integer theValue,
484                                                const Standard_Integer theMin, const Standard_Integer theMax)
485 {
486   Standard_Integer aMinLimit (0), aMaxLimit (230);
487
488   Standard_Integer aHue = aMaxLimit;
489   if (theMin != theMax)
490     aHue = (Standard_Integer)( aMaxLimit - ( aMaxLimit - aMinLimit ) * ( theValue - theMin ) / ( theMax - theMin ) );
491
492   aHue = Min (Max (aMinLimit, aHue), aMaxLimit);
493
494   return aHue;
495 }
496
497 //=======================================================================
498 //function : FindColor
499 //purpose  :
500 //=======================================================================
501 Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
502                                             Quantity_Color& theColor) const
503 {
504   if (theValue < myMin || theValue > myMax || myMax < myMin)
505   {
506     theColor = Quantity_Color();
507     return Standard_False;
508   }
509
510   if (GetColorType() == Aspect_TOCSD_USER)
511   {
512     Standard_Integer anIndex = 0;
513     if (Abs (myMax - myMin) > Precision::Approximation())
514     {
515       anIndex = (theValue - myMin < Precision::Confusion()) 
516         ? 1
517         : Standard_Integer (Ceiling (( theValue - myMin ) / ( (myMax - myMin) / myInterval)));
518     }
519
520     if (anIndex <= 0 || anIndex > myColors.Length())
521     {
522       theColor = Quantity_Color();
523       return Standard_False;
524     }
525
526     theColor = myColors.Value (anIndex);
527     return Standard_True;
528   }
529
530   return FindColor (theValue, myMin, myMax, myInterval, theColor);
531 }
532
533 //=======================================================================
534 //function : FindColor
535 //purpose  :
536 //=======================================================================
537 Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
538                                             const Standard_Real theMin,
539                                             const Standard_Real theMax,
540                                             const Standard_Integer theColorsCount,
541                                             Quantity_Color& theColor)
542 {
543   if (theValue < theMin || theValue > theMax || theMax < theMin)
544     return Standard_False;
545
546   else
547   {
548     Standard_Real anIntervNumber = 0;
549     if(Abs (theMax-theMin) > Precision::Approximation())
550       anIntervNumber = Floor (Standard_Real (theColorsCount) * ( theValue - theMin ) / ( theMax - theMin ));
551
552     Standard_Integer anInterv = Standard_Integer (anIntervNumber);
553
554     theColor = Quantity_Color (HueFromValue (anInterv, 0, theColorsCount - 1), 1.0, 1.0, Quantity_TOC_HLS);
555
556     return Standard_True;
557   }
558 }
559
560 //=======================================================================
561 //function : Compute
562 //purpose  :
563 //=======================================================================
564 void AIS_ColorScale::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
565                              const Handle(Prs3d_Presentation)& thePresentation,
566                              const Standard_Integer /*theMode*/)
567 {
568   Handle(V3d_Viewer) aViewer= GetContext()->CurrentViewer();
569   aViewer->InitActiveViews();
570   Standard_Integer aNum = GetNumberOfIntervals();
571   Aspect_TypeOfColorScalePosition aLabPos = GetLabelPosition();
572
573   Standard_Integer aSpacer = 5;
574   Standard_Integer aTextWidth = 0;
575   Standard_Integer aTextHeight = myTextHeight;
576   Standard_Boolean toDrawLabel = GetLabelPosition() != Aspect_TOCSP_NONE;
577   TCollection_ExtendedString aTitle = GetTitle();
578   Standard_Integer aTitleHeight = aSpacer;
579   Quantity_Color aFgColor (hasOwnColor ? myOwnColor : Quantity_NOC_WHITE);
580
581   // Draw title
582   if (aTitle.Length())
583   {
584     aTitleHeight += myTextHeight + aSpacer;
585     drawText (thePresentation, aTitle, (Standard_Integer)myXPos + aSpacer, myHeight - ((Standard_Integer)myYPos - 2 * aSpacer + aTitleHeight), aFgColor);
586   }
587
588   Standard_Boolean toReverse = IsReversed();
589
590   Aspect_SequenceOfColor aColors;
591   for (Standard_Integer i = 1; i <= aNum; i++)
592   {
593     if (toReverse)
594     {
595       aColors.Prepend (GetIntervalColor (i));
596     }
597     else
598     {
599       aColors.Append (GetIntervalColor (i));
600     }
601   }
602
603   TColStd_SequenceOfExtendedString aLabels;
604   Standard_Integer aLabCount = IsLabelAtBorder() ? aNum + 1 : aNum;
605   for (Standard_Integer i = 1; i <= aLabCount; i++)
606   {
607     if (toReverse)
608     {
609       aLabels.Prepend (GetLabel (i));
610     }
611     else
612     {
613       aLabels.Append (GetLabel (i));
614     }
615   }
616
617   if (toDrawLabel)
618     for (Standard_Integer i = 1; i <= aLabels.Length(); i++)
619       aTextWidth = Max (aTextWidth, TextWidth (aLabels.Value (i)));
620
621   Standard_Integer aSpc = ( myHeight - ( ( Min (aLabCount, 2) + Abs (aLabCount - aNum - 1) ) * aTextHeight ) - aTitleHeight );
622   Standard_Real aVal = aSpc != 0 ? 1.0 * ( aLabCount - Min (aLabCount, 0) ) * aTextHeight / aSpc : 0;
623   Standard_Real anIPart;
624   Standard_Real anFPart = modf (aVal, &anIPart);
625   Standard_Integer aFilter = (Standard_Integer)anIPart + ( anFPart != 0 ? 1 : 0 );
626
627   Standard_Real aStep = 1.0 * ( myHeight - (aLabCount - aNum + Abs (aLabCount - aNum - 1)) * aTextHeight - aTitleHeight ) / aNum;
628
629   Standard_Integer anAscent = 0;
630   Standard_Integer aColorBreadth = Max (5, Min (20, myBreadth - aTextWidth - 3 * aSpacer));
631   if (aLabPos == Aspect_TOCSP_CENTER || !toDrawLabel)
632     aColorBreadth += aTextWidth;
633
634   // Draw colors
635   Standard_Integer aX = (Standard_Integer)myXPos + aSpacer;
636   if (aLabPos == Aspect_TOCSP_LEFT)
637     aX += aTextWidth + ( aTextWidth ? 1 : 0 ) * aSpacer;
638
639   Standard_Real anOffset = 1.0 * aTextHeight / 2 * ( aLabCount - aNum + Abs (aLabCount - aNum - 1) );
640   anOffset += 2*aSpacer;
641   Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
642   Handle (Graphic3d_ArrayOfTriangles) aPrim;
643   Standard_Integer anEdgesPerColor = 6;
644   Standard_Integer aVerticiesPerColor = 4;
645   aPrim = new Graphic3d_ArrayOfTriangles (aColors.Length()*aVerticiesPerColor, aColors.Length()*anEdgesPerColor, 0, 1);
646   Standard_Integer aVertIndex = 1;
647   for (Standard_Integer i = 1; i <= aColors.Length() && aStep > 0; i++)
648   {
649     Standard_Integer aY = (Standard_Integer)( myYPos + ( i - 1 )* aStep + anOffset );
650     Standard_Integer aColorHeight = (Standard_Integer)( myYPos + ( i ) * aStep + anOffset ) - aY;
651     aPrim->AddVertex (gp_Pnt (aX, aY, 0.0), aColors.Value( i ));
652     aPrim->AddVertex (gp_Pnt (aX+aColorBreadth, aY, 0.0), aColors.Value( i ));
653     aPrim->AddVertex (gp_Pnt (aX, aY+aColorHeight, 0.0), aColors.Value( i ));
654     aPrim->AddVertex (gp_Pnt (aX+aColorBreadth, aY+aColorHeight, 0.0), aColors.Value( i ));
655     aPrim->AddEdge(aVertIndex);
656     aPrim->AddEdge(aVertIndex+1);
657     aPrim->AddEdge(aVertIndex+2);
658     aPrim->AddEdge(aVertIndex+1);
659     aPrim->AddEdge(aVertIndex+2);
660     aPrim->AddEdge(aVertIndex+3);
661     aVertIndex += 4;
662   }
663   aGroup->AddPrimitiveArray (aPrim);
664
665   if (aStep > 0)
666     drawFrame (thePresentation, aX - 1, (Standard_Integer)(myYPos + anOffset - 1), aColorBreadth + 2, (Standard_Integer)(aColors.Length() * aStep + 2), aFgColor);
667
668   // Draw Labels
669   anOffset = 1.0 * Abs (aLabCount - aNum - 1) * ( aStep - aTextHeight ) / 2 + 1.0 * Abs (aLabCount - aNum - 1) * aTextHeight / 2;
670   anOffset += 2*aSpacer;
671   if (toDrawLabel && aLabels.Length() && aFilter > 0)
672   {
673     Standard_Integer i1 = 0;
674     Standard_Integer i2 = aLabCount - 1;
675     Standard_Integer aLast1( i1 ), aLast2( i2 );
676     aX = (Standard_Integer)myXPos + aSpacer;
677     switch (aLabPos)
678     {
679       case Aspect_TOCSP_NONE:
680       case Aspect_TOCSP_LEFT:
681         break;
682       case Aspect_TOCSP_CENTER:
683         aX += ( aColorBreadth - aTextWidth ) / 2;
684         break;
685       case Aspect_TOCSP_RIGHT:
686         aX += aColorBreadth + aSpacer;
687         break;
688     }
689     while (i2 - i1 >= aFilter || ( i2 == 0 && i1 == 0 ))
690     {
691       Standard_Integer aPos1 = i1;
692       Standard_Integer aPos2 = aLabCount - 1 - i2;
693       if (aFilter && !( aPos1 % aFilter ))
694       {
695         drawText (thePresentation, aLabels.Value (i1 + 1), aX, (Standard_Integer)( myYPos + i1 * aStep + anAscent + anOffset ), aFgColor);
696         aLast1 = i1;
697       }
698       if (aFilter && !( aPos2 % aFilter ))
699       {
700         drawText (thePresentation, aLabels.Value (i2 + 1), aX, (Standard_Integer)( myYPos + i2 * aStep + anAscent + anOffset ), aFgColor);
701         aLast2 = i2;
702       }
703       i1++;
704       i2--;
705     }
706     Standard_Integer aPos = i1;
707     Standard_Integer i0 = -1;
708     while (aPos <= i2 && i0 == -1)
709     {
710       if (aFilter && !( aPos % aFilter ) && Abs (aPos - aLast1) >= aFilter && Abs (aPos - aLast2) >= aFilter)
711         i0 = aPos;
712       aPos++;
713     }
714
715     if (i0 != -1)
716       drawText (thePresentation, aLabels.Value (i0 + 1), aX, (Standard_Integer)( myYPos + i0 * aStep + anAscent + anOffset ), aFgColor);
717   }
718 }
719
720 //=======================================================================
721 //function : drawFrame
722 //purpose  :
723 //=======================================================================
724 void AIS_ColorScale::drawFrame (const Handle(Prs3d_Presentation)& thePresentation,
725                        const Standard_Integer theX, const Standard_Integer theY,
726                        const Standard_Integer theWidth, const Standard_Integer theHeight,
727                        const Quantity_Color& theColor)
728 {
729   Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
730   Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
731   aPrim->AddVertex (theX,theY,0.0);
732   aPrim->AddVertex (theX+theWidth,theY,0.0);
733   aPrim->AddVertex (theX+theWidth,theY+theHeight,0.0);
734   aPrim->AddVertex (theX,theY+theHeight,0.0);
735   aPrim->AddVertex (theX,theY,0.0);
736   Handle(Prs3d_LineAspect) anAspect = 
737     new Prs3d_LineAspect (theColor, Aspect_TOL_SOLID, 1.0);
738   anAspect->SetColor (theColor);
739   aGroup->SetPrimitivesAspect (anAspect->Aspect());
740   aGroup->AddPrimitiveArray (aPrim);
741 }
742
743 //=======================================================================
744 //function : drawText
745 //purpose  :
746 //=======================================================================
747 void AIS_ColorScale::drawText (const Handle(Prs3d_Presentation)& thePresentation,
748                   const TCollection_ExtendedString& theText,
749                   const Standard_Integer theX, const Standard_Integer theY,
750                   const Quantity_Color& theColor)
751 {
752   if (!myDrawer->HasOwnTextAspect())
753   {
754     myDrawer->SetTextAspect (new Prs3d_TextAspect());
755     *myDrawer->TextAspect()->Aspect() = *myDrawer->Link()->TextAspect()->Aspect();
756   }
757   Handle(Prs3d_TextAspect) anAspect = myDrawer->TextAspect();
758   anAspect->SetColor (theColor);
759   anAspect->SetHeight (myTextHeight);
760   anAspect->SetHorizontalJustification (Graphic3d_HTA_LEFT);
761   anAspect->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
762   anAspect->Aspect()->SetTextZoomable (Standard_True);
763   anAspect->Aspect()->SetTextAngle (0.0);
764   anAspect->Aspect()->SetTextFontAspect (Font_FA_Regular);
765   Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePresentation), anAspect, theText, gp_Ax2 (gp_Pnt (theX, theY, 0.0), gp::DZ()), Standard_False);
766 }
767
768 //=======================================================================
769 //function : TextWidth
770 //purpose  :
771 //=======================================================================
772 Standard_Integer AIS_ColorScale::TextWidth (const TCollection_ExtendedString& theText) const
773 {
774   Standard_Integer aWidth, anAscent, aDescent;
775   TextSize (theText, GetTextHeight(), aWidth, anAscent, aDescent);
776   return aWidth;
777 }
778
779 //=======================================================================
780 //function : TextHeight
781 //purpose  :
782 //=======================================================================
783 Standard_Integer AIS_ColorScale::TextHeight (const TCollection_ExtendedString& theText) const
784 {
785   Standard_Integer aWidth, anAscent, aDescent;
786   TextSize (theText, GetTextHeight(), aWidth, anAscent, aDescent);
787   return anAscent+aDescent;
788 }
789
790 //=======================================================================
791 //function : TextSize
792 //purpose  :
793 //=======================================================================
794 void AIS_ColorScale::TextSize (const TCollection_ExtendedString& theText, const Standard_Integer theHeight, Standard_Integer& theWidth, Standard_Integer& theAscent, Standard_Integer& theDescent) const
795 {
796   const Handle(Graphic3d_CView)& aView = GetContext()->CurrentViewer()->ActiveView()->View();
797   Standard_ShortReal aWidth(10.0), anAscent(1.0), aDescent(1.0);
798   TCollection_AsciiString aText (theText.ToExtString(), '?');
799   GetContext()->CurrentViewer()->Driver()->TextSize (aView, aText.ToCString(), (Standard_ShortReal)theHeight, aWidth, anAscent, aDescent);
800   theWidth = (Standard_Integer)aWidth;
801   theAscent = (Standard_Integer)anAscent;
802   theDescent = (Standard_Integer)aDescent;
803 }