/*************************************************************************** * Copyright (C) 2003-2005 by David Saxton * * david@bluehaze.org * * * * 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. * ***************************************************************************/ #include "canvasitemparts.h" #include "flowcodedocument.h" #include "microinfo.h" #include "microsettings.h" #include "microsettingsdlg.h" #include "micropackage.h" #include "picitem.h" #include #include #include #include static const int InnerWidth = 88; static const int SidePadding = 24; static const int TopPadding = 36; static const int BottomPadding = 42; static const int PinWidth = 12; static const int PinSeparation = 16 - PinWidth; static const int PinLength = 8; static const int ArcWidth = 22; static const int PinDirArrow = 3; //BEGIN class PinItem PinItem::PinItem( FlowCodeDocument* _view, TQPoint position, bool _onLeft, PinSettings * pinSettings ) : TQCanvasRectangle(0) { m_pinSettings = pinSettings; view = _view; onLeft = _onLeft; connect( m_pinSettings, TQT_SIGNAL(settingsChanged()), this, TQT_SLOT(updateDrawing()) ); if ( TQFontInfo(m_font).pixelSize() > 11 ) // It has to be > 11, not > 12, as (I think) pixelSize() rounds off the actual size m_font.setPixelSize(12); setCanvas( view->canvas() ); move ( position.x(), position.y() ); initItem(); setZ( (ICNDocument::Z::RaisedItem + ICNDocument::Z::ResizeHandle)/2 + 1 ); // Hackish, but whatever } int PinItem::rtti() const { return ItemDocument::RTTI::Pin; } void PinItem::updateDrawing() { update(); } void PinItem::initItem() { setSize( PinLength, PinWidth ); setSelected(false); setPen( TQt::black ); calcTextRect(); show(); } void PinItem::drawShape( TQPainter& p ) { if (!m_pinSettings) return; if ( m_pinSettings->state() == PinSettings::ps_on ) { if ( m_pinSettings->type() == PinSettings::pt_output ) setBrush( TQColor( 255, 127, 127 ) ); else setBrush( TQColor( 255, 191, 191 ) ); } else setBrush( TQt::white ); p.drawRect(rect()); p.setFont(m_font); p.setBrush( TQt::NoBrush ); TQRect r = m_textRect; if ( onLeft ) p.drawText( r, TQt::AlignLeft, m_pinSettings->id() ); else p.drawText( r, TQt::AlignRight, m_pinSettings->id() ); TQRect br = p.boundingRect( r, TQt::AlignLeft, m_pinSettings->id() ); int left; int right; if ( onLeft ) { right = (int)x(); left = right - 8; } else { left = (int)x() + PinLength; right = left + 8; } int midY = (int)y() + PinWidth/2; TQPointArray pa(3); int midLeft = left + (8-PinDirArrow)/2; int midRight = left + (8+PinDirArrow)/2; if ( onLeft ) { midLeft--; midRight--; } else { midLeft++; midRight++; } p.setBrush( TQt::black ); // Right facing arrow if ( (m_pinSettings->type() == PinSettings::pt_input && onLeft) || (m_pinSettings->type() == PinSettings::pt_output && !onLeft) ) { pa[0] = TQPoint( midRight, midY ); pa[1] = TQPoint( midLeft, midY - PinDirArrow ); pa[2] = TQPoint( midLeft, midY + PinDirArrow ); p.drawPolygon(pa); p.drawLine ( left, midY, right, midY ); } else // Left facing arrow { pa[0] = TQPoint( midLeft, midY ); pa[1] = TQPoint( midRight, midY - PinDirArrow ); pa[2] = TQPoint( midRight, midY + PinDirArrow ); p.drawPolygon(pa); p.drawLine ( left, midY, right, midY ); } } TQRect PinItem::boundingRect () const { TQRect r = m_textRect; if ( onLeft ) r.setLeft( (int)x() - 10 ); else r.setRight( (int)x() + PinLength + 10 ); return r; } TQString PinItem::id() { return m_pinSettings->id(); } void PinItem::switchState() { if ( m_pinSettings->state() == PinSettings::ps_on ) m_pinSettings->setState(PinSettings::ps_off); else m_pinSettings->setState(PinSettings::ps_on); update(); } void PinItem::dragged( int dx ) { if ( (onLeft && dx > 0) || (!onLeft && dx < 0) ) { m_pinSettings->setType(PinSettings::pt_input); } else m_pinSettings->setType(PinSettings::pt_output); update(); } void PinItem::moveBy ( double dx, double dy ) { TQCanvasRectangle::moveBy( dx, dy ); calcTextRect(); } void PinItem::calcTextRect() { m_textRect = rect(); m_textRect.moveTop( m_textRect.top()-2 ); TQRect br; TQWidget tmpWidget; TQPainter p(&tmpWidget); p.setFont(m_font); if (!m_pinSettings) { kdDebug() << "PinItem::textRect: No pinSettings!"<id() ); } else { m_textRect.setLeft( m_textRect.right() - InnerWidth/2 ); m_textRect.setRight( (int)x() - 2 ); br = p.boundingRect( m_textRect, TQt::AlignRight, m_pinSettings->id() ); } } //END class PinItem //BEGIN class PicItem PicItem::PicItem( ICNDocument *icnDocument, bool newItem, const char *id, MicroSettings *_microSettings ) : CNItem( icnDocument, newItem, id ? id : "picitem" ) { m_name = "PIC"; m_type = typeString(); p_icnDocument = icnDocument; icnDocument->registerItem(this); microSettings = _microSettings; const int numPins = microSettings->microInfo()->package()->pinCount( PicPin::type_bidir | PicPin::type_input | PicPin::type_open ); const int numSide = (numPins/2) + (numPins%2); m_bExpanded = true; m_innerHeight = (numSide+2)*PinWidth + (numSide-1)*PinSeparation; updateVisibility(); addButton( "settings", TQRect( SidePadding-8, m_innerHeight+TopPadding+(BottomPadding-24)/2-1, InnerWidth+16, 24 ), i18n("Advanced...") ); addButton( "expandBtn", TQRect( (TopPadding-22)/2, (TopPadding-22)/2, 22, 22 ), TDEGlobal::iconLoader()->loadIcon( "go-down", TDEIcon::Small ), true ); button("expandBtn")->setState(true); move( 12, 12 ); TQStringList pinIDs = microSettings->microInfo()->package()->pinIDs( PicPin::type_bidir | PicPin::type_input | PicPin::type_open ); TQStringList::iterator it = pinIDs.begin(); for ( int i=0; i < numSide; ++i, ++it ) { TQPoint position( int(this->x()) + SidePadding - PinLength+1, int(y()) + TopPadding + (i+1)*PinWidth + i*PinSeparation ); const TQString id = *it; PinSettings *settings = microSettings->pinWithID(id); m_pinItemList.append( new PinItem( dynamic_cast(icnDocument), position, true, settings ) ); } for ( int i=0; i < numPins/2; ++i, ++it ) { TQPoint position( int(this->x()) + SidePadding + InnerWidth-1, int(y()) + TopPadding + m_innerHeight - ( (i+2)*PinWidth + i*PinSeparation ) ); const TQString id = *it; PinSettings *settings = microSettings->pinWithID(id); m_pinItemList.append( new PinItem( dynamic_cast(icnDocument), position, false, settings ) ); } setSelected(false); setPen( TQt::black ); updateZ(-1); update(); show(); } PicItem::~PicItem() { const PinItemList::iterator end = m_pinItemList.end(); for ( PinItemList::iterator it = m_pinItemList.begin(); it != end; ++it ) delete *it; m_pinItemList.clear(); } void PicItem::updateZ( int baseZ ) { (void)baseZ; setZ( (ICNDocument::Z::RaisedItem + ICNDocument::Z::ResizeHandle)/2 ); // Hackish, but whatever button("settings")->setZ( z()+1 ); button("expandBtn")->setZ( z()+1 ); } void PicItem::drawShape( TQPainter & p ) { int _x = int(x()); int _y = int(y()); p.setBrush( TQColor( 0xef, 0xff, 0xef ) ); p.setFont( font() ); p.drawRoundRect( _x, _y, width(), height(), 2000/width(), 2000/height() ); p.drawText( _x+TopPadding-2, _y, width()-TopPadding+2, TopPadding, TQt::AlignVCenter, i18n("PIC Settings") ); if ( !m_bExpanded ) return; // Draw rectangle to cut off pins p.setBrush( TQColor( 239, 255, 255 ) ); TQRect r( _x+SidePadding, _y+TopPadding, InnerWidth, m_innerHeight ); p.drawRect(r); // Draw dimple thingy at end of pic p.drawArc( r.x()+(r.width()-ArcWidth)/2, r.y()+1-ArcWidth/2, ArcWidth, ArcWidth, 180*16, 180*16 ); // Draw vertical text centered in PIC p.translate( r.width()/2 + r.x(), r.height()/2 + r.y() ); p.rotate(90); TQRect textRect( r.width()/-2, r.height()/-2, r.width(), r.height() ); p.drawText( textRect, TQt::AlignCenter, microSettings->microInfo()->id() ); p.rotate(-90); p.translate( r.width()/-2 - r.x(), r.height()/-2 - r.y() ); } void PicItem::buttonStateChanged( const TQString &id, bool state ) { if ( id == "expandBtn" ) { m_bExpanded = state; updateVisibility(); } else if ( id == "settings" ) { if (!state) return; // Redraw button button("settings")->setState(false); update(); MicroSettingsDlg *dlg = new MicroSettingsDlg( microSettings, 0L, "microSettingsDlg" ); connect( dlg, TQT_SIGNAL(okClicked()), this, TQT_SLOT(slotMicroSettingsDlgAccepted()) ); connect( dlg, TQT_SIGNAL(applyClicked()), this, TQT_SLOT(slotMicroSettingsDlgAccepted()) ); dlg->show(); // At this point the PIC is selected but this does not appear to the // user so we must deselect it when done. p_icnDocument->unselectAll(); } } void PicItem::updateVisibility() { if (m_bExpanded) setSize( 0, 0, InnerWidth+(2*SidePadding), m_innerHeight+TopPadding+BottomPadding, true ); else setSize( 0, 0, InnerWidth+(2*SidePadding), TopPadding, true ); const PinItemList::iterator end = m_pinItemList.end(); for ( PinItemList::iterator it = m_pinItemList.begin(); it != end; ++it ) (*it)->setVisible(m_bExpanded); if ( Button * btn = button("settings") ) btn->setVisible(m_bExpanded); } void PicItem::slotMicroSettingsDlgAccepted() { const PinItemList::iterator end = m_pinItemList.end(); for ( PinItemList::iterator it = m_pinItemList.begin(); it != end; ++it ) canvas()->setChanged( (*it)->boundingRect() ); p_icnDocument->requestStateSave(); } //END class PicItem #include "picitem.moc"