#include <QtConcurrent/QtConcurrent>
#include "bigintmandelwidget.h"
-
-static inline QMenuBar *setup_menu_bar(BigintMandelWidget *parent) {
- QMenuBar *menu_bar = new QMenuBar(parent);
- QMenu *menu = new QMenu("&File", parent);
- QPushButton *button = new QPushButton("Settings");
- QAction *two, *four, *eight, *sixteen;
- menu_bar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- QObject::connect(
- menu->addAction("&Reset"),
- &QAction::triggered,
- parent,
- &BigintMandelWidget::reset
- );
- QObject::connect(
- menu->addAction("&Load"),
- &QAction::triggered,
- parent,
- &BigintMandelWidget::load_data
- );
- QObject::connect(
- menu->addAction("&Save"),
- &QAction::triggered,
- parent,
- &BigintMandelWidget::save_data
- );
- menu->addSeparator();
- QObject::connect(
- menu->addAction("&Export"),
- &QAction::triggered,
- parent,
- &BigintMandelWidget::export_img
- );
- menu->addSeparator();
- QObject::connect(
- menu->addAction("E&xit"),
- &QAction::triggered,
- parent,
- &BigintMandelWidget::close
- );
- menu_bar->addMenu(menu);
- menu = new QMenu("&Zoom factor", parent);
- two = menu->addAction("&2");
- four = menu->addAction("&4");
- eight = menu->addAction("&8");
- sixteen = menu->addAction("1&6");
- two->setCheckable(true);
- two->setChecked(true);
- four->setCheckable(true);
- eight->setCheckable(true);
- sixteen->setCheckable(true);
- QObject::connect(
- two,
- &QAction::triggered,
- parent,
- [two, four, eight, sixteen, parent]() {
- two->setChecked(true);
- four->setChecked(false);
- eight->setChecked(false);
- sixteen->setChecked(false);
- parent->set_zoom_factor(2);
- }
- );
- QObject::connect(
- four,
- &QAction::triggered,
- parent,
- [two, four, eight, sixteen, parent]() {
- two->setChecked(false);
- four->setChecked(true);
- eight->setChecked(false);
- sixteen->setChecked(false);
- parent->set_zoom_factor(4);
- }
- );
- QObject::connect(
- eight,
- &QAction::triggered,
- parent,
- [two, four, eight, sixteen, parent]() {
- two->setChecked(false);
- four->setChecked(false);
- eight->setChecked(true);
- sixteen->setChecked(false);
- parent->set_zoom_factor(8);
- }
- );
- QObject::connect(
- sixteen,
- &QAction::triggered,
- parent,
- [two, four, eight, sixteen, parent]() {
- two->setChecked(false);
- four->setChecked(false);
- eight->setChecked(false);
- sixteen->setChecked(true);
- parent->set_zoom_factor(16);
- }
- );
- menu_bar->addMenu(menu);
- QObject::connect(
- button,
- &QPushButton::clicked,
- parent,
- &BigintMandelWidget::exec_settings_widget
- );
- menu_bar->setCornerWidget(button);
- return menu_bar;
-}
-
-static inline void start_calculation(
- QFutureWatcher<MandelResultCell> *fw, QVector<MandelCell> cells
-) {
- fw->setFuture(
- QtConcurrent::mapped(
- cells,
- [](const MandelCell &cell){ return cell.iterate(); }
- )
- );
-}
+#include "mandellabel.h"
+#include "menubar.h"
BigintMandelWidget::BigintMandelWidget(QWidget *parent)
: QWidget(parent),
fw(new QFutureWatcher<MandelResultCell>(this)),
settings(128, QSize(502, 334)),
+ menu_bar(new MenuBar(this)),
scroll_area(new QScrollArea(this)),
- img_label(new QLabel(this)),
- img_dirty(true),
+ mandel_label(new MandelLabel(this)),
status_bar(new QStatusBar(this)),
- settings_widget(new SettingsWidget(this)),
- draw_progress(-1)
+ settings_widget(new SettingsWidget(this))
{
- scroll_area->setWidget(img_label);
+ scroll_area->setWidget(mandel_label);
connect(
settings_widget,
&QDialog::accepted,
this,
&BigintMandelWidget::finished
);
- start_calculation(fw, settings.get_cells());
setLayout(new QVBoxLayout());
- layout()->addWidget(setup_menu_bar(this));
+ layout()->addWidget(menu_bar);
layout()->addWidget(scroll_area);
status_bar->setSizeGripEnabled(false);
layout()->addWidget(status_bar);
- img_label->resize(settings.get_params().get_size());
+ mandel_label->resize(settings.get_params().get_size());
+ start();
}
BigintMandelWidget::~BigintMandelWidget() {
}
void BigintMandelWidget::finished_cell(int num) {
- int y = num / settings.get_params().get_size().width();
- if (y > draw_progress)
- 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_img();
+ update();
}
void BigintMandelWidget::finished() {
- draw_progress = -1;
+ mandel_label->set_draw_progress(-1);
settings_widget->set_finished(true);
- update_img();
-}
-
-static inline QPixmap enhance_pixmap(QPixmap pixmap, int draw_progress) {
- QPainter qp;
- if (draw_progress > -1) {
- qp.begin(&pixmap);
- qp.setPen(Qt::GlobalColor::gray);
- qp.drawLine(0, draw_progress, pixmap.width() - 1, draw_progress);
- qp.end();
- }
- return pixmap;
+ update();
}
-static inline void calculating_status(
- QStatusBar *status_bar, int &prev_num_threads
-) {
- QTextStream ss(new QString());
- int num_threads = QThreadPool::globalInstance()->activeThreadCount();
- if (prev_num_threads == num_threads)
+void BigintMandelWidget::update_status_bar() {
+ QTextStream ss;
+ static int prev_num_threads = -1;
+ int num_threads;
+ if (fw->isFinished())
+ num_threads = -1;
+ else
+ num_threads = QThreadPool::globalInstance()->activeThreadCount();
+ if (num_threads == prev_num_threads)
return;
- ss << "Calculating with " << num_threads << " threads ...";
- status_bar->showMessage(ss.readAll());
+ ss.setString(new QString());
+ if (num_threads != -1)
+ ss << "Calculating with " << num_threads << " threads ...";
+ else
+ ss << "Click the rendering to zoom.";
+ status_bar->showMessage(*ss.string());
prev_num_threads = num_threads;
}
-static inline void finished_status(QStatusBar *status_bar) {
- status_bar->showMessage("Click the rendering to zoom.");
-}
-
-void BigintMandelWidget::paintEvent(QPaintEvent *event) {
- static int prev_num_threads = -1;
- if (!img_dirty)
- return;
- img_label->setPixmap(enhance_pixmap(settings.get_pixmap(), draw_progress));
- img_label->resize(img_label->pixmap().size());
- img_dirty = false;
- if (fw->isFinished())
- finished_status(status_bar);
- else {
- calculating_status(status_bar, prev_num_threads);
- prev_num_threads = -1;
- }
+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;
- for (w = img_label; w != this; w = w->parentWidget())
+ 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
|| !fw->isFinished()
|| 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(), zoom_factor, pos);
- start_calculation(fw, settings.get_cells());
- update_img();
-}
-
-void BigintMandelWidget::update_img() {
- img_dirty = true;
- update();
+ start();
}
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();
}
fw->cancel();
fw->waitForFinished();
settings.reset(128, get_ideal_size());
- start_calculation(fw, settings.get_cells());
- update_img();
+ start();
}
void BigintMandelWidget::settings_widget_accepted() {
settings.set_max_iter(settings_widget->get_max_iter().toULongLong());
- start_calculation(fw, settings.get_cells());
- update_img();
+ start();
}
void BigintMandelWidget::load_data() {
if (file_name.endsWith(".qcompress"))
qba = qUncompress(qba);
settings.from_json(QJsonDocument::fromJson(qba).object());
- update_img();
+ update();
}
void BigintMandelWidget::save_data() {
file.write(qba);
file.close();
}
+
+void BigintMandelWidget::update() {
+ update_status_bar();
+ QWidget::update();
+}