/*
* Copyright (c) 2002-2006 Samit Basu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "HandleWindow.hpp"
#include "HandleAxis.hpp"
#include "HandleCommands.hpp"
#include <qgl.h>
#include "GLRenderEngine.hpp"
#include "QTRenderEngine.hpp"
#include <QStackedLayout>
#include "HandleCommands.hpp"
#include <QtGui>
#include <math.h>
class BaseFigureQt : public QWidget {
HandleFigure *hfig;
QPixmap backStore;
public:
BaseFigureQt(QWidget *parent, HandleFigure *fig);
void paintEvent(QPaintEvent *e);
void resizeEvent(QResizeEvent *e);
// QSize sizeHint() const;
// QSizePolicy sizePolicy() const;
};
// QSize BaseFigureQt::sizeHint() const {
// HPTwoVector *htv = (HPTwoVector*) hfig->LookupProperty("figsize");
// qDebug() << "Size hint " << (htv->Data()[0]) << "," << (htv->Data()[1]) << "\r\n";
// return QSize((int)(htv->Data()[0]),(int)(htv->Data()[1]));
// // return QSize(10000,10000);
// }
void BaseFigureQt::resizeEvent(QResizeEvent *e) {
QWidget::resizeEvent(e);
// qDebug() << "resize " << width() << " " << height() << "\r\n";
backStore = QPixmap(qMax(8,width()),
qMax(8,height()));
hfig->resizeGL(qMax(8,width()),
qMax(8,height()));
}
static bool enableRepaint = false;
void GfxEnableRepaint() {
enableRepaint = true;
DoDrawNow();
}
void GfxDisableRepaint() {
enableRepaint = false;
}
void BaseFigureQt::paintEvent(QPaintEvent *e) {
// qDebug() << "Paint\r";
if (enableRepaint && hfig->ParentWindow()->isDirty()) {
{
// enableRepaint is true, and the background is dirty - update
// the backing store, and then redraw it.
// qDebug() << "Redraw\r";
QPainter pnt(&backStore);
QTRenderEngine gc(&pnt,0,0,width(),height());
hfig->PaintMe(gc);
hfig->ParentWindow()->markClean();
}
QPainter pnt2(this);
pnt2.drawPixmap(0,0,backStore);
} else {
// qDebug() << "Refresh\r";
QPainter pnt(this);
pnt.drawPixmap(e->rect(),backStore);
}
}
BaseFigureQt::BaseFigureQt(QWidget *parent, HandleFigure *fig) :
QWidget(parent) {
hfig = fig;
// hfig->resizeGL(width(),height());
}
class BaseFigureGL : public QGLWidget {
HandleFigure *hfig;
public:
BaseFigureGL(QWidget *parent, HandleFigure *fig);
virtual void initializeGL();
virtual void paintGL();
virtual void resizeGL(int width, int height);
// Support dragging...
// void mousePressEvent(QMouseEvent* e);
// void mouseMoveEvent(QMouseEvent* e);
// void mouseReleaseEvent(QMouseEvent* e);
// virtual void Show() {QWidget::show();};
};
BaseFigureGL::BaseFigureGL(QWidget *parent, HandleFigure *fig) :
QGLWidget(parent) {
hfig = fig;
hfig->resizeGL(width(),height());
}
void BaseFigureGL::initializeGL() {
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
}
void BaseFigureGL::paintGL() {
// qDebug("GLpaint");
GLRenderEngine gc(this,0,0,width(),height());
hfig->PaintMe(gc);
}
void BaseFigureGL::resizeGL(int width, int height) {
// qDebug("GLsize");
hfig->resizeGL(width,height);
}
#if 0
void BaseFigureGL::mousePressEvent(QMouseEvent* e) {
if (e->button() & Qt::LeftButton)
elevazim = true;
else
elevazim = false;
beginx = e->x();
beginy = e->y();
}
void BaseFigureGL::mouseMoveEvent(QMouseEvent* e) {
if (elevazim) {
elev -= (e->y() - beginy);
azim += (e->x() - beginx);
elev = (elev + 360) % 360;
azim = (azim + 360) % 360;
} else {
arot += (e->y() - beginy);
arot = (arot + 360) % 360;
}
beginx = e->x();
beginy = e->y();
// updateGL();
}
void BaseFigureGL::mouseReleaseEvent(QMouseEvent* e) {
}
#endif
void HandleWindow::closeEvent(QCloseEvent* e) {
NotifyFigureClosed(handle);
}
bool HandleWindow::event(QEvent* e) {
if (e->type() == QEvent::WindowActivate) {
NotifyFigureActive(handle);
// qDebug() << "focus event " << handle << "\n";
}
return QWidget::event(e);
}
HandleWindow::HandleWindow(unsigned ahandle) : QMainWindow() {
initialized = false;
setWindowIcon(QPixmap(":/images/freemat_small_mod_64.png"));
handle = ahandle;
hfig = new HandleFigure(this);
char buffer[1000];
sprintf(buffer,"Figure %d",ahandle+1);
setWindowTitle(buffer);
qtchild = new BaseFigureQt(this,hfig);
band = NULL;
setMinimumSize(50,50);
// if (QGLFormat::hasOpenGL())
// glchild = new BaseFigureGL(NULL,hfig);
// layout = new QStackedWidget(this);
// QHBoxLayout *box = new QHBoxLayout(this);
// box->setMargin(0);
// setLayout(box);
// layout = new QTabWidget;
// layout->addTab(qtchild,"QT");
// layout->addTab(glchild,"GL");
// layout->addWidget(qtchild);
// if (QGLFormat::hasOpenGL())
// layout->addWidget(glchild);
// layout->show();
// box->addWidget(layout);
createActions();
createMenus();
createToolBars();
setCentralWidget(qtchild);
resize(600,400);
initialized = true;
mode = normal_mode;
dirty = false;
}
// Useful tools:
//
// Zoom in - fix for images
// Zoom out - fix for images
// Pan - fix for images
// Rotate - fix for imagesqw
// Annotate
// Save
// Copy
// Examine (values)
//
void HandleWindow::zoom(bool active) {
panAct->setChecked(false);
rotateAct->setChecked(false);
camRotateAct->setChecked(false);
if (active)
mode = zoom_mode;
else
mode = normal_mode;
}
void HandleWindow::pan(bool active) {
zoomAct->setChecked(false);
rotateAct->setChecked(false);
camRotateAct->setChecked(false);
if (active)
mode = pan_mode;
else
mode = normal_mode;
}
void HandleWindow::rotate(bool active) {
zoomAct->setChecked(false);
panAct->setChecked(false);
camRotateAct->setChecked(false);
if (active)
mode = rotate_mode;
else
mode = normal_mode;
}
void HandleWindow::camRotate(bool active) {
zoomAct->setChecked(false);
panAct->setChecked(false);
rotateAct->setChecked(false);
if (active)
mode = cam_rotate_mode;
else
mode = normal_mode;
}
void HandleWindow::save() {
QString fn = QFileDialog::getSaveFileName();
try {
HPrintFunction(0,singleArrayVector(Array::stringConstructor(fn.toStdString())));
} catch(Exception &e) {
QMessageBox::critical(0,"Critical Error in Save",QString::fromStdString(e.getMessageCopy()));
}
}
void HandleWindow::copy() {
try {
HCopyFunction(0,ArrayVector());
} catch(Exception &e) {
QMessageBox::critical(0,"Critical Error in Copy",QString::fromStdString(e.getMessageCopy()));
}
}
void HandleWindow::createActions() {
zoomAct = new QAction(QIcon(":/images/zoomin.png"),"&Zoom",this);
zoomAct->setCheckable(true);
zoomAct->setToolTip("Left click to zoom in by 2, left click and drag to zoom a region, right click to zoom out by 2");
connect(zoomAct,SIGNAL(triggered(bool)),this,SLOT(zoom(bool)));
panAct = new QAction(QIcon(":/images/pan.png"),"&Pan",this);
connect(panAct,SIGNAL(triggered(bool)),this,SLOT(pan(bool)));
panAct->setCheckable(true);
rotateAct = new QAction(QIcon(":/images/rotate.png"),"&Rotate",this);
connect(rotateAct,SIGNAL(triggered(bool)),this,SLOT(rotate(bool)));
rotateAct->setCheckable(true);
camRotateAct = new QAction(QIcon(":/images/cam_rotate.png"),"&Camera Rotate",this);
connect(camRotateAct,SIGNAL(triggered(bool)),this,SLOT(camRotate(bool)));
camRotateAct->setCheckable(true);
saveAct = new QAction(QIcon(":/images/save.png"),"&Save",this);
connect(saveAct,SIGNAL(triggered()),this,SLOT(save()));
copyAct = new QAction(QIcon(":/images/copy.png"),"&Copy",this);
connect(copyAct,SIGNAL(triggered()),this,SLOT(copy()));
closeAct = new QAction(QIcon(":/images/quit.png"),"&Close",this);
connect(closeAct,SIGNAL(triggered()),this,SLOT(close()));
}
void HandleWindow::createMenus() {
fileMenu = menuBar()->addMenu("&File");
fileMenu->addAction(saveAct);
fileMenu->addAction(closeAct);
editMenu = menuBar()->addMenu("&Tools");
editMenu->addAction(copyAct);
editMenu->addAction(zoomAct);
editMenu->addAction(panAct);
editMenu->addAction(rotateAct);
editMenu->addAction(camRotateAct);
}
void HandleWindow::createToolBars() {
toolBar = addToolBar("Tools");
toolBar->setObjectName("ToolsToolBar");
toolBar->addAction(saveAct);
toolBar->addAction(closeAct);
toolBar->addAction(copyAct);
toolBar->addAction(zoomAct);
toolBar->addAction(panAct);
toolBar->addAction(rotateAct);
toolBar->addAction(camRotateAct);
}
unsigned HandleWindow::Handle() {
return handle;
}
HandleFigure* HandleWindow::HFig() {
return hfig;
}
void HandleWindow::GetClick(int &x, int &y) {
// Set the cross cursor
QApplication::setOverrideCursor(Qt::CrossCursor);
// Run the event loop
int save_mode = mode;
mode = click_mode;
m_loop.exec();
x = click_x;
y = click_y;
QApplication::restoreOverrideCursor();
mode = save_mode;
}
HandleAxis* GetContainingAxis(HandleFigure *fig, int x, int y) {
// qDebug() << "Click " << x << "," << y;
HPHandles *cp = (HPHandles*) fig->LookupProperty("children");
std::vector<unsigned> children(cp->Data());
// qDebug() << "Click " << x << "," << y;
for (int i=0;i<children.size();i++) {
HandleObject* hp = LookupHandleObject(children[i]);
if (hp->IsType("axes")) {
// Get the axis extents
std::vector<double> position(((HandleAxis*) hp)->GetPropertyVectorAsPixels("position"));
// qDebug() << "Axis: " << position[0] << "," << position[1] << "," << position[2] << "," << position[3];
if ((x >= position[0]) && (x < (position[0]+position[2])) &&
(y >= position[1]) && (y < (position[1]+position[3])))
return (HandleAxis*)hp;
}
}
return NULL;
}
void HandleWindow::mousePressEvent(QMouseEvent* e) {
try {
if (mode == click_mode) {
click_x = e->x();
click_y = e->y();
m_loop.exit();
}
if ((mode == zoom_mode) && (e->button() == Qt::LeftButton)) {
origin = e->pos();
if (!band)
band = new QRubberBand(QRubberBand::Rectangle, this);
band->setGeometry(QRect(origin,QSize()));
band->show();
zoom_active = true;
} else
zoom_active = false;
if (mode == pan_mode) {
origin = e->pos();
QRect plot_region(qtchild->geometry());
HandleAxis *h = GetContainingAxis(hfig,remapX(e->x()),remapY(e->y()));
if (h) {
HPTwoVector *hp = (HPTwoVector*) h->LookupProperty("xlim");
pan_xrange = (hp->Data()[1] - hp->Data()[0]);
pan_xmean = (hp->Data()[1] + hp->Data()[0])/2;
hp = (HPTwoVector*) h->LookupProperty("ylim");
pan_yrange = (hp->Data()[1] - hp->Data()[0]);
pan_ymean = (hp->Data()[1] + hp->Data()[0])/2;
pan_active = true;
} else {
pan_active = false;
}
}
if ((mode == rotate_mode) || (mode == cam_rotate_mode)) {
origin = e->pos();
QRect plot_region(qtchild->geometry());
HandleAxis *h = GetContainingAxis(hfig,remapX(e->x()),remapY(e->y()));
if (h) {
rotate_active = true;
rotate_camera = ((HPThreeVector*) h->LookupProperty("cameraposition"))->Data();
rotate_up = ((HPThreeVector*) h->LookupProperty("cameraupvector"))->Data();
rotate_target = ((HPThreeVector*) h->LookupProperty("cameratarget"))->Data();
rotate_forward = rotate_target;
rotate_forward[0] -= rotate_camera[0];
rotate_forward[1] -= rotate_camera[1];
rotate_forward[2] -= rotate_camera[2];
rotate_source_cam_dist = sqrt(rotate_forward[0]*rotate_forward[0] +
rotate_forward[1]*rotate_forward[1] +
rotate_forward[2]*rotate_forward[2]);
rotate_forward[0] /= rotate_source_cam_dist;
rotate_forward[1] /= rotate_source_cam_dist;
rotate_forward[2] /= rotate_source_cam_dist;
rotate_right = rotate_up;
rotate_right[0] = (rotate_forward[1] * rotate_up[2]) - (rotate_forward[2] * rotate_up[1]);
rotate_right[1] = (rotate_forward[2] * rotate_up[0]) - (rotate_forward[0] * rotate_up[2]);
rotate_right[2] = (rotate_forward[0] * rotate_up[1]) - (rotate_forward[1] * rotate_up[0]);
}
}
} catch (Exception &e) {
}
}
void HandleWindow::mouseMoveEvent(QMouseEvent* e) {
try {
if ((mode == zoom_mode) && zoom_active)
band->setGeometry(QRect(origin, e->pos()).normalized());
if ((mode == pan_mode) && pan_active) {
QPoint dest(e->pos());
QRect plot_region(qtchild->geometry());
HandleAxis *h = GetContainingAxis(hfig,remapX(origin.x()),remapY(origin.y()));
if (h) {
std::vector<double> position(h->GetPropertyVectorAsPixels("position"));
double delx, dely;
if (h->StringCheck("xdir","reverse"))
delx = (e->x() - origin.x())/position[2];
else
delx = -(e->x() - origin.x())/position[2];
if (h->StringCheck("ydir","reverse"))
dely = -(e->y() - origin.y())/position[3];
else
dely = (e->y() - origin.y())/position[3];
h->SetTwoVectorDefault("xlim",pan_xmean+pan_xrange*delx-pan_xrange/2,
pan_xmean+pan_xrange*delx+pan_xrange/2);
h->SetConstrainedStringDefault("xlimmode","manual");
h->SetTwoVectorDefault("ylim",pan_ymean+pan_yrange*dely-pan_yrange/2,
pan_ymean+pan_yrange*dely+pan_yrange/2);
h->SetConstrainedStringDefault("ylimmode","manual");
h->UpdateState();
hfig->Repaint();
UpdateState();
}
}
if ((mode == rotate_mode) && rotate_active) {
QPoint dest(e->pos());
QRect plot_region(qtchild->geometry());
HandleAxis *h = GetContainingAxis(hfig,remapX(origin.x()),remapY(origin.y()));
if (h) {
double az = (e->x() - origin.x())/180.0*M_PI;
double el = (e->y() - origin.y())/180.0*M_PI;
// The delx means we rotate the camera
vector<double> camera_position(rotate_target);
camera_position[0] += rotate_source_cam_dist*(cos(el)*sin(az)*rotate_right[0] +
-cos(el)*cos(az)*rotate_forward[0] +
sin(el)*rotate_up[0]);
camera_position[1] += rotate_source_cam_dist*(cos(el)*sin(az)*rotate_right[1] +
-cos(el)*cos(az)*rotate_forward[1] +
sin(el)*rotate_up[1]);
camera_position[2] += rotate_source_cam_dist*(cos(el)*sin(az)*rotate_right[2] +
-cos(el)*cos(az)*rotate_forward[2] +
sin(el)*rotate_up[2]);
vector<double> camera_up(rotate_target);
camera_up[0] = (cos(el+M_PI/2.0)*sin(az)*rotate_right[0] +
-cos(el+M_PI/2.0)*cos(az)*rotate_forward[0] +
sin(el+M_PI/2.0)*rotate_up[0]);
camera_up[1] = (cos(el+M_PI/2.0)*sin(az)*rotate_right[1] +
-cos(el+M_PI/2.0)*cos(az)*rotate_forward[1] +
sin(el+M_PI/2.0)*rotate_up[1]);
camera_up[2] = (cos(el+M_PI/2.0)*sin(az)*rotate_right[2] +
-cos(el+M_PI/2.0)*cos(az)*rotate_forward[2] +
sin(el+M_PI/2.0)*rotate_up[2]);
h->SetThreeVectorDefault("cameraposition",camera_position[0],
camera_position[1],camera_position[2]);
h->SetConstrainedStringDefault("camerapositionmode","manual");
h->SetThreeVectorDefault("cameraupvector",camera_up[0],
camera_up[1],camera_up[2]);
h->SetConstrainedStringDefault("cameraupvectormode","manual");
h->UpdateState();
hfig->Repaint();
UpdateState();
}
}
if ((mode == cam_rotate_mode) && rotate_active) {
QPoint dest(e->pos());
QRect plot_region(qtchild->geometry());
HandleAxis *h = GetContainingAxis(hfig,remapX(origin.x()),remapY(origin.y()));
if (h) {
double el = (e->y() - origin.y())/180.0*M_PI;
vector<double> camera_up(rotate_target);
camera_up[0] = cos(el)*rotate_up[0] - sin(el)*rotate_right[0];
camera_up[1] = cos(el)*rotate_up[1] - sin(el)*rotate_right[1];
camera_up[2] = cos(el)*rotate_up[2] - sin(el)*rotate_right[2];
h->SetThreeVectorDefault("cameraupvector",camera_up[0],
camera_up[1],camera_up[2]);
h->SetConstrainedStringDefault("cameraupvectormode","manual");
h->UpdateState();
hfig->Repaint();
UpdateState();
}
}
} catch (Exception &e) {
}
}
int HandleWindow::remapX(int x) {
QRect plot_region(qtchild->geometry());
return x - plot_region.x();
}
int HandleWindow::remapY(int y) {
QRect plot_region(qtchild->geometry());
return (plot_region.height()-y+plot_region.y());
}
void HandleWindow::mouseReleaseEvent(QMouseEvent * e) {
try {
if (mode == pan_mode)
pan_active = false;
if (mode == zoom_mode) {
if (zoom_active) {
band->hide();
QRect rect(band->geometry().normalized());
if ((rect.width()*rect.height()) < 20) {
// Treat as a click
int click_x, click_y;
click_x = e->x();
click_y = e->y();
HandleAxis *h = GetContainingAxis(hfig,remapX(click_x),remapY(click_y));
if (h) {
HPTwoVector *hp = (HPTwoVector*) h->LookupProperty("xlim");
double range = (hp->Data()[1] - hp->Data()[0])/2;
double mean = (hp->Data()[1] + hp->Data()[0])/2;
h->SetTwoVectorDefault("xlim",mean-range/2,mean+range/2);
h->SetConstrainedStringDefault("xlimmode","manual");
hp = (HPTwoVector*) h->LookupProperty("ylim");
range = (hp->Data()[1] - hp->Data()[0])/2;
mean = (hp->Data()[1] + hp->Data()[0])/2;
h->SetTwoVectorDefault("ylim",mean-range/2,mean+range/2);
h->SetConstrainedStringDefault("ylimmode","manual");
h->UpdateState();
hfig->Repaint();
}
} else {
QRect plot_region(qtchild->geometry());
HandleAxis *h = GetContainingAxis(hfig,remapX(rect.x()),remapY(rect.y()));
if (h) {
std::vector<double> position(h->GetPropertyVectorAsPixels("position"));
double xminfrac = (remapX(rect.x()) - position[0])/position[2];
double xmaxfrac = (remapX(rect.x()+rect.width()) - position[0])/position[2];
double yminfrac = (remapY(rect.y()+rect.height()) - position[1])/position[3];
double ymaxfrac = (remapY(rect.y()) - position[1])/position[3];
// qDebug() << "xrange " << xminfrac << "," << xmaxfrac;
// qDebug() << "yrange " << yminfrac << "," << ymaxfrac;
xminfrac = qMax(0.,qMin(1.,xminfrac));
xmaxfrac = qMax(0.,qMin(1.,xmaxfrac));
yminfrac = qMax(0.,qMin(1.,yminfrac));
ymaxfrac = qMax(0.,qMin(1.,ymaxfrac));
if (h->StringCheck("ydir","reverse")) {
double y1 = 1-yminfrac;
double y2 = 1-ymaxfrac;
yminfrac = y2;
ymaxfrac = y1;
}
if (h->StringCheck("xdir","reverse")) {
double x1 = 1-xminfrac;
double x2 = 1-xmaxfrac;
xminfrac = x2;
xmaxfrac = x1;
}
HPTwoVector *hp = (HPTwoVector*) h->LookupProperty("xlim");
double range = (hp->Data()[1] - hp->Data()[0]);
double mean = (hp->Data()[1] + hp->Data()[0])/2;
h->SetTwoVectorDefault("xlim",mean-range/2+xminfrac*range,mean-range/2+xmaxfrac*range);
h->SetConstrainedStringDefault("xlimmode","manual");
hp = (HPTwoVector*) h->LookupProperty("ylim");
range = (hp->Data()[1] - hp->Data()[0]);
mean = (hp->Data()[1] + hp->Data()[0])/2;
h->SetTwoVectorDefault("ylim",mean-range/2+yminfrac*range,mean-range/2+ymaxfrac*range);
h->SetConstrainedStringDefault("ylimmode","manual");
h->UpdateState();
hfig->Repaint();
}
}
} else {
// Treat as a click
int click_x, click_y;
click_x = e->x();
click_y = e->y();
QRect plot_region(qtchild->geometry());
HandleAxis *h = GetContainingAxis(hfig,remapX(click_x),remapY(click_y));
if (h) {
HPTwoVector *hp = (HPTwoVector*) h->LookupProperty("xlim");
double range = (hp->Data()[1] - hp->Data()[0])*2;
double mean = (hp->Data()[1] + hp->Data()[0])/2;
h->SetTwoVectorDefault("xlim",mean-range/2,mean+range/2);
h->SetConstrainedStringDefault("xlimmode","manual");
hp = (HPTwoVector*) h->LookupProperty("ylim");
range = (hp->Data()[1] - hp->Data()[0])*2;
mean = (hp->Data()[1] + hp->Data()[0])/2;
h->SetTwoVectorDefault("ylim",mean-range/2,mean+range/2);
h->SetConstrainedStringDefault("ylimmode","manual");
h->UpdateState();
hfig->Repaint();
}
}
}
} catch (Exception &e) {
}
dirty = true;
}
void HandleWindow::markClean() {
dirty = false;
}
void HandleWindow::UpdateState() {
if (!initialized) return;
dirty = true;
// HPTwoVector *htv = (HPTwoVector*) hfig->LookupProperty("figsize");
// qtchild->resize((int)(htv->Data()[0]),(int)(htv->Data()[1]));
// qtchild->updateGeometry();
// adjustSize();
// if (hfig->StringCheck("renderer","opengl") && (QGLFormat::hasOpenGL())) {
// if (layout->currentWidget() != glchild) {
// layout->setCurrentWidget(glchild);
// glchild->show();
// glchild->updateGeometry();
// repaint();
// glchild->updateGL();
// update();
// UpdateState();
// }
// glchild->updateGL();
// update();
// } else if (hfig->StringCheck("renderer","painters")) {
// if (layout->currentWidget() != qtchild) {
// if (QGLFormat::hasOpenGL())
// glchild->setGeometry(0,0,1,1);
// layout->setCurrentWidget(qtchild);
// }
repaint();
// }
}
syntax highlighted by Code2HTML, v. 0.9.1