guit  0.1
 All Classes Functions Variables Typedefs Enumerations Friends
gstyle.hpp
1 //
2 // Styles & CSS
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_Style_hpp
9 #define Guit_Style_hpp
10 #include <list>
11 #include <unordered_map>
12 #include <gprop.hpp>
13 #include <gadget.hpp>
14 namespace guit {
15 
16 struct GStyleMap : public std::unordered_map<GId,GStyle*> {
17  ~GStyleMap();
18  GStyle* findStyle(GId selid);
19  GStyle& obtainStyle(GId selid);
20 };
21 
22 class GPseudoStyle;
23 
30 class GStyle {
31 public:
32  enum Specif : GProp::Specif {
33  TypeSpecif = 1,
34  ClassSpecif = 100,
35  IdSpecif = 10'000,
36  InlineSpecif = 1'000'000,
37  InterSpecif = 10'000'000,
38  CondSpecif = 20'000'000,
39  AnimSpecif = 30'000'000
40  };
41 
42  struct PropMap : public std::unordered_map<int, gptr<GProp>> {
43  void apply(Gadget* g, GRender& r, GProp::Specif specif) {
44  for (auto& p : *this) p.second->apply(g, r, specif);
45  }
46  };
47 
48  ~GStyle();
49  GStyle(GId selector_id);
50 
52  void realize();
53 
56  void addProp(GProp* prop);
57  GStyle& operator<<(GProp* prop) {addProp(prop); return *this;}
58  GStyle& operator<<(GProp& prop) {addProp(&prop); return *this;}
60 
63  GProp* findProp(GPropType&) const;
64  template <class T> auto* findProp() const {return dynamic_cast<T*>(findProp(T::Type()));}
66 
69  void removeProp(GProp&);
70  void removeProp(GPropType&);
72 
73  PropMap const& props() const {return props_;}
74 
75  void apply(Gadget* g, GRender& r) {
76  if (!realized_) realize();
77  if (!props_.empty()) props_.apply(g, r, specif_);
78  if (!pseudos_.empty()) applyPseudos(g, r);
79  }
80 
81  void applyPseudos(Gadget* g, GRender& r);
82 
83  // calls realize() if style if alraedy realized_, otherwise just adds decl block
84  void addStyleDecl(GString const& decl, GProp::Specif, GPseudoStyle* ps);
85  GStyle* addStyleDecl2(GString const& decl, GProp::Specif, GPseudoStyle* ps,
86  GString const& desc, char reltype, bool is_subrule);
87 
90  enum RelType {DirectChild = 1};
91  void addDecl(GString const& decl);
92  bool realized_{}, has_desc_{}, any_desc_{}, direct_desc_{}, has_subrule_{}, is_pseudo_{};
93  GId id_{};
94  GProp::Specif specif_{};
95  GadgetModes modes_{};
96  GString decl_;
97  PropMap props_;
98  GStyleMap* stylemap_{};
99  std::forward_list<GPseudoStyle*> pseudos_;
101 };
102 
103 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
104 
106 class GStyleBase {
107 public:
109  static GStyleBase& instance();
110 
112  bool loadFile(GString const& css_filename);
113 
115  bool loadBuffer(GString const& css_buffer);
116 
118  bool load(std::istream& in, GString const& stream_name);
119 
123  GStyle* findStyle(GId selector_id);
124  GStyle* findStyle(GString const& selector_name);
125  GStyle& obtainStyle(GId selector_id);
126  GStyle& obtainStyle(GString const& selector_name);
128 
130  bool addStyle(GStrings& seltab, GString const& decl_block);
131 
134  void addCoreStyle(GString const& name, GStyle&);
135  void error(GString const& msg);
136  bool parseStyle(std::istream&);
137 
138 
139  //bool parseSelName(GString const& sel, GString& name,
140  // GStrings& pseudos, GProp::Specif&);
141 
142 
143  bool parseSelName(GString const& sel, GString& name,
144  GProp::Specif& spec, GPseudoStyle*& ps);
145 
146  GString streamname_;
147  GStyleMap styles_;
149 };
150 
151 
152 }
153 #endif