/* Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "createtool.h" #include "mwidget.h" #include "structureport.h" //#include #include #include #include #include MWidgetTool::MWidgetTool(ModuleWidget *mwidget) { this->mwidget = mwidget; } MWidgetTool::~MWidgetTool() { } CreateTool::CreateTool(ModuleWidget *mwidget) : MWidgetTool(mwidget) { oldCursor = mwidget->cursor(); mwidget->setCursor(TQt::crossCursor); oldMouseTracking = mwidget->hasMouseTracking(); mwidget->setMouseTracking(true); width = -1; height = -1; componentRect = TQRect(0, 0, 0, 0); } CreateTool::~CreateTool() { mwidget->repaint(componentRect); mwidget->setCursor(oldCursor); mwidget->setMouseTracking(oldMouseTracking); } void CreateTool::mousePressEvent(TQMouseEvent *e) { int x = mwidget->findCol(e->x()); int y = mwidget->findRow(e->y()); if(x < 0 || y < 0) return; if( e->button() == Qt::LeftButton ) performCreate(x, y); // well, perhaps make this an option mwidget->leaveTool(this); } void CreateTool::mouseMoveEvent(TQMouseEvent *e) { if(width == -1) estimateSize(); int x = mwidget->findCol(e->x()); int y = mwidget->findRow(e->y()); if(x < 0 || y < 0) return; int cellx, celly, cellx2, celly2; bool posok = mwidget->colXPos(x, &cellx) && mwidget->rowYPos(y, &celly) && mwidget->colXPos(x + width, &cellx2) && mwidget->rowYPos(y + height, &celly2); if(!posok) return; mwidget->repaint(componentRect); componentRect = TQRect(cellx, celly, cellx2 - cellx, celly2 - celly); TQPainter *p = new TQPainter; p->begin(mwidget); p->save(); p->drawRect(componentRect); p->restore(); p->end(); delete p; } void CreateTool::mouseReleaseEvent(TQMouseEvent *e) { } // module creation void CreateModuleTool::estimateSize() { // yes, this is a it ugly: we create here the new module for a microsecond, // just to see how big it is, to be able to paint an accurate preview // // We delete it again, and if the user finally really creates the module // we recreate it. mwidget->unselectAll(); Module *newModule = mwidget->theStructure()->createModule(minfo); width = newModule->width(); height = newModule->height(); newModule->setSelected(true); mwidget->theStructure()->deleteSelected(); } void CreateModuleTool::performCreate(int x, int y) { mwidget->unselectAll(); Module *newModule = mwidget->theStructure()->createModule(minfo); newModule->setSelected(true); newModule->move(x, y); if(!mwidget->insertModule(newModule)) mwidget->theStructure()->deleteSelected(); } CreateModuleTool::CreateModuleTool(ModuleWidget *mwidget, const Arts::ModuleInfo& minfo) : CreateTool(mwidget) { this->minfo = minfo; } CreateModuleTool::~CreateModuleTool() { } // interface creation void CreateInterfaceTool::estimateSize() { vector::iterator pi; int input_width = 0; int output_width = 0; for(pi = minfo.ports.begin(); pi != minfo.ports.end(); ++pi) { if(pi->direction == Arts::input) input_width++; if(pi->direction == Arts::output) output_width++; } width = max(input_width, output_width); height = 5; } void CreateInterfaceTool::performCreate(int x, int y) { vector::iterator pni; vector::iterator pi; mwidget->theStructure()->addInheritedInterface(minfo.name.c_str()); int input_width = 0; int output_width = 0; for(pi = minfo.ports.begin(), pni = minfo.portnames.begin(); pi != minfo.ports.end(); ++pi, pni++) { StructurePort *port = 0; /* * watch out: input ports (as in ports that accept data) are on the lower * side of the structure, as the data flows out trough them ;) */ if(pi->direction == Arts::input) { port = mwidget->insertPort(*pi, x + input_width, y + 4); input_width++; } else if(pi->direction == Arts::output) { port = mwidget->insertPort(*pi, x + output_width, y); output_width++; } assert(port); port->rename(pni->c_str()); port->inheritedInterface(minfo.name.c_str()); } } CreateInterfaceTool::CreateInterfaceTool(ModuleWidget *mwidget, const Arts::ModuleInfo& minfo) : CreateTool(mwidget) { this->minfo = minfo; vector::iterator pi; for(pi = this->minfo.ports.begin(); pi != this->minfo.ports.end(); ++pi) { /* reverse since we're inside the interface, not outside */ if(pi->direction == Arts::input) pi->direction = Arts::output; else if(pi->direction == Arts::output) pi->direction = Arts::input; } } CreateInterfaceTool::~CreateInterfaceTool() { } // port creation void CreatePortTool::estimateSize() { width = height = 1; } void CreatePortTool::performCreate(int x, int y) { mwidget->insertPort(type, x, y); } CreatePortTool::CreatePortTool(ModuleWidget *mwidget, const Arts::PortType& type) : CreateTool(mwidget) { this->type = type; } MoveComponentsTool::MoveComponentsTool(ModuleWidget *widget, TQMouseEvent *e) : MWidgetTool(widget), lastPos(e->pos()) { } void MoveComponentsTool::mousePressEvent(TQMouseEvent *e) { } void MoveComponentsTool::mouseMoveEvent(TQMouseEvent *e) { int dx = (e->x() - lastPos.x())/mwidget->cellsize; int dy = (e->y() - lastPos.y())/mwidget->cellsize; if(dx == 0 && dy == 0) return; std::list::iterator i; std::list *ComponentList = mwidget->structure->getComponentList(); for(i = ComponentList->begin();i != ComponentList->end();++i) { StructureComponent *c = *i; if(c->selected() && !mwidget->hasSpace(c, c->x() + dx, c->y() + dy, true)) return; } mwidget->beginUpdate(); for(i = ComponentList->begin();i != ComponentList->end();++i) { StructureComponent *c = *i; if(c->selected()) c->move(c->x() + dx, c->y() + dy); } mwidget->endUpdate(); lastPos.setX(lastPos.x() + dx*mwidget->cellsize); lastPos.setY(lastPos.y() + dy*mwidget->cellsize); mwidget->reRoute(); } void MoveComponentsTool::mouseReleaseEvent(TQMouseEvent *e) { mwidget->leaveTool(this, true); } ConnectPortsTool::ConnectPortsTool(ModuleWidget *widget, ModulePort *connectingPort) : MWidgetTool(widget), connectingPort(connectingPort) { firstPos = mwidget->portPos(connectingPort) + connectingPort->clickrect.center(); } void ConnectPortsTool::mousePressEvent(TQMouseEvent *e) { } void ConnectPortsTool::mouseMoveEvent(TQMouseEvent *e) { TQPainter painter(mwidget); painter.setPen(TQt::white); mwidget->repaint(TQRect(firstPos, lastPos).normalize()); painter.drawLine(firstPos, e->pos()); lastPos = e->pos(); } void ConnectPortsTool::mouseReleaseEvent(TQMouseEvent *e) { StructureComponent *component; ModulePort *otherPort; mwidget->findAt(e->x(), e->y(), component, otherPort); if(otherPort && (otherPort!= connectingPort)) { // user is trying to close a connection if(connectingPort->direction == otherPort->direction) { KMessageBox::sorry(mwidget, i18n("You can only connect an IN-port with an OUT-port,\n" "not two ports with the same direction.")); } else { if(connectingPort->direction == ModulePort::in) { if(otherPort->PortDesc.connectTo(connectingPort->PortDesc)) mwidget->reRoute(); } else { if(connectingPort->PortDesc.connectTo(otherPort->PortDesc)) mwidget->reRoute(); } } } mwidget->repaint(TQRect(firstPos, lastPos).normalize()); mwidget->leaveTool(this); }