~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to arts/builder/module.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
        /*
 
2
 
 
3
        Copyright (C) 1998-1999 Stefan Westerfeld
 
4
                            stefan@space.twc.de
 
5
 
 
6
    This program is free software; you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation; either version 2 of the License, or
 
9
    (at your option) any later version.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program; if not, write to the Free Software
 
18
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 
 
20
    */
 
21
 
 
22
#include "module.h"
 
23
#include "drawutils.h"
 
24
#include "portablekde.h"
 
25
#include <stdio.h>
 
26
#include <arts/debug.h>
 
27
 
 
28
#include <kiconloader.h>
 
29
#include <algorithm>
 
30
 
 
31
using namespace std;
 
32
 
 
33
ModulePort::ModulePort(StructureComponent *owner, const string& description,
 
34
                                int drawsegment, Direction direction, Arts::PortDesc PortDesc)
 
35
{
 
36
        selected = false;
 
37
 
 
38
        this->owner = owner;                            // whats the syntax for that again?
 
39
        this->drawsegment = drawsegment;
 
40
        this->direction = direction;
 
41
        this->PortDesc = PortDesc;
 
42
        this->description = description.c_str();
 
43
 
 
44
        pdID = PortDesc.ID();
 
45
 
 
46
        isinitarg = (PortDesc.type().connType == Arts::conn_property);
 
47
        if(isinitarg) arts_debug("port %s is an init arg",(const char *)this->description);
 
48
        arts_debug("port %s created",(const char *)this->description);
 
49
        conntype = none;
 
50
        route_owner = 0;
 
51
}
 
52
 
 
53
bool ModulePort::down()
 
54
{
 
55
        return (PortDesc.isConnected() || PortDesc.hasValue() || selected);
 
56
}
 
57
 
 
58
QColor ModulePort::color(bool isInterface)
 
59
{
 
60
        if(selected) return QColor(255,165,0);
 
61
 
 
62
        if(PortDesc.hasValue())
 
63
        {
 
64
                if(isinitarg) return QColor(180,180,180);
 
65
                return QColor(100,100,255);
 
66
        }
 
67
 
 
68
        if(isinitarg) return QColor(128,128,128);
 
69
 
 
70
        if(isInterface) return QColor(100,100,100);
 
71
        return QColor(43,43,168);
 
72
}
 
73
 
 
74
Module::Module(Arts::ModuleDesc module, Arts::StructureDesc structuredesc,
 
75
                                        StructureCanvas *canvas) : StructureComponent(canvas)
 
76
{
 
77
        StructureDesc = structuredesc;
 
78
        ModuleDesc = module;
 
79
 
 
80
        _x = ModuleDesc.x();
 
81
        _y = ModuleDesc.y();
 
82
        initModule();
 
83
}
 
84
 
 
85
Module::Module(const Arts::ModuleInfo& minfo,Arts::StructureDesc structuredesc,
 
86
                                        StructureCanvas *canvas) : StructureComponent(canvas)
 
87
{
 
88
        StructureDesc = structuredesc;
 
89
        ModuleDesc = StructureDesc.createModuleDesc(minfo);
 
90
        
 
91
        initModule();
 
92
}
 
93
 
 
94
void Module::initModule()
 
95
{
 
96
        QString iconname;
 
97
        KIconLoader iconloader;
 
98
 
 
99
        _selected = false;
 
100
        _visible = false;
 
101
        _height = 1;
 
102
        _name = ModuleDesc.name().c_str();
 
103
        _pixmap = NULL;
 
104
 
 
105
// test if pixmap available
 
106
 
 
107
        iconname = _name+".xpm";
 
108
 
 
109
        _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User));
 
110
        if(!_pixmap->height())
 
111
        {
 
112
                delete _pixmap;
 
113
                _pixmap = 0;
 
114
        }
 
115
// try again without Arts:: - prefix
 
116
 
 
117
        if(iconname.startsWith("Arts::"))
 
118
        {
 
119
                iconname = iconname.mid(6);
 
120
 
 
121
                _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User));
 
122
                if(!_pixmap->height())
 
123
                {
 
124
                        delete _pixmap;
 
125
                        _pixmap = 0;
 
126
                }
 
127
        }
 
