/**************************************************************************** ** $Id: xform.cpp,v 2.9.2.1 1998/10/05 13:28:02 warwick Exp $ ** ** Copyright (C) 1992-1998 Troll Tech AS. 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 <qpainter.h> #include <qpixmap.h> #include <stdlib.h> class FontSelect; class XFormControl : public QFrame { Q_OBJECT public: XFormControl( QWidget *parent=0, const char *name=0 ); ~XFormControl() {} signals: void newMatrix( QWMatrix ); void newText( const char * ); void newFont( const QFont & ); void newMode( bool image ); private slots: void newMtx(); void selectFont(); void selectFontDestroyed(); void fontSelected( const QFont & ); void toggleMode(); private: 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 QLineEdit *textEd; // Inp[ut field for xForm text QPushButton *f; // Select font push button QCheckBox *imgCheckBox; // Check box for image on/off FontSelect *fs; // font select dialog box bool fsUp; // TRUE if font select is visible }; /* ShowXForm displays a text or a pixmap (QPixmap) using a coordinate transformation matrix (QWMatrix) */ class ShowXForm : public QWidget { Q_OBJECT public: ShowXForm( QWidget *parent=0, const char *name=0 ); ~ShowXForm() {} void showIt(); // (Re)displays text or pixmap bool pixmapMode() const { return usingPixmap; } public slots: void setText( const char* ); void setMatrix( QWMatrix ); void setFont( const QFont &f ); void setPixmap( QPixmap ); void setPixmapMode( bool b ); private: void paintEvent( QPaintEvent * ); void resizeEvent( QResizeEvent * ); QString text; // text to be displayed QWMatrix mtx; // coordinate transform matrix QPixmap pix; // pixmap to be displayed bool usingPixmap; // TRUE if pix is being displayed QRect eraseRect; // covers last displayed text/pixmap }; class FontSelect : public QDialog { Q_OBJECT public: FontSelect( QWidget *parent=0, const char *name=0 ); private slots: void newStrikeOut(); void doFont(); void newUnderline(); void newItalic(); void newWeight( int id ); void newFamily(); void newSize( int ); void slidingSize( int ); void doApply(); void familyActivated( int ); void pSizeActivated( int ); signals: void newFont( const QFont & ); protected: void updateMetrics(); private: QLabel *familyL; QLabel *sizeL; QLineEdit *family; QLineEdit *sizeE; QCheckBox *italic; QCheckBox *underline; QCheckBox *strikeOut; QPushButton *apply; QPushButton *stat; QSlider *sizeS; QRadioButton *rb[5]; QButtonGroup *weight; QGroupBox *mGroup; QFont f; QMenuBar *menu; QLabel *metrics[4][2]; QWidget *fontInternal; }; XFormControl::XFormControl( QWidget *parent, const char *name ) : QFrame( parent, name ) { 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" ); textEd = new QLineEdit( this, "text" ); f = new QPushButton( this, "text" ); imgCheckBox = new QCheckBox( this, "fontOrImage" ); rotLCD->setGeometry( 10, 10, 100, 60 ); rotLCD->display( " 0'" ); rotS->setGeometry( 10, 80, 100, 15 ); rotS->setRange( -180, 180 ); rotS->setValue( 0 ); connect( rotS, SIGNAL(valueChanged(int)), SLOT(newMtx()) ); shearLCD->setGeometry( 10, 105, 100, 60 ); shearLCD->display( "0.00" ); shearS->setGeometry( 10, 175, 100, 15 ); shearS->setRange( -25, 25 ); shearS->setValue( 0 ); connect( shearS, SIGNAL(valueChanged(int)), SLOT(newMtx()) ); mirror->setGeometry( 10, 200, 100, 15 ); mirror->setText( "Mirror" ); connect( mirror, SIGNAL(clicked()), SLOT(newMtx()) ); imgCheckBox->setGeometry( 10, 220, 100, 15 ); imgCheckBox->setText( "Image" ); connect( imgCheckBox, SIGNAL(clicked()), SLOT(toggleMode()) ); textEd->setGeometry( 10, 245, 100, 20 ); textEd->setText( "Troll" ); connect( textEd, SIGNAL(textChanged(const char*)), SIGNAL(newText(const char*)) ); f->setGeometry( 10, 275, 100, 20 ); f->setText( "Select font..." ); connect( f, SIGNAL(clicked()), SLOT(selectFont()) ); magS = 0; fs = 0; } /* Called whenever the user has changed one of the matrix parameters (i.e. rotate, shear or magnification) */ void XFormControl::newMtx() { QWMatrix m; if ( imgCheckBox->isChecked() ) { 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 ); emit newMatrix( m ); } void XFormControl::selectFont() { if (!fs) { fs = new FontSelect; connect( fs, SIGNAL(destroyed()), SLOT(selectFontDestroyed()) ); connect( fs, SIGNAL(newFont(const QFont&)), SLOT(fontSelected(const QFont&)) ); fs->setGeometry( QRect( 100, 200, 380, 260 ) ); fsUp = FALSE; } fsUp = !fsUp; if ( fsUp ) fs->show(); else fs->hide(); } /* Called when the user has closed the SelectFont dialog via the window manager. */ void XFormControl::selectFontDestroyed() { fs = 0; } void XFormControl::fontSelected( const QFont &font ) { imgCheckBox->setChecked( FALSE ); emit newFont( font ); toggleMode(); } /* Toggles between image and text mode. */ void XFormControl::toggleMode() { if ( magS == 0 ) { magS = new QSlider( QSlider::Horizontal, this, "magnifySlider" ); magS->setGeometry( 10, 375, 100, 15 ); magS->setRange( 0, 400 ); magS->setValue( 100 ); connect( magS, SIGNAL(valueChanged(int)), SLOT(newMtx()) ); magLCD = new QLCDNumber( 4,this, "shearLCD" ); magLCD->setGeometry( 10, 305, 100, 60 ); magLCD->display( "100" ); connect( magS, SIGNAL(valueChanged(int)), magLCD, SLOT(display(int))); } emit newMode( imgCheckBox->isChecked() ); newMtx(); if ( imgCheckBox->isChecked() ) { magS->show(); magLCD->show(); } else { magS->hide(); magLCD->hide(); } qApp->flushX(); } const int yOff = 35; ShowXForm::ShowXForm( QWidget *parent, const char *name ) : QWidget( parent, name ) { setFont( QFont( "Charter", 48, QFont::Bold ) ); setBackgroundColor( white ); usingPixmap = FALSE; eraseRect = QRect( 0, 0, 0, 0 ); } void ShowXForm::paintEvent( QPaintEvent * ) { showIt(); } void ShowXForm::resizeEvent( QResizeEvent * ) { eraseRect = QRect( width()/2, height()/2, 0, 0 ); } void ShowXForm::setText( const char *s ) { text = s; showIt(); } void ShowXForm::setMatrix( QWMatrix w ) { mtx = w; showIt(); } void ShowXForm::setFont( const QFont &f ) { usingPixmap = FALSE; QWidget::setFont( f ); } void ShowXForm::setPixmap( QPixmap pm ) { pix = pm; usingPixmap = TRUE; showIt(); } void ShowXForm::setPixmapMode( bool enable ) { usingPixmap = enable; } void ShowXForm::showIt() { QPainter p; QRect r; // rectangle covering new text/pixmap in virtual coordinates QWMatrix m; // 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 if ( pixmapMode() ) { r = pix.rect(); } else { br = fm.boundingRect( text ); // rectangle covering text r = br; textYPos = -r.y(); textXPos = -r.x(); br.moveTopLeft( QPoint( -br.width()/2, -br.height()/2 ) ); } r.moveTopLeft( QPoint(-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.map(r) ); eraseRect.moveBy( -1, -1 ); // add border for matrix round off eraseRect.setSize( QSize( eraseRect.width() + 2,eraseRect.height() + 2 ) ); 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 ); m.translate( pw/2, ph/2 ); // 0,0 is center m = mtx * m; p.setWorldMatrix( m ); if ( pixmapMode() ) { p.drawPixmap( -pix.width()/2, -pix.height()/2, pix ); } else { p.setFont( font() ); // use widget font p.drawText( r.left() + textXPos, r.top() + textYPos, text ); } #if 0 p.setPen( red ); p.drawRect( br ); #endif 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 ); } FontSelect::FontSelect( QWidget *parent, const char *name) : QDialog( parent, name, 0 ), f( "Charter", 48, QFont::Bold ) { static const char *radios[] = { "Light (25)", "Normal (50)", "DemiBold (63)", "Bold (75)", "Black (87)" }; int i; fontInternal = new QWidget( this ); fontInternal->setFont( f ); fontInternal->hide(); familyL = new QLabel( this, "familyLabel" ); sizeL = new QLabel( this, "sizeLabel" ); family = new QLineEdit( this, "family" ); sizeE = new QLineEdit( this, "pointSize" ); italic = new QCheckBox( this, "italic" ); underline = new QCheckBox( this, "underline" ); strikeOut = new QCheckBox( this, "strikeOut" ); apply = new QPushButton( this, "apply" ); sizeS = new QSlider( QSlider::Horizontal, this, "pointSizeSlider" ); familyL->setGeometry( 10, yOff + 10, 100,20 ); familyL->setText( "Family :" ); sizeL->setGeometry( 10, yOff + 40, 100, 20 ); sizeL->setText( "Point size :" ); family->setGeometry( 110, yOff + 10, 100, 20 ); family->setText( "Charter" ); sizeE->setGeometry( 110, yOff + 40, 100, 20 ); sizeE->setText( "48" ); sizeS->setGeometry( 220, yOff + 40, 100, 20 ); sizeS->setRange( 1, 100 ); sizeS->setValue( 48 ); sizeS->setTracking( FALSE ); connect( sizeS, SIGNAL(valueChanged(int)), SLOT(newSize(int)) ); connect( sizeS, SIGNAL(sliderMoved(int)), SLOT(slidingSize(int)) ); italic->setGeometry( 10, yOff + 70, 80, 20 ); italic->setText( "Italic" ); connect( italic, SIGNAL(clicked()), SLOT(newItalic()) ); underline->setGeometry( 110, yOff + 70, 80, 20 ); underline->setText( "Underline" ); connect( underline, SIGNAL(clicked()), SLOT(newUnderline()) ); strikeOut->setGeometry( 210, yOff + 70, 80, 20 ); strikeOut->setText( "StrikeOut" ); connect( strikeOut, SIGNAL(clicked()), SLOT(newStrikeOut()) ); apply->setGeometry( 235, yOff + 10, 70, 20); apply->setText( "APPLY" ); apply->setDefault( TRUE ); connect( apply, SIGNAL(clicked()), SLOT(doApply()) ); weight = new QButtonGroup( "Weight", this, "weightGroupBox" ); weight->setGeometry( 10, yOff + 100, 120, 120 ); connect( weight, SIGNAL(clicked(int)), SLOT(newWeight(int)) ); QString wname; for( i = 0 ; i < 5 ; i++ ) { wname.sprintf("radioButton %i",i); rb[i] = new QRadioButton( weight, wname ); rb[i]->setGeometry( 10, 15+i*20 , 95, 20 ); rb[i]->setText( radios[i] ); } rb[3]->setChecked( TRUE ); #ifdef _OS_WIN32_ static const char *families[] = { "Arial", "Book Antiqua", "Bookman", "Century Schoolbook", "Comic Sans MS", "Courier New", "Garamond", "Haettenschweiler", "Impact", "Symbol", "Times New Roman", "Verdana", "WingDings", 0 }; #else static const char *families[] = { "Charter", "Clean", "Courier", "Fixed", "Gothic", "Helvetica", "Lucida", "Lucidabright", "Lucidatypewriter", "Mincho", "New century schoolbook", "Symbol", "Terminal", "Times", "Utopia", 0 }; #endif // _OS_WIN32_ static const char *pSizes[] = { "8", "10", "12", "14", "18", "24", "36", "48", "72", "96", 0 }; QPopupMenu *familyPopup = new QPopupMenu; const char **tmp; tmp = families; while( *tmp ) familyPopup->insertItem( *tmp++ ); QPopupMenu *pSize = new QPopupMenu; tmp = pSizes; while( *tmp ) pSize->insertItem( *tmp++ ); menu = new QMenuBar( this ); menu->move( 0, 0 ); menu->resize( 350, 30 ); menu->insertItem( "Family", familyPopup ); menu->insertItem( "Point size", pSize ); connect( familyPopup, SIGNAL(activated(int)), SLOT(familyActivated(int)) ); connect( pSize, SIGNAL(activated(int)), SLOT(pSizeActivated(int)) ); static const char *mLabelStr[] = { "Family:", "Point size:", "Weight:", "Italic:" }; mGroup = new QButtonGroup( this, "metricsGroupBox" ); mGroup->setTitle( "Actual font" ); mGroup->setGeometry(140, yOff + 100, 230, 100); for( i = 0 ; i < 4 ; i++ ) { wname.sprintf("MetricsLabel[%i][%i]",i,0); metrics[i][0] = new QLabel( mGroup, wname); metrics[i][0]->setGeometry(10, 15 + 20*i, 70, 20); metrics[i][0]->setText( mLabelStr[i] ); wname.sprintf("MetricsLabel[%i][%i]",i,1); metrics[i][1] = new QLabel( mGroup, wname); metrics[i][1]->setGeometry(90, 15 + 20*i, 135, 20); } updateMetrics(); } void FontSelect::newStrikeOut() { f.setStrikeOut( strikeOut->isChecked() ); doFont(); } void FontSelect::doFont() { QFont xyz = f; xyz.setPointSize( f.pointSize()+1 ); xyz.setPointSize( f.pointSize() ); fontInternal->setFont( xyz ); updateMetrics(); } void FontSelect::newUnderline() { f.setUnderline( underline->isChecked() ); doFont(); } void FontSelect::newItalic() { f.setItalic( italic->isChecked() ); doFont(); } void FontSelect::newFamily() { f.setFamily( family->text() ); doFont(); } void FontSelect::newWeight( int id ) { switch( id ) { case 0 : f.setWeight( QFont::Light ); break; case 1 : f.setWeight( QFont::Normal ); break; case 2 : f.setWeight( QFont::DemiBold ); break; case 3 : f.setWeight( QFont::Bold ); break; case 4 : f.setWeight( QFont::Black ); break; default: return; } doFont(); } void FontSelect::newSize( int value ) { QString tmp; tmp.sprintf("%i", value); sizeE->setText( tmp ); f.setPointSize( value ); doFont(); } void FontSelect::slidingSize( int value ) { QString tmp; tmp.sprintf("%i", value); sizeE->setText( tmp ); } void FontSelect::doApply() { int sz = atoi( sizeE->text() ); if ( sz > 100) { sizeS->blockSignals( TRUE ); sizeS->setValue( 100 ); sizeS->blockSignals( FALSE ); f.setPointSize( sz ); } else { sizeS->setValue( atoi( sizeE->text() ) ); } f.setFamily( family->text() ); doFont(); emit newFont( fontInternal->font() ); } void FontSelect::familyActivated( int id ) { family->setText( ((QPopupMenu*)sender())->text(id) ); newFamily(); } void FontSelect::pSizeActivated( int id ) { int value = atoi( ( (QPopupMenu*)sender())->text( id ) ); sizeS->blockSignals( TRUE ); sizeS->setValue( value ); sizeS->blockSignals( FALSE ); newSize( value ); } void FontSelect::updateMetrics() { QFontInfo fi = fontInternal->fontInfo(); metrics[0][1]->setText( fi.family() ); metrics[1][1]->setNum( fi.pointSize() ); metrics[2][1]->setNum( fi.weight() ); metrics[3][1]->setNum( (int)fi.italic() ); } /* Grand unifying widget, putting ShowXForm and XFormControl together. */ class XFormCenter : public QWidget { Q_OBJECT public: XFormCenter( QWidget *parent=0, const char *name=0 ); public slots: void setFont( const QFont &f ) { sx->setFont( f ); } void newMode( bool ); private: void resizeEvent( QResizeEvent* ); ShowXForm *sx; XFormControl *xc; }; void XFormCenter::resizeEvent( QResizeEvent* ) { sx->resize( width() - 120, height() ); xc->resize( 120, height() ); } void XFormCenter::newMode( bool showPix ) { static bool first = TRUE; if ( sx->pixmapMode() == showPix ) return; if ( showPix && first ) { first = FALSE; QPixmap pm; pm.load( "image.any" ); sx->setPixmap( pm ); return; } sx->setPixmapMode( showPix ); } XFormCenter::XFormCenter( QWidget *parent, const char *name ) : QWidget( parent, name ) { sx = new ShowXForm(this); sx->move( 120, 0 ); // the size is set by resizeEvent xc = new XFormControl(this); xc->move( 0, 0 ); // the size is set by resizeEvent xc->setFrameStyle( QFrame::Box | QFrame::Sunken ); xc->setLineWidth( 2 ); connect( xc, SIGNAL(newText(const char*)), sx, SLOT(setText(const char*)) ); connect( xc, SIGNAL(newMatrix(QWMatrix)), sx, SLOT(setMatrix(QWMatrix)) ); connect( xc, SIGNAL(newFont(const QFont&)), sx, SLOT(setFont(const QFont&)) ); connect( xc, SIGNAL(newMode(bool)), SLOT(newMode(bool)) ); sx->setText( "Troll" ); } int main( int argc, char **argv ) { QApplication a( argc, argv ); #if 0 QColor x( 0xaa, 0xbe, 0xff ); // kind of blue QColorGroup g( black, x, x.light(), x.dark(), x.dark(120), black, white ); QPalette p( g, g, g ); a.setPalette( p ); #endif XFormCenter *xfc = new XFormCenter; xfc->setGeometry( 0, 0, 500, 400 ); a.setMainWidget( xfc ); xfc->show(); return a.exec(); } #include "xform.moc" // include metadata generated by the moc
Copyright © 1998 Troll Tech | Trademarks | Qt version 1.42
|