diff options
Diffstat (limited to 'arts/builder/module.cpp')
-rw-r--r-- | arts/builder/module.cpp | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/arts/builder/module.cpp b/arts/builder/module.cpp new file mode 100644 index 00000000..250ee3a2 --- /dev/null +++ b/arts/builder/module.cpp @@ -0,0 +1,439 @@ + /* + + Copyright (C) 1998-1999 Stefan Westerfeld + stefan@space.twc.de + + 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. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include "module.h" +#include "drawutils.h" +#include <stdio.h> +#include <arts/debug.h> + +#include <qpalette.h> +#include <qdrawutil.h> +#include <kiconloader.h> +#include <algorithm> + +using namespace std; + +ModulePort::ModulePort(StructureComponent *owner, const string& description, + int drawsegment, Direction direction, Arts::PortDesc PortDesc) +{ + selected = false; + + this->owner = owner; // whats the syntax for that again? + this->drawsegment = drawsegment; + this->direction = direction; + this->PortDesc = PortDesc; + this->description = description.c_str(); + + pdID = PortDesc.ID(); + + isinitarg = (PortDesc.type().connType == Arts::conn_property); + if(isinitarg) arts_debug("port %s is an init arg", (const char *)this->description.latin1()); + arts_debug("port %s created", (const char *)this->description.latin1()); + conntype = none; + route_owner = 0; +} + +bool ModulePort::down() +{ + return (PortDesc.isConnected() || PortDesc.hasValue() || selected); +} + +QColor ModulePort::color(bool isInterface) +{ + if(selected) return QColor(255, 165, 0); + + if(PortDesc.hasValue()) + { + if(isinitarg) return QColor(180, 180, 180); + return QColor(100, 100, 255); + } + + if(isinitarg) return QColor(128, 128, 128); + + if(isInterface) return QColor(100, 100, 100); + return QColor(43, 43, 168); +} + +Module::Module(Arts::ModuleDesc module, Arts::StructureDesc structuredesc, + StructureCanvas *canvas) : StructureComponent(canvas) +{ + StructureDesc = structuredesc; + ModuleDesc = module; + + _x = ModuleDesc.x(); + _y = ModuleDesc.y(); + initModule(); +} + +Module::Module(const Arts::ModuleInfo& minfo, Arts::StructureDesc structuredesc, + StructureCanvas *canvas) : StructureComponent(canvas) +{ + StructureDesc = structuredesc; + ModuleDesc = StructureDesc.createModuleDesc(minfo); + + initModule(); +} + +void Module::initModule() +{ + QString iconname; + KIconLoader iconloader; + + _selected = false; + _visible = false; + _height = 1; + _name = ModuleDesc.name().c_str(); + _pixmap = NULL; + +// test if pixmap available + + iconname = _name + ".xpm"; + + _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User)); + if(!_pixmap->height()) + { + iconname = _name + ".png"; + delete _pixmap; + _pixmap = new QPixmap( iconloader.loadIcon( iconname, KIcon::User ) ); + if( !_pixmap->height() ) + { + delete _pixmap; + _pixmap = 0; + } + } +// try again without Arts:: - prefix + + if(iconname.startsWith("Arts::")) + { + iconname = iconname.mid(6); + + _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User)); + if(!_pixmap->height()) + { + iconname.replace( iconname.length() - 4, 3, "png" ); + delete _pixmap; + _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User)); + if( !_pixmap->height() ) + { + delete _pixmap; + _pixmap = 0; + } + } + } +/* + FILE *test = fopen(QFile::encodeName(iconname), "r"); + if(test) + { + pixmap = new QPixmap(iconname); + fclose(test); + } +*/ + +// create lists with inports & outports for this module +// and bind them to it ... + + arts_debug("Getting ports..."); + vector<Arts::PortDesc >*ports = ModuleDesc.ports(); + unsigned long portpos; + long indraw = 1, outdraw = 2; + + for(portpos = 0; portpos < ports->size(); portpos++) + { + Arts::PortDesc pd = (*ports)[portpos]; + ModulePort *p; + + arts_debug("CREATING %s", pd.name().c_str()); + switch(pd.type().direction) + { + case Arts::input: + p = new ModulePort(this, pd.name(), indraw++, + ModulePort::in, pd); + inports.push_back(p); + break; + case Arts::output: + p = new ModulePort(this, pd.name(), outdraw++, + ModulePort::out, pd); + outports.push_back(p); + break; + default: + assert(false); // shouldn't happen! + } + } + + delete ports; + + _width = 1 + max(inports.size(), outports.size() + 1); + + mdID = ModuleDesc.ID(); + isInterface = ModuleDesc.isInterface(); +} + +Module::~Module() +{ + arts_debug("hide..."); + hide(); + arts_debug("sdfmd..."); + list<ModulePort *>::iterator i; + + for(i = inports.begin(); i != inports.end(); ++i) delete *i; + inports.clear(); + + for(i = outports.begin(); i != outports.end(); ++i) delete *i; + outports.clear(); + + StructureDesc.freeModuleDesc(ModuleDesc); + arts_debug("ok..."); + delete _pixmap; +} + +bool Module::moveInternal(int x, int y) +{ + return ModuleDesc.moveTo(x, y); +} + +int Module::width() const +{ + return _width; +} + +int Module::height() const +{ + return _height; +} + +StructureComponent::ComponentType Module::type() +{ + return ctModule; +} + +bool Module::drawNeedsBackground(int segment) +{ + return (segment == 0); +} + +void Module::drawSegment(QPainter *p, int cellsize, int segment) +{ + int border = cellsize / 10; // for the logo + int ltop = (cellsize - border)/2; + int lbot = (cellsize + border)/2; + + QColor mcolor(43, 43, 168); + QColor mcolorlight(164, 176, 242); + + if(isInterface) + { + mcolor = QColor(100, 100, 100); + mcolorlight = QColor(160, 160, 160); + } + QColorGroup g( Qt::white, Qt::blue, mcolorlight, mcolor.dark(), mcolor, + Qt::black, Qt::black ); + QBrush fill( mcolor ); + QPen textpen(QColor(255, 255, 180), 1); + + if(segment == 0) + { + qDrawShadePanel(p, border, border, cellsize - 2*border + 1, cellsize - 2*border + 1, + g, false, 1, &fill); + p->fillRect(cellsize - border - 1, ltop, cellsize, lbot - ltop + 1, fill); + p->setPen(g.light()); + p->drawLine(cellsize - border, ltop - 1, cellsize, ltop - 1); + p->setPen(g.dark()); + p->drawLine(cellsize - border, lbot + 1, cellsize, lbot + 1); + if(_pixmap) + { + int destsize = (cellsize - 4*border); + float sx = (float)destsize/(float)_pixmap->width(); + float sy = (float)destsize/(float)_pixmap->height(); + + QWMatrix matrix; + matrix.scale(sx, sy); + QPixmap pmscaled = _pixmap->xForm(matrix); + p->drawPixmap(border*2, border*2, pmscaled); + } + return; + } + + p->fillRect(0, 0, cellsize, cellsize, fill); + + /* + * take care of the bevel lines around the module + */ + + p->setPen(g.light()); + p->drawLine(0, 0, cellsize - 1, 0); + if(segment < 2) + p->drawLine(0, 0, 0, cellsize - 1); + + p->setPen(g.dark()); + p->drawLine(cellsize - 1, cellsize - 1, 0, cellsize - 1); + if(segment == 0 || segment == width() - 1) + p->drawLine(cellsize - 1, cellsize - 1, cellsize - 1, 0); + + /* + * now draw the ports + */ + int direction; + + for(direction = 0;direction < 2; direction++) + { + ModulePort *port = findPort(segment, direction); + + if(port) + { + int border = cellsize/7; + int textwidth; + QString label = DrawUtils::cropText(p, port->description, + cellsize/2, textwidth); + + QBrush pbrush(port->color(isInterface)); + + port->clickrect = QRect(border, direction * cellsize/2 + border, + cellsize/2 - 2*border, cellsize/2 - 2*border); + qDrawShadePanel(p, port->clickrect, g, port->down(), 2, &pbrush); + +#if 0 + QBrush fillport(fill); + if(port->isinitarg) + { + fillport = QColor(128, 128, 128); + } + + if(port->selected) + { + QBrush fillorange(QColor(255, 165, 0)); + qDrawShadePanel(p, port->clickrect, g, true, 2, &fillorange); + } + else + { + if(port->PortDesc->isConnected()) + { + qDrawShadePanel(p, port->clickrect, g, true, 2, &fillport); + } + else if(port->PortDesc->hasValue()) + { + QBrush fillp(QColor(100, 100, 255)); + if(port->isinitarg) + { + fillp = QColor(180, 180, 180); + } + qDrawShadePanel(p, port->clickrect, g, true, 2, &fillp); + } + else // not connected and no value(); + qDrawShadePanel(p, port->clickrect, g, false, 2, &fillport); + } +#endif + + p->setPen(textpen); + p->drawText((cellsize - border)/2, + (1 + direction) * (cellsize/2) - border, label); + } + } + + /* + * if it was the rightmost part of the module, it has the module name + * and the connection to the logo as well + */ + + if(segment == 1) + { + // object type label + int textwidth; + QString label = DrawUtils::cropText(p, _name, cellsize - 4, textwidth); + + p->setPen(textpen); + p->fillRect(1, cellsize - 16, textwidth + 7, 15, QBrush(g.dark())); + p->drawText(4, cellsize - 5, label); + + // logo connection + p->setPen(mcolor); + p->drawLine(0, ltop, 0, lbot); + } + + /* + * when selected, draw a line of white dots around the module + */ + + if(selected()) + { + QPen pen(Qt::white, 1, Qt::DotLine); + + p->setPen(pen); + p->drawLine(0, 0, cellsize - 1, 0); + p->drawLine(0, cellsize - 1, cellsize - 1, cellsize - 1); + if(segment == 1) + p->drawLine(0, 0, 0, cellsize - 1); + if(segment == _width - 1) + p->drawLine(cellsize - 1, 0, cellsize - 1, cellsize - 1); + } +} + +ModulePort *Module::findPort(int xoffset, int direction) +{ + list<ModulePort *>*ports; + list<ModulePort *>::iterator i; + + long n; + + if(direction == 0) ports = &inports; else ports = &outports; + + i = ports->begin(); + n = xoffset - 1 - direction; + + if(n < (long)ports->size() && n >= 0) + { + while(n > 0) { n--; i++; } + return (*i); + } + return(NULL); +} + +ModulePort *Module::portAt(int segment, int x, int y) +{ + for(int direction = 0; direction < 2; direction++) + { + ModulePort *port = findPort(segment, direction); + if(port) + { + QPoint clickpoint(x, y); + if(port->clickrect.contains(clickpoint)) return port; + } + } + return 0; +} + +void Module::dumpPorts(list<ModulePort *>& ports) +{ + list<ModulePort *>::iterator i; + for(i = inports.begin(); i != inports.end(); ++i) ports.push_back(*i); + for(i = outports.begin(); i != outports.end(); ++i) ports.push_back(*i); +} + +QPixmap *Module::pixmap() +{ + return _pixmap; +} + +QString Module::name() +{ + return _name; +} + +// vim: sw=4 ts=4 noet |