فهرست منبع

starting serialization

Nicolas Winkler 4 سال پیش
والد
کامیت
e83eb83ea1

+ 3 - 3
include/EscapeTimeVisualWidget.h

@@ -41,7 +41,7 @@ protected:
     GLuint gradientTextureId;
     float gradientTextureMax;
     float maxIterations;
-    Gradient gradient;
+    alm::Gradient gradient;
     bool gradientNeedsUpdate;
 
     float resolutionX;
@@ -53,8 +53,8 @@ protected:
 public:
     EscapeTimeVisualWidget(QWidget* parent = nullptr);
 
-    void setGradient(Gradient newGradient);
-    const Gradient& getGradient(void);
+    void setGradient(alm::Gradient newGradient);
+    const alm::Gradient& getGradient(void);
 
     virtual void initializeGL(void) override;
     virtual void resizeGL(int w, int h) override;

+ 4 - 17
include/GradientMenu.h

@@ -13,34 +13,21 @@ class GradientMenu;
 }
 
 
-class MinHeightWrapperWidget :
-    public QWidget
-{
-    Q_OBJECT
-    int minHeight;
-    QWidget* widget;
-public:
-    MinHeightWrapperWidget(QWidget* contains, QWidget* parent);
-    QSize minimumSizeHint(void) const override;
-    QSize sizeHint(void) const override;
-};
-
-
 class GradientMenu : public QWidget
 {
     Q_OBJECT
 
     Ui::GradientMenu *ui;
-    Gradient before;
+    alm::Gradient before;
 
     static const QString presetNames[];
 public:
     explicit GradientMenu(QWidget *parent = nullptr);
     ~GradientMenu(void);
 
-    const Gradient& getGradient(void);
-    const Gradient& getGradientBefore(void) const;
-    void setGradient(Gradient grad);
+    const alm::Gradient& getGradient(void);
+    const alm::Gradient& getGradientBefore(void) const;
+    void setGradient(alm::Gradient grad);
 
     void loadGradient(QFile& file);
 

+ 3 - 3
include/GradientWidget.h

@@ -15,7 +15,7 @@ class GradientWidget :
     Q_OBJECT
 
     std::vector<std::pair<RGBColor, float>> points;
-    Gradient gradient;
+    alm::Gradient gradient;
     float maxValue;
 
     QColorDialog* colorPicker;
@@ -41,8 +41,8 @@ public:
 
     explicit GradientWidget(QWidget *parent = nullptr);
 
-    const Gradient& getGradient(void) const;
-    void setGradient(Gradient gradient);
+    const alm::Gradient& getGradient(void) const;
+    void setGradient(alm::Gradient gradient);
 
 private:
     void updateGradient(void);

+ 0 - 26
libalmond/include/ExportRecipe.h

@@ -1,26 +0,0 @@
-#pragma once
-#ifndef LIBALMOND_EXPORT_RECIPE_H
-#define LIBALMOND_EXPORT_RECIPE_H
-
-#include <MandelUtil.h>
-#include "Gradient.h"
-
-#include <string>
-
-namespace alm
-{
-    struct ImageExportRecipe;
-}
-
-
-struct alm::ImageExportRecipe
-{
-    mnd::MandelInfo view;
-    Gradient gradient;
-
-    std::string toXml(void) const;
-    static ImageExportRecipe fromXml(const std::string& xml);
-};
-
-#endif // LIBALMOND_EXPORT_RECIPE_H
-

+ 12 - 8
libalmond/include/Gradient.h

@@ -1,5 +1,5 @@
-#ifndef GRADIENT_H
-#define GRADIENT_H
+#ifndef LIBALMOND_GRADIENT_H
+#define LIBALMOND_GRADIENT_H
 
 #include <vector>
 #include <map>
@@ -8,9 +8,16 @@
 #include "CubicSpline.h"
 #include <tuple>
 #include <cinttypes>
+#include <memory>
 
 
-class Gradient
+namespace alm
+{
+    class Gradient;
+}
+
+
+class alm::Gradient
 {
     std::vector<std::pair<RGBColor, float>> points;
     std::map<float, RGBColor, std::greater<float>> pointMap;
@@ -27,12 +34,9 @@ public:
     Gradient(std::vector<std::pair<RGBColor, float>> colors, float maxValue, bool repeat = false, int precalcSteps = -1);
 
     const std::vector<std::pair<RGBColor, float>>& getPoints(void) const;
-    inline bool isRepeat(void) const { return repeat; }
-
     static Gradient defaultGradient(void);
+    bool isRepeat(void) const;
 
-    static Gradient fromXml(const std::string& xml);
-    std::string toXml(void) const;
 
     ///
     /// \brief get the maximum value this gradient accepts
@@ -57,4 +61,4 @@ private:
     std::tuple<RGBColor, RGBColor, float> getNeighbors(float x) const;
 };
 
-#endif // GRADIENT_H
+#endif // LIBALMOND_GRADIENT_H

+ 1 - 1
libalmond/include/MandelVideoGenerator.h

@@ -19,7 +19,7 @@ struct ExportVideoInfo
     mnd::MandelInfo mi;
 
     /// the gradient to use
-    Gradient gradient;
+    alm::Gradient gradient;
 
     int fps;
     double zoomSpeed;

+ 42 - 0
libalmond/include/Serialize.h

@@ -0,0 +1,42 @@
+#pragma once
+#ifndef LIBALMOND_SERIALIZE_H
+#define LIBALMOND_SERIALIZE_H
+
+#include <MandelUtil.h>
+#include "Gradient.h"
+
+#include <string>
+
+namespace tinyxml2
+{
+    struct XMLElement;
+}
+
+namespace alm
+{
+    struct ImageView;
+
+    Gradient deserializeGradient(tinyxml2::XMLElement* xml);
+    std::unique_ptr<tinyxml2::XMLElement> serializeGradient(const Gradient& g);
+
+    Gradient loadGradient(const std::string& xml);
+    std::string saveGradient(const Gradient& g);
+
+    ImageView deserializeImageView(tinyxml2::XMLElement* xml);
+    std::unique_ptr<tinyxml2::XMLElement> serializeImageView(const ImageView& iv);
+
+    ImageView loadImageView(const std::string& xml);
+    std::string saveImageView(const ImageView& iv);
+}
+
+
+struct alm::ImageView
+{
+    mnd::MandelInfo view;
+    Gradient gradient;
+
+    std::string toXml(void) const;
+    static ImageView fromXml(const std::string& xml);
+};
+
+#endif // LIBALMOND_SERIALIZE_H

+ 0 - 21
libalmond/src/ExportRecipe.cpp

@@ -1,21 +0,0 @@
-#include "ExportRecipe.h"
-#include "tinyxml2.h"
-
-#include "XmlException.h"
-
-using alm::ImageExportRecipe;
-using alm::XmlException;
-
-
-std::string ImageExportRecipe::toXml(void) const
-{
-    return "";
-}
-
-
-ImageExportRecipe ImageExportRecipe::fromXml(const std::string& xml)
-{
-    tinyxml2::XMLDocument xmlDoc;
-    xmlDoc.Parse(xml.c_str());
-    return ImageExportRecipe{};
-}

+ 4 - 66
libalmond/src/Gradient.cpp

@@ -2,14 +2,14 @@
 
 #include "CubicSpline.h"
 
-#include "../tinyxml2/tinyxml2.h"
 #include "XmlException.h"
 
 #include <cmath>
-#include <sstream>
 #include <algorithm>
 #include <functional>
 
+using alm::Gradient;
+
 
 Gradient::Gradient(void) :
     max{ 1.0 }
@@ -165,71 +165,9 @@ Gradient Gradient::defaultGradient(void)
 }
 
 
