1 // Copyright (C) 2005 OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : OPEN CASCADE
22 //#include <GLViewerAfx.h>
23 #include "GLViewer_BaseObjects.h"
24 #include "GLViewer_BaseDrawers.h"
25 #include "GLViewer_AspectLine.h"
26 #include "GLViewer_CoordSystem.h"
27 #include "GLViewer_Text.h"
28 #include "GLViewer_Group.h"
30 #include "GLViewer_Drawer.h"
33 //using namespace std;
38 GLViewer_MarkerSet::GLViewer_MarkerSet( int number, float size, const QString& toolTip ) :
49 myUSelNumbers.clear();
50 myCurSelNumbers.clear();
51 myPrevHNumbers.clear();
53 myType = "GLViewer_MarkerSet";
54 myToolTipText = toolTip;
56 setNumMarkers( number );
62 GLViewer_MarkerSet::~GLViewer_MarkerSet()
71 Adds coords to text buffer in HPGL format
72 \param buffer - text buffer
73 \param command - command to be added with coords
74 \param aViewerCS - viewer co-ordinates system
75 \param aPaperCS - paper co-ordinates system
76 \param x - x co-ordinate
77 \param y - y co-ordinate
78 \param NewLine - adds new line to buffer
80 void AddCoordsToHPGL( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS,
81 GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
83 if( aViewerCS && aPaperCS )
84 aViewerCS->transform( *aPaperCS, x, y );
86 QString temp = command + "%1, %2;";
87 buffer += temp.arg( x ).arg( y );
93 Adds coords to text buffer in PostScript format
94 \param buffer - text buffer
95 \param command - command to be added with coords
96 \param aViewerCS - viewer co-ordinates system
97 \param aPaperCS - paper co-ordinates system
98 \param x - x co-ordinate
99 \param y - y co-ordinate
100 \param NewLine - adds new line to buffer
102 void AddCoordsToPS( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS,
103 GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
105 if( aViewerCS && aPaperCS )
106 aViewerCS->transform( *aPaperCS, x, y );
108 QString temp = "%1 %2 "+command;
109 buffer += temp.arg( x ).arg( y );
115 Adds line aspect description to text buffer in PostScript format
116 \param buffer - text buffer
117 \param anAspect - line aspect
118 \param aViewerCS - viewer co-ordinates system
119 \param aPaperCS - paper co-ordinates system
121 void AddLineAspectToPS( QString& buffer, GLViewer_AspectLine* anAspect,
122 GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
126 QColor col1, col2, col3;
127 anAspect->getLineColors( col1, col2, col3 );
129 float aWidth = anAspect->getLineWidth();
130 int aLineType = anAspect->getLineType();
132 QString temp = "%1 %2 %3 setrgbcolor\n";
133 double rr = 1 - double( col1.red() ) / 255.0, //color inverting
134 gg = 1 - double( col1.green() ) / 255.0,
135 bb = 1 - double( col1.blue() ) / 255.0;
137 buffer += temp.arg( rr ).arg( gg ).arg( bb );
139 double x_stretch, y_stretch;
140 aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
141 buffer += temp.arg( x_stretch * aWidth )+" setlinewidth\n";
143 if( aLineType==0 ) //solid
144 buffer += "[] 0 setdash\n";
145 else if( aLineType==1 ) //strip
146 buffer += "[2] 0 setdash\n";
152 Adds line aspect description EMF image
153 \param hDC - descriptor of EMF
154 \param anAspect - line aspect
155 \param aViewerCS - viewer co-ordinates system
156 \param aPaperCS - paper co-ordinates system
158 HPEN AddLineAspectToEMF( HDC hDC, GLViewer_AspectLine* anAspect,
159 GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
163 QColor col1, col2, col3;
164 anAspect->getLineColors( col1, col2, col3 );
166 double x_stretch, y_stretch;
167 aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
169 double aWidth = anAspect->getLineWidth()*x_stretch;
170 int aLineType = anAspect->getLineType();
172 return CreatePen( PS_SOLID, aWidth, RGB( 255-col1.red(), 255-col1.green(), 255-col1.blue() ) );
180 Saves to file PostScript set of markers
181 \param hFile - file instance
182 \param aViewerCS - viewer co-ordinates system
183 \param aPSCS - paper co-ordinates system
185 bool GLViewer_MarkerSet::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
189 QString aBuffer = "newpath\n";
191 AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
193 for( int i=0; i<myNumber; i++ )
197 double x_stretch, y_stretch;
198 aViewerCS->getStretching( *aPSCS, x_stretch, y_stretch );
200 double x0 = myXCoord[i],
205 for( int j=0; j<=noPoints; j++ )
207 x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
208 y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
210 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, x, y, true );
212 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, x, y, true );
215 aBuffer+="closepath\nstroke\n";
217 hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
223 Saves to file HPGL set of markers
224 \param hFile - file instance
225 \param aViewerCS - viewer co-ordinates system
226 \param aHPGLCS - paper co-ordinates system
228 bool GLViewer_MarkerSet::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS,
229 GLViewer_CoordSystem* aHPGLCS )
233 for( int i=0; i<myNumber; i++ )
237 double x_stretch, y_stretch;
238 aViewerCS->getStretching( *aHPGLCS, x_stretch, y_stretch );
240 double x0 = myXCoord[i],
245 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, x0+r, y0 );
247 for( int j=1; j<=noPoints; j++ )
249 x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
250 y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
251 AddCoordsToHPGL( aBuffer, "PD", aViewerCS, aHPGLCS, x, y );
255 hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
263 Saves to EMF image set of markers
264 \param dc - EMF image descriptor
265 \param aViewerCS - viewer co-ordinates system
266 \param aEMFCS - paper co-ordinates system
268 bool GLViewer_MarkerSet::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
271 if( !aViewerCS || !aEMFCS )
274 HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
275 HGDIOBJ old = SelectObject( dc, pen );
277 for( int i=0; i<myNumber; i++ )
279 double x0 = myXCoord[i],
284 for( int j=0; j<=noPoints; j++ )
286 x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
287 y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
288 aViewerCS->transform( *aEMFCS, x, y );
290 MoveToEx( dc, x, y, NULL );
296 SelectObject( dc, old );
304 Computes all necessary information about object for presentation in drawer
306 void GLViewer_MarkerSet::compute()
308 // cout << "GLViewer_MarkerSet::compute" << endl;
309 GLfloat xa = myXCoord[0];
310 GLfloat xb = myXCoord[0];
311 GLfloat ya = myYCoord[0];
312 GLfloat yb = myYCoord[0];
314 for ( int i = 0; i < myNumber; i++ )
316 xa = QMIN( xa, myXCoord[i] );
317 xb = QMAX( xb, myXCoord[i] );
318 ya = QMIN( ya, myYCoord[i] );
319 yb = QMAX( yb, myYCoord[i] );
322 myXGap = ( xb - xa ) / 10;
323 myYGap = ( yb - ya ) / 10;
325 myRect->setLeft( xa - myXGap );
326 myRect->setTop( yb + myYGap );
327 myRect->setRight( xb + myXGap );
328 myRect->setBottom( ya - myYGap );
332 Creates corresponding drawer
334 GLViewer_Drawer* GLViewer_MarkerSet::createDrawer()
336 // cout << "GLViewer_MarkerSet::createDrawer" << endl;
337 return myDrawer = new GLViewer_MarkerDrawer();
341 Computes highlight presentation
344 \param tol - tolerance of detecting
345 \param isCircle - true if sensitive area of detection is round
346 \return true if highlight status is changed
348 GLboolean GLViewer_MarkerSet::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
352 // cout << "GLViewer_MarkerSet::highlight " << x <<" " << y << " " << tol << endl;
354 GLfloat xdist, ydist, radius;
355 QValueList<int>::Iterator it;
356 QValueList<int> curHNumbers;
361 radius = tol - myMarkerSize / 2.;
363 myUHNumbers += myHNumbers;
366 for ( int i = 0; i < myNumber; i++ )
368 xdist = ( myXCoord[i] - x ) * myXScale;
369 ydist = ( myYCoord[i] - y ) * myYScale;
371 // if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
372 if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
373 !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) )
377 for ( it = myCurSelNumbers.begin(); it != myCurSelNumbers.end(); ++it )
381 curHNumbers.append( i );
385 myHNumbers.append( i );
390 myCurSelNumbers = curHNumbers;
392 myIsHigh = ( GLboolean )count;
393 update = ( GLboolean )( myHNumbers != myPrevHNumbers );
395 myPrevHNumbers = myHNumbers;
397 //cout << "GLViewer_MarkerSet::highlight complete with " << (int)myIsHigh << endl;
404 GLboolean GLViewer_MarkerSet::unhighlight()
406 if( !myHNumbers.isEmpty() )
408 myUHNumbers += myHNumbers;
409 myPrevHNumbers.clear();
411 //??? myCurSelNumbers.clear();
420 /param x, y - co-ordinates of mouse
421 /param tol - tolerance
422 /param rect - rectangle (in case of rectangular selection)
423 /param isFull - if it is true, then object may selected only if it lays whole in selection zone
424 \param isCircle - true if sensitive area of detection is round
425 \param isShift - true if selection exec with append option
427 GLboolean GLViewer_MarkerSet::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
428 GLboolean isCircle, GLboolean isShift )
432 // cout << "GLViewer_MarkerSet::select " << x << " " << y << endl;
434 GLfloat xdist, ydist, radius;
435 QValueList<int>::Iterator it;
436 QValueList<int>::Iterator it1;
437 QValueList<int>::Iterator remIt;
438 QValueList<int>::Iterator curIt;
440 radius = tol - myMarkerSize / 2.;
442 if( radius < myMarkerSize / 2.)
443 radius = myMarkerSize / 2.;
445 count = isShift ? mySelNumbers.count() : 0;
447 myUSelNumbers = mySelNumbers;
451 mySelNumbers.clear();
452 myCurSelNumbers.clear();
455 for ( int i = 0; i < myNumber; i++ )
457 xdist = ( myXCoord[i] - x ) * myXScale;
458 ydist = ( myYCoord[i] - y ) * myYScale;
460 //if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
461 if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
462 !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) )
467 bool isFound = FALSE;
468 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
471 myUSelNumbers.append( *it );
479 mySelNumbers.append( i );
480 myCurSelNumbers.append( i );
481 for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
484 myHNumbers.remove( it1 );
487 for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
490 myUHNumbers.remove( it1 );
496 mySelNumbers.remove( remIt );
497 for ( curIt = myCurSelNumbers.begin(); curIt != myCurSelNumbers.end(); ++curIt )
498 if( *curIt == *remIt)
500 myCurSelNumbers.remove( curIt );
503 for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
506 myHNumbers.remove( it1 );
509 for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
512 myUHNumbers.remove( it1 );
519 mySelNumbers.append( i );
520 myCurSelNumbers.append( i );
521 for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
524 myHNumbers.remove( it1 );
527 for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
530 myUHNumbers.remove( it1 );
537 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
538 for( it1 = myUSelNumbers.begin(); it1 != myUSelNumbers.end(); ++it1 )
541 it1 = myUSelNumbers.remove( it1 );
545 myIsSel = (GLboolean)count;
547 // cout << "GLViewer_MarkerSet::select complete with " << (int)myIsSel << endl;
554 GLboolean GLViewer_MarkerSet::unselect()
556 if( !mySelNumbers.isEmpty() )
558 myUSelNumbers = mySelNumbers;
559 mySelNumbers.clear();
560 myCurSelNumbers.clear();
568 \return update object rectangle
569 Does not equal getRect() if object have a persistence to some viewer transformations
571 GLViewer_Rect* GLViewer_MarkerSet::getUpdateRect()
573 GLViewer_Rect* rect = new GLViewer_Rect();
575 rect->setLeft( myRect->left() + myXGap - myMarkerSize / myXScale );
576 rect->setTop( myRect->top() + myYGap + myMarkerSize / myYScale );
577 rect->setRight( myRect->right() - myXGap + myMarkerSize / myXScale );
578 rect->setBottom( myRect->bottom() - myYGap - myMarkerSize / myYScale );
579 //cout << " Additional tolerance " << myMarkerSize / myYScale << endl;
580 //rect->setLeft( myRect->left() - myMarkerSize / myXScale );
581 //rect->setTop( myRect->top() - myMarkerSize / myYScale );
582 //rect->setRight( myRect->right() + myMarkerSize / myXScale );
583 //rect->setBottom( myRect->bottom() + myMarkerSize / myYScale );
589 Sets array of x coords of points
590 \param xCoord - array of co-ordinates
591 \param size - array size
593 void GLViewer_MarkerSet::setXCoord( GLfloat* xCoord, int size )
595 myXCoord = new GLfloat[ size ];
596 for( int i = 0; i < size; i++ )
597 myXCoord[i] = xCoord[i];
601 Sets array of y coords of points
602 \param yCoord - array of co-ordinates
603 \param size - array size
605 void GLViewer_MarkerSet::setYCoord( GLfloat* yCoord, int size )
607 myYCoord = new GLfloat[ size ];
608 for( int i = 0; i < size; i++ )
609 myYCoord[i] = yCoord[i];
613 Sets number of markers
614 \param number - new number of markers
616 void GLViewer_MarkerSet::setNumMarkers( GLint number )
618 if ( myNumber == number )
621 if ( myXCoord && myYCoord )
628 myXCoord = new GLfloat[ myNumber ];
629 myYCoord = new GLfloat[ myNumber ];
634 Export numbers of highlighted/selected lines
636 void GLViewer_MarkerSet::exportNumbers( QValueList<int>& highlight,
637 QValueList<int>& unhighlight,
638 QValueList<int>& select,
639 QValueList<int>& unselect )
641 highlight = myHNumbers;
642 unhighlight = myUHNumbers;
643 select = mySelNumbers;
644 unselect = myUSelNumbers;
646 myUHNumbers = myHNumbers;
650 Adds or remove selected number
651 \param index - selected index
653 bool GLViewer_MarkerSet::addOrRemoveSelected( int index )
655 if( index < 0 || index > myNumber )
658 int n = mySelNumbers.findIndex( index );
660 mySelNumbers.append( index );
663 QValueList<int>::Iterator it;
664 it = mySelNumbers.at( n );
665 mySelNumbers.remove( it );
666 myUSelNumbers.append( index );
672 Adds some selected numbers
673 \param seq - sequence of indices
675 void GLViewer_MarkerSet::addSelected( const TColStd_SequenceOfInteger& seq )
677 for ( int i = 1; i <= seq.Length(); i++ )
678 if( mySelNumbers.findIndex( seq.Value( i ) ) == -1 )
679 mySelNumbers.append( seq.Value( i ) - 1 );
683 Sets some numbers as selected
684 \param seq - sequence of indices
686 void GLViewer_MarkerSet::setSelected( const TColStd_SequenceOfInteger& seq )
688 // for( QValueList<int>::Iterator it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
689 // if( myUSelNumbers.findIndex( *it ) == -1 )
690 // myUSelNumbers.append( *it );
692 myUSelNumbers = mySelNumbers;
693 mySelNumbers.clear();
695 for ( int i = 1; i <= seq.Length(); i++ )
696 mySelNumbers.append( seq.Value( i ) - 1 );
699 /*! Moves object by recomputing
700 \param dx - moving along X coord
701 \param dy - moving along Y coord
702 \param fromGroup - is true if this method called from group
704 void GLViewer_MarkerSet::moveObject( float theX, float theY, bool fromGroup )
706 if( !fromGroup && myGroup)
708 myGroup->dragingObjects( theX, theY );
711 for( int i = 0; i < myNumber; i++ )
713 myXCoord[i] = myXCoord[i] + theX;
714 myYCoord[i] = myYCoord[i] + theY;
720 Codes marker set as byte copy
723 QByteArray GLViewer_MarkerSet::getByteCopy()
726 int anISize = sizeof( GLint );
727 int aFSize = sizeof( GLfloat );
729 QByteArray aObject = GLViewer_Object::getByteCopy();
731 QByteArray aResult( anISize + 2*aFSize*myNumber + aFSize + aObject.size());
733 char* aPointer = (char*)&myNumber;
734 for( i = 0; i < anISize; i++, aPointer++ )
735 aResult[i] = *aPointer;
737 aPointer = (char*)myXCoord;
738 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
739 aResult[i] = *aPointer;
740 aPointer = (char*)myYCoord;
741 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
742 aResult[i] = *aPointer;
744 aPointer = (char*)&myMarkerSize;
745 for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
746 aResult[i] = *aPointer;
749 for ( ; i < (int)aResult.size(); i++ )
750 aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - aFSize];
756 Initialize marker set by byte array
757 \param theArray - byte array
759 bool GLViewer_MarkerSet::initializeFromByteCopy( QByteArray theArray )
762 int anISize = sizeof( GLint );
763 int aFSize = sizeof( GLfloat );
765 char* aPointer = (char*)&myNumber;
766 for( i = 0; i < anISize; i++, aPointer++ )
767 *aPointer = theArray[i];
769 int aSize = theArray.size();
770 if( aSize < anISize + 2*aFSize*myNumber + aFSize)
773 myXCoord = new GLfloat[myNumber];
774 myYCoord = new GLfloat[myNumber];
775 aPointer = (char*)myXCoord;
776 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
777 *aPointer = theArray[i];
778 aPointer = (char*)myYCoord;
779 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
780 *aPointer = theArray[i];
782 aPointer = (char*)&myMarkerSize;
783 for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
784 *aPointer = theArray[i];
786 int aCurIndex = anISize + 2*aFSize*myNumber + aFSize;
787 QByteArray aObject( aSize - aCurIndex );
788 for( ; i < aSize; i++ )
789 aObject[i - aCurIndex] = theArray[i];
792 if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_MarkerSet" )
797 mySelNumbers.clear();
798 myUSelNumbers.clear();
799 myCurSelNumbers.clear();
800 myPrevHNumbers.clear();
806 \class GLViewer_Polyline
815 \param number - number of segments
816 \param size - size of polyline
817 \param toolTip - tool tip of polyline
819 GLViewer_Polyline::GLViewer_Polyline( int number, float size, const QString& toolTip ):
825 myHighFlag = GL_TRUE;
829 mySelNumbers.clear();
830 myUSelNumbers.clear();
831 myCurSelNumbers.clear();
832 myPrevHNumbers.clear();
836 myType = "GLViewer_Polyline";
837 myToolTipText = toolTip;
841 Destructor, destroys internal arrays of co-ordinates
843 GLViewer_Polyline::~GLViewer_Polyline()
852 Saves polyline to file PostScript
853 \param hFile - file instance
854 \param aViewerCS - viewer co-ordinates system
855 \param aPSCS - paper co-ordinates system
857 bool GLViewer_Polyline::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
859 QString aBuffer = "newpath\n";
861 AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
863 for( int i=0; i<myNumber; i++ )
865 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
867 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
870 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[0], myYCoord[0] );
872 aBuffer+="closepath\nstroke\n";
874 hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
880 Saves polyline to file HPGL
881 \param hFile - file instance
882 \param aViewerCS - viewer co-ordinates system
883 \param aHPGLCS - paper co-ordinates system
885 bool GLViewer_Polyline::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
887 QString aBuffer = "";
888 for( int i=0; i<myNumber; i++ )
890 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[i], myYCoord[i] );
896 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[0], myYCoord[0] );
900 hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
907 Saves polyline to EMF image
908 \param dc - EMF image descriptor
909 \param aViewerCS - viewer co-ordinates system
910 \param aEMFCS - paper co-ordinates system
912 bool GLViewer_Polyline::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
914 if( !aViewerCS || !aEMFCS )
917 HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
918 HGDIOBJ old = SelectObject( dc, pen );
921 for( int i=0; i<myNumber; i++ )
925 aViewerCS->transform( *aEMFCS, x, y );
927 MoveToEx( dc, x, y, NULL );
936 aViewerCS->transform( *aEMFCS, x, y );
940 SelectObject( dc, old );
949 Computes all necessary information about object for presentation in drawer
951 void GLViewer_Polyline::compute()
953 // cout << "GLViewer_MarkerSet::compute" << endl;
954 GLfloat xa = myXCoord[0];
955 GLfloat xb = myXCoord[0];
956 GLfloat ya = myYCoord[0];
957 GLfloat yb = myYCoord[0];
959 for ( int i = 0; i < myNumber; i++ )
961 xa = QMIN( xa, myXCoord[i] );
962 xb = QMAX( xb, myXCoord[i] );
963 ya = QMIN( ya, myYCoord[i] );
964 yb = QMAX( yb, myYCoord[i] );
967 GLfloat xGap = ( xb - xa ) / 10;
968 GLfloat yGap = ( yb - ya ) / 10;
970 myRect->setLeft( xa - xGap );
971 myRect->setTop( yb + yGap );
972 myRect->setRight( xb + xGap );
973 myRect->setBottom( ya - yGap );
977 \return update object rectangle
978 Does not equal getRect() if object have a persistence to some viewer transformations
980 GLViewer_Rect* GLViewer_Polyline::getUpdateRect()
982 GLViewer_Rect* rect = new GLViewer_Rect();
984 rect->setLeft( myRect->left() - myXGap );
985 rect->setTop( myRect->top() + myYGap );
986 rect->setRight( myRect->right() + myXGap );
987 rect->setBottom( myRect->bottom() - myYGap );
993 Creates corresponding drawer
995 GLViewer_Drawer* GLViewer_Polyline::createDrawer()
997 // cout << "GLViewer_MarkerSet::createDrawer" << endl;
998 return myDrawer = new GLViewer_PolylineDrawer();
1002 Computes highlight presentation
1005 \param tol - tolerance of detecting
1006 \param isCircle - true if sensitive area of detection is round
1007 \return true if highlight status is changed
1009 GLboolean GLViewer_Polyline::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
1013 GLfloat xa, xb, ya, yb, l;
1014 GLfloat rsin, rcos, r, ra, rb;
1016 GLboolean highlighted = myIsHigh;
1018 myIsHigh = GL_FALSE;
1024 for( int i = 0; i < myNumber-1+c; i++ )
1028 if( i != myNumber-1 )
1039 l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
1042 r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
1043 ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
1044 rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
1045 if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
1052 if( !myHighFlag && myIsHigh )
1053 myIsHigh = GL_FALSE;
1055 myHighFlag = GL_TRUE;
1057 update = ( GLboolean )( myIsHigh != highlighted );
1059 // cout << "GLViewer_Polyline::highlight complete with " << (int)myIsHigh << endl;
1066 GLboolean GLViewer_Polyline::unhighlight()
1068 // if( !myHNumbers.isEmpty() )
1070 // myUHNumbers = myHNumbers;
1071 // myHNumbers.clear();
1077 myIsHigh = GL_FALSE;
1086 /param x, y - co-ordinates of mouse
1087 /param tol - tolerance
1088 /param rect - rectangle (in case of rectangular selection)
1089 /param isFull - if it is true, then object may selected only if it lays whole in selection zone
1090 \param isCircle - true if sensitive area of detection is round
1091 \param isShift - true if selection exec with append option
1093 GLboolean GLViewer_Polyline::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
1094 GLboolean isCircle, GLboolean isShift )
1098 GLfloat xa, xb, ya, yb, l;
1099 GLfloat rsin, rcos, r, ra, rb;
1101 GLboolean selected = myIsSel;
1109 for( int i = 0; i < myNumber-1+c; i++ )
1113 if( i != myNumber-1 )
1124 l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
1127 r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
1128 ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
1129 rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
1130 if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
1139 myHighFlag = GL_FALSE;
1140 myIsHigh = GL_FALSE;
1143 myHighFlag = GL_TRUE;
1145 update = ( GLboolean )( myIsSel != selected );
1147 // cout << "GLViewer_Polyline::select complete with " << (int)myIsSel << endl;
1149 // return update; !!!!!!!!!!!!!!!!!!!!!!!!!!! no here
1156 GLboolean GLViewer_Polyline::unselect()
1158 // if( !mySelNumbers.isEmpty() )
1160 // myUSelNumbers = mySelNumbers;
1161 // mySelNumbers.clear();
1162 // myCurSelNumbers.clear();
1176 Sets array of abscisses for points of polyline
1177 \param xCoord - array of of abscisses
1178 \param size - size of array
1180 void GLViewer_Polyline::setXCoord( GLfloat* xCoord, int size )
1182 myXCoord = new GLfloat[ size ];
1183 for( int i = 0; i < size; i++ )
1184 myXCoord[i] = xCoord[i];
1188 Sets array of ordinates for points of polyline
1189 \param xCoord - array of of ordinates
1190 \param size - size of array
1192 void GLViewer_Polyline::setYCoord( GLfloat* yCoord, int size )
1194 myYCoord = new GLfloat[ size ];
1195 for( int i = 0; i < size; i++ )
1196 myYCoord[i] = yCoord[i];
1200 Sets number of points
1201 \param number - new number of points
1203 void GLViewer_Polyline::setNumber( GLint number )
1205 if ( myNumber == number )
1208 if ( myXCoord && myYCoord )
1215 myXCoord = new GLfloat[ myNumber ];
1216 myYCoord = new GLfloat[ myNumber ];
1220 Export numbers of highlighted/selected lines
1222 void GLViewer_Polyline::exportNumbers( QValueList<int>& highlight,
1223 QValueList<int>& unhighlight,
1224 QValueList<int>& select,
1225 QValueList<int>& unselect )
1227 highlight = myHNumbers;
1228 unhighlight = myUHNumbers;
1229 select = mySelNumbers;
1230 unselect = myUSelNumbers;
1234 Moves object by recomputing
1235 \param dx - moving along X coord
1236 \param dy - moving along Y coord
1237 \param fromGroup - is true if this method called from group
1239 void GLViewer_Polyline::moveObject( float theX, float theY, bool fromGroup )
1241 if( !fromGroup && myGroup)
1243 myGroup->dragingObjects( theX, theY );
1246 for( int i = 0; i < myNumber; i++ )
1248 myXCoord[i] = myXCoord[i] + theX;
1249 myYCoord[i] = myYCoord[i] + theY;
1255 Codes polyline as byte copy
1258 QByteArray GLViewer_Polyline::getByteCopy()
1261 int anISize = sizeof( GLint );
1262 int aFSize = sizeof( GLfloat );
1263 int aBSize = sizeof( GLboolean );
1265 QByteArray aObject = GLViewer_Object::getByteCopy();
1267 QByteArray aResult( aFSize*myNumber*2 + anISize + 2*aBSize + aObject.size());
1269 char* aPointer = (char*)&myNumber;
1270 for( i = 0; i < anISize; i++, aPointer++ )
1271 aResult[i] = *aPointer;
1273 aPointer = (char*)myXCoord;
1274 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1275 aResult[i] = *aPointer;
1276 aPointer = (char*)myYCoord;
1277 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1278 aResult[i] = *aPointer;
1280 aPointer = (char*)&myIsClosed;
1281 for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1282 aResult[i] = *aPointer;
1283 aPointer = (char*)&myHighSelAll;
1284 for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1285 aResult[i] = *aPointer;
1287 for ( ; i < (int)aResult.size(); i++ )
1288 aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - 2*aBSize];
1295 Initialize polyline by byte array
1296 \param theArray - byte array
1298 bool GLViewer_Polyline::initializeFromByteCopy( QByteArray theArray )
1301 int anISize = sizeof( GLint );
1302 int aFSize = sizeof( GLfloat );
1303 int aBSize = sizeof( GLboolean );
1305 char* aPointer = (char*)&myNumber;
1306 for( i = 0; i < anISize; i++, aPointer++ )
1307 *aPointer = theArray[i];
1309 int aSize = theArray.size();
1310 if( aSize < aFSize*myNumber*2 + anISize + 2*aBSize )
1313 myXCoord = new GLfloat[myNumber];
1314 myYCoord = new GLfloat[myNumber];
1315 aPointer = (char*)myXCoord;
1316 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1317 *aPointer = theArray[i];
1318 aPointer = (char*)myYCoord;
1319 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1320 *aPointer = theArray[i];
1322 aPointer = (char*)&myIsClosed;
1323 for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1324 *aPointer = theArray[i];
1325 aPointer = (char*)&myHighSelAll;
1326 for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1327 *aPointer = theArray[i];
1329 int aCurIndex = anISize + 2*aFSize*myNumber + 2*aBSize;
1330 QByteArray aObject( aSize - aCurIndex );
1331 for( ; i < aSize; i++ )
1332 aObject[i - aCurIndex] = theArray[i];
1334 if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_Polyline" )
1338 myUHNumbers.clear();
1339 mySelNumbers.clear();
1340 myUSelNumbers.clear();
1341 myCurSelNumbers.clear();
1342 myPrevHNumbers.clear();
1351 \param theStr - text string
1352 \param xPos - x position
1353 \param yPos - y position
1354 \param color - color of text
1355 \param toolTip - tooltip of text object
1357 GLViewer_TextObject::GLViewer_TextObject( const QString& theStr, float xPos, float yPos,
1358 const QColor& color, const QString& toolTip )
1361 myGLText = new GLViewer_Text( theStr, xPos, yPos, color );
1365 myHighFlag = GL_TRUE;
1367 myToolTipText = toolTip;
1373 GLViewer_TextObject::~GLViewer_TextObject()
1380 Saves text object to file PostScript
1381 \param hFile - file instance
1382 \param aViewerCS - viewer co-ordinates system
1383 \param aPSCS - paper co-ordinates system
1385 bool GLViewer_TextObject::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
1387 QString aText = myGLText->getText();
1389 myGLText->getPosition( xPos, yPos );
1391 QString aBuffer = "/Times-Roman findfont\n";
1392 aBuffer += "12 scalefont setfont\n";
1394 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, double(xPos), double(yPos) );
1395 aBuffer += "(" + aText + ") show\n";
1397 hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1403 Saves text object to file HPGL
1404 \param hFile - file instance
1405 \param aViewerCS - viewer co-ordinates system
1406 \param aHPGLCS - paper co-ordinates system
1408 bool GLViewer_TextObject::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
1410 QString aText = myGLText->getText();
1412 myGLText->getPosition( xPos, yPos );
1414 QString aBuffer = "";
1415 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, double(xPos), double(yPos) );
1417 aBuffer = "LB" + aText + "#;";
1419 hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1426 Saves text object to EMF image
1427 \param dc - EMF image descriptor
1428 \param aViewerCS - viewer co-ordinates system
1429 \param aEMFCS - paper co-ordinates system
1431 bool GLViewer_TextObject::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
1433 QString aText = myGLText->getText();
1435 myGLText->getPosition( xPos, yPos );
1437 double x = double( xPos ),
1440 aViewerCS->transform( *aEMFCS, x, y );
1441 const char* str = aText.ascii();
1443 int nHeight = 35*14; // height of font
1444 int nWidth = 35*12; // average character width
1445 int nEscapement = 0; // angle of escapement
1446 int nOrientation = 0; // base-line orientation angle
1447 int fnWeight = FW_NORMAL; // font weight
1448 DWORD fdwItalic = FALSE; // italic attribute option
1449 DWORD fdwUnderline = FALSE; // underline attribute option
1450 DWORD fdwStrikeOut = FALSE; // strikeout attribute option
1451 DWORD fdwCharSet = ANSI_CHARSET; // character set identifier
1452 DWORD fdwOutputPrecision = OUT_DEFAULT_PRECIS; // output precision
1453 DWORD fdwClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
1454 DWORD fdwQuality = PROOF_QUALITY; // output quality
1455 DWORD fdwPitchAndFamily = FIXED_PITCH | FF_DONTCARE; // pitch and family
1456 LPCTSTR lpszFace = NULL; // typeface name
1459 HFONT aFont = CreateFont( nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic,
1460 fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision,
1461 fdwClipPrecision, fdwQuality, fdwPitchAndFamily, lpszFace );
1462 LOGBRUSH aBrushData;
1463 aBrushData.lbStyle = BS_HOLLOW;
1465 HBRUSH aBrush = CreateBrushIndirect( &aBrushData );
1467 HGDIOBJ old1 = SelectObject( dc, aFont );
1468 HGDIOBJ old2 = SelectObject( dc, aBrush );
1470 TextOut( dc, x, y, str, aText.length() );
1472 SelectObject ( dc, old1 );
1473 SelectObject ( dc, old2 );
1475 DeleteObject( aFont );
1482 Creates corresponding drawer
1484 GLViewer_Drawer* GLViewer_TextObject::createDrawer()
1486 myDrawer = new GLViewer_TextDrawer();
1492 Computes all necessary information about object for presentation in drawer
1494 void GLViewer_TextObject::compute()
1497 QString aStr = myGLText->getText();
1498 myGLText->getPosition( xPos, yPos );
1500 myWidth = myGLText->getWidth();
1501 myHeight = myGLText->getHeight();
1502 myRect->setLeft( xPos );
1503 myRect->setTop( yPos + myHeight );
1504 myRect->setRight( xPos + myWidth );
1505 myRect->setBottom( yPos );
1509 Installing already exist drawer with same type
1510 \param theDrawer - new drawer
1512 void GLViewer_TextObject::setDrawer( GLViewer_Drawer* theDrawer )
1514 myDrawer = theDrawer;
1519 \return update object rectangle
1520 Does not equal getRect() if object have a persistence to some viewer transformations
1522 GLViewer_Rect* GLViewer_TextObject::getUpdateRect()
1524 GLViewer_Rect* rect = new GLViewer_Rect();
1527 QString aStr = myGLText->getText();
1528 myGLText->getPosition( xPos, yPos );
1530 rect->setLeft( myRect->left() + myXGap - myWidth / myXScale );
1531 rect->setTop( myRect->top() + myYGap + myHeight / myYScale );
1532 rect->setRight( myRect->right() - myXGap + myWidth / myXScale );
1533 rect->setBottom( myRect->bottom() - myYGap - myHeight / myYScale );
1539 Computes highlight presentation
1542 \param tol - tolerance of detecting
1543 \param isCircle - true if sensitive area of detection is round
1544 \return true if highlight status is changed
1546 GLboolean GLViewer_TextObject::highlight( GLfloat theX, GLfloat theY, GLfloat theTol, GLboolean isCircle )
1552 myGLText->getPosition( xPos, yPos );
1555 aRect.setLeft( (int)xPos );
1556 aRect.setRight( (int)(xPos + myWidth / myXScale) );
1557 aRect.setTop( (int)yPos );// - myHeight / myYScale );
1558 aRect.setBottom( (int)(yPos + myHeight / myYScale) );
1560 //cout << "theX: " << theX << " theY: " << theY << endl;
1561 //cout << "aRect.left(): " << aRect.left() << " aRect.right(): " << aRect.right() << endl;
1562 //cout << "aRect.top(): " << aRect.top() << " aRect.bottom(): " << aRect.bottom() << endl;
1564 QRegion obj( aRect );
1565 QRegion intersection;
1568 region.setLeft( (int)(theX - theTol) );
1569 region.setRight( (int)(theX + theTol) );
1570 region.setTop( (int)(theY - theTol) );
1571 region.setBottom( (int)(theY + theTol) );
1573 QRegion circle( (int)(theX - theTol), (int)(theY - theTol),
1574 (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1576 intersection = obj.intersect( circle );
1578 intersection = obj.intersect( region );
1580 if( intersection.isEmpty() )
1585 if( !myHighFlag && myIsHigh )
1586 myIsHigh = GL_FALSE;
1588 myHighFlag = GL_TRUE;
1596 GLboolean GLViewer_TextObject::unhighlight()
1600 myIsHigh = GL_FALSE;
1609 /param x, y - co-ordinates of mouse
1610 /param tol - tolerance
1611 /param rect - rectangle (in case of rectangular selection)
1612 /param isFull - if it is true, then object may selected only if it lays whole in selection zone
1613 \param isCircle - true if sensitive area of detection is round
1614 \param isShift - true if selection exec with append option
1616 GLboolean GLViewer_TextObject::select( GLfloat theX, GLfloat theY, GLfloat theTol, GLViewer_Rect rect,
1617 GLboolean isFull, GLboolean isCircle, GLboolean isShift )
1622 QRegion obj( myRect->toQRect() );
1623 QRegion intersection;
1626 region.setLeft( (int)(theX - theTol) );
1627 region.setRight( (int)(theX + theTol) );
1628 region.setTop( (int)(theY - theTol) );
1629 region.setBottom( (int)(theY + theTol) );
1631 QRegion circle( (int)(theX - theTol), (int)(theY - theTol),
1632 (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1634 intersection = obj.intersect( circle );
1636 intersection = obj.intersect( region );
1638 if( intersection.isEmpty() )
1645 myHighFlag = GL_FALSE;
1646 myIsHigh = GL_FALSE;
1649 myHighFlag = GL_TRUE;
1655 Unselects text object
1657 GLboolean GLViewer_TextObject::unselect()
1669 Moves object by recomputing
1670 \param dx - moving along X coord
1671 \param dy - moving along Y coord
1672 \param fromGroup - is true if this method called from group
1674 void GLViewer_TextObject::moveObject( float theX, float theY, bool fromGroup )
1676 if( !fromGroup && myGroup)
1678 myGroup->dragingObjects( theX, theY );
1682 myGLText->getPosition( aX, anY );
1685 myGLText->setPosition( aX, anY );
1690 Codes text object as byte copy
1693 QByteArray GLViewer_TextObject::getByteCopy()
1695 QByteArray aObject = GLViewer_Object::getByteCopy();
1701 Initialize text object by byte array
1702 \param theArray - byte array
1704 bool GLViewer_TextObject::initializeFromByteCopy( QByteArray theArray )
1706 if( !GLViewer_Object::initializeFromByteCopy( theArray ) || myType != "GLViewer_TextObject" )