1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=4 et sw=4 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include <QApplication>
11 #include <QGraphicsWidget>
12 #include <QGraphicsView>
13 #include "mozqglwidgetwrapper.h"
17 #ifdef MOZ_ENABLE_MEEGOTOUCH
18 #include <MSceneWindow>
19 #include <MInputMethodState>
20 #include <QtGui/QGraphicsSceneResizeEvent>
26 class IMozQWidget
: public QGraphicsWidget
33 virtual void setModal(bool) {}
34 virtual void dropReceiver() { };
35 virtual nsWindow
* getReceiver() { return NULL
; };
37 virtual void activate() {}
38 virtual void deactivate() {}
41 * VirtualKeyboardIntegration
43 virtual bool isVKBOpen() { return false; }
45 virtual void NotifyVKB(const QRect
& rect
) {}
46 virtual void SwitchToForeground() {}
47 virtual void SwitchToBackground() {}
50 class MozQGraphicsViewEvents
54 MozQGraphicsViewEvents(QGraphicsView
* aView
)
58 void handleEvent(QEvent
* aEvent
, IMozQWidget
* aTopLevel
)
62 if (aEvent
->type() == QEvent::WindowActivate
) {
64 aTopLevel
->activate();
67 if (aEvent
->type() == QEvent::WindowDeactivate
) {
69 aTopLevel
->deactivate();
73 void handleResizeEvent(QResizeEvent
* aEvent
, IMozQWidget
* aTopLevel
)
78 // transfer new size to graphics widget
79 aTopLevel
->setGeometry(0.0, 0.0,
80 static_cast<qreal
>(aEvent
->size().width()),
81 static_cast<qreal
>(aEvent
->size().height()));
82 // resize scene rect to vieport size,
83 // to avoid extra scrolling from QAbstractScrollable
85 mView
->setSceneRect(mView
->viewport()->rect());
89 bool handleCloseEvent(QCloseEvent
* aEvent
, IMozQWidget
* aTopLevel
)
94 // close graphics widget instead, this view will be discarded
96 QApplication::postEvent(aTopLevel
, new QCloseEvent(*aEvent
));
105 QGraphicsView
* mView
;
109 This is a helper class to synchronize the QGraphicsView window with
110 its contained QGraphicsWidget for things like resizing and closing
113 class MozQGraphicsView
: public QGraphicsView
118 MozQGraphicsView(QWidget
* aParent
= nullptr)
119 : QGraphicsView (new QGraphicsScene(), aParent
)
120 , mEventHandler(this)
121 , mTopLevelWidget(NULL
)
124 setMouseTracking(true);
125 setFrameShape(QFrame::NoFrame
);
128 void SetTopLevel(IMozQWidget
* aTopLevel
, QWidget
* aParent
)
130 scene()->addItem(aTopLevel
);
131 mTopLevelWidget
= aTopLevel
;
134 void setGLWidgetEnabled(bool aEnabled
)
137 mGLWidget
= new MozQGLWidgetWrapper();
138 mGLWidget
->setViewport(this);
142 setViewport(new QWidget());
148 virtual bool event(QEvent
* aEvent
)
150 mEventHandler
.handleEvent(aEvent
, mTopLevelWidget
);
151 return QGraphicsView::event(aEvent
);
154 virtual void resizeEvent(QResizeEvent
* aEvent
)
156 mEventHandler
.handleResizeEvent(aEvent
, mTopLevelWidget
);
157 QGraphicsView::resizeEvent(aEvent
);
160 virtual void closeEvent (QCloseEvent
* aEvent
)
162 if (!mEventHandler
.handleCloseEvent(aEvent
, mTopLevelWidget
))
163 QGraphicsView::closeEvent(aEvent
);
166 virtual void paintEvent(QPaintEvent
* aEvent
)
169 mGLWidget
->makeCurrent();
171 QGraphicsView::paintEvent(aEvent
);
175 MozQGraphicsViewEvents mEventHandler
;
176 IMozQWidget
* mTopLevelWidget
;
177 MozQGLWidgetWrapper
* mGLWidget
;
180 #ifdef MOZ_ENABLE_MEEGOTOUCH
181 class MozMSceneWindow
: public MSceneWindow
185 MozMSceneWindow(IMozQWidget
* aTopLevel
)
186 : MSceneWindow(aTopLevel
->parentItem())
187 , mTopLevelWidget(aTopLevel
)
189 MInputMethodState
* inputMethodState
= MInputMethodState::instance();
190 if (inputMethodState
) {
191 connect(inputMethodState
, SIGNAL(inputMethodAreaChanged(const QRect
&)),
192 this, SLOT(VisibleScreenAreaChanged(const QRect
&)));
196 void SetTopLevel(IMozQWidget
* aTopLevel
)
198 mTopLevelWidget
= aTopLevel
;
199 mTopLevelWidget
->setParentItem(this);
200 mTopLevelWidget
->installEventFilter(this);
204 virtual void resizeEvent(QGraphicsSceneResizeEvent
* aEvent
)
206 mCurrentSize
= aEvent
->newSize();
207 MSceneWindow::resizeEvent(aEvent
);
211 virtual bool eventFilter(QObject
* watched
, QEvent
* e
)
213 if (e
->type() == QEvent::GraphicsSceneResize
||
214 e
->type() == QEvent::GraphicsSceneMove
) {
216 //Do this in next event loop, or we are in recursion!
217 QTimer::singleShot(0, this, SLOT(CheckTopLevelSize()));
224 void CheckTopLevelSize()
226 if (mTopLevelWidget
) {
229 qreal width
= mCurrentSize
.width();
230 qreal height
= mCurrentSize
.height();
232 // transfer new size to graphics widget if changed
233 QRectF r
= mTopLevelWidget
->geometry();
234 if (r
!= QRectF(xpos
, ypos
, width
, height
)) {
235 mTopLevelWidget
->setGeometry(xpos
, ypos
, width
, height
);
240 void VisibleScreenAreaChanged(const QRect
& rect
) {
241 if (mTopLevelWidget
) {
242 mTopLevelWidget
->NotifyVKB(rect
);
247 IMozQWidget
* mTopLevelWidget
;
252 This is a helper class to synchronize the MWindow window with
253 its contained QGraphicsWidget for things like resizing and closing
256 class MozMGraphicsView
: public MWindow
260 MozMGraphicsView(QWidget
* aParent
= nullptr)
262 , mEventHandler(this)
263 , mTopLevelWidget(NULL
)
266 QObject::connect(this, SIGNAL(switcherEntered()), this, SLOT(onSwitcherEntered()));
267 QObject::connect(this, SIGNAL(switcherExited()), this, SLOT(onSwitcherExited()));
268 setFrameShape(QFrame::NoFrame
);
271 void SetTopLevel(IMozQWidget
* aTopLevel
, QWidget
* aParent
)
274 mSceneWin
= new MozMSceneWindow(aTopLevel
);
275 mSceneWin
->appear(this);
277 mSceneWin
->SetTopLevel(aTopLevel
);
278 mTopLevelWidget
= aTopLevel
;
282 void onSwitcherEntered() {
283 if (mTopLevelWidget
) {
284 mTopLevelWidget
->SwitchToBackground();
287 void onSwitcherExited() {
288 if (mTopLevelWidget
) {
289 mTopLevelWidget
->SwitchToForeground();
294 virtual bool event(QEvent
* aEvent
) {
295 mEventHandler
.handleEvent(aEvent
, mTopLevelWidget
);
296 return MWindow::event(aEvent
);
299 virtual void resizeEvent(QResizeEvent
* aEvent
)
301 setSceneRect(viewport()->rect());
302 MWindow::resizeEvent(aEvent
);
305 virtual void closeEvent (QCloseEvent
* aEvent
)
307 if (!mEventHandler
.handleCloseEvent(aEvent
, mTopLevelWidget
)) {
308 MWindow::closeEvent(aEvent
);
313 MozQGraphicsViewEvents mEventHandler
;
314 IMozQWidget
* mTopLevelWidget
;
315 MozMSceneWindow
* mSceneWin
;
318 #endif /* MOZ_ENABLE_MEEGOTOUCH */