From 5b02172eada89fb48f4be24090665246b629ce89 Mon Sep 17 00:00:00 2001 From: mar77i Date: Mon, 29 Apr 2024 02:32:42 +0200 Subject: [PATCH] display zoom rect, cleanup --- bigintmandelwidget.cpp | 56 ++++++++++++++++++++++-------------------- bigintmandelwidget.h | 8 +++++- mandellabel.cpp | 49 +++++++++++++++++++++++++++++++++--- mandellabel.h | 8 +++++- menubar.cpp | 33 +++++++++++++------------ menubar.h | 18 +++++++++++--- 6 files changed, 121 insertions(+), 51 deletions(-) diff --git a/bigintmandelwidget.cpp b/bigintmandelwidget.cpp index 97dfa52..6280e54 100644 --- a/bigintmandelwidget.cpp +++ b/bigintmandelwidget.cpp @@ -12,17 +12,6 @@ #include "mandellabel.h" #include "menubar.h" -static inline void start_calculation( - QFutureWatcher *fw, QVector cells -) { - fw->setFuture( - QtConcurrent::mapped( - cells, - [](const MandelCell &cell){ return cell.iterate(); } - ) - ); -} - BigintMandelWidget::BigintMandelWidget(QWidget *parent) : QWidget(parent), fw(new QFutureWatcher(this)), @@ -52,13 +41,13 @@ BigintMandelWidget::BigintMandelWidget(QWidget *parent) this, &BigintMandelWidget::finished ); - start_calculation(fw, settings.get_cells()); setLayout(new QVBoxLayout()); layout()->addWidget(menu_bar); layout()->addWidget(scroll_area); status_bar->setSizeGripEnabled(false); layout()->addWidget(status_bar); mandel_label->resize(settings.get_params().get_size()); + start(); } BigintMandelWidget::~BigintMandelWidget() { @@ -67,8 +56,9 @@ BigintMandelWidget::~BigintMandelWidget() { } void BigintMandelWidget::finished_cell(int num) { - int y = num / settings.get_params().get_size().width(); - mandel_label->set_draw_progress(y); + QSize size = settings.get_params().get_size(); + int y = num / size.width() + 1; + mandel_label->set_draw_progress(y < size.height() - 1 ? y + 1 : -1); settings.finished_cell(num, fw->resultAt(num)); update(); } @@ -98,10 +88,22 @@ void BigintMandelWidget::update_status_bar() { prev_num_threads = num_threads; } +void BigintMandelWidget::start() { + fw->setFuture( + QtConcurrent::mapped( + settings.get_cells(), + [](const MandelCell &cell){ return cell.iterate(); } + ) + ); + menu_bar->set_zoom_factor(-1); + update(); +} + void BigintMandelWidget::mousePressEvent(QMouseEvent *event) { QSize size(settings.get_params().get_size()); QPoint pos(event->pos()); QWidget *w; + int zoom_factor = menu_bar->get_zoom_factor(); for (w = mandel_label; w != this; w = w->parentWidget()) pos = w->mapFromParent(pos); if (event->button() != Qt::MouseButton::LeftButton @@ -109,11 +111,11 @@ void BigintMandelWidget::mousePressEvent(QMouseEvent *event) { || pos.x() < 0 || pos.x() >= size.width() || pos.y() < 0 - || pos.y() >= size.height()) + || pos.y() >= size.height() + || zoom_factor == -1) return; - settings.zoom(get_ideal_size(), menu_bar->get_zoom_factor(), pos); - start_calculation(fw, settings.get_cells()); - update(); + settings.zoom(get_ideal_size(), zoom_factor, pos); + start(); } static inline QString get_save_file_name( @@ -127,18 +129,22 @@ static inline QString get_save_file_name( QTextStream ss(new QString()); QStringList::const_iterator ext_list_iter; QString file_name; - qsizetype pos; ss << filter_title << " (" << ext_list.join(" ") << ")"; file_name = QFileDialog::getSaveFileName( parent, caption, dir, *ss.string() ); if (file_name.isEmpty()) return file_name; - ss.seek(0); ss.string()->clear(); ss << file_name; - pos = file_name.lastIndexOf("."); - if (pos < 0 || !ext_list.contains(file_name.mid(pos))) + for ( + ext_list_iter = ext_list.constBegin(); + ext_list_iter != ext_list.constEnd(); + ext_list_iter++ + ) + if (file_name.endsWith(*ext_list_iter)) + break; + if (ext_list_iter == ext_list.constEnd()) ss << default_ext; return *ss.string(); } @@ -165,14 +171,12 @@ void BigintMandelWidget::reset() { fw->cancel(); fw->waitForFinished(); settings.reset(128, get_ideal_size()); - start_calculation(fw, settings.get_cells()); - update(); + start(); } void BigintMandelWidget::settings_widget_accepted() { settings.set_max_iter(settings_widget->get_max_iter().toULongLong()); - start_calculation(fw, settings.get_cells()); - update(); + start(); } void BigintMandelWidget::load_data() { diff --git a/bigintmandelwidget.h b/bigintmandelwidget.h index 2101cb6..8f20425 100644 --- a/bigintmandelwidget.h +++ b/bigintmandelwidget.h @@ -28,17 +28,23 @@ class BigintMandelWidget : public QWidget { SettingsWidget *settings_widget; void update_status_bar(); + void start(); inline const QSize get_ideal_size() const { return scroll_area->size().shrunkBy(scroll_area->contentsMargins()); } +protected: + void mousePressEvent(QMouseEvent *event); + public: explicit BigintMandelWidget(QWidget *parent = nullptr); ~BigintMandelWidget(); - void mousePressEvent(QMouseEvent *event); inline const MandelSettings *get_settings() const { return &settings; } + inline const MenuBar *get_menu_bar() const { + return menu_bar; + } public Q_SLOTS: void reset(); diff --git a/mandellabel.cpp b/mandellabel.cpp index 397b166..f7d600c 100644 --- a/mandellabel.cpp +++ b/mandellabel.cpp @@ -4,23 +4,66 @@ #include #include "mandellabel.h" +#include "menubar.h" +#include "qevent.h" MandelLabel::MandelLabel(BigintMandelWidget *parent) : QLabel(parent), settings(parent->get_settings()), - draw_progress(-1) {} + menu_bar(parent->get_menu_bar()), + draw_progress(-1), + zoom_rect_center(-1, -1) { + setMouseTracking(true); +} + +static inline QRect get_rect(QSize size, QPoint pos, int zoom_factor) { + QSize scaled_size(size.width() / zoom_factor, size.height() / zoom_factor); + return QRect( + QPoint( + pos.x() - scaled_size.width() / 2, + pos.y() - scaled_size.height() / 2 + ), + scaled_size + ); +} void MandelLabel::paintEvent(QPaintEvent *event) { QPixmap pixmap; QPainter qp; + int zoom_factor = menu_bar->get_zoom_factor(); + bool draw_zoom_rect = ( + zoom_factor != -1 + && zoom_rect_center.x() != -1 + && zoom_rect_center.y() != -1 + ); pixmap = settings->get_pixmap(); - if (draw_progress != -1) { + if (draw_progress != -1 || draw_zoom_rect) qp.begin(&pixmap); + if (draw_progress != -1) { qp.setPen(Qt::GlobalColor::gray); qp.drawLine(0, draw_progress, pixmap.width() - 1, draw_progress); - qp.end(); } + if (draw_zoom_rect) { + qp.setPen(Qt::GlobalColor::gray); + qp.drawRect( + get_rect( + pixmap.size(), + zoom_rect_center, + zoom_factor + ) + ); + } + if (draw_progress != -1 || draw_zoom_rect) + qp.end(); resize(pixmap.size()); setPixmap(pixmap); QLabel::paintEvent(event); } + +void MandelLabel::leaveEvent(QEvent *event) { + zoom_rect_center = QPoint(-1, -1); +} + +void MandelLabel::mouseMoveEvent(QMouseEvent *event) { + zoom_rect_center = event->pos(); +} diff --git a/mandellabel.h b/mandellabel.h index 4d5fccd..39a8822 100644 --- a/mandellabel.h +++ b/mandellabel.h @@ -11,11 +11,17 @@ class MandelLabel : public QLabel { const MandelSettings *settings; + const MenuBar *menu_bar; int draw_progress; + QPoint zoom_rect_center; + +protected: + void paintEvent(QPaintEvent *event); + void leaveEvent(QEvent *event); + void mouseMoveEvent(QMouseEvent *event); public: explicit MandelLabel(BigintMandelWidget *parent = nullptr); - void paintEvent(QPaintEvent *event); inline int get_draw_progress() { return draw_progress; } inline void set_draw_progress(int draw_progress) { if (draw_progress == this->draw_progress) diff --git a/menubar.cpp b/menubar.cpp index 0042659..39683c3 100644 --- a/menubar.cpp +++ b/menubar.cpp @@ -23,21 +23,17 @@ static inline QAction *zoom_action( MenuBar::MenuBar(BigintMandelWidget *parent) : QMenuBar(parent), file_menu(new QMenu("&File", parent)), - zoom_factor_menu(new QMenu("&Zoom factor", parent)), - zoom_factor(2) { + calc_menu(new QMenu("&Calculation", parent)), + zoom_menu(new QMenu("&Zoom", parent)), + zoom_factor(-1) { QKeySequence no_key; setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - addMenu(file_menu); - reset_action = file_menu->addAction( - "&Reset", no_key, parent, &BigintMandelWidget::reset - ); load_action = file_menu->addAction( "&Load...", no_key, parent, &BigintMandelWidget::load_data ); save_action = file_menu->addAction( "&Save...", no_key, parent, &BigintMandelWidget::save_data ); - file_menu->addSeparator(); export_action = file_menu->addAction( "&Export...", no_key, parent, &BigintMandelWidget::export_img ); @@ -45,16 +41,21 @@ MenuBar::MenuBar(BigintMandelWidget *parent) exit_action = file_menu->addAction( "E&xit", no_key, parent, &BigintMandelWidget::close ); + addMenu(file_menu); - addMenu(zoom_factor_menu); - two_action = zoom_action(this, zoom_factor_menu->addAction("&2"), 2); - four_action = zoom_action(this, zoom_factor_menu->addAction("&4"), 4); - eight_action = zoom_action(this, zoom_factor_menu->addAction("&8"), 8); - sixteen_action = zoom_action(this, zoom_factor_menu->addAction("1&6"), 16); - check_action(); -} + reset_action = calc_menu->addAction( + "&Reset", no_key, parent, &BigintMandelWidget::reset + ); + settings_action = calc_menu->addAction( + "&Settings", no_key, parent, &BigintMandelWidget::exec_settings_widget + ); + addMenu(calc_menu); -void MenuBar::change_zoom_factor() { - zoom_factor = static_cast(sender())->data().toInt(); + no_action = zoom_action(this, zoom_menu->addAction("&Off"), -1); + two_action = zoom_action(this, zoom_menu->addAction("&2"), 2); + four_action = zoom_action(this, zoom_menu->addAction("&4"), 4); + eight_action = zoom_action(this, zoom_menu->addAction("&8"), 8); + sixteen_action = zoom_action(this, zoom_menu->addAction("1&6"), 16); + addMenu(zoom_menu); check_action(); } diff --git a/menubar.h b/menubar.h index d251e61..e1b0702 100644 --- a/menubar.h +++ b/menubar.h @@ -12,13 +12,17 @@ class MenuBar : public QMenuBar { Q_OBJECT QMenu *file_menu; - QAction *reset_action, *load_action, *save_action; + QAction *load_action, *save_action; QAction *export_action, *exit_action; - QMenu *zoom_factor_menu; - QAction *two_action, *four_action, *eight_action, *sixteen_action; + QMenu *calc_menu; + QAction *reset_action, *settings_action; + QMenu *zoom_menu; + QAction *no_action, *two_action, *four_action; + QAction *eight_action, *sixteen_action; int zoom_factor; inline void check_action() { + no_action->setChecked(zoom_factor == -1); two_action->setChecked(zoom_factor == 2); four_action->setChecked(zoom_factor == 4); eight_action->setChecked(zoom_factor == 8); @@ -28,8 +32,14 @@ class MenuBar : public QMenuBar { public: explicit MenuBar(BigintMandelWidget *parent); inline int get_zoom_factor() const { return zoom_factor; } + inline void set_zoom_factor(int zoom_factor) { + this->zoom_factor = zoom_factor; + check_action(); + } public Q_SLOTS: - void change_zoom_factor(); + void change_zoom_factor() { + set_zoom_factor(static_cast(sender())->data().toInt()); + } }; #endif // MENUBAR_H -- 2.47.1