Merge pull request #752 from qSLX/master

Preventing losing keyboard focus by editor.
master
Marius Kintel 2014-04-22 01:03:21 -04:00
commit 91074eba48
5 changed files with 93 additions and 70 deletions

View File

@ -181,7 +181,7 @@ public slots:
void viewCenter();
void viewPerspective();
void viewOrthogonal();
void viewResetView();
void viewResetView();
void hideConsole();
void animateUpdateDocChanged();
void animateUpdate();
@ -198,14 +198,14 @@ public slots:
private:
static void report_func(const class AbstractNode*, void *vp, int mark);
char const * afterCompileSlot;
bool procevents;
class QTemporaryFile *tempFile;
class ProgressWidget *progresswidget;
class CGALWorker *cgalworker;
QMutex consolemutex;
signals:
void highlightError(int);
void unhighlightLastError();

View File

@ -126,6 +126,9 @@
<pointsize>8</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::WheelFocus</enum>
</property>
</widget>
</item>
</layout>
@ -139,6 +142,9 @@
</property>
<widget class="QGLView" name="qglview" native="true"/>
<widget class="QTextEdit" name="console">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
@ -328,6 +334,9 @@
<addaction name="viewActionDiagonal"/>
<addaction name="viewActionCenter"/>
<addaction name="separator"/>
<addaction name="viewActionZoomIn"/>
<addaction name="viewActionZoomOut"/>
<addaction name="separator"/>
<addaction name="viewActionResetView"/>
<addaction name="separator"/>
<addaction name="viewActionPerspective"/>
@ -864,6 +873,22 @@
<string>Reset View</string>
</property>
</action>
<action name="viewActionZoomIn">
<property name="text">
<string>Zoom In</string>
</property>
<property name="shortcut">
<string>Ctrl+]</string>
</property>
</action>
<action name="viewActionZoomOut">
<property name="text">
<string>Zoom Out</string>
</property>
<property name="shortcut">
<string>Ctrl+[</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -170,25 +170,6 @@ void QGLView::paintGL()
if (running_under_wine) swapBuffers();
}
void QGLView::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Plus: // On many keyboards, this requires to press Shift-equals
case Qt::Key_Equal: // ...so simplify this a bit.
cam.viewer_distance *= 0.9;
updateGL();
break;
case Qt::Key_Minus:
cam.viewer_distance /= 0.9;
updateGL();
break;
case Qt::Key_C: // 'center'
cam.object_trans << 0, 0, 0;
updateGL();
break;
}
}
void QGLView::wheelEvent(QWheelEvent *event)
{
cam.viewer_distance *= pow(0.9, event->delta() / 120.0);
@ -197,7 +178,6 @@ void QGLView::wheelEvent(QWheelEvent *event)
void QGLView::mousePressEvent(QMouseEvent *event)
{
setFocus();
mouse_drag_active = true;
last_mouse = event->globalPos();
}
@ -298,3 +278,14 @@ bool QGLView::save(const char *filename)
return img.save(filename, "PNG");
}
void QGLView::ZoomIn(void)
{
cam.viewer_distance *= 0.9;
updateGL();
}
void QGLView::ZoomOut(void)
{
cam.viewer_distance /= 0.9;
updateGL();
}

View File

@ -44,7 +44,11 @@ public:
float getDPI() { return this->devicePixelRatio(); }
#endif
bool save(const char *filename);
void resetView();
void resetView();
public slots:
void ZoomIn(void);
void ZoomOut(void);
public:
QLabel *statusLabel;
@ -55,7 +59,6 @@ private:
bool mouse_drag_active;
QPoint last_mouse;
void keyPressEvent(QKeyEvent *event);
void wheelEvent(QWheelEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);

View File

@ -171,7 +171,7 @@ MainWindow::MainWindow(const QString &filename)
#ifdef ENABLE_CGAL
this->cgalworker = new CGALWorker();
connect(this->cgalworker, SIGNAL(done(CGAL_Nef_polyhedron *)),
connect(this->cgalworker, SIGNAL(done(CGAL_Nef_polyhedron *)),
this, SLOT(actionRenderCGALDone(CGAL_Nef_polyhedron *)));
#endif
@ -198,6 +198,8 @@ MainWindow::MainWindow(const QString &filename)
fps = 0;
fsteps = 1;
editActionZoomIn->setShortcuts(QList<QKeySequence>() << editActionZoomIn->shortcuts() << QKeySequence("CTRL+="));
connect(this, SIGNAL(highlightError(int)), editor, SLOT(highlightError(int)));
connect(this, SIGNAL(unhighlightLastError()), editor, SLOT(unhighlightLastError()));
editor->setTabStopWidth(30);
@ -265,7 +267,7 @@ MainWindow::MainWindow(const QString &filename)
this, SLOT(clearRecentFiles()));
if (!qexamplesdir.isEmpty()) {
bool found_example = false;
QStringList examples = QDir(qexamplesdir).entryList(QStringList("*.scad"),
QStringList examples = QDir(qexamplesdir).entryList(QStringList("*.scad"),
QDir::Files | QDir::Readable, QDir::Name);
foreach (const QString &ex, examples) {
this->menuExamples->addAction(ex, this, SLOT(actionOpenExample()));
@ -357,6 +359,8 @@ MainWindow::MainWindow(const QString &filename)
connect(this->viewActionPerspective, SIGNAL(triggered()), this, SLOT(viewPerspective()));
connect(this->viewActionOrthogonal, SIGNAL(triggered()), this, SLOT(viewOrthogonal()));
connect(this->viewActionHide, SIGNAL(triggered()), this, SLOT(hideConsole()));
connect(this->viewActionZoomIn, SIGNAL(triggered()), qglview, SLOT(ZoomIn()));
connect(this->viewActionZoomOut, SIGNAL(triggered()), qglview, SLOT(ZoomOut()));
// Help menu
connect(this->helpActionAbout, SIGNAL(triggered()), this, SLOT(helpAbout()));
@ -384,11 +388,11 @@ MainWindow::MainWindow(const QString &filename)
connect(this->qglview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
connect(Preferences::inst(), SIGNAL(requestRedraw()), this->qglview, SLOT(updateGL()));
connect(Preferences::inst(), SIGNAL(fontChanged(const QString&,uint)),
connect(Preferences::inst(), SIGNAL(fontChanged(const QString&,uint)),
this, SLOT(setFont(const QString&,uint)));
connect(Preferences::inst(), SIGNAL(openCSGSettingsChanged()),
this, SLOT(openCSGSettingsChanged()));
connect(Preferences::inst(), SIGNAL(syntaxHighlightChanged(const QString&)),
connect(Preferences::inst(), SIGNAL(syntaxHighlightChanged(const QString&)),
editor, SLOT(setHighlightScheme(const QString&)));
Preferences::inst()->apply();
@ -496,7 +500,7 @@ void MainWindow::report_func(const class AbstractNode*, void *vp, int mark)
{
MainWindow *thisp = static_cast<MainWindow*>(vp);
int v = (int)((mark*1000.0) / progress_report_count);
int permille = v < 1000 ? v : 999;
int permille = v < 1000 ? v : 999;
if (permille > thisp->progresswidget->value()) {
QMetaObject::invokeMethod(thisp->progresswidget, "setValue", Qt::QueuedConnection,
Q_ARG(int, permille));
@ -568,7 +572,7 @@ MainWindow::setFileName(const QString &filename)
} else {
this->fileName = fileinfo.fileName();
}
this->top_ctx.setDocumentPath(fileinfo.dir().absolutePath().toLocal8Bit().constData());
QDir::setCurrent(fileinfo.dir().absolutePath());
}
@ -632,7 +636,7 @@ void MainWindow::refreshDocument()
if (!this->fileName.isEmpty()) {
QFile file(this->fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
PRINTB("Failed to open file %s: %s",
PRINTB("Failed to open file %s: %s",
this->fileName.toLocal8Bit().constData() % file.errorString().toLocal8Bit().constData());
}
else {
@ -783,15 +787,15 @@ void MainWindow::instantiateRoot()
// Evaluate CSG tree
PRINT("Compiling design (CSG Tree generation)...");
if (this->procevents) QApplication::processEvents();
AbstractNode::resetIndexCounter();
// split these two lines - gcc 4.7 bug
ModuleInstantiation mi = ModuleInstantiation( "group" );
this->root_inst = mi;
this->root_inst = mi;
this->absolute_root_node = this->root_module->instantiate(&top_ctx, &this->root_inst, NULL);
if (this->absolute_root_node) {
// Do we have an explicit root node (! modifier)?
if (!(this->root_node = find_root_tag(this->absolute_root_node))) {
@ -863,7 +867,7 @@ void MainWindow::compileCSG(bool procevents)
if (root_raw_term) {
PRINT("Compiling design (CSG Products normalization)...");
if (procevents) QApplication::processEvents();
size_t normalizelimit = 2 * Preferences::inst()->getValue("advanced/openCSGLimit").toUInt();
CSGTermNormalizer normalizer(normalizelimit);
this->root_norm_term = normalizer.normalize(this->root_raw_term);
@ -876,24 +880,24 @@ void MainWindow::compileCSG(bool procevents)
PRINT("WARNING: CSG normalization resulted in an empty tree");
if (procevents) QApplication::processEvents();
}
if (highlight_terms.size() > 0)
{
PRINTB("Compiling highlights (%d CSG Trees)...", highlight_terms.size());
if (procevents) QApplication::processEvents();
highlights_chain = new CSGChain();
for (unsigned int i = 0; i < highlight_terms.size(); i++) {
highlight_terms[i] = normalizer.normalize(highlight_terms[i]);
highlights_chain->import(highlight_terms[i]);
}
}
if (background_terms.size() > 0)
{
PRINTB("Compiling background (%d CSG Trees)...", background_terms.size());
if (procevents) QApplication::processEvents();
background_chain = new CSGChain();
for (unsigned int i = 0; i < background_terms.size(); i++) {
background_terms[i] = normalizer.normalize(background_terms[i]);
@ -901,22 +905,22 @@ void MainWindow::compileCSG(bool procevents)
}
}
if (this->root_chain &&
(this->root_chain->objects.size() >
if (this->root_chain &&
(this->root_chain->objects.size() >
Preferences::inst()->getValue("advanced/openCSGLimit").toUInt())) {
PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size());
PRINT("WARNING: OpenCSG rendering has been disabled.");
}
else {
PRINTB("Normalized CSG tree has %d elements",
PRINTB("Normalized CSG tree has %d elements",
(this->root_chain ? this->root_chain->objects.size() : 0));
this->opencsgRenderer = new OpenCSGRenderer(this->root_chain,
this->highlights_chain,
this->background_chain,
this->opencsgRenderer = new OpenCSGRenderer(this->root_chain,
this->highlights_chain,
this->background_chain,
this->qglview->shaderinfo);
}
this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
this->highlights_chain,
this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
this->highlights_chain,
this->background_chain);
PRINT("CSG generation finished.");
int s = t.elapsed() / 1000;
@ -957,7 +961,7 @@ void MainWindow::actionOpen()
if (!new_filename.isEmpty()) {
if (!maybeSave())
return;
setCurrentOutput();
openFile(new_filename);
clearCurrentOutput();
@ -1040,7 +1044,7 @@ void MainWindow::writeBackup(QFile *file)
QTextStream writer(file);
writer.setCodec("UTF-8");
writer << this->editor->toPlainText();
PRINTB("Saved backup file: %s", file->fileName().toLocal8Bit().constData());
}
@ -1272,13 +1276,13 @@ bool MainWindow::eventFilter(QObject* obj, QEvent *event)
void MainWindow::updateTemporalVariables()
{
this->top_ctx.set_variable("$t", Value(this->e_tval->text().toDouble()));
Value::VectorType vpt;
vpt.push_back(Value(-qglview->cam.object_trans.x()));
vpt.push_back(Value(-qglview->cam.object_trans.y()));
vpt.push_back(Value(-qglview->cam.object_trans.z()));
this->top_ctx.set_variable("$vpt", Value(vpt));
Value::VectorType vpr;
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.x() + 90, 360)));
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.y(), 360)));
@ -1316,21 +1320,21 @@ void MainWindow::compileTopLevelDocument()
{
updateTemporalVariables();
resetPrintedDeprecations();
this->last_compiled_doc = editor->toPlainText();
std::string fulltext =
std::string fulltext =
std::string(this->last_compiled_doc.toLocal8Bit().constData()) +
"\n" + commandline_commands;
delete this->root_module;
this->root_module = NULL;
this->root_module = parse(fulltext.c_str(),
this->fileName.isEmpty() ?
"" :
QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
this->fileName.isEmpty() ?
"" :
QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
false);
}
void MainWindow::checkAutoReload()
@ -1437,7 +1441,7 @@ void MainWindow::csgRender()
filename.sprintf("frame%05d.png", int(round(s*t)));
img.save(filename, "PNG");
}
compileEnded();
}
@ -1503,7 +1507,7 @@ void MainWindow::actionRenderCGALDone(CGAL_Nef_polyhedron *root_N)
PRINTB(" FaceCycles: %6d", root_N->p2->explorer().number_of_face_cycles());
PRINTB(" ConnComp: %6d", root_N->p2->explorer().number_of_connected_components());
}
if (root_N->dim == 3) {
PRINT(" Top level object is a 3D object:");
PRINTB(" Simple: %6s", (root_N->p3->is_simple() ? "yes" : "no"));
@ -1529,7 +1533,7 @@ void MainWindow::actionRenderCGALDone(CGAL_Nef_polyhedron *root_N)
else {
viewModeCGALSurface();
}
PRINT("Rendering finished.");
}
else {
@ -1590,10 +1594,10 @@ void MainWindow::actionDisplayCSGProducts()
e->setWindowTitle("CSG Products Dump");
e->setReadOnly(true);
e->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n\n\nCSG rendering chain:\n%3\n\n\nHighlights CSG rendering chain:\n%4\n\n\nBackground CSG rendering chain:\n%5\n")
.arg(root_raw_term ? QString::fromLocal8Bit(root_raw_term->dump().c_str()) : "N/A",
root_norm_term ? QString::fromLocal8Bit(root_norm_term->dump().c_str()) : "N/A",
this->root_chain ? QString::fromLocal8Bit(this->root_chain->dump().c_str()) : "N/A",
highlights_chain ? QString::fromLocal8Bit(highlights_chain->dump().c_str()) : "N/A",
.arg(root_raw_term ? QString::fromLocal8Bit(root_raw_term->dump().c_str()) : "N/A",
root_norm_term ? QString::fromLocal8Bit(root_norm_term->dump().c_str()) : "N/A",
this->root_chain ? QString::fromLocal8Bit(this->root_chain->dump().c_str()) : "N/A",
highlights_chain ? QString::fromLocal8Bit(highlights_chain->dump().c_str()) : "N/A",
background_chain ? QString::fromLocal8Bit(background_chain->dump().c_str()) : "N/A"));
e->show();
e->resize(600, 400);
@ -1655,7 +1659,7 @@ void MainWindow::actionExportSTLorOFF(bool)
QString suffix = stl_mode ? ".stl" : ".off";
QString stl_filename = QFileDialog::getSaveFileName(this,
stl_mode ? "Export STL File" : "Export OFF File",
stl_mode ? "Export STL File" : "Export OFF File",
this->fileName.isEmpty() ? "Untitled"+suffix : QFileInfo(this->fileName).baseName()+suffix,
stl_mode ? "STL Files (*.stl)" : "OFF Files (*.off)");
if (stl_filename.isEmpty()) {
@ -1708,7 +1712,7 @@ void MainWindow::actionExportDXF()
}
QString dxf_filename = QFileDialog::getSaveFileName(this,
"Export DXF File",
"Export DXF File",
this->fileName.isEmpty() ? "Untitled.dxf" : QFileInfo(this->fileName).baseName()+".dxf",
"DXF Files (*.dxf)");
if (dxf_filename.isEmpty()) {
@ -1741,7 +1745,7 @@ void MainWindow::actionExportCSG()
return;
}
QString csg_filename = QFileDialog::getSaveFileName(this, "Export CSG File",
QString csg_filename = QFileDialog::getSaveFileName(this, "Export CSG File",
this->fileName.isEmpty() ? "Untitled.csg" : QFileInfo(this->fileName).baseName()+".csg",
"CSG Files (*.csg)");
if (csg_filename.isEmpty()) {