DEVELOPERS BLOG

Cloudy Pics Part 3: Persisting Camera Settings

Cloud Pics Part 3_1

Photo by Gary Fioret

Welcome back everyone. In the last post of the Cloud Pics series, we talked about how to easily set the Camera Roll with CameraRollManager. However, users don’t want to do it every time your app launches. To solve that problem, we will use CameraSettingsStore.

CameraSettingsStore

Similar to the CameraRollManager, this class can be used from both C++ and QML. There are a lot of functions on CameraRollManager available to you if you want to save and restore certain settings, but at its most basic you only need to do two things:

  1. When you change settings on your camera, call saveSettings with your CameraSettings object to have your settings written out to the file system (using QSettings, under the hood).
  2. When you open the camera for the first time, if you have saved settings call restoreAndApplySettings with your Camera object to have your save settings pulled off the file system and applied automatically. Otherwise, apply your defaults and save them.

And that’s just about it! For example, we could do this in our onCameraOpened slot:

onCameraOpened: {
       //Prepare to set up the camera
if (cameraSettingsStore.isEmpty()) {
              //No previous settings, use defaults
camera.getSettings(cameraSettings);
cameraSettings.cameraMode = CameraMode.Photo;
cameraSettings.focusMode = CameraFocusMode.ContinuousAuto;
cameraSettings.shootingMode = CameraShootingMode.Stabilization;

camera.applySettings(cameraSettings);

cameraSettingsStore.saveSettings(cameraSettings);

} else {
              //Restore previous settings
cameraSettingsStore.restoreAndApplySettings(camera);
camera.getSettings(cameraSettings);
}                   
//Now we can actually start the viewfinder
camera.startViewfinder();
}

If you’re expecting users to change a whole bunch of settings at once, those two functions are all you need. If users are changing one function at a time, however, you may want to just save individual settings. Let’s talk about how to do that.

saveSetting/loadSetting/deleteSetting

saveSetting, loadSetting and deleteSetting are the basic building blocks of the CameraSettingsStore class. These let you save, load or delete an individual setting. So for example, since we are only changing the camera roll path, our onCameraRollPathUpdated snippet from the last post would more correctly be something like this:

CameraRollManager {
id: cameraRollManager
onCameraRollPathUpdated: {
camera.getSettings(cameraSettings);
cameraSettings.cameraRollPath = cameraRollPath;
camera.applySettings(cameraSettings);
cameraSettingsStore.saveSetting(CameraSettingsStore.CameraRollPath, cameraRollPath);

}
}

Delete is useful if you wanted to save everything on the CameraSettings object except, for example,  the focus region. Load gives you an individual setting value. Since it’s a QVariant, you will have to cast it yourself or use populateSetting.

Cloud Pics Part 3_2

Photo by Erin Rahnenfueher

populateSetting

populateSetting is a slightly higher level version of loadSetting. Rather than having to manage the actual value of the setting yourself, you just load it directly into a CameraSettings object.

cameraSettingsStore.populateSetting(CameraSettingsStore.CameraRollPath, cameraRollPath);

populateSettings

Building on top of populateSetting, we have populateSettings, which will go through and fill a CameraSettings object with every saved setting. This is useful because it allows you to build restoreAndApply (which we saw in the beginning). Also, if you want to handle applying the CameraSettings yourself, this is the function for you.

If you’ve actually looked at the header file for this class, you may have noticed that there are two populateSettings and saveSettings functions, with one taking a generic QObject instead of a CameraSettings object like you might expect. This is due to a limitation with how CameraSettings was exposed to QML . It should be fixed in the future, but for now, the QObject version will be the one that gets called from QML.

Especially observant readers will have seen that populateSetting DOESN’T have a QObject version. That means you can’t call it from QML as it stands. If you need to, it would be easy enough to fix (just follow the example of populateSettings and saveSettings), but otherwise, wait for the next CloudyPics update!

Exposing enums to QML

Let’s end off with something not really camera-related, but something I see developers struggling with occasionally: enums in QML. Check out the bottom of the CameraSettingsStore header file:

QML_DECLARE_TYPE(bb::community::camera::CameraSettingsStore)
QML_DECLARE_TYPE(bb::community::camera::CameraSettingsStore::CameraSettingsType)

That’s all we need to do in order to make our CameraSettingsType enum available in QML. It’s that simple, but it’s easy to miss or forget if you aren’t paying attention.

Cloud Pics Part 3_3

Photo by Paul Bernhardt

Next time!

That’s the CameraSettingsStore. As you can see, it’s pretty simple and straightforward to use. It also probably won’t need much improvement in the future (other than perhaps expanding the enum).  Next time, we’ll have a double feature where we talk about invocation and working in an enterprise. As always, if you have any questions, comments, or feature requests, hit me up in the comments or at @PBernhardt.

About paulbe1