diff --git a/samples/qt/Common/src/OcctWindow.cxx b/samples/qt/Common/src/OcctWindow.cxx new file mode 100644 index 0000000000..c9bc3cad44 --- /dev/null +++ b/samples/qt/Common/src/OcctWindow.cxx @@ -0,0 +1,168 @@ +#include + +// ======================================================================= +// function : OcctWindow +// purpose : +// ======================================================================= +OcctWindow::OcctWindow ( QWidget* theWidget, const Quantity_NameOfColor theBackColor ) +: Aspect_Window(), + myWidget( theWidget ) +{ + SetBackground (theBackColor); + myXLeft = myWidget->rect().left(); + myYTop = myWidget->rect().top(); + myXRight = myWidget->rect().right(); + myYBottom = myWidget->rect().bottom(); +} + +// ======================================================================= +// function : Destroy +// purpose : +// ======================================================================= +void OcctWindow::Destroy() +{ + myWidget = NULL; +} + +// ======================================================================= +// function : NativeParentHandle +// purpose : +// ======================================================================= +Aspect_Drawable OcctWindow::NativeParentHandle() const +{ + QWidget* aParentWidget = myWidget->parentWidget(); + if ( aParentWidget != NULL ) + return (Aspect_Drawable)aParentWidget->winId(); + else + return 0; +} + +// ======================================================================= +// function : NativeHandle +// purpose : +// ======================================================================= +Aspect_Drawable OcctWindow::NativeHandle() const +{ + return (Aspect_Drawable)myWidget->winId(); +} + +// ======================================================================= +// function : IsMapped +// purpose : +// ======================================================================= +Standard_Boolean OcctWindow::IsMapped() const +{ + return !( myWidget->isMinimized() || myWidget->isHidden() ); +} + +// ======================================================================= +// function : Map +// purpose : +// ======================================================================= +void OcctWindow::Map() const +{ + myWidget->show(); + myWidget->update(); +} + +// ======================================================================= +// function : Unmap +// purpose : +// ======================================================================= +void OcctWindow::Unmap() const +{ + myWidget->hide(); + myWidget->update(); +} + +// ======================================================================= +// function : DoResize +// purpose : +// ======================================================================= +Aspect_TypeOfResize OcctWindow::DoResize() const +{ + int aMask = 0; + Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN; + + if ( !myWidget->isMinimized() ) + { + if ( Abs ( myWidget->rect().left() - myXLeft ) > 2 ) aMask |= 1; + if ( Abs ( myWidget->rect().right() - myXRight ) > 2 ) aMask |= 2; + if ( Abs ( myWidget->rect().top() - myYTop ) > 2 ) aMask |= 4; + if ( Abs ( myWidget->rect().bottom() - myYBottom ) > 2 ) aMask |= 8; + + switch ( aMask ) + { + case 0: + aMode = Aspect_TOR_NO_BORDER; + break; + case 1: + aMode = Aspect_TOR_LEFT_BORDER; + break; + case 2: + aMode = Aspect_TOR_RIGHT_BORDER; + break; + case 4: + aMode = Aspect_TOR_TOP_BORDER; + break; + case 5: + aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; + break; + case 6: + aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; + break; + case 8: + aMode = Aspect_TOR_BOTTOM_BORDER; + break; + case 9: + aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; + break; + case 10: + aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; + break; + default: + break; + } // end switch + + *( ( Standard_Integer* )&myXLeft ) = myWidget->rect().left(); + *( ( Standard_Integer* )&myXRight ) = myWidget->rect().right(); + *( ( Standard_Integer* )&myYTop ) = myWidget->rect().top(); + *( ( Standard_Integer* )&myYBottom) = myWidget->rect().bottom(); + } + + return aMode; +} + +// ======================================================================= +// function : Ratio +// purpose : +// ======================================================================= +Quantity_Ratio OcctWindow::Ratio() const +{ + QRect aRect = myWidget->rect(); + return Quantity_Ratio( aRect.right() - aRect.left() ) / Quantity_Ratio( aRect.bottom() - aRect.top() ); +} + +// ======================================================================= +// function : Size +// purpose : +// ======================================================================= +void OcctWindow::Size ( Standard_Integer& theWidth, Standard_Integer& theHeight ) const +{ + QRect aRect = myWidget->rect(); + theWidth = aRect.right(); + theHeight = aRect.bottom(); +} + +// ======================================================================= +// function : Position +// purpose : +// ======================================================================= +void OcctWindow::Position ( Standard_Integer& theX1, Standard_Integer& theY1, + Standard_Integer& theX2, Standard_Integer& theY2 ) const +{ + theX1 = myWidget->rect().left(); + theX2 = myWidget->rect().right(); + theY1 = myWidget->rect().top(); + theY2 = myWidget->rect().bottom(); +} \ No newline at end of file diff --git a/samples/qt/Common/src/OcctWindow.h b/samples/qt/Common/src/OcctWindow.h new file mode 100644 index 0000000000..80c9668ee8 --- /dev/null +++ b/samples/qt/Common/src/OcctWindow.h @@ -0,0 +1,89 @@ +#ifndef OcctWindow_H +#define OcctWindow_H + +#include + +#include +class OcctWindow; + +/* + OcctWindow class implements Aspect_Window interface using Qt API + as a platform-independent source of window geometry information. + A similar class should be used instead of platform-specific OCCT + classes (WNT_Window, Xw_Window) in any Qt 5 application using OCCT + 3D visualization. + + With Qt 5, the requirement for a Qt-based application to rely fully + on Qt public API and stop using platform-specific APIs looks mandatory. + An example of this is changed QWidget event sequence: when a widget is + first shown on the screen, a resize event is generated before the + underlying native window is resized correctly, however the QWidget instance + already holds correct size information at that moment. The OCCT classes + acting as a source of window geometry for V3d_View class (WNT_Window, Xw_Window) + are no longer compatible with changed Qt behavior because they rely on + platform-specific API that cannot return correct window geometry information + in some cases. A reasonable solution is to provide a Qt-based implementation + of Aspect_Window interface at application level. +*/ + +class OcctWindow : public Aspect_Window +{ +public: + + //! Constructor + OcctWindow( QWidget* theWidget, const Quantity_NameOfColor theBackColor = Quantity_NOC_MATRAGRAY ); + + virtual void Destroy(); + + //! Destructor + ~OcctWindow() + { + Destroy(); + } + + //! Returns native Window handle + virtual Aspect_Drawable NativeHandle() const; + + //! Returns parent of native Window handle. + virtual Aspect_Drawable NativeParentHandle() const; + + //! Applies the resizing to the window + virtual Aspect_TypeOfResize DoResize() const; + + //! Returns True if the window is opened + //! and False if the window is closed. + virtual Standard_Boolean IsMapped() const; + + //! Apply the mapping change to the window + //! and returns TRUE if the window is mapped at screen. + virtual Standard_Boolean DoMapping() const { return Standard_True; } + + //! Opens the window . + virtual void Map() const; + + //! Closes the window . + virtual void Unmap() const; + + virtual void Position( Standard_Integer& theX1, Standard_Integer& theY1, + Standard_Integer& theX2, Standard_Integer& theY2 ) const; + + //! Returns The Window RATIO equal to the physical + //! WIDTH/HEIGHT dimensions. + virtual Quantity_Ratio Ratio() const; + + virtual void Size( Standard_Integer& theWidth, Standard_Integer& theHeight ) const; + + virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return NULL; } + + DEFINE_STANDARD_RTTI( OcctWindow, Aspect_Window ) + +protected: + Standard_Integer myXLeft; + Standard_Integer myYTop; + Standard_Integer myXRight; + Standard_Integer myYBottom; + QWidget* myWidget; +}; + + +#endif // OcctWindow_H \ No newline at end of file diff --git a/samples/qt/Common/src/View.cxx b/samples/qt/Common/src/View.cxx index 7014ad8d84..ae4df1d9b8 100755 --- a/samples/qt/Common/src/View.cxx +++ b/samples/qt/Common/src/View.cxx @@ -20,21 +20,8 @@ #include #include #include - -#if defined(_WIN32) || defined(__WIN32__) -#include -#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) -#include -#else -#include -#include -#include -#include -#include -#include -#include -#endif +#include #include // the key for multi selection : @@ -63,12 +50,6 @@ View::View( Handle(AIS_InteractiveContext) theContext, QWidget* parent ) myRaytraceActions( 0 ), myBackMenu( NULL ) { -#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) - //XSynchronize( x11Display(),true ); // it is possible to use QApplication::syncX(); - XSynchronize( x11Info().display(),true ); // it is possible to use QApplication::syncX(); -#endif - - myFirst = true; myContext = theContext; myXmin = 0; @@ -81,77 +62,6 @@ View::View( Handle(AIS_InteractiveContext) theContext, QWidget* parent ) setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); -#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) - XVisualInfo* pVisualInfo; - if ( x11Info().display() ) - { - /* Initialization with the default VisualID */ - Visual *v = DefaultVisual( x11Info().display(), DefaultScreen( x11Info().display() ) ); - int visualID = XVisualIDFromVisual( v ); - - /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */ - int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; - pVisualInfo = ::glXChooseVisual( x11Info().display(), DefaultScreen( x11Info().display() ), visualAttr ); - - if ( isVisible() ) - hide(); - - XSetWindowAttributes a; - - Window p = RootWindow( x11Info().display(), DefaultScreen( x11Info().display() ) ); - a.colormap = XCreateColormap( x11Info().display(), RootWindow( x11Info().display(), pVisualInfo->screen ), - pVisualInfo->visual, AllocNone ); - - QColor color = palette().color( backgroundRole() ); - QColormap colmap = QColormap::instance(); - a.background_pixel = colmap.pixel( color ); - a.border_pixel = colmap.pixel( Qt::black ); - if ( parentWidget() ) - p = parentWidget()->winId(); - - Window w = XCreateWindow( x11Info().display(), p, x(), y(), width(), height(), - 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual, - CWBackPixel | CWBorderPixel | CWColormap, &a ); - Window *cmw; - Window *cmwret; - int count; - if ( XGetWMColormapWindows( x11Info().display(), topLevelWidget()->winId(), &cmwret, &count ) ) - { - cmw = new Window[count+1]; - memcpy( (char *)cmw, (char *)cmwret, sizeof(Window)*count ); - XFree( (char *)cmwret ); - int i; - for ( i = 0; i < count; i++ ) - { - if ( cmw[i] == winId() ) /* replace old window */ - { - cmw[i] = w; - break; - } - } - if ( i >= count ) /* append new window */ - cmw[count++] = w; - } - else - { - count = 1; - cmw = new Window[count]; - cmw[0] = w; - } - /* Creating new window (with good VisualID) for this widget */ - create(w); - XSetWMColormapWindows( x11Info().display(), topLevelWidget()->winId(), cmw, count ); - delete [] cmw; - - if ( isVisible() ) - show(); - if ( pVisualInfo ) - XFree( (char *)pVisualInfo ); - XFlush( x11Info().display() ); - } -#endif - myCurrentMode = CurAction3d_Nothing; myHlrModeIsOn = Standard_False; setMouseTracking( true ); @@ -164,7 +74,7 @@ View::View( Handle(AIS_InteractiveContext) theContext, QWidget* parent ) setFocusPolicy( Qt::StrongFocus ); setAttribute( Qt::WA_PaintOnScreen ); setAttribute( Qt::WA_NoSystemBackground ); - + init(); } View::~View() @@ -176,19 +86,8 @@ void View::init() { if ( myView.IsNull() ) myView = myContext->CurrentViewer()->CreateView(); - -#if defined(_WIN32) || defined(__WIN32__) - Aspect_Handle aWindowHandle = (Aspect_Handle )winId(); - Handle(WNT_Window) hWnd = new WNT_Window (aWindowHandle); -#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) - NSView* aViewHandle = (NSView* )winId(); - Handle(Cocoa_Window) hWnd = new Cocoa_Window (aViewHandle); -#else - Window aWindowHandle = (Window )winId(); - Handle(Aspect_DisplayConnection) aDispConnection = myContext->CurrentViewer()->Driver()->GetDisplayConnection(); - Handle(Xw_Window) hWnd = new Xw_Window (aDispConnection, aWindowHandle); -#endif // _WIN32 + Handle(OcctWindow) hWnd = new OcctWindow ( this ); myView->SetWindow (hWnd); if ( !hWnd->IsMapped() ) { @@ -204,11 +103,6 @@ void View::init() void View::paintEvent( QPaintEvent * ) { // QApplication::syncX(); - if( myFirst ) - { - init(); - myFirst = false; - } myView->Redraw(); } diff --git a/samples/qt/Common/src/View.h b/samples/qt/Common/src/View.h index 796b2ac02c..3d49755c6c 100755 --- a/samples/qt/Common/src/View.h +++ b/samples/qt/Common/src/View.h @@ -17,8 +17,8 @@ class View: public QWidget Q_OBJECT protected: enum CurrentAction3d { CurAction3d_Nothing, CurAction3d_DynamicZooming, - CurAction3d_WindowZooming, CurAction3d_DynamicPanning, - CurAction3d_GlobalPanning, CurAction3d_DynamicRotation }; + CurAction3d_WindowZooming, CurAction3d_DynamicPanning, + CurAction3d_GlobalPanning, CurAction3d_DynamicRotation }; public: enum ViewAction { ViewFitAllId, ViewFitAreaId, ViewZoomId, ViewPanId, ViewGlobalPanId, @@ -54,14 +54,14 @@ public: static QString GetShapeType( TopAbs_ShapeEnum aShapeType ); Standard_EXPORT static void OnButtonuseraction( int ExerciceSTEP, - Handle(AIS_InteractiveContext)& ); + Handle(AIS_InteractiveContext)& ); Standard_EXPORT static void DoSelection( int Id, Handle(AIS_InteractiveContext)& ); Standard_EXPORT static void OnSetSelectionMode( Handle(AIS_InteractiveContext)&, Standard_Integer&, - TopAbs_ShapeEnum& SelectionMode, - Standard_Boolean& ); - virtual QPaintEngine* paintEngine() const; + TopAbs_ShapeEnum& SelectionMode, + Standard_Boolean& ); + virtual QPaintEngine* paintEngine() const; signals: void selectionChanged(); @@ -129,8 +129,7 @@ private: bool myIsReflectionsEnabled; bool myIsAntialiasingEnabled; - bool myFirst; - bool myDrawRect; // set when a rect is used for selection or magnify + bool myDrawRect; // set when a rect is used for selection or magnify Handle(V3d_View) myView; Handle(AIS_InteractiveContext) myContext; CurrentAction3d myCurrentMode; diff --git a/samples/qt/IESample/env.bat b/samples/qt/IESample/env.bat index 6d50198a83..70f36037f9 100755 --- a/samples/qt/IESample/env.bat +++ b/samples/qt/IESample/env.bat @@ -9,3 +9,4 @@ set "CSF_ResourcesDefaults=%RES_DIR%" set "CSF_IEResourcesDefaults=%RES_DIR%" set "PATH=%QT_DIR%/bin;%PATH%" +set "QT_QPA_PLATFORM_PLUGIN_PATH=%QT_DIR%\plugins\platforms" \ No newline at end of file diff --git a/samples/qt/Interface/src/Application.h b/samples/qt/Interface/src/Application.h index e9ee23b350..952135da67 100755 --- a/samples/qt/Interface/src/Application.h +++ b/samples/qt/Interface/src/Application.h @@ -14,7 +14,7 @@ public: enum { FileImportBREPId=0, FileExportBREPId=1, FileImportIGESId=2, FileExportIGESId=3, FileImportSTEPId=4, FileExportSTEPId=5, - FileExportSTLId=6, FileExportVRMLId=7 }; + FileExportSTLId=6, FileExportVRMLId=7, FileUserId }; ApplicationWindow(); ~ApplicationWindow(); diff --git a/samples/qt/Tutorial/env.bat b/samples/qt/Tutorial/env.bat index 8ac246656c..1516692cd2 100755 --- a/samples/qt/Tutorial/env.bat +++ b/samples/qt/Tutorial/env.bat @@ -9,3 +9,4 @@ set "CSF_ResourcesDefaults=%RES_DIR%" set "CSF_TutorialResourcesDefaults=%RES_DIR%" set "PATH=%QT_DIR%/bin;%PATH%" +set "QT_QPA_PLATFORM_PLUGIN_PATH=%QT_DIR%\plugins\platforms" \ No newline at end of file