Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / QtCollider / QcWidgetFactory.h
blobc963ad18052410af4232c773e3aa4593354795d5
1 /************************************************************************
3 * Copyright 2010-2012 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 #ifndef QC_WIDGET_FACTORY_H
23 #define QC_WIDGET_FACTORY_H
25 #include "QcObjectFactory.h"
26 #include "QWidgetProxy.h"
28 #include <QMetaMethod>
29 #include <QLayout>
31 template <class QWIDGET>
32 class QcWidgetFactory : public QcObjectFactory<QWIDGET>
34 public:
36 virtual QObjectProxy *newInstance( PyrObject *scObject, QtCollider::Variant arg[10] ) {
38 // Omit the first two arguments - parent and bounds
40 QWIDGET *w;
42 if( arg[2].type() == QMetaType::Void ) {
43 w = new QWIDGET;
45 else {
46 QObject *obj = QWIDGET::staticMetaObject.newInstance(
47 arg[2].asGenericArgument(),
48 arg[3].asGenericArgument(),
49 arg[4].asGenericArgument(),
50 arg[5].asGenericArgument(),
51 arg[6].asGenericArgument(),
52 arg[7].asGenericArgument(),
53 arg[8].asGenericArgument(),
54 arg[9].asGenericArgument()
57 w = qobject_cast<QWIDGET*>(obj);
58 if( !w ) {
59 qcNoConstructorMsg( QcObjectFactory<QWIDGET>::metaObject(), 8, &arg[2] );
60 return 0;
64 // NOTE: performance: it is completely equal if parent is passed
65 // in constructor, or set later, but for some reason it is cheaper
66 // if it is set here, before setting other stuff like geometry, etc.
68 QObjectProxy *parentProxy( arg[0].value<QObjectProxy*>() );
69 QWidget *parent = parentProxy ? qobject_cast<QWidget*>( parentProxy->object() ) : 0;
71 if( parent )
73 const QMetaObject *mo = parent->metaObject();
74 int mi = mo->indexOfMethod( "addChild(QWidget*)" );
75 bool ok;
76 if( mi >= 0 )
78 QMetaMethod mm = mo->method( mi );
79 ok = mm.invoke( parent, Q_ARG(QWidget*, w) );
80 if(!ok)
82 qcErrorMsg("Could not set parent!");
83 delete w;
84 return 0;
87 else
89 if(parent->layout())
90 parent->layout()->addWidget(w);
91 else
92 w->setParent( parent );
96 // set requested geometry
98 QRect r( arg[1].value<QRectF>().toRect() );
99 if( r.size().isEmpty() ) r.setSize( w->sizeHint() );
101 w->setGeometry( r );
103 // automatically support drag and drop
105 w->setAcceptDrops( true );
107 // ensure visible:
109 if(parent && parent->isVisible()) w->show();
111 // create the proxy:
113 QObjectProxy *prox( proxy(w, scObject) );
115 return prox;
118 protected:
120 virtual QObjectProxy * proxy( QWIDGET *w, PyrObject *sc_obj )
122 QWidgetProxy *prox( new QWidgetProxy( w, sc_obj ) );
123 initialize( prox, w );
124 return prox;
127 virtual void initialize( QWidgetProxy *proxy, QWIDGET *obj ) {};
130 #define QC_DECLARE_QWIDGET_FACTORY( QWIDGET ) QC_DECLARE_FACTORY( QWIDGET, QcWidgetFactory<QWIDGET> )
132 #endif