|
|
|
/*
|
|
|
|
|
|
|
|
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 <arts/debug.h>
|
|
|
|
#include <tqpalette.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
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<Arts::PortType>::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<std::string>::iterator pni;
|
|
|
|
vector<Arts::PortType>::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<Arts::PortType>::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<StructureComponent *>::iterator i;
|
|
|
|
std::list<StructureComponent *> *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);
|
|
|
|
}
|