Making a snapshot of the current parameter state

We will implement a simple but useful mechanism for saving and loading the parameters' states. The code used in the examples will be based on the previous recipes.

Getting ready

Let's say we have a variable that we are changing frequently. In this case, it will be the color of some element we are drawing and the main class will have the following member variable:

ColorA mColor;

How to do it...

We will use a built-in XML parser and the fileDrop event handler.

  1. We have to include the following additional headers:
    #include "cinder/params/Params.h"
    #include "cinder/ImageIo.h"
    #include "cinder/Utilities.h"
    #include "cinder/Xml.h"
  2. First, we implement two methods for loading and saving parameters:
    void MainApp::loadParameters(std::string filename)
    {
      try {
        XmlTree doc( loadFile( fs::path(filename) ) );
        XmlTree &generalNode = doc.getChild( "general" );
    
            mColor.r = generalNode.getChild("ColorR").getValue<float>();
            mColor.g = generalNode.getChild("ColorG").getValue<float>();
            mColor.b = generalNode.getChild("ColorB").getValue<float>();
            
      } catch(XmlTree::Exception e) {
        console() << "ERROR: loading/reading configuration file." << e.what() << std::endl;
      }
    }
    
    void MainApp::saveParameters(std::string filename)
    {
      std::string beginXmlStr( "<?xml version="1.0" encoding="UTF-8" ?>" );
      XmlTree doc( beginXmlStr );
    
      XmlTree generalNode;
      generalNode.setTag("general");
      generalNode.push_back(XmlTree("ColorR", toString(mColor.r)));
      generalNode.push_back(XmlTree("ColorG", toString(mColor.g)));
      generalNode.push_back(XmlTree("ColorB", toString(mColor.b)));
    
      doc.push_back(generalNode);
    
      doc.write( writeFile( getAppPath() / fs::path("..") / fs::path(filename) ) );
    }
  3. Now we declare a class member. It will be the flag to trigger snapshot creation:
    bool mMakeSnapshot;
  4. Assign a value to it value inside the setup method:
    mMakeSnapshot = false;
  5. At the end of the draw method we put the following code, just before the params::InterfaceGl::draw(); line:
    if(mMakeSnapshot) {
      mMakeSnapshot = false;
    
      double timestamp = getElapsedSeconds();
      std::string timestampStr = toString(timestamp);
    
      writeImage(getAppPath() / fs::path("..") / fs::path("snapshot_" + timestampStr + ".png"), copyWindowSurface());
      saveParameters("snapshot_" + timestampStr + ".xml");
    }
  6. We want to make a button in our InterfaceGl window:
    mParams.addButton( "Make snapshot", std::bind( &MainApp::makeSnapshotClick, this ) );

    As you can see we don't have the makeSnapshotClick method yet. It is simple to implement:

    void MainApp::makeSnapshotClick()
    {
        mMakeSnapshot = true;
    }
  7. The last step will be adding the following method for drag-and-drop support:
    void MainApp::fileDrop( FileDropEvent event )
    {
        std::string filepath = event.getFile( event.getNumFiles() - 1 ).generic_string();
        loadParameters(filepath);
    }

How it works...

We have two methods for loading and storing the mColor values in an XML file. These methods are loadParameters and saveParameters.

The code we put inside the draw method needs some explanation. We are waiting for the mMakeSnapshot method to be set to true and then we are creating a timestamp to avoid overwriting previous snapshots.The next two lines store the chosen values by invoking the saveParameters method and save a current window view as a PNG file using the writeImage function. Please notice that we have put that code before invoking InterfaceGl::draw, so we save the window view without the GUI.

A nice thing we have here is the drag-and-drop feature for loading snapshot files. It's implemented in the fileDrop method; Cinder invokes this method every time files are dropped to your application window. First, we get a path to the dropped file; in the case of multiple files, we are taking only one. Then we invoke the loadParameters method with the dropped file path as an argument.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.174.191