📄 regionselector.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 "regionselector.h"#include "imageui.h"#include <qtopia/global.h>#include <qtopia/resource.h>#include <qtopia/contextbar.h>#include <qaction.h>#include <qpainter.h>#include <qbrush.h>#include <qregion.h>RegionSelector::RegionSelector( ImageUI* iui, const char* name, WFlags f ) : QWidget( iui, name, f | Qt::WResizeNoErase | Qt::WRepaintNoErase ), image_ui( iui ), enabled( false ){#ifdef QTOPIA_PHONE if( Global::mousePreferred() ) {#endif current_state = MARK;#ifdef QTOPIA_PHONE } else current_state = MOVE;#endif // Update display when image ui updated connect( image_ui, SIGNAL( updated() ), this, SLOT( update() ) );}QRect RegionSelector::region() const{ if( !_region.isNull() && _region.left() != _region.right() && _region.top() != _region.bottom() && !image_ui->region().intersect( _region ).isEmpty() ) return _region.normalize(); return QRect();}void RegionSelector::setEnabled( bool b ){ enabled = b; #ifdef QTOPIA_PHONE // If selection enabled, add labels to context bar // Otherwise, remove labels from context bar if( enabled ) { if( Global::mousePreferred() ) { // Disable context menu ContextBar::setLabel( this, ContextMenu::key(), ContextBar::NoLabel ); } else { setStateLabel(); ContextBar::setLabel( this, Qt::Key_Select, ContextBar::Select ); } ContextBar::setLabel( this, Qt::Key_Back, ContextBar::Cancel ); } else { ContextBar::clearLabel( this, ContextMenu::key() ); if( !Global::mousePreferred() ) ContextBar::clearLabel( this, Qt::Key_Select ); ContextBar::clearLabel( this, Qt::Key_Back ); }#endif}void RegionSelector::reset(){#define DEFAULT_WIDTH 100#define DEFAULT_HEIGHT 100 // Reset region#ifdef QTOPIA_PHONE if( Global::mousePreferred() ) {#endif region_start = QPoint(); _region = QRect(); current_state = MARK;#ifdef QTOPIA_PHONE } else { // Set default region _region = QRect( 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT ); _region.moveCenter( rect().center() ); // Set current state to move current_state = MOVE; // If enabled toggle state label if( enabled ) setStateLabel(); }#endif}void RegionSelector::paintEvent( QPaintEvent* ){#ifdef QTOPIA_PHONEstatic const char *top_left_xpm[] = { "7 7 2 1", "x c #ffffff", ". c None", "xxxxxxx", "xxxxxx.", "xxxxx..", "xxxx...", "xxx....", "xx.....", "x......"};static const char *top_right_xpm[] = { "7 7 2 1", "x c #ffffff", ". c None", "xxxxxxx", ".xxxxxx", "..xxxxx", "...xxxx", "....xxx", ".....xx", "......x"};static const char *bottom_left_xpm[] = { "7 7 2 1", "x c #ffffff", ". c None", "x......", "xx.....", "xxx....", "xxxx...", "xxxxx..", "xxxxxx.", "xxxxxxx"};static const char *bottom_right_xpm[] = { "7 7 2 1", "x c #ffffff", ". c None", "......x", ".....xx", "....xxx", "...xxxx", "..xxxxx", ".xxxxxx", "xxxxxxx"};static const char *crosshair_xpm[] = { "15 15 2 1", "x c #ffffff", ". c None", ".......x.......", ".......x.......", ".......x.......", ".......x.......", ".......x.......", ".......x.......", ".......x.......", "xxxxxxxxxxxxxxx", ".......x.......", ".......x.......", ".......x.......", ".......x.......", ".......x.......", ".......x.......", ".......x.......",};static const QPixmap top_left( top_left_xpm );static const QPixmap top_right( top_right_xpm );static const QPixmap bottom_left( bottom_left_xpm );static const QPixmap bottom_right( bottom_right_xpm );static const QPixmap crosshair( crosshair_xpm );#define CROSSHAIR_CENTER 7#define CORNER_WIDTH 7#define CORNER_HEIGHT 7#define INSET 1#endif#define PAINTER_COLOR Qt::white#define SPACE_FILL_PATTERN QBrush::Dense6Pattern QPainter painter; // If selection enabled, draw selected region onto widget // Otherwise, draw image ui onto widget if( enabled ) { QPixmap buffer( image_ui->pixmap() ); painter.begin( &buffer ); painter.setPen( PAINTER_COLOR ); painter.setRasterOp( Qt::XorROP ); // Draw box around current selection region painter.drawRect( _region.normalize() ); #ifdef QTOPIA_PHONE if( !Global::mousePreferred() ) { QPoint center( _region.center() ); switch( current_state ) { // If current state is move, draw crosshair in center of region case MOVE: painter.drawPixmap( center.x() - CROSSHAIR_CENTER, center.y() - CROSSHAIR_CENTER, crosshair ); break; // If current state is size, draw corners around inner edge of region case SIZE: painter.drawPixmap( _region.left() + INSET, _region.top() + INSET, top_left ); painter.drawPixmap( _region.right() - CORNER_WIDTH, _region.top() + INSET, top_right ); painter.drawPixmap( _region.left() + INSET, _region.bottom() - CORNER_HEIGHT, bottom_left ); painter.drawPixmap( _region.right() - CORNER_WIDTH, _region.bottom() - CORNER_HEIGHT, bottom_right ); break; default: // Ignore break; } }#endif painter.setClipRegion( image_ui->region().subtract( _region.normalize() ) ); painter.setClipping( true ); // Gray out area surrounding current selection region painter.fillRect( rect(), QBrush( PAINTER_COLOR, SPACE_FILL_PATTERN ) ); painter.end(); painter.begin( this ); painter.drawPixmap( 0, 0, buffer ); } else { painter.begin( this ); painter.drawPixmap( 0, 0, image_ui->pixmap() ); }}#ifdef QTOPIA_PHONEvoid RegionSelector::keyPressEvent( QKeyEvent* e ){#define STEP 4 if( enabled && !Global::mousePreferred() ) { if( e->key() == ContextMenu::key() ) { // Toggle current state switch( current_state ) { case MOVE: current_state = SIZE; setStateLabel(); update(); break; case SIZE: current_state = MOVE; setStateLabel(); update(); break; default: // Ignore break; } } else if( e->key() == Key_Select ) { emit selected(); } else { switch( current_state ) { // Move region case MOVE: switch( e->key() ) { case Key_Left: moveBy( -STEP, 0 ); update(); break; case Key_Right: moveBy( STEP, 0 ); update(); break; case Key_Up: moveBy( 0, -STEP ); update(); break; case Key_Down: moveBy( 0, STEP ); update(); break; default: // Ignore e->ignore(); break; } break; // Size region case SIZE: switch( e->key() ) { case Key_Left: sizeBy( -STEP, 0 ); update(); break; case Key_Right: sizeBy( STEP, 0 ); update(); break; case Key_Up: sizeBy( 0, STEP ); update(); break; case Key_Down: sizeBy( 0, -STEP ); update(); break; default: // Ignore e->ignore(); break; } break; default: // Ignore break; } } } else { if( e->key() == Qt::Key_Back ) emit pressed(); e->ignore(); }}#endifvoid RegionSelector::mousePressEvent( QMouseEvent* e ){#define LAG 15 switch( e->button() ) { // If stylus has been pressed case Qt::LeftButton: // If selection enabled update press position with stylus position // Otherwise, emit pressed if( enabled ) { region_start = e->pos(); lag_area = QRect( region_start - QPoint( LAG, LAG ), region_start + QPoint( LAG, LAG ) ); } else emit pressed(); break; default: // Ignore break; }}void RegionSelector::mouseReleaseEvent( QMouseEvent* e ){ if( enabled ) { switch( current_state ) { // If region is being marked case MARK: // If stylus released within the selected region, emit selected // Otherwise, emit canceled signal if( _region.normalize().contains( e->pos() ) ) emit selected(); else emit canceled(); break; // If region is moving, change to mark case MOVING: current_state = MARK; break; default: // Ignore break; } }}void RegionSelector::mouseMoveEvent( QMouseEvent* e ){ if( enabled ) { switch( current_state ) { case MARK: // If stylus has moved outside lag area, change to moving if( !lag_area.contains( e->pos() ) ) current_state = MOVING; break; case MOVING: { // Update region int x = e->pos().x(), y = e->pos().y(); // Contain region within widget if( x < rect().left() ) x = rect().left(); if( x > rect().right() ) x = rect().right(); if( y < rect().top() ) y = rect().top(); if( y > rect().bottom() ) y = rect().bottom(); // Update region end with current stylus position _region = QRect( region_start, QPoint( x, y ) ); } // Update display update(); break; default: // Ignore break; } }}#ifdef QTOPIA_PHONEvoid RegionSelector::setStateLabel(){ switch( current_state ) { case MOVE: ContextBar::setLabel( this, ContextMenu::key(), "photoedit/resize", QString::null ); break; case SIZE: ContextBar::setLabel( this, ContextMenu::key(), "photoedit/move", QString::null ); break; default: // Ignore break; }}void RegionSelector::moveBy( int dx, int dy ){ // Contain region within widget if( _region.left() + dx < rect().left() ) dx = rect().left() - _region.left(); if( _region.right() + dx > rect().right() ) dx = rect().right() - _region.right(); if( _region.top() + dy < rect().top() ) dy = rect().top() - _region.top(); if( _region.bottom() + dy > rect().bottom() ) dy = rect().bottom() - _region.bottom(); _region.moveBy( dx, dy );}void RegionSelector::sizeBy( int dw, int dh ){#define MIN_WIDTH 20#define MIN_HEIGHT 20 _region.setLeft( _region.left() - dw ); _region.setRight( _region.right() + dw ); _region.setTop( _region.top() - dh ); _region.setBottom( _region.bottom() + dh ); // Limit to minimum if( _region.width() < MIN_WIDTH ) { _region.setLeft( _region.left() + dw ); _region.setRight( _region.right() - dw ); } if( _region.height() < MIN_HEIGHT ) { _region.setTop( _region.top() + dh ); _region.setBottom( _region.bottom() - dh ); } // Contain region within widget if( _region.left() < rect().left() ) _region.setLeft( rect().left() ); if( _region.right() > rect().right() ) _region.setRight( rect().right() ); if( _region.top() < rect().top() ) _region.setTop( rect().top() ); if( _region.bottom() > rect().bottom() ) _region.setBottom( rect().bottom() );}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -