mirror of https://github.com/vitalif/openscad
Preventing loosing keyboard focus by editor.
When you write your code in editor sometimes you want to rotate or move object on 3D view, but due stealing focus by this widget it is quite tedious. You need additional mouse click to return focus to editor and search line where you last edited. This behavior is not neccessary as we can interpret keyboard events globally (in MainWindow) and send commands to 3D view. Console window need ClickFocus to show context menu. Zoom In/Out 3D view is assigned to CTRL+[ and CTRL+]. Adding also additional shortcut to zoom in editor font CTRL+= (with CTRL++ SHIFT is necessary).master
parent
fcf7b27257
commit
ff555d760b
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Reference in New Issue