1 /**
2  * @file lv_calendar_header_arrow.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "../../core/lv_obj_class_private.h"
10 #include "lv_calendar_header_arrow.h"
11 #if LV_USE_CALENDAR && LV_USE_CALENDAR_HEADER_ARROW
12 
13 #include "lv_calendar.h"
14 #include "../button/lv_button.h"
15 #include "../label/lv_label.h"
16 #include "../../layouts/flex/lv_flex.h"
17 #include "../../misc/lv_assert.h"
18 
19 /*********************
20  *      DEFINES
21  *********************/
22 
23 /**********************
24  *      TYPEDEFS
25  **********************/
26 
27 /**********************
28  *  STATIC PROTOTYPES
29  **********************/
30 static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
31 static void month_event_cb(lv_event_t * e);
32 static void value_changed_event_cb(lv_event_t * e);
33 
34 /**********************
35  *  STATIC VARIABLES
36  **********************/
37 
38 const lv_obj_class_t lv_calendar_header_arrow_class = {
39     .base_class = &lv_obj_class,
40     .constructor_cb = my_constructor,
41     .width_def = LV_PCT(100),
42     .height_def = LV_DPI_DEF / 3,
43     .name = "calendar-header-arrow",
44 };
45 
46 static const char * month_names_def[12] = LV_CALENDAR_DEFAULT_MONTH_NAMES;
47 
48 /**********************
49  *      MACROS
50  **********************/
51 
52 /**********************
53  *   GLOBAL FUNCTIONS
54  **********************/
55 
lv_calendar_header_arrow_create(lv_obj_t * parent)56 lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent)
57 {
58     lv_obj_t * obj = lv_obj_class_create_obj(&lv_calendar_header_arrow_class, parent);
59     lv_obj_class_init_obj(obj);
60     return obj;
61 }
62 
63 /**********************
64  *  STATIC FUNCTIONS
65  **********************/
66 
my_constructor(const lv_obj_class_t * class_p,lv_obj_t * obj)67 static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
68 {
69     LV_TRACE_OBJ_CREATE("begin");
70 
71     LV_UNUSED(class_p);
72 
73     lv_obj_move_to_index(obj, 0);
74 
75     lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);
76     lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START);
77 
78     lv_obj_t * mo_prev = lv_button_create(obj);
79     lv_obj_set_style_bg_image_src(mo_prev, LV_SYMBOL_LEFT, 0);
80     lv_obj_set_height(mo_prev, lv_pct(100));
81     lv_obj_update_layout(mo_prev);
82     int32_t btn_size = lv_obj_get_height(mo_prev);
83     lv_obj_set_width(mo_prev, btn_size);
84 
85     lv_obj_add_event_cb(mo_prev, month_event_cb, LV_EVENT_CLICKED, NULL);
86     lv_obj_remove_flag(mo_prev, LV_OBJ_FLAG_CLICK_FOCUSABLE);
87 
88     lv_obj_t * label = lv_label_create(obj);
89     lv_label_set_long_mode(label, LV_LABEL_LONG_MODE_SCROLL_CIRCULAR);
90     lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
91     lv_obj_set_flex_grow(label, 1);
92 
93     lv_obj_t * mo_next = lv_button_create(obj);
94     lv_obj_set_style_bg_image_src(mo_next, LV_SYMBOL_RIGHT, 0);
95     lv_obj_set_size(mo_next, btn_size, btn_size);
96 
97     lv_obj_add_event_cb(mo_next, month_event_cb, LV_EVENT_CLICKED, NULL);
98     lv_obj_remove_flag(mo_next, LV_OBJ_FLAG_CLICK_FOCUSABLE);
99 
100     lv_obj_add_event_cb(obj, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
101     /*Refresh the drop downs*/
102     lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
103 }
104 
month_event_cb(lv_event_t * e)105 static void month_event_cb(lv_event_t * e)
106 {
107     lv_obj_t * btn = lv_event_get_current_target(e);
108 
109     lv_obj_t * header = lv_obj_get_parent(btn);
110     lv_obj_t * calendar = lv_obj_get_parent(header);
111 
112     const lv_calendar_date_t * d;
113     d = lv_calendar_get_showed_date(calendar);
114     lv_calendar_date_t newd = *d;
115 
116     LV_ASSERT_FORMAT_MSG(newd.year >= 0 && newd.month >= 1 && newd.month <= 12,
117                          "Invalid date: %d-%d", newd.year, newd.month);
118 
119     /*The last child is the right button*/
120     if(lv_obj_get_child(header, 0) == btn) {
121         if(newd.month == 1) {
122             newd.month = 12;
123             newd.year --;
124         }
125         else {
126             newd.month --;
127         }
128     }
129     else {
130         if(newd.month == 12) {
131             newd.month = 1;
132             newd.year ++;
133         }
134         else {
135             newd.month ++;
136         }
137     }
138 
139     lv_calendar_set_month_shown(calendar, newd.year, newd.month);
140 
141     lv_obj_t * label = lv_obj_get_child(header, 1);
142     lv_label_set_text_fmt(label, "%d %s", newd.year, month_names_def[newd.month - 1]);
143 }
144 
value_changed_event_cb(lv_event_t * e)145 static void value_changed_event_cb(lv_event_t * e)
146 {
147     lv_obj_t * header = lv_event_get_current_target(e);
148     lv_obj_t * calendar = lv_obj_get_parent(header);
149 
150     const lv_calendar_date_t * date = lv_calendar_get_showed_date(calendar);
151     LV_ASSERT_FORMAT_MSG(date->year >= 0 && date->month >= 1 && date->month <= 12,
152                          "Invalid date: %d-%d", date->year, date->month);
153 
154     lv_obj_t * label = lv_obj_get_child(header, 1);
155     lv_label_set_text_fmt(label, "%d %s", date->year, month_names_def[date->month - 1]);
156 }
157 
158 #endif /*LV_USE_CALENDAR_HEADER_ARROW*/
159