Settings (xtd.core)
When creating an application, you often need to save certain parameters such as the last file used by the user, the last tool used by the user, the current size of the main form or the background color. That's where settings come into play In fact, thanks to its very simple settings management, xtd makes it easy to load and save your resources. Thanks to an automatically generated static class, you can access your settings without worrying about format and location, which may differ depending on the platform used.
Settings declaration
Using the CMake
commands specific to xtd
, simply describe the settings to be added to your application.
Although you can add the setting and setting_include commands (which are the only two commands for adding settings) to your CMakeLists.txt
file, the best thing to do is to create a properties
folder next to the src
folder and describe your resources in the settings.cmake
file.
When CMake generates your xtd project, the properties/settings.cmake
file will be detected automatically.
Here's an example of the properties/settings.cmake
file with some specific CMake commands to describe your settings.
properties/settings.cmake
# Settings file
# =============
# Remarks
# This file generates the "properties/settings.hpp" file, which is used to access the settings.
# Includes
setting_include("xtd/drawing/point")
setting_include("xtd/drawing/size")
setting_include("xtd/drawing/system_colors")
# User settings
setting(back_color xtd::drawing::color USER "xtd::drawing::system_colors::control()")
setting(location xtd::drawing::point USER "{100, 50}")
setting(size xtd::drawing::size USER "{335, 45}")
# Application settings
setting(text xtd::string APPLICATION "\"Settings example\"")
Settings CMake Commands
setting
setting(NAME TYPE SCOPE VALUE)
- Description Add setting to current project.
- NAME param The name of the setting to add.This will be the name of the property in the generated static settings class
your_project::properties::settings
. - TYPE param The type of setting to add.
- SCOPE param The scope of setting to add (APPLICATION or USER).
- APPLICATION : Application-scope settings are read only at run time.
- USER : User-scope settings are read/write at run time, and their values can be changed and saved in code.
- VALUE param The value of setting to add.
- remarks
- This method can be called multiple times in the same project.
- This method must be called before target_type().
- This method is optional.
- See setting command
- See CMake commands
setting_include
setting_include(SETTIING_INCLUDE_FILE)
- Description Adds a setting include file to current project.
- SETTIING_INCLUDE_FILE param The include file to add.
- remarks
- This method can be called multiple times in the same project.
- This method must be called before target_type().
- This method is optional.
- See setting_include command
- See CMake commands
Remarks
The setting_include commands are optional, you can remove them but you must be sure that before including the properties/settings.hpp
file all the types defined in the properties/settings.cmake
file are already known.
Settings generation
Generating your xtd
project with CMake
will automatically generate a static class your_project::properties::settings
containing the static properties for accessing settings.
The settings
class will be generated in the propertes/settings.hpp
file. And this file will be automatically added to your project as a source.
properties/settings.hpp
#pragma region xtd generated code
// This code was generated by CMake script.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
#pragma once
#include <xtd/drawing/point>
#include <xtd/drawing/size>
#include <xtd/drawing/system_colors>
#include <xtd/configuration/settings>
namespace application_settings::properties {
/// @brief A strongly typed settings class, for storing user and system settings
/// @details This class was auto-generated by CMake script. To add or remove a member, edit your CMakeList.txt or properties/settings.cmake file then rerun cmake tools.
/// @remarks See [Settings](https://gammasoft71.github.io/xtd/docs/documentation/guides/xtd.core/settings) for more informations.
class settings : public xtd::object {
public:
/// @name Public Constructors
/// @{
/// @brief Initializes a new instance of the application_settings::properties::settings class.
/// @remarks All properties are reloaded with the last saved value.
settings() noexcept : settings {true} {}
/// @brief Initializes a new instance of the application_settings::properties::settings class.
/// @param load If `true` all properties are reloaded with the last saved values; otherwise none.
explicit settings(bool load) noexcept {
if (load) reload();
}
/// @}
/// @cond
settings(settings&&) noexcept = default;
settings(const settings&) noexcept = default;
settings& operator =(const settings&) noexcept = default;
/// @endcond
/// @name Public Properties
/// @{
/// @brief Gets the back_color user setting property.
/// @return A xtd::drawing::color value.
xtd::drawing::color back_color() const noexcept {return back_color_;}
/// @brief Sets the back_color user setting property.
/// @param value A xtd::drawing::color value.
settings& back_color(xtd::drawing::color value) noexcept {
back_color_ = value;
return *this;
}
/// @brief Gets the location user setting property.
/// @return A xtd::drawing::point value.
xtd::drawing::point location() const noexcept {return location_;}
/// @brief Sets the location user setting property.
/// @param value A xtd::drawing::point value.
settings& location(xtd::drawing::point value) noexcept {
location_ = value;
return *this;
}
/// @brief Gets the size user setting property.
/// @return A xtd::drawing::size value.
xtd::drawing::size size() const noexcept {return size_;}
/// @brief Sets the size user setting property.
/// @param value A xtd::drawing::size value.
settings& size(xtd::drawing::size value) noexcept {
size_ = value;
return *this;
}
/// @brief Gets the text system setting property.
/// @return A xtd::string value.
xtd::string text() const noexcept {return "Settings example";}
/// @}
/// @name Public Methods
/// @{
/// @brief Reload all properties with the last saved values.
/// @remarks See [Settings](https://gammasoft71.github.io/xtd/docs/documentation/guides/xtd.core/settings) for more informations.
void reload() noexcept {
back_color_ = settings_.read("back_color", back_color_);
location_ = settings_.read("location", location_);
size_ = settings_.read("size", size_);
}
/// @brief Reset all properties to their default values.
/// @remarks See [Settings](https://gammasoft71.github.io/xtd/docs/documentation/guides/xtd.core/settings) for more informations.
void reset() noexcept {
settings_.reset();
*this = settings {false};
}
/// @brief Save all properties.
/// @remarks See [Settings](https://gammasoft71.github.io/xtd/docs/documentation/guides/xtd.core/settings) for more informations.
void save() noexcept {
settings_.write("back_color", back_color_);
settings_.write("location", location_);
settings_.write("size", size_);
settings_.save();
}
/// @}
/// @name Public Static Properties
/// @{
/// @brief Gets the default instance of settings.
/// @return The default instance.
/// @remarks At the first call all properties are reloaded with the last saved values.
static settings& default_settings() noexcept {
static auto default_settings = settings {};
return default_settings;
}
/// @}
private:
xtd::configuration::settings settings_;
xtd::drawing::color back_color_ {xtd::drawing::system_colors::control()};
xtd::drawing::point location_ {{100, 50}};
xtd::drawing::size size_ {{335, 45}};
};
}
#pragma endregion
Settings usage
All that's left is to exploit your settings in a way that's simple and transparent to your environment and OS.
Just include the inlcude file propertes/settings.hpp
and use its properties.
application_settings.cpp
#include "../properties/settings.hpp"
#include <xtd/forms/application>
#include <xtd/forms/button>
#include <xtd/forms/color_picker>
#include <xtd/forms/form>
using namespace application_settings::properties;
using namespace xtd::forms;
auto main() -> int {
auto main_form = form::create(settings::default_settings().text(), form_start_position::manual);
auto back_color_picker = color_picker::create(main_form, main_form.back_color(), {10, 10}, {75, 25});
back_color_picker.color_picker_changed += [&] {
main_form.back_color(back_color_picker.color());
};
auto save_button = button::create(main_form, "&Save", {90, 10});
save_button.click += [&] {
settings::default_settings().size(main_form.client_size());
settings::default_settings().location(main_form.location());
settings::default_settings().back_color(main_form.back_color());
settings::default_settings().save();
};
auto reload_button = button::create(main_form, "&Reload", {170, 10});
reload_button.click += [&] {
main_form.client_size(settings::default_settings().size());
main_form.location(settings::default_settings().location());
main_form.back_color(settings::default_settings().back_color());
back_color_picker.color(settings::default_settings().back_color());
};
auto reset_button = button::create(main_form, "R&eset", {250, 10});
reset_button.click += [&] {
settings::default_settings().reset();
reload_button.perform_click();
};
// Recovers saved settings (reload) on launch
reload_button.perform_click();
application::run(main_form);
}
Settings types
xtd settings can handle different types of parameters:
- Native types: int, bool, char, ...
- xtd types: xtd::string, xtd::drawing::color, ...
- Or any type you define, there's no limit.
Remarks
- If you don't add a setting and setting_include commands to your
CMakeLists.txt
and don't add aproperties/settings.cmake
file, then xtd won't generate anything. - The simplified use of xtd settings is totally optional. You can use your own method.
Settings path
The basic settings path can be obtained with the command xtd::environment::get_folder_path(xtd::environment::special_folder::application_data).
Depending on the platform, settings are stored in the following locations:
Platform | Path |
---|---|
Windows | %APPDATA%\company_name\product_name.ini |
macOS | ~/Library/Preferences/company_name/product_name Preferences |
Linux | ~/.config/company_name/product_name.conf |
The `product_name`` is defined by the xtd::reflection::assembly::product() property of the xtd::reflection::assembly::get_executing_assembly() assembly if it’s not empty; otherwise, it defaults to the filename of the first argument passed to main.
The company_name
is defined by the xtd::reflection::assembly::company() property of the same assembly if not empty; otherwise, it defaults to the same value as product_name
.
Examples
Some xtd examples use settings :
and more see xtd.examples.
See also