2 // bigintmandelwidget.cpp
9 #include <QtConcurrent/QtConcurrent>
11 #include "bigintmandelwidget.h"
12 #include "mandellabel.h"
15 static inline void start_calculation(
16 QFutureWatcher
<MandelResultCell
> *fw
, QVector
<MandelCell
> cells
21 [](const MandelCell
&cell
){ return cell
.iterate(); }
26 BigintMandelWidget::BigintMandelWidget(QWidget
*parent
)
28 fw(new QFutureWatcher
<MandelResultCell
>(this)),
29 settings(128, QSize(502, 334)),
30 menu_bar(new MenuBar(this)),
31 scroll_area(new QScrollArea(this)),
32 mandel_label(new MandelLabel(this)),
33 status_bar(new QStatusBar(this)),
34 settings_widget(new SettingsWidget(this))
36 scroll_area
->setWidget(mandel_label
);
41 &BigintMandelWidget::settings_widget_accepted
45 &QFutureWatcher
<MandelResultCell
>::resultReadyAt
,
47 &BigintMandelWidget::finished_cell
51 &QFutureWatcher
<MandelResultCell
>::finished
,
53 &BigintMandelWidget::finished
55 start_calculation(fw
, settings
.get_cells());
56 setLayout(new QVBoxLayout());
57 layout()->addWidget(menu_bar
);
58 layout()->addWidget(scroll_area
);
59 status_bar
->setSizeGripEnabled(false);
60 layout()->addWidget(status_bar
);
61 mandel_label
->resize(settings
.get_params().get_size());
64 BigintMandelWidget::~BigintMandelWidget() {
66 fw
->waitForFinished();
69 void BigintMandelWidget::finished_cell(int num
) {
70 int y
= num
/ settings
.get_params().get_size().width();
71 mandel_label
->set_draw_progress(y
);
72 settings
.finished_cell(num
, fw
->resultAt(num
));
76 void BigintMandelWidget::finished() {
77 mandel_label
->set_draw_progress(-1);
78 settings_widget
->set_finished(true);
82 void BigintMandelWidget::update_status_bar() {
84 static int prev_num_threads
= -1;
89 num_threads
= QThreadPool::globalInstance()->activeThreadCount();
90 if (num_threads
== prev_num_threads
)
92 ss
.setString(new QString());
93 if (num_threads
!= -1)
94 ss
<< "Calculating with " << num_threads
<< " threads ...";
96 ss
<< "Click the rendering to zoom.";
97 status_bar
->showMessage(*ss
.string());
98 prev_num_threads
= num_threads
;
101 void BigintMandelWidget::mousePressEvent(QMouseEvent
*event
) {
102 QSize
size(settings
.get_params().get_size());
103 QPoint
pos(event
->pos());
105 for (w
= mandel_label
; w
!= this; w
= w
->parentWidget())
106 pos
= w
->mapFromParent(pos
);
107 if (event
->button() != Qt::MouseButton::LeftButton
110 || pos
.x() >= size
.width()
112 || pos
.y() >= size
.height())
114 settings
.zoom(get_ideal_size(), menu_bar
->get_zoom_factor(), pos
);
115 start_calculation(fw
, settings
.get_cells());
119 static inline QString
get_save_file_name(
120 QWidget
*parent
= nullptr,
121 const QString
&caption
= QString(),
122 const QString
&dir
= QString(),
123 const QString
&filter_title
= QString(),
124 const QStringList
&ext_list
= QStringList
{},
125 const QString default_ext
= QString()
127 QTextStream
ss(new QString());
128 QStringList::const_iterator ext_list_iter
;
131 ss
<< filter_title
<< " (" << ext_list
.join(" ") << ")";
132 file_name
= QFileDialog::getSaveFileName(
133 parent
, caption
, dir
, *ss
.string()
135 if (file_name
.isEmpty())
138 ss
.string()->clear();
140 pos
= file_name
.lastIndexOf(".");
141 if (pos
< 0 || !ext_list
.contains(file_name
.mid(pos
)))
146 void BigintMandelWidget::export_img() {
147 QString file_name
= get_save_file_name(
152 QStringList
{".png", ".xpm", ".jpg"},
155 if (!file_name
.isEmpty())
156 settings
.save_img(file_name
);
159 void BigintMandelWidget::exec_settings_widget() {
160 settings_widget
->update_fields(settings
.get_params(), fw
->isFinished());
161 settings_widget
->exec();
164 void BigintMandelWidget::reset() {
166 fw
->waitForFinished();
167 settings
.reset(128, get_ideal_size());
168 start_calculation(fw
, settings
.get_cells());
172 void BigintMandelWidget::settings_widget_accepted() {
173 settings
.set_max_iter(settings_widget
->get_max_iter().toULongLong());
174 start_calculation(fw
, settings
.get_cells());
178 void BigintMandelWidget::load_data() {
182 QString file_name
= QFileDialog::getOpenFileName(
183 this, "Load Data", "", "BigintMandel Data (*.json *.json.qcompress)"
185 if (file_name
.isEmpty())
187 file
.setFileName(file_name
);
188 if (!file
.open(QIODevice::ReadOnly
)) {
189 qWarning("Couldn't open save file.");
192 qba
= file
.readAll();
194 if (file_name
.endsWith(".qcompress"))
195 qba
= qUncompress(qba
);
196 settings
.from_json(QJsonDocument::fromJson(qba
).object());
200 void BigintMandelWidget::save_data() {
203 QString file_name
= get_save_file_name(
208 QStringList
{".json", ".json.qcompress"},
211 if (file_name
.isEmpty())
213 qba
= QJsonDocument(settings
.to_json()).toJson();
214 if (file_name
.endsWith(".qcompress"))
215 qba
= qCompress(qba
, 9);
216 file
.setFileName(file_name
);
217 if (!file
.open(QIODevice::WriteOnly
)) {
218 qWarning("Couldn't open save file.");
225 void BigintMandelWidget::update() {