1 /*
2  *
3  * Copyright 2019, The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef LIBTEEUI_BUTTON_H_
19 #define LIBTEEUI_BUTTON_H_
20 
21 #include "utils.h"
22 
23 // #define DRAW_DEBUG_MARKERS
24 
25 namespace teeui {
26 
27 class ButtonImpl {
28 
29   public:
30     struct ConvexObjectInfo {
31         const PxPoint* begin;
32         const PxPoint* end;
33     };
34 
ButtonImpl()35     ButtonImpl()
36         : radius_(0), color_(0), convexObjectColor_(0), roundTopLeft_(false), roundTopRight_(false),
37           roundBottomLeft_(false), roundBottomRight_(false) {}
ButtonImpl(pxs radius,Color color,Color convexObjectColor,bool roundTopLeft,bool roundTopRight,bool roundBottomLeft,bool roundBottomRight)38     ButtonImpl(pxs radius, Color color, Color convexObjectColor, bool roundTopLeft,
39                bool roundTopRight, bool roundBottomLeft, bool roundBottomRight)
40         : radius_(radius), color_(color), convexObjectColor_(convexObjectColor),
41           roundTopLeft_(roundTopLeft), roundTopRight_(roundTopRight),
42           roundBottomLeft_(roundBottomLeft), roundBottomRight_(roundBottomRight) {}
43 
setColor(Color color)44     void setColor(Color color) { color_ = color; }
setConvexObjectColor(Color color)45     void setConvexObjectColor(Color color) { convexObjectColor_ = color; }
46 
47     Error draw(const PixelDrawer& drawPixel, const Box<pxs>& bounds,
48                const ConvexObjectInfo* coBegin, const ConvexObjectInfo* coEnd);
49 
50   private:
51     pxs radius_;
52     Color color_;
53     Color convexObjectColor_;
54     bool roundTopLeft_;
55     bool roundTopRight_;
56     bool roundBottomLeft_;
57     bool roundBottomRight_;
58 };
59 
60 /**
61  * Button is a LayoutElement and should be used as second argument in the BEGIN_ELEMENT() macro.
62  * The template argument Derived is the new class derived from Button, that is created by the
63  * BEGIN_ELEMENT() macro. The arguments convexElemCount and convexObjectCapacity denote the number
64  * of convex objects and the capacity (maximum number of vertexes) each of the objects should have.
65  * This is used to reserve enough space at compile time.
66  */
67 template <typename Derived, typename convexElemCount = std::integral_constant<size_t, 0>,
68           typename convexObjectCapacity = std::integral_constant<size_t, 10>>
69 class Button : public LayoutElement<Derived>, public ButtonImpl {
70   public:
71     static const constexpr bool button_round_top_left = false;
72     static const constexpr bool button_round_top_right = false;
73     static const constexpr bool button_round_bottom_left = false;
74     static const constexpr bool button_round_bottom_right = false;
75     static const constexpr std::tuple<> button_drawable_objects = {};
76     static const constexpr Color button_drawable_object_color = 0xff000000;
77 
78   private:
79     ConvexObject<convexObjectCapacity::value> convex_objects_[convexElemCount::value];
80 
81   public:
82     Button() = default;
83     template <typename Context>
Button(const Context & context)84     explicit Button(const Context& context)
85         : LayoutElement<Derived>(context),
86           ButtonImpl(context = Derived::button_radius, context = Derived::button_color,
87                      context = Derived::button_drawable_object_color,
88                      Derived::button_round_top_left, Derived::button_round_top_right,
89                      Derived::button_round_bottom_left, Derived::button_round_bottom_right) {
90         static_assert(
91             convexElemCount::value >=
92                 std::tuple_size<decltype(Derived::button_drawable_objects)>::value,
93             "Reserved convex element count must be greater or equal to the number of given convex "
94             "objects. Set count by passing ConvexObjectCount(n) to BEGIN_ELEMENT as third "
95             "argument");
96         initConvexObjectArray(context, convex_objects_, Derived::button_drawable_objects);
97     }
98 
draw(const PixelDrawer & drawPixel)99     Error draw(const PixelDrawer& drawPixel) {
100         constexpr const size_t convex_object_count =
101             std::tuple_size<decltype(Derived::button_drawable_objects)>::value;
102         ButtonImpl::ConvexObjectInfo coInfo[convex_object_count];
103         for (size_t i = 0; i < convex_object_count; ++i) {
104             coInfo[i].begin = convex_objects_[i].begin();
105             coInfo[i].end = convex_objects_[i].end();
106         }
107         return ButtonImpl::draw(drawPixel, this->bounds_, &coInfo[0], &coInfo[convex_object_count]);
108     }
109 };
110 
111 }  //  namespace teeui
112 
113 #define CornerRadius(radius) static const constexpr auto button_radius = radius
114 
115 #define ButtonColor(color) static const constexpr auto button_color = color
116 
117 #define RoundTopLeft static const constexpr bool button_round_top_left = true
118 #define RoundTopRight static const constexpr bool button_round_top_right = true
119 #define RoundBottomLeft static const constexpr bool button_round_bottom_left = true
120 #define RoundBottomRight static const constexpr bool button_round_bottom_right = true
121 
122 /*
123  * ConvexObjecCount may be passed to BEGIN_ELEMENT as third argument to layout elements that
124  * draw convex objects, such as teeui::Button. It informs the underlying implementation
125  * how much memory to reserve for convex objects.
126  */
127 #define ConvexObjectCount(n) std::integral_constant<size_t, n>
128 
129 #define ConvexObjects(convex_objects)                                                              \
130     static constexpr const auto button_drawable_objects = convex_objects
131 
132 #define ConvexObjectColor(color) static constexpr const auto button_drawable_object_color = color
133 
134 #endif  // LIBTEEUI_BUTTON_H_
135