canvasitemparts.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2003-2005 by David Saxton                               *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "canvasitemparts.h"
00012 #include "cells.h"
00013 #include "cnitem.h"
00014 #include "icndocument.h"
00015 
00016 #include <qpainter.h>
00017 
00018 //BEGIN Class GuiPart
00019 GuiPart::GuiPart( CNItem *parent, const QRect & r, QCanvas * canvas )
00020         : QObject(parent),
00021         QCanvasRectangle( r, canvas ),
00022         m_angleDegrees(0),
00023         p_parent(parent),
00024         b_pointsAdded(false),
00025         m_originalRect(r)
00026 {
00027         connect( parent, SIGNAL(movedBy(double, double )), this, SLOT(slotMoveBy(double, double )) );
00028         setZ( parent->z() + 0.5 );
00029 }
00030 
00031 GuiPart::~GuiPart()
00032 {
00033         hide();
00034 }
00035 
00036 void GuiPart::setAngleDegrees( int angleDegrees )
00037 {
00038         m_angleDegrees = angleDegrees;
00039         posChanged();
00040         if (canvas())
00041                 canvas()->setChanged( boundingRect() );
00042 }
00043 
00044 void GuiPart::setGuiPartSize( int width, int height )
00045 {
00046         updateConnectorPoints(false);
00047         setSize( width, height );
00048         posChanged();
00049 }
00050 
00051 void GuiPart::initPainter( QPainter &p )
00052 {
00053         if((m_angleDegrees%180) == 0) return;
00054         
00055         p.translate( int(x()+(width()/2)), int(y()+(height()/2)) );
00056         p.rotate(m_angleDegrees);
00057         p.translate( -int(x()+(width()/2)), -int(y()+(height()/2)) );
00058 }
00059 
00060 void GuiPart::deinitPainter( QPainter &p )
00061 {
00062         if((m_angleDegrees%180) == 0 ) return;
00063 
00064         p.translate( int(x()+(width()/2)), int(y()+(height()/2)) );
00065         p.rotate(-m_angleDegrees);
00066         p.translate( -int(x()+(width()/2)), -int(y()+(height()/2)) );
00067 }
00068 
00069 void GuiPart::slotMoveBy( double dx, double dy )
00070 {
00071         if(dx==0 && dy==0 ) return;
00072 
00073         moveBy( dx, dy );
00074         posChanged();
00075 }
00076 
00077 void GuiPart::updateConnectorPoints( bool add )
00078 {
00079         ICNDocument *icnd = dynamic_cast<ICNDocument*>(p_parent->itemDocument());
00080         if ( !icnd) return;
00081 
00082         Cells * cells = icnd->cells();
00083         if (!cells) return;
00084 
00085         if ( add == b_pointsAdded ) return;
00086 
00087         b_pointsAdded = add;
00088 
00089         int mult = add ? 1 : -1;
00090         int sx = int(x()/8);
00091         int sy = int(y()/8);
00092         int ex = int((x()+width())/8);
00093         int ey = int((y()+height())/8);
00094 
00095         for ( int x=sx; x<=ex; ++x ) {
00096                 for ( int y=sy; y<=ey; ++y ) {
00097                         if ( icnd->isValidCellReference( x, y ) )
00098                                 (*cells)[x][y].CIpenalty += mult*ICNDocument::hs_item/2;
00099                 }
00100         }
00101 }
00102 
00103 QRect GuiPart::drawRect()
00104 {
00105         QRect dr = rect();
00106         if( m_angleDegrees%180 != 0 ) {
00107                 QWMatrix m;
00108                 m.translate( int(x()+(width()/2)), int(y()+(height()/2)) );
00109         
00110                 if ( (m_angleDegrees%180) != 0 )
00111                         m.rotate(-m_angleDegrees);
00112                 
00113                 m.translate( -int(x()+(width()/2)), -int(y()+(height()/2)) );
00114                 
00115                 dr = m.mapRect(dr);
00116         }
00117         return dr;
00118 }
00119 //END Class GuiPart
00120 
00121 //BEGIN Class Text
00122 Text::Text(const QString &text, CNItem *parent, const QRect & r, QCanvas * canvas, int flags )
00123         : GuiPart( parent, r, canvas )
00124 {
00125         m_flags = flags;
00126         setText(text);
00127 }
00128 
00129 Text::~Text()
00130 {
00131 }
00132 
00133 bool Text::setText( const QString & text )
00134 {
00135         if ( m_text == text )
00136                 return false;
00137         
00138         updateConnectorPoints(false);
00139         
00140         m_text = text;
00141         return true;
00142 }
00143 
00144 void Text::setFlags( int flags )
00145 {
00146         updateConnectorPoints( false );
00147         m_flags = flags;
00148 }
00149 
00150 void Text::drawShape( QPainter & p )
00151 {
00152         initPainter(p);
00153         p.setFont( p_parent->font() );
00154         p.drawText( drawRect(), m_flags, m_text );
00155         deinitPainter(p);
00156 }
00157 
00158 QRect Text::recommendedRect() const
00159 {
00160         return QFontMetrics( p_parent->font() ).boundingRect( m_originalRect.x(), m_originalRect.y(), m_originalRect.width(), m_originalRect.height(), m_flags, m_text );
00161 }
00162 //END Class Text
00163 
00164 //BEGIN Class Widget
00165 Widget::Widget( const QString & id, CNItem * parent, const QRect & r, QCanvas * canvas )
00166         : GuiPart( parent, r, canvas )
00167 {
00168         m_id = id;
00169         show();
00170 }
00171 
00172 Widget::~Widget()
00173 {
00174 }
00175 
00176 int Widget::rtti() const
00177 {
00178         return ItemDocument::RTTI::Widget;
00179 }
00180 
00181 void Widget::setEnabled( bool enabled )
00182 {
00183         widget()->setEnabled(enabled);
00184 }
00185 
00186 void Widget::posChanged()
00187 {
00188         // Swap around the width / height if we are rotated at a non-half way around
00189         if ( m_angleDegrees%90 != 0 )
00190                 widget()->setFixedSize( QSize( height(), width() ) );
00191         else widget()->setFixedSize( size() );
00192 
00193         widget()->move( int(x()), int(y()) );
00194 }
00195 
00196 void Widget::drawShape( QPainter &p )
00197 {
00198 //      initPainter(p);
00199         p.drawPixmap( int(x()), int(y()), QPixmap::grabWidget( widget() ) );
00200 //      deinitPainter(p);
00201 }
00202 //END Class Widget
00203 
00204 //BEGIN Class ToolButton
00205 ToolButton::ToolButton( QWidget *parent )
00206         : QToolButton(parent)
00207 {
00208         m_angleDegrees = 0;
00209         if ( QFontInfo(m_font).pixelSize() > 11 ) // It has to be > 11, not > 12, as (I think) pixelSize() rounds off the actual size
00210                 m_font.setPixelSize(12);
00211 }
00212 
00213 void ToolButton::drawButtonLabel( QPainter * p )
00214 {
00215         if ( m_angleDegrees % 180 == 0 || text().isEmpty() )
00216         {
00217                 QToolButton::drawButtonLabel(p);
00218                 return;
00219         }
00220 
00221         double dx = size().width()/2;
00222         double dy = size().height()/2;
00223 
00224         p->translate( dx, dy );
00225         p->rotate( m_angleDegrees );
00226         p->translate( -dx, -dy );
00227 
00228         p->translate( -dy+dx, 0 );
00229 
00230         int m = width() > height() ? width() : height();
00231 
00232         p->setPen( Qt::black );
00233         p->drawText( isDown()?1:0, isDown()?1:0, m, m, Qt::AlignVCenter | Qt::AlignHCenter, text() );
00234 
00235         p->translate( dy-dx, 0 );
00236 
00237         p->translate( dx, dy );
00238         p->rotate( -m_angleDegrees );
00239         p->translate( -dx, -dy );
00240 }
00241 //END Class ToolButton
00242 
00243 //BEGIN Class Button
00244 Button::Button(const QString &id, CNItem *parent, bool isToggle, const QRect &r, QCanvas *canvas )
00245         : Widget(id, parent, r, canvas)
00246 {
00247         b_isToggle = isToggle;
00248         m_button = new ToolButton(0);
00249         m_button->setUsesTextLabel(false);
00250         m_button->setToggleButton(b_isToggle);
00251         connect(m_button, SIGNAL(pressed()), this, SLOT(slotStateChanged()));
00252         connect(m_button, SIGNAL(released()), this, SLOT(slotStateChanged()));
00253         posChanged();
00254 }
00255 
00256 Button::~Button()
00257 {
00258         delete m_button;
00259 }
00260 
00261 void Button::setToggle( bool toggle )
00262 {
00263         if ( b_isToggle == toggle ) return;
00264 
00265         if (b_isToggle) {
00266                 // We must first untoggle it, else it'll be forever stuck...
00267                 setState(false);
00268         }
00269 
00270         b_isToggle = toggle;
00271         m_button->setToggleButton(b_isToggle);
00272 }
00273 
00274 void Button::posChanged()
00275 {
00276         Widget::posChanged();
00277         m_button->setAngleDegrees(m_angleDegrees);
00278 }
00279 
00280 void Button::slotStateChanged()
00281 {
00282         parent()->buttonStateChanged( id(), m_button->isDown() || m_button->isOn() );
00283 }
00284 
00285 QWidget* Button::widget() const
00286 {
00287         return m_button;
00288 }
00289 
00290 void Button::setPixmap( const QPixmap &p )
00291 {
00292         m_button->setPixmap(p);
00293 }
00294 
00295 void Button::setState( bool state )
00296 {
00297         if ( this->state() == state ) return;
00298 
00299         if(isToggle()) m_button->setOn(state);
00300         else m_button->setDown(state);
00301 
00302         slotStateChanged();
00303 }
00304 
00305 bool Button::state() const
00306 {
00307         if(isToggle()) return m_button->state();
00308         else return m_button->isDown();
00309 }
00310 
00311 QRect Button::recommendedRect() const
00312 {
00313         QSize sizeHint = m_button->sizeHint();
00314         if ( sizeHint.width() < m_originalRect.width() )
00315                 sizeHint.setWidth( m_originalRect.width() );
00316 
00317         // Hmm...for now, lets just keep the recomended rect the same height as the original rect
00318         sizeHint.setHeight( m_originalRect.height() );
00319 
00320         int hdw = (sizeHint.width() - m_originalRect.width())/2;
00321         int hdh = (sizeHint.height() - m_originalRect.height())/2;
00322 
00323         return QRect( m_originalRect.x()-hdw, m_originalRect.y()-hdh, sizeHint.width(), sizeHint.height() );
00324 }
00325 
00326 void Button::setText( const QString &text )
00327 {
00328         if(m_button->text() == text) return;
00329 
00330         updateConnectorPoints(false);
00331 
00332         m_button->setUsesTextLabel(true);
00333         m_button->setText(text);
00334         m_button->setTextLabel(text);
00335         canvas()->setChanged( rect() );
00336         p_parent->updateAttachedPositioning();
00337 }
00338 
00339 void Button::mousePressEvent( QMouseEvent *e )
00340 {
00341         if(!m_button->isEnabled()) return;
00342 
00343         QMouseEvent event( QEvent::MouseButtonPress, e->pos()-QPoint(int(x()),int(y())), e->button(), e->state() );
00344         m_button->mousePressEvent(&event);
00345 
00346         if (event.isAccepted()) e->accept();
00347 
00348         canvas()->setChanged( rect() );
00349 }
00350 
00351 void Button::mouseReleaseEvent( QMouseEvent *e )
00352 {
00353         QMouseEvent event( QEvent::MouseButtonRelease, e->pos()-QPoint(int(x()),int(y())), e->button(), e->state() );
00354         m_button->mouseReleaseEvent(&event);
00355 
00356         if (event.isAccepted()) e->accept();
00357 
00358         canvas()->setChanged( rect() );
00359 }
00360 
00361 void Button::enterEvent()
00362 {
00363         m_button->enterEvent();
00364 //      m_button->setFocus();
00365 //      bool hasFocus = m_button->hasFocus();
00366 //      m_button->setAutoRaise(true);
00367 //      m_button->setOn(true);
00368 }
00369 
00370 void Button::leaveEvent()
00371 {
00372         m_button->leaveEvent();
00373 //      m_button->clearFocus();
00374 //      bool hasFocus = m_button->hasFocus();
00375 //      m_button->setAutoRaise(false);
00376 //      m_button->setOn(false);
00377 }
00378 //END Class Button
00379 
00380 //BEGIN Class SliderWidget
00381 SliderWidget::SliderWidget( QWidget *parent )
00382         : QSlider(parent)
00383 {
00384         setWFlags(WNoAutoErase|WRepaintNoErase);
00385 }
00386 //END Class SliderWidget
00387 
00388 //BEGIN Class Slider
00389 Slider::Slider( const QString & id, CNItem * parent, const QRect & r, QCanvas * canvas )
00390         : Widget( id, parent, r, canvas )
00391 {
00392         m_orientation = Qt::Vertical;
00393         m_slider = new SliderWidget(0);
00394         m_slider->setPaletteBackgroundColor(Qt::white);
00395         m_slider->setPaletteForegroundColor(Qt::white);
00396         m_slider->setEraseColor(Qt::white);
00397         m_slider->setBackgroundMode( Qt::NoBackground );
00398         connect( m_slider, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int)) );
00399         posChanged();
00400 }
00401 
00402 Slider::~Slider()
00403 {
00404         delete m_slider;
00405 }
00406 
00407 QWidget* Slider::widget() const
00408 {
00409         return m_slider;
00410 }
00411 
00412 int Slider::value() const
00413 {
00414         return m_slider->value();
00415 }
00416 
00417 void Slider::setValue( int value )
00418 {
00419         m_slider->setValue(value);
00420 }
00421 
00422 void Slider::mousePressEvent( QMouseEvent *e )
00423 {
00424         QMouseEvent event( QEvent::MouseButtonPress, e->pos()-QPoint(int(x()),int(y())), e->button(), e->state() );
00425         m_slider->mousePressEvent(&event);
00426 
00427         if (event.isAccepted()) e->accept();
00428 
00429         canvas()->setChanged( rect() );
00430 }
00431 
00432 void Slider::mouseReleaseEvent( QMouseEvent *e )
00433 {
00434         QMouseEvent event( QEvent::MouseButtonRelease, e->pos()-QPoint(int(x()),int(y())), e->button(), e->state() );
00435         m_slider->mouseReleaseEvent(&event);
00436 
00437         if (event.isAccepted()) e->accept();
00438 
00439         canvas()->setChanged( rect() );
00440 }
00441 
00442 void Slider::mouseDoubleClickEvent ( QMouseEvent *e )
00443 {
00444         QMouseEvent event( QEvent::MouseButtonDblClick, e->pos()-QPoint(int(x()),int(y())), e->button(), e->state() );
00445         m_slider->mouseDoubleClickEvent(&event);
00446 
00447         if (event.isAccepted()) e->accept();
00448 
00449         canvas()->setChanged( rect() );
00450 }
00451 
00452 void Slider::mouseMoveEvent( QMouseEvent *e )
00453 {
00454         QMouseEvent event( QEvent::MouseMove, e->pos()-QPoint(int(x()),int(y())), e->button(), e->state() );
00455         m_slider->mouseMoveEvent(&event);
00456 
00457         if (event.isAccepted()) e->accept();
00458 }
00459 
00460 void Slider::wheelEvent( QWheelEvent *e )
00461 {
00462         QWheelEvent event( e->pos()-QPoint(int(x()),int(y())), e->delta(), e->state(), e->orientation() );
00463         m_slider->wheelEvent(&event);
00464 
00465         if (event.isAccepted())e->accept();
00466 
00467         canvas()->setChanged( rect() );
00468 }
00469 
00470 void Slider::enterEvent()
00471 {
00472         m_slider->enterEvent();
00473 }
00474 
00475 void Slider::leaveEvent()
00476 {
00477         m_slider->leaveEvent();
00478 }
00479 
00480 void Slider::slotValueChanged( int value )
00481 {
00482         parent()->itemDocument()->setModified(true);
00483         parent()->sliderValueChanged(id(),value);
00484 }
00485 
00486 void Slider::setOrientation( Qt::Orientation o )
00487 {
00488         m_orientation = o;
00489         posChanged();
00490 }
00491 
00492 void Slider::posChanged()
00493 {
00494         Widget::posChanged();
00495         
00496         if(m_orientation == Qt::Vertical )
00497                 m_slider->setOrientation( (m_angleDegrees%180 == 0) ? Qt::Vertical : Qt::Horizontal );
00498         else m_slider->setOrientation( (m_angleDegrees%180 == 0) ? Qt::Horizontal : Qt::Vertical );
00499 }
00500 
00501 //END Class Slider
00502 
00503 #include "canvasitemparts.moc"

Generated on Tue May 8 17:05:28 2007 for KTechLab by  doxygen 1.5.1