#include <QFileDialog>
#include <QLayout>
#include <QMouseEvent>
+#include <QPainter>
#include <QPushButton>
#include <QtConcurrent/QtConcurrent>
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"),
&BigintWidget::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,
img_label(new QLabel(this)),
img_dirty(true),
status_bar(new QStatusBar(this)),
- settings_widget(new SettingsWidget(this))
+ settings_widget(new SettingsWidget(this)),
+ draw_progress(-1)
{
scroll_area->setWidget(img_label);
connect(
}
void BigintWidget::finished_cell(int num) {
+ int y = num / settings.get_params().get_size().width();
+ if (y > draw_progress)
+ draw_progress = y;
settings.finished_cell(num, fw->resultAt(num));
update_img();
}
void BigintWidget::finished() {
+ 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;
+}
+
static inline void calculating_status(
QStatusBar *status_bar, int &prev_num_threads
) {
static int prev_num_threads = -1;
if (!img_dirty)
return;
- img_label->setPixmap(settings.get_pixmap());
+ img_label->setPixmap(enhance_pixmap(settings.get_pixmap(), draw_progress));
img_label->resize(img_label->pixmap().size());
img_dirty = false;
if (fw->isFinished())
|| pos.y() < 0
|| pos.y() >= size.height())
return;
- settings.zoom(get_ideal_size(), pos);
+ settings.zoom(get_ideal_size(), zoom_factor, pos);
start_calculation(fw, settings.get_cells());
update_img();
}
bool img_dirty;
QStatusBar *status_bar;
SettingsWidget *settings_widget;
+ int draw_progress, zoom_factor;
inline const QSize get_ideal_size() const {
return scroll_area->size().shrunkBy(scroll_area->contentsMargins());
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void update_img();
+ inline void set_zoom_factor(int zoom_factor) {
+ this->zoom_factor = zoom_factor;
+ }
public Q_SLOT:
void reset();
: max_iter(max_iter),
size(size),
center_f(center_f),
- one(one) {}
+ one(one),
+ left(center_f.get_x() - size.width() / 2.),
+ top(center_f.get_y() + size.height() / 2.) {}
MandelParams::MandelParams(const MandelParams &other)
: max_iter(other.max_iter),
size(other.size),
center_f(other.center_f),
- one(other.one) {}
+ one(other.one),
+ left(center_f.get_x() - size.width() / 2.),
+ top(center_f.get_y() + size.height() / 2.) {}
MandelParams MandelParams::from_json(const QJsonObject &json) {
return MandelParams(
reset(max_iter, size);
}
-void MandelSettings::zoom(const QSize size, const QPoint pos) {
+void MandelSettings::zoom(const QSize size, int zoom_factor, const QPoint pos) {
MpzPoint p = cells[img->width() * pos.y() + pos.x()].get_rpos0();
params = MandelParams(
params.get_max_iter(),
size,
- MpzPoint(p.get_x() * 2, p.get_y() * 2),
- params.get_one() * 2
+ MpzPoint(p.get_x() * zoom_factor, p.get_y() * zoom_factor),
+ params.get_one() * zoom_factor
);
img = setup_image(img, size);
img->fill(Qt::GlobalColor::black);
rpos0(cell.rpos0) {}
void MandelCell::setup(const QPoint pos) {
- QSize size(params->get_size());
- MpzPoint center_f = params->get_center_f();
this->pos = pos;
- rpos0 = MpzPoint(
- center_f.get_x() + (pos.x() - size.width() / 2.),
- center_f.get_y() - (pos.y() - size.height() / 2.)
- );
+ rpos0 = MpzPoint(params->get_left() + pos.x(), params->get_top() - pos.y());
result = MandelResultCell();
}
MpzPoint();
MpzPoint(mpz_class x, mpz_class y);
MpzPoint(const MpzPoint &other);
- const mpz_class get_x() const { return x; }
- const mpz_class get_y() const { return y; }
+ inline const mpz_class get_x() const { return x; }
+ inline const mpz_class get_y() const { return y; }
};
class MandelResultCell {
public:
MandelResultCell();
MandelResultCell(size_t iter, MpzPoint rpos);
- const size_t get_iter() const { return iter; }
- const MpzPoint get_rpos() const { return rpos; }
+ inline const size_t get_iter() const { return iter; }
+ inline const MpzPoint get_rpos() const { return rpos; }
};
class MandelParams {
size_t max_iter;
QSize size;
MpzPoint center_f;
- mpz_class one;
+ mpz_class left, top, one;
public:
MandelParams();
mpz_class one
);
MandelParams(const MandelParams &other);
- const size_t get_max_iter() const { return max_iter; }
- void set_max_iter(const size_t max_iter) { this->max_iter = max_iter; }
- const QSize get_size() const { return size; }
- const MpzPoint get_center_f() const { return center_f; }
- const mpz_class get_one() const { return one; }
+ inline const size_t get_max_iter() const { return max_iter; }
+ inline void set_max_iter(const size_t max_iter) { this->max_iter = max_iter; }
+ inline const QSize get_size() const { return size; }
+ inline const MpzPoint get_center_f() const { return center_f; }
+ inline const mpz_class get_left() const {
+ return left;
+ }
+ inline const mpz_class get_top() const {
+ return top;
+ }
+ inline const mpz_class get_one() const { return one; }
static MandelParams from_json(const QJsonObject &json);
QJsonObject to_json() const;
public:
MandelSettings(size_t max_iter, QSize size);
- inline const QPixmap get_pixmap() const { return QPixmap::fromImage(*img); }
+ inline QPixmap get_pixmap() const { return QPixmap::fromImage(*img); }
inline const QVector<MandelCell> get_cells() const { return cells; }
inline const MandelParams &get_params() const { return params; }
inline void set_max_iter(size_t max_iter) { params.set_max_iter(max_iter); }
- void zoom(const QSize size, const QPoint pos);
+ void zoom(const QSize size, int zoom_factor, const QPoint pos);
void finished_cell(int num, const MandelResultCell &cell);
void save_img(QString file_name);
void reset(size_t max_iter, QSize size);