File indexing completed on 2025-01-18 10:10:45
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef ROOT7_RLegend
0010 #define ROOT7_RLegend
0011
0012 #include <ROOT/RPave.hxx>
0013 #include <ROOT/RAttrLine.hxx>
0014 #include <ROOT/RAttrFill.hxx>
0015 #include <ROOT/RAttrMarker.hxx>
0016 #include <ROOT/RDisplayItem.hxx>
0017
0018 #include <initializer_list>
0019 #include <memory>
0020 #include <vector>
0021
0022 namespace ROOT {
0023 namespace Experimental {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 class RLegend : public RPave {
0034
0035 public:
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 class RCustomDrawable final : public RDrawable {
0047 public:
0048 RCustomDrawable() : RDrawable("lentry") {}
0049
0050 RAttrLine line{this, "line"};
0051 RAttrFill fill{this, "fill"};
0052 RAttrMarker marker{this, "marker"};
0053 };
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 class REntry {
0065
0066 friend class RLegend;
0067
0068 std::string fLabel;
0069
0070 bool fLine{true}, fFill{false}, fMarker{false}, fError{false};
0071
0072 Internal::RIOShared<RDrawable> fDrawable;
0073
0074 std::string fDrawableId;
0075
0076 bool IsCustomDrawable() const { return dynamic_cast<const RCustomDrawable *>(fDrawable.get()) != nullptr; }
0077
0078 void DecodeOptions(const std::string &opt)
0079 {
0080 if (opt.find('l') != std::string::npos) SetLine(true);
0081 if (opt.find('f') != std::string::npos) SetFill(true);
0082 if (opt.find('m') != std::string::npos) SetMarker(true);
0083 if (opt.find('e') != std::string::npos) SetError(true);
0084 }
0085
0086 public:
0087 REntry() = default;
0088
0089
0090 REntry(const std::string &lbl, const std::string &opt)
0091 {
0092 fDrawableId = "custom";
0093 fLabel = lbl;
0094 DecodeOptions(opt);
0095 }
0096
0097
0098 REntry(std::shared_ptr<RDrawable> drawable, const std::string &lbl, const std::string &opt)
0099 {
0100 fDrawable = drawable;
0101 fLabel = lbl;
0102 DecodeOptions(opt);
0103 }
0104
0105 REntry &SetLabel(const std::string &lbl) { fLabel = lbl; return *this; }
0106 const std::string &GetLabel() const { return fLabel; }
0107
0108 REntry &SetLine(bool on = true) { fLine = on; return *this; }
0109 bool GetLine() const { return fLine; }
0110
0111 REntry &SetFill(bool on = true) { fFill = on; return *this; }
0112 bool GetFill() const { return fFill; }
0113
0114 REntry &SetMarker(bool on = true) { fMarker = on; return *this; }
0115 bool GetMarker() const { return fMarker; }
0116
0117 REntry &SetError(bool on = true) { fError = on; return *this; }
0118 bool GetError() const { return fError; }
0119
0120 std::shared_ptr<RDrawable> GetDrawable() const { return fDrawable.get_shared(); }
0121 };
0122
0123 private:
0124 std::string fTitle;
0125
0126 std::vector<REntry> fEntries;
0127
0128 protected:
0129 void CollectShared(Internal::RIOSharedVector_t &vect) override
0130 {
0131 for (auto &entry : fEntries) {
0132 vect.emplace_back(&entry.fDrawable);
0133 if (entry.fDrawable)
0134 entry.fDrawable->CollectShared(vect);
0135 }
0136 }
0137
0138
0139 std::unique_ptr<RDisplayItem> Display(const RDisplayContext &) override
0140 {
0141 for (auto &entry : fEntries) {
0142 if (!entry.IsCustomDrawable()) {
0143 entry.fDrawableId = RDisplayItem::ObjectIDFromPtr(entry.fDrawable.get());
0144 entry.fDrawable.reset_io();
0145 }
0146 }
0147
0148 return std::make_unique<RDrawableDisplayItem>(*this);
0149 }
0150
0151
0152 void OnDisplayItemDestroyed(RDisplayItem *) const override
0153 {
0154 for (auto ¢ry : fEntries) {
0155 if (!centry.IsCustomDrawable()) {
0156 auto entry = const_cast<REntry *>(¢ry);
0157 entry->fDrawable.restore_io();
0158 entry->fDrawableId.clear();
0159 }
0160 }
0161 }
0162
0163 public:
0164 RLegend() : RPave("legend") {}
0165
0166 RLegend(const std::string &title) : RLegend() { SetTitle(title); }
0167
0168 RLegend(const RPadPos &offset, const RPadExtent &size) : RLegend()
0169 {
0170 offsetX = offset.Horiz();
0171 offsetY = offset.Vert();
0172 width = size.Horiz();
0173 height = size.Vert();
0174 }
0175
0176 RLegend &SetTitle(const std::string &title) { fTitle = title; return *this; }
0177 const std::string &GetTitle() const { return fTitle; }
0178
0179 std::shared_ptr<RCustomDrawable> AddEntry(const std::string &lbl, const std::string &opt = "")
0180 {
0181 fEntries.emplace_back(lbl, opt);
0182 auto drawable = std::make_shared<RCustomDrawable>();
0183 fEntries.back().fDrawable = drawable;
0184 return drawable;
0185 }
0186
0187 void AddEntry(const std::shared_ptr<RDrawable> &drawable, const std::string &lbl, const std::string &opt = "")
0188 {
0189 fEntries.emplace_back(drawable, lbl, opt);
0190 }
0191
0192 auto NumEntries() const { return fEntries.size(); }
0193
0194 auto &GetEntry(int n) { return fEntries[n]; }
0195 };
0196
0197 }
0198 }
0199
0200 #endif