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 ************************************************************************/
23 #include "QObjectProxy.h"
25 #include "primitives/prim_QPalette.hpp"
27 #include <PyrObject.h>
28 #include <PyrKernel.h>
30 #include <VMGlobals.h>
38 using namespace QtCollider
;
40 static QPalette::ColorRole paletteColorRoles
[] = {
48 QPalette::HighlightedText
,
51 void Slot::setRect( PyrSlot
*slot
, const QRectF
&r
)
53 PyrObject
*obj
= instantiateObject( gMainVMGlobals
->gc
, class_Rect
, 0, true, true );
54 SetObject( slot
, obj
);
56 PyrSlot
*slots
= obj
->slots
;
57 SetFloat( slots
+0, r
.x() );
58 SetFloat( slots
+1, r
.y() );
59 SetFloat( slots
+2, r
.width() );
60 SetFloat( slots
+3, r
.height() );
63 void Slot::setPoint( PyrSlot
*slot
, const QPointF
&pt
)
65 PyrObject
*obj
= instantiateObject( gMainVMGlobals
->gc
, class_Point
, 0, true, true );
66 SetObject( slot
, obj
);
68 PyrSlot
*slots
= obj
->slots
;
69 SetFloat( slots
+0, pt
.x() );
70 SetFloat( slots
+1, pt
.y() );
73 void Slot::setSize( PyrSlot
*slot
, const QSizeF
&sz
)
75 PyrObject
*obj
= instantiateObject( gMainVMGlobals
->gc
, class_Size
, 0, true, true );
76 SetObject( slot
, obj
);
78 PyrSlot
*slots
= obj
->slots
;
79 SetFloat( slots
+0, sz
.width() );
80 SetFloat( slots
+1, sz
.height() );
83 void Slot::setString( PyrSlot
*slot
, const QString
& arg
)
85 PyrString
*str
= newPyrString( gMainVMGlobals
->gc
,
86 arg
.toStdString().c_str(), 0, true );
87 SetObject( slot
, str
);
90 void Slot::setColor( PyrSlot
*slot
, const QColor
&c
)
92 PyrObject
*obj
= instantiateObject( gMainVMGlobals
->gc
, class_Color
, 0, true, true );
93 SetObject( slot
, obj
);
95 PyrSlot
*slots
= obj
->slots
;
96 SetFloat( slots
+0, c
.red() / 255.0 );
97 SetFloat( slots
+1, c
.green() / 255.0 );
98 SetFloat( slots
+2, c
.blue() / 255.0 );
99 SetFloat( slots
+3, c
.alpha() / 255.0 );
102 void Slot::setPalette( PyrSlot
*slot
, const QPalette
&plt
)
104 PyrGC
*gc
= gMainVMGlobals
->gc
;
105 PyrObject
*obj
= instantiateObject( gc
, class_QPalette
, 0, true, true );
106 SetObject( slot
, obj
);
108 QPalette_Init( gMainVMGlobals
, obj
, plt
);
111 void Slot::setQObject( PyrSlot
*s
, QObject
*o
)
118 QObjectProxy
*proxy
= QObjectProxy::fromObject(o
);
119 if( proxy
&& proxy
->scObject() )
120 SetObject( s
, proxy
->scObject() );
125 void Slot::setTreeWidgetItem( PyrSlot
*s
, const SafePtr
<QcTreeWidget::Item
> & itemPtr
)
127 PyrObject
*obj
= instantiateObject( gMainVMGlobals
->gc
, class_QTreeViewItem
, 0, true, true );
128 QcTreeWidget::Item::initialize( gMainVMGlobals
, obj
, itemPtr
);
132 void Slot::setVariantList( PyrSlot
*slot
, const VariantList
& varList
)
134 VMGlobals
*g
= gMainVMGlobals
;
136 int count
= varList
.data
.count();
138 PyrObject
*array
= newPyrArray( g
->gc
, count
, 0, true );
139 SetObject( slot
, array
);
142 PyrSlot
*s
= array
->slots
;
143 for( i
= 0; i
< count
; ++i
, ++s
) {
144 if( !Slot::setVariant( s
, varList
.data
[i
] ) ) {
145 qcDebugMsg(1, "WARNING: Could not set one slot of array" );
148 g
->gc
->GCWrite( array
, s
);
152 template<typename numeric_type
>
153 static void setNumeric( PyrSlot
*, numeric_type
);
157 void setNumeric
<double>( PyrSlot
*s
, double val
)
163 void setNumeric
<int>( PyrSlot
*s
, int val
)
168 template<typename numeric_type
>
169 static void setNumericVector( PyrSlot
*slot
, const QVector
<numeric_type
> & vec
)
171 VMGlobals
*g
= gMainVMGlobals
;
173 int count
= vec
.count();
175 PyrObject
*array
= newPyrArray( g
->gc
, count
, 0, true );
176 SetObject( slot
, array
);
178 PyrSlot
*s
= array
->slots
;
179 Q_FOREACH( numeric_type val
, vec
) {
180 setNumeric
<numeric_type
>( s
, val
);
186 bool Slot::setVariant( PyrSlot
*slot
, const QVariant
&val
)
189 int type
= val
.userType();
192 case QMetaType::Bool
:
193 b_val
= val
.toBool();
194 if( b_val
) SetTrue( slot
);
195 else SetFalse( slot
);
198 case QMetaType::QPoint
:
199 case QMetaType::QPointF
:
200 Slot::setPoint( slot
, val
.toPointF() );
203 case QMetaType::QSize
:
204 case QMetaType::QSizeF
:
205 Slot::setSize( slot
, val
.toSizeF() );
208 case QMetaType::QRect
:
209 case QMetaType::QRectF
:
210 Slot::setRect( slot
, val
.toRectF() );
213 case QMetaType::QString
:
214 Slot::setString( slot
, val
.toString() );
217 case QMetaType::QColor
:
218 Slot::setColor( slot
, val
.value
<QColor
>() );
221 case QMetaType::QPalette
:
222 Slot::setPalette( slot
, val
.value
<QPalette
>() );
225 case QMetaType::Float
:
226 case QMetaType::Double
:
227 SetFloat( slot
, val
.value
<double>() );
231 SetInt( slot
, val
.toInt() );
234 case QMetaType::QObjectStar
:
235 Slot::setQObject( slot
, val
.value
<QObject
*>() );
238 case QMetaType::QWidgetStar
:
239 Slot::setQObject( slot
, val
.value
<QWidget
*>() );
242 case QMetaType::Void
:
247 if( type
== qMetaTypeId
<PyrObject
*>() ) {
248 SetObject( slot
, val
.value
<PyrObject
*>() );
250 else if( type
== qMetaTypeId
<VariantList
>() ) {
251 Slot::setVariantList( slot
, val
.value
<VariantList
>() );
253 else if( type
== qMetaTypeId
< QVector
<double> >() ) {
254 setNumericVector( slot
, val
.value
< QVector
<double> >() );
256 else if( type
== qMetaTypeId
< QVector
<int> >() ) {
257 setNumericVector( slot
, val
.value
< QVector
<int> >() );
259 else if( type
== qMetaTypeId
<QcTreeWidget::ItemPtr
>() ) {
260 Slot::setTreeWidgetItem( slot
, val
.value
< QtCollider::SafePtr
<QcTreeWidget::Item
> >() );
263 qcErrorMsg( "the QVariant could not be interpreted!" );
271 bool Slot::toBool( PyrSlot
*slot
)
273 return IsTrue( slot
);
276 int Slot::toInt( PyrSlot
*slot
)
279 if( slotIntVal( slot
, &i
) ) return 0;
283 float Slot::toFloat( PyrSlot
*slot
)
286 if( slotFloatVal( slot
, &f
) ) return 0.f
;
290 double Slot::toDouble( PyrSlot
*slot
)
293 if( slotDoubleVal( slot
, &d
) ) return 0.0;
297 QString
Slot::toString( PyrSlot
*slot
)
300 return QString( slotRawSymbol(slot
)->name
);
302 else if( isKindOfSlot( slot
, class_String
) ) {
303 int len
= slotRawObject( slot
)->size
;
304 return QString::fromAscii( slotRawString(slot
)->s
, len
);
309 QPointF
Slot::toPoint( PyrSlot
*slot
)
311 if( !isKindOfSlot( slot
, class_Point
) ) {
314 PyrSlot
*slots
= slotRawObject( slot
)->slots
;
317 err
= slotFloatVal( slots
+0, &x
); if( err
) return QPointF();
318 err
= slotFloatVal( slots
+1, &y
); if( err
) return QPointF();
319 return QPointF( x
, y
);
322 QRectF
Slot::toRect( PyrSlot
*slot
)
324 if( !isKindOfSlot( slot
, class_Rect
) ) {
328 PyrSlot
*slots
= slotRawObject( slot
)->slots
;
330 for( int i
=0; i
<4; ++i
)
332 int err
= slotFloatVal(slots
+ i
, &bounds
[i
]);
333 if( err
) return QRectF();
336 return QRectF( bounds
[0], bounds
[1], bounds
[2], bounds
[3] );
339 QSizeF
Slot::toSize( PyrSlot
*slot
)
341 if( !isKindOfSlot( slot
, class_Size
) ) {
345 PyrSlot
*slots
= slotRawObject( slot
)->slots
;
346 float w
= 0.f
, h
= 0.f
;
347 slotFloatVal( slots
+0, &w
);
348 slotFloatVal( slots
+1, &h
);
350 return QSizeF( w
, h
);
353 namespace QtCollider
{
356 QColor
asColor( PyrObject
*obj
)
358 PyrSlot
*slots
= obj
->slots
;
363 err
= slotFloatVal(slots
+0, &r
);
364 if (err
) return QColor();
365 err
= slotFloatVal(slots
+1, &g
);
366 if (err
) return QColor();
367 err
= slotFloatVal(slots
+2, &b
);
368 if (err
) return QColor();
369 err
= slotFloatVal(slots
+3, &a
);
370 if (err
) return QColor();
371 return QColor( r
*255, g
*255, b
*255, a
*255 );
377 QColor
Slot::toColor( PyrSlot
*slot
)
379 if( NotObj(slot
) ) return QColor();
381 PyrObject
*obj
= slotRawObject(slot
);
382 PyrClass
*klass
= obj
->classptr
;
384 if( klass
== class_Color
)
387 if( klass
== SC_CLASS(Gradient
) || klass
== SC_CLASS(HiliteGradient
) )
389 qcWarningMsg("WARNING: Gradient and HiliteGradient are not supported yet."
390 " Using the average gradient color instead.");
392 QColor
c1( toColor(obj
->slots
+0) );
393 QColor
c2( toColor(obj
->slots
+1) );
394 QColor
mix( (c1
.red() + c2
.red()) / 2,
395 (c1
.green() + c2
.green()) / 2,
396 (c1
.blue() + c2
.blue()) / 2 );
403 QFont
Slot::toFont( PyrSlot
*slot
)
405 if( !isKindOfSlot( slot
, class_QFont
) )
408 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
410 QString family
= Slot::toString( slots
+0 );
411 float fSize
= Slot::toFloat( slots
+1 );
412 bool bold
= IsTrue( slots
+2 );
413 bool italic
= IsTrue( slots
+3 );
414 bool isPtSize
= IsTrue( slots
+4 );
418 if( !family
.isEmpty() ) f
.setFamily( family
);
422 f
.setPointSizeF( fSize
);
425 int pixSize
= ( fSize
> 1.f
? qRound(fSize
) : 1 );
426 f
.setPixelSize( pixSize
);
432 f
.setItalic( italic
);
437 QPalette
Slot::toPalette( PyrSlot
*slot
)
439 if( !isKindOfSlot( slot
, class_QPalette
) )
442 QPalette
*p
= QPALETTE_FROM_OBJECT(slotRawObject(slot
));
446 VariantList
Slot::toVariantList( PyrSlot
*slot
)
448 if( isKindOfSlot( slot
, class_Array
) ) {
449 PyrObject
*obj
= slotRawObject( slot
);
450 PyrSlot
*slots
= obj
->slots
;
451 int size
= obj
->size
;
453 for( int i
= 0; i
< size
; ++i
, ++slots
)
454 list
.data
<< Slot::toVariant( slots
);
457 else if( isKindOfSlot( slot
, class_SymbolArray
) ) {
458 PyrSymbolArray
*symarray
= slotRawSymbolArray( slot
);
459 PyrSymbol
**symbols
= symarray
->symbols
;
460 int size
= symarray
->size
;
462 for( int i
= 0; i
< size
; ++i
, ++symbols
)
463 list
.data
<< QVariant( QString( (*symbols
)->name
) );
467 return VariantList();
470 #define WRONG_OBJECT_FORMAT false
472 template<typename DEST
, typename ORIG
>
473 inline static void copy( QVector
<DEST
> & dest
, PyrSlot
*orig
, int size
)
475 ORIG
*array
= (ORIG
*) orig
;
476 for( int i
= 0; i
< size
; ++i
)
477 dest
<< DEST(array
[i
]);
480 template<typename numeric_type
>
481 static QVector
<numeric_type
> toNumericVector( PyrObject
*obj
)
483 int size
= obj
->size
;
484 PyrSlot
*slots
= obj
->slots
;
486 QVector
<numeric_type
> vector
;
487 vector
.reserve(size
);
489 switch (obj
->obj_format
) {
491 copy
<numeric_type
, double>( vector
, slots
, size
); break;
493 copy
<numeric_type
, float>( vector
, slots
, size
); break;
495 copy
<numeric_type
, int32
>( vector
, slots
, size
); break;
497 copy
<numeric_type
, int16
>( vector
, slots
, size
); break;
499 copy
<numeric_type
, int8
>( vector
, slots
, size
); break;
501 Q_ASSERT( WRONG_OBJECT_FORMAT
);
507 QObjectProxy
* Slot::toObjectProxy( PyrSlot
*slot
)
509 if( !isKindOfSlot( slot
, class_QObject
) ) return 0;
510 QObjectProxy
*proxy
= 0;
511 PyrSlot
*proxySlot
= slotRawObject( slot
)->slots
;
512 if( IsPtr( proxySlot
) ) proxy
= (QObjectProxy
*) slotRawPtr( proxySlot
);
516 QcTreeWidget::ItemPtr
Slot::toTreeWidgetItem( PyrSlot
*slot
)
518 if( !isKindOfSlot( slot
, class_QTreeViewItem
) ) return QcTreeWidget::ItemPtr();
519 PyrSlot
*ptrSlot
= slotRawObject(slot
)->slots
+0;
520 if( IsPtr( ptrSlot
) ) {
521 QcTreeWidget::ItemPtr
*safePtr
= static_cast<QcTreeWidget::ItemPtr
*>( slotRawPtr(ptrSlot
) );
525 return QcTreeWidget::ItemPtr();
529 QVariant
Slot::toVariant( PyrSlot
*slot
)
532 switch (GetTag(slot
)) {
537 return QVariant( toInt(slot
) );
539 return QVariant( toString(slot
) );
541 return QVariant( false );
543 return QVariant( true );
546 PyrObject
*obj
= slotRawObject(slot
);
547 PyrClass
*klass
= obj
->classptr
;
548 unsigned char format
= obj
->obj_format
;
550 if( format
== obj_double
|| format
== obj_float
)
551 return QVariant::fromValue
< QVector
<double> >( toNumericVector
<double>(obj
) );
553 else if( format
== obj_int32
|| format
== obj_int16
|| format
== obj_int8
)
554 return QVariant::fromValue
< QVector
<int> >( toNumericVector
<int>(obj
) );
556 else if( isKindOfSlot( slot
, class_String
) ) {
557 return QVariant( toString(slot
) );
559 else if( isKindOfSlot( slot
, class_Point
) ) {
560 return QVariant( toPoint( slot
) );
562 else if( isKindOfSlot( slot
, class_Rect
) ) {
563 return QVariant( toRect(slot
) );
565 else if( isKindOfSlot( slot
, class_Size
) ) {
566 return QVariant( toSize(slot
) );
568 else if( klass
== class_Color
||
569 klass
== SC_CLASS(Gradient
) ||
570 klass
== SC_CLASS(HiliteGradient
) )
572 return QVariant::fromValue
<QColor
>( toColor(slot
) );
574 else if( isKindOfSlot( slot
, class_QFont
) ) {
575 return QVariant::fromValue
<QFont
>( toFont(slot
) );
577 else if( isKindOfSlot( slot
, class_QPalette
) ) {
578 return QVariant::fromValue
<QPalette
>( toPalette(slot
) );
580 else if( isKindOfSlot( slot
, class_QObject
) ) {
581 proxy
= toObjectProxy(slot
);
582 return QVariant::fromValue
<QObjectProxy
*>( proxy
);
584 else if( isKindOfSlot( slot
, class_Array
) || isKindOfSlot( slot
, class_SymbolArray
) ) {
585 return QVariant::fromValue
<VariantList
>( toVariantList(slot
) );
587 else if( isKindOfSlot( slot
, class_QTreeViewItem
) ) {
588 return QVariant::fromValue
<QcTreeWidget::ItemPtr
>( toTreeWidgetItem(slot
) );
591 QString className
= Slot::toString( &slotRawObject(slot
)->classptr
->name
);
592 qcWarningMsg(QString("WARNING: Do not know how to use an instance of class '%1'").arg(className
));
597 return QVariant( toDouble( slot
) );
601 using namespace Slot
;
603 void QtCollider::Variant::setData( PyrSlot
*slot
)
606 switch (GetTag(slot
)) {
609 _type
= QMetaType::Void
;
613 _type
= QMetaType::Int
;
614 _ptr
= new int( toInt(slot
) );
617 _type
= QMetaType::QString
;
618 _ptr
= new QString( toString(slot
) );
621 _type
= QMetaType::Bool
;
622 _ptr
= new bool( false );
625 _type
= QMetaType::Bool
;
626 _ptr
= new bool( true );
630 PyrObject
*obj
= slotRawObject(slot
);
631 PyrClass
*klass
= obj
->classptr
;
632 unsigned char format
= obj
->obj_format
;
634 if( format
== obj_double
|| format
== obj_float
) {
635 _type
= qMetaTypeId
< QVector
<double> >();
636 _ptr
= new QVector
<double>( toNumericVector
<double>(obj
) );
638 else if( format
== obj_int32
|| format
== obj_int16
|| format
== obj_int8
) {
639 _type
= qMetaTypeId
< QVector
<int> >();
640 _ptr
= new QVector
<int>( toNumericVector
<int>(obj
) );
642 else if( isKindOfSlot( slot
, class_String
) ) {
643 _type
= QMetaType::QString
;
644 _ptr
= new QString( toString(slot
) );
646 else if( isKindOfSlot( slot
, class_Point
) ) {
647 _type
= QMetaType::QPointF
;
648 _ptr
= new QPointF( toPoint(slot
) );
650 else if( isKindOfSlot( slot
, class_Rect
) ) {
651 _type
= QMetaType::QRectF
;
652 _ptr
= new QRectF( toRect(slot
) );
654 else if( isKindOfSlot( slot
, class_Size
) ) {
655 _type
= QMetaType::QSizeF
;
656 _ptr
= new QSizeF( toSize(slot
) );
658 else if( klass
== class_Color
||
659 klass
== SC_CLASS(Gradient
) ||
660 klass
== SC_CLASS(HiliteGradient
) )
662 _type
= QMetaType::QColor
;
663 _ptr
= new QColor( toColor(slot
) );
665 else if( isKindOfSlot( slot
, class_Array
) || isKindOfSlot( slot
, class_SymbolArray
) ) {
666 _type
= qMetaTypeId
<VariantList
>();
667 _ptr
= new VariantList( toVariantList(slot
) );
669 else if( isKindOfSlot( slot
, class_QObject
) ) {
670 proxy
= toObjectProxy(slot
);
672 _type
= QMetaType::Void
;
676 _type
= qMetaTypeId
<QObjectProxy
*>();
677 _ptr
= new QObjectProxy
*( proxy
);
680 else if( isKindOfSlot( slot
, class_QTreeViewItem
) ) {
681 _type
= qMetaTypeId
<QcTreeWidget::ItemPtr
>();
682 _ptr
= new QcTreeWidget::ItemPtr( toTreeWidgetItem(slot
) );
685 QString className
= Slot::toString( &slotRawObject(slot
)->classptr
->name
);
686 qcWarningMsg(QString("WARNING: Do not know how to use an instance of class '%1'").arg(className
));
687 _type
= QMetaType::Void
;
693 _type
= QMetaType::Double
;
694 _ptr
= new double( toDouble(slot
) );