128
/*
 
129
        FILE *test=fopen(QFile::encodeName(iconname),"r");
 
130
        if(test)
 
131
        {
 
132
                pixmap = new QPixmap(iconname);
 
133
                fclose(test);
 
134
        }
 
135
*/
 
136
        
 
137
// create lists with inports & outports for this module
 
138
// and bind them to it ...
 
139
 
 
140
        arts_debug("Getting ports...");
 
141
        vector<Arts::PortDesc> *ports = ModuleDesc.ports();
 
142
        unsigned long portpos;
 
143
        long indraw = 1, outdraw = 2;
 
144
 
 
145
        for(portpos=0; portpos<ports->size(); portpos++)
 
146
        {
 
147
                Arts::PortDesc pd = (*ports)[portpos];
 
148
                ModulePort *p;
 
149
 
 
150
                arts_debug("CREATING %s",pd.name().c_str());
 
151
                switch(pd.type().direction)
 
152
                {
 
153
                        case Arts::input:
 
154
                                        p = new ModulePort(this,pd.name(),indraw++,
 
155
                                                        ModulePort::in,pd);
 
156
                                        inports.push_back(p);
 
157
                                break;
 
158
                        case Arts::output:
 
159
                                        p = new ModulePort(this,pd.name(),outdraw++,
 
160
                                                        ModulePort::out,pd);
 
161
                                        outports.push_back(p);
 
162
                                break;
 
163
                        default:
 
164
                                assert(false);  // shouldn't happen!
 
165
                }
 
166
        }
 
167
 
 
168
        delete ports;
 
169
 
 
170
        _width = 1+max(inports.size(),outports.size()+1);
 
171
 
 
172
        mdID = ModuleDesc.ID();
 
173
        isInterface = ModuleDesc.isInterface();
 
174
}
 
175
 
 
176
Module::~Module()
 
177
{
 
178
        arts_debug("hide...");
 
179
        hide();
 
180
        arts_debug("sdfmd...");
 
181
        list<ModulePort *>::iterator i;
 
182
        
 
183
        for(i=inports.begin(); i != inports.end(); i++) delete *i;
 
184
        inports.clear();
 
185
 
 
186
        for(i=outports.begin(); i != outports.end(); i++) delete *i;
 
187
        outports.clear();
 
188
 
 
189
        StructureDesc.freeModuleDesc(ModuleDesc);
 
190
        arts_debug("ok...");
 
191
}
 
192
 
 
193
StructureComponent::ComponentType Module::type()
 
194
{
 
195
        return ctModule;
 
196
}
 
197
 
 
198
bool Module::move(int newx, int newy)
 
199
{
 
200
        int oldx = _x, oldy = _y;
 
201
 
 
202
        _x = newx;
 
203
        _y = newy;
 
204
 
 
205
        canvas->redrawRect(oldx,oldy,_width,_height);
 
206
        canvas->redrawRect(_x,_y,_width,_height);
 
207
 
 
208
        return ModuleDesc.moveTo(_x,_y);
 
209
}
 
210
 
 
211
int Module::width()
 
212
{
 
213
        return _width;
 
214
}
 
215
 
 
216
int Module::height()
 
217
{
 
218
        return _height;
 
219
}
 
220
 
 
221
int Module::x()
 
222
{
 
223
        return _x;
 
224
}
 
225
 
 
226
int Module::y()
 
227
{
 
228
        return _y;
 
229
}
 
230
 
 
231
bool Module::selected()
 
232
{
 
233
        return _selected;
 
234
}
 
235
 
 
236
void Module::setSelected(bool newselection)
 
237
{
 
238
        if(newselection != _selected)
 
239
        {
 
240
                _selected = newselection;
 
241
                canvas->redrawRect(_x,_y,_width,_height);
 
242
        }
 
243
}
 
244
 
 
245
bool Module::drawNeedsBackground(int segment)
 
246
{
 
247
        return (segment==0);
 
248
}
 
249
 
 
250
void Module::drawSegment(QPainter *p, int cellsize, int segment)
 
