⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 penwidget.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 CPP
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS.  All rights reserved.**** This file is part of the Qtopia Environment.** ** 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.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include <qapplication.h>#include <qinputdialog.h>#include <qpainter.h>#include <qfile.h>#include <qdatastream.h>#include <qtimer.h>#include <qtopia/mstroke/char.h>#include "penwidget.h"#define TITLE_WIDTH	30  // ### magic/*!  \class QIMPenWidget qimpenwidget.h  \brief The QIMPenWidget class provides an character input panel.  Draws characters and allows input of characters.*/QIMPenWidget::QIMPenWidget( QWidget *parent ) : QWidget( parent ){    charSets.setAutoDelete( TRUE );    inputStroke = 0;    outputChar = 0;    outputStroke = 0;    mode = Waiting;    currCharSet = 0;    readOnly = FALSE;    strokes.setAutoDelete( TRUE );    timer = new QTimer(this);    connect( timer, SIGNAL(timeout()), SLOT(timeout()));    setBackgroundColor( qApp->palette().color( QPalette::Active,                                               QColorGroup::Base ) );    strokeColor = black;    setFixedHeight( 75 );}void QIMPenWidget::clear(){    timer->stop();    mode = Waiting;    QRect r( dirtyRect );    QIMPenStrokeIterator it( strokes );    while ( it.current() ) {	r |= it.current()->boundingRect();	++it;    }    outputChar = 0;    outputStroke = 0;    strokes.clear();    if ( !r.isNull() ) {	r.moveBy( -2, -2 );	r.setSize( r.size() + QSize( 4, 4 ) );	repaint( r );    } else {	repaint();    }}void QIMPenWidget::removeStroke(){    QRect r( dirtyRect );    QIMPenStroke *st = strokes.getFirst();    QRect strokeRect;    if ( st )       strokeRect = st->boundingRect();    r |= strokeRect;    strokes.removeFirst();    if ( !r.isNull() ) {	r.moveBy( -2, -2 );	r.setSize( r.size() + QSize( 4, 4 ) );	repaint( r );    }}void QIMPenWidget::greyStroke(){    QRect r( dirtyRect );    QIMPenStroke *st = strokes.getLast();    QRect strokeRect;    if ( st )       strokeRect = st->boundingRect();    r |= strokeRect;    QColor oldCol = strokeColor;    strokeColor = gray;    if ( !r.isNull() ) {	r.moveBy( -2, -2 );	r.setSize( r.size() + QSize( 4, 4 ) );	repaint( r );    }    strokeColor = oldCol;}/*  Insert a character set into the list.*/void QIMPenWidget::insertCharSet( QIMPenCharSet *cs, int stretch, int pos ){    CharSetEntry *e = new CharSetEntry;    e->cs = cs;    e->stretch = stretch;    if ( pos < 0 )	pos = charSets.count();    charSets.insert( pos, e );    currCharSet = 0;    emit changeCharSet( currCharSet );    emit changeCharSet( charSets.at(currCharSet)->cs );    totalStretch = 0;    CharSetEntryIterator it( charSets );    for ( ; it.current(); ++it )	totalStretch += it.current()->stretch;    update();}/*  Remove a character set from the list.*/void QIMPenWidget::removeCharSet( int pos ){    if ( pos >= 0 && pos < (int)charSets.count() ) {	charSets.remove( pos );	currCharSet = 0;	if ( charSets.count() ) {	    emit changeCharSet( currCharSet );	    emit changeCharSet( charSets.at(currCharSet)->cs );	}	totalStretch = 0;	CharSetEntryIterator it( charSets );	for ( ; it.current(); ++it )	    totalStretch += it.current()->stretch;	update();    }}void QIMPenWidget::changeCharSet( QIMPenCharSet *cs, int pos ){    if ( pos >= 0 && pos < (int)charSets.count() ) {	CharSetEntry *e = new CharSetEntry;	e->cs = cs;	e->stretch = charSets.at(pos)->stretch;	charSets.remove( pos );	charSets.insert( pos, e );	if ( pos == currCharSet ) {	    emit changeCharSet( charSets.at(currCharSet)->cs );	}	update();    }}void QIMPenWidget::clearCharSets(){    charSets.clear();    currCharSet = 0;    update();}/*  Display a character. \a speed determines how quickly the character is  drawn.*/void QIMPenWidget::showCharacter( QIMPenChar *ch, int speed ){    outputChar = 0;    outputStroke = 0;    strokes.clear();    mode = Output;    repaint();    if ( !ch || ch->isEmpty() ) {        mode = Waiting;        return;    }    outputChar = ch;    outputStroke = outputChar->penStrokes().getFirst();    if ( speed < 0 ) speed = 0;    if ( speed > 20 ) speed = 20;    speed = 50 - speed;    pointIndex = 0;    strokeIndex = 0;    lastPoint = outputStroke->startingPoint();    QRect br( outputChar->boundingRect() );    lastPoint.setX( (width() - br.width()) / 2 + (lastPoint.x () - br.left()) );    QPoint offset = lastPoint - outputStroke->startingPoint();    br.moveBy( offset.x(), offset.y() );    dirtyRect |= br;    timer->start( speed );}/*!  Handle drawing/clearing of characters.*/void QIMPenWidget::timeout(){    if ( mode == Output ) {        const QArray<QIMPenGlyphLink> &chain = outputStroke->chain();        if ( pointIndex < chain.count() ) {            QPainter paint( this );            paint.setBrush( Qt::black );            for ( unsigned i = 0; i < 3 && pointIndex < chain.count(); i++ ) {                lastPoint.rx() += chain[(int)pointIndex].dx;                lastPoint.ry() += chain[(int)pointIndex].dy;                pointIndex++;                paint.drawRect( lastPoint.x()-1, lastPoint.y()-1, 2, 2 );            }        }        if ( pointIndex >= chain.count() ) {            QIMPenStrokeList strokes = outputChar->penStrokes();            if ( strokeIndex < (int)strokes.count() - 1 ) {                pointIndex = 0;                strokeIndex++;                outputStroke = strokes.at( strokeIndex );                lastPoint = outputChar->startingPoint();                QRect br( outputChar->boundingRect() );                lastPoint.setX( (width() - br.width()) / 2                                + (lastPoint.x () - br.left()) );                QPoint off = lastPoint - outputChar->startingPoint();                lastPoint = outputStroke->startingPoint() + off;            } else {                timer->stop();                mode = Waiting;            }        }    } else if ( mode == Waiting ) {	QRect r( dirtyRect );	if ( !r.isNull() ) {	    r.moveBy( -2, -2 );	    r.setSize( r.size() + QSize( 4, 4 ) );	    repaint( r );	}    }}/*!  If the point \a p is over one of the character set titles, switch  to the set and return TRUE.*/bool QIMPenWidget::selectSet( QPoint p ){    if ( charSets.count() ) {	CharSetEntryIterator it( charSets );	int spos = 0;	int idx = 0;	for ( ; it.current(); ++it, idx++ ) {	    int setWidth = width() * it.current()->stretch / totalStretch;	    spos += setWidth;	    if ( p.x() < spos ) {		if ( idx != currCharSet ) {		    currCharSet = idx;		    update( 0, 0, width(), 12 );		    emit changeCharSet( currCharSet );		    emit changeCharSet( charSets.at(currCharSet)->cs );		}		break;	    }	}    }    return FALSE;}/*!  Hopefully returns a sensible size.*/QSize QIMPenWidget::sizeHint(){    return QSize( TITLE_WIDTH * charSets.count(), 75 );}void QIMPenWidget::mousePressEvent( QMouseEvent *e ){    if ( !readOnly && e->button() == LeftButton && mode == Waiting ) {        // if selectSet returns false the click was not over the        // char set selectors.        if ( !selectSet( e->pos() ) ) {            // start of character input            timer->stop();            if ( outputChar ) {                outputChar = 0;                outputStroke = 0;                repaint();            }            mode = Input;            lastPoint = e->pos();            emit beginStroke();            inputStroke = new QIMPenStroke;            strokes.append( inputStroke );            inputStroke->beginInput( e->pos() );            QPainter paint( this );            paint.setBrush( Qt::black );            paint.drawRect( lastPoint.x()-1, lastPoint.y()-1, 2, 2 );        }    }}void QIMPenWidget::mouseReleaseEvent( QMouseEvent *e ){    if ( !readOnly && e->button() == LeftButton && mode == Input ) {        mode = Waiting;        inputStroke->endInput();        if ( charSets.count() )            emit stroke( inputStroke );	inputStroke = 0;    }}void QIMPenWidget::mouseMoveEvent( QMouseEvent *e ){    if ( !readOnly && mode == Input ) {        int dx = QABS( e->pos().x() - lastPoint.x() );        int dy = QABS( e->pos().y() - lastPoint.y() );        if ( dx + dy > 1 ) {            if ( inputStroke->addPoint( e->pos() ) ) {		QPainter paint( this );		paint.setPen( Qt::black );		paint.setBrush( Qt::black );		const QArray<QIMPenGlyphLink> &chain = inputStroke->chain();		QPoint p( e->pos() );		for ( int i = (int)chain.count()-1; i >= 0; i-- ) {		    paint.drawRect( p.x()-1, p.y()-1, 2, 2 );		    p.rx() -= chain[i].dx;		    p.ry() -= chain[i].dy;		    if ( p == lastPoint )			break;		}		/* ### use this when thick lines work properly on all devices		paint.setPen( QPen( Qt::black, 2 ) );		paint.drawLine( lastPoint, e->pos() );		*/	    }	    lastPoint = e->pos();        }    }}void QIMPenWidget::paintEvent( QPaintEvent * ){    QPainter paint( this );    // draw guidelines    paint.setPen( Qt::gray );    paint.drawLine( 0, 0, width(), 0 );    int y = height() / 3;    paint.drawLine( 0, y, width(), y );    y *= 2;    paint.setPen( blue );    paint.drawLine( 0, y, width(), y );    paint.setPen( Qt::gray );    if ( !charSets.count() )	return;    // draw the character set titles    QFont selFont( "helvetica", 8, QFont::Bold ); // no tr    QFont font( "helvetica", 8 ); // no tr    CharSetEntryIterator it( charSets );    int spos = 0;    for ( ; it.current(); ++it ) {	int setWidth = width() * it.current()->stretch / totalStretch;        spos += setWidth;	if ( it.current() != charSets.getLast() ) {	    paint.drawLine( spos, 0, spos, 5 );	    paint.drawLine( spos, height()-1, spos, height()-6 );	}	paint.setFont( font );	int w = paint.fontMetrics().width( it.current()->cs->title() );        int tpos = spos - setWidth / 2;        paint.drawText( tpos - w/2, 0, w, 12, QPainter::AlignCenter,                        it.current()->cs->title() );    }    // draw any character that should be displayed when repainted.    QPoint off;    const QIMPenStrokeList *stk = 0;    if ( outputChar && mode == Waiting ) {        stk = &outputChar->penStrokes();        QPoint p( outputChar->startingPoint() );        QRect br( outputChar->boundingRect() );        p.setX( (width() - br.width()) / 2 + (p.x () - br.left()) );        off = p - outputChar->startingPoint();    } else if ( mode == Waiting ) {        stk = &strokes;	strokeColor = gray;    }    if ( stk && !stk->isEmpty() ) {        paint.setPen( strokeColor );        paint.setBrush( strokeColor );        QIMPenStrokeIterator it( *stk );        while ( it.current() ) {            QPoint p = it.current()->startingPoint() + off;            paint.drawRect( p.x()-1, p.y()-1, 2, 2 );            const QArray<QIMPenGlyphLink> &chain = it.current()->chain();            for ( int i = 0; i < (int)chain.count(); i++ ) {                    p.rx() += chain[i].dx;                    p.ry() += chain[i].dy;                    paint.drawRect( p.x()-1, p.y()-1, 2, 2 );            }            ++it;	    if ( it.atLast() && mode == Waiting )		strokeColor = black;        }    }    dirtyRect = QRect();    // debug/*    if ( input ) {        QArray<int> sig = input->sig();        for ( unsigned i = 0; i < sig.count(); i++ ) {            paint.drawPoint( 200 + i, height()/2 - sig[i] / 8 );        }    }*/}void QIMPenWidget::resizeEvent( QResizeEvent *e ){    if ( mode == Output )	showCharacter( outputChar, 0 );    QWidget::resizeEvent( e );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -