Merge m-c to fx-team.
[gecko.git] / widget / qt / moziqwidget.h
blob7fa42f288d901153ed2eebbd7e23874f3563cc3b
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/. */
7 #ifndef MOZIQWIDGET_H
8 #define MOZIQWIDGET_H
10 #include <QApplication>
11 #include <QGraphicsWidget>
12 #include <QGraphicsView>
13 #include "mozqglwidgetwrapper.h"
15 #include "nsCOMPtr.h"
17 #ifdef MOZ_ENABLE_MEEGOTOUCH
18 #include <MSceneWindow>
19 #include <MInputMethodState>
20 #include <QtGui/QGraphicsSceneResizeEvent>
21 #include <QTimer>
22 #endif
24 class nsWindow;
26 class IMozQWidget : public QGraphicsWidget
28 Q_OBJECT
29 public:
30 /**
31 * Mozilla helper.
33 virtual void setModal(bool) {}
34 virtual void dropReceiver() { };
35 virtual nsWindow* getReceiver() { return NULL; };
37 virtual void activate() {}
38 virtual void deactivate() {}
40 /**
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
52 public:
54 MozQGraphicsViewEvents(QGraphicsView* aView)
55 : mView(aView)
56 { }
58 void handleEvent(QEvent* aEvent, IMozQWidget* aTopLevel)
60 if (!aEvent)
61 return;
62 if (aEvent->type() == QEvent::WindowActivate) {
63 if (aTopLevel)
64 aTopLevel->activate();
67 if (aEvent->type() == QEvent::WindowDeactivate) {
68 if (aTopLevel)
69 aTopLevel->deactivate();
73 void handleResizeEvent(QResizeEvent* aEvent, IMozQWidget* aTopLevel)
75 if (!aEvent)
76 return;
77 if (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
84 if (mView)
85 mView->setSceneRect(mView->viewport()->rect());
89 bool handleCloseEvent(QCloseEvent* aEvent, IMozQWidget* aTopLevel)
91 if (!aEvent)
92 return false;
93 if (aTopLevel) {
94 // close graphics widget instead, this view will be discarded
95 // automatically
96 QApplication::postEvent(aTopLevel, new QCloseEvent(*aEvent));
97 aEvent->ignore();
98 return true;
101 return false;
104 private:
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
111 by the user.
113 class MozQGraphicsView : public QGraphicsView
115 Q_OBJECT
117 public:
118 MozQGraphicsView(QWidget * aParent = nullptr)
119 : QGraphicsView (new QGraphicsScene(), aParent)
120 , mEventHandler(this)
121 , mTopLevelWidget(NULL)
122 , mGLWidget(0)
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)
136 if (aEnabled) {
137 mGLWidget = new MozQGLWidgetWrapper();
138 mGLWidget->setViewport(this);
139 } else {
140 delete mGLWidget;
141 mGLWidget = 0;
142 setViewport(new QWidget());
146 protected:
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)
168 if (mGLWidget) {
169 mGLWidget->makeCurrent();
171 QGraphicsView::paintEvent(aEvent);
174 private:
175 MozQGraphicsViewEvents mEventHandler;
176 IMozQWidget* mTopLevelWidget;
177 MozQGLWidgetWrapper* mGLWidget;
180 #ifdef MOZ_ENABLE_MEEGOTOUCH
181 class MozMSceneWindow : public MSceneWindow
183 Q_OBJECT
184 public:
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);
203 protected:
204 virtual void resizeEvent(QGraphicsSceneResizeEvent* aEvent)
206 mCurrentSize = aEvent->newSize();
207 MSceneWindow::resizeEvent(aEvent);
208 CheckTopLevelSize();
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()));
220 return false;
223 private Q_SLOTS:
224 void CheckTopLevelSize()
226 if (mTopLevelWidget) {
227 qreal xpos = 0;
228 qreal ypos = 0;
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);
246 private:
247 IMozQWidget* mTopLevelWidget;
248 QSizeF mCurrentSize;
252 This is a helper class to synchronize the MWindow window with
253 its contained QGraphicsWidget for things like resizing and closing
254 by the user.
256 class MozMGraphicsView : public MWindow
258 Q_OBJECT
259 public:
260 MozMGraphicsView(QWidget* aParent = nullptr)
261 : MWindow(aParent)
262 , mEventHandler(this)
263 , mTopLevelWidget(NULL)
264 , mSceneWin(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)
273 if (!mSceneWin) {
274 mSceneWin = new MozMSceneWindow(aTopLevel);
275 mSceneWin->appear(this);
277 mSceneWin->SetTopLevel(aTopLevel);
278 mTopLevelWidget = aTopLevel;
281 public Q_SLOTS:
282 void onSwitcherEntered() {
283 if (mTopLevelWidget) {
284 mTopLevelWidget->SwitchToBackground();
287 void onSwitcherExited() {
288 if (mTopLevelWidget) {
289 mTopLevelWidget->SwitchToForeground();
293 protected:
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);
312 private:
313 MozQGraphicsViewEvents mEventHandler;
314 IMozQWidget* mTopLevelWidget;
315 MozMSceneWindow* mSceneWin;
318 #endif /* MOZ_ENABLE_MEEGOTOUCH */
319 #endif