File indexing completed on 2025-09-16 09:08:27
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef ROOT7_RAttrBase
0010 #define ROOT7_RAttrBase
0011
0012 #include <ROOT/RAttrMap.hxx>
0013 #include <ROOT/RStyle.hxx>
0014 #include <ROOT/RDrawable.hxx>
0015
0016 namespace ROOT {
0017
0018 class RLogChannel;
0019
0020 namespace Experimental {
0021
0022
0023 ROOT::RLogChannel &GPadLog();
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 class RAttrBase {
0034
0035 friend class RAttrMap;
0036
0037 enum {kDrawable, kParent, kOwnAttr} fKind{kDrawable};
0038
0039 union {
0040 RDrawable *drawable;
0041 RAttrBase *parent;
0042 RAttrMap *ownattr;
0043 } fD{nullptr};
0044
0045 const char *fPrefix{nullptr};
0046
0047 void ClearData();
0048 RAttrMap *CreateOwnAttr();
0049
0050 protected:
0051
0052 RDrawable *GetDrawable() const { return fKind == kDrawable ? fD.drawable : nullptr; }
0053 RAttrBase *GetParent() const { return fKind == kParent ? fD.parent : nullptr; }
0054 RAttrMap *GetOwnAttr() const { return fKind == kOwnAttr ? fD.ownattr : nullptr; }
0055
0056 virtual RAttrMap CollectDefaults() const = 0;
0057
0058 virtual bool IsAggregation() const { return false; }
0059
0060
0061
0062 struct Rec_t {
0063 RAttrMap *attr{nullptr};
0064 std::string fullname;
0065 RDrawable *drawable{nullptr};
0066 operator bool() const { return !!attr; }
0067 };
0068
0069
0070 const Rec_t AccessAttr(const std::string &name) const
0071 {
0072 const RAttrBase *prnt = this;
0073 std::string fullname = name;
0074 while (prnt) {
0075 if (prnt->IsAggregation() && prnt->fPrefix) {
0076 fullname.insert(0, "_");
0077 fullname.insert(0, prnt->fPrefix);
0078 }
0079 if (auto dr = prnt->GetDrawable())
0080 return { &dr->fAttr, fullname, dr };
0081 if (auto attr = prnt->GetOwnAttr())
0082 return { attr, fullname, nullptr };
0083 prnt = prnt->GetParent();
0084 }
0085 return {nullptr, fullname, nullptr};
0086 }
0087
0088 struct Val_t {
0089 const RAttrMap::Value_t *value{nullptr};
0090 std::shared_ptr<RStyle> style;
0091 operator bool() const { return !!value; }
0092 };
0093
0094
0095 const Val_t AccessValue(const std::string &name, bool use_style = true) const
0096 {
0097 if (auto access = AccessAttr(name)) {
0098 if (auto rec = access.attr->Find(access.fullname))
0099 return {rec, nullptr};
0100 if (access.drawable && use_style)
0101 if (auto observe = access.drawable->fStyle.lock()) {
0102 if (auto rec = observe->Eval(access.fullname, *access.drawable))
0103 return {rec, observe};
0104 }
0105 }
0106
0107 return {nullptr, nullptr};
0108 }
0109
0110
0111
0112 Rec_t EnsureAttr(const std::string &name)
0113 {
0114 auto prnt = this;
0115 std::string fullname = name;
0116 while (prnt) {
0117 if (prnt->IsAggregation() && prnt->fPrefix) {
0118 fullname.insert(0, "_");
0119 fullname.insert(0, prnt->fPrefix);
0120 }
0121 if (auto dr = prnt->GetDrawable())
0122 return { &dr->fAttr, fullname, dr };
0123 if (prnt->fKind != kParent)
0124 return { prnt->CreateOwnAttr(), fullname, nullptr };
0125 prnt = prnt->GetParent();
0126 }
0127 return {nullptr, fullname, nullptr};
0128 }
0129
0130 RAttrBase(const char *prefix)
0131 {
0132 fKind = kOwnAttr;
0133 fD.ownattr = nullptr;
0134 fPrefix = prefix;
0135 }
0136
0137 RAttrBase(RDrawable *drawable, const char *prefix = nullptr)
0138 {
0139 fKind = kDrawable;
0140 fD.drawable = drawable;
0141 fPrefix = prefix;
0142 }
0143
0144 RAttrBase(RAttrBase *parent, const char *prefix = nullptr)
0145 {
0146 fKind = kParent;
0147 fD.parent = parent;
0148 fPrefix = prefix;
0149 }
0150
0151 void SetNoValue(const std::string &name);
0152
0153 const char *GetPrefix() const { return fPrefix; }
0154
0155 void ClearValue(const std::string &name);
0156
0157 void MoveTo(RAttrBase &tgt);
0158
0159 public:
0160 RAttrBase() = default;
0161
0162 virtual ~RAttrBase() { ClearData(); }
0163
0164 virtual void Clear() = 0;
0165
0166 };
0167
0168 }
0169 }
0170
0171 #endif