Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / QtCollider / primitives / prim_QWidget.cpp
blobce38e72c6960ba8a4f347b27bc60f67080d642f4
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 #include "primitives.h"
23 #include "../Slot.h"
24 #include "../QWidgetProxy.h"
25 #include "../Common.h"
27 #include <PyrKernel.h>
28 #include <SCBase.h>
30 #include <QWidget>
31 #include <QThread>
32 #include <QApplication>
33 #include <QDrag>
34 #include <QMimeData>
36 // WARNING these primitives have to always execute asynchronously, or Cocoa language client will
37 // hang.
39 namespace QtCollider {
41 QC_LANG_PRIMITIVE( QWidget_SetFocus, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g )
43 QWidgetProxy *proxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy( r ) );
45 QApplication::postEvent( proxy, new SetFocusEvent( IsTrue(a) ) );
47 return errNone;
50 QC_LANG_PRIMITIVE( QWidget_BringFront, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
51 QWidgetProxy *proxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy( r ) );
53 QApplication::postEvent( proxy,
54 new QEvent( (QEvent::Type) QtCollider::Event_Proxy_BringFront ) );
56 return errNone;
59 QC_LANG_PRIMITIVE( QWidget_Refresh, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
60 QWidgetProxy *proxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy( r ) );
62 if( !proxy->compareThread() ) return QtCollider::wrongThreadError();
64 proxy->refresh();
66 return errNone;
69 QC_LANG_PRIMITIVE( QWidget_MapToGlobal, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
70 QWidgetProxy *proxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy( r ) );
72 if( !proxy->compareThread() ) return QtCollider::wrongThreadError();
74 QWidget *w = proxy->widget();
75 if( !w ) return errNone;
77 QPoint pt( Slot::toPoint( a ).toPoint() );
78 pt = w->mapToGlobal( pt );
79 Slot::setPoint( r, pt );
81 return errNone;
84 QC_LANG_PRIMITIVE( QWidget_SetLayout, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
85 if( !isKindOfSlot( a, SC_CLASS(QLayout) ) ) return errWrongType;
87 QWidgetProxy *wProxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy(r) );
89 if( !wProxy->compareThread() ) return QtCollider::wrongThreadError();
91 QObjectProxy *lProxy = Slot::toObjectProxy( a );
92 wProxy->setLayout( lProxy );
94 return errNone;
97 QC_LANG_PRIMITIVE( QWidget_GetAlwaysOnTop, 0, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
98 QWidgetProxy *wProxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy(r) );
100 if( QThread::currentThread() != wProxy->thread() ) return errFailed;
102 SetBool( r, wProxy->alwaysOnTop() );
103 return errNone;
106 QC_LANG_PRIMITIVE( QWidget_SetAlwaysOnTop, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
107 QWidgetProxy *wProxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy(r) );
109 QApplication::postEvent( wProxy, new SetAlwaysOnTopEvent( IsTrue(a) ) );
111 return errNone;
114 struct MimeData : public QMimeData {
115 virtual ~MimeData() {
116 qcDebugMsg(1,"Drag data object destroyed, clearing QView.currentDrag.");
118 QtCollider::lockLang();
120 PyrClass *classView = getsym("View")->u.classobj;
121 PyrSymbol *symClearDrag = getsym("prClearCurrentDrag");
122 if( !classView || !symClearDrag ) return;
124 QtCollider::runLang( classView, symClearDrag );
126 QtCollider::unlockLang();
130 QC_LANG_PRIMITIVE( QWidget_StartDrag, 3, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
131 QWidgetProxy *wProxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy(r) );
132 if( !wProxy->compareThread() ) return QtCollider::wrongThreadError();
134 PyrSlot *data = a+1;
135 QString str = Slot::toString(a+2);
137 QMimeData *mime = new QtCollider::MimeData;
139 mime->setData( "application/supercollider", QByteArray() );
141 QColor color( Slot::toColor(data) );
142 if( color.isValid() )
143 mime->setColorData( QVariant(color) );
145 if( !str.isEmpty() )
146 mime->setText( str );
148 QApplication::postEvent( wProxy, new StartDragEvent( Slot::toString(a), mime ) );
150 return errNone;
153 QC_LANG_PRIMITIVE( QWidget_SetGlobalEventEnabled, 2, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
154 if( NotInt( a+0 ) ) return errWrongType;
155 int event = Slot::toInt(a+0);
156 bool enabled = IsTrue(a+1);
157 if( !enabled && !IsFalse(a+1) ) return errWrongType;
159 QWidgetProxy::setGlobalEventEnabled( (QWidgetProxy::GlobalEvent) event, enabled );
161 return errNone;
164 QC_LANG_PRIMITIVE( QWidget_SetAcceptsMouse, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
165 QWidgetProxy *proxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy(r) );
166 if( !proxy->compareThread() ) return QtCollider::wrongThreadError();
168 QWidget *w = proxy->widget();
169 if( !w ) return errNone;
171 bool accept = IsTrue(a);
172 w->setAttribute( Qt::WA_TransparentForMouseEvents, !accept );
174 return errNone;
177 QC_LANG_PRIMITIVE( QWidget_AcceptsMouse, 1, PyrSlot *r, PyrSlot *a, VMGlobals *g ) {
178 QWidgetProxy *proxy = qobject_cast<QWidgetProxy*>( Slot::toObjectProxy(r) );
179 if( !proxy->compareThread() ) return QtCollider::wrongThreadError();
181 QWidget *w = proxy->widget();
182 if( !w ) return errNone;
184 bool accept = !w->testAttribute( Qt::WA_TransparentForMouseEvents );
185 SetBool(r, accept);
187 return errNone;
190 void defineQWidgetPrimitives()
192 LangPrimitiveDefiner definer;
193 definer.define<QWidget_SetFocus>();
194 definer.define<QWidget_BringFront>();
195 definer.define<QWidget_Refresh>();
196 definer.define<QWidget_MapToGlobal>();
197 definer.define<QWidget_SetLayout>();
198 definer.define<QWidget_GetAlwaysOnTop>();
199 definer.define<QWidget_SetAlwaysOnTop>();
200 definer.define<QWidget_StartDrag>();
201 definer.define<QWidget_SetGlobalEventEnabled>();
202 definer.define<QWidget_AcceptsMouse>();
203 definer.define<QWidget_SetAcceptsMouse>();
206 } // namespace QtCollider