1 /**
2 * @file lv_led.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_led_private.h"
10 #include "../../core/lv_obj_private.h"
11 #include "../../core/lv_obj_class_private.h"
12
13 #if LV_USE_LED
14
15 #include "../../misc/lv_assert.h"
16 #include "../../themes/lv_theme.h"
17 #include "../../misc/lv_color.h"
18
19 /*********************
20 * DEFINES
21 *********************/
22 #define MY_CLASS (&lv_led_class)
23
24 /**********************
25 * TYPEDEFS
26 **********************/
27
28 /**********************
29 * STATIC PROTOTYPES
30 **********************/
31 static void lv_led_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
32 static void lv_led_event(const lv_obj_class_t * class_p, lv_event_t * e);
33
34 /**********************
35 * STATIC VARIABLES
36 **********************/
37
38 const lv_obj_class_t lv_led_class = {
39 .base_class = &lv_obj_class,
40 .constructor_cb = lv_led_constructor,
41 .width_def = LV_DPI_DEF / 5,
42 .height_def = LV_DPI_DEF / 5,
43 .event_cb = lv_led_event,
44 .instance_size = sizeof(lv_led_t),
45 .name = "led",
46 };
47
48 /**********************
49 * MACROS
50 **********************/
51
52 /**********************
53 * GLOBAL FUNCTIONS
54 **********************/
55
lv_led_create(lv_obj_t * parent)56 lv_obj_t * lv_led_create(lv_obj_t * parent)
57 {
58 LV_LOG_INFO("begin");
59 lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
60 lv_obj_class_init_obj(obj);
61 return obj;
62 }
63
64 /*=====================
65 * Setter functions
66 *====================*/
67
lv_led_set_color(lv_obj_t * obj,lv_color_t color)68 void lv_led_set_color(lv_obj_t * obj, lv_color_t color)
69 {
70 LV_ASSERT_OBJ(obj, MY_CLASS);
71
72 lv_led_t * led = (lv_led_t *)obj;
73 led->color = color;
74 lv_obj_invalidate(obj);
75 }
76
lv_led_set_brightness(lv_obj_t * obj,uint8_t bright)77 void lv_led_set_brightness(lv_obj_t * obj, uint8_t bright)
78 {
79 LV_ASSERT_OBJ(obj, MY_CLASS);
80
81 lv_led_t * led = (lv_led_t *)obj;
82 if(led->bright == bright) return;
83
84 led->bright = LV_CLAMP(LV_LED_BRIGHT_MIN, bright, LV_LED_BRIGHT_MAX);
85
86 /*Invalidate the object there fore it will be redrawn*/
87 lv_obj_invalidate(obj);
88 }
89
lv_led_on(lv_obj_t * led)90 void lv_led_on(lv_obj_t * led)
91 {
92 lv_led_set_brightness(led, LV_LED_BRIGHT_MAX);
93 }
94
lv_led_off(lv_obj_t * led)95 void lv_led_off(lv_obj_t * led)
96 {
97 lv_led_set_brightness(led, LV_LED_BRIGHT_MIN);
98 }
99
lv_led_toggle(lv_obj_t * obj)100 void lv_led_toggle(lv_obj_t * obj)
101 {
102 uint8_t bright = lv_led_get_brightness(obj);
103 if(bright > (LV_LED_BRIGHT_MIN + LV_LED_BRIGHT_MAX) >> 1)
104 lv_led_off(obj);
105 else
106 lv_led_on(obj);
107 }
108
109 /*=====================
110 * Getter functions
111 *====================*/
112
lv_led_get_brightness(const lv_obj_t * obj)113 uint8_t lv_led_get_brightness(const lv_obj_t * obj)
114 {
115 LV_ASSERT_OBJ(obj, MY_CLASS);
116
117 lv_led_t * led = (lv_led_t *)obj;
118 return led->bright;
119 }
120
121 /**********************
122 * STATIC FUNCTIONS
123 **********************/
124
lv_led_constructor(const lv_obj_class_t * class_p,lv_obj_t * obj)125 static void lv_led_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
126 {
127 LV_UNUSED(class_p);
128 lv_led_t * led = (lv_led_t *)obj;
129 led->color = lv_theme_get_color_primary(obj);
130 led->bright = LV_LED_BRIGHT_MAX;
131 }
132
lv_led_event(const lv_obj_class_t * class_p,lv_event_t * e)133 static void lv_led_event(const lv_obj_class_t * class_p, lv_event_t * e)
134 {
135 LV_UNUSED(class_p);
136
137 lv_result_t res;
138
139 /* Call the ancestor's event handler */
140 lv_event_code_t code = lv_event_get_code(e);
141 if(code != LV_EVENT_DRAW_MAIN && code != LV_EVENT_DRAW_MAIN_END) {
142 res = lv_obj_event_base(MY_CLASS, e);
143 if(res != LV_RESULT_OK) return;
144 }
145
146 lv_obj_t * obj = lv_event_get_current_target(e);
147 if(code == LV_EVENT_DRAW_MAIN) {
148 /*Make darker colors in a temporary style according to the brightness*/
149 lv_led_t * led = (lv_led_t *)obj;
150 lv_layer_t * layer = lv_event_get_layer(e);
151
152 lv_draw_rect_dsc_t rect_dsc;
153 lv_draw_rect_dsc_init(&rect_dsc);
154 rect_dsc.base.layer = layer;
155 lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &rect_dsc);
156
157 /*Use the original colors brightness to modify color->led*/
158 rect_dsc.bg_color = lv_color_mix(led->color, lv_color_black(), lv_color_brightness(rect_dsc.bg_color));
159 rect_dsc.bg_grad.stops[0].color = lv_color_mix(led->color, lv_color_black(),
160 lv_color_brightness(rect_dsc.bg_grad.stops[0].color));
161 rect_dsc.bg_grad.stops[1].color = lv_color_mix(led->color, lv_color_black(),
162 lv_color_brightness(rect_dsc.bg_grad.stops[1].color));
163 rect_dsc.shadow_color = lv_color_mix(led->color, lv_color_black(), lv_color_brightness(rect_dsc.shadow_color));
164 rect_dsc.border_color = lv_color_mix(led->color, lv_color_black(), lv_color_brightness(rect_dsc.border_color));
165 rect_dsc.outline_color = lv_color_mix(led->color, lv_color_black(), lv_color_brightness(rect_dsc.outline_color));
166
167 /*Mix. the color with black proportionally with brightness*/
168 rect_dsc.bg_color = lv_color_mix(rect_dsc.bg_color, lv_color_black(), led->bright);
169 rect_dsc.bg_grad.stops[0].color = lv_color_mix(rect_dsc.bg_grad.stops[0].color, lv_color_black(), led->bright);
170 rect_dsc.bg_grad.stops[1].color = lv_color_mix(rect_dsc.bg_grad.stops[1].color, lv_color_black(), led->bright);
171 rect_dsc.border_color = lv_color_mix(rect_dsc.border_color, lv_color_black(), led->bright);
172 rect_dsc.shadow_color = lv_color_mix(rect_dsc.shadow_color, lv_color_black(), led->bright);
173 rect_dsc.outline_color = lv_color_mix(rect_dsc.outline_color, lv_color_black(), led->bright);
174
175 /*Set the current shadow width according to brightness proportionally between LV_LED_BRIGHT_OFF
176 * and LV_LED_BRIGHT_ON*/
177 rect_dsc.shadow_width = ((led->bright - LV_LED_BRIGHT_MIN) * rect_dsc.shadow_width) /
178 (LV_LED_BRIGHT_MAX - LV_LED_BRIGHT_MIN);
179 rect_dsc.shadow_spread = ((led->bright - LV_LED_BRIGHT_MIN) * rect_dsc.shadow_spread) /
180 (LV_LED_BRIGHT_MAX - LV_LED_BRIGHT_MIN);
181
182 lv_draw_rect(layer, &rect_dsc, &obj->coords);
183 }
184 }
185
186 #endif
187