____
+.. image:: ../../../../src/OCCViewer/resources/occ_view_rect_style.png
+ :align: center
+
+**Advanced selection by polygon** - enables advanced selection by polygon.
+
+____
+
+.. image:: ../../../../src/OCCViewer/resources/occ_view_circle_style.png
+ :align: center
+
+**Advanced selection by polygon** - enables advanced selection by circle.
+
+____
+
.. image:: ../../../../src/OCCViewer/resources/occ_view_fitall.png
:align: center
- **Enable preselection** - switches preselection on/off.
- **Enable selection** - switches selection on/off.
+ - **Advanced selection** - switches default advanced selection style by Polygon or by Circle.
- **Clipping parameters** - specifies the default clipping plane parameters.
resMgr->doubleValue( "OCCViewer", "focus_value", vm->stereographicFocusValue() ));
vm->setInterocularDistance( resMgr->integerValue( "OCCViewer", "iod_type", vm->interocularDistanceType() ),
resMgr->doubleValue( "OCCViewer", "iod_value", vm->interocularDistanceValue() ));
+ vm->setSelectionStyle( resMgr->integerValue( "OCCViewer", "adv_selection_mode", vm->selectionStyle() ) );
vm->setReverseStereo( resMgr->booleanValue( "OCCViewer", "reverse_stereo", vm->isReverseStereo() ) );
vm->setVSync( resMgr->booleanValue( "OCCViewer", "enable_vsync", vm->isVSync() ) );
// ... "Selection" group <<start>>
int occSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), occGroup );
- pref->setItemProperty( "columns", 2, occSelectionGroup );
+ pref->setItemProperty( "columns", 3, occSelectionGroup );
// .... -> enable preselection
pref->addPreference( tr( "PREF_ENABLE_PRESELECTION" ), occSelectionGroup,
LightApp_Preferences::Bool, "OCCViewer", "enable_preselection" );
// .... -> enable selection
pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), occSelectionGroup,
LightApp_Preferences::Bool, "OCCViewer", "enable_selection" );
+ // .... -> selection style
+ int aSeleStyle = pref->addPreference( tr( "PREF_SELECTION_STYLE" ), occSelectionGroup,
+ LightApp_Preferences::Selector, "OCCViewer", "adv_selection_mode" );
+ aValuesList.clear();
+ anIndicesList.clear();
+ aValuesList << tr("PREF_POLYGON_SELECTION") << tr("PREF_CIRCLE_SELECTION");
+ anIndicesList << 0 << 1;
+ pref->setItemProperty( "strings", aValuesList, aSeleStyle);
+ pref->setItemProperty( "indexes", anIndicesList, aSeleStyle);
// ... "Selection" group <<end>>
// ... "Clipping" group <<start>>
}
#endif
+
+#ifndef DISABLE_OCCVIEWER
+ if (sec == QString("OCCViewer") && param == QString("adv_selection_mode"))
+ {
+ int mode = resMgr->integerValue("OCCViewer", "adv_selection_mode", 0);
+ QList<SUIT_ViewManager*> lst;
+ viewManagers(OCCViewer_Viewer::Type(), lst);
+ QListIterator<SUIT_ViewManager*> it(lst);
+ while (it.hasNext())
+ {
+ SUIT_ViewModel* vm = it.next()->getViewModel();
+ if (!vm || !vm->inherits("OCCViewer_Viewer"))
+ continue;
+
+ OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
+ occVM->setSelectionStyle(mode);
+ }
+ }
+#endif
+
+
#ifndef DISABLE_OCCVIEWER
if ( sec == QString( "OCCViewer" ) && param == QString( "stereo_type" ) )
{
<!-- OCC viewer preferences -->
<parameter name="projection_mode" value="0"/>
<parameter name="stereo_type" value="0"/>
+ <parameter name="adv_selection_mode" value="0"/>
<parameter name="anaglyph_filter" value="0"/>
<parameter name="focus_type" value="1"/>
<parameter name="focus_value" value="1.0"/>
<source>PREF_PERSPECTIVE</source>
<translation>Perspective</translation>
</message>
+ <message>
+ <source>PREF_POLYGON_SELECTION</source>
+ <translation>Polygon</translation>
+ </message>
+ <message>
+ <source>PREF_CIRCLE_SELECTION</source>
+ <translation>Circle</translation>
+ </message>
+ <message>
+ <source>PREF_SELECTION_STYLE</source>
+ <translation>Advanced selection</translation>
+ </message>
<message>
<source>PREF_NAVIGATION</source>
<translation>Navigation style</translation>
<source>PREF_PERSPECTIVE</source>
<translation>Perspective</translation>
</message>
+ <message>
+ <source>PREF_POLYGON_SELECTION</source>
+ <translation>Polygon</translation>
+ </message>
+ <message>
+ <source>PREF_CIRCLE_SELECTION</source>
+ <translation>Circle</translation>
+ </message>
+ <message>
+ <source>PREF_SELECTION_STYLE</source>
+ <translation>Advanced selection</translation>
+ </message>
<message>
<source>PREF_NAVIGATION</source>
<translation>Navigation:</translation>
<source>PREF_PERSPECTIVE</source>
<translation>遠近法</translation>
</message>
+ <message>
+ <source>PREF_POLYGON_SELECTION</source>
+ <translation>Polygon</translation>
+ </message>
+ <message>
+ <source>PREF_CIRCLE_SELECTION</source>
+ <translation>Circle</translation>
+ </message>
+ <message>
+ <source>PREF_SELECTION_STYLE</source>
+ <translation>Advanced selection</translation>
+ </message>
<message>
<source>PREF_NAVIGATION</source>
<translation>ナビゲーション スタイル</translation>
resources/occ_view_ray_tracing.png
resources/occ_view_env_texture.png
resources/occ_view_light_source.png
+ resources/occ_view_circle_style.png
+ resources/occ_view_rect_style.png
)
# --- sources ---
}
}
+//**************************************************************************************
+int OCCViewer_ViewFrame::selectionStyle() const
+{
+ return getView(MAIN_VIEW)->selectionStyle();
+}
+
+//**************************************************************************************
+void OCCViewer_ViewFrame::setSelectionStyle(int t)
+{
+ foreach(OCCViewer_ViewWindow* aView, myViews) {
+ aView->setSelectionStyle(t);
+ }
+}
+
//**************************************************************************************
int OCCViewer_ViewFrame::stereoType() const
{
virtual int projectionType() const;
virtual void setProjectionType( int );
+ virtual int selectionStyle() const;
+ virtual void setSelectionStyle(int);
+
virtual int stereoType() const;
virtual void setStereoType( const int );
// set projection type to orthographic
myProjectionType = 0;
+ mySelectionStyle = 0;
// set stereo parameters
myStereoType = 0;
myAnaglyphFilter = 0;
view->initSketchers();
view->setInteractionStyle( interactionStyle() );
view->setProjectionType( projectionType() );
+ view->setSelectionStyle( selectionStyle() );
view->setStereoType( stereoType() );
view->setAnaglyphFilter( anaglyphFilter() );
view->setStereographicFocus( stereographicFocusType(), stereographicFocusValue() );
}
}
+
+int OCCViewer_Viewer::selectionStyle() const
+{
+ return mySelectionStyle;
+}
+
+void OCCViewer_Viewer::setSelectionStyle(const int theMode)
+{
+ if (mySelectionStyle != theMode) {
+ mySelectionStyle = theMode;
+ if (!myViewManager)
+ return;
+
+ QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
+ for (int i = 0; i < (int)wins.count(); i++)
+ {
+ OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>(wins.at(i));
+ if (win)
+ win->setSelectionStyle(theMode);
+ }
+ }
+}
+
+
+
/*!
\return stereo type
*/
int stereoType() const;
void setStereoType( const int );
+ int selectionStyle() const;
+ void setSelectionStyle(const int);
+
int anaglyphFilter() const;
void setAnaglyphFilter( const int );
int myAnaglyphFilter;
int myStereographicFocusType;
int myInterocularDistanceType;
+ int mySelectionStyle;
double myStereographicFocusValue;
double myInterocularDistanceValue;
myToler ( 5, 5 ),
//mypPoints ( 0L ),
myAddButton ( 0 ),
- myDelButton ( 0 )
+ myDelButton ( 0 ),
+ myMode ( Poligone )
{
mySketchButton = Qt::RightButton;
if ( vw )
- {
- OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
- mypPolyRB = new QtxPolyRubberBand( avp );
- }
+ {
+ OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
+ mypPolyRB = new QtxPolyRubberBand( avp );
+ mypCircleRB = new QtxCircleRubberBand( avp );
+ }
+ mypData = new QPolygon( 0 );
}
OCCViewer_PolygonSketcher::~OCCViewer_PolygonSketcher()
void OCCViewer_PolygonSketcher::onActivate()
{
myDbl = false;
- mypData = new QPolygon( 0 );
//mypPoints = new QPolygon( 0 );
switch ( sketchButton() )
void OCCViewer_PolygonSketcher::onDeactivate()
{
- //delete mypPoints;
- //mypPoints = 0;
- delete (QPolygon*)mypData;
- mypData = 0;
-
if ( mypPolyRB )
mypPolyRB->clearGeometry();
+ if (mypCircleRB)
+ mypCircleRB->clearGeometry();
+ ((QPolygon*)mypData)->clear();
}
bool OCCViewer_PolygonSketcher::onKey( QKeyEvent* e )
void OCCViewer_PolygonSketcher::onSketch( SketchState state )
{
- //OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
-
QPolygon* points = (QPolygon*)data();
- /*QPainter p( avp );
- p.setPen( Qt::white );
- p.setCompositionMode( QPainter::CompositionMode_Xor );
- if ( state != Debut )
- p.drawPolyline( *mypPoints );
-
- if ( points->count() )
- {
- mypPoints->resize( points->count() + 1 );
- for ( uint i = 0; i < points->count(); i++ )
- mypPoints->setPoint( i, points->point( i ) );
- mypPoints->setPoint( points->count(), myCurr );
- if ( state != Fin )
- p.drawPolyline( *mypPoints );
- }*/
- if ( mypPolyRB ) {
- if ( state == Fin ) {
- mypPolyRB->clearGeometry();
- mypPolyRB->hide();
- mypViewWindow->activateSketching( OCCViewer_ViewWindow::NoSketching );
- } else {
- mypPolyRB->setUpdatesEnabled ( false );
- if ( !mypPolyRB->isVisible() )
- mypPolyRB->show();
- //if ( state != Debut )
- // mypPolyRB->repaint();
-
- if ( state != Fin && points->count() )
- mypPolyRB->initGeometry( QPolygon(*points) << myCurr );
- //mypPolyRB->addNode( myCurr );
-
- //if ( state != Fin )
- // mypPolyRB->repaint();
- mypPolyRB->setUpdatesEnabled ( true );
- //mypPolyRB->repaint();
+ switch (myMode) {
+ case Poligone:
+ if (mypPolyRB) {
+ if (state == Fin) {
+ mypPolyRB->clearGeometry();
+ mypPolyRB->hide();
+ mypViewWindow->activateSketching(OCCViewer_ViewWindow::NoSketching);
+ }
+ else {
+ mypPolyRB->setUpdatesEnabled(false);
+ if (!mypPolyRB->isVisible())
+ mypPolyRB->show();
+
+ if (state != Fin && points->count())
+ mypPolyRB->initGeometry(QPolygon(*points) << myCurr);
+ mypPolyRB->setUpdatesEnabled(true);
+ }
}
+ break;
+ case Circle:
+ if (mypCircleRB) {
+ if (state == Fin) {
+ mypCircleRB->getPoligon(points);
+ mypCircleRB->clearGeometry();
+ mypCircleRB->hide();
+ if (points->size() == CIRCLE_NB_POINTS)
+ myResult = Accept;
+ mypViewWindow->activateSketching(OCCViewer_ViewWindow::NoSketching);
+ }
+ else {
+ mypCircleRB->setUpdatesEnabled(false);
+
+ if (state != Fin) {
+ if (mypCircleRB->isCenterDefined()) {
+ mypCircleRB->setRadius(myCurr);
+ if ((mypCircleRB->radius() > MIN_RADIUS) && (!mypCircleRB->isVisible()))
+ mypCircleRB->show();
+ }
+ else {
+ mypCircleRB->initGeometry(myCurr);
+ }
+ }
+ mypCircleRB->setUpdatesEnabled(true);
+ }
+ }
+ break;
}
}
}
+void OCCViewer_PolygonSketcher::setSketcherMode(int theMode)
+{
+ myMode = (SketchMode)theMode;
+}
class QtxRectRubberBand;
class QtxPolyRubberBand;
+class QtxCircleRubberBand;
#ifdef WIN32
#pragma warning ( disable:4251 )
virtual bool isDefault() const;
virtual bool eventFilter( QObject*, QEvent* );
+ virtual void setSketcherMode(int theMode) {}
+ virtual int sketcherMode() const { return 0; }
+
private slots:
void onDrawViewPort();
class OCCVIEWER_EXPORT OCCViewer_PolygonSketcher : public OCCViewer_ViewSketcher
{
public:
+ enum SketchMode { Poligone, Circle };
+
OCCViewer_PolygonSketcher( OCCViewer_ViewWindow*, int );
virtual ~OCCViewer_PolygonSketcher();
+ virtual void setSketcherMode(int theMode);
+ virtual int sketcherMode() const {
+ return myMode;
+ }
+
protected:
virtual bool onKey( QKeyEvent* );
virtual void onMouse( QMouseEvent* );
int myDelButton;
QtxPolyRubberBand* mypPolyRB;
+ QtxCircleRubberBand* mypCircleRB;
+
+ SketchMode myMode;
};
#ifdef WIN32
emit keyPressed(this, (QKeyEvent*) e);
return true;
+ case QEvent::KeyRelease:
+ emit keyReleased(this, (QKeyEvent*) e);
+ return true;
+
default:
break;
}
connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchZoomingStyle(bool)));
toolMgr()->registerAction( aAction, SwitchZoomingStyleId );
+ // Switch advanced selection style (poligone/circle)
+ aAction = new QtxAction(tr("MNU_RECTANGLE_SELECTION_STYLE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_RECT_STYLE" ) ),
+ tr( "MNU_RECTANGLE_SELECTION_STYLE" ), 0, this);
+ aAction->setStatusTip(tr("DSC_RECTANGLE_SELECTION_STYLE"));
+ aAction->setCheckable(true);
+ toolMgr()->registerAction( aAction, RectangleSelectionStyleId);
+
+ aAction = new QtxAction(tr("MNU_CIRCLE_SELECTION_STYLE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CIRCLE_STYLE" ) ),
+ tr( "MNU_CIRCLE_SELECTION_STYLE" ), 0, this);
+ aAction->setStatusTip(tr("DSC_CIRCLE_SELECTION_STYLE"));
+ aAction->setCheckable(true);
+ toolMgr()->registerAction( aAction, CircleSelectionStyleId);
+
+ // - add exclusive action group
+ QActionGroup* aSelectionGroup = new QActionGroup(this);
+ aSelectionGroup->addAction(toolMgr()->action(RectangleSelectionStyleId));
+ aSelectionGroup->addAction(toolMgr()->action(CircleSelectionStyleId));
+ connect(aSelectionGroup, SIGNAL(triggered(QAction*)), this, SLOT(onSwitchSelectionStyle(QAction*)));
+
// Maximized view
aAction = new QtxAction(tr("MNU_MINIMIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ),
tr( "MNU_MINIMIZE_VIEW" ), 0, this );
toolMgr()->append( SwitchZoomingStyleId, tid );
toolMgr()->append( SwitchPreselectionId, tid );
toolMgr()->append( SwitchSelectionId, tid );
+ toolMgr()->append(RectangleSelectionStyleId, tid );
+ toolMgr()->append(CircleSelectionStyleId, tid );
if( myModel->trihedronActivated() )
toolMgr()->append( TrihedronShowId, tid );
}
}
+/*!
+ \brief Switches style of advanced multiple selection by Poligon/Circle
+*/
+void OCCViewer_ViewWindow::onSwitchSelectionStyle(QAction* theAction)
+{
+ // selection
+ OCCViewer_ViewSketcher* aSkecher = getSketcher(Polygon);
+ if (aSkecher) {
+ if (theAction == toolMgr()->action(RectangleSelectionStyleId)) {
+ aSkecher->setSketcherMode(OCCViewer_PolygonSketcher::Poligone);
+ }
+ else if (theAction == toolMgr()->action(CircleSelectionStyleId)) {
+ aSkecher->setSketcherMode(OCCViewer_PolygonSketcher::Circle);
+ }
+ }
+}
+
+int OCCViewer_ViewWindow::selectionStyle() const
+{
+ OCCViewer_ViewSketcher* aSkecher = getSketcher(Polygon);
+ if (aSkecher) {
+ return aSkecher->sketcherMode();
+ }
+ return 0;
+}
+
+void OCCViewer_ViewWindow::setSelectionStyle(int theMode)
+{
+ OCCViewer_ViewSketcher* aSkecher = getSketcher(Polygon);
+ if (aSkecher) {
+ aSkecher->setSketcherMode(theMode);
+ if (theMode == 0) {
+ toolMgr()->action(RectangleSelectionStyleId)->setChecked(true);
+ toolMgr()->action(CircleSelectionStyleId)->setChecked(false);
+ }
+ else {
+ toolMgr()->action(RectangleSelectionStyleId)->setChecked(false);
+ toolMgr()->action(CircleSelectionStyleId)->setChecked(true);
+ }
+ }
+}
+
/*!
\brief Switches "keyboard free" interaction style on/off
*/
}
}
-OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ )
+OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ ) const
{
OCCViewer_ViewSketcher* sketcher = 0;
- QList<OCCViewer_ViewSketcher*>::Iterator it;
- for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
+ QList<OCCViewer_ViewSketcher*>::ConstIterator it;
+ for ( it = mySketchers.cbegin(); it != mySketchers.cend() && !sketcher; ++it )
{
OCCViewer_ViewSketcher* sk = (*it);
if ( sk->type() == typ )
SwitchPreselectionId, SwitchSelectionId,
MaximizedId, SynchronizeId, ReturnTo3dViewId,
OrthographicId, PerspectiveId, StereoId, RayTracingId, EnvTextureId, LightSourceId,
+ RectangleSelectionStyleId, CircleSelectionStyleId,
UserId };
enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE,
virtual void setVisualParameters( const QString& parameters );
virtual void initSketchers();
- virtual OCCViewer_ViewSketcher* getSketcher( const int );
+ virtual OCCViewer_ViewSketcher* getSketcher( const int ) const;
virtual void activateSketching( int );
virtual int projectionType() const;
virtual void setProjectionType( int );
+ virtual int selectionStyle() const;
+ virtual void setSelectionStyle(int);
+
virtual int stereoType() const;
virtual void setStereoType( const int );
virtual void onSwitchZoomingStyle( bool on );
virtual void onSwitchPreselection( bool on );
virtual void onSwitchSelection( bool on );
+ virtual void onSwitchSelectionStyle(QAction* theAction);
virtual void onRayTracing();
virtual void onEnvTexture();
virtual void onLightSource();
<source>ICON_OCCVIEWER_ZOOMING_STYLE_SWITCH</source>
<translation>occ_view_zooming_style_switch.png</translation>
</message>
+ <message>
+ <source>ICON_OCCVIEWER_RECT_STYLE</source>
+ <translation>occ_view_rect_style.png</translation>
+ </message>
+ <message>
+ <source>ICON_OCCVIEWER_CIRCLE_STYLE</source>
+ <translation>occ_view_circle_style.png</translation>
+ </message>
<message>
<source>ICON_OCCVIEWER_MAXIMIZE</source>
<translation>occ_view_maximized.png</translation>
<source>DSC_ZOOMING_STYLE_SWITCH</source>
<translation>Zooming style switch</translation>
</message>
+ <message>
+ <source>MNU_RECTANGLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by polygon</translation>
+ </message>
+ <message>
+ <source>DSC_RECTANGLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by polygon</translation>
+ </message>
+ <message>
+ <source>MNU_CIRCLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by circle</translation>
+ </message>
+ <message>
+ <source>DSC_CIRCLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by circle</translation>
+ </message>
<message>
<source>MNU_ENABLE_PRESELECTION</source>
<translation>Enable/disable preselection</translation>
<source>DSC_ZOOMING_STYLE_SWITCH</source>
<translation>Changer le style de zoom</translation>
</message>
+ <message>
+ <source>MNU_RECTANGLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by polygon</translation>
+ </message>
+ <message>
+ <source>DSC_RECTANGLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by polygon</translation>
+ </message>
+ <message>
+ <source>MNU_CIRCLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by circle</translation>
+ </message>
+ <message>
+ <source>DSC_CIRCLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by circle</translation>
+ </message>
<message>
<source>MNU_ENABLE_PRESELECTION</source>
<translation>Activer/Désactiver préselection</translation>
<source>DSC_ZOOMING_STYLE_SWITCH</source>
<translation>ズームのスタイルを変更します。</translation>
</message>
+ <message>
+ <source>MNU_RECTANGLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by polygon</translation>
+ </message>
+ <message>
+ <source>DSC_RECTANGLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by polygon</translation>
+ </message>
+ <message>
+ <source>MNU_CIRCLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by circle</translation>
+ </message>
+ <message>
+ <source>DSC_CIRCLE_SELECTION_STYLE</source>
+ <translation>Advanced selection by circle</translation>
+ </message>
<message>
<source>MNU_ENABLE_PRESELECTION</source>
<translation>予選の有効/無効にします。</translation>
#include <QShowEvent>
#include <QVectorIterator>
+#include <math.h>
+
/*!
\class QtxAbstractRubberBand
\brief Analog of class QRubberBand with possibility of creation non-rectangular contour for selection.
QPainter aPainter( this );
aPainter.setRenderHint( QPainter::Antialiasing );
QRect r = myPoints.boundingRect();
- aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) );
+ //aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) );
aPainter.drawTiledPixmap( 0, 0, width(), height(), tiledPixmap);
aPainter.end();
updateMask();
}
}
+
+QtxCircleRubberBand::QtxCircleRubberBand(QWidget* parent)
+ :QtxAbstractRubberBand(parent), myHasCenter(false)
+{
+ myPoints.resize(2);
+ myIsClosed = true;
+}
+
+QtxCircleRubberBand::~QtxCircleRubberBand()
+{
+}
+
+void QtxCircleRubberBand::initGeometry(const QPoint& thePoint)
+{
+ myIsClosed = false;
+ myHasCenter = true;
+ myPoints.clear();
+ myPoints << thePoint;
+ updateMask();
+}
+
+void QtxCircleRubberBand::setRadius(const QPoint& thePoint)
+{
+ if (myPoints.size() == 1)
+ myPoints << thePoint;
+ else
+ myPoints.setPoint(1, thePoint);
+ myIsClosed = true;
+ updateMask();
+}
+
+void QtxCircleRubberBand::updateMask()
+{
+ int aLen = radius();
+ if (aLen > MIN_RADIUS) {
+ QRegion aReg1(myPoints[0].x() - aLen,
+ myPoints[0].y() - aLen, aLen * 2, aLen * 2, QRegion::Ellipse);
+ QRegion aReg2(myPoints[0].x() - aLen + 2,
+ myPoints[0].y() - aLen + 2, aLen * 2 - 4, aLen * 2 - 4, QRegion::Ellipse);
+ setMask(aReg1 - aReg2);
+ }
+}
+
+bool QtxCircleRubberBand::isCenterDefined() const
+{
+ return myHasCenter;
+}
+
+void QtxCircleRubberBand::clearGeometry()
+{
+ QtxAbstractRubberBand::clearGeometry();
+ myHasCenter = false;
+ myIsClosed = false;
+}
+
+QPoint rotatePoint(const QPoint& theStart, const QPoint& theCenter, double theAngle)
+{
+ double cosTheta = cos(theAngle);
+ double sinTheta = sin(theAngle);
+ int aX = (int)(cosTheta * (theStart.x() - theCenter.x()) -
+ sinTheta * (theStart.y() - theCenter.y()) + theCenter.x());
+ int aY = (int)(sinTheta * (theStart.x() - theCenter.x()) +
+ cosTheta * (theStart.y() - theCenter.y()) + theCenter.y());
+ return QPoint(aX, aY);
+}
+
+static double m_pi = 4 * atan(1);
+static double angle_deg = 360. / CIRCLE_NB_POINTS;
+static double angle_rad = angle_deg * (m_pi / 180.);
+
+
+void QtxCircleRubberBand::getPoligon(QPolygon* thePoints) const
+{
+ int aLen = radius();
+ if (aLen > MIN_RADIUS) {
+ thePoints->clear();
+ QPoint aCenter = myPoints[0];
+ QPoint aStart = myPoints[1];
+ for (int i = 0; i < CIRCLE_NB_POINTS; i++) {
+ thePoints->append(aStart);
+ aStart = rotatePoint(aStart, aCenter, angle_rad);
+ }
+ }
+}
+
+int QtxCircleRubberBand::radius() const
+{
+ if (myPoints.size() < 2)
+ return -1;
+ QPoint aDist = myPoints[1] - myPoints[0];
+ return (int)std::sqrt(std::pow(aDist.x(), 2) + std::pow(aDist.y(), 2));
+}
\ No newline at end of file
void setClosed( bool );
};
+
+#define CIRCLE_NB_POINTS 30
+#define MIN_RADIUS 5
+
+class QTX_EXPORT QtxCircleRubberBand : public QtxAbstractRubberBand
+{
+ Q_OBJECT
+
+public:
+ QtxCircleRubberBand(QWidget*);
+ virtual ~QtxCircleRubberBand();
+
+ void initGeometry(const QPoint&);
+
+ void setRadius(const QPoint&);
+
+ bool isCenterDefined() const;
+
+ virtual void clearGeometry();
+
+ void getPoligon(QPolygon* thePoints) const;
+
+ int radius() const;
+
+protected:
+ virtual void updateMask();
+ bool myHasCenter;
+};
+
#endif //QTXRUBBERBAND_H