1 // Aseprite 2 // Copyright (C) 2001-2018 David Capello 3 // 4 // This program is distributed under the terms of 5 // the End-User License Agreement for Aseprite. 6 7 #ifndef APP_PREF_OPTION_H_INCLUDED 8 #define APP_PREF_OPTION_H_INCLUDED 9 #pragma once 10 11 #include "obs/signal.h" 12 #include <string> 13 14 namespace app { 15 16 class OptionBase; 17 18 class Section { 19 public: Section(const std::string & name)20 Section(const std::string& name) : m_name(name) { } ~Section()21 virtual ~Section() { } name()22 const char* name() const { return m_name.c_str(); } 23 24 virtual Section* section(const char* id) = 0; 25 virtual OptionBase* option(const char* id) = 0; 26 27 obs::signal<void()> BeforeChange; 28 obs::signal<void()> AfterChange; 29 30 private: 31 std::string m_name; 32 }; 33 34 class OptionBase { 35 public: OptionBase(Section * section,const char * id)36 OptionBase(Section* section, const char* id) 37 : m_section(section) 38 , m_id(id) { 39 } ~OptionBase()40 virtual ~OptionBase() { } section()41 const char* section() const { return m_section->name(); } id()42 const char* id() const { return m_id; } 43 protected: 44 Section* m_section; 45 const char* m_id; 46 }; 47 48 template<typename T> 49 class Option : public OptionBase { 50 public: 51 Option(Section* section, const char* id, const T& defaultValue = T()) OptionBase(section,id)52 : OptionBase(section, id) 53 , m_default(defaultValue) 54 , m_value(defaultValue) 55 , m_dirty(false) { 56 } 57 operator()58 const T& operator()() const { 59 return m_value; 60 } 61 operator()62 const T& operator()(const T& newValue) { 63 setValue(newValue); 64 return m_value; 65 } 66 67 // operator=() changes the value and the default value of the 68 // option. E.g. it's used when we copy two complete Sections, 69 // from default settings to user settings, or viceversa (the 70 // default value is always involved). 71 Option& operator=(const Option& opt) { 72 setValueAndDefault(opt.m_value); 73 return *this; 74 } 75 76 // Changes the default value and the current one. setValueAndDefault(const T & value)77 void setValueAndDefault(const T& value) { 78 setDefaultValue(value); 79 setValue(value); 80 } 81 defaultValue()82 const T& defaultValue() const { return m_default; } setDefaultValue(const T & defValue)83 void setDefaultValue(const T& defValue) { 84 m_default = defValue; 85 } 86 isDirty()87 bool isDirty() const { return m_dirty; } forceDirtyFlag()88 void forceDirtyFlag() { m_dirty = true; } cleanDirtyFlag()89 void cleanDirtyFlag() { m_dirty = false; } 90 setValue(const T & newValue)91 void setValue(const T& newValue) { 92 if (m_value == newValue) 93 return; 94 95 BeforeChange(newValue); 96 if (m_section) 97 m_section->BeforeChange(); 98 99 m_value = newValue; 100 m_dirty = true; 101 102 AfterChange(newValue); 103 if (m_section) 104 m_section->AfterChange(); 105 } 106 107 obs::signal<void(const T&)> BeforeChange; 108 obs::signal<void(const T&)> AfterChange; 109 110 private: 111 T m_default; 112 T m_value; 113 bool m_dirty; 114 115 Option(); 116 Option(const Option& opt); 117 }; 118 119 } // namespace app 120 121 #endif 122