guit  0.1
 All Classes Functions Variables Typedefs Enumerations Friends
gvarprop.hpp
1 //
2 // Base class for variable props
3 // Guit GUI Toolkit
4 // Copyright © 2019/2020 Eric Lecolinet. All rights reserved.
5 // http://www.telecom-paris.fr/~elc
6 //
7 
8 #ifndef Guit_VarProp_hpp
9 #define Guit_VarProp_hpp
10 #include <gproplist.hpp>
11 namespace guit {
12 
53 class GVarProp : public GProp {
54 public:
55  using IsVarProp = bool;
56  using IsGadgetOrVarProp = bool;
57 
58  using BindTag = int8_t;
59 
60  ~GVarProp();
61 
62  GVarProp* toVarProp() override {return this;}
63 
64  GVarProp* toMutableProp() override {
65  return omodes_.immutable ? nullptr : this;
66  }
67 
68  bool isMutable() const override {return !omodes_.immutable;}
69  void setImmutable() override {omodes_.immutable = 1;}
70 
72  virtual void set(GString const& value) = 0;
73 
77  virtual void set(GProp const& value) = 0;
78 
81  virtual void blend(GProp const& value1, GProp const& value2, float mix);
82 
85  bool read(GString const& filename);
86  virtual void read(std::istream& in);
87  friend std::istream& operator>>(std::istream& in, GVarProp&);
89 
98  void unbind(GVarProp& sender);
99  void unbind(GVarProp::BindTag bindtag = 0);
101 
104  void blink(GString const& msg = "", GTime duration = 500);
105 
107  void update();
108 
110  void perform(std::function<void(Gadget&)> fun);
111 
113  GPropList const& props() const {return props_;}
114 
115  virtual void addFun(GFunction const& fun);
116  virtual void add(GProp&);
117  virtual void add(GCond&);
118  virtual void addBegin(GProp&);
119  virtual void remove(GProp&);
120  virtual void removeNotifiers(void* object) override;
121  virtual void removeAll();
122  virtual void removeFromGadgets();
123 
126  bool changing() const {return pmodes_.changing;}
127  void changing(bool val) {pmodes_.changing = val;}
128  void bindImpl(GExpr& sender);
129  void bindImpl(GVarProp& sender, GFunction fun, BindTag);
130  void bindImpl(GVarProp& sender, class GChangeNotifier&, BindTag, bool recv_is_master);
131  void fireCallbacks(GEvent&);
132  void fireDefaultCallbacks();
133  bool hasActiveNotifiers();
134  void startNotify(Gadget&, std::function<void(Gadget&)> const& fun);
135  void startNotifyGadget(Gadget&);
136  void stopNotify(Gadget&);
137  bool testMasterValue();
138  void propagateChange();
139  void immutableError(const char*);
140  class GChangeNotifier* getMaster();
141  struct { // nb: ordre optimise pour gagner de la place memoire
142  uint8_t changing:1, removing:1, isSet:1, hasMaster:1, autoReset:1;
143  } pmodes_{};
144  GPropList props_;
146 };
147 
148 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
149 
151 template <class T> class GVarProp_ : public GVarProp {
152 public:
153  using ValueType = T;
154 
157  GVarProp_() = default;
158  explicit GVarProp_(T const& value) {doChange(value);}
160 
163  T const& value() const {return value_;}
164  T const& operator()() const {return value_;}
166 
168  //operator T const&() const {return value_;}
169 
171  GString stringValue() const override {return guit::toString(value_);}
172 
178  virtual void set(T const& value, bool callalways) {
179  if (omodes_.immutable) immutableError("set");
180  else if (doChange(value) || callalways)
181  propagateChange();
182  }
183 
185  void set(GString const& str) override {
186  T val{}; gconvert(str, val); set(val, false);
187  }
188 
189  void set(GProp const& value) override {
190  if (auto* p = dynamic_cast<GVarProp_<T> const*>(&value)) {
191  set(p->value(), false);
192  }
193  else if (value.isString()) {
194  set(value.stringValue());
195  }
196  else error("set(GProp)","incompatible argument");
197  }
198 
199  bool operator==(T const& value) const {return value_ == value;}
200 
201  template <class V>
202  bool operator==(GVarProp_<V> const& other) const {return value_ == other.value_;}
203 
204 
205  virtual bool isValid(T const&) const {return true;}
206 
207  virtual bool doChange(T const& v) {
208  if (v == value_ && pmodes_.isSet) return false;
209  pmodes_.isSet = 1;
210  value_ = v;
211  return true;
212  }
213 
215  T value_{};
216 };
217 
218 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
219 
225 class GPropRef {
226 public:
227  explicit GPropRef(GProp& prop) : prop_(prop) {}
228  GProp& prop_;
229 };
230 class GNumPropRef {
231 public:
232  explicit GNumPropRef(GProp& prop) : prop_(prop) {}
233  GProp& prop_;
234 };
236 
237 
238 template <class P> class GPropRef_ : public GPropRef {
239 public:
240  explicit GPropRef_(P& prop) : GPropRef(prop) {}
241 };
242 
243 template <class P> class GNumPropRef_ : public GNumPropRef {
244 public:
245  explicit GNumPropRef_(P& prop) : GNumPropRef(prop) {}
246 };
247 
248 
256 template <class P, class F>
257 class GPropField {
258 public:
259  GPropField(P& prop, F& field) : prop_(prop), field_(field) {}
260  GPropRef operator~();
261  P& prop_;
262  F& field_;
263 };
264 template <class P, class F>
265 class GNumPropField : public GPropField<P,F> {
266 public:
267  GNumPropField(P& prop, F& field) : GPropField<P,F>(prop,field) {}
268  GNumPropRef operator~();
269 };
271 
272 }
273 #endif