3 * bigintmandelwidget.cpp
5 * This file is covered by the LICENSE file in the root of this project.
10 #include <QMouseEvent>
12 #include <QPushButton>
13 #include <QtConcurrent/QtConcurrent>
15 #include "bigintmandelwidget.h"
16 #include "mandellabel.h"
18 #include "settingswidget.h"
20 BigintMandelWidget::BigintMandelWidget(QWidget
*parent
)
22 fw(new QFutureWatcher
<MandelResultCell
>(this)),
23 settings(128, QSize(502, 334)),
24 menu_bar(new MenuBar(this)),
25 scroll_area(new QScrollArea(this)),
26 mandel_label(new MandelLabel(this)),
27 status_bar(new QStatusBar(this)),
28 settings_widget(new SettingsWidget(this))
30 scroll_area
->setWidget(mandel_label
);
35 &BigintMandelWidget::settings_widget_accepted
39 &QFutureWatcher
<MandelResultCell
>::resultReadyAt
,
41 &BigintMandelWidget::finished_cell
45 &QFutureWatcher
<MandelResultCell
>::finished
,
47 &BigintMandelWidget::finished
49 setLayout(new QVBoxLayout());
50 layout()->addWidget(menu_bar
);
51 layout()->addWidget(scroll_area
);
52 status_bar
->setSizeGripEnabled(false);
53 layout()->addWidget(status_bar
);
54 mandel_label
->resize(settings
.get_params().get_size());
58 BigintMandelWidget::~BigintMandelWidget() {
62 void BigintMandelWidget::finished_cell(int num
) {
63 QSize size
= settings
.get_params().get_size();
64 int y
= num
/ size
.width() + 1;
65 mandel_label
->set_draw_progress(y
< size
.height() - 1 ? y
+ 1 : -1);
66 settings
.finished_cell(num
, fw
->resultAt(num
));
70 void BigintMandelWidget::finished() {
71 mandel_label
->set_draw_progress(-1);
75 void BigintMandelWidget::update_status_bar() {
77 static int prev_num_threads
= -1;
82 num_threads
= QThreadPool::globalInstance()->activeThreadCount();
83 if (num_threads
== prev_num_threads
)
85 ss
.setString(new QString());
86 if (num_threads
!= -1)
87 ss
<< "Calculating with " << num_threads
<< " threads ...";
88 else if (settings
.get_zoom_factor() == -1)
89 ss
<< "Choose a zoom factor from the \"Zoom\" menu.";
91 ss
<< "Click the rendering to zoom.";
92 status_bar
->showMessage(*ss
.string());
93 prev_num_threads
= num_threads
;
96 void BigintMandelWidget::start() {
100 settings
.get_cells(),
101 [](const MandelCell
&cell
){ return cell
.iterate(); }
104 settings
.set_zoom_factor(-1);
108 void BigintMandelWidget::stop() {
110 fw
->waitForFinished();
113 void BigintMandelWidget::mousePressEvent(QMouseEvent
*event
) {
114 QSize
size(settings
.get_params().get_size());
115 QPoint
pos(event
->pos());
117 int zoom_factor
= settings
.get_zoom_factor();
118 for (w
= mandel_label
; w
!= this; w
= w
->parentWidget())
119 pos
= w
->mapFromParent(pos
);
120 if (event
->button() != Qt::MouseButton::LeftButton
123 || pos
.x() >= size
.width()
125 || pos
.y() >= size
.height()
126 || zoom_factor
== -1)
128 settings
.zoom(get_ideal_size(), zoom_factor
, pos
);
132 static inline QString
get_save_file_name(
133 QWidget
*parent
= nullptr,
134 const QString
&caption
= QString(),
135 const QString
&dir
= QString(),
136 const QString
&filter_title
= QString(),
137 const QStringList
&ext_list
= QStringList
{},
138 const QString default_ext
= QString()
140 QTextStream
ss(new QString());
141 QStringList::const_iterator ext_list_iter
;
143 ss
<< filter_title
<< " (" << ext_list
.join(" ") << ")";
144 file_name
= QFileDialog::getSaveFileName(
145 parent
, caption
, dir
, *ss
.string()
147 if (file_name
.isEmpty())
149 ss
.string()->clear();
152 ext_list_iter
= ext_list
.constBegin();
153 ext_list_iter
!= ext_list
.constEnd();
156 if (file_name
.endsWith(*ext_list_iter
))
158 if (ext_list_iter
== ext_list
.constEnd())
163 void BigintMandelWidget::export_img() {
164 QString file_name
= get_save_file_name(
169 QStringList
{".png", ".xpm", ".jpg"},
172 if (!file_name
.isEmpty())
173 settings
.save_img(file_name
);
176 void BigintMandelWidget::exec_settings_widget() {
177 settings_widget
->update_params(settings
.get_params());
178 settings_widget
->exec();
181 void BigintMandelWidget::reset() {
182 settings
.reset(128, get_ideal_size());
186 void BigintMandelWidget::settings_widget_accepted() {
187 if (settings_widget
->is_clear_image_checked()) {
188 settings
.set_params(settings_widget
->get_params());
191 quint64 max_iter
= settings_widget
->get_max_iter();
192 if (max_iter
<= settings
.get_max_iter())
194 settings
.set_max_iter(max_iter
);
199 void BigintMandelWidget::load_data() {
203 QString file_name
= QFileDialog::getOpenFileName(
204 this, "Load Data", "", "BigintMandel Data (*.json *.json.qcompress)"
206 if (file_name
.isEmpty())
208 file
.setFileName(file_name
);
209 if (!file
.open(QIODevice::ReadOnly
)) {
210 qWarning("Couldn't open save file.");
213 qba
= file
.readAll();
215 if (file_name
.endsWith(".qcompress"))
216 qba
= qUncompress(qba
);
217 settings
.from_json(QJsonDocument::fromJson(qba
).object());
221 void BigintMandelWidget::save_data() {
224 QString file_name
= get_save_file_name(
229 QStringList
{".json", ".json.qcompress"},
232 if (file_name
.isEmpty())
234 qba
= QJsonDocument(settings
.to_json()).toJson();
235 if (file_name
.endsWith(".qcompress"))
236 qba
= qCompress(qba
, 9);
237 file
.setFileName(file_name
);
238 if (!file
.open(QIODevice::WriteOnly
)) {
239 qWarning("Couldn't open save file.");
246 void BigintMandelWidget::update() {
251 void BigintMandelWidget::resize_to_window() {
252 QSize size
= get_ideal_size();
253 if (size
== settings
.get_params().get_size())
255 settings
.set_size(size
);