diff --git a/Kotatogram-Settings:-Quick-developer-reference.md b/Kotatogram-Settings:-Quick-developer-reference.md new file mode 100644 index 0000000..f5372b3 --- /dev/null +++ b/Kotatogram-Settings:-Quick-developer-reference.md @@ -0,0 +1,241 @@ +## Step 1: add setting to definition map + +_File: Telegram/SourceFiles/kotato/kotato_settings.cpp_ + +Find the following: + +```cpp +const std::map> DefinitionMap +``` + +and add new definition to it: + +```cpp + { "my_custom_setting", { + .scope = SettingScope::Global, + .storage = SettingStorage::MainJson, + .type = SettingType::BoolSetting, + .defaultValue = false, + .fillerValue = false, + .limitHandler = nullptr }}, +``` + +- key (in this example `"my_custom_setting"`, `QString`): this is the name of option that will be used both in code and in JSON file. +- `scope` (`enum SettingScope`): `SettingScope::Global` will apply setting to all accounts, `SettingScope::Account` will apply to current account only. If not set, `SettingScope::Global` is assumed. +- `storage` (`enum SettingStorage`): `SettingStorage::MainJson` will save it to JSON settings file, `SettingStorage::None` can be used in app, but changes won't be saved. If not set, `SettingStorage::MainJson` is assumed. +- `type` (`enum SettingType`): values `SettingType::BoolSetting`, `SettingType::IntSetting`, `SettingType::QStringSetting`, `SettingType::QJsonArraySetting` resemble the types `bool`, `int`, `QString` and `QJsonArray`. If not set, `SettingType::BoolSetting` is assumed. +- `defaultValue` (`QVariant`): sets default value that will be used if it wasn't set earlier. Will be null if it's not set. +- `fillerValue` (`QVariant`): used in default settings file as an example. If not set, it will use `defaultValue`. +- `limitHandler` (`CheckHandler`, defined as `Fn`): this function takes user-provided value (`QVariant`) and returns filtered version of this value (`QVariant`). If it's `nullptr`, only basic type will be checked. If not set, `nullptr` is assumed. + +### Handler generators + +Some handler generator functions that you can use as an example or value: + +```cpp +CheckHandler IntLimit(int min, int max, int defaultValue) +``` +`IntLimit` generates handler that sets number to `min` if it's lower than `min`, and sets number to `max` if it's higher than `max`. If value can't be converted to `int`, sets it to `defaultValue`. + +--- + +```cpp +inline CheckHandler IntLimit(int min, int max) +``` +Same `IntLimit` as previous one, but uses `min` instead of `defaultValue`. + +--- + +```cpp +CheckHandler IntLimitMin(int min) +``` +Version of `IntLimit` that limits only from one side: it sets number to `min` if it's lower than `min`. If value can't be converted to `int`, sets it to `min`. + +--- + +```cpp +CheckHandler ScalesLimit() +``` +Handler generator used specifically in `"scales"` option. Limits array to 6 values, and scales to range from `style::kScaleMin` to `style::kScaleMax`. + +--- + +```cpp +CheckHandler ReplacesLimit() +``` +Handler generator used specifically in `"replaces"` option. Checks if sub-values are `QJsonArray`'s with two `QString` elements (from, to). + +--- + +```cpp +CheckHandler FileDialogLimit() +``` +Handler generator used specifically in `"file_dialog_type"` option. Converts integer values to Platform::FileDialog::ImplementationType enum. + +--- + +```cpp +CheckHandler NetSpeedBoostConv(CheckHandler wrapped = nullptr) +``` +Handler generator used specifically in `"net_speed_boost"` option. Maps string values (`low`, `medium`, `high`) to integer values. `wrapped` used as post-filter. In `"net_speed_boost"` it's used `NetSpeedBoostConv(IntLimit(0, 3))`. + + +## Step 2: use your option in code + +First, you must include settings header file, if it's not included: + +```cpp +#include "kotato/kotato_settings.h" +``` + +### Getting the value + +To get the value, you can use this: + +```cpp +::Kotato::JsonSettings::Get("my_custom_setting") +``` + +There are also two additonal parameters: account id (`uint64`, default is `0`, which means "all accounts"), and "is test server" (`bool`, default is `false`, but it is used only when account id is not `0`). + +Example for account id `777` on test server: + +```cpp +::Kotato::JsonSettings::Get("my_custom_setting", 777, true) +``` + +Example for account id `555` on production server: + +```cpp +::Kotato::JsonSettings::Get("my_custom_setting", 555) +``` + +or + +```cpp +::Kotato::JsonSettings::Get("my_custom_setting", 555, false) +``` + +Usually you don't need to set those by hand, these examples are just for demonstration. + +### `Get` function caveat + +There's the one caveat. `::Kotato::JsonSettings::Get`, returns `QVariant`, so to use it correctly you should use `QVariant`'s methods `.toBool()`, `.toInt()`, `.toString()` and `.toJsonArray()`, depending on type. You can also use shorthand methods: + +```cpp +::Kotato::JsonSettings::GetBool("my_custom_setting"); // returns bool +::Kotato::JsonSettings::GetInt("my_custom_setting"); // returns int +::Kotato::JsonSettings::GetString("my_custom_setting"); // returns QString +::Kotato::JsonSettings::GetJsonArray("my_custom_setting"); // returns QJsonArray +``` + +Parameters are the same as in original `Get`, only difference is that shorthands return type you need. + +### Setting the value + +To set an option you can use a following method: + +```cpp +::Kotato::JsonSettings::Set("my_custom_setting", true); +``` + +In that case true is the value (`QVariant`). `QVariant` will accept any supported value. + +> **Warning!** `Set` is **not** doing type checks, so it's the developer responsiblity to use the correct type. You have been warned. + +`Set` also supports account id and test server check parameters, explained in "Getting the value": + +```cpp +::Kotato::JsonSettings::Set("my_custom_setting", true /* value */, 777 /* account id */, true /* is test server */); +``` + +Don't forget to save your options after you've changed them: + +```cpp +::Kotato::JsonSettings::Write(); +``` + +If called multiple times in short period of time, writing to file is delayed for 5 seconds to reduce file I/O operations, unless app is restarting. + +### Resetting the value to default + +To reset an option you can use a following method: + +```cpp +::Kotato::JsonSettings::Reset("my_custom_setting"); +``` + +Like with `Set`, account id and test server check parameters are also supported: + +```cpp +::Kotato::JsonSettings::Reset("my_custom_setting", 777 /* account id */, true /* is test server */); +``` + +Don't forget to save your options after you've changed them: + +```cpp +::Kotato::JsonSettings::Write(); +``` + +### After-restart options + +Some options must be applied only after restart, because there are too many dependencies to change it on the go. + +To set an option after restart you can use a following method: + +```cpp +::Kotato::JsonSettings::SetAfterRestart("my_custom_setting", true); +``` + +`Reset` also has `AfterRestart` version: + +```cpp +::Kotato::JsonSettings::ResetAfterRestart("my_custom_setting"); +``` + +Note that `Get` method (along with shorthands) will return the value that was loaded on app start. If you want to know what value will be applied after restart, you can use `GetWithPending` method: + +```cpp +::Kotato::JsonSettings::GetWithPending("my_custom_setting"); +``` + +Note that it returns `QVariant` that is needed to convert. Instead of that, you can use shorthands: + +```cpp +::Kotato::JsonSettings::GetBoolWithPending("my_custom_setting"); // returns bool +::Kotato::JsonSettings::GetIntWithPending("my_custom_setting"); // returns int +::Kotato::JsonSettings::GetStringWithPending("my_custom_setting"); // returns QString +::Kotato::JsonSettings::GetJsonArrayWithPending("my_custom_setting"); // returns QJsonArray +``` + +Account id and test server check parameters are also supported in all these methods. + +### RPL + +TDesktop heavily relies on self-written RPL library. This library allows to listen to events, and do actions in widgets after they're triggered. + +While RPL itself is out of scope of this page, there are methods that you can use. + +--- + +```cpp +::Kotato::JsonSettings::Events("my_custom_setting") // returns rpl::producer +``` + +This method, combined with, for example, `rpl::start_with_next`, will allow to run actions after it's changed. Actual implementation may be harder, so it's better to study code that already uses RPL. Also note that QString is not a value: it's a combined settings map key. Value should be obtained yourself by calling `Get` or `GetWithPending` (or their shorthands). + +`Events` also supports account id and test server check parameters, explained in "Getting the value": + +```cpp +::Kotato::JsonSettings::Events("my_custom_setting", 777 /* account id */, true /* is test server */); +``` + +--- + +```cpp +::Kotato::JsonSettings::RestartEvents() // returns rpl::producer +``` + +Triggers when `SetAfterRestart`/`ResetAfterRestart` is used. Contained value shows if restart is needed: `true`: needs restart, `false`: doesn't need restart. + +> This function is currently unused and may be changed or removed. \ No newline at end of file