1 /**
2 * @file lv_calendar_obj_dropdown.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "../../core/lv_obj_class_private.h"
10 #include "lv_calendar_header_dropdown.h"
11 #if LV_USE_CALENDAR && LV_USE_CALENDAR_HEADER_DROPDOWN
12
13 #include "lv_calendar.h"
14 #include "../dropdown/lv_dropdown.h"
15 #include "../../layouts/flex/lv_flex.h"
16
17 /*********************
18 * DEFINES
19 *********************/
20
21 /**********************
22 * TYPEDEFS
23 **********************/
24
25 /**********************
26 * STATIC PROTOTYPES
27 **********************/
28 static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
29 static void year_event_cb(lv_event_t * e);
30 static void month_event_cb(lv_event_t * e);
31 static void value_changed_event_cb(lv_event_t * e);
32
33 /**********************
34 * STATIC VARIABLES
35 **********************/
36
37 const lv_obj_class_t lv_calendar_header_dropdown_class = {
38 .base_class = &lv_obj_class,
39 .width_def = LV_PCT(100),
40 .height_def = LV_SIZE_CONTENT,
41 .constructor_cb = my_constructor,
42 .name = "calendar-header-dropdown",
43 };
44
45 static const char * month_list = "01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12";
46 static const char * year_list = {
47 "2025\n2024\n2023\n2022\n2021\n"
48 "2020\n2019\n2018\n2017\n2016\n2015\n2014\n2013\n2012\n2011\n2010\n2009\n2008\n2007\n2006\n2005\n2004\n2003\n2002\n2001\n"
49 "2000\n1999\n1998\n1997\n1996\n1995\n1994\n1993\n1992\n1991\n1990\n1989\n1988\n1987\n1986\n1985\n1984\n1983\n1982\n1981\n"
50 "1980\n1979\n1978\n1977\n1976\n1975\n1974\n1973\n1972\n1971\n1970\n1969\n1968\n1967\n1966\n1965\n1964\n1963\n1962\n1961\n"
51 "1960\n1959\n1958\n1957\n1956\n1955\n1954\n1953\n1952\n1951\n1950\n1949\n1948\n1947\n1946\n1945\n1944\n1943\n1942\n1941\n"
52 "1940\n1939\n1938\n1937\n1936\n1935\n1934\n1933\n1932\n1931\n1930\n1929\n1928\n1927\n1926\n1925\n1924\n1923\n1922\n1921\n"
53 "1920\n1919\n1918\n1917\n1916\n1915\n1914\n1913\n1912\n1911\n1910\n1909\n1908\n1907\n1906\n1905\n1904\n1903\n1902\n1901"
54 };
55
56 /**********************
57 * MACROS
58 **********************/
59
60 /**********************
61 * GLOBAL FUNCTIONS
62 **********************/
63
lv_calendar_header_dropdown_create(lv_obj_t * parent)64 lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent)
65 {
66 lv_obj_t * obj = lv_obj_class_create_obj(&lv_calendar_header_dropdown_class, parent);
67 lv_obj_class_init_obj(obj);
68
69 return obj;
70 }
71
lv_calendar_header_dropdown_set_year_list(lv_obj_t * parent,const char * years_list)72 void lv_calendar_header_dropdown_set_year_list(lv_obj_t * parent, const char * years_list)
73 {
74 /* Search for the header dropdown */
75 lv_obj_t * header = lv_obj_get_child_by_type(parent, 0, &lv_calendar_header_dropdown_class);
76 if(NULL == header) {
77 /* Header not found */
78 return;
79 }
80
81 /* Search for the year dropdown
82 * Index is 0 because in the header dropdown constructor the year dropdown (year_dd)
83 * is the first created child of the header */
84 const int32_t year_dropdown_index = 0;
85 lv_obj_t * year_dropdown = lv_obj_get_child_by_type(header, year_dropdown_index, &lv_dropdown_class);
86 if(NULL == year_dropdown) {
87 /* year dropdown not found */
88 return;
89 }
90
91 lv_dropdown_clear_options(year_dropdown);
92 lv_dropdown_set_options(year_dropdown, years_list);
93
94 lv_obj_invalidate(parent);
95 }
96
97 /**********************
98 * STATIC FUNCTIONS
99 **********************/
100
my_constructor(const lv_obj_class_t * class_p,lv_obj_t * obj)101 static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
102 {
103 LV_TRACE_OBJ_CREATE("begin");
104
105 LV_UNUSED(class_p);
106
107 lv_obj_t * calendar = lv_obj_get_parent(obj);
108 lv_obj_move_to_index(obj, 0);
109 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);
110
111 lv_obj_t * year_dd = lv_dropdown_create(obj);
112 lv_dropdown_set_options(year_dd, year_list);
113 lv_obj_add_event_cb(year_dd, year_event_cb, LV_EVENT_VALUE_CHANGED, calendar);
114 lv_obj_set_flex_grow(year_dd, 1);
115
116 lv_obj_t * month_dd = lv_dropdown_create(obj);
117 lv_dropdown_set_options(month_dd, month_list);
118 lv_obj_add_event_cb(month_dd, month_event_cb, LV_EVENT_VALUE_CHANGED, calendar);
119 lv_obj_set_flex_grow(month_dd, 1);
120
121 lv_obj_add_event_cb(obj, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
122 /*Refresh the drop downs*/
123 lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
124 }
125
month_event_cb(lv_event_t * e)126 static void month_event_cb(lv_event_t * e)
127 {
128 lv_obj_t * dropdown = lv_event_get_current_target(e);
129 lv_obj_t * calendar = lv_event_get_user_data(e);
130
131 uint32_t sel = lv_dropdown_get_selected(dropdown);
132
133 const lv_calendar_date_t * d;
134 d = lv_calendar_get_showed_date(calendar);
135 lv_calendar_date_t newd = *d;
136 newd.month = sel + 1;
137
138 lv_calendar_set_month_shown(calendar, newd.year, newd.month);
139 }
140
year_event_cb(lv_event_t * e)141 static void year_event_cb(lv_event_t * e)
142 {
143 lv_obj_t * dropdown = lv_event_get_current_target(e);
144 lv_obj_t * calendar = lv_event_get_user_data(e);
145
146 uint32_t sel = lv_dropdown_get_selected(dropdown);
147
148 const lv_calendar_date_t * d;
149 d = lv_calendar_get_showed_date(calendar);
150
151 /* Get the first year on the options list
152 * NOTE: Assumes the first 4 digits in the option list are numbers */
153 const char * year_p = lv_dropdown_get_options(dropdown);
154 const uint32_t year = (year_p[0] - '0') * 1000 + (year_p[1] - '0') * 100 + (year_p[2] - '0') * 10 +
155 (year_p[3] - '0');
156
157 lv_calendar_date_t newd = *d;
158 newd.year = year - sel;
159
160 lv_calendar_set_month_shown(calendar, newd.year, newd.month);
161 }
162
value_changed_event_cb(lv_event_t * e)163 static void value_changed_event_cb(lv_event_t * e)
164 {
165 lv_obj_t * header = lv_event_get_current_target(e);
166 lv_obj_t * calendar = lv_obj_get_parent(header);
167 const lv_calendar_date_t * cur_date = lv_calendar_get_showed_date(calendar);
168
169 lv_obj_t * year_dd = lv_obj_get_child(header, 0);
170
171 /* Get the first year on the options list
172 * NOTE: Assumes the first 4 digits in the option list are numbers */
173 const char * year_p = lv_dropdown_get_options(year_dd);
174 const uint32_t year = (year_p[0] - '0') * 1000 + (year_p[1] - '0') * 100 + (year_p[2] - '0') * 10 +
175 (year_p[3] - '0');
176
177 lv_dropdown_set_selected(year_dd, year - cur_date->year, LV_ANIM_OFF);
178
179 lv_obj_t * month_dd = lv_obj_get_child(header, 1);
180 lv_dropdown_set_selected(month_dd, cur_date->month - 1, LV_ANIM_OFF);
181 }
182
183 #endif /*LV_USE_CALENDAR_HEADER_ARROW*/
184