You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegraphics/kpovmodeler/pmglview.cpp

1854 lines
51 KiB

/*
**************************************************************************
description
--------------------
copyright : (C) 2000-2003 by Andreas Zehender
email : zehender@kde.org
**************************************************************************
**************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
**************************************************************************/
#include "pmglview.h"
#include "pmpart.h"
#include "pmrendermanager.h"
#include "pmcamera.h"
#include "pmscene.h"
#include "pmdatachangecommand.h"
#include "pmdebug.h"
#include "pmdefaults.h"
#include <math.h>
#include <tqpopupmenu.h>
#include <tqpainter.h>
#include <tqapplication.h>
#include <tqcursor.h>
#include <tqcolor.h>
#include <tqglobal.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqcombobox.h>
#include <tqdom.h>
#include <kxmlguifactory.h>
#include <kaction.h>
#include <kconfig.h>
#include <kstaticdeleter.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kdialog.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/Xmu/StdCmap.h>
const double c_sizeFactor = log( 2.0 ) / 100.0;
const int c_mouseChangeDelayPixel = 3;
const int c_mouseChangeDelayMs = 300;
const int c_multipleSelectDelayPixel = 3;
const double c_defaultAutoScrollSpeed = 200; // pixels per second
const int c_minAutoScrollUpdateTime = 30; //ms
const double keyMoveSpeed = 40.0;
const double keyScaleFactor = 1.4;
static int glxAttributeList[] = { GLX_LEVEL, 0,
GLX_DOUBLEBUFFER,
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
//GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
None };
class PMGLViewStatic
{
public:
PMGLViewStatic( )
{
m_colormap = 0;
m_context = NULL;
m_colormapAllocated = false;
m_display = 0;
m_visualInfo = 0;
}
~PMGLViewStatic( )
{
if( m_colormapAllocated )
XFreeColormap( m_display, m_colormap );
if( m_context != NULL )
glXDestroyContext( m_display, m_context );
if( m_visualInfo )
XFree( m_visualInfo );
}
Colormap m_colormap;
GLXContext m_context;
bool m_colormapAllocated;
Display* m_display;
XVisualInfo* m_visualInfo;
};
static PMGLViewStatic* s_pSharedData = 0;
static KStaticDeleter<PMGLViewStatic> s_staticDeleter;
bool PMGLView::s_bDirect = true;
PMGLView::PMGLView( PMPart* part, PMViewType t,
TQWidget* parent, const char* name, WFlags f )
: PMViewBase( parent, name, f | TQt::WWinOwnDC | TQt::WRepaintNoErase )
{
m_pPart = part;
m_type = t;
m_bScaleMode = false;
m_scaleIntX = 0.0;
m_scaleIntY = 0.0;
m_bTranslateMode = false;
m_bGraphicalChangeMode = false;
m_bMousePressed = false;
m_bMidMousePressed = false;
m_dTransX = 0.0;
m_dTransY = 0.0;
m_dScale = 30.0;
m_bInverseValid = false;
m_pActiveObject = part->activeObject( );
m_bMementoCreated = false;
m_bSelectUnderMouse = false;
m_bDeselectUnderMouse = false;
m_bMultipleSelectionMode = false;
m_bSelectionStarted = false;
m_bAutoScroll = false;
m_autoScrollSpeed = c_defaultAutoScrollSpeed;
m_bAboutToUpdate = false;
m_projectionUpToDate = false;
m_contextClickPosition = PMVector( 0.0, 0.0 );
m_objectActions.setAutoDelete( true );
m_controlPointsPosition.setAutoDelete( true );
m_pUnderMouse = 0;
setCamera( m_pPart->firstCamera( ) );
initializeGL( );
setMouseTracking( true );
setFocusPolicy( TQ_WheelFocus );
PMRenderManager* rm = PMRenderManager::theManager( );
rm->viewCreated( );
setMinimumSize( 50, 50 );
connect( part, TQT_SIGNAL( refresh( ) ), TQT_SLOT( slotRefresh( ) ) );
connect( part, TQT_SIGNAL( clear( ) ), TQT_SLOT( slotClear( ) ) );
connect( this, TQT_SIGNAL( objectChanged( PMObject*, const int, TQObject* ) ),
part, TQT_SLOT( slotObjectChanged( PMObject*, const int, TQObject* ) ) );
connect( part, TQT_SIGNAL( objectChanged( PMObject*, const int, TQObject* ) ),
TQT_SLOT( slotObjectChanged( PMObject*, const int, TQObject* ) ) );
connect( part, TQT_SIGNAL( activeRenderModeChanged( ) ),
TQT_SLOT( slotActiveRenderModeChanged( ) ) );
connect( &m_startTimer, TQT_SIGNAL( timeout( ) ),
TQT_SLOT( slotMouseChangeTimer( ) ) );
connect( &m_autoScrollTimer, TQT_SIGNAL( timeout( ) ),
TQT_SLOT( slotAutoScroll( ) ) );
connect( rm, TQT_SIGNAL( renderingStarted( PMGLView* ) ),
TQT_SLOT( slotRenderingStarted( PMGLView* ) ) );
connect( rm, TQT_SIGNAL( aboutToUpdate( PMGLView* ) ),
TQT_SLOT( slotAboutToUpdate( PMGLView* ) ) );
connect( rm, TQT_SIGNAL( renderingFinished( PMGLView* ) ),
TQT_SLOT( slotRenderingFinished( PMGLView* ) ) );
connect( rm, TQT_SIGNAL( renderingSettingsChanged( ) ),
TQT_SLOT( slotRefresh( ) ) );
connect( this, TQT_SIGNAL( controlPointMessage( const TQString& ) ),
m_pPart, TQT_SIGNAL( controlPointMessage( const TQString& ) ) );
updateControlPoints( );
}
void PMGLView::initializeGL( )
{
Display* display = x11Display( );
int screen = x11Screen( );
int i;
if( !s_pSharedData )
{
s_staticDeleter.setObject( s_pSharedData, new PMGLViewStatic );
s_pSharedData->m_display = display;
if( PMRenderManager::hasOpenGL( ) )
{
// get an appropriate visual
XVisualInfo* vi = glXChooseVisual( display, screen, glxAttributeList );
s_pSharedData->m_visualInfo = vi;
if( vi )
{
kdDebug( PMArea ) << "PMGLView: XVisual found\n";
// create a color map (from qgl_x11.cpp)
// check if we can use the global colormap
// should be the default ?
if( vi->visualid ==
XVisualIDFromVisual( ( Visual* ) TQPaintDevice::x11AppVisual( ) ) )
{
kdDebug( PMArea ) << "PMGLView: Default colormap used\n";
s_pSharedData->m_colormap = TQPaintDevice::x11AppColormap();
s_pSharedData->m_colormapAllocated = false;
}
if( !s_pSharedData->m_colormap )
{
const char* v = glXQueryServerString( display, vi->screen,
GLX_VERSION );
bool mesa_gl = false;
if( v )
mesa_gl = strstr( v, "Mesa" ) != 0;
if( mesa_gl )
{
XStandardColormap* c;
int n;
Atom hp_cmaps = XInternAtom( display, "_HP_RGB_SMOOTH_MAP_LIST",
TRUE );
if( hp_cmaps && ( vi->visual->c_class == TrueColor )
&& ( vi->depth == 8 ) )
{
if( XGetRGBColormaps( display, RootWindow( display,vi->screen ),
&c, &n, hp_cmaps ) )
{
i = 0;
while( ( i < n ) && ( s_pSharedData->m_colormap == 0 ) )
{
if( c[i].visualid == vi->visual->visualid )
{
s_pSharedData->m_colormap = c[i].colormap;
kdDebug( PMArea ) << "PMGLView: HP_RGB scmap used\n";
}
i++;
}
XFree( ( char* ) c );
}
}
}
}
#if !defined(Q_OS_SOLARIS)
if( !s_pSharedData->m_colormap )
{
XStandardColormap* c;
int n;
if( XmuLookupStandardColormap( display, vi->screen, vi->visualid,
vi->depth, XA_RGB_DEFAULT_MAP,
FALSE, TRUE ) )
{
if( XGetRGBColormaps( display, RootWindow( display, vi->screen ),
&c, &n, XA_RGB_DEFAULT_MAP ) )
{
i = 0;
while( ( i < n ) && ( s_pSharedData->m_colormap == 0 ) )
{
if( c[i].visualid == vi->visualid )
{
s_pSharedData->m_colormap = c[i].colormap;
kdDebug( PMArea ) << "PMGLView: RGB_DEFAULT scmap used\n";
}
i++;
}
XFree( ( char* ) c );
}
}
}
#endif
if( !s_pSharedData->m_colormap )
{
// create a new colormap otherwise
kdDebug( PMArea ) << "PMGLView: New colormap created\n";
s_pSharedData->m_colormap =
XCreateColormap( display,
RootWindow( display, vi->screen ),
vi->visual, AllocNone );
s_pSharedData->m_colormapAllocated = true;
}
// create the context
// this context is shared between all gl views!
s_pSharedData->m_context = glXCreateContext( display, vi, 0, s_bDirect );
if( s_pSharedData->m_context != NULL )
kdDebug( PMArea ) << "PMGLView: glx context created\n";
}
}
}
if( s_pSharedData->m_context != NULL )
{
XVisualInfo* vi = s_pSharedData->m_visualInfo;
// create the window
XSetWindowAttributes swa;
swa.colormap = s_pSharedData->m_colormap;
swa.border_pixel = 0;
swa.background_pixel = 0;
Window p;
p = RootWindow( display, vi->screen );
TQWidget* pw = parentWidget( );
if( pw )
p = pw->winId( );
Window w = XCreateWindow( display, p, x( ), y( ), width( ),
height( ), 0, vi->depth, InputOutput,
vi->visual,
CWColormap | CWBorderPixel | CWBackPixel,
&swa );
// tell the windowmanager to use the colormap
Window* colorMapWindows = 0;
Window* newWindows = 0;
int num;
if( XGetWMColormapWindows( display, topLevelWidget( )->winId( ),
&colorMapWindows, &num ) )
{
// create a new list and append the new window
bool replaced = false;
newWindows = new Window[num+1];
for( i = 0; i < num; i++ )
{
newWindows[i] = colorMapWindows[i];
if( newWindows[i] == winId( ) ) // old window
{
newWindows[i] = w;
replaced = true;
}
}
if( !replaced )
{
newWindows[num] = w;
num++;
}
}
else
{
num = 1;
newWindows = new Window[1];
newWindows[0] = w;
}
// tell TQt to use this window
create( w );
XSetWMColormapWindows( display, topLevelWidget( )->winId( ),
newWindows, num );
delete[] newWindows;
XFlush( x11Display( ) );
}
else
{
TQVBoxLayout* topLayout = new TQVBoxLayout( this );
TQLabel* label = new TQLabel( i18n( "No OpenGL support" ), this );
label->setAlignment( TQt::AlignCenter );
topLayout->addWidget( label );
}
//setProjection( );
}
PMGLView::~PMGLView( )
{
PMRenderManager* rm = PMRenderManager::theManager( );
rm->removeView( this );
rm->viewDeleted( );
emit destroyed( this );
}
bool PMGLView::isValid( ) const
{
if( s_pSharedData && ( s_pSharedData->m_context != NULL ) )
return true;
return false;
}
void PMGLView::makeCurrent( )
{
if( isValid( ) )
glXMakeCurrent( x11Display( ), winId( ), s_pSharedData->m_context );
}
void PMGLView::swapBuffers( )
{
if( isValid( ) )
glXSwapBuffers( x11Display( ), winId( ) );
}
void PMGLView::setScale( double scale )
{
if( m_dScale > 0 )
{
m_dScale = scale;
invalidateProjection( );
}
else
kdError( PMArea ) << "Scale <= 0 in PMGLView::setScale\n";
}
void PMGLView::setTranslationX( double d )
{
m_dTransX = d;
invalidateProjection( );
}
void PMGLView::setTranslationY( double d )
{
m_dTransY = d;
invalidateProjection( );
}
void PMGLView::resizeEvent( TQResizeEvent* )
{
invalidateProjection( );
}
void PMGLView::paintEvent( TQPaintEvent* )
{
tqrepaint( );
}
void PMGLView::invalidateProjection( bool graphicalChange /*= true*/ )
{
m_viewTransformation = PMMatrix::identity( );
if( m_type != PMViewCamera )
{
m_viewTransformation = m_viewTransformation * PMMatrix::scale( m_dScale, m_dScale, m_dScale );
m_viewTransformation = m_viewTransformation * PMMatrix::translation( m_dTransX, m_dTransY, 0 );
switch( m_type )
{
case PMViewPosZ:
m_normal = PMVector( 0.0, 0.0, 1.0 );
break;
case PMViewNegZ:
m_viewTransformation = m_viewTransformation * PMMatrix::rotation( 0.0, M_PI, 0.0 );
m_normal = PMVector( 0.0, 0.0, -1.0 );
break;
case PMViewNegY:
m_viewTransformation = m_viewTransformation * PMMatrix::rotation( M_PI_2, 0.0, 0.0 );
m_normal = PMVector( 0.0, -1.0, 0.0 );
break;
case PMViewPosY:
m_normal = PMVector( 0.0, 1.0, 0.0 );
m_viewTransformation = m_viewTransformation * PMMatrix::rotation( -M_PI_2, 0.0, 0.0 );
break;
case PMViewPosX:
m_viewTransformation = m_viewTransformation * PMMatrix::rotation( 0.0, M_PI_2, 0.0 );
m_normal = PMVector( 1.0, 0.0, 0.0 );
break;
case PMViewNegX:
m_viewTransformation = m_viewTransformation * PMMatrix::rotation( 0.0, -M_PI_2, 0.0 );
m_normal = PMVector( -1.0, 0.0, 0.0 );
break;
default:
break;
}
m_viewTransformation = m_viewTransformation * PMMatrix::scale( 1.0, 1.0, -1.0 );
if( m_controlPoints.count( ) > 0 )
recalculateTransformations( );
recalculateControlPointPosition( );
}
m_projectionUpToDate = false;
tqrepaint( graphicalChange );
}
void PMGLView::enableTranslateMode( bool yes )
{
if( m_type != PMViewCamera )
{
m_bScaleMode = false;
m_bTranslateMode = yes;
setCursor( yes ? crossCursor : arrowCursor );
}
}
void PMGLView::enableScaleMode( bool yes )
{
if( m_type != PMViewCamera )
{
m_bScaleMode = yes;
m_bTranslateMode = false;
setCursor( yes ? crossCursor : arrowCursor );
}
}
void PMGLView::mousePressEvent( TQMouseEvent* e )
{
if( m_bScaleMode || m_bTranslateMode )
{
if( ( e->button( ) & Qt::LeftButton ) && ( e->state( ) == 0 ) )
{
m_bMousePressed = true;
m_mousePos = e->pos( );
m_scaleIntX = screenToInternalX( e->x( ) );
m_scaleIntY = screenToInternalY( e->y( ) );
}
}
else if( m_type != PMViewCamera )
{
if( ( e->button( ) & Qt::LeftButton ) && m_bInverseValid
&& m_pActiveObject )
{
if( m_pUnderMouse )
{
// check the control point selection
if( m_pActiveObject->multipleSelectControlPoints( ) )
{
if( m_pUnderMouse->selected( ) )
{
if( e->state( ) & ControlButton )
m_bDeselectUnderMouse = true;
else
m_bSelectUnderMouse = true;
}
else
{
if( e->state( ) & ControlButton )
selectControlPoint( m_pUnderMouse,
!m_pUnderMouse->selected( ), false );
else
selectControlPoint( m_pUnderMouse, true );
}
}
else
selectControlPoint( m_pUnderMouse, true );
// start the graphical change
if( !m_bGraphicalChangeMode )
{
m_bGraphicalChangeMode = true;
m_bMementoCreated = false;
m_changeStartPos = e->pos( );
m_changeStartTime = TQTime::currentTime( );
m_currentMousePos = m_changeStartPos;
m_startTimer.start( c_mouseChangeDelayMs, true );
}
}
else
{
if( m_pActiveObject->multipleSelectControlPoints( ) )
{
// multiple selection mode
// start only when the view is rendered
if( !PMRenderManager::theManager( )->containsTask( this ) )
{
m_bMultipleSelectionMode = true;
m_bSelectionStarted = false;
m_selectionStart = e->pos( );
m_selectionEnd = m_selectionStart;
}
}
else
selectControlPoint( 0, false );
}
}
}
if( !( m_bGraphicalChangeMode || m_bMousePressed ) )
{
if( ( e->button( ) == Qt::RightButton ) && ( e->state( ) == 0 ) )
{
m_contextClickPosition = PMVector( screenToInternalX( e->x( ) ),
screenToInternalY( e->y( ) ) );
if( m_pUnderMouse )
{
// check the control point selection
if( m_pActiveObject->multipleSelectControlPoints( ) )
{
if( !m_pUnderMouse->selected( ) )
selectControlPoint( m_pUnderMouse, true );
}
else
selectControlPoint( m_pUnderMouse, true );
}
contextMenu( );
}
}
if( e->button( ) == Qt::MidButton )
{
m_bMidMousePressed = true;
m_mousePos = e->pos( );
}
}
void PMGLView::mouseReleaseEvent( TQMouseEvent* e )
{
m_bMousePressed = false;
if( m_bGraphicalChangeMode )
{
m_startTimer.stop( );
if( m_bMementoCreated )
{
PMDataChangeCommand* cmd;
cmd = new PMDataChangeCommand( m_pActiveObject->takeMemento( ) );
m_pPart->executeCommand( cmd );
checkUnderMouse( ( int ) screenToInternalX( e->x( ) ),
( int ) screenToInternalY( e->y( ) ) );
}
else
{
if( m_pUnderMouse )
{
if( m_bSelectUnderMouse )
selectControlPoint( m_pUnderMouse, true );
else if( m_bDeselectUnderMouse )
selectControlPoint( m_pUnderMouse, false, false );
}
}
m_bGraphicalChangeMode = false;
}
else if( m_bMultipleSelectionMode )
{
if( m_bSelectionStarted )
{
int sx, sy, ex, ey, w, h;
double isx, isy, iex, iey;
TQPtrListIterator<PMVector> pit( m_controlPointsPosition );
PMControlPointListIterator cit( m_controlPoints );
PMVector p;
calculateSelectionBox( sx, sy, ex, ey, w, h );
isx = screenToInternalX( sx );
iex = screenToInternalX( ex );
isy = screenToInternalY( ey );
iey = screenToInternalY( sy );
restoreSelectionBox( );
while( pit.current( ) && cit.current( ) )
{
p = *( pit.current( ) );
if( ( isx <= p[0] ) && ( iex >= p[0] )
&& ( isy <= p[1] ) && ( iey >= p[1] ) )
selectControlPoint( cit.current( ), true, false );
else if( !( e->state( ) & ControlButton ) )
selectControlPoint( cit.current( ), false, false );
++cit;
++pit;
}
}
else
selectControlPoint( 0, false );
m_bMultipleSelectionMode = false;
}
if( m_bAutoScroll )
{
m_bAutoScroll = false;
m_autoScrollTimer.stop( );
}
if( e->button( ) & Qt::MidButton )
m_bMidMousePressed = false;
m_bSelectUnderMouse = false;
m_bDeselectUnderMouse = false;
}
void PMGLView::mouseMoveEvent( TQMouseEvent* e )
{
if( m_bMousePressed )
{
if( m_bScaleMode )
{
int d = e->x( ) - m_mousePos.x( );
if( d != 0 )
{
double s = exp( d * c_sizeFactor );
double c = 1.0 / ( m_dScale * s ) - 1.0 / m_dScale;
m_dTransX += m_scaleIntX * c;
m_dTransY += m_scaleIntY * c;
m_dScale *= s;
invalidateProjection( );
}
}
else if( m_bTranslateMode )
{
m_dTransX += ( e->x( ) - m_mousePos.x( ) ) / m_dScale;
m_dTransY -= ( e->y( ) - m_mousePos.y( ) ) / m_dScale;
invalidateProjection( );
}
m_mousePos = e->pos( );
}
else if( m_bMidMousePressed )
{
m_dTransX += ( e->x( ) - m_mousePos.x( ) ) / m_dScale;
m_dTransY -= ( e->y( ) - m_mousePos.y( ) ) / m_dScale;
invalidateProjection( );
m_mousePos = e->pos( );
}
else if( m_bGraphicalChangeMode )
{
m_currentMousePos = e->pos( );
if( !m_bMementoCreated )
{
TQPoint movement = e->pos( ) - m_changeStartPos;
if( ( m_changeStartTime.msecsTo( TQTime::currentTime( ) ) > c_mouseChangeDelayMs )
|| ( movement.manhattanLength( ) > c_mouseChangeDelayPixel ) )
{
m_startTimer.stop( );
startChange( m_changeStartPos );
}
}
if( m_bMementoCreated )
graphicalChange( e->pos( ) );
}
else if( m_bMultipleSelectionMode )
{
if( !m_bSelectionStarted )
{
m_selectionEnd = e->pos( );
startSelection( );
}
else
{
restoreSelectionBox( );
m_selectionEnd = e->pos( );
saveSelectionBox( );
paintSelectionBox( );
}
}
else if( !( m_bScaleMode || m_bTranslateMode ) )
{
checkUnderMouse( ( int ) screenToInternalX( e->x( ) ),
( int ) screenToInternalY( e->y( ) ) );
}
if( m_bMultipleSelectionMode || m_bGraphicalChangeMode )
{
bool as = m_bAutoScroll;
if( e->x( ) < 0 )
m_autoScrollDirectionX = 1;
else if( e->x( ) >= width( ) )
m_autoScrollDirectionX = -1;
else
m_autoScrollDirectionX = 0;
if( e->y( ) < 0 )
m_autoScrollDirectionY = 1;
else if( e->y( ) >= height( ) )
m_autoScrollDirectionY = -1;
else
m_autoScrollDirectionY = 0;
if( ( m_autoScrollDirectionX != 0 ) || ( m_autoScrollDirectionY != 0 ) )
m_bAutoScroll = true;
else
m_bAutoScroll = false;
if( m_bAutoScroll && !as )
{
m_lastAutoScrollUpdate = TQTime::currentTime( );
m_autoScrollTimer.start( c_minAutoScrollUpdateTime, true );
}
if( !m_bAutoScroll && as )
m_autoScrollTimer.stop( );
}
}
void PMGLView::wheelEvent( TQWheelEvent* e )
{
if( m_type != PMViewCamera )
{
double s = exp( e->delta( ) / 4 * c_sizeFactor );
double deltaX = screenToInternalX( e->x( ) );
double deltaY = screenToInternalY( e->y( ) );
double c = 1.0 / ( m_dScale * s ) - 1.0 / m_dScale;
m_dTransX += deltaX * c;
m_dTransY += deltaY * c;
m_dScale *= s;
invalidateProjection( );
}
}
void PMGLView::keyPressEvent( TQKeyEvent* e )
{
bool accept = true;
if( e->state( ) == 0 )
{
if( m_type != PMViewCamera )
{
if( m_dScale > 0 )
{
switch( e->key( ) )
{
case Key_Left:
m_dTransX -= keyMoveSpeed / m_dScale;
break;
case Key_Right:
m_dTransX += keyMoveSpeed / m_dScale;
break;
case Key_Up:
m_dTransY += keyMoveSpeed / m_dScale;
break;
case Key_Down:
m_dTransY -= keyMoveSpeed / m_dScale;
break;
default:
accept = false;
}
}
else
kdError( PMArea ) << "scale <= 0 in PMGLView::keyPressEvent\n";
}
}
else if( e->state( ) == ControlButton )
{
if( m_type != PMViewCamera )
{
switch( e->key( ) )
{
case Key_Left:
case Key_Down:
m_dScale /= keyScaleFactor;
break;
case Key_Right:
case Key_Up:
m_dScale *= keyScaleFactor;
break;
default:
accept = false;
}
}
}
else
accept = false;
if( accept )
invalidateProjection( );
else
e->ignore( );
}
void PMGLView::slotAutoScroll( )
{
if( m_bAutoScroll )
{
TQTime now = TQTime::currentTime( );
int msecs = m_lastAutoScrollUpdate.msecsTo( now );
int pixels = ( int ) ( m_autoScrollSpeed * msecs / 1000.0 );
if( pixels < 1 )
pixels = 1;
if( pixels > ( width( ) * 3 / 4 ) )
pixels = width( ) * 3 / 4;
if( pixels > ( height( ) * 3 / 4 ) )
pixels = height( ) * 3 / 4;
if( m_bGraphicalChangeMode && !m_bMementoCreated )
startChange( m_changeStartPos );
if( m_bMultipleSelectionMode )
restoreSelectionBox( );
m_dTransX += pixels * m_autoScrollDirectionX / m_dScale;
m_dTransY -= pixels * m_autoScrollDirectionY / m_dScale;
invalidateProjection( );
if( m_bGraphicalChangeMode )
if( m_bMultipleSelectionMode )
{
m_selectionStart += TQPoint( pixels * m_autoScrollDirectionX,
pixels * m_autoScrollDirectionY );
saveSelectionBox( );
paintSelectionBox( );
}
if( m_bGraphicalChangeMode )
graphicalChange( mapFromGlobal( TQCursor::pos( ) ) );
else
tqrepaint( );
m_lastAutoScrollUpdate = now;
}
}
void PMGLView::slotMouseChangeTimer( )
{
if( !m_bMementoCreated )
{
if( m_currentMousePos != m_changeStartPos )
{
startChange( m_changeStartPos );
graphicalChange( m_currentMousePos );
}
}
}
void PMGLView::startChange( const TQPoint& mousePos )
{
m_pActiveObject->createMemento( );
m_bMementoCreated = true;
PMVector p = mousePosition( m_pUnderMouse, mousePos.x( ), mousePos.y( ) );
p.transform( m_inversePointsTransformation );
if( m_pActiveObject->multipleSelectControlPoints( ) )
{
PMControlPointListIterator it( m_controlPoints );
for( ; it.current( ); ++it )
if( it.current( )->selected( ) )
it.current( )->startChange( p, m_normal );
}
else
m_pUnderMouse->startChange( p, m_normal );
}
void PMGLView::graphicalChange( const TQPoint& mousePos )
{
PMVector p = mousePosition( m_pUnderMouse, mousePos.x( ), mousePos.y( ) );
p.transform( m_inversePointsTransformation );
if( m_pActiveObject->multipleSelectControlPoints( ) )
{
PMControlPointListIterator it( m_controlPoints );
for( ; it.current( ); ++it )
if( it.current( )->selected( ) )
it.current( )->change( p );
}
else
m_pUnderMouse->change( p );
PMObjectList changedObjects;
m_pActiveObject->controlPointsChangedList( m_controlPoints, changedObjects );
if( changedObjects.isEmpty( ) )
emit objectChanged( m_pActiveObject, PMCGraphicalChange, TQT_TQOBJECT(this) );
else
{
PMObjectListIterator it( changedObjects );
for( ; it.current( ); ++it )
emit objectChanged( it.current( ), PMCGraphicalChange, TQT_TQOBJECT(this) );
}
}
void PMGLView::checkUnderMouse( int x, int y )
{
// is cursor over a control point?
// double z;
PMVector* v;
PMControlPoint* p;
PMControlPoint* old = m_pUnderMouse;
if( m_bInverseValid && ( m_type != PMViewCamera ) )
{
m_pUnderMouse = 0;
// z = -1e10;
v = m_controlPointsPosition.first( );
p = m_controlPoints.first( );
while( p )
{
if( p->displayType( ) == PMControlPoint::CPCross )
{
if( !m_pUnderMouse )
m_pUnderMouse = p;
}
else
{
if( ( fabs( x - (*v)[0] ) < ( controlPointSize / 2.0 + 0.1 ) )
&& ( fabs( y - (*v)[1] ) < ( controlPointSize / 2.0 + 0.1 ) ) )
{
if( m_pUnderMouse )
{
if( p->selected( ) && !m_pUnderMouse->selected( ) )
m_pUnderMouse = p;
}
else
m_pUnderMouse = p;
}
}
p = m_controlPoints.next( );
v = m_controlPointsPosition.next( );
}
}
else
m_pUnderMouse = 0;
setCursor( m_pUnderMouse ? crossCursor : arrowCursor );
if( m_pUnderMouse != old )
{
if( m_pUnderMouse )
emit controlPointMessage( m_pUnderMouse->description( ) );
else
emit controlPointMessage( "" );
}
}
void PMGLView::updateControlPoints( )
{
m_controlPoints.clear( );
m_controlPoints = m_pPart->activeControlPoints( );
if( ( m_controlPoints.count( ) > 0 ) && m_pActiveObject )
{
m_objectsTransformation = m_pActiveObject->transformedWith( );
recalculateTransformations( );
}
if( m_bGraphicalChangeMode )
m_bGraphicalChangeMode = false;
recalculateControlPointPosition( );
}
void PMGLView::recalculateControlPointPosition( )
{
PMControlPointListIterator it( m_controlPoints );
m_controlPointsPosition.clear( );
PMVector* v;
for( ; it.current( ); ++it )
{
v = new PMVector( m_controlPointsTransformation * it.current( )->position( ) );
m_controlPointsPosition.append( v );
}
if( !m_bGraphicalChangeMode )
{
m_pUnderMouse = 0;
emit controlPointMessage( "" );
}
}
PMVector PMGLView::mousePosition( PMControlPoint* cp, int x, int y )
{
PMVector result;
int index;
PMVector* p;
result[0] = screenToInternalX( x );
result[1] = screenToInternalY( y );
if( cp )
{
index = m_controlPoints.findRef( cp );
if( index >= 0 )
{
p = m_controlPointsPosition.at( ( uint ) index );
if( p )
result[2] = p->z( );
}
}
return result;
}
void PMGLView::recalculateTransformations( )
{
int r, c;
m_controlPointsTransformation = m_viewTransformation * m_objectsTransformation;
if( m_controlPointsTransformation.canBuildInverse( ) )
{
m_inversePointsTransformation = m_controlPointsTransformation.inverse( );
for( c = 0; c < 4; c++ )
for( r = 0; r < 4; r++ )
if( fabs( m_inversePointsTransformation[c][r] ) < 1e-8 )
m_inversePointsTransformation[c][r] = 0.0;
m_bInverseValid = true;
}
else
m_bInverseValid = false;
}
void PMGLView::setType( PMViewType t )
{
if( m_type != t )
m_viewTransformation = PMMatrix::identity( );
m_type = t;
invalidateProjection( );
emit viewTypeChanged( viewTypeAsString( t ) );
}
void PMGLView::setCamera( PMCamera* c )
{
m_pCamera = c;
invalidateProjection( );
}
void PMGLView::slotRefresh( )
{
if( m_type == PMViewCamera )
if( !m_pCamera )
setCamera( m_pPart->firstCamera( ) );
tqrepaint( );
}
void PMGLView::slotClear( )
{
m_controlPointsPosition.clear( );
m_controlPoints.clear( );
m_pUnderMouse = 0;
m_pCamera = 0;
m_pActiveObject = 0;
slotStopRendering( );
}
void PMGLView::slotActiveRenderModeChanged( )
{
if( ( m_type == PMViewCamera ) && m_pCamera )
invalidateProjection( );
}
void PMGLView::slotStopRendering( )
{
PMRenderManager* rm = PMRenderManager::theManager( );
rm->removeView( this );
}
void PMGLView::slotObjectChanged( PMObject* obj, const int mode,
TQObject* sender )
{
bool redraw = false;
if( mode & PMCNewSelection )
{
if( obj )
{
if( obj != m_pActiveObject )
{
m_pActiveObject = obj;
redraw = true;
}
}
else
{
m_pActiveObject = 0;
redraw = true;
}
}
if( mode & ( PMCSelected | PMCDeselected ) )
{
m_pActiveObject = 0;
redraw = true;
}
if( mode & ( PMCViewStructure | PMCGraphicalChange ) )
{
if( m_type == PMGLView::PMViewCamera )
{
if( obj->type( ) == "Camera" )
if( m_pCamera == ( PMCamera* ) obj )
invalidateProjection( );
if( obj->parent( ) )
if( obj->parent( )->type( ) == "Camera" )
if( m_pCamera == ( PMCamera* ) obj->parent( ) )
if( obj->hasTransformationMatrix( ) )
invalidateProjection( );
}
redraw = true;
}
if( mode & PMCNewControlPoints )
{
updateControlPoints( );
m_pActiveObject = m_pPart->activeObject( );
redraw = true;
}
if( mode & PMCControlPointSelection )
{
redraw = true;
}
if( mode & PMCDescription )
{
if( m_type == PMGLView::PMViewCamera && obj && obj == m_pCamera )
redraw = true;
}
if( mode & PMCAdd )
{
if( m_type == PMGLView::PMViewCamera )
{
if( obj->type( ) == "Camera" )
if( !m_pCamera )
setCamera( ( PMCamera* ) obj );
if( obj->parent( ) )
if( obj->parent( )->type( ) == "Camera" )
if( m_pCamera == ( PMCamera* ) obj->parent( ) )
if( obj->hasTransformationMatrix( ) )
invalidateProjection( );
}
redraw = true;
}
if( mode & PMCRemove )
{
if( obj->type( ) == "Camera" )
if( m_pCamera == ( PMCamera* ) obj )
setCamera( 0 );
if( m_type == PMGLView::PMViewCamera )
if( obj->parent( ) )
if( obj->parent( )->type( ) == "Camera" )
if( m_pCamera == ( PMCamera* ) obj->parent( ) )
if( obj->hasTransformationMatrix( ) )
invalidateProjection( );
redraw = true;
}
if( mode & PMCChildren )
redraw = true;
if( redraw )
tqrepaint( TQT_BASE_OBJECT(sender) == TQT_BASE_OBJECT(this) );
}
void PMGLView::tqrepaint( bool graphicalChange )
{
if( isValid( ) )
{
PMObject* obj = m_pActiveObject;
if( obj )
obj = topLevelRenderingObject( obj );
else
{
const PMObjectList& selected = m_pPart->selectedObjects( );
PMObjectListIterator it( selected );
if( it.current( ) )
obj = topLevelRenderingObject( it.current( ) );
if( obj && ( obj->type( ) != "Scene" ) )
for( ++it; it.current( ) && obj; ++it )
if( topLevelRenderingObject( it.current( ) ) != obj )
obj = 0;
}
if( !obj )
obj = m_pPart->scene( );
if( obj )
{
double aspectRatio = 1.0;
PMRenderMode* mode = m_pPart->scene( )->renderModes( )->current( );
if( mode )
if( mode->height( ) != 0 )
aspectRatio = ( double ) mode->width( )
/ ( double ) mode->height( );
PMRenderManager* rm = PMRenderManager::theManager( );
rm->addView( this, m_pActiveObject, obj,
&m_controlPoints, aspectRatio,
m_pPart->scene( )->visibilityLevel( ), graphicalChange );
}
}
}
PMObject* PMGLView::topLevelRenderingObject( PMObject* o ) const
{
PMObject* obj = o;
bool stop = false;
if( obj )
{
do
{
if( !obj )
stop = true;
else if( obj->isA( "Scene" ) || obj->isA( "Declare" ) )
stop = true;
else
obj = obj->parent( );
}
while( !stop );
}
else
obj = m_pPart->scene( );
return obj;
}
void PMGLView::selectControlPoint( PMControlPoint* cp, bool select, bool deselectOthers )
{
bool selectionChanged = false;
if( cp )
{
if( deselectOthers )
{
PMControlPointListIterator it( m_controlPoints );
for( ; it.current( ); ++it )
{
bool s;
if( it.current( ) == cp )
s = select;
else
s = false;
if( s != it.current( )->selected( ) )
{
selectionChanged = true;
it.current( )->setSelected( s );
}
}
}
else
{
if( select != cp->selected( ) )
{
selectionChanged = true;
cp->setSelected( select );
}
}
}
else
{
PMControlPointListIterator it( m_controlPoints );
for( ; it.current( ); ++it )
{
if( select != it.current( )->selected( ) )
{
selectionChanged = true;
it.current( )->setSelected( select );
}
}
}
if( selectionChanged )
emit objectChanged( m_pActiveObject, PMCControlPointSelection, TQT_TQOBJECT(this) );
}
void PMGLView::startSelection( )
{
if( !m_bSelectionStarted )
{
saveSelectionBox( );
paintSelectionBox( );
m_bSelectionStarted = true;
}
}
void PMGLView::restoreSelectionBox( )
{
if( !m_bAboutToUpdate )
{
int sx, sy, ex, ey, w, h;
calculateSelectionBox( sx, sy, ex, ey, w, h );
if( !m_selectionPixmap[0].isNull( ) )
bitBlt( this, sx, sy, &( m_selectionPixmap[0] ), 0, 0, w, 1, CopyROP );
if( !m_selectionPixmap[1].isNull( ) )
bitBlt( this, sx, ey, &( m_selectionPixmap[1] ), 0, 0, w, 1, CopyROP );
if( !m_selectionPixmap[2].isNull( ) )
bitBlt( this, sx, sy+1, &( m_selectionPixmap[2] ), 0, 0, 1, h-2, CopyROP );
if( !m_selectionPixmap[3].isNull( ) )
bitBlt( this, ex, sy+1, &( m_selectionPixmap[3] ), 0, 0, 1, h-2, CopyROP );
}
}
void PMGLView::saveSelectionBox( )
{
if( !m_bAboutToUpdate )
{
int sx, sy, ex, ey, w, h;
calculateSelectionBox( sx, sy, ex, ey, w, h );
m_selectionPixmap[0].resize( w, 1 );
if( !m_selectionPixmap[0].isNull( ) )
bitBlt( &( m_selectionPixmap[0] ), 0, 0, this, sx, sy, w, 1, CopyROP );
m_selectionPixmap[1].resize( w, 1 );
if( !m_selectionPixmap[1].isNull( ) )
bitBlt( &( m_selectionPixmap[1] ), 0, 0, this, sx, ey, w, 1, CopyROP );
m_selectionPixmap[2].resize( 1, h-2 );
if( !m_selectionPixmap[2].isNull( ) )
bitBlt( &( m_selectionPixmap[2] ), 0, 0, this, sx, sy+1, 1, h-2, CopyROP );
m_selectionPixmap[3].resize( 1, h-2 );
if( !m_selectionPixmap[3].isNull( ) )
bitBlt( &( m_selectionPixmap[3] ), 0, 0, this, ex, sy+1, 1, h-2, CopyROP );
}
}
void PMGLView::paintSelectionBox( )
{
if( !m_bAboutToUpdate )
{
int sx, sy, ex, ey, w, h;
calculateSelectionBox( sx, sy, ex, ey, w, h );
TQPainter p;
p.begin( this );
p.setPen( PMRenderManager::theManager( )->controlPointColor( 1 ) );
p.drawRect( sx, sy, w, h );
p.end( );
}
}
void PMGLView::calculateSelectionBox( int& sx, int& sy, int& ex, int& ey,
int& w, int& h )
{
if( m_selectionStart.x( ) < m_selectionEnd.x( ) )
{
sx = m_selectionStart.x( );
ex = m_selectionEnd.x( );
}
else
{
ex = m_selectionStart.x( );
sx = m_selectionEnd.x( );
}
if( m_selectionStart.y( ) < m_selectionEnd.y( ) )
{
sy = m_selectionStart.y( );
ey = m_selectionEnd.y( );
}
else
{
ey = m_selectionStart.y( );
sy = m_selectionEnd.y( );
}
w = ex - sx + 1;
h = ey - sy + 1;
}
double PMGLView::screenToInternalX( int x ) const
{
return rint( x - width( ) / 2.0 + 0.1 );
}
double PMGLView::screenToInternalY( int y ) const
{
return rint( height( ) / 2.0 - y - 0.1 );
}
void PMGLView::slotRenderingStarted( PMGLView* )
{
}
void PMGLView::slotAboutToUpdate( PMGLView* view )
{
if( view == this )
m_bAboutToUpdate = true;
}
void PMGLView::slotRenderingFinished( PMGLView* view )
{
if( view == this )
{
m_bAboutToUpdate = false;
if( m_bMultipleSelectionMode )
{
saveSelectionBox( );
paintSelectionBox( );
}
if( m_bAutoScroll )
{
TQTime now = TQTime::currentTime( );
int msecs = m_lastAutoScrollUpdate.msecsTo( now );
if( msecs < c_minAutoScrollUpdateTime )
m_autoScrollTimer.start( c_minAutoScrollUpdateTime - msecs, true );
else
m_autoScrollTimer.start( 0, true );
}
}
}
TQString PMGLView::viewTypeAsString( PMViewType t )
{
TQString str;
switch( t )
{
case PMViewPosX:
str = i18n( "Left" );
break;
case PMViewNegX:
str = i18n( "Right" );
break;
case PMViewPosY:
str = i18n( "Bottom" );
break;
case PMViewNegY:
str = i18n( "Top" );
break;
case PMViewPosZ:
str = i18n( "Front" );
break;
case PMViewNegZ:
str = i18n( "Back" );
break;
case PMViewCamera:
str = i18n( "Camera" );
break;
}
return str;
}
void PMGLView::saveConfig( KConfig* /*cfg*/ )
{
}
void PMGLView::restoreConfig( KConfig* /*cfg*/ )
{
}
void PMGLView::contextMenu( )
{
TQPopupMenu* m = new TQPopupMenu( );
m->insertItem( i18n( "Left View" ), this, TQT_SLOT( slotSetTypePosX( ) ) );
m->insertItem( i18n( "Right View" ), this, TQT_SLOT( slotSetTypeNegX( ) ) );
m->insertItem( i18n( "Top View" ), this, TQT_SLOT( slotSetTypeNegY( ) ) );
m->insertItem( i18n( "Bottom View" ), this, TQT_SLOT( slotSetTypePosY( ) ) );
m->insertItem( i18n( "Front View" ), this, TQT_SLOT( slotSetTypePosZ( ) ) );
m->insertItem( i18n( "Back View" ), this, TQT_SLOT( slotSetTypeNegZ( ) ) );
TQPopupMenu* cm = new TQPopupMenu( m );
TQPtrListIterator<PMCamera> it = m_pPart->cameras( );
TQString name;
if( !it.current( ) )
cm->insertItem( i18n( "No Cameras" ) );
else
{
int cnr = 0;
for( ; it.current( ); ++it, ++cnr )
{
name = it.current( )->name( );
if( name.isEmpty( ) )
name = i18n( "(unnamed)" );
cm->insertItem( name, cnr );
}
}
connect( cm, TQT_SIGNAL( activated( int ) ), TQT_SLOT( slotCameraView( int ) ) );
m->insertItem( SmallIconSet( "pmcamera" ), i18n( "Camera" ), cm );
m->insertSeparator( );
m->insertItem( i18n( "Snap to Grid" ), this, TQT_SLOT( slotSnapToGrid( ) ) );
m_objectActions.clear( );
if( m_pActiveObject )
{
m_pActiveObject->addObjectActions( m_controlPoints, m_objectActions );
if( !m_objectActions.isEmpty( ) )
{
PMObjectAction* oa = 0;
TQPtrListIterator<PMObjectAction> ait( m_objectActions );
for( ; ait.current( ); ++ait )
{
oa = ait.current( );
oa->setMenuID( m->insertItem( oa->description( ) ) );
}
}
}
connect( m, TQT_SIGNAL( activated( int ) ), TQT_SLOT( slotObjectAction( int ) ) );
m->insertSeparator( );
TQPopupMenu* menu = new TQPopupMenu( m );
PMControlPointListIterator pit( m_controlPoints );
if( !pit.current( ) )
menu->insertItem( i18n( "No Control Points" ) );
else
{
int cnr = 0;
for( ; pit.current( ); ++pit, ++cnr )
menu->insertItem( pit.current( )->description( ), cnr );
}
connect( menu, TQT_SIGNAL( activated( int ) ), TQT_SLOT( slotControlPoint( int ) ) );
m->insertItem( i18n( "Control Points" ), menu );
m->exec( TQCursor::pos( ) );
delete m;
}
void PMGLView::slotCameraView( int id )
{
int i;
TQPtrListIterator<PMCamera> it = m_pPart->cameras( );
for( i = 0; i < id; i++ )
++it;
if( it.current( ) )
{
setCamera( it.current( ) );
setType( PMGLView::PMViewCamera );
}
}
void PMGLView::slotObjectAction( int id )
{
TQPtrListIterator<PMObjectAction> it( m_objectActions );
PMObjectAction* oa = 0;
for( ; it.current( ) && !oa; ++it )
if( it.current( )->menuID( ) == id )
oa = it.current( );
if( oa && m_pActiveObject )
{
// otherwise no object action was selected in the context menu
m_pActiveObject->createMemento( );
m_pActiveObject->objectActionCalled( oa, m_controlPoints,
m_controlPointsPosition,
m_contextClickPosition );
PMDataChangeCommand* cmd;
cmd = new PMDataChangeCommand( m_pActiveObject->takeMemento( ) );
cmd->setText( oa->description( ) );
m_pPart->executeCommand( cmd );
}
}
void PMGLView::slotControlPoint( int id )
{
PMControlPoint* p = m_controlPoints.at( id );
if( p )
{
PMControlPointListIterator cit( m_controlPoints );
for( ; cit.current( ); ++cit )
cit.current( )->setSelected( p == cit.current( ) );
emit objectChanged( m_pActiveObject, PMCControlPointSelection, TQT_TQOBJECT(this) );
}
}
void PMGLView::slotSnapToGrid( )
{
if( m_pActiveObject )
{
if( !m_pActiveObject->mementoCreated( ) )
m_pActiveObject->createMemento( );
PMControlPointListIterator it( m_controlPoints );
for( ; it.current( ); ++it )
if( it.current( )->selected( ) )
it.current( )->snapToGrid( );
m_pActiveObject->controlPointsChanged( m_controlPoints );
PMDataChangeCommand* cmd;
cmd = new PMDataChangeCommand( m_pActiveObject->takeMemento( ) );
cmd->setText( i18n( "Snap to Grid" ) );
m_pPart->executeCommand( cmd );
}
}
TQString PMGLView::description( ) const
{
return viewTypeAsString( m_type );
}
void PMGLView::restoreViewConfig( PMViewOptions* vo )
{
if( vo && vo->viewType( ) == "glview" )
{
PMGLViewOptions* o = ( PMGLViewOptions* ) vo;
m_type = o->glViewType( );
}
}
void PMGLView::saveViewConfig( PMViewOptions* vo ) const
{
if( vo && vo->viewType( ) == "glview" )
{
PMGLViewOptions* o = ( PMGLViewOptions* ) vo;
o->setGLViewType( m_type );
}
}
void PMGLViewOptions::loadData( TQDomElement& e )
{
TQString s = e.attribute( "type", "Camera" );
if( s == "Camera" ) m_glViewType = PMGLView::PMViewCamera;
else if( s == "X" ) m_glViewType = PMGLView::PMViewPosX;
else if( s == "Y" ) m_glViewType = PMGLView::PMViewPosY;
else if( s == "Z" ) m_glViewType = PMGLView::PMViewPosZ;
else if( s == "NegX" ) m_glViewType = PMGLView::PMViewNegX;
else if( s == "NegY" ) m_glViewType = PMGLView::PMViewNegY;
else if( s == "NegZ" ) m_glViewType = PMGLView::PMViewNegZ;
}
void PMGLViewOptions::saveData( TQDomElement& e )
{
switch( m_glViewType )
{
case PMGLView::PMViewCamera:
e.setAttribute( "type", "Camera" );
break;
case PMGLView::PMViewPosX:
e.setAttribute( "type", "X" );
break;
case PMGLView::PMViewPosY:
e.setAttribute( "type", "Y" );
break;
case PMGLView::PMViewPosZ:
e.setAttribute( "type", "Z" );
break;
case PMGLView::PMViewNegX:
e.setAttribute( "type", "NegX" );
break;
case PMGLView::PMViewNegY:
e.setAttribute( "type", "NegY" );
break;
case PMGLView::PMViewNegZ:
e.setAttribute( "type", "NegZ" );
break;
default:
kdError( PMArea ) << i18n( "Unknown GL view type." )
<< endl;
break;
}
}
TQString PMGLViewFactory::description( ) const
{
return i18n( "3D View" );
}
TQString PMGLViewFactory::description( PMViewOptions* vo ) const
{
if( vo && vo->viewType( ) == "glview" )
{
PMGLViewOptions* o = ( PMGLViewOptions* ) vo;
return i18n( "3D View (%1)" ).tqarg(
PMGLView::viewTypeAsString( o->glViewType( ) ) );
}
return description( );
}
PMViewOptionsWidget* PMGLViewFactory::newOptionsWidget( TQWidget* parent,
PMViewOptions* o )
{
return new PMGLViewOptionsWidget( parent, o );
}
PMViewOptions* PMGLViewFactory::newOptionsInstance( ) const
{
PMGLViewOptions* o = new PMGLViewOptions( );
return o;
}
PMGLViewOptionsWidget::PMGLViewOptionsWidget( TQWidget* parent,
PMViewOptions* o )
: PMViewOptionsWidget( parent )
{
m_pOptions = ( PMGLViewOptions* ) o;
TQHBoxLayout* hl = new TQHBoxLayout( this, 0, KDialog::spacingHint( ) );
TQLabel* l = new TQLabel( i18n( "3D view type:" ), this );
hl->addWidget( l );
m_pGLViewType = new TQComboBox( false, this );
m_pGLViewType->insertItem( i18n( "Top" ) );
m_pGLViewType->insertItem( i18n( "Bottom" ) );
m_pGLViewType->insertItem( i18n( "Left" ) );
m_pGLViewType->insertItem( i18n( "Right" ) );
m_pGLViewType->insertItem( i18n( "Front" ) );
m_pGLViewType->insertItem( i18n( "Back" ) );
m_pGLViewType->insertItem( i18n( "Camera" ) );
switch( m_pOptions->glViewType( ) )
{
case PMGLView::PMViewNegY:
m_pGLViewType->setCurrentItem( 0 );
break;
case PMGLView::PMViewPosY:
m_pGLViewType->setCurrentItem( 1 );
break;
case PMGLView::PMViewPosX:
m_pGLViewType->setCurrentItem( 2 );
break;
case PMGLView::PMViewNegX:
m_pGLViewType->setCurrentItem( 3 );
break;
case PMGLView::PMViewPosZ:
m_pGLViewType->setCurrentItem( 4 );
break;
case PMGLView::PMViewNegZ:
m_pGLViewType->setCurrentItem( 5 );
break;
case PMGLView::PMViewCamera:
m_pGLViewType->setCurrentItem( 6 );
break;
}
connect( m_pGLViewType, TQT_SIGNAL( activated( int ) ),
TQT_SLOT( slotGLViewTypeChanged( int ) ) );
hl->addWidget( m_pGLViewType );
}
void PMGLViewOptionsWidget::slotGLViewTypeChanged( int index )
{
switch( index )
{
case 0:
m_pOptions->setGLViewType( PMGLView::PMViewNegY );
break;
case 1:
m_pOptions->setGLViewType( PMGLView::PMViewPosY );
break;
case 2:
m_pOptions->setGLViewType( PMGLView::PMViewPosX );
break;
case 3:
m_pOptions->setGLViewType( PMGLView::PMViewNegX );
break;
case 4:
m_pOptions->setGLViewType( PMGLView::PMViewPosZ );
break;
case 5:
m_pOptions->setGLViewType( PMGLView::PMViewNegZ );
break;
case 6:
m_pOptions->setGLViewType( PMGLView::PMViewCamera );
break;
}
emit viewTypeDescriptionChanged( );
}
#include "pmglview.moc"