1
0

Almond.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. #include "Almond.h"
  2. #include <QIntValidator>
  3. #include <QIcon>
  4. #include <QFileDialog>
  5. #include <QMessageBox>
  6. #include <QGradient>
  7. #include "gradientchoosedialog.h"
  8. #include <cmath>
  9. Almond::Almond(QWidget* parent) :
  10. QMainWindow{ parent },
  11. mandelContext{ mnd::initializeContext() }
  12. {
  13. ui.setupUi(this);
  14. mw = std::make_unique<MandelWidget>(mandelContext,
  15. &mandelContext.getDefaultGenerator(),
  16. ui.centralWidget);
  17. customGeneratorDialog = std::make_unique<CustomGenerator>(mandelContext);
  18. customGenerator = nullptr;
  19. customViewSave = mnd::MandelViewport::centerView();
  20. on_maxIterations_editingFinished();
  21. mw->setSmoothColoring(ui.smooth->isChecked());
  22. currentView = MANDELBROT;
  23. mandelGenerator = &mandelContext.getDefaultGenerator();
  24. mandelViewSave = mw->getViewport();
  25. QObject::connect(mw.get(), &MandelWidget::pointSelected, this, &Almond::pointSelected);
  26. ui.mainContainer->addWidget(mw.get());
  27. ui.maxIterations->setValidator(new QIntValidator(1, 1000000000, this));
  28. ui.backgroundProgress->setVisible(false);
  29. this->setWindowIcon(QIcon(":/icons/icon"));
  30. //ui.verticalLayout_left->addWidget(new MyGLWidget(ui.centralWidget));
  31. //mw->show();
  32. }
  33. Almond::~Almond(void)
  34. {
  35. }
  36. void Almond::submitBackgroundTask(BackgroundTask* task)
  37. {
  38. QObject::connect(task, &BackgroundTask::finished, this, &Almond::backgroundTaskFinished);
  39. QObject::connect(task, &BackgroundTask::progress, this, &Almond::backgroundTaskProgress);
  40. backgroundTasks.start(task);
  41. //if (taken) {
  42. ui.backgroundProgress->setRange(0, 0);
  43. ui.backgroundProgress->setVisible(true);
  44. ui.backgroundProgress->setFormat("");
  45. //}
  46. }
  47. void Almond::backgroundTaskFinished(bool succ)
  48. {
  49. ui.backgroundProgress->setVisible(false);
  50. ui.backgroundProgress->setFormat("");
  51. }
  52. void Almond::backgroundTaskProgress(float percentage)
  53. {
  54. QObject* task = QObject::sender();
  55. if (auto* bt = qobject_cast<BackgroundTask*>(task)) {
  56. ui.backgroundProgress->setFormat(QString::fromStdString(bt->getShortDescription() + ": %p%"));
  57. }
  58. if (percentage > 0) {
  59. ui.backgroundProgress->setRange(0, 100);
  60. ui.backgroundProgress->setValue(percentage);
  61. }
  62. else {
  63. ui.backgroundProgress->reset();
  64. ui.backgroundProgress->setRange(0, 0);
  65. ui.backgroundProgress->setValue(-1);
  66. }
  67. }
  68. void Almond::on_zoom_out_clicked()
  69. {
  70. mw->zoom(2);
  71. }
  72. void Almond::on_zoom_in_clicked()
  73. {
  74. mw->zoom(0.5);
  75. }
  76. void Almond::on_maxIterations_editingFinished()
  77. {
  78. QString text = ui.maxIterations->text();
  79. int maxIter = text.toInt();
  80. mw->setMaxIterations(maxIter);
  81. }
  82. void Almond::on_chooseGradient_clicked()
  83. {
  84. gcd.exec();
  85. auto gradient = gcd.getGradient();
  86. if (gradient)
  87. mw->setGradient(std::move(*gradient));
  88. }
  89. void Almond::on_exportVideo_clicked()
  90. {
  91. ExportVideoInfo evi;
  92. evi.start = mnd::MandelViewport::standardView();
  93. evi.end = mw->getViewport();
  94. evi.gradient = mw->getGradient();
  95. ExportVideoDialog dialog(this, evi);
  96. //dialog.show();
  97. auto response = dialog.exec();
  98. printf("dialog executed\n"); fflush(stdout);
  99. if (response == 1) {
  100. mnd::MandelInfo mi;
  101. evi = dialog.getExportVideoInfo();
  102. MandelVideoGenerator mvg(evi);
  103. mnd::MandelGenerator& g = *mw->getGenerator();
  104. submitBackgroundTask(new VideoExportTask(std::move(mvg), g));
  105. //if (exportVideo(evi)) {
  106. //Video
  107. /*mi.maxIter = dialog.getMaxIterations();
  108. mi.view = mw->getViewport();
  109. mi.bWidth = dialog.getWidth();
  110. mi.bHeight = dialog.getHeight();
  111. mi.view.adjustAspectRatio(mi.bWidth, mi.bHeight);
  112. mnd::Generator& g = mandelContext.getDefaultGenerator();
  113. auto fmap = Bitmap<float>(mi.bWidth, mi.bHeight);
  114. g.generate(mi, fmap.pixels.get());
  115. auto bitmap = fmap.map<RGBColor>([](float i) { return i < 0 ? RGBColor{ 0,0,0 } : RGBColor{ uint8_t(cos(i * 0.015f) * 127 + 127), uint8_t(sin(i * 0.01f) * 127 + 127), uint8_t(i) }; });//uint8_t(::sin(i * 0.01f) * 100 + 100), uint8_t(i) }; });
  116. QImage img((unsigned char*)bitmap.pixels.get(), bitmap.width, bitmap.height, bitmap.width * 3, QImage::Format_RGB888);
  117. img.save(dialog.getPath());*/
  118. }
  119. }
  120. void Almond::on_smooth_stateChanged(int checked)
  121. {
  122. this->mw->setSmoothColoring(checked != Qt::Unchecked);
  123. }
  124. void Almond::on_exportImage_clicked()
  125. {
  126. ExportImageDialog dialog(this);
  127. dialog.setMaxIterations(mw->getMaxIterations());
  128. //dialog.show();
  129. auto response = dialog.exec();
  130. if (response == 1) {
  131. mnd::MandelInfo mi;
  132. mi.maxIter = dialog.getMaxIterations();
  133. mi.view = mw->getViewport();
  134. mi.bWidth = dialog.getWidth();
  135. mi.bHeight = dialog.getHeight();
  136. mi.view.adjustAspectRatio(mi.bWidth, mi.bHeight);
  137. mi.smooth = mw->getSmoothColoring();
  138. if (currentView == JULIA) {
  139. mi.julia = mw->getMandelInfo().julia;
  140. mi.juliaX = mw->getJuliaX();
  141. mi.juliaY = mw->getJuliaY();
  142. }
  143. mnd::MandelGenerator* currentGenerator = mw->getGenerator();
  144. mnd::MandelGenerator& g = currentGenerator ? *currentGenerator : mandelContext.getDefaultGenerator();
  145. alm::ImageExportInfo iei;
  146. iei.drawInfo = mi;
  147. iei.generator = &g;
  148. iei.gradient = mw->getGradient();
  149. iei.path = dialog.getPath().toStdString();
  150. submitBackgroundTask(new ImageExportTask(iei));
  151. /*auto exprt = [iei, path = dialog.getPath().toStdString()]() {
  152. alm::exportPng(path, iei);
  153. };
  154. submitBackgroundTask();*/
  155. /*auto fmap = Bitmap<float>(mi.bWidth, mi.bHeight);
  156. g.generate(mi, fmap.pixels.get());
  157. auto bitmap = fmap.map<RGBColor>([&mi, this] (float i) {
  158. return i >= mi.maxIter ? RGBColor{ 0,0,0 } : mw->getGradient().get(i);
  159. });
  160. QImage img(reinterpret_cast<unsigned char*>(bitmap.pixels.get()), bitmap.width, bitmap.height, bitmap.width * 3, QImage::Format_RGB888);
  161. img.save(dialog.getPath());*/
  162. }
  163. }
  164. void Almond::on_resetZoom_clicked()
  165. {
  166. if (currentView == MANDELBROT) {
  167. mw->setViewport(mnd::MandelViewport::standardView());
  168. }
  169. else {
  170. mw->setViewport(mnd::MandelViewport::centerView());
  171. }
  172. }
  173. void Almond::on_displayInfo_stateChanged(int checked)
  174. {
  175. this->mw->setDisplayInfo(checked != Qt::Unchecked);
  176. }
  177. void Almond::on_chooseGenerator_clicked()
  178. {
  179. std::unique_ptr<ChooseGenerators> generatorsDialog;
  180. if (currentView == MANDELBROT || currentView == JULIA)
  181. generatorsDialog = std::make_unique<ChooseGenerators>(mandelContext, *mandelGenerator, *this);
  182. else if (currentView == CUSTOM)
  183. generatorsDialog = std::make_unique<ChooseGenerators>(mandelContext, this->currentCustom->gc, *customGenerator, *this);
  184. else
  185. return;
  186. auto response = generatorsDialog->exec();
  187. auto gen = generatorsDialog->extractChosenGenerator();
  188. if (gen) {
  189. if (currentView == MANDELBROT || currentView == JULIA) {
  190. mandelGenerator = gen.get();
  191. }
  192. else if (currentView == CUSTOM) {
  193. customGenerator = gen.get();
  194. }
  195. currentGenerator = gen.get();
  196. this->mw->setGenerator(currentGenerator);
  197. adjustedGenerators.push_back(std::move(gen));
  198. }
  199. else {
  200. //mandelGenerator = &mandelContext.getDefaultGenerator();
  201. }
  202. //this->currentView = MANDELBROT;
  203. //this->mw->getMandelInfo().julia = false;
  204. //printf("dialog executed\n"); fflush(stdout);
  205. }
  206. void Almond::pointSelected(mnd::Real x, mnd::Real y)
  207. {
  208. if (currentView != JULIA) {
  209. saveView();
  210. this->mw->setViewport(mnd::MandelViewport::centerView());
  211. this->mw->setJuliaPos(x, y);
  212. this->mw->getMandelInfo().julia = true;
  213. this->mw->clearAll();
  214. }
  215. currentView = JULIA;
  216. }
  217. void Almond::on_groupBox_toggled(bool arg1)
  218. {
  219. printf("arg1: %i\n", int(arg1)); fflush(stdout);
  220. }
  221. void Almond::on_wMandel_clicked()
  222. {
  223. }
  224. void Almond::saveView()
  225. {
  226. if (currentView == MANDELBROT)
  227. mandelViewSave = mw->getViewport();
  228. else if (currentView == CUSTOM)
  229. customViewSave = mw->getViewport();
  230. }
  231. void Almond::setViewType(ViewType v)
  232. {
  233. saveView();
  234. if (v == MANDELBROT) {
  235. currentGenerator = mandelGenerator;
  236. emit this->mw->stopSelectingPoint();
  237. this->mw->setViewport(mandelViewSave);
  238. this->mw->setGenerator(currentGenerator);
  239. this->mw->getMandelInfo().julia = false;
  240. this->mw->clearAll();
  241. currentView = MANDELBROT;
  242. }
  243. else if (v == CUSTOM) {
  244. if (customGenerator != nullptr) {
  245. currentGenerator = customGenerator;
  246. this->mw->setGenerator(currentGenerator);
  247. emit this->mw->stopSelectingPoint();
  248. this->mw->setViewport(customViewSave);
  249. this->mw->getMandelInfo().julia = false;
  250. this->mw->clearAll();
  251. currentView = CUSTOM;
  252. }
  253. else {
  254. setViewType(MANDELBROT);
  255. }
  256. }
  257. else if (v == JULIA) {
  258. if (currentView == MANDELBROT) {
  259. emit this->mw->selectPoint();
  260. }
  261. else {
  262. currentView = MANDELBROT;
  263. currentGenerator = mandelGenerator;
  264. this->mw->setGenerator(currentGenerator);
  265. this->mw->setViewport(mandelViewSave);
  266. this->mw->getMandelInfo().julia = false;
  267. this->mw->clearAll();
  268. emit this->mw->selectPoint();
  269. }
  270. }
  271. }
  272. void Almond::on_wMandel_toggled(bool checked)
  273. {
  274. if (checked)
  275. setViewType(MANDELBROT);
  276. }
  277. void Almond::on_radioButton_toggled(bool checked)
  278. {
  279. saveView();
  280. if (checked) {
  281. setViewType(JULIA);
  282. }
  283. }
  284. void Almond::on_radioButton_2_toggled(bool checked)
  285. {
  286. saveView();
  287. if (checked) {
  288. if (customGenerator == nullptr) {
  289. customGeneratorDialog->exec();
  290. if (auto* frac = customGeneratorDialog->getLastCompiled()) {
  291. customGenerator = frac->gc.adaptiveGenerator.get();
  292. customGenerators.push_back(std::make_unique<FractalDef>(std::move(*frac)));
  293. currentCustom = customGenerators[customGenerators.size() - 1].get();
  294. }
  295. }
  296. setViewType(CUSTOM);
  297. }
  298. }
  299. void Almond::on_createCustom_clicked()
  300. {
  301. auto response = customGeneratorDialog->exec();
  302. if (response != 1)
  303. return;
  304. if (auto* frac = customGeneratorDialog->getLastCompiled()) {
  305. customGenerator = frac->gc.adaptiveGenerator.get();
  306. customGenerators.push_back(std::make_unique<FractalDef>(std::move(*frac)));
  307. currentCustom = customGenerators[customGenerators.size() - 1].get();
  308. this->ui.radioButton_2->setChecked(true);
  309. setViewType(CUSTOM);
  310. }
  311. }