-Gradient Gradient::fromXml(const std::string& xml)
+bool Gradient::isRepeat(void) const
 {
-    using tinyxml2::XMLDocument;
-    using tinyxml2::XMLError;
-    using tinyxml2::XMLNode;
-    using tinyxml2::XMLElement;
-    using tinyxml2::XML_SUCCESS;
-
-    XMLDocument xmlDoc;
-    XMLError err = xmlDoc.Parse(xml.c_str());
-    if (err != XML_SUCCESS)
-        throw alm::XmlException{ "error parsing gradient xml" };
-    XMLNode* rootNode = xmlDoc.FirstChild();
-    if (rootNode == nullptr)
-        throw alm::XmlException{ "invalid root node" };
-
-    bool repeat = false;
-    bool hasMax = false;
-    float maxVal = 0.0f;
-    if (auto* re = dynamic_cast<XMLElement*>(rootNode)) {
-        repeat = re->BoolAttribute("repeat", false);
-        XMLError e = re->QueryFloatAttribute("max", &maxVal);
-        if (e == XML_SUCCESS)
-            hasMax = true;
-    }
-
-    std::vector<std::pair<RGBColor, float>> points;
-
-    XMLElement* colorNode = rootNode->FirstChildElement("color");
-    while(colorNode != nullptr) {
-        int r = colorNode->IntAttribute("r");
-        int g = colorNode->IntAttribute("g");
-        int b = colorNode->IntAttribute("b");
-        float p = colorNode->FloatAttribute("p");
-        
-        uint8_t cr = uint8_t(std::clamp(r, 0, 255));
-        uint8_t cg = uint8_t(std::clamp(g, 0, 255));
-        uint8_t cb = uint8_t(std::clamp(b, 0, 255));
-        points.push_back(std::make_pair(RGBColor{ cr, cg, cb }, p));
-
-        colorNode = colorNode->NextSiblingElement("color");
-    }
-    if (hasMax)
-        return Gradient{ std::move(points), maxVal, repeat };
-    else
-        return Gradient{ std::move(points), repeat };
-}
-
-
-std::string Gradient::toXml(void) const
-{
-    std::stringstream buf;
-
-    std::string version = "1.0.0";
-    buf << "<gradient max=\"" << max << "\" repeat=\"" << (repeat ? "true" : "false") 
-        << "\" version=\"" << version << "\" >" << std::endl;
-    for (const auto&[color, val] : points) {
-        buf << "    <color " <<
-               "r=\"" << int(color.r) <<
-               "\" g=\"" << int(color.g) <<
-               "\" b=\"" << int(color.b) <<
-               "\" p=\"" << val << "\" />" << std::endl;
-    }
-    buf << "</gradient>" << std::endl;
-    return buf.str();
+    return repeat;
 }
 
 