251
{
 
252
        int border = cellsize / 10;  // for the logo
 
253
        int ltop = (cellsize-border)/2;
 
254
        int lbot = (cellsize+border)/2;
 
255
 
 
256
        QColor mcolor(43,43,168);
 
257
        QColor mcolorlight(164,176,242);
 
258
 
 
259
        if(isInterface)
 
260
        {
 
261
                mcolor = QColor(100,100,100);
 
262
                mcolorlight = QColor(160,160,160);
 
263
        }
 
264
    QColorGroup g( Qt::white, Qt::blue, mcolorlight, mcolor.dark(), mcolor,
 
265
                                                        Qt::black, Qt::black );
 
266
        QBrush fill( mcolor );
 
267
        QPen textpen(QColor(255,255,180),1);
 
268
 
 
269
        if(segment == 0)
 
270
        {
 
271
                qDrawShadePanel(p,border,border,cellsize-2*border+1,cellsize-2*border+1,
 
272
                        g, false, 1, &fill);
 
273
                p->fillRect(cellsize-border-1,ltop,cellsize,lbot-ltop+1,fill);
 
274
                p->setPen(g.light());
 
275
                p->drawLine(cellsize-border,ltop-1,cellsize,ltop-1);
 
276
                p->setPen(g.dark());
 
277
                p->drawLine(cellsize-border,lbot+1,cellsize,lbot+1);
 
278
                if(_pixmap)
 
279
                {
 
280
                        int destsize = (cellsize-4*border);
 
281
                        float sx = (float)destsize/(float)_pixmap->width();
 
282
                        float sy = (float)destsize/(float)_pixmap->height();
 
283
 
 
284
                        QWMatrix matrix;
 
285
                        matrix.scale(sx,sy);
 
286
                        QPixmap pmscaled = _pixmap->xForm(matrix);
 
287
                        p->drawPixmap(border*2,border*2,pmscaled);  
 
288
                }
 
289
                return;
 
290
        }
 
291
 
 
292
        p->fillRect(0,0,cellsize,cellsize,fill);
 
293
 
 
294
        /*
 
295
     * take care of the bevel lines around the module
 
296
     */
 
297
 
 
298
        p->setPen(g.light());
 
299
        p->drawLine(0,0,cellsize-1,0);
 
300
        if(segment < 2)
 
301
                p->drawLine(0,0,0,cellsize-1);
 
302
 
 
303
        p->setPen(g.dark());
 
304
        p->drawLine(cellsize-1,cellsize-1,0,cellsize-1);
 
305
        if(segment == 0 || segment == width()-1)
 
306
                p->drawLine(cellsize-1,cellsize-1,cellsize-1,0);
 
307
 
 
308
        /*
 
309
         * now draw the ports
 
310
         */
 
311
        int direction;
 
312
 
 
313
        for(direction = 0;direction < 2; direction++)
 
314
        {
 
315
                ModulePort *port = findPort(segment, direction);
 
316
 
 
317
                if(port)
 
318
                {
 
319
                        int border = cellsize/7;
 
320
                        int textwidth;
 
321
                        char *label = DrawUtils::cropText(p, port->description.ascii(),
 
322
                                                                                cellsize/2, textwidth);
 
323
 
 
324
                        QBrush pbrush(port->color(isInterface));
 
325
 
 
326
                        port->clickrect = QRect(border,direction * cellsize/2 + border,
 
327
                                cellsize/2-2*border, cellsize/2-2*border);
 
328
                        qDrawShadePanel(p, port->clickrect, g, port->down(), 2, &pbrush);
 
329
 
 
330
#if 0
 
331
                        QBrush fillport(fill);
 
332
                        if(port->isinitarg)
 
333
                        {
 
334
                                fillport = QColor(128,128,128);
 
335
                        }
 
336
 
 
337
                        if(port->selected)
 
338
                        {
 
339
                                QBrush fillorange(QColor(255,165,0));
 
340
                                qDrawShadePanel(p, port->clickrect, g,true,2,&fillorange);
 
341
                        }
 
342
                        else
 
343
                        {
 
344
                                if(port->PortDesc->isConnected())
 
345
                                {
 
346
                                        qDrawShadePanel(p, port->clickrect, g,true,2,&fillport);
 
347
                                }
 
348
                                else if(port->PortDesc->hasValue())
 
349
                                {
 
350
                                        QBrush fillp(QColor(100,100,255));
 
351
                                        if(port->isinitarg)
 
352
                                        {
 
353
                                                fillp = QColor(180,180,180);
 
354
                                        }
 
355
                                        qDrawShadePanel(p, port->clickrect, g,true,2,&fillp);
 
356
                                }
 
357
                                else    // not connected and no value();
 
358
                                   qDrawShadePanel(p, port->clickrect, g,false,2,&fillport);
 
359
                        }
 
360
#endif
 
361
 
 
362
                        p->setPen(textpen);
 
363
                        p->drawText((cellsize-border)/2,
 
364
                                                        (1+direction) * (cellsize/2)-border,label);
 
365
                }
 
366
        }
 
367
 
 
368
        /*
 
369
         * if it was the rightmost part of the module, it has the module name
 
370
         * and the connection to the logo as well
 
371
         */
 
372
 
 
373
        if(segment == 1)
 
374
        {
 
375
                // object type label
 
376
                int textwidth;
 
377
                char *label=DrawUtils::cropText(p, _name.ascii(), cellsize-4, textwidth);
 
378
 
 
379
                p->setPen(textpen);
 
380
                p->fillRect(1,cellsize-16,textwidth+7,15,QBrush(g.dark()));
 
381
                p->drawText(4,cellsize-5,label);
 
382
 
 
383
                // logo connection
 
384
                p->setPen(mcolor);
 
385
                p->drawLine(0,ltop,0,lbot);
 
386
        }
 
387
 
 
388
        /*
 
389
         * when selected, draw a line of white dots around the module
 
390
         */
 
391
 
 
392
        if(selected())
 
393
        {
 
394
                QPen pen(Qt::white,1,Qt::DotLine);
 
395
 
 
396
                p->setPen(pen);
 
397
                p->drawLine(0,0,cellsize-1,0);
 
398
                p->drawLine(0,cellsize-1,cellsize-1,cellsize-1);
 
399
                if (segment == 1)
 
400
                        p->drawLine(0,0,0,cellsize-1);
 
401
                if (segment == _width-1)
 
402
                        p->drawLine(cellsize-1,0,cellsize-1,cellsize-1);
 
403
        }
 
404
}
 
