1 /************************************************************************ 2 * 3 * Copyright 2010-2012 Jakob Leben (jakob.leben@gmail.com) 4 * 5 * This file is part of SuperCollider Qt GUI. 6 * 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 2 of the License, or 10 * (at your option) any later version. 11 * 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. 16 * 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/>. 19 * 20 ************************************************************************/ 21 22 #pragma once 23 24 #include "QcObjectFactory.h" 25 #include "QWidgetProxy.h" 26 27 #include <QMetaMethod> 28 #include <QLayout> 29 30 template <class QWIDGET> class QcWidgetFactory : public QcObjectFactory<QWIDGET> { 31 public: newInstance(PyrObject * scObject,QtCollider::MetaValue arg[10])32 virtual QObjectProxy* newInstance(PyrObject* scObject, QtCollider::MetaValue arg[10]) { 33 // Omit the first two arguments - parent and bounds 34 35 QWIDGET* w; 36 37 if (!arg[2].type()) { 38 w = new QWIDGET; 39 } else { 40 QObject* obj = QWIDGET::staticMetaObject.newInstance( 41 arg[2].toGenericArgument(), arg[3].toGenericArgument(), arg[4].toGenericArgument(), 42 arg[5].toGenericArgument(), arg[6].toGenericArgument(), arg[7].toGenericArgument(), 43 arg[8].toGenericArgument(), arg[9].toGenericArgument()); 44 45 w = qobject_cast<QWIDGET*>(obj); 46 if (!w) { 47 qcNoConstructorMsg(QcObjectFactory<QWIDGET>::metaObject(), 8, &arg[2]); 48 return 0; 49 } 50 } 51 52 // NOTE: performance: it is completely equal if parent is passed 53 // in constructor, or set later, but for some reason it is cheaper 54 // if it is set here, before setting other stuff like geometry, etc. 55 56 QWidget* parent = arg[0].value<QWidget*>(); 57 58 if (parent) { 59 const QMetaObject* mo = parent->metaObject(); 60 int mi = mo->indexOfMethod("addChild(QWidget*)"); 61 bool ok; 62 if (mi >= 0) { 63 QMetaMethod mm = mo->method(mi); 64 ok = mm.invoke(parent, Q_ARG(QWidget*, w)); 65 if (!ok) { 66 qcErrorMsg("Could not set parent!"); 67 delete w; 68 return 0; 69 } 70 } else { 71 if (parent->layout()) 72 parent->layout()->addWidget(w); 73 else 74 w->setParent(parent); 75 } 76 } 77 78 // set requested geometry 79 80 QRect r(arg[1].value<QRectF>().toRect()); 81 if (r.size().isEmpty()) 82 r.setSize(w->sizeHint()); 83 84 w->setGeometry(r); 85 86 // automatically support drag and drop 87 88 w->setAcceptDrops(true); 89 90 // ensure visible: 91 92 if (parent && parent->isVisible()) 93 w->show(); 94 95 // create the proxy: 96 97 QObjectProxy* prox(proxy(w, scObject)); 98 99 return prox; 100 } 101 102 protected: proxy(QWIDGET * w,PyrObject * sc_obj)103 virtual QObjectProxy* proxy(QWIDGET* w, PyrObject* sc_obj) { 104 QWidgetProxy* prox(new QWidgetProxy(w, sc_obj)); 105 initialize(prox, w); 106 return prox; 107 } 108 109 // avoid overload of virtual initialize( QObjectProxy *, QWIDGET * ) 110 using QcObjectFactory<QWIDGET>::initialize; 111 initialize(QWidgetProxy * proxy,QWIDGET * obj)112 virtual void initialize(QWidgetProxy* proxy, QWIDGET* obj) {}; 113 }; 114 115 #define QC_DECLARE_QWIDGET_FACTORY(QWIDGET) QC_DECLARE_FACTORY(QWIDGET, QcWidgetFactory<QWIDGET>) 116