24class QView3DWidget :
public QGLWidget
28 QView3DWidget(QWidget *parent);
29 virtual void initializeGL();
30 void resizeGL(
int w,
int h) override;
31 virtual void paintGL();
34 void addTexture(QWidget *w,
const QPixmap &pm);
36 void beginAddingWidgets(QWidget *form);
37 void addWidget(
int depth, QWidget *w);
38 void endAddingWidgets();
40 QWidget *widgetAt(
const QPoint &pos);
46 void mousePressEvent(QMouseEvent *);
47 void mouseReleaseEvent(QMouseEvent *);
48 void mouseMoveEvent(QMouseEvent *);
49 void wheelEvent(QWheelEvent *);
50 void keyReleaseEvent(QKeyEvent *);
52 void contextMenuEvent(QContextMenuEvent *);
57 bool m_layer_coloring;
59 GLuint m_form_list_id;
61 typedef QMap<QWidget*, GLuint> TextureMap;
62 TextureMap m_texture_map;
64 typedef QMap<GLuint, QWidget*> WidgetNameMap;
65 GLuint m_next_widget_name;
66 WidgetNameMap m_widget_name_map;
94void QView3DWidget::addTexture(
QWidget *w,
const QPixmap &pm)
96 int tx_w = nearestSize(pm.width());
97 int tx_h = nearestSize(pm.height());
99 QPixmap tmp(tx_w, tx_h);
100 tmp.fill(QColor(0,0,0));
102 p.drawPixmap(0, tx_h - pm.height(), pm);
104 QImage tex = tmp.toImage();
109 tex = QGLWidget::convertToGLFormat(tex);
112 glGenTextures(1, &tx_id);
113 glBindTexture(GL_TEXTURE_2D, tx_id);
114 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
118 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
121 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
123 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex.width(), tex.height(), 0, GL_RGBA,
124 GL_UNSIGNED_BYTE, tex.bits());
125 m_texture_map[w] = tx_id;
128void QView3DWidget::addWidget(
int depth,
QWidget *widget)
130 const auto it = m_texture_map.find(widget);
131 Q_ASSERT(it != m_texture_map.end());
135 int w = m_form->size().width();
136 int h = m_form->size().height();
137 int max = qMax(w, h);
138 QRect r = widget->rect();
139 QPoint pos = widget->mapToGlobal(QPoint(0, 0));
140 r.moveTopLeft(m_form->mapFromGlobal(pos));
142 float s = r.width()/
float(nearestSize(r.width()));
143 float t = r.height()/
float(nearestSize(r.height()));
145 if (m_layer_coloring)
146 glColor4f(1.0 - depth/10.0, 1.0 - depth/10.0, 1.0, 1.0 - depth/20.0);
148 glColor4f(1.0, 1.0, 1.0, 1.0);
150 glBindTexture(GL_TEXTURE_2D, *it);
152 glLoadName(m_next_widget_name);
153 glTexCoord2f(0.0, 0.0); glVertex3f(r.left() - w/2, r.bottom() - h/2, depth*max/8);
154 glTexCoord2f(s, 0.0); glVertex3f(r.right() - w/2, r.bottom()- h/2, depth*max/8);
155 glTexCoord2f(s, t); glVertex3f(r.right() - w/2, r.top() - h/2, depth*max/8);
156 glTexCoord2f(0.0, t); glVertex3f(r.left() - w/2, r.top() - h/2, depth*max/8);
159 m_widget_name_map[m_next_widget_name++] = widget;
162void QView3DWidget::clear()
165 glDeleteLists(m_form_list_id, 1);
166 for (
auto it = m_texture_map.begin(), end = m_texture_map.end(); it != end; ++it)
167 glDeleteTextures(1, &(it.value()));
168 m_texture_map.clear();
169 m_widget_name_map.clear();
170 m_next_widget_name = 0;
190void QView3DWidget::initializeGL()
192 glMatrixMode(GL_MODELVIEW);
195 qglClearColor(palette().color(QPalette::Window).darker());
196 glColor3f (1.0, 1.0, 1.0);
197 glEnable(GL_DEPTH_TEST);
198 glDepthFunc(GL_LEQUAL);
200 glShadeModel(GL_FLAT);
201 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
202 QString extensions(
reinterpret_cast<
const char *>(glGetString(GL_EXTENSIONS)));
203 m_use_mipmaps =
false;
206void QView3DWidget::resizeGL(
int width,
int height)
208 glViewport(0, 0, width, height);
209 glMatrixMode(GL_PROJECTION);
211 glOrtho(-width/2, width/2, height/2, -height/2, -999999, 999999);
214void QView3DWidget::paintGL()
216 glColor4f(1.0, 1.0, 1.0, 1.0);
217 glEnable(GL_TEXTURE_2D);
219 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
220 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
221 glCallList(m_form_list_id);
223 glPushAttrib(GL_ENABLE_BIT);
224 glDisable(GL_DEPTH_TEST);
225 glDisable(GL_LIGHTING);
226 glDisable(GL_TEXTURE_2D);
227 glMatrixMode(GL_MODELVIEW);
230 glTranslatef(-width()/2, -height()/2, 0.0);
232 QFontMetrics fm(font());
233 glColor4f(0.4, 0.4, 0.4, 0.7);
234 glRecti(0, height() - fm.lineSpacing()*2.5, width(), height());
236 glColor3f(1.0, 1.0, 1.0);
237 renderText(10, height() - fm.lineSpacing()*1.5,
238 "Press and hold left/right mouse button = tilt the view.");
239 renderText(10, height() - fm.lineSpacing()*0.5,
240 "Mouse wheel = zoom. 't' = toggle layer coloring. 'r' = reset transform.");
260void QView3DWidget::keyReleaseEvent(QKeyEvent *e)
262 if (e->key() == Qt::Key_T) {
263 m_layer_coloring = !m_layer_coloring;
265 }
else if (e->key() == Qt::Key_R) {
267 glMatrixMode(GL_MODELVIEW);
284void QView3DWidget::mouseMoveEvent(QMouseEvent *e)
286 if (e->buttons() & (Qt::LeftButton | Qt::RightButton)) {
287 GLfloat rx = (GLfloat) (e->x() - m_old_pos.x()) / width();
288 GLfloat ry = (GLfloat) (e->y() - m_old_pos.y()) / height();
291 glMatrixMode(GL_MODELVIEW);
292 if (e->buttons() & Qt::LeftButton) {
294 glRotatef(-180*ry, 1, 0, 0);
295 glRotatef(180*rx, 0, 1, 0);
296 }
else if (e->buttons() & Qt::RightButton) {
298 glRotatef(-180*ry, 1, 0, 0);
299 glRotatef(-180*rx, 0, 0, 1);
302 m_old_pos = e->pos();
350 if (!widget->isVisible())
354 func
(depth++
, widget
);
356 const QObjectList child_obj_list = widget->children();
357 for (QObject *child_obj : child_obj_list) {
358 QWidget *child = qobject_cast<QWidget*>(child_obj);
360 walkWidgetTree(core, depth, child, func);
365 const QRect &r,
const QPoint &offset, QDesignerFormEditorInterface *core)
367 buf.fill(widget, r.topLeft());
368 QPainter::setRedirected(widget, &buf, r.topLeft());
369 QPaintEvent e(r & widget->rect());
370 QApplication::sendEvent(widget, &e);
371 QPainter::restoreRedirected(widget);
374 pt.drawPixmap(offset.x(), offset.y(), buf, 0, 0, r.width(), r.height());
377 for (
auto *o : widget->children()) {
378 QWidget *child = qobject_cast<QWidget*>(o);
379 if (child == 0 || child->isWindow())
381 if (child->isHidden() || !child->geometry().intersects(r))
383 if (core->metaDataBase()->item(child) != 0)
385 QRect cr = r & child->geometry();
386 cr.translate(-child->pos());
387 grabWidget_helper(child, res, buf, cr, offset + child->pos(), core);
396 QRect r = widget->rect();
397 QSize s = widget->size();
399 QPixmap res(s), buf(s);
401 grabWidget_helper(widget, res, buf, r, QPoint(), core);
433 m_form_window = form_window;
434 m_3d_widget =
new QView3DWidget(
this);
435 connect(m_3d_widget, SIGNAL(updateForm()),
this, SLOT(updateForm()));
437 QGridLayout *layout =
new QGridLayout(
this);
438 layout->setContentsMargins(QMargins());
439 layout->addWidget(m_3d_widget, 0, 0, 1, 1);
446 QWidget *w = m_form_window->mainContainer();
450 m_3d_widget->clear();
452 walkWidgetTree(m_form_window->core(), 0, w,
AddTexture(m_form_window->core(), m_3d_widget));
453 m_3d_widget->beginAddingWidgets(w);
454 walkWidgetTree(m_form_window->core(), 0, w,
AddWidget(m_3d_widget
));
455 m_3d_widget->endAddingWidgets();
QView3DWidget * m_3d_widget
virtual void operator()(int, QWidget *w) const
QDesignerFormEditorInterface * m_core
AddTexture(QDesignerFormEditorInterface *core, QView3DWidget *w)
static void grabWidget_helper(QWidget *widget, QPixmap &res, QPixmap &buf, const QRect &r, const QPoint &offset, QDesignerFormEditorInterface *core)