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