acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
lv_line.c (5229B)
1 /** 2 * @file lv_line.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 #include "lv_line.h" 10 11 #if LV_USE_LINE != 0 12 #include "../misc/lv_assert.h" 13 #include "../draw/lv_draw.h" 14 #include "../misc/lv_math.h" 15 #include <stdbool.h> 16 #include <stdint.h> 17 #include <string.h> 18 19 /********************* 20 * DEFINES 21 *********************/ 22 #define MY_CLASS &lv_line_class 23 24 /********************** 25 * TYPEDEFS 26 **********************/ 27 28 /********************** 29 * STATIC PROTOTYPES 30 **********************/ 31 static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); 32 static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e); 33 34 /********************** 35 * STATIC VARIABLES 36 **********************/ 37 const lv_obj_class_t lv_line_class = { 38 .constructor_cb = lv_line_constructor, 39 .event_cb = lv_line_event, 40 .width_def = LV_SIZE_CONTENT, 41 .height_def = LV_SIZE_CONTENT, 42 .instance_size = sizeof(lv_line_t), 43 .base_class = &lv_obj_class 44 }; 45 46 /********************** 47 * MACROS 48 **********************/ 49 50 /********************** 51 * GLOBAL FUNCTIONS 52 **********************/ 53 54 lv_obj_t * lv_line_create(lv_obj_t * parent) 55 { 56 LV_LOG_INFO("begin"); 57 lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); 58 lv_obj_class_init_obj(obj); 59 return obj; 60 } 61 62 /*===================== 63 * Setter functions 64 *====================*/ 65 66 void lv_line_set_points(lv_obj_t * obj, const lv_point_t points[], uint16_t point_num) 67 { 68 LV_ASSERT_OBJ(obj, MY_CLASS); 69 70 lv_line_t * line = (lv_line_t *)obj; 71 line->point_array = points; 72 line->point_num = point_num; 73 74 lv_obj_refresh_self_size(obj); 75 76 lv_obj_invalidate(obj); 77 } 78 79 void lv_line_set_y_invert(lv_obj_t * obj, bool en) 80 { 81 LV_ASSERT_OBJ(obj, MY_CLASS); 82 83 lv_line_t * line = (lv_line_t *)obj; 84 if(line->y_inv == en) return; 85 86 line->y_inv = en ? 1U : 0U; 87 88 lv_obj_invalidate(obj); 89 } 90 91 /*===================== 92 * Getter functions 93 *====================*/ 94 95 bool lv_line_get_y_invert(const lv_obj_t * obj) 96 { 97 LV_ASSERT_OBJ(obj, MY_CLASS); 98 99 lv_line_t * line = (lv_line_t *)obj; 100 101 return line->y_inv == 1U; 102 } 103 104 /********************** 105 * STATIC FUNCTIONS 106 **********************/ 107 108 static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) 109 { 110 LV_UNUSED(class_p); 111 LV_TRACE_OBJ_CREATE("begin"); 112 113 lv_line_t * line = (lv_line_t *)obj; 114 115 line->point_num = 0; 116 line->point_array = NULL; 117 line->y_inv = 0; 118 119 lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); 120 121 LV_TRACE_OBJ_CREATE("finished"); 122 } 123 124 static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e) 125 { 126 LV_UNUSED(class_p); 127 128 lv_res_t res; 129 130 /*Call the ancestor's event handler*/ 131 res = lv_obj_event_base(MY_CLASS, e); 132 if(res != LV_RES_OK) return; 133 134 lv_event_code_t code = lv_event_get_code(e); 135 lv_obj_t * obj = lv_event_get_target(e); 136 137 if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) { 138 /*The corner of the skew lines is out of the intended area*/ 139 lv_coord_t line_width = lv_obj_get_style_line_width(obj, LV_PART_MAIN); 140 lv_coord_t * s = lv_event_get_param(e); 141 if(*s < line_width) *s = line_width; 142 } 143 else if(code == LV_EVENT_GET_SELF_SIZE) { 144 lv_line_t * line = (lv_line_t *)obj; 145 146 if(line->point_num == 0 || line->point_array == NULL) return; 147 148 lv_point_t * p = lv_event_get_param(e); 149 lv_coord_t w = 0; 150 lv_coord_t h = 0; 151 152 uint16_t i; 153 for(i = 0; i < line->point_num; i++) { 154 w = LV_MAX(line->point_array[i].x, w); 155 h = LV_MAX(line->point_array[i].y, h); 156 } 157 158 lv_coord_t line_width = lv_obj_get_style_line_width(obj, LV_PART_MAIN); 159 w += line_width; 160 h += line_width; 161 p->x = w; 162 p->y = h; 163 } 164 else if(code == LV_EVENT_DRAW_MAIN) { 165 lv_line_t * line = (lv_line_t *)obj; 166 lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e); 167 168 if(line->point_num == 0 || line->point_array == NULL) return; 169 170 lv_area_t area; 171 lv_obj_get_coords(obj, &area); 172 lv_coord_t x_ofs = area.x1 - lv_obj_get_scroll_x(obj); 173 lv_coord_t y_ofs = area.y1 - lv_obj_get_scroll_y(obj); 174 lv_coord_t h = lv_obj_get_height(obj); 175 176 lv_draw_line_dsc_t line_dsc; 177 lv_draw_line_dsc_init(&line_dsc); 178 lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &line_dsc); 179 180 /*Read all points and draw the lines*/ 181 uint16_t i; 182 for(i = 0; i < line->point_num - 1; i++) { 183 lv_point_t p1; 184 lv_point_t p2; 185 p1.x = line->point_array[i].x + x_ofs; 186 p2.x = line->point_array[i + 1].x + x_ofs; 187 188 if(line->y_inv == 0) { 189 p1.y = line->point_array[i].y + y_ofs; 190 p2.y = line->point_array[i + 1].y + y_ofs; 191 } 192 else { 193 p1.y = h - line->point_array[i].y + y_ofs; 194 p2.y = h - line->point_array[i + 1].y + y_ofs; 195 } 196 lv_draw_line(draw_ctx, &line_dsc, &p1, &p2); 197 line_dsc.round_start = 0; /*Draw the rounding only on the end points after the first line*/ 198 } 199 } 200 } 201 #endif