405
 
 
406
void Module::hide()
 
407
{
 
408
        if(_visible)
 
409
        {
 
410
                _visible = false;
 
411
                canvas->redrawRect(_x,_y,_width,_height);
 
412
        }
 
413
}
 
414
 
 
415
void Module::show()
 
416
{
 
417
        if(!_visible)
 
418
        {
 
419
                _visible = true;
 
420
                canvas->redrawRect(_x,_y,_width,_height);
 
421
        }
 
422
}
 
423
 
 
424
bool Module::visible()
 
425
{
 
426
        return _visible;
 
427
}
 
428
 
 
429
ModulePort *Module::findPort(int xoffset, int direction)
 
430
{
 
431
        list<ModulePort *> *ports;
 
432
        list<ModulePort *>::iterator i;
 
433
 
 
434
        long n;
 
435
 
 
436
        if(direction == 0) ports = &inports; else ports = &outports;
 
437
 
 
438
        i = ports->begin();
 
439
        n = xoffset-1-direction;
 
440
 
 
441
        if(n<(long)ports->size() && n>=0)
 
442
        {
 
443
                while(n>0) { n--; i++; }
 
444
                return(*i);
 
445
        }
 
446
        return(NULL);
 
447
}
 
448
 
 
449
ModulePort *Module::portAt(int segment, int x, int y)
 
450
{
 
451
        for(int direction = 0;direction < 2; direction++)
 
452
        {
 
453
                ModulePort *port = findPort(segment,direction);
 
454
                if(port)
 
455
                {
 
456
                        QPoint clickpoint(x,y);
 
457
                        if(port->clickrect.contains(clickpoint)) return port;
 
458
                }
 
459
        }
 
460
        return 0;
 
461
}
 
462
 
 
463
void Module::dumpPorts(list<ModulePort *>& ports)
 
464
{
 
465
        list<ModulePort *>::iterator i;
 
466
        for(i=inports.begin();i != inports.end();i++) ports.push_back(*i);
 
467
        for(i=outports.begin();i != outports.end();i++) ports.push_back(*i);
 
468
}
 
469
 
 
470
QPixmap *Module::pixmap()
 
471
{
 
472
        return _pixmap;
 
473
}
 
474
 
 
475
const char *Module::name()
 
476
{
 
477
        return _name;
 
478
}