summaryrefslogtreecommitdiffstats
path: root/src/picitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/picitem.cpp')
-rw-r--r--src/picitem.cpp397
1 files changed, 397 insertions, 0 deletions
diff --git a/src/picitem.cpp b/src/picitem.cpp
new file mode 100644
index 0000000..cbd7f1f
--- /dev/null
+++ b/src/picitem.cpp
@@ -0,0 +1,397 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 by David Saxton *
+ * *
+ * 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 <kdebug.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <qpainter.h>
+
+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, QPoint position, bool _onLeft, PinSettings * pinSettings )
+ : QCanvasRectangle(0)
+{
+ m_pinSettings = pinSettings;
+ view = _view;
+ onLeft = _onLeft;
+
+ connect( m_pinSettings, SIGNAL(settingsChanged()), this, SLOT(updateDrawing()) );
+
+ if ( QFontInfo(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( Qt::black );
+ calcTextRect();
+ show();
+}
+
+
+void PinItem::drawShape( QPainter& p )
+{
+ if (!m_pinSettings)
+ return;
+
+ if ( m_pinSettings->state() == PinSettings::ps_on )
+ {
+ if ( m_pinSettings->type() == PinSettings::pt_output )
+ setBrush( QColor( 255, 127, 127 ) );
+ else
+ setBrush( QColor( 255, 191, 191 ) );
+ }
+ else
+ setBrush( Qt::white );
+
+ p.drawRect(rect());
+
+ p.setFont(m_font);
+ p.setBrush( Qt::NoBrush );
+ QRect r = m_textRect;
+ if ( onLeft )
+ p.drawText( r, Qt::AlignLeft, m_pinSettings->id() );
+ else
+ p.drawText( r, Qt::AlignRight, m_pinSettings->id() );
+ QRect br = p.boundingRect( r, Qt::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;
+ QPointArray pa(3);
+ int midLeft = left + (8-PinDirArrow)/2;
+ int midRight = left + (8+PinDirArrow)/2;
+
+ if ( onLeft )
+ {
+ midLeft--;
+ midRight--;
+ }
+ else
+ {
+ midLeft++;
+ midRight++;
+ }
+
+ p.setBrush( Qt::black );
+
+ // Right facing arrow
+ if ( (m_pinSettings->type() == PinSettings::pt_input && onLeft) ||
+ (m_pinSettings->type() == PinSettings::pt_output && !onLeft) )
+ {
+ pa[0] = QPoint::QPoint( midRight, midY );
+ pa[1] = QPoint::QPoint( midLeft, midY - PinDirArrow );
+ pa[2] = QPoint::QPoint( midLeft, midY + PinDirArrow );
+ p.drawPolygon(pa);
+ p.drawLine ( left, midY, right, midY );
+ }
+ else // Left facing arrow
+ {
+ pa[0] = QPoint::QPoint( midLeft, midY );
+ pa[1] = QPoint::QPoint( midRight, midY - PinDirArrow );
+ pa[2] = QPoint::QPoint( midRight, midY + PinDirArrow );
+ p.drawPolygon(pa);
+ p.drawLine ( left, midY, right, midY );
+ }
+}
+
+
+QRect PinItem::boundingRect () const
+{
+ QRect r = m_textRect;
+ if ( onLeft )
+ r.setLeft( (int)x() - 10 );
+ else
+ r.setRight( (int)x() + PinLength + 10 );
+
+ return r;
+}
+
+
+QString 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 )
+{
+ QCanvasRectangle::moveBy( dx, dy );
+ calcTextRect();
+}
+
+
+void PinItem::calcTextRect()
+{
+ m_textRect = rect();
+ m_textRect.moveTop( m_textRect.top()-2 );
+ QRect br;
+
+ QWidget tmpWidget;
+ QPainter p(&tmpWidget);
+
+ p.setFont(m_font);
+
+ if (!m_pinSettings)
+ {
+ kdDebug() << "PinItem::textRect: No pinSettings!"<<endl;
+ return;
+ }
+ if ( onLeft )
+ {
+ m_textRect.setLeft( (int)x() + PinLength + 2 );
+ m_textRect.setRight( (int)x() + InnerWidth/2 );
+ br = p.boundingRect( m_textRect, Qt::AlignLeft, m_pinSettings->id() );
+ }
+ else
+ {
+ m_textRect.setLeft( m_textRect.right() - InnerWidth/2 );
+ m_textRect.setRight( (int)x() - 2 );
+ br = p.boundingRect( m_textRect, Qt::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", QRect( SidePadding-8, m_innerHeight+TopPadding+(BottomPadding-24)/2-1, InnerWidth+16, 24 ), i18n("Advanced...") );
+ addButton( "expandBtn", QRect( (TopPadding-22)/2, (TopPadding-22)/2, 22, 22 ), KGlobal::iconLoader()->loadIcon( "down", KIcon::Small ), true );
+ button("expandBtn")->setState(true);
+
+ move( 12, 12 );
+
+ QStringList pinIDs = microSettings->microInfo()->package()->pinIDs( PicPin::type_bidir | PicPin::type_input | PicPin::type_open );
+ QStringList::iterator it = pinIDs.begin();
+
+ for ( int i=0; i < numSide; ++i, ++it )
+ {
+ QPoint position( int(this->x()) + SidePadding - PinLength+1, int(y()) + TopPadding + (i+1)*PinWidth + i*PinSeparation );
+ const QString id = *it;
+ PinSettings *settings = microSettings->pinWithID(id);
+ m_pinItemList.append( new PinItem( dynamic_cast<FlowCodeDocument*>(icnDocument), position, true, settings ) );
+ }
+
+ for ( int i=0; i < numPins/2; ++i, ++it )
+ {
+ QPoint position( int(this->x()) + SidePadding + InnerWidth-1, int(y()) + TopPadding + m_innerHeight - ( (i+2)*PinWidth + i*PinSeparation ) );
+ const QString id = *it;
+ PinSettings *settings = microSettings->pinWithID(id);
+ m_pinItemList.append( new PinItem( dynamic_cast<FlowCodeDocument*>(icnDocument), position, false, settings ) );
+ }
+
+ setSelected(false);
+ setPen( Qt::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( QPainter & p )
+{
+ int _x = int(x());
+ int _y = int(y());
+
+ p.setBrush( QColor( 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, Qt::AlignVCenter, i18n("PIC Settings") );
+
+ if ( !m_bExpanded )
+ return;
+
+ // Draw rectangle to cut off pins
+ p.setBrush( QColor( 239, 255, 255 ) );
+ QRect 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);
+ QRect textRect( r.width()/-2, r.height()/-2, r.width(), r.height() );
+ p.drawText( textRect, Qt::AlignCenter, microSettings->microInfo()->id() );
+
+ p.rotate(-90);
+ p.translate( r.width()/-2 - r.x(), r.height()/-2 - r.y() );
+}
+
+
+void PicItem::buttonStateChanged( const QString &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, SIGNAL(okClicked()), this, SLOT(slotMicroSettingsDlgAccepted()) );
+ connect( dlg, SIGNAL(applyClicked()), this, 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"