#include "mandellabel.h"
#include "menubar.h"
-static inline void start_calculation(
- QFutureWatcher<MandelResultCell> *fw, QVector<MandelCell> cells
-) {
- fw->setFuture(
- QtConcurrent::mapped(
- cells,
- [](const MandelCell &cell){ return cell.iterate(); }
- )
- );
-}
-
BigintMandelWidget::BigintMandelWidget(QWidget *parent)
: QWidget(parent),
fw(new QFutureWatcher<MandelResultCell>(this)),
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() {
}
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();
}
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
|| 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(
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();
+ 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() {
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();
#include <QPainter>
#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();
+}
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)
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
);
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<QAction*>(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();
}
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);
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<QAction*>(sender())->data().toInt());
+ }
};
#endif // MENUBAR_H