From 7f820c8f6798d42370dc7668aaa40b494a6e5ea8 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 26 Aug 2020 23:44:50 +0300 Subject: [PATCH] new Graphic feature - floatingAxisType: Free, TraceX/Y qpicalculator moved to PIEvaluator --- CMakeLists.txt | 2 +- piqt/utils/qpicalculator/CMakeLists.txt | 2 +- piqt/utils/qpicalculator/mainwindow.cpp | 27 +++++-- piqt/utils/qpicalculator/mainwindow.h | 6 +- qad/libs/graphic/graphic.cpp | 102 +++++++++++++++++++----- qad/libs/graphic/graphic.h | 9 ++- qad/libs/graphic/graphic.ui | 47 ++++++++--- 7 files changed, 150 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8390db..342bd71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ else() endif() set(_QAD_MAJOR 1) -set(_QAD_MINOR 7) +set(_QAD_MINOR 8) set(_QAD_REVISION 0) set(_QAD_SUFFIX ) set(_QAD_COMPANY SHS) diff --git a/piqt/utils/qpicalculator/CMakeLists.txt b/piqt/utils/qpicalculator/CMakeLists.txt index 27ecf2c..9400a12 100644 --- a/piqt/utils/qpicalculator/CMakeLists.txt +++ b/piqt/utils/qpicalculator/CMakeLists.txt @@ -7,7 +7,7 @@ else() set(APP_ICON "icons/qpicalculator.png") endif() set(APP_INFO "Small calculator ang grapher") -qad_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_graphic") +qad_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_graphic;pip;piqt") if (Qt5_FOUND) import_version(${PROJ_NAME}5 ${PROJECT_NAME}) deploy_target(${PROJECT_NAME}5 DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR} DESTINATION ${ROOT_DIR}/release) diff --git a/piqt/utils/qpicalculator/mainwindow.cpp b/piqt/utils/qpicalculator/mainwindow.cpp index 4381f41..e6825f2 100644 --- a/piqt/utils/qpicalculator/mainwindow.cpp +++ b/piqt/utils/qpicalculator/mainwindow.cpp @@ -1,4 +1,5 @@ #include "mainwindow.h" +#include "piqt.h" MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow() { @@ -62,7 +63,7 @@ void MainWindow::redrawGraphics() { graphic->setGraphicName(ti->text(1), i); pol.clear(); if (ti->checkState(0) == Qt::Checked) { - if (evaluator.check(ti->text(1))) { + if (evaluator.check(Q2PIString(ti->text(1)))) { cx = sx; while (cx < fx) { evaluator.setVariable(vi, complexd(cx, 0.)); @@ -140,19 +141,19 @@ void MainWindow::saving(QPIConfig & conf) { void MainWindow::on_lineInput_textChanged(QString text) { - if (evaluator.check(text)) lineInput->setPalette(npal); + if (evaluator.check(Q2PIString(text))) lineInput->setPalette(npal); else lineInput->setPalette(epal); - labelParsed->setText(evaluator.expression()); - labelError->setText(evaluator.error()); + labelParsed->setText(PI2QString(evaluator.expression())); + labelError->setText(PI2QString(evaluator.error())); } void MainWindow::on_lineInput_returnPressed() { - bool ret = evaluator.check(lineInput->text()); + bool ret = evaluator.check(Q2PIString(lineInput->text())); if (ret) lineInput->setPalette(npal); else lineInput->setPalette(epal); - labelParsed->setText(evaluator.expression()); - labelError->setText(evaluator.error()); + labelParsed->setText(PI2QString(evaluator.expression())); + labelError->setText(PI2QString(evaluator.error())); if (!ret) return; complexd val = evaluator.evaluate(); evaluator.setVariable(ans, val); @@ -182,6 +183,16 @@ void MainWindow::on_lineInput_returnPressed() { } +void MainWindow::on_treeGraphics_itemSelectionChanged() { + buttonGraphicDel->setDisabled(treeGraphics->selectedItems().isEmpty()); + if (treeGraphics->currentItem()) { + int ind = treeGraphics->indexOfTopLevelItem(treeGraphics->currentItem()); + if (ind < 0 || ind >= graphic->graphicsCount()) return; + graphic->setCurrentGraphic(ind); + } +} + + void MainWindow::on_treeGraphics_itemDoubleClicked(QTreeWidgetItem * item, int column) { Qt::ItemFlags f = item->flags(); if (column != 1) f &= ~Qt::ItemIsEditable; @@ -254,7 +265,7 @@ void MainWindow::on_tabWidget_currentChanged(int index) { vn = treeVariables->topLevelItem(i)->text(0); vv = treeVariables->topLevelItem(i)->text(1); eval.check(vv); - evaluator.setVariable(vn, eval.evaluate()); + evaluator.setVariable(Q2PIString(vn), eval.evaluate()); } if (index == 0) on_lineInput_returnPressed(); if (index == 2) redrawGraphics(); diff --git a/piqt/utils/qpicalculator/mainwindow.h b/piqt/utils/qpicalculator/mainwindow.h index efb44b9..b46c4dd 100644 --- a/piqt/utils/qpicalculator/mainwindow.h +++ b/piqt/utils/qpicalculator/mainwindow.h @@ -8,7 +8,7 @@ #include #include #include "ui_mainwindow.h" -#include "qpievaluator.h" +#include "pievaluator.h" #include "session_manager.h" @@ -26,7 +26,7 @@ private: void updateGraphics(); void redrawGraphics(); - QPIEvaluator evaluator; + PIEvaluator evaluator; QPalette npal, epal; SessionManager session; int ans; @@ -39,7 +39,7 @@ private slots: void on_lineInput_returnPressed(); void on_treeHistory_itemDoubleClicked(QTreeWidgetItem * item, int column) {lineInput->setText(item->text(0));} void on_treeVariables_itemSelectionChanged() {buttonVarDel->setDisabled(treeVariables->selectedItems().isEmpty());} - void on_treeGraphics_itemSelectionChanged() {buttonGraphicDel->setDisabled(treeGraphics->selectedItems().isEmpty());} + void on_treeGraphics_itemSelectionChanged(); void on_treeGraphics_itemChanged(QTreeWidgetItem * , int col) { if (active_) redrawGraphics();} void on_treeGraphics_itemDoubleClicked(QTreeWidgetItem * item, int column); void on_buttonVarAdd_clicked(); diff --git a/qad/libs/graphic/graphic.cpp b/qad/libs/graphic/graphic.cpp index c7b7eb6..d4fcb41 100644 --- a/qad/libs/graphic/graphic.cpp +++ b/qad/libs/graphic/graphic.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # include #endif @@ -37,6 +38,18 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), #endif ui = new Ui::Graphic(); ui->setupUi(this); + QActionGroup * agroup = new QActionGroup(this); + agroup->addAction(ui->actionGuidesFree ); + agroup->addAction(ui->actionGuidesTraceX); + agroup->addAction(ui->actionGuidesTraceY); + ui->actionGuidesFree ->setProperty("_value", (int)Free ); + ui->actionGuidesTraceX->setProperty("_value", (int)TraceX); + ui->actionGuidesTraceY->setProperty("_value", (int)TraceY); + ui->actionGuidesFree->setChecked(true); + connect(agroup, SIGNAL(triggered(QAction*)), this, SLOT(actionGuidesTriggered(QAction*))); + ui->checkGuides->addAction(ui->actionGuidesFree ); + ui->checkGuides->addAction(ui->actionGuidesTraceX); + ui->checkGuides->addAction(ui->actionGuidesTraceY); line_x_min.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); line_x_max.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); ((QBoxLayout * )ui->widgetLY->layout())->insertWidget(0, &line_y_min); @@ -76,6 +89,7 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), emaxx = emaxy = DBL_MIN; grad_x = grad_y = Auto; axis_type_x = Numeric; + floating_axis_type = Free; min_repaint_int = 25; inc_x = 1.; buffer = 0; @@ -374,10 +388,7 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) { emit graphicMousePressEvent(canvas2real(QPointF(e->pos())), e->button()); if (!navigation) return; if (gestures && !need_mouse_pan) return; -#ifdef HAS_GL - canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); -#endif - ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); + setGuidesCursor(); prevpos = e->pos(); startpos = prevpos; startpos_r = canvas2real(startpos); @@ -393,7 +404,7 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) { return; } else { prevaction = curaction; - curaction = gaMove; + setCurrentAction(gaMove); return; } } @@ -419,10 +430,7 @@ void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) { if (gestures) return; need_mouse_pan = false; if (!navigation) return; -#ifdef HAS_GL - canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); -#endif - ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); + setGuidesCursor(); QPointF tlp, brp; QRect sr; sr = QRect(startpos, curpos).normalized(); @@ -1149,14 +1157,58 @@ void Graphic::drawGuides() { painter->resetTransform(); painter->setClipping(true); painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y())); - painter->drawLine(0, curpos.y(), wid, curpos.y()); - painter->drawLine(curpos.x(), 0, curpos.x(), hei); - QString str = pointCoords(canvas2real(curpos)) + fp_size; + QPoint apos = curpos; + QPointF rpos = canvas2real(apos); + QString str; + str = pointCoords(rpos) + fp_size; + switch (floating_axis_type) { + case TraceX: + if (curGraphic >= 0 && curGraphic < graphics.size()) { + QPolygonF & pol(pause_ ? graphics[curGraphic].polyline_pause : graphics[curGraphic].polyline); + double cursor = rpos.x(), min_dist = -1, dist = 0.; + int index = -1; + for (int i = 0; i < pol.size(); ++i) { + dist = qAbs(pol[i].x() - cursor); + if (min_dist > dist || min_dist < 0) { + min_dist = dist; + index = i; + } + } + if (index >= 0) { + rpos = pol[index]; + apos = real2canvas(rpos).toPoint(); + str = pointCoords(pol[index]) + fp_size; + } + } + break; + case TraceY: + if (curGraphic >= 0 && curGraphic < graphics.size()) { + QPolygonF & pol(pause_ ? graphics[curGraphic].polyline_pause : graphics[curGraphic].polyline); + double cursor = rpos.y(), min_dist = -1, dist = 0.; + int index = -1; + for (int i = 0; i < pol.size(); ++i) { + dist = qAbs(pol[i].y() - cursor); + if (min_dist > dist || min_dist < 0) { + min_dist = dist; + index = i; + } + } + if (index >= 0) { + rpos = pol[index]; + apos = real2canvas(rpos).toPoint(); + str = pointCoords(pol[index]) + fp_size; + } + } + break; + default: break; + } + painter->drawLine(0, apos.y(), wid, apos.y()); + painter->drawLine(apos.x(), 0, apos.x(), hei); + QPoint p = apos + QPoint(font_sz.height() / 4., -font_sz.height() / 4.); QFontMetrics fm(font()); QRect r = fm.boundingRect(str); - QPoint p = curpos + QPoint(font_sz.height() / 4., -font_sz.height() / 4.); - if (r.width() + curpos.x() > wid - font_sz.height() / 2.) p.setX(curpos.x() - r.width() - font_sz.height() / 4.); - if (curpos.y() - r.height() < font_sz.height() / 8.) p.setY(curpos.y() + r.height() - font_sz.height() / 8.); + if (r.width() + apos.x() > wid - font_sz.height() / 2.) p.setX(apos.x() - r.width() - font_sz.height() / 4.); + if (apos.y() - r.height() < font_sz.height() / 8.) p.setY(apos.y() + r.height() - font_sz.height() / 8.); painter->setPen(text_color); painter->drawText(p, str); } @@ -1287,8 +1339,7 @@ void Graphic::setCurrentAction(GraphicAction action) { curaction = action; switch (action) { case gaNone: - if (guides) setCanvasCursor(Qt::BlankCursor); - else setCanvasCursor(Qt::ArrowCursor); + setGuidesCursor(); break; case gaZoomInRect: setCanvasCursor(Qt::CrossCursor); @@ -1314,6 +1365,14 @@ void Graphic::setCanvasCursor(QCursor cursor) { } +void Graphic::setGuidesCursor() { + if (guides) { + setCanvasCursor(floating_axis_type == Free ? Qt::BlankCursor : Qt::CrossCursor); + } else + setCanvasCursor(Qt::ArrowCursor); +} + + void Graphic::swapToBuffer() { QImage timg; #ifdef HAS_GL @@ -1461,8 +1520,7 @@ void Graphic::on_buttonConfigure_clicked() { void Graphic::on_checkGuides_toggled(bool checked) { guides = checked; - if (guides) setCanvasCursor(Qt::BlankCursor); - else setCanvasCursor(Qt::ArrowCursor); + setGuidesCursor(); update(); } @@ -1743,3 +1801,9 @@ void Graphic::on_checkExpandX_toggled(bool checked) { only_expand_x = checked; ui->checkExpandX->setIcon(checked ? icon_exp_x : icon_exp_sx); } + + +void Graphic::actionGuidesTriggered(QAction * a) { + ui->checkGuides->setChecked(true); + setFloatingAxisType((FloatingAxisType)a->property("_value").toInt()); +} diff --git a/qad/libs/graphic/graphic.h b/qad/libs/graphic/graphic.h index 199cf54..b66381f 100644 --- a/qad/libs/graphic/graphic.h +++ b/qad/libs/graphic/graphic.h @@ -53,7 +53,7 @@ class QAD_GRAPHIC_EXPORT Graphic: public QFrame { Q_OBJECT Q_FLAGS(Buttons) - Q_ENUMS(Alignment Graduation AxisType) + Q_ENUMS(Alignment Graduation AxisType FloatingAxisType) Q_PROPERTY(QString caption READ caption WRITE setCaption) Q_PROPERTY(QString labelX READ labelX WRITE setLabelX) @@ -113,6 +113,7 @@ class QAD_GRAPHIC_EXPORT Graphic: public QFrame Q_PROPERTY(double graduationStepX READ graduationStepX WRITE setGraduationStepX) Q_PROPERTY(double graduationStepY READ graduationStepY WRITE setGraduationStepY) Q_PROPERTY(AxisType axisType READ axisType WRITE setAxisType) + Q_PROPERTY(FloatingAxisType floatingAxisType READ floatingAxisType WRITE setFloatingAxisType) Q_PROPERTY(Graphic::GraphicsData graphicsData READ graphicsData WRITE setGraphicsData) Q_PROPERTY(QByteArray graphicsDataRaw READ graphicsDataRaw WRITE setGraphicsDataRaw) @@ -143,6 +144,7 @@ public: enum Alignment {Left, Right}; enum Graduation {Auto, Fixed}; enum AxisType {Numeric, DateTime}; + enum FloatingAxisType {Free, TraceX, TraceY}; Q_DECLARE_FLAGS(Buttons, Button) QString caption() const; @@ -200,6 +202,7 @@ public: double graduationStepX() const {return gridx;} double graduationStepY() const {return gridy;} AxisType axisType() const {return axis_type_x;} + FloatingAxisType floatingAxisType() const {return floating_axis_type;} QVector graphicData(const int index = 0) const {return graphics[index].polyline;} GraphicsData graphicsData() const; QByteArray graphicsDataRaw() const; @@ -294,6 +297,7 @@ public slots: void setGraduationStepY(double sy) {gridy = sy; if (aupdate) update();} void setGraduationSteps(double sx, double sy) {gridx = sx; gridy = sy; if (aupdate) update();} void setAxisType(AxisType t) {axis_type_x = t; if (aupdate) update();} + void setFloatingAxisType(FloatingAxisType t) {floating_axis_type = t; setGuidesCursor(); if (aupdate) update();} void addPoint(const QPointF & p, int graphic, bool update_ = true); void addPoint(const QPointF & p, bool update = true) {addPoint(p, curGraphic, update);} @@ -346,6 +350,7 @@ protected: void updateLegend(bool es = true); void updateLegendChecks(); void setCanvasCursor(QCursor cursor); + void setGuidesCursor(); void swapToBuffer(); void swapToNormal() {bufferActive = false;} void setRectToLines(); @@ -388,6 +393,7 @@ protected: QImage icon_pause_b, icon_pause_f; Graduation grad_x, grad_y; AxisType axis_type_x; + FloatingAxisType floating_axis_type; double gridx, gridy, history, visible_time, inc_x, grid_numbers_x, grid_numbers_y, LN10; double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle; int lastw, lasth, min_repaint_int, timer_pause, thick; @@ -422,6 +428,7 @@ protected slots: void on_checkBorderInputs_toggled(bool checked) {setBorderInputsVisible(checked);} void on_checkLegend_toggled(bool checked) {setLegendVisible(checked);} void on_checkPause_toggled(bool checked) {setPaused(checked);} + void actionGuidesTriggered(QAction * a); void enterFullscreen(); void leaveFullscreen(); diff --git a/qad/libs/graphic/graphic.ui b/qad/libs/graphic/graphic.ui index 2e58869..e2c2f4b 100644 --- a/qad/libs/graphic/graphic.ui +++ b/qad/libs/graphic/graphic.ui @@ -64,7 +64,7 @@ Grid - + :/icons/view-grid.png:/icons/view-grid.png @@ -81,7 +81,7 @@ Cursor axis - + :/icons/edit-guides.png:/icons/edit-guides.png @@ -95,7 +95,7 @@ Only expand Y - + :/icons/expand_s_y.png:/icons/expand_s_y.png @@ -109,7 +109,7 @@ Only expand X - + :/icons/expand_s_x.png:/icons/expand_s_x.png @@ -134,7 +134,7 @@ Border inputs - + :/icons/border-line.png:/icons/border-line.png @@ -151,7 +151,7 @@ Legend - + :/icons/legend.png:/icons/legend.png @@ -182,7 +182,7 @@ Configure ... - + :/icons/configure.png:/icons/configure.png @@ -193,7 +193,7 @@ Save image ... - + :/icons/document-save.png:/icons/document-save.png @@ -220,7 +220,7 @@ Clear - + :/icons/edit-clear.png:/icons/edit-clear.png @@ -231,7 +231,7 @@ Close - + :/icons/dialog-close.png:/icons/dialog-close.png @@ -425,6 +425,30 @@ + + + true + + + Free + + + + + true + + + Trace X + + + + + true + + + Trace Y + + @@ -434,8 +458,7 @@ - - +