diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /examples/xform/xform.cpp | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'examples/xform/xform.cpp')
-rw-r--r-- | examples/xform/xform.cpp | 507 |
1 files changed, 507 insertions, 0 deletions
diff --git a/examples/xform/xform.cpp b/examples/xform/xform.cpp new file mode 100644 index 0000000..dff8cb8 --- /dev/null +++ b/examples/xform/xform.cpp @@ -0,0 +1,507 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qapplication.h> + +#include <qdialog.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qlcdnumber.h> +#include <qslider.h> +#include <qmenubar.h> +#include <qfontdialog.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qwidgetstack.h> + +#include <qpainter.h> +#include <qpixmap.h> +#include <qpicture.h> + +#include <stdlib.h> + + +class ModeNames { +public: + enum Mode { Text, Image, Picture }; +}; + + +class XFormControl : public QVBox, public ModeNames +{ + Q_OBJECT +public: + XFormControl( const QFont &initialFont, QWidget *parent=0, const char *name=0 ); + ~XFormControl() {} + + QWMatrix matrix(); + +signals: + void newMatrix( QWMatrix ); + void newText( const QString& ); + void newFont( const QFont & ); + void newMode( int ); +private slots: + void newMtx(); + void newTxt(const QString&); + void selectFont(); + void fontSelected( const QFont & ); + void changeMode(int); + void timerEvent(QTimerEvent*); +private: + Mode mode; + QSlider *rotS; // Rotation angle scroll bar + QSlider *shearS; // Shear value scroll bar + QSlider *magS; // Magnification value scroll bar + QLCDNumber *rotLCD; // Rotation angle LCD display + QLCDNumber *shearLCD; // Shear value LCD display + QLCDNumber *magLCD; // Magnification value LCD display + QCheckBox *mirror; // Checkbox for mirror image on/of + QWidgetStack* optionals; + QLineEdit *textEd; // Inp[ut field for xForm text + QPushButton *fpb; // Select font push button + QRadioButton *rb_txt; // Radio button for text + QRadioButton *rb_img; // Radio button for image + QRadioButton *rb_pic; // Radio button for picture + QFont currentFont; +}; + +/* + ShowXForm displays a text or a pixmap (QPixmap) using a coordinate + transformation matrix (QWMatrix) +*/ + +class ShowXForm : public QWidget, public ModeNames +{ + Q_OBJECT +public: + ShowXForm( const QFont &f, QWidget *parent=0, const char *name=0 ); + ~ShowXForm() {} + void showIt(); // (Re)displays text or pixmap + + Mode mode() const { return m; } +public slots: + void setText( const QString& ); + void setMatrix( QWMatrix ); + void setFont( const QFont &f ); + void setPixmap( QPixmap ); + void setPicture( const QPicture& ); + void setMode( int ); +private: + QSizePolicy sizePolicy() const; + QSize sizeHint() const; + void paintEvent( QPaintEvent * ); + void resizeEvent( QResizeEvent * ); + QWMatrix mtx; // coordinate transform matrix + QString text; // text to be displayed + QPixmap pix; // pixmap to be displayed + QPicture picture; // text to be displayed + QRect eraseRect; // covers last displayed text/pixmap + Mode m; +}; + +XFormControl::XFormControl( const QFont &initialFont, + QWidget *parent, const char *name ) + : QVBox( parent, name ) +{ + setSpacing(6); + setMargin(6); + currentFont = initialFont; + mode = Image; + + rotLCD = new QLCDNumber( 4, this, "rotateLCD" ); + rotS = new QSlider( QSlider::Horizontal, this, + "rotateSlider" ); + shearLCD = new QLCDNumber( 5,this, "shearLCD" ); + shearS = new QSlider( QSlider::Horizontal, this, + "shearSlider" ); + mirror = new QCheckBox( this, "mirrorCheckBox" ); + rb_txt = new QRadioButton( this, "text" ); + rb_img = new QRadioButton( this, "image" ); + rb_pic = new QRadioButton( this, "picture" ); + optionals = new QWidgetStack(this); + QVBox* optionals_text = new QVBox(optionals); + optionals_text->setSpacing(6); + QVBox* optionals_other = new QVBox(optionals); + optionals_other->setSpacing(6); + optionals->addWidget(optionals_text,0); + optionals->addWidget(optionals_other,1); + fpb = new QPushButton( optionals_text, "text" ); + textEd = new QLineEdit( optionals_text, "text" ); + textEd->setFocus(); + + rotLCD->display( " 0'" ); + + rotS->setRange( -180, 180 ); + rotS->setValue( 0 ); + connect( rotS, SIGNAL(valueChanged(int)), SLOT(newMtx()) ); + + shearLCD->display( "0.00" ); + + shearS->setRange( -25, 25 ); + shearS->setValue( 0 ); + connect( shearS, SIGNAL(valueChanged(int)), SLOT(newMtx()) ); + + mirror->setText( tr("Mirror") ); + connect( mirror, SIGNAL(clicked()), SLOT(newMtx()) ); + + QButtonGroup *bg = new QButtonGroup(this); + bg->hide(); + bg->insert(rb_txt,0); + bg->insert(rb_img,1); + bg->insert(rb_pic,2); + rb_txt->setText( tr("Text") ); + rb_img->setText( tr("Image") ); + rb_img->setChecked(TRUE); + rb_pic->setText( tr("Picture") ); + connect( bg, SIGNAL(clicked(int)), SLOT(changeMode(int)) ); + + fpb->setText( tr("Select font...") ); + connect( fpb, SIGNAL(clicked()), SLOT(selectFont()) ); + + textEd->setText( "Troll" ); + connect( textEd, SIGNAL(textChanged(const QString&)), + SLOT(newTxt(const QString&)) ); + + magLCD = new QLCDNumber( 4,optionals_other, "magLCD" ); + magLCD->display( "100" ); + magS = new QSlider( QSlider::Horizontal, optionals_other, + "magnifySlider" ); + magS->setRange( 0, 800 ); + connect( magS, SIGNAL(valueChanged(int)), SLOT(newMtx()) ); + magS->setValue( 0 ); + connect( magS, SIGNAL(valueChanged(int)), magLCD, SLOT(display(int))); + + optionals_text->adjustSize(); + optionals_other->adjustSize(); + changeMode(Image); + + startTimer(20); // start an initial animation +} + +void XFormControl::timerEvent(QTimerEvent*) +{ + int v = magS->value(); + v = (v+2)+v/10; + if ( v >= 200 ) { + v = 200; + killTimers(); + } + magS->setValue(v); +} + + + +/* + Called whenever the user has changed one of the matrix parameters + (i.e. rotate, shear or magnification) +*/ +void XFormControl::newMtx() +{ + emit newMatrix( matrix() ); +} + +void XFormControl::newTxt(const QString& s) +{ + emit newText(s); + changeMode(Text); +} + +/* + Calculates the matrix appropriate for the current controls, + and updates the displays. +*/ +QWMatrix XFormControl::matrix() +{ + QWMatrix m; + if (mode != Text) { + double magVal = 1.0*magS->value()/100; + m.scale( magVal, magVal ); + } + double shearVal = 1.0*shearS->value()/25; + m.shear( shearVal, shearVal ); + m.rotate( rotS->value() ); + if ( mirror->isChecked() ) { + m.scale( 1, -1 ); + m.rotate( 180 ); + } + + QString tmp; + tmp.sprintf( "%1.2f", shearVal ); + if ( shearVal >= 0 ) + tmp.insert( 0, " " ); + shearLCD->display( tmp ); + + int rot = rotS->value(); + if ( rot < 0 ) + rot = rot + 360; + tmp.sprintf( "%3i'", rot ); + rotLCD->display( tmp ); + return m; +} + + +void XFormControl::selectFont() +{ + bool ok; + QFont f = QFontDialog::getFont( &ok, currentFont ); + if ( ok ) { + currentFont = f; + fontSelected( f ); + } +} + +void XFormControl::fontSelected( const QFont &font ) +{ + emit newFont( font ); + changeMode(Text); +} + +/* + Sets the mode - Text, Image, or Picture. +*/ + +void XFormControl::changeMode(int m) +{ + mode = (Mode)m; + + emit newMode( m ); + newMtx(); + if ( mode == Text ) { + optionals->raiseWidget(0); + rb_txt->setChecked(TRUE); + } else { + optionals->raiseWidget(1); + if ( mode == Image ) + rb_img->setChecked(TRUE); + else + rb_pic->setChecked(TRUE); + } + qApp->flushX(); +} + +ShowXForm::ShowXForm( const QFont &initialFont, + QWidget *parent, const char *name ) + : QWidget( parent, name, WResizeNoErase ) +{ + setFont( initialFont ); + setBackgroundColor( white ); + m = Text; + eraseRect = QRect( 0, 0, 0, 0 ); +} + +QSizePolicy ShowXForm::sizePolicy() const +{ + return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); +} + +QSize ShowXForm::sizeHint() const +{ + return QSize(400,400); +} + +void ShowXForm::paintEvent( QPaintEvent * ) +{ + showIt(); +} + +void ShowXForm::resizeEvent( QResizeEvent * ) +{ + eraseRect = QRect( width()/2, height()/2, 0, 0 ); + repaint(rect()); +} + +void ShowXForm::setText( const QString& s ) +{ + text = s; + showIt(); +} + +void ShowXForm::setMatrix( QWMatrix w ) +{ + mtx = w; + showIt(); +} + +void ShowXForm::setFont( const QFont &f ) +{ + m = Text; + QWidget::setFont( f ); +} + +void ShowXForm::setPixmap( QPixmap pm ) +{ + pix = pm; + m = Image; + showIt(); +} + +void ShowXForm::setPicture( const QPicture& p ) +{ + picture = p; + m = Picture; + showIt(); +} + +void ShowXForm::setMode( int mode ) +{ + m = (Mode)mode; +} + +void ShowXForm::showIt() +{ + QPainter p; + QRect r; // rectangle covering new text/pixmap in virtual coordinates + QWMatrix um; // copy user specified transform + int textYPos = 0; // distance from boundingRect y pos to baseline + int textXPos = 0; // distance from boundingRect x pos to text start + QRect br; + QFontMetrics fm( fontMetrics() ); // get widget font metrics + switch ( mode() ) { + case Text: + br = fm.boundingRect( text ); // rectangle covering text + r = br; + textYPos = -r.y(); + textXPos = -r.x(); + br.moveTopLeft( QPoint( -br.width()/2, -br.height()/2 ) ); + break; + case Image: + r = QRect(0, 0, pix.width()+1, pix.height()+1); + break; + case Picture: + // ### need QPicture::boundingRect() + r = QRect(0,0,1000,1000); + break; + } + r.moveTopLeft( QPoint(-r.width()/2, -r.height()/2) ); + r.moveBy( -1, -1 ); // add border for matrix round off + r.setSize( QSize( r.width() + 2,r.height() + 2 ) ); + // compute union of new and old rect + // the resulting rectangle will cover what is already displayed + // and have room for the new text/pixmap + eraseRect = eraseRect.unite( mtx.mapRect(r) ); + int pw = QMIN(eraseRect.width(),width()); + int ph = QMIN(eraseRect.height(),height()); + QPixmap pm( pw, ph ); // off-screen drawing pixmap + pm.fill( backgroundColor() ); + + p.begin( &pm ); + um.translate( pw/2, ph/2 ); // 0,0 is center + um = mtx * um; + p.setWorldMatrix( um ); + switch ( mode() ) { + case Text: + p.setFont( font() ); // use widget font + p.drawText( r.left() + textXPos, r.top() + textYPos, text ); +#if 0 + p.setPen( red ); + p.drawRect( br ); +#endif + break; + case Image: + p.drawPixmap( -pix.width()/2, -pix.height()/2, pix ); + break; + case Picture: + // ### need QPicture::boundingRect() + p.scale(0.25,0.25); + p.translate(-230,-180); + p.drawPicture( picture ); + } + p.end(); + + int xpos = width()/2 - pw/2; + int ypos = height()/2 - ph/2; + bitBlt( this, xpos, ypos, // copy pixmap to widget + &pm, 0, 0, -1, -1 ); + eraseRect = mtx.map( r ); +} + + +/* + Grand unifying widget, putting ShowXForm and XFormControl + together. +*/ + +class XFormCenter : public QHBox, public ModeNames +{ + Q_OBJECT +public: + XFormCenter( QWidget *parent=0, const char *name=0 ); +public slots: + void setFont( const QFont &f ) { sx->setFont( f ); } + void newMode( int ); +private: + ShowXForm *sx; + XFormControl *xc; +}; + +void XFormCenter::newMode( int m ) +{ + static bool first_i = TRUE; + static bool first_p = TRUE; + + if ( sx->mode() == m ) + return; + if ( m == Image && first_i ) { + first_i = FALSE; + QPixmap pm; + if ( pm.load( "image.any" ) ) + sx->setPixmap( pm ); + return; + } + if ( m == Picture && first_p ) { + first_p = FALSE; + QPicture p; + if (p.load( "picture.any" )) + sx->setPicture( p ); + return; + } + sx->setMode(m); +} + +XFormCenter::XFormCenter( QWidget *parent, const char *name ) + : QHBox( parent, name ) +{ + QFont f( "Charter", 36, QFont::Bold ); + + xc = new XFormControl( f, this ); + sx = new ShowXForm( f, this ); + setStretchFactor(sx,1); + xc->setFrameStyle( QFrame::Panel | QFrame::Raised ); + xc->setLineWidth( 2 ); + connect( xc, SIGNAL(newText(const QString&)), sx, + SLOT(setText(const QString&)) ); + connect( xc, SIGNAL(newMatrix(QWMatrix)), + sx, SLOT(setMatrix(QWMatrix)) ); + connect( xc, SIGNAL(newFont(const QFont&)), sx, + SLOT(setFont(const QFont&)) ); + connect( xc, SIGNAL(newMode(int)), SLOT(newMode(int)) ); + sx->setText( "Troll" ); + newMode( Image ); + sx->setMatrix(xc->matrix()); +} + + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + XFormCenter *xfc = new XFormCenter; + + a.setMainWidget( xfc ); + xfc->setCaption("Qt Example - XForm"); + xfc->show(); + return a.exec(); +} + +#include "xform.moc" // include metadata generated by the moc |