source: trunk/examples/xform/xform.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 13.0 KB
Line 
1/****************************************************************************
2** $Id: xform.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
5**
6** This file is part of an example program for Qt. This example
7** program may be used, distributed and modified without limitation.
8**
9*****************************************************************************/
10
11#include <qapplication.h>
12
13#include <qdialog.h>
14#include <qlabel.h>
15#include <qlineedit.h>
16#include <qpushbutton.h>
17#include <qcheckbox.h>
18#include <qradiobutton.h>
19#include <qbuttongroup.h>
20#include <qlcdnumber.h>
21#include <qslider.h>
22#include <qmenubar.h>
23#include <qfontdialog.h>
24#include <qlayout.h>
25#include <qvbox.h>
26#include <qwidgetstack.h>
27
28#include <qpainter.h>
29#include <qpixmap.h>
30#include <qpicture.h>
31
32#include <stdlib.h>
33
34
35class ModeNames {
36public:
37 enum Mode { Text, Image, Picture };
38};
39
40
41class XFormControl : public QVBox, public ModeNames
42{
43 Q_OBJECT
44public:
45 XFormControl( const QFont &initialFont, QWidget *parent=0, const char *name=0 );
46 ~XFormControl() {}
47
48 QWMatrix matrix();
49
50signals:
51 void newMatrix( QWMatrix );
52 void newText( const QString& );
53 void newFont( const QFont & );
54 void newMode( int );
55private slots:
56 void newMtx();
57 void newTxt(const QString&);
58 void selectFont();
59 void fontSelected( const QFont & );
60 void changeMode(int);
61 void timerEvent(QTimerEvent*);
62private:
63 Mode mode;
64 QSlider *rotS; // Rotation angle scroll bar
65 QSlider *shearS; // Shear value scroll bar
66 QSlider *magS; // Magnification value scroll bar
67 QLCDNumber *rotLCD; // Rotation angle LCD display
68 QLCDNumber *shearLCD; // Shear value LCD display
69 QLCDNumber *magLCD; // Magnification value LCD display
70 QCheckBox *mirror; // Checkbox for mirror image on/of
71 QWidgetStack* optionals;
72 QLineEdit *textEd; // Inp[ut field for xForm text
73 QPushButton *fpb; // Select font push button
74 QRadioButton *rb_txt; // Radio button for text
75 QRadioButton *rb_img; // Radio button for image
76 QRadioButton *rb_pic; // Radio button for picture
77 QFont currentFont;
78};
79
80/*
81 ShowXForm displays a text or a pixmap (QPixmap) using a coordinate
82 transformation matrix (QWMatrix)
83*/
84
85class ShowXForm : public QWidget, public ModeNames
86{
87 Q_OBJECT
88public:
89 ShowXForm( const QFont &f, QWidget *parent=0, const char *name=0 );
90 ~ShowXForm() {}
91 void showIt(); // (Re)displays text or pixmap
92
93 Mode mode() const { return m; }
94public slots:
95 void setText( const QString& );
96 void setMatrix( QWMatrix );
97 void setFont( const QFont &f );
98 void setPixmap( QPixmap );
99 void setPicture( const QPicture& );
100 void setMode( int );
101private:
102 QSizePolicy sizePolicy() const;
103 QSize sizeHint() const;
104 void paintEvent( QPaintEvent * );
105 void resizeEvent( QResizeEvent * );
106 QWMatrix mtx; // coordinate transform matrix
107 QString text; // text to be displayed
108 QPixmap pix; // pixmap to be displayed
109 QPicture picture; // text to be displayed
110 QRect eraseRect; // covers last displayed text/pixmap
111 Mode m;
112};
113
114XFormControl::XFormControl( const QFont &initialFont,
115 QWidget *parent, const char *name )
116 : QVBox( parent, name )
117{
118 setSpacing(6);
119 setMargin(6);
120 currentFont = initialFont;
121 mode = Image;
122
123 rotLCD = new QLCDNumber( 4, this, "rotateLCD" );
124 rotS = new QSlider( QSlider::Horizontal, this,
125 "rotateSlider" );
126 shearLCD = new QLCDNumber( 5,this, "shearLCD" );
127 shearS = new QSlider( QSlider::Horizontal, this,
128 "shearSlider" );
129 mirror = new QCheckBox( this, "mirrorCheckBox" );
130 rb_txt = new QRadioButton( this, "text" );
131 rb_img = new QRadioButton( this, "image" );
132 rb_pic = new QRadioButton( this, "picture" );
133 optionals = new QWidgetStack(this);
134 QVBox* optionals_text = new QVBox(optionals);
135 optionals_text->setSpacing(6);
136 QVBox* optionals_other = new QVBox(optionals);
137 optionals_other->setSpacing(6);
138 optionals->addWidget(optionals_text,0);
139 optionals->addWidget(optionals_other,1);
140 fpb = new QPushButton( optionals_text, "text" );
141 textEd = new QLineEdit( optionals_text, "text" );
142 textEd->setFocus();
143
144 rotLCD->display( " 0'" );
145
146 rotS->setRange( -180, 180 );
147 rotS->setValue( 0 );
148 connect( rotS, SIGNAL(valueChanged(int)), SLOT(newMtx()) );
149
150 shearLCD->display( "0.00" );
151
152 shearS->setRange( -25, 25 );
153 shearS->setValue( 0 );
154 connect( shearS, SIGNAL(valueChanged(int)), SLOT(newMtx()) );
155
156 mirror->setText( tr("Mirror") );
157 connect( mirror, SIGNAL(clicked()), SLOT(newMtx()) );
158
159 QButtonGroup *bg = new QButtonGroup(this);
160 bg->hide();
161 bg->insert(rb_txt,0);
162 bg->insert(rb_img,1);
163 bg->insert(rb_pic,2);
164 rb_txt->setText( tr("Text") );
165 rb_img->setText( tr("Image") );
166 rb_img->setChecked(TRUE);
167 rb_pic->setText( tr("Picture") );
168 connect( bg, SIGNAL(clicked(int)), SLOT(changeMode(int)) );
169
170 fpb->setText( tr("Select font...") );
171 connect( fpb, SIGNAL(clicked()), SLOT(selectFont()) );
172
173 textEd->setText( "Troll" );
174 connect( textEd, SIGNAL(textChanged(const QString&)),
175 SLOT(newTxt(const QString&)) );
176
177 magLCD = new QLCDNumber( 4,optionals_other, "magLCD" );
178 magLCD->display( "100" );
179 magS = new QSlider( QSlider::Horizontal, optionals_other,
180 "magnifySlider" );
181 magS->setRange( 0, 800 );
182 connect( magS, SIGNAL(valueChanged(int)), SLOT(newMtx()) );
183 magS->setValue( 0 );
184 connect( magS, SIGNAL(valueChanged(int)), magLCD, SLOT(display(int)));
185
186 optionals_text->adjustSize();
187 optionals_other->adjustSize();
188 changeMode(Image);
189
190 startTimer(20); // start an initial animation
191}
192
193void XFormControl::timerEvent(QTimerEvent*)
194{
195 int v = magS->value();
196 v = (v+2)+v/10;
197 if ( v >= 200 ) {
198 v = 200;
199 killTimers();
200 }
201 magS->setValue(v);
202}
203
204
205
206/*
207 Called whenever the user has changed one of the matrix parameters
208 (i.e. rotate, shear or magnification)
209*/
210void XFormControl::newMtx()
211{
212 emit newMatrix( matrix() );
213}
214
215void XFormControl::newTxt(const QString& s)
216{
217 emit newText(s);
218 changeMode(Text);
219}
220
221/*
222 Calculates the matrix appropriate for the current controls,
223 and updates the displays.
224*/
225QWMatrix XFormControl::matrix()
226{
227 QWMatrix m;
228 if (mode != Text) {
229 double magVal = 1.0*magS->value()/100;
230 m.scale( magVal, magVal );
231 }
232 double shearVal = 1.0*shearS->value()/25;
233 m.shear( shearVal, shearVal );
234 m.rotate( rotS->value() );
235 if ( mirror->isChecked() ) {
236 m.scale( 1, -1 );
237 m.rotate( 180 );
238 }
239
240 QString tmp;
241 tmp.sprintf( "%1.2f", shearVal );
242 if ( shearVal >= 0 )
243 tmp.insert( 0, " " );
244 shearLCD->display( tmp );
245
246 int rot = rotS->value();
247 if ( rot < 0 )
248 rot = rot + 360;
249 tmp.sprintf( "%3i'", rot );
250 rotLCD->display( tmp );
251 return m;
252}
253
254
255void XFormControl::selectFont()
256{
257 bool ok;
258 QFont f = QFontDialog::getFont( &ok, currentFont );
259 if ( ok ) {
260 currentFont = f;
261 fontSelected( f );
262 }
263}
264
265void XFormControl::fontSelected( const QFont &font )
266{
267 emit newFont( font );
268 changeMode(Text);
269}
270
271/*
272 Sets the mode - Text, Image, or Picture.
273*/
274
275void XFormControl::changeMode(int m)
276{
277 mode = (Mode)m;
278
279 emit newMode( m );
280 newMtx();
281 if ( mode == Text ) {
282 optionals->raiseWidget(0);
283 rb_txt->setChecked(TRUE);
284 } else {
285 optionals->raiseWidget(1);
286 if ( mode == Image )
287 rb_img->setChecked(TRUE);
288 else
289 rb_pic->setChecked(TRUE);
290 }
291 qApp->flushX();
292}
293
294ShowXForm::ShowXForm( const QFont &initialFont,
295 QWidget *parent, const char *name )
296 : QWidget( parent, name, WResizeNoErase )
297{
298 setFont( initialFont );
299 setBackgroundColor( white );
300 m = Text;
301 eraseRect = QRect( 0, 0, 0, 0 );
302}
303
304QSizePolicy ShowXForm::sizePolicy() const
305{
306 return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
307}
308
309QSize ShowXForm::sizeHint() const
310{
311 return QSize(400,400);
312}
313
314void ShowXForm::paintEvent( QPaintEvent * )
315{
316 showIt();
317}
318
319void ShowXForm::resizeEvent( QResizeEvent * )
320{
321 eraseRect = QRect( width()/2, height()/2, 0, 0 );
322 repaint(rect());
323}
324
325void ShowXForm::setText( const QString& s )
326{
327 text = s;
328 showIt();
329}
330
331void ShowXForm::setMatrix( QWMatrix w )
332{
333 mtx = w;
334 showIt();
335}
336
337void ShowXForm::setFont( const QFont &f )
338{
339 m = Text;
340 QWidget::setFont( f );
341}
342
343void ShowXForm::setPixmap( QPixmap pm )
344{
345 pix = pm;
346 m = Image;
347 showIt();
348}
349
350void ShowXForm::setPicture( const QPicture& p )
351{
352 picture = p;
353 m = Picture;
354 showIt();
355}
356
357void ShowXForm::setMode( int mode )
358{
359 m = (Mode)mode;
360}
361
362void ShowXForm::showIt()
363{
364 QPainter p;
365 QRect r; // rectangle covering new text/pixmap in virtual coordinates
366 QWMatrix um; // copy user specified transform
367 int textYPos = 0; // distance from boundingRect y pos to baseline
368 int textXPos = 0; // distance from boundingRect x pos to text start
369 QRect br;
370 QFontMetrics fm( fontMetrics() ); // get widget font metrics
371 switch ( mode() ) {
372 case Text:
373 br = fm.boundingRect( text ); // rectangle covering text
374 r = br;
375 textYPos = -r.y();
376 textXPos = -r.x();
377 br.moveTopLeft( QPoint( -br.width()/2, -br.height()/2 ) );
378 break;
379 case Image:
380 r = pix.rect();
381 break;
382 case Picture:
383 // ### need QPicture::boundingRect()
384 r = QRect(0,0,1000,1000);
385 break;
386 }
387 r.moveTopLeft( QPoint(-r.width()/2, -r.height()/2) );
388 // compute union of new and old rect
389 // the resulting rectangle will cover what is already displayed
390 // and have room for the new text/pixmap
391 eraseRect = eraseRect.unite( mtx.map(r) );
392 eraseRect.moveBy( -1, -1 ); // add border for matrix round off
393 eraseRect.setSize( QSize( eraseRect.width() + 2,eraseRect.height() + 2 ) );
394 int pw = QMIN(eraseRect.width(),width());
395 int ph = QMIN(eraseRect.height(),height());
396 QPixmap pm( pw, ph ); // off-screen drawing pixmap
397 pm.fill( backgroundColor() );
398
399 p.begin( &pm );
400 um.translate( pw/2, ph/2 ); // 0,0 is center
401 um = mtx * um;
402 p.setWorldMatrix( um );
403 switch ( mode() ) {
404 case Text:
405 p.setFont( font() ); // use widget font
406 p.drawText( r.left() + textXPos, r.top() + textYPos, text );
407#if 0
408 p.setPen( red );
409 p.drawRect( br );
410#endif
411 break;
412 case Image:
413 p.drawPixmap( -pix.width()/2, -pix.height()/2, pix );
414 //QPixmap rotated = pix.xForm(mtx);
415 //bitBlt( &pm, pm.width()/2 - rotated.width()/2,
416 //pm.height()/2 - rotated.height()/2, &rotated );
417 break;
418 case Picture:
419 // ### need QPicture::boundingRect()
420 p.scale(0.25,0.25);
421 p.translate(-230,-180);
422 p.drawPicture( picture );
423 }
424 p.end();
425
426 int xpos = width()/2 - pw/2;
427 int ypos = height()/2 - ph/2;
428 bitBlt( this, xpos, ypos, // copy pixmap to widget
429 &pm, 0, 0, -1, -1 );
430 eraseRect = mtx.map( r );
431}
432
433
434/*
435 Grand unifying widget, putting ShowXForm and XFormControl
436 together.
437*/
438
439class XFormCenter : public QHBox, public ModeNames
440{
441 Q_OBJECT
442public:
443 XFormCenter( QWidget *parent=0, const char *name=0 );
444public slots:
445 void setFont( const QFont &f ) { sx->setFont( f ); }
446 void newMode( int );
447private:
448 ShowXForm *sx;
449 XFormControl *xc;
450};
451
452void XFormCenter::newMode( int m )
453{
454 static bool first_i = TRUE;
455 static bool first_p = TRUE;
456
457 if ( sx->mode() == m )
458 return;
459 if ( m == Image && first_i ) {
460 first_i = FALSE;
461 QPixmap pm;
462 if ( pm.load( "image.any" ) )
463 sx->setPixmap( pm );
464 return;
465 }
466 if ( m == Picture && first_p ) {
467 first_p = FALSE;
468 QPicture p;
469 if (p.load( "picture.any" ))
470 sx->setPicture( p );
471 return;
472 }
473 sx->setMode(m);
474}
475
476XFormCenter::XFormCenter( QWidget *parent, const char *name )
477 : QHBox( parent, name )
478{
479 QFont f( "Charter", 36, QFont::Bold );
480
481 xc = new XFormControl( f, this );
482 sx = new ShowXForm( f, this );
483 setStretchFactor(sx,1);
484 xc->setFrameStyle( QFrame::Panel | QFrame::Raised );
485 xc->setLineWidth( 2 );
486 connect( xc, SIGNAL(newText(const QString&)), sx,
487 SLOT(setText(const QString&)) );
488 connect( xc, SIGNAL(newMatrix(QWMatrix)),
489 sx, SLOT(setMatrix(QWMatrix)) );
490 connect( xc, SIGNAL(newFont(const QFont&)), sx,
491 SLOT(setFont(const QFont&)) );
492 connect( xc, SIGNAL(newMode(int)), SLOT(newMode(int)) );
493 sx->setText( "Troll" );
494 newMode( Image );
495 sx->setMatrix(xc->matrix());
496}
497
498
499int main( int argc, char **argv )
500{
501 QApplication a( argc, argv );
502
503 XFormCenter *xfc = new XFormCenter;
504
505 a.setMainWidget( xfc );
506 xfc->setCaption("Qt Example - XForm");
507 xfc->show();
508 return a.exec();
509}
510
511#include "xform.moc" // include metadata generated by the moc
Note: See TracBrowser for help on using the repository browser.