1 #ifndef CPPURSES_WIDGET_SIZE_POLICY_HPP
2 #define CPPURSES_WIDGET_SIZE_POLICY_HPP
3 #include <cstddef>
4 #include <limits>
5 
6 namespace cppurses {
7 class Widget;
8 
9 /// Defines how a Layout should resize a Widget in one length Dimension.
10 class Size_policy {
11    public:
12     /// Descriptions of how the size hint should be used.
13     /** Fixed: hint is the only acceptable size. */
14     /** Minimum: hint is the minimum acceptable size, may be larger. */
15     /** Maximum: hint is the maximum acceptable size, may be smaller. */
16     /** Preferred: hint is preferred, though it can be any size. */
17     /** Expanding: hint is preferred, but it will expand to use extra space. */
18     /** MinimumExpanding: hint is minimum, it will expand into unused space. */
19     /** Ignored: hint is ignored and stretch factor is the only consideration */
20     enum Type {
21         Fixed,
22         Minimum,
23         Maximum,
24         Preferred,
25         Expanding,
26         MinimumExpanding,
27         Ignored
28     };
29 
30     /// Constructs a size policy with \p owner.
31     /** \p owner is needed to notify its parent whenever a value has been
32      *  changed, this is done by posting a Child_polished_event. */
Size_policy(Widget * owner)33     explicit Size_policy(Widget* owner) : owner_{owner} {}
34 
35     /// Set the type to Fixed with size hint of \p hint.
fixed(std::size_t hint)36     void fixed(std::size_t hint) {
37         type_ = Type::Fixed;
38         hint_ = hint;
39         this->notify_parent();
40     }
41 
42     /// Set the type to Minimum with size hint of \p hint.
minimum(std::size_t hint)43     void minimum(std::size_t hint) {
44         type_ = Type::Minimum;
45         hint_ = hint;
46         this->notify_parent();
47     }
48 
49     /// Set the type to Maximum with size hint of \p hint.
maximum(std::size_t hint)50     void maximum(std::size_t hint) {
51         type_ = Type::Maximum;
52         hint_ = hint;
53         this->notify_parent();
54     }
55 
56     /// Set the type to Preferred with size hint of \p hint.
preferred(std::size_t hint)57     void preferred(std::size_t hint) {
58         type_ = Type::Preferred;
59         hint_ = hint;
60         this->notify_parent();
61     }
62 
63     /// Set the type to Expanding with size hint of \p hint.
expanding(std::size_t hint)64     void expanding(std::size_t hint) {
65         type_ = Type::Expanding;
66         hint_ = hint;
67         this->notify_parent();
68     }
69 
70     /// Set the type to MinimumExpanding with size hint of \p hint.
minimumExpanding(std::size_t hint)71     void minimumExpanding(std::size_t hint) {
72         type_ = Type::MinimumExpanding;
73         hint_ = hint;
74         this->notify_parent();
75     }
76 
77     /// Set the type to Ignored.
ignored()78     void ignored() { this->type(Type::Ignored); }
79 
80     /// Set the Type of the Size_policy.
type(Size_policy::Type type)81     void type(Size_policy::Type type) {
82         type_ = type;
83         this->notify_parent();
84     }
85 
86     /// Return the type of Size_policy currently being used.
type() const87     Size_policy::Type type() const { return type_; }
88 
89     /// Set the stretch factor.
90     /** Used to fit adjacent Widgets within a length. The stretch is used to
91      *  compute a percentage of length the Widget should receive by dividing it
92      *  by the total stretch of all Widgets in the layout. */
stretch(std::size_t value)93     void stretch(std::size_t value) {
94         stretch_ = value;
95         this->notify_parent();
96     }
97 
98     /// Return the stretch factor currently being used.
stretch() const99     std::size_t stretch() const { return stretch_; }
100 
101     /// Set the size hint, used in accordance to the Type enum.
hint(std::size_t value)102     void hint(std::size_t value) {
103         hint_ = value;
104         this->notify_parent();
105     }
106 
107     /// Return the size hint currently being used.
hint() const108     std::size_t hint() const { return hint_; }
109 
110     /// Set the minimum length that the owning Widget should be.
min_size(std::size_t value)111     void min_size(std::size_t value) {
112         min_ = value;
113         this->notify_parent();
114     }
115 
116     /// Return the minimum length currently set.
min_size() const117     std::size_t min_size() const { return min_; }
118 
119     /// Set the maximum length/height that the owning Widget can be.
max_size(std::size_t value)120     void max_size(std::size_t value) {
121         max_ = value;
122         this->notify_parent();
123     }
124 
125     /// Return the maximum length currently set.
max_size() const126     std::size_t max_size() const { return max_; }
127 
128    private:
129     Size_policy::Type type_{Type::Ignored};
130     std::size_t stretch_{1};
131     std::size_t hint_{0};
132     std::size_t min_{0};
133     std::size_t max_{std::numeric_limits<std::size_t>::max()};
134     Widget* owner_;
135 
136     /// Post a Child_polished_event to the parent of owner_.
137     void notify_parent() const;
138 };
139 
140 }  // namespace cppurses
141 #endif  // CPPURSES_WIDGET_SIZE_POLICY_HPP
142