+ 2 - 0
libalmond/src/MandelVideoGenerator.cpp

@@ -5,6 +5,8 @@
 #include <cmath>
 #include <omp.h>
 
+using alm::Gradient;
+
 MandelVideoGenerator::MandelVideoGenerator(const ExportVideoInfo& evi) :
     evi{ evi }
 {

+ 84 - 0
libalmond/src/Serialize.cpp

@@ -0,0 +1,84 @@
+#include "Serialize.h"
+#include "tinyxml2.h"
+
+#include "XmlException.h"
+
+#include <sstream>
+
+using alm::ImageView;
+using alm::XmlException;
+
+using tinyxml2::XMLElement;
+using tinyxml2::XMLDocument;
+using tinyxml2::XMLError;
+using tinyxml2::XMLNode;
+using tinyxml2::XML_SUCCESS;
+
+
+alm::Gradient alm::deserializeGradient(XMLElement* elem)
+{
+    if (elem == nullptr)
+        throw alm::XmlException{ "invalid root node" };
+
+    bool repeat = false;
+    bool hasMax = false;
+    float maxVal = 0.0f;
+    repeat = elem->BoolAttribute("repeat", false);
+    XMLError e = elem->QueryFloatAttribute("max", &maxVal);
+    if (e == XML_SUCCESS)
+        hasMax = true;
+
+    std::vector<std::pair<RGBColor, float>> points;
+
+    XMLElement* colorNode = elem->FirstChildElement("color");
+    while(colorNode != nullptr) {
+        int r = colorNode->IntAttribute("r");
+        int g = colorNode->IntAttribute("g");
+        int b = colorNode->IntAttribute("b");
+        float p = colorNode->FloatAttribute("p");
+        
+        uint8_t cr = uint8_t(std::clamp(r, 0, 255));
+        uint8_t cg = uint8_t(std::clamp(g, 0, 255));
+        uint8_t cb = uint8_t(std::clamp(b, 0, 255));
+        points.push_back(std::make_pair(RGBColor{ cr, cg, cb }, p));
+
+        colorNode = colorNode->NextSiblingElement("color");
+    }
+    if (hasMax)
+        return Gradient{ std::move(points), maxVal, repeat };
+    else
+        return Gradient{ std::move(points), repeat };
+}
+
+
+alm::Gradient alm::loadGradient(const std::string& xml)
+{
+    XMLDocument xmlDoc;
+    XMLError err = xmlDoc.Parse(xml.c_str());
+    if (err != XML_SUCCESS)
+        throw alm::XmlException{ "error parsing gradient xml" };
+    return deserializeGradient(xmlDoc.RootElement());
+}
+
+
+std::string alm::saveGradient(const Gradient& g)
+{
+    std::stringstream buf;
+
+    std::string version = "1.0.0";
+    buf << "<gradient max=\"" << g.getMax() << "\" repeat=\"" << (g.isRepeat() ? "true" : "false") 
+        << "\" version=\"" << version << "\" >" << std::endl;
+    for (const auto&[color, val] : g.getPoints()) {
+        buf << "    <color " <<
+               "r=\"" << int(color.r) <<
+               "\" g=\"" << int(color.g) <<
+               "\" b=\"" << int(color.b) <<
+               "\" p=\"" << val << "\" />" << std::endl;
+    }
+    buf << "</gradient>" << std::endl;
+    return buf.str();
+}
+
+
+ImageView deserializeImageView(tinyxml2::XMLElement* xml);
+std::unique_ptr<tinyxml2::XMLElement> serializeImageView(const ImageView& iv);

+ 34 - 32
resources/icons/cancel.svg

@@ -7,37 +7,39 @@
    xmlns="http://www.w3.org/2000/svg"
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
-   sodipodi:docname="cancel.svg"
-   width="12.690882mm"
-   height="12.683558mm"
-   viewBox="0 0 12.690882 12.683558"
+   id="svg8"
    version="1.1"
-   id="svg8">
+   viewBox="0 0 16.933333 16.933333"
+   height="64"
+   width="64"
+   sodipodi:docname="cancel.svg"
+   inkscape:version="1.0 (4035a4fb49, 2020-05-01)">
   <sodipodi:namedview
-     fit-margin-bottom="0"
-     fit-margin-right="0"
-     fit-margin-left="0"
-     fit-margin-top="0"
-     inkscape:current-layer="svg8"
-     inkscape:window-maximized="0"
-     inkscape:window-y="34"
-     inkscape:window-x="0"
-     inkscape:cy="59.061224"
-     inkscape:cx="20.161843"
-     inkscape:zoom="8.5724337"
-     showgrid="false"
-     id="namedview2497"
-     inkscape:window-height="1360"
-     inkscape:window-width="2552"
-     inkscape:pageshadow="2"
-     inkscape:pageopacity="0"
-     guidetolerance="10"
-     gridtolerance="10"
-     objecttolerance="10"
-     borderopacity="1"
+     units="px"
+     inkscape:document-rotation="0"
+     pagecolor="#ffffff"
      bordercolor="#666666"
-     pagecolor="#ffffff" />
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1496"
+     inkscape:window-height="1006"
+     id="namedview2497"
+     showgrid="false"
+     inkscape:zoom="8.5724337"
+     inkscape:cx="20.161843"
+     inkscape:cy="31.064507"
+     inkscape:window-x="23"
+     inkscape:window-y="15"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg8"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
   <defs
      id="defs2" />
   <metadata
@@ -53,11 +55,11 @@
     </rdf:RDF>
   </metadata>
   <g
-     transform="matrix(0.06284129,0,0,0.06286613,-0.15410871,-2.9496449)"
-     id="layer1">
+     id="layer1"
+     transform="matrix(0.06284129,0,0,0.06286613,1.9671167,-0.82475766)">
     <path
-       style="fill:none;stroke:#ec2900;stroke-width:45.1731;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
+       id="path832"
        d="m 27.854233,223.32152 c -5.883202,-6.26321 -5.275239,-7.12501 29.66983,-42.05665 17.74761,-17.74081 32.2684,-32.80134 32.2684,-33.4679 0,-0.66653 -14.52079,-15.72707 -32.2684,-33.46788 C 29.249776,86.065646 25.255669,81.617004 25.255669,78.388467 c 0,-4.920247 4.276916,-8.882457 9.587959,-8.882457 3.713063,0 6.813285,2.751136 36.683505,32.55286 l 32.627687,32.55285 32.56476,-32.55285 c 29.23171,-29.221038 32.96149,-32.55286 36.44091,-32.55286 5.28047,0 8.65664,3.595229 8.65664,9.218288 0,4.211257 -1.64139,6.081976 -32.24511,36.749912 l -32.24515,32.31277 32.24515,32.32769 c 30.01558,30.09242 32.24511,32.61973 32.24511,36.55155 0,5.21525 -4.03264,9.42173 -9.03245,9.42173 -2.98751,0 -8.26987,-4.76779 -36.05527,-32.54304 l -32.55492,-32.54302 -32.678497,32.54302 c -30.293713,30.16814 -32.983692,32.54304 -36.860829,32.54304 -2.826495,0 -5.024765,-0.89685 -6.780931,-2.76643 z"
-       id="path832" />
+       style="fill:none;stroke:#ec2900;stroke-width:45.1731;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
   </g>
 </svg>

+ 1 - 1
src/Almond.cpp

@@ -19,7 +19,7 @@ Almond::Almond(QWidget* parent) :
     ui.setupUi(this);
     fractalWidget = new FractalWidget(this);
     fractalWidget->setGenerator(&mandelContext.getDefaultGenerator());
-    fractalWidget->setGradient(Gradient::defaultGradient());
+    fractalWidget->setGradient(alm::Gradient::defaultGradient());
     fractalWidget->setSmoothColoring(ui.smooth->isChecked());
     QSizePolicy fsp{ QSizePolicy::Expanding, QSizePolicy::Expanding };
     fsp.setHorizontalStretch(2);

+ 1 - 0
src/EscapeTimeVisualWidget.cpp

@@ -11,6 +11,7 @@
 
 #include <vector>
 
+using alm::Gradient;
 
 ETVImage::ETVImage(EscapeTimeVisualWidget& owner,
                    const Bitmap<float>& img) :

+ 2 - 2
src/FractalWidget.cpp

@@ -108,8 +108,8 @@ void FractalWidget::mouseReleaseEvent(QMouseEvent* me)
 void FractalWidget::wheelEvent(QWheelEvent* we)
 {
     QOpenGLWidget::wheelEvent(we);
-    float x = float(we->x()) / this->width();
-    float y = float(we->y()) / this->height();
+    float x = float(we->position().x()) / this->width();
+    float y = float(we->position().y()) / this->height();
     float scale = ::powf(0.9975f, we->angleDelta().y());
     //mandelInfo.view.zoom(scale, x, y);
     zoom(scale, x, y);

+ 5 - 34
src/GradientMenu.cpp

@@ -1,6 +1,7 @@
 #include "GradientMenu.h"
 #include "ui_GradientMenu.h"
 
+#include "Serialize.h"
 #include "XmlException.h"
 
 #include <QFile>
@@ -8,6 +9,8 @@
 #include <QFileDialog>
 #include <QTextEdit>
 
+using alm::Gradient;
+
 const QString GradientMenu::presetNames[] = {
     "blue gold",
     "clouds",
@@ -18,38 +21,6 @@ const QString GradientMenu::presetNames[] = {
 };
 
 
-MinHeightWrapperWidget::MinHeightWrapperWidget(QWidget* contains, QWidget* parent) :
-    QWidget{ parent },
-    widget{ contains }
-{
-    this->setContentsMargins(0, 0, 0, 0);
-    resize(300, 1200);
-    QVBoxLayout* l = new QVBoxLayout(this);
-    l->setStretch(0, 1);
-    this->setLayout(l);
-    widget->setParent(this);
-    widget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
-    //this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-    this->layout()->update();
-}
-
-
-QSize MinHeightWrapperWidget::minimumSizeHint(void) const
-{
-    return QSize(300, 1200);
-    QSize minH = widget->minimumSizeHint();
-    return QSize(minH.width(), qMax(minH.height(), minHeight));
-}
-
-
-QSize MinHeightWrapperWidget::sizeHint(void) const
-{
-    return QSize(300, 1200);
-    QSize minH = widget->sizeHint();
-    return QSize(minH.width(), qMax(minH.height(), minHeight));
-}
-
-
 GradientMenu::GradientMenu(QWidget *parent) :
     QWidget(parent),
     ui(new Ui::GradientMenu)
@@ -101,7 +72,7 @@ void GradientMenu::loadGradient(QFile& file)
     if (file.isOpen() || file.open(QFile::ReadOnly)) {
         QString xml = QString::fromUtf8(file.readAll());
         try {
-            ui->gradientWidget->setGradient(Gradient::fromXml(xml.toStdString()));
+            ui->gradientWidget->setGradient(alm::loadGradient(xml.toStdString()));
         } catch (alm::XmlException& xmlex) {
             QMessageBox::critical(this, tr("Error Loading Gradient"), tr("Error loading gradient: ") + xmlex.what());
         } catch (...) {
@@ -131,7 +102,7 @@ void GradientMenu::on_presetCmb_currentIndexChanged(int index)
 
 void GradientMenu::on_saveBtn_clicked()
 {
-    std::string xml = ui->gradientWidget->getGradient().toXml();
+    std::string xml = alm::saveGradient(ui->gradientWidget->getGradient());
     QString filename =
             QFileDialog::getSaveFileName(this, tr("Save Gradient"), "", "Gradient XML Files (*.xml)");
     if (!filename.isNull()) {

+ 2 - 0
src/GradientWidget.cpp

@@ -9,6 +9,8 @@
 #include <algorithm>
 #include <cmath>
 
+using alm::Gradient;
+
 GradientWidget::GradientWidget(QWidget* parent) :
     QWidget{ parent }
 {