class library: PriorityQueue - implement removeValue, hide array
[supercollider.git] / QtCollider / Slot.cpp
blob9a9fc1ef8d768f20504f2dfde444fc203c69251f
1 /************************************************************************
3 * Copyright 2010 Jakob Leben (jakob.leben@gmail.com)
5 * This file is part of SuperCollider Qt GUI.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ************************************************************************/
22 #include "Slot.h"
23 #include "QObjectProxy.h"
24 #include "Common.h"
26 #include <PyrObject.h>
27 #include <PyrKernel.h>
28 #include <GC.h>
29 #include <VMGlobals.h>
31 #include <QPalette>
32 #include <QWidget>
34 #include <qmath.h>
36 using namespace QtCollider;
38 static QPalette::ColorRole paletteColorRoles[] = {
39 QPalette::Window,
40 QPalette::WindowText,
41 QPalette::Button,
42 QPalette::ButtonText,
43 QPalette::Base,
44 QPalette::Text,
45 QPalette::Highlight,
46 QPalette::HighlightedText,
49 void Slot::setRect( PyrSlot *slot, const QRectF &r )
51 PyrObject *obj = instantiateObject( gMainVMGlobals->gc, class_Rect, 0, true, true );
52 SetObject( slot, obj );
54 PyrSlot *slots = obj->slots;
55 SetFloat( slots+0, r.x() );
56 SetFloat( slots+1, r.y() );
57 SetFloat( slots+2, r.width() );
58 SetFloat( slots+3, r.height() );
61 void Slot::setPoint( PyrSlot *slot, const QPointF &pt )
63 PyrObject *obj = instantiateObject( gMainVMGlobals->gc, class_Point, 0, true, true );
64 SetObject( slot, obj );
66 PyrSlot *slots = obj->slots;
67 SetFloat( slots+0, pt.x() );
68 SetFloat( slots+1, pt.y() );
71 void Slot::setSize( PyrSlot *slot, const QSizeF &sz )
73 PyrObject *obj = instantiateObject( gMainVMGlobals->gc, class_Size, 0, true, true );
74 SetObject( slot, obj );
76 PyrSlot *slots = obj->slots;
77 SetFloat( slots+0, sz.width() );
78 SetFloat( slots+1, sz.height() );
81 void Slot::setString( PyrSlot *slot, const QString& arg )
83 PyrString *str = newPyrString( gMainVMGlobals->gc,
84 arg.toStdString().c_str(), 0, true );
85 SetObject( slot, str );
88 void Slot::setColor( PyrSlot *slot, const QColor &c )
90 PyrObject *obj = instantiateObject( gMainVMGlobals->gc, class_Color, 0, true, true );
91 SetObject( slot, obj );
93 PyrSlot *slots = obj->slots;
94 SetFloat( slots+0, c.red() / 255.0 );
95 SetFloat( slots+1, c.green() / 255.0 );
96 SetFloat( slots+2, c.blue() / 255.0 );
97 SetFloat( slots+3, c.alpha() / 255.0 );
100 void Slot::setPalette( PyrSlot *slot, const QPalette &plt )
102 PyrGC *gc = gMainVMGlobals->gc;
103 PyrObject *obj = instantiateObject( gc, class_QPalette, 0, true, true );
104 SetObject( slot, obj );
106 PyrSlot *s = obj->slots;
108 for( int i=0; i<8; ++i, ++s ) {
109 setColor( s, plt.color( paletteColorRoles[i] ) );
110 gc->GCWrite( obj, s );
114 void Slot::setQObject( PyrSlot *s, QObject *o )
116 if( !o ) {
117 SetNil(s);
118 return;
121 QObjectProxy *proxy = QObjectProxy::fromObject(o);
122 if( proxy && proxy->scObject() )
123 SetObject( s, proxy->scObject() );
124 else
125 SetNil( s );
128 void Slot::setTreeWidgetItem( PyrSlot *s, const SafePtr<QcTreeWidget::Item> & itemPtr )
130 PyrObject *obj = instantiateObject( gMainVMGlobals->gc, class_QTreeViewItem, 0, true, true );
131 QcTreeWidget::Item::initialize( gMainVMGlobals, obj, itemPtr );
132 SetObject( s, obj );
135 void Slot::setVariantList( PyrSlot *slot, const VariantList& varList )
137 VMGlobals *g = gMainVMGlobals;
139 int count = varList.data.count();
141 PyrObject *array = newPyrArray( g->gc, count, 0, true );
142 SetObject( slot, array );
144 int i;
145 PyrSlot *s = array->slots;
146 for( i = 0; i < count; ++i, ++s ) {
147 if( !Slot::setVariant( s, varList.data[i] ) ) {
148 qcDebugMsg(1, "WARNING: Could not set one slot of array" );
150 array->size++;
151 g->gc->GCWrite( array, s );
155 bool Slot::setVariant( PyrSlot *slot, const QVariant &val )
157 bool b_val;
158 int type = val.userType();
160 switch( type ) {
161 case QMetaType::Bool:
162 b_val = val.toBool();
163 if( b_val ) SetTrue( slot );
164 else SetFalse( slot );
165 break;
167 case QMetaType::QPoint:
168 case QMetaType::QPointF:
169 Slot::setPoint( slot, val.toPointF() );
170 break;
172 case QMetaType::QSize:
173 case QMetaType::QSizeF:
174 Slot::setSize( slot, val.toSizeF() );
175 break;
177 case QMetaType::QRect:
178 case QMetaType::QRectF:
179 Slot::setRect( slot, val.toRectF() );
180 break;
182 case QMetaType::QString:
183 Slot::setString( slot, val.toString() );
184 break;
186 case QMetaType::QColor:
187 Slot::setColor( slot, val.value<QColor>() );
188 break;
190 case QMetaType::QPalette:
191 Slot::setPalette( slot, val.value<QPalette>() );
192 break;
194 case QMetaType::Float:
195 case QMetaType::Double:
196 SetFloat( slot, val.value<double>() );
197 break;
199 case QMetaType::Int:
200 SetInt( slot, val.toInt() );
201 break;
203 case QMetaType::QObjectStar:
204 Slot::setQObject( slot, val.value<QObject*>() );
205 break;
207 case QMetaType::QWidgetStar:
208 Slot::setQObject( slot, val.value<QWidget*>() );
209 break;
211 case QMetaType::Void:
212 SetNil( slot );
213 break;
215 default:
216 if( type == qMetaTypeId<PyrObject*>() ) {
217 SetObject( slot, val.value<PyrObject*>() );
219 else if( type == qMetaTypeId<VariantList>() ) {
220 Slot::setVariantList( slot, val.value<VariantList>() );
222 else if( type == qMetaTypeId<QcTreeWidget::ItemPtr>() ) {
223 Slot::setTreeWidgetItem( slot, val.value< QtCollider::SafePtr<QcTreeWidget::Item> >() );
225 else {
226 qcErrorMsg( "the QVariant could not be interpreted!" );
227 return false;
231 return true;
234 bool Slot::toBool( PyrSlot *slot )
236 return IsTrue( slot );
239 int Slot::toInt( PyrSlot *slot )
241 int i;
242 if( slotIntVal( slot, &i ) ) return 0;
243 return i;
246 float Slot::toFloat( PyrSlot *slot )
248 float f;
249 if( slotFloatVal( slot, &f ) ) return 0.f;
250 return f;
253 double Slot::toDouble( PyrSlot *slot )
255 double d;
256 if( slotDoubleVal( slot, &d ) ) return 0.0;
257 return d;
260 QString Slot::toString( PyrSlot *slot )
262 if( IsSym(slot) ) {
263 return QString( slotRawSymbol(slot)->name );
265 else if( isKindOfSlot( slot, class_String ) ) {
266 int len = slotRawObject( slot )->size;
267 return QString::fromAscii( slotRawString(slot)->s, len );
269 return QString();
272 QPointF Slot::toPoint( PyrSlot *slot )
274 if( !isKindOfSlot( slot, class_Point ) ) {
275 return QPointF();
277 PyrSlot *slots = slotRawObject( slot )->slots;
278 float x, y;
279 int err;
280 err = slotFloatVal( slots+0, &x ); if( err ) return QPointF();
281 err = slotFloatVal( slots+1, &y ); if( err ) return QPointF();
282 return QPointF( x, y );
285 QRectF Slot::toRect( PyrSlot *slot )
287 if( !isKindOfSlot( slot, class_Rect ) ) {
288 return QRectF();
291 PyrSlot *slots = slotRawObject( slot )->slots;
292 float bounds[4];
293 for( int i=0; i<4; ++i )
295 int err = slotFloatVal(slots + i, &bounds[i]);
296 if( err ) return QRectF();
299 return QRectF( bounds[0], bounds[1], bounds[2], bounds[3] );
302 QSizeF Slot::toSize( PyrSlot *slot )
304 if( !isKindOfSlot( slot, class_Size ) ) {
305 return QSizeF();
308 PyrSlot *slots = slotRawObject( slot )->slots;
309 float w = 0.f, h = 0.f;
310 slotFloatVal( slots+0, &w );
311 slotFloatVal( slots+1, &h );
313 return QSizeF( w, h );
316 QColor Slot::toColor( PyrSlot *slot )
318 if( !isKindOfSlot( slot, class_Color) )
319 return QColor();
321 PyrSlot *slots = slotRawObject(slot)->slots;
323 float r,g,b,a;
324 r = g = b = a = 0.f;
325 int err;
326 err = slotFloatVal(slots+0, &r);
327 if (err) return err;
328 err = slotFloatVal(slots+1, &g);
329 if (err) return err;
330 err = slotFloatVal(slots+2, &b);
331 if (err) return err;
332 err = slotFloatVal(slots+3, &a);
333 if (err) return err;
334 return QColor( r*255, g*255, b*255, a*255 );
337 QFont Slot::toFont( PyrSlot *slot )
339 if( !isKindOfSlot( slot, class_QFont ) )
340 return QFont();
342 PyrSlot *slots = slotRawObject(slot)->slots;
344 QString family = Slot::toString( slots+0 );
345 float fSize = Slot::toFloat( slots+1 );
346 bool bold = IsTrue( slots+2 );
347 bool italic = IsTrue( slots+3 );
348 bool isPtSize = IsTrue( slots+4 );
350 QFont f;
352 if( !family.isEmpty() ) f.setFamily( family );
354 if( fSize > 0.f ) {
355 if( isPtSize ) {
356 f.setPointSizeF( fSize );
358 else {
359 int pixSize = ( fSize > 1.f ? qRound(fSize) : 1 );
360 f.setPixelSize( pixSize );
364 f.setBold( bold );
366 f.setItalic( italic );
368 return f;
371 QPalette Slot::toPalette( PyrSlot *slot )
373 if( !isKindOfSlot( slot, class_QPalette ) )
374 return QPalette();
376 PyrSlot *slots = slotRawObject( slot )->slots;
377 QPalette palette;
379 for( int i=0; i<8; ++i, ++slots ) {
380 QColor c = Slot::toColor(slots);
381 if( !c.isValid() ) continue;
382 palette.setColor( paletteColorRoles[i], c );
385 return palette;
388 VariantList Slot::toVariantList( PyrSlot *slot )
390 if( isKindOfSlot( slot, class_Array ) ) {
391 PyrObject *obj = slotRawObject( slot );
392 PyrSlot *slots = obj->slots;
393 int size = obj->size;
394 VariantList list;
395 for( int i = 0; i < size; ++i, ++slots )
396 list.data << Slot::toVariant( slots );
397 return list;
399 else if( isKindOfSlot( slot, class_SymbolArray ) ) {
400 PyrSymbolArray *symarray = slotRawSymbolArray( slot );
401 PyrSymbol **symbols = symarray->symbols;
402 int size = symarray->size;
403 VariantList list;
404 for( int i = 0; i < size; ++i, ++symbols )
405 list.data << QVariant( QString( (*symbols)->name) );
406 return list;
409 return VariantList();
412 QObjectProxy* Slot::toObjectProxy( PyrSlot *slot )
414 if( !isKindOfSlot( slot, class_QObject ) ) return 0;
415 QObjectProxy *proxy = 0;
416 PyrSlot *proxySlot = slotRawObject( slot )->slots;
417 if( IsPtr( proxySlot ) ) proxy = (QObjectProxy*) slotRawPtr( proxySlot );
418 return proxy;
421 QcTreeWidget::ItemPtr Slot::toTreeWidgetItem( PyrSlot *slot )
423 if( !isKindOfSlot( slot, class_QTreeViewItem ) ) return QcTreeWidget::ItemPtr();
424 PyrSlot *ptrSlot = slotRawObject(slot)->slots+0;
425 if( IsPtr( ptrSlot ) ) {
426 QcTreeWidget::ItemPtr *safePtr = static_cast<QcTreeWidget::ItemPtr*>( slotRawPtr(ptrSlot) );
427 return *safePtr;
429 else {
430 return QcTreeWidget::ItemPtr();
434 QVariant Slot::toVariant( PyrSlot *slot )
436 QObjectProxy *proxy;
437 switch (GetTag(slot)) {
438 case tagChar :
439 case tagNil :
440 return QVariant();
441 case tagInt :
442 return QVariant( toInt(slot) );
443 case tagSym :
444 return QVariant( toString(slot) );
445 case tagFalse :
446 return QVariant( false );
447 case tagTrue :
448 return QVariant( true );
449 case tagObj :
451 if( isKindOfSlot( slot, class_String ) ) {
452 return QVariant( toString(slot) );
454 else if( isKindOfSlot( slot, class_Point ) ) {
455 return QVariant( toPoint( slot ) );
457 else if( isKindOfSlot( slot, class_Rect ) ) {
458 return QVariant( toRect(slot) );
460 else if( isKindOfSlot( slot, class_Size ) ) {
461 return QVariant( toSize(slot) );
463 else if( isKindOfSlot( slot, class_Color) ) {
464 return QVariant::fromValue<QColor>( toColor(slot) );
466 else if( isKindOfSlot( slot, class_QFont ) ) {
467 return QVariant::fromValue<QFont>( toFont(slot) );
469 else if( isKindOfSlot( slot, class_QPalette ) ) {
470 return QVariant::fromValue<QPalette>( toPalette(slot) );
472 else if( isKindOfSlot( slot, class_QObject ) ) {
473 proxy = toObjectProxy(slot);
474 return QVariant::fromValue<QObjectProxy*>( proxy );
476 else if( isKindOfSlot( slot, class_Array ) || isKindOfSlot( slot, class_SymbolArray ) ) {
477 return QVariant::fromValue<VariantList>( toVariantList(slot) );
479 else if( isKindOfSlot( slot, class_QTreeViewItem ) ) {
480 return QVariant::fromValue<QcTreeWidget::ItemPtr>( toTreeWidgetItem(slot) );
482 else {
483 qcErrorMsg("Could not interpret slot!");
484 return QVariant();
487 default:
488 return QVariant( toDouble( slot ) );
492 using namespace Slot;
494 void QtCollider::Variant::setData( PyrSlot *slot )
496 QObjectProxy *proxy;
497 switch (GetTag(slot)) {
498 case tagChar :
499 case tagNil :
500 _type = QMetaType::Void;
501 _ptr = 0;
502 break;
503 case tagInt :
504 _type = QMetaType::Int;
505 _ptr = new int( toInt(slot) );
506 break;
507 case tagSym :
508 _type = QMetaType::QString;
509 _ptr = new QString( toString(slot) );
510 break;
511 case tagFalse :
512 _type = QMetaType::Bool;
513 _ptr = new bool( false );
514 break;
515 case tagTrue :
516 _type = QMetaType::Bool;
517 _ptr = new bool( true );
518 break;
519 case tagObj :
521 if( isKindOfSlot( slot, class_String ) ) {
522 _type = QMetaType::QString;
523 _ptr = new QString( toString(slot) );
525 else if( isKindOfSlot( slot, class_Point ) ) {
526 _type = QMetaType::QPointF;
527 _ptr = new QPointF( toPoint(slot) );
529 else if( isKindOfSlot( slot, class_Rect ) ) {
530 _type = QMetaType::QRectF;
531 _ptr = new QRectF( toRect(slot) );
533 else if( isKindOfSlot( slot, class_Size ) ) {
534 _type = QMetaType::QSizeF;
535 _ptr = new QSizeF( toSize(slot) );
537 else if( isKindOfSlot( slot, class_Color) ) {
538 _type = QMetaType::QColor;
539 _ptr = new QColor( toColor(slot) );
541 else if( isKindOfSlot( slot, class_Array ) || isKindOfSlot( slot, class_SymbolArray ) ) {
542 _type = qMetaTypeId<VariantList>();
543 _ptr = new VariantList( toVariantList(slot) );
545 else if( isKindOfSlot( slot, class_QObject ) ) {
546 proxy = toObjectProxy(slot);
547 if( !proxy ) {
548 _type = QMetaType::Void;
549 _ptr = 0;
551 else {
552 _type = qMetaTypeId<QObjectProxy*>();
553 _ptr = new QObjectProxy*( proxy );
556 else if( isKindOfSlot( slot, class_QTreeViewItem ) ) {
557 _type = qMetaTypeId<QcTreeWidget::ItemPtr>();
558 _ptr = new QcTreeWidget::ItemPtr( toTreeWidgetItem(slot) );
560 else {
561 qcErrorMsg("Could not interpret slot!");
562 _type = QMetaType::Void;
563 _ptr = 0;
565 break;
567 default :
568 _type = QMetaType::Double;
569 _ptr = new double( toDouble(slot) );