9 #ifndef ROOT7_RAttrBase
10 #define ROOT7_RAttrBase
17 namespace Experimental {
29 friend class RAttrMap;
31 RDrawable *fDrawable{
nullptr};
32 std::unique_ptr<RAttrMap> fOwnAttr;
34 RAttrBase *fParent{
nullptr};
38 virtual const RAttrMap &GetDefaults()
const;
40 bool CopyValue(
const std::string &name,
const RAttrMap::Value_t &value,
bool check_type =
true);
42 bool IsValueEqual(
const std::string &name,
const RAttrMap::Value_t &value,
bool use_style =
false)
const;
46 void AssignDrawable(RDrawable *drawable,
const std::string &prefix);
48 void AssignParent(RAttrBase *parent,
const std::string &prefix);
51 RAttrMap *attr{
nullptr};
53 RDrawable *drawable{
nullptr};
54 operator bool()
const {
return !!attr; }
58 const Rec_t AccessAttr(
const std::string &name)
const
60 const RAttrBase *prnt =
this;
61 std::string fullname = name;
63 fullname.insert(0, prnt->fPrefix);
65 return {&(prnt->fDrawable->fAttr), fullname, prnt->fDrawable};
67 return {prnt->fOwnAttr.get(), fullname,
nullptr};
70 return {
nullptr, fullname,
nullptr};
74 const RAttrMap::Value_t *value{
nullptr};
75 std::shared_ptr<RStyle> style;
76 operator bool()
const {
return !!value; }
79 const Val_t AccessValue(
const std::string &name,
bool use_style =
true)
const
81 if (
auto access = AccessAttr(name)) {
82 if (
auto rec = access.attr->Find(access.fullname))
83 return {rec,
nullptr};
84 if (access.drawable && use_style)
85 if (
auto observe = access.drawable->fStyle.lock()) {
86 if (
auto rec = observe->Eval(access.fullname, *access.drawable))
87 return {rec, observe};
91 return {
nullptr,
nullptr};
96 Rec_t EnsureAttr(
const std::string &name)
99 std::string fullname = name;
101 fullname.insert(0, prnt->fPrefix);
103 return {&(prnt->fDrawable->fAttr), fullname, prnt->fDrawable};
104 if (!prnt->fParent && !prnt->fOwnAttr)
105 prnt->fOwnAttr = std::make_unique<RAttrMap>();
107 return {prnt->fOwnAttr.get(), fullname,
nullptr};
108 prnt = prnt->fParent;
110 return {
nullptr, fullname,
nullptr};
115 template <
typename RET_TYPE,
typename MATCH_TYPE =
void>
116 auto Eval(
const std::string &name,
bool use_dflts =
true)
const
118 if (
auto v = AccessValue(name,
true))
119 return RAttrMap::Value_t::GetValue<RET_TYPE,MATCH_TYPE>(v.value);
121 const RAttrMap::Value_t *rec =
nullptr;
124 rec = GetDefaults().Find(name);
126 return RAttrMap::Value_t::GetValue<RET_TYPE,MATCH_TYPE>(rec);
129 void CopyTo(RAttrBase &tgt,
bool use_style =
true)
const;
131 bool IsSame(
const RAttrBase &src,
bool use_style =
true)
const;
133 RAttrBase(RDrawable *drawable,
const std::string &prefix) { AssignDrawable(drawable, prefix); }
135 RAttrBase(RAttrBase *parent,
const std::string &prefix) { AssignParent(parent, prefix); }
137 RAttrBase(
const RAttrBase &src) { src.CopyTo(*
this); }
139 RAttrBase &operator=(
const RAttrBase &src)
146 void SetValue(
const std::string &name,
bool value);
147 void SetValue(
const std::string &name,
double value);
148 void SetValue(
const std::string &name,
int value);
149 void SetValue(
const std::string &name,
const std::string &value);
151 const std::string &GetPrefix()
const {
return fPrefix; }
153 void ClearValue(
const std::string &name);
157 template <
typename T =
void>
158 bool HasValue(
const std::string &name,
bool check_defaults =
false)
const
160 return Eval<const RAttrMap::Value_t *, T>(name, check_defaults) !=
nullptr;
163 template <
typename T>
164 T GetValue(
const std::string &name)
const
166 return Eval<T>(name);
170 RAttrBase() =
default;
172 virtual ~RAttrBase() =
default;
174 friend bool operator==(
const RAttrBase& lhs,
const RAttrBase& rhs){
return lhs.IsSame(rhs) && rhs.IsSame(lhs); }
175 friend bool operator!=(
const RAttrBase& lhs,
const RAttrBase& rhs){
return !lhs.IsSame(rhs) || !rhs.IsSame(lhs); }
182 #define R__ATTR_CLASS(ClassName,dflt_prefix,dflt_values) \
184 const RAttrMap &GetDefaults() const override \
186 static auto dflts = RAttrMap().dflt_values; \
190 ClassName() = default; \
191 ClassName(RDrawable *drawable, const std::string &prefix = dflt_prefix) { AssignDrawable(drawable, prefix); } \
192 ClassName(RAttrBase *parent, const std::string &prefix = dflt_prefix) { AssignParent(parent, prefix); } \
193 ClassName(const ClassName &src) : ClassName() { src.CopyTo(*this); } \
194 ClassName(ClassName &&src) = default; \
195 ClassName &operator=(ClassName &&src) = default; \
196 ClassName &operator=(const ClassName &src) \