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.
koffice/karbon/widgets/vstrokefillpreview.cpp

448 lines
12 KiB

/* This file is part of the KDE project
Copyright (C) 2002 - 2005, The Karbon Developers
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <tqcolor.h>
#include <kdebug.h>
#include <KoPoint.h>
#include "karbon_part.h"
#include "vcolordlg.h"
#include "vfill.h"
#include "vfillcmd.h"
#include "vkopainter.h"
#include "vselection.h"
#include "vstroke.h"
#include "vstrokecmd.h"
#include "vstrokefillpreview.h"
#define PANEL_SIZEX 50.0
#define PANEL_SIZEY 50.0
#define FILL_TOPX 15.0
#define FILL_TOPY 15.0
#define FILL_BOTTOMX 45.0
#define FILL_BOTTOMY 45.0
#define STROKE_TOPX 5.0
#define STROKE_TOPY 5.0
#define STROKE_BOTTOMX 35.0
#define STROKE_BOTTOMY 35.0
#define STROKE_TOPX_INNER STROKE_TOPX + 4
#define STROKE_TOPY_INNER STROKE_TOPY + 4
#define STROKE_BOTTOMX_INNER STROKE_BOTTOMX - 4
#define STROKE_BOTTOMY_INNER STROKE_BOTTOMY - 4
VStrokeFillPreview::VStrokeFillPreview(
KarbonPart *part, TQWidget* parent, const char* name )
: TQFrame( parent, name ), m_part( part )
{
m_strokeWidget = false;
setFocusPolicy( TQWidget::NoFocus );
setFrameStyle( TQFrame::GroupBoxPanel | TQFrame::Sunken );
installEventFilter( this );
m_pixmap.resize( int( PANEL_SIZEX ), int( PANEL_SIZEY ) );
m_painter = new VKoPainter( TQT_TQPAINTDEVICE(&m_pixmap), uint( PANEL_SIZEX ), uint( PANEL_SIZEY ) );
}
VStrokeFillPreview::~VStrokeFillPreview()
{
delete( m_painter );
}
void
VStrokeFillPreview::paintEvent( TQPaintEvent* event )
{
bitBlt( this,
(int)( width() - PANEL_SIZEX ) / 2, (int)( height() - PANEL_SIZEY ) / 2,
&m_pixmap,
0, 0, (int)PANEL_SIZEX, (int)PANEL_SIZEY );
TQFrame::paintEvent( event );
}
bool
VStrokeFillPreview::eventFilter( TQObject *, TQEvent *event )
{
TQMouseEvent* e = static_cast<TQMouseEvent*>( event );
int ex = e->x() - int( ( width() - PANEL_SIZEX ) / 2 );
int ey = e->y() - int( ( height() - PANEL_SIZEY ) / 2 );
if( event && event->type() == TQEvent::MouseButtonPress )
{
if ( m_strokeWidget )
{
if(
ex >= STROKE_TOPX && ex <= STROKE_BOTTOMX &&
ey >= STROKE_TOPY && ey <= STROKE_BOTTOMY )
{
m_strokeWidget = true;
emit strokeSelected();
}
else if(
ex >= FILL_TOPX && ex <= FILL_BOTTOMX &&
ey >= FILL_TOPY && ey <= FILL_BOTTOMY )
{
m_strokeWidget = false;
emit fillSelected();
}
}
else
{
if(
ex >= FILL_TOPX && ex <= FILL_BOTTOMX &&
ey >= FILL_TOPY && ey <= FILL_BOTTOMY )
{
m_strokeWidget = false;
emit fillSelected();
}
else if(
ex >= STROKE_TOPX && ex <= STROKE_BOTTOMX &&
ey >= STROKE_TOPY && ey <= STROKE_BOTTOMY )
{
m_strokeWidget = true;
emit strokeSelected();
}
}
update( m_stroke, m_fill );
}
if( event && event->type() == TQEvent::MouseButtonDblClick )
{
if(
ex >= FILL_TOPX && ex <= FILL_BOTTOMX &&
ey >= FILL_TOPY && ey <= FILL_BOTTOMY )
{
VColorDlg* dialog = new VColorDlg( m_fill.color(), this );
if( dialog->exec() == TQDialog::Accepted )
{
if( m_part && m_part->document().selection() ) m_part->addCommand( new VFillCmd( &m_part->document(), VFill( dialog->Color() ) ), true );
}
delete dialog;
}
else if(
ex >= STROKE_TOPX && ex <= STROKE_BOTTOMX
&& ey >= STROKE_TOPY && ey <= STROKE_BOTTOMY )
{
VColorDlg* dialog = new VColorDlg( m_stroke.color(), this );
if( dialog->exec() == TQDialog::Accepted )
{
if( m_part && m_part->document().selection() ) m_part->addCommand( new VStrokeCmd( &m_part->document(), dialog->Color() ), true );
}
delete dialog;
}
}
return false;
}
void
VStrokeFillPreview::update( const VStroke &s, const VFill &f )
{
m_painter->begin();
if( &f )
m_fill = f;
else
m_fill = VFill();
if( &s )
m_stroke = s;
else
m_stroke = VStroke();
// draw checkerboard
VFill fill;
m_painter->setPen( TQt::NoPen );
for( unsigned char y = 0; y < PANEL_SIZEY; y += 10 )
for( unsigned char x = 0; x < PANEL_SIZEX; x += 10 )
{
fill.setColor( ( ( ( x + y ) % 20 ) == 0 ) ? TQColor( 180, 180, 180 ) : TQColor( 100, 100, 100 ) );
m_painter->setBrush( fill );
m_painter->drawRect( x, y, 10, 10 );
}
if ( m_strokeWidget )
{
drawFill( m_fill );
drawStroke( m_stroke );
}
else
{
drawStroke( m_stroke );
drawFill( m_fill );
}
m_painter->end();
repaint();
}
void
VStrokeFillPreview::drawFill( const VFill &f )
{
VStroke stroke;
if( f.type() != VFill::none )
{
if( f.type() != VFill::solid )
{
VFill fill;
fill = f;
if( f.type() == VFill::grad )
{
if( f.gradient().type() == VGradient::linear )
{
fill.gradient().setOrigin( KoPoint( 30, 20 ) );
fill.gradient().setVector( KoPoint( 30, 50 ) );
}
else if( f.gradient().type() == VGradient::radial ||
f.gradient().type() == VGradient::conic )
{
fill.gradient().setOrigin( KoPoint( 30, 35 ) );
fill.gradient().setFocalPoint( KoPoint( 30, 35 ) );
fill.gradient().setVector( KoPoint( 30, 50 ) );
}
}
if( f.type() == VFill::patt )
{
fill.pattern() = f.pattern();
fill.pattern().setOrigin( KoPoint( 20, 10 ) );
fill.pattern().setVector( KoPoint( 30, 10 ) );
fill.setType( VFill::patt );
}
m_painter->setBrush( fill );
}
else
m_painter->setBrush( f );
m_painter->setPen( TQt::NoPen );
m_painter->drawRect( KoRect( FILL_TOPX, FILL_TOPY, FILL_BOTTOMX - FILL_TOPX, FILL_BOTTOMY - FILL_TOPY ) );
}
else
{
VFill fill;
fill.setColor( TQt::white );
m_painter->setBrush( fill );
m_painter->setPen( TQt::NoPen );
m_painter->drawRect( KoRect( FILL_TOPX, FILL_TOPY,
FILL_BOTTOMX - FILL_TOPX,
FILL_BOTTOMY - FILL_TOPY ) );
}
// show 3D outline of fill part
VColor color;
m_painter->setBrush( TQt::NoBrush );
color.set( 1.0, 1.0, 1.0 );
stroke.setColor( color );
m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( FILL_BOTTOMX, FILL_TOPY ) );
m_painter->lineTo( KoPoint( FILL_TOPX, FILL_TOPY ) );
m_painter->lineTo( KoPoint( FILL_TOPX, FILL_BOTTOMY ) );
m_painter->strokePath();
color.set( 0.5, 0.5, 0.5 );
stroke.setColor( color );
m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( FILL_BOTTOMX, FILL_TOPY ) );
m_painter->lineTo( KoPoint( FILL_BOTTOMX, FILL_BOTTOMY ) );
m_painter->lineTo( KoPoint( FILL_TOPX, FILL_BOTTOMY ) );
m_painter->strokePath();
if( f.type() == VFill::none )
{
stroke.setColor( TQt::red );
m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( FILL_BOTTOMX, FILL_TOPY ) );
m_painter->lineTo( KoPoint( FILL_TOPX, FILL_BOTTOMY ) );
m_painter->strokePath();
}
}
void
VStrokeFillPreview::drawStroke( const VStroke &s )
{
VStroke stroke;
stroke.setLineWidth( 2.0 );
m_painter->setPen( TQt::NoPen );
if( s.type() != VStroke::none )
{
VFill fill;
if( s.type() != VStroke::solid )
{
if( s.type() == VStroke::grad )
{
fill.gradient() = s.gradient();
if( s.gradient().type() == VGradient::linear )
{
fill.gradient().setOrigin( KoPoint( FILL_TOPX, 10 ) );
fill.gradient().setVector( KoPoint( FILL_TOPX, 40 ) );
}
else if( s.gradient().type() == VGradient::radial ||
s.gradient().type() == VGradient::conic )
{
fill.gradient().setOrigin( KoPoint( FILL_TOPX, 25 ) );
fill.gradient().setFocalPoint( KoPoint( FILL_TOPX, 25 ) );
fill.gradient().setVector( KoPoint( FILL_TOPX, 40 ) );
}
fill.setType( VFill::grad );
}
if( s.type() == VStroke::patt )
{
fill.pattern() = s.pattern();
fill.pattern().setOrigin( KoPoint( FILL_TOPX, 10 ) );
fill.pattern().setVector( KoPoint( FILL_TOPX, 40 ) );
fill.setType( VFill::patt );
}
}
else
fill.setColor( s.color() );
m_painter->setFillRule( evenOdd );
m_painter->setBrush( fill );
m_painter->newPath();
m_painter->moveTo( KoPoint( STROKE_TOPX, STROKE_TOPY ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX, STROKE_TOPY ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX, STROKE_BOTTOMY ) );
m_painter->lineTo( KoPoint( STROKE_TOPX, STROKE_BOTTOMY ) );
m_painter->lineTo( KoPoint( STROKE_TOPX, STROKE_TOPY ) );
m_painter->moveTo( KoPoint( STROKE_TOPX_INNER, STROKE_TOPY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX_INNER, STROKE_TOPY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX_INNER, STROKE_BOTTOMY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_TOPX_INNER, STROKE_BOTTOMY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_TOPX_INNER, STROKE_TOPY_INNER ) );
m_painter->fillPath();
}
else
{
VFill fill;
m_painter->setFillRule( evenOdd );
fill.setColor( TQt::white );
m_painter->setBrush( fill );
m_painter->setPen( TQt::NoPen );
m_painter->newPath();
m_painter->moveTo( KoPoint( STROKE_TOPX, STROKE_TOPY ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX, STROKE_TOPY ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX, STROKE_BOTTOMY ) );
m_painter->lineTo( KoPoint( STROKE_TOPX, STROKE_BOTTOMY ) );
m_painter->lineTo( KoPoint( STROKE_TOPX, STROKE_TOPY ) );
m_painter->moveTo( KoPoint( STROKE_TOPX_INNER, STROKE_TOPY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX_INNER, STROKE_TOPY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX_INNER, STROKE_BOTTOMY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_TOPX_INNER, STROKE_BOTTOMY_INNER ) );
m_painter->lineTo( KoPoint( STROKE_TOPX_INNER, STROKE_TOPY_INNER ) );
m_painter->fillPath();
}
// show 3D outline of stroke part
VColor color;
color.set( 1.0, 1.0, 1.0 );
stroke.setColor( color );
m_painter->setBrush( TQt::NoBrush );
m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( STROKE_BOTTOMX + 1, STROKE_TOPY - 1 ) );
m_painter->lineTo( KoPoint( STROKE_TOPX - 1, STROKE_TOPY - 1 ) );
m_painter->lineTo( KoPoint( STROKE_TOPX - 1, STROKE_BOTTOMY + 1 ) );
m_painter->strokePath();
color.set( 0.5, 0.5, 0.5 );
stroke.setColor( color );
m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( STROKE_BOTTOMX + 1, STROKE_TOPY - 1 ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX + 1, STROKE_BOTTOMY + 1 ) );
m_painter->lineTo( KoPoint( STROKE_TOPX - 1, STROKE_BOTTOMY + 1 ) );
m_painter->strokePath();
//stroke.setColor( TQt::black.rgb() );
//m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( STROKE_BOTTOMX_INNER - 1, STROKE_TOPY_INNER + 1 ) );
m_painter->lineTo( KoPoint( STROKE_TOPX_INNER + 1, STROKE_TOPY_INNER + 1 ) );
m_painter->lineTo( KoPoint( STROKE_TOPX_INNER + 1, STROKE_BOTTOMY_INNER - 1 ) );
m_painter->strokePath();
color.set( 1.0, 1.0, 1.0 );
stroke.setColor( color );
m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( STROKE_BOTTOMX_INNER - 1, STROKE_TOPY_INNER + 1 ) );
m_painter->lineTo( KoPoint( STROKE_BOTTOMX_INNER - 1, STROKE_BOTTOMY_INNER - 1 ) );
m_painter->lineTo( KoPoint( STROKE_TOPX_INNER + 1, STROKE_BOTTOMY_INNER - 1 ) );
m_painter->strokePath();
if( s.type() == VStroke::none )
{
stroke.setColor( TQt::red );
m_painter->setPen( stroke );
m_painter->newPath();
m_painter->moveTo( KoPoint( STROKE_BOTTOMX, STROKE_TOPY ) );
m_painter->lineTo( KoPoint( STROKE_TOPX, STROKE_BOTTOMY ) );
m_painter->strokePath();
}
}
void
VStrokeFillPreview::setFillSelected()
{
m_strokeWidget = false;
update( m_stroke, m_fill );
emit fillSelected();
}
void
VStrokeFillPreview::setStrokeSelected()
{
m_strokeWidget = true;
update( m_stroke, m_fill );
emit strokeSelected();
}
#include "vstrokefillpreview.moc"