25class QView3DWidget :
public QGLWidget
29 QView3DWidget(QWidget *parent);
30 virtual void initializeGL();
31 void resizeGL(
int w,
int h) override;
32 virtual void paintGL();
35 void addTexture(QWidget *w,
const QPixmap &pm);
37 void beginAddingWidgets(QWidget *form);
38 void addWidget(
int depth, QWidget *w);
39 void endAddingWidgets();
41 QWidget *widgetAt(
const QPoint &pos);
47 void mousePressEvent(QMouseEvent *);
48 void mouseReleaseEvent(QMouseEvent *);
49 void mouseMoveEvent(QMouseEvent *);
50 void wheelEvent(QWheelEvent *);
51 void keyReleaseEvent(QKeyEvent *);
53 void contextMenuEvent(QContextMenuEvent *);
58 bool m_layer_coloring;
60 GLuint m_form_list_id;
62 typedef QMap<QWidget*, GLuint> TextureMap;
63 TextureMap m_texture_map;
65 typedef QMap<GLuint, QWidget*> WidgetNameMap;
66 GLuint m_next_widget_name;
67 WidgetNameMap m_widget_name_map;
95void QView3DWidget::addTexture(
QWidget *w,
const QPixmap &pm)
97 int tx_w = nearestSize(pm.width());
98 int tx_h = nearestSize(pm.height());
100 QPixmap tmp(tx_w, tx_h);
101 tmp.fill(QColor(0,0,0));
103 p.drawPixmap(0, tx_h - pm.height(), pm);
105 QImage tex = tmp.toImage();
110 tex = QGLWidget::convertToGLFormat(tex);
113 glGenTextures(1, &tx_id);
114 glBindTexture(GL_TEXTURE_2D, tx_id);
115 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
119 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
122 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
124 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex.width(), tex.height(), 0, GL_RGBA,
125 GL_UNSIGNED_BYTE, tex.bits());
126 m_texture_map[w] = tx_id;
129void QView3DWidget::addWidget(
int depth,
QWidget *widget)
131 const auto it = m_texture_map.find(widget);
132 Q_ASSERT(it != m_texture_map.end());
136 int w = m_form->size().width();
137 int h = m_form->size().height();
138 int max = qMax(w, h);
139 QRect r = widget->rect();
140 QPoint pos = widget->mapToGlobal(QPoint(0, 0));
141 r.moveTopLeft(m_form->mapFromGlobal(pos));
143 float s = r.width()/
float(nearestSize(r.width()));
144 float t = r.height()/
float(nearestSize(r.height()));
146 if (m_layer_coloring)
147 glColor4f(1.0 - depth/10.0, 1.0 - depth/10.0, 1.0, 1.0 - depth/20.0);
149 glColor4f(1.0, 1.0, 1.0, 1.0);
151 glBindTexture(GL_TEXTURE_2D, *it);
153 glLoadName(m_next_widget_name);
154 glTexCoord2f(0.0, 0.0); glVertex3f(r.left() - w/2, r.bottom() - h/2, depth*max/8);
155 glTexCoord2f(s, 0.0); glVertex3f(r.right() - w/2, r.bottom()- h/2, depth*max/8);
156 glTexCoord2f(s, t); glVertex3f(r.right() - w/2, r.top() - h/2, depth*max/8);
157 glTexCoord2f(0.0, t); glVertex3f(r.left() - w/2, r.top() - h/2, depth*max/8);
160 m_widget_name_map[m_next_widget_name++] = widget;
163void QView3DWidget::clear()
166 glDeleteLists(m_form_list_id, 1);
167 for (
auto it = m_texture_map.begin(), end = m_texture_map.end(); it != end; ++it)
168 glDeleteTextures(1, &(it.value()));
169 m_texture_map.clear();
170 m_widget_name_map.clear();
171 m_next_widget_name = 0;
191void QView3DWidget::initializeGL()
193 glMatrixMode(GL_MODELVIEW);
196 qglClearColor(palette().color(QPalette::Window).darker());
197 glColor3f (1.0, 1.0, 1.0);
198 glEnable(GL_DEPTH_TEST);
199 glDepthFunc(GL_LEQUAL);
201 glShadeModel(GL_FLAT);
202 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
203 QString extensions(
reinterpret_cast<
const char *>(glGetString(GL_EXTENSIONS)));
204 m_use_mipmaps =
false;
207void QView3DWidget::resizeGL(
int width,
int height)
209 glViewport(0, 0, width, height);
210 glMatrixMode(GL_PROJECTION);
212 glOrtho(-width/2, width/2, height/2, -height/2, -999999, 999999);
215void QView3DWidget::paintGL()
217 glColor4f(1.0, 1.0, 1.0, 1.0);
218 glEnable(GL_TEXTURE_2D);
220 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
221 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
222 glCallList(m_form_list_id);
224 glPushAttrib(GL_ENABLE_BIT);
225 glDisable(GL_DEPTH_TEST);
226 glDisable(GL_LIGHTING);
227 glDisable(GL_TEXTURE_2D);
228 glMatrixMode(GL_MODELVIEW);
231 glTranslatef(-width()/2, -height()/2, 0.0);
233 QFontMetrics fm(font());
234 glColor4f(0.4, 0.4, 0.4, 0.7);
235 glRecti(0, height() - fm.lineSpacing()*2.5, width(), height());
237 glColor3f(1.0, 1.0, 1.0);
238 renderText(10, height() - fm.lineSpacing()*1.5,
239 "Press and hold left/right mouse button = tilt the view.");
240 renderText(10, height() - fm.lineSpacing()*0.5,
241 "Mouse wheel = zoom. 't' = toggle layer coloring. 'r' = reset transform.");
261void QView3DWidget::keyReleaseEvent(QKeyEvent *e)
263 if (e->key() == Qt::Key_T) {
264 m_layer_coloring = !m_layer_coloring;
266 }
else if (e->key() == Qt::Key_R) {
268 glMatrixMode(GL_MODELVIEW);
285void QView3DWidget::mouseMoveEvent(QMouseEvent *e)
287 if (e->buttons() & (Qt::LeftButton | Qt::RightButton)) {
288 GLfloat rx = (GLfloat) (e->x() - m_old_pos.x()) / width();
289 GLfloat ry = (GLfloat) (e->y() - m_old_pos.y()) / height();
292 glMatrixMode(GL_MODELVIEW);
293 if (e->buttons() & Qt::LeftButton) {
295 glRotatef(-180*ry, 1, 0, 0);
296 glRotatef(180*rx, 0, 1, 0);
297 }
else if (e->buttons() & Qt::RightButton) {
299 glRotatef(-180*ry, 1, 0, 0);
300 glRotatef(-180*rx, 0, 0, 1);
303 m_old_pos = e->pos();
351 if (!widget->isVisible())
355 func
(depth++
, widget
);
357 const QObjectList child_obj_list = widget->children();
358 for (QObject *child_obj : child_obj_list) {
359 QWidget *child = qobject_cast<QWidget*>(child_obj);
361 walkWidgetTree(core, depth, child, func);
366 const QRect &r,
const QPoint &offset, QDesignerFormEditorInterface *core)
368 buf.fill(widget, r.topLeft());
369 QPainter::setRedirected(widget, &buf, r.topLeft());
370 QPaintEvent e(r & widget->rect());
371 QApplication::sendEvent(widget, &e);
372 QPainter::restoreRedirected(widget);
375 pt.drawPixmap(offset.x(), offset.y(), buf, 0, 0, r.width(), r.height());
378 for (
auto *o : widget->children()) {
379 QWidget *child = qobject_cast<QWidget*>(o);
380 if (child == 0 || child->isWindow())
382 if (child->isHidden() || !child->geometry().intersects(r))
384 if (core->metaDataBase()->item(child) != 0)
386 QRect cr = r & child->geometry();
387 cr.translate(-child->pos());
388 grabWidget_helper(child, res, buf, cr, offset + child->pos(), core);
397 QRect r = widget->rect();
398 QSize s = widget->size();
400 QPixmap res(s), buf(s);
402 grabWidget_helper(widget, res, buf, r, QPoint(), core);
434 m_form_window = form_window;
435 m_3d_widget =
new QView3DWidget(
this);
436 connect(m_3d_widget, SIGNAL(updateForm()),
this, SLOT(updateForm()));
438 QGridLayout *layout =
new QGridLayout(
this);
439 layout->setContentsMargins(QMargins());
440 layout->addWidget(m_3d_widget, 0, 0, 1, 1);
447 QWidget *w = m_form_window->mainContainer();
451 m_3d_widget->clear();
453 walkWidgetTree(m_form_window->core(), 0, w,
AddTexture(m_form_window->core(), m_3d_widget));
454 m_3d_widget->beginAddingWidgets(w);
455 walkWidgetTree(m_form_window->core(), 0, w,
AddWidget(m_3d_widget
));
456 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)