You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
11 KiB
375 lines
11 KiB
/*************************************************************************** |
|
* Copyright (C) 2005 by Enrico Ros <eros.kde@email.it> * |
|
* * |
|
* 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. * |
|
***************************************************************************/ |
|
|
|
// qt/kde includes |
|
#include <qbitmap.h> |
|
#include <qpixmap.h> |
|
#include <qimage.h> |
|
#include <qpainter.h> |
|
#include <qtimer.h> |
|
#include <qtooltip.h> |
|
#include <kiconloader.h> |
|
#include <kimageeffect.h> |
|
#include <klocale.h> |
|
#include <kdeversion.h> |
|
#include <kaccelmanager.h> |
|
#include <kdebug.h> |
|
|
|
// system includes |
|
#include <math.h> |
|
|
|
// local includes |
|
#include "pageviewtoolbox.h" |
|
//#include "conf/settings.h" |
|
|
|
/** ToolboxButton **/ |
|
|
|
static const int ToolboxButtonIcon = 32; |
|
static const int ToolboxButtonSize = 40; |
|
|
|
// a flat button that enlights on hover and has an ID |
|
class ToolboxButton : public QPushButton |
|
{ |
|
public: |
|
ToolboxButton( QWidget * parent, const ToolboxItem & item, const QPixmap & backPixmap ); |
|
int toolboxID() const; |
|
|
|
protected: |
|
void mouseMoveEvent( QMouseEvent * e ); |
|
void mouseReleaseEvent( QMouseEvent * e ); |
|
void paintEvent( QPaintEvent * e ); |
|
|
|
private: |
|
int m_id; |
|
bool m_hovering; |
|
const QPixmap & m_background; |
|
}; |
|
|
|
ToolboxButton::ToolboxButton( QWidget * parent, const ToolboxItem & item, const QPixmap & pix ) |
|
: QPushButton( parent ), m_id( item.id ), m_hovering( false ), m_background( pix ) |
|
{ |
|
setMouseTracking( true ); |
|
setToggleButton( true ); |
|
resize( ToolboxButtonSize, ToolboxButtonSize ); |
|
setPixmap( DesktopIcon( item.pixmap, ToolboxButtonIcon ) ); |
|
QToolTip::add( this, item.text ); |
|
setWFlags( Qt::WNoAutoErase ); |
|
#if KDE_IS_VERSION(3,3,90) |
|
KAcceleratorManager::setNoAccel( this ); |
|
#endif |
|
} |
|
|
|
int ToolboxButton::toolboxID() const |
|
{ |
|
return m_id; |
|
} |
|
|
|
void ToolboxButton::mouseMoveEvent( QMouseEvent * e ) |
|
{ |
|
// check for mouse hovering |
|
const QRect myGeom( 0,0, width(), height() ); |
|
bool hover = myGeom.contains( e->pos() ); |
|
|
|
// if hover state changed update gfx |
|
if ( m_hovering != hover ) |
|
{ |
|
m_hovering = hover; |
|
update(); |
|
} |
|
} |
|
|
|
void ToolboxButton::mouseReleaseEvent( QMouseEvent * e ) |
|
{ |
|
// call default handler |
|
QPushButton::mouseReleaseEvent( e ); |
|
|
|
// reset hover state when clicking |
|
m_hovering = false; |
|
update(); |
|
} |
|
|
|
void ToolboxButton::paintEvent( QPaintEvent * e ) |
|
{ |
|
// always not hovering in disabled state |
|
if ( !isEnabled() ) |
|
m_hovering = false; |
|
|
|
// paint button in different flavours |
|
if ( isOn() || m_hovering ) |
|
{ |
|
// if the button is pressed or we're hovering it, use QPushButton style |
|
QPushButton::paintEvent( e ); |
|
} |
|
else |
|
{ |
|
// else draw button's pixmap over the parent's background (fake transparency) |
|
QPainter p( this ); |
|
QRect backRect = e->rect(); |
|
backRect.moveBy( x(), y() ); |
|
p.drawPixmap( e->rect().topLeft(), m_background, backRect ); |
|
drawButtonLabel( &p ); |
|
} |
|
} |
|
|
|
/** PageViewToolbox **/ |
|
|
|
static const int ToolboxGridSize = 40; |
|
|
|
PageViewToolbox::PageViewToolbox( QWidget * parent, QWidget * anchorWidget, bool vertical ) |
|
: QWidget( parent, "", Qt::WNoAutoErase ), m_anchor( anchorWidget ), |
|
m_vertical( vertical ), m_timerID( 0 ), m_hiding( false ) |
|
{ |
|
} |
|
|
|
void PageViewToolbox::setItems( const QValueList<ToolboxItem> & items ) |
|
{ |
|
#ifndef NDEBUG |
|
if ( !m_buttons.isEmpty() ) |
|
kdDebug() << "PageViewToolbox: adding items over existing ones" << endl; |
|
#endif |
|
QValueList<ToolboxItem>::const_iterator it = items.begin(), end = items.end(); |
|
for ( ; it != end; ++it ) |
|
{ |
|
ToolboxButton * button = new ToolboxButton( this, *it, m_pixmap ); |
|
connect( button, SIGNAL( clicked() ), this, SLOT( slotButtonClicked() ) ); |
|
m_buttons.append( button ); |
|
} |
|
} |
|
|
|
void PageViewToolbox::show() |
|
{ |
|
// rebuild pixmap and mask |
|
buildGfx(); |
|
QWidget::show(); |
|
|
|
// set scroll parameters |
|
m_hiding = false; |
|
m_currentPosition = getStartPoint(); |
|
m_endPosition = getEndPoint(); |
|
move( m_currentPosition ); |
|
|
|
// deselect all buttons |
|
QValueList< ToolboxButton * >::iterator it = m_buttons.begin(), end = m_buttons.end(); |
|
for ( ; it != end; ++it ) |
|
(*it)->setOn( false ); |
|
|
|
// start scrolling in |
|
if ( m_timerID ) |
|
killTimer( m_timerID ); |
|
m_timerID = startTimer( 20 ); |
|
} |
|
|
|
void PageViewToolbox::hideAndDestroy() |
|
{ |
|
// set scroll parameters |
|
m_hiding = true; |
|
m_endPosition = getStartPoint(); |
|
|
|
// start scrolling out |
|
if ( m_timerID ) |
|
killTimer( m_timerID ); |
|
m_timerID = startTimer( 10 ); |
|
} |
|
|
|
void PageViewToolbox::anchorChanged() |
|
{ |
|
// stop timer |
|
if ( m_timerID ) |
|
{ |
|
killTimer( m_timerID ); |
|
m_timerID = 0; |
|
} |
|
// if was hiding delete this |
|
if ( m_hiding ) |
|
delete this; |
|
else |
|
{ |
|
// else rebuild widget and set it completely visible |
|
buildGfx(); |
|
m_currentPosition = getEndPoint(); |
|
move( m_currentPosition ); |
|
// repaint all buttons (to update background) |
|
QValueList< ToolboxButton * >::iterator it = m_buttons.begin(), end = m_buttons.end(); |
|
for ( ; it != end; ++it ) |
|
(*it)->update(); |
|
} |
|
} |
|
|
|
void PageViewToolbox::paintEvent( QPaintEvent * e ) |
|
{ |
|
// paint the internal pixmap over the widget |
|
bitBlt( this, e->rect().topLeft(), &m_pixmap, e->rect() ); |
|
} |
|
|
|
void PageViewToolbox::timerEvent( QTimerEvent * ) |
|
{ |
|
// move currentPosition towards endPosition |
|
int dX = m_endPosition.x() - m_currentPosition.x(), |
|
dY = m_endPosition.y() - m_currentPosition.y(); |
|
dX = dX / 6 + QMAX( -2, QMIN( 2, dX) ); |
|
dY = dY / 6 + QMAX( -2, QMIN( 2, dY) ); |
|
m_currentPosition.setX( m_currentPosition.x() + dX ); |
|
m_currentPosition.setY( m_currentPosition.y() + dY ); |
|
|
|
// move the widget |
|
move( m_currentPosition ); |
|
|
|
// handle arrival to the end |
|
if ( m_currentPosition == m_endPosition ) |
|
{ |
|
killTimer( m_timerID ); |
|
m_timerID = 0; |
|
if ( m_hiding ) |
|
delete this; |
|
} |
|
} |
|
|
|
QPoint PageViewToolbox::getStartPoint() |
|
{ |
|
if ( m_vertical ) |
|
return QPoint( -width(), (m_anchor->height() - height()) / 2 ); |
|
return QPoint( (m_anchor->width() - width()) / 2, -height() ); |
|
} |
|
|
|
QPoint PageViewToolbox::getEndPoint() |
|
{ |
|
if ( m_vertical ) |
|
return QPoint( 0, (m_anchor->height() - height()) / 2 ); |
|
return QPoint( (m_anchor->width() - width()) / 2, 0 ); |
|
} |
|
|
|
void PageViewToolbox::buildGfx() |
|
{ |
|
int buttonsNumber = m_buttons.count(), |
|
parentWidth = m_anchor->width(), |
|
parentHeight = m_anchor->height(), |
|
myCols = 1, |
|
myRows = 1; |
|
|
|
// 1. find out columns and rows we're going to use |
|
if ( m_vertical ) |
|
{ |
|
myCols = 1 + (buttonsNumber * ToolboxGridSize) / |
|
(parentHeight - ToolboxGridSize); |
|
myRows = (int)ceilf( (float)buttonsNumber / (float)myCols ); |
|
} |
|
else |
|
{ |
|
myRows = 1 + (buttonsNumber * ToolboxGridSize) / |
|
(parentWidth - ToolboxGridSize); |
|
myCols = (int)ceilf( (float)buttonsNumber / (float)myRows ); |
|
} |
|
|
|
// 2. compute widget size (from rows/cols) |
|
int myWidth = myCols * ToolboxGridSize, |
|
myHeight = myRows * ToolboxGridSize, |
|
xOffset = (ToolboxGridSize - ToolboxButtonSize) / 2, |
|
yOffset = (ToolboxGridSize - ToolboxButtonSize) / 2; |
|
|
|
if ( m_vertical ) |
|
{ |
|
myHeight += 8; |
|
myWidth += 4; |
|
yOffset += 4; |
|
} |
|
else |
|
{ |
|
myWidth += 8; |
|
myHeight += 4; |
|
xOffset += 4; |
|
} |
|
|
|
// 3. resize pixmap, mask and widget |
|
static QBitmap mask; |
|
mask.resize( myWidth, myHeight ); |
|
m_pixmap.resize( myWidth, myHeight ); |
|
resize( myWidth, myHeight ); |
|
|
|
// 4. create and set transparency mask |
|
QPainter maskPainter( &mask); |
|
mask.fill( Qt::black ); |
|
maskPainter.setBrush( Qt::white ); |
|
if ( m_vertical ) |
|
maskPainter.drawRoundRect( -10, 0, myWidth + 10, myHeight, 2000 / (myWidth + 10), 2000 / myHeight ); |
|
else |
|
maskPainter.drawRoundRect( 0, -10, myWidth, myHeight + 10, 2000 / myWidth, 2000 / (myHeight + 10) ); |
|
setMask( mask ); |
|
|
|
// 5. draw background |
|
QPainter bufferPainter( &m_pixmap ); |
|
QPixmap gradientPattern; |
|
// 5.1. draw horizontal/vertical gradient |
|
if ( m_vertical ) |
|
gradientPattern = KImageEffect::gradient( QSize( myWidth, 1), |
|
palette().active().button(), palette().active().light(), |
|
KImageEffect::HorizontalGradient ); |
|
else |
|
gradientPattern = KImageEffect::gradient( QSize( 1, myHeight ), |
|
palette().active().button(), palette().active().light(), |
|
KImageEffect::VerticalGradient ); |
|
bufferPainter.drawTiledPixmap( 0, 0, myWidth, myHeight, gradientPattern ); |
|
// 5.2. draw rounded border |
|
bufferPainter.setPen( palette().active().dark() ); |
|
if ( m_vertical ) |
|
bufferPainter.drawRoundRect( -10, 0, myWidth + 10, myHeight, 2000 / (myWidth + 10), 2000 / myHeight ); |
|
else |
|
bufferPainter.drawRoundRect( 0, -10, myWidth, myHeight + 10, 2000 / myWidth, 2000 / (myHeight + 10) ); |
|
|
|
// 6. reposition buttons (in rows/col grid) |
|
int gridX = 0, |
|
gridY = 0; |
|
QValueList< ToolboxButton * >::iterator it = m_buttons.begin(), end = m_buttons.end(); |
|
for ( ; it != end; ++it ) |
|
{ |
|
ToolboxButton * button = *it; |
|
button->move( gridX * ToolboxGridSize + xOffset, |
|
gridY * ToolboxGridSize + yOffset ); |
|
if ( ++gridX == myCols ) |
|
{ |
|
gridX = 0; |
|
gridY++; |
|
} |
|
} |
|
} |
|
|
|
void PageViewToolbox::slotButtonClicked() |
|
{ |
|
ToolboxButton * button = (ToolboxButton *)sender(); |
|
if ( button ) |
|
{ |
|
// deselect other buttons |
|
QValueList< ToolboxButton * >::iterator it = m_buttons.begin(), end = m_buttons.end(); |
|
for ( ; it != end; ++it ) |
|
if ( *it != button ) |
|
(*it)->setOn( false ); |
|
// emit signal |
|
if ( button->isOn() ) |
|
emit toolSelected( button->toolboxID() ); |
|
else |
|
button->setOn( true ); |
|
} |
|
} |
|
|
|
|
|
/** PageViewEditTools **/ |
|
|
|
PageViewEditTools::PageViewEditTools( QWidget * parent, QWidget * anchorWidget ) |
|
: PageViewToolbox( parent, anchorWidget, true ) |
|
{ |
|
QValueList<ToolboxItem> items; |
|
items.push_back( ToolboxItem( 1, i18n("Text"), "pinnote" ) ); |
|
items.push_back( ToolboxItem( 2, i18n("Yellow Highlighter"), "highlight_yellow" ) ); |
|
items.push_back( ToolboxItem( 3, i18n("Orange Highlighter"), "highlight_orange" ) ); |
|
items.push_back( ToolboxItem( 4, i18n("Green Highlighter"), "highlight_green" ) ); |
|
items.push_back( ToolboxItem( 5, i18n("Pencil"), "pencil" ) ); |
|
setItems( items ); |
|
show(); |
|
} |
|
|
|
#include "pageviewtoolbox.moc"
|
|
|