qt_demoe/third/3rd_qwt/qwt_plot_glcanvas.cpp

378 lines
7.9 KiB
C++
Raw Normal View History

2021-10-08 02:51:37 +00:00
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_plot_glcanvas.h"
#include "qwt_plot.h"
#include "qwt_painter.h"
#include <qevent.h>
#include <qpainter.h>
#include <qdrawutil.h>
#include <qstyle.h>
#include <qstyleoption.h>
#define FIX_GL_TRANSLATION 0
static QWidget *qwtBGWidget( QWidget *widget )
{
QWidget *w = widget;
for ( ; w->parentWidget() != NULL; w = w->parentWidget() )
{
if ( w->autoFillBackground() ||
w->testAttribute( Qt::WA_StyledBackground ) )
{
return w;
}
}
return w;
}
static void qwtUpdateContentsRect( QwtPlotGLCanvas *canvas )
{
const int fw = canvas->frameWidth();
canvas->setContentsMargins( fw, fw, fw, fw );
}
class QwtPlotGLCanvas::PrivateData
{
public:
PrivateData():
frameStyle( QFrame::Panel | QFrame::Sunken),
lineWidth( 2 ),
midLineWidth( 0 )
{
}
int frameStyle;
int lineWidth;
int midLineWidth;
};
class QwtPlotGLCanvasFormat: public QGLFormat
{
public:
QwtPlotGLCanvasFormat():
QGLFormat( QGLFormat::defaultFormat() )
{
setSampleBuffers( true );
}
};
/*!
\brief Constructor
\param plot Parent plot widget
\sa QwtPlot::setCanvas()
*/
QwtPlotGLCanvas::QwtPlotGLCanvas( QwtPlot *plot ):
QGLWidget( QwtPlotGLCanvasFormat(), plot )
{
d_data = new PrivateData;
#ifndef QT_NO_CURSOR
setCursor( Qt::CrossCursor );
#endif
setAutoFillBackground( true );
qwtUpdateContentsRect( this );
}
//! Destructor
QwtPlotGLCanvas::~QwtPlotGLCanvas()
{
delete d_data;
}
/*!
Set the frame style
\param style The bitwise OR between a shape and a shadow.
\sa frameStyle(), QFrame::setFrameStyle(),
setFrameShadow(), setFrameShape()
*/
void QwtPlotGLCanvas::setFrameStyle( int style )
{
if ( style != d_data->frameStyle )
{
d_data->frameStyle = style;
qwtUpdateContentsRect( this );
update();
}
}
/*!
\return The bitwise OR between a frameShape() and a frameShadow()
\sa setFrameStyle(), QFrame::frameStyle()
*/
int QwtPlotGLCanvas::frameStyle() const
{
return d_data->frameStyle;
}
/*!
Set the frame shadow
\param shadow Frame shadow
\sa frameShadow(), setFrameShape(), QFrame::setFrameShadow()
*/
void QwtPlotGLCanvas::setFrameShadow( Shadow shadow )
{
setFrameStyle(( d_data->frameStyle & QFrame::Shape_Mask ) | shadow );
}
/*!
\return Frame shadow
\sa setFrameShadow(), QFrame::setFrameShadow()
*/
QwtPlotGLCanvas::Shadow QwtPlotGLCanvas::frameShadow() const
{
return (Shadow) ( d_data->frameStyle & QFrame::Shadow_Mask );
}
/*!
Set the frame shape
\param shape Frame shape
\sa frameShape(), setFrameShadow(), QFrame::frameShape()
*/
void QwtPlotGLCanvas::setFrameShape( Shape shape )
{
setFrameStyle( ( d_data->frameStyle & QFrame::Shadow_Mask ) | shape );
}
/*!
\return Frame shape
\sa setFrameShape(), QFrame::frameShape()
*/
QwtPlotGLCanvas::Shape QwtPlotGLCanvas::frameShape() const
{
return (Shape) ( d_data->frameStyle & QFrame::Shape_Mask );
}
/*!
Set the frame line width
The default line width is 2 pixels.
\param width Line width of the frame
\sa lineWidth(), setMidLineWidth()
*/
void QwtPlotGLCanvas::setLineWidth( int width )
{
width = qMax( width, 0 );
if ( width != d_data->lineWidth )
{
d_data->lineWidth = qMax( width, 0 );
qwtUpdateContentsRect( this );
update();
}
}
/*!
\return Line width of the frame
\sa setLineWidth(), midLineWidth()
*/
int QwtPlotGLCanvas::lineWidth() const
{
return d_data->lineWidth;
}
/*!
Set the frame mid line width
The default midline width is 0 pixels.
\param width Midline width of the frame
\sa midLineWidth(), setLineWidth()
*/
void QwtPlotGLCanvas::setMidLineWidth( int width )
{
width = qMax( width, 0 );
if ( width != d_data->midLineWidth )
{
d_data->midLineWidth = width;
qwtUpdateContentsRect( this );
update();
}
}
/*!
\return Midline width of the frame
\sa setMidLineWidth(), lineWidth()
*/
int QwtPlotGLCanvas::midLineWidth() const
{
return d_data->midLineWidth;
}
/*!
\return Frame width depending on the style, line width and midline width.
*/
int QwtPlotGLCanvas::frameWidth() const
{
return ( frameStyle() != NoFrame ) ? d_data->lineWidth : 0;
}
/*!
Paint event
\param event Paint event
\sa QwtPlot::drawCanvas()
*/
void QwtPlotGLCanvas::paintEvent( QPaintEvent *event )
{
Q_UNUSED( event );
QPainter painter( this );
#if FIX_GL_TRANSLATION
if ( painter.paintEngine()->type() == QPaintEngine::OpenGL2 )
{
// work around a translation bug of QPaintEngine::OpenGL2
painter.translate( 1, 1 );
}
#endif
drawBackground( &painter );
drawItems( &painter );
if ( !testAttribute( Qt::WA_StyledBackground ) )
{
if ( frameWidth() > 0 )
drawBorder( &painter );
}
}
/*!
Qt event handler for QEvent::PolishRequest and QEvent::StyleChange
\param event Qt Event
\return See QGLWidget::event()
*/
bool QwtPlotGLCanvas::event( QEvent *event )
{
const bool ok = QGLWidget::event( event );
if ( event->type() == QEvent::PolishRequest ||
event->type() == QEvent::StyleChange )
{
// assuming, that we always have a styled background
// when we have a style sheet
setAttribute( Qt::WA_StyledBackground,
testAttribute( Qt::WA_StyleSheet ) );
}
return ok;
}
/*!
Draw the plot items
\param painter Painter
\sa QwtPlot::drawCanvas()
*/
void QwtPlotGLCanvas::drawItems( QPainter *painter )
{
painter->save();
painter->setClipRect( contentsRect(), Qt::IntersectClip );
QwtPlot *plot = qobject_cast< QwtPlot *>( parent() );
if ( plot )
plot->drawCanvas( painter );
painter->restore();
}
/*!
Draw the background of the canvas
\param painter Painter
*/
void QwtPlotGLCanvas::drawBackground( QPainter *painter )
{
painter->save();
QWidget *w = qwtBGWidget( this );
const QPoint off = mapTo( w, QPoint() );
painter->translate( -off );
const QRect fillRect = rect().translated( off );
if ( w->testAttribute( Qt::WA_StyledBackground ) )
{
painter->setClipRect( fillRect );
QStyleOption opt;
opt.initFrom( w );
w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w);
}
else
{
painter->fillRect( fillRect,
w->palette().brush( w->backgroundRole() ) );
}
painter->restore();
}
/*!
Draw the border of the canvas
\param painter Painter
*/
void QwtPlotGLCanvas::drawBorder( QPainter *painter )
{
const int fw = frameWidth();
if ( fw <= 0 )
return;
if ( frameShadow() == QwtPlotGLCanvas::Plain )
{
qDrawPlainRect( painter, frameRect(),
palette().shadow().color(), lineWidth() );
}
else
{
if ( frameShape() == QwtPlotGLCanvas::Box )
{
qDrawShadeRect( painter, frameRect(), palette(),
frameShadow() == Sunken, lineWidth(), midLineWidth() );
}
else
{
qDrawShadePanel( painter, frameRect(), palette(),
frameShadow() == Sunken, lineWidth() );
}
}
}
//! Calls repaint()
void QwtPlotGLCanvas::replot()
{
repaint();
}
/*!
\return Empty path
*/
QPainterPath QwtPlotGLCanvas::borderPath( const QRect &rect ) const
{
Q_UNUSED( rect );
return QPainterPath();
}
//! \return The rectangle where the frame is drawn in.
QRect QwtPlotGLCanvas::frameRect() const
{
const int fw = frameWidth();
return contentsRect().adjusted( -fw, -fw, fw, fw );
}