/*
 *******************************************************************************
 *  Copyright (c) 2010-2022 VATICS(KNERON) Inc. All rights reserved.
 *
 *  +-----------------------------------------------------------------+
 *  | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
 *  | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH  |
 *  | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
 *  | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE   |
 *  | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE   |
 *  | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.        |
 *  |                                                                 |
 *  | THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT   |
 *  | ANY PRIOR NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY |
 *  | VATICS(KNERON) INC.                                             |
 *  +-----------------------------------------------------------------+
 *
 *******************************************************************************
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <signal.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>

#include "lvgl/lvgl.h"
#include "lvgl/custom/lv_custom.h"

#if defined(PC_SIMULATOR)
#include "lv_drivers/indev/keyboard.h"
#define SAMPLE_PICTURE "cup.packed.rgb"
#else
#include "lv_drivers/indev/evdev.h"
#include "vmf/yuv_rgb_cvt.h"
#define SAMPLE_PICTURE "cup.planar.420.yuv"
#endif

#define CANVAS_WIDTH  200
#define CANVAS_HEIGHT  150

extern lv_point_t btn_positon[4];
lv_obj_t * ta1;
static uint8_t *buf = NULL;

static void exit_handler(void)
{
	if (buf)
		free(buf);
}

void lv_ex_clean_display(void)
{
	lv_obj_clean(lv_scr_act());
}

void lv_ex_font(void)
{
	static lv_style_t style;
	lv_obj_t *scr = NULL;
	lv_obj_t *label = NULL;

	LV_FONT_DECLARE(jianyaya_20)

	lv_style_copy(&style, &lv_style_pretty);
	style.text.font = &jianyaya_20;

	scr = lv_disp_get_scr_act(NULL);
	lv_obj_set_style(scr, &style);

	label = lv_label_create(scr, NULL);
	lv_label_set_text(label, "音乐");
	lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
}

void lv_ex_demo(void)
{
	const char *g_aszBtnTxt[4] = { "button0", "img_btn_red", "img_btn_green", "button3" };

	static lv_style_t button_style_rel;
	static lv_style_t button_style_pre;
	uint32_t btn_w = lv_scr_get_hor_res() / 2;
	uint32_t btn_h = lv_scr_get_ver_res() / 8;

	// Init button styles
	lv_style_copy(&button_style_rel, &lv_style_btn_rel);
	lv_style_copy(&button_style_pre, &lv_style_btn_pr);
	button_style_rel.text.color = LV_COLOR_WHITE;
	button_style_pre.text.color = LV_COLOR_YELLOW;

	for (int i = 0; i < 4; i++) {
		lv_obj_t *btn = NULL;
		lv_obj_t *label = NULL;
		lv_area_t coords;
		uint32_t offset = btn_h * 2 + i * btn_h;

		// Init buttons
		btn = lv_btn_create(lv_scr_act(), NULL);
		lv_btn_set_style(btn, LV_BTN_STYLE_REL, &button_style_rel);
		lv_btn_set_style(btn, LV_BTN_STYLE_PR,  &button_style_pre);
		lv_obj_set_size(btn, btn_w, btn_h);
		lv_obj_align(btn, NULL, LV_ALIGN_IN_TOP_MID, 0, offset);
		lv_obj_get_coords(btn, &coords);
		btn_positon[i].x = (coords.x1 + coords.x2) >> 1;
		btn_positon[i].y = (coords.y1 + coords.y2) >> 1;
		// Init labels
		label = lv_label_create(btn, NULL);
		lv_label_set_text(label, g_aszBtnTxt[i]);
	}
}

void lv_ex_win_1(void)
{
	// Create a window
	lv_obj_t * win = lv_win_create(lv_scr_act(), NULL);
	lv_win_set_title(win, "Window title");	// Set the title

	//Add control button to the header
	lv_obj_t * close_btn = lv_win_add_btn(win, LV_SYMBOL_CLOSE);	// Add close button and use built-in close action
	lv_obj_set_event_cb(close_btn, lv_win_close_event_cb);
	lv_win_add_btn(win, LV_SYMBOL_SETTINGS);	// Add a setup button

	// Add some dummy content
	lv_obj_t * txt = lv_label_create(win, NULL);
	lv_label_set_text(txt, "This is the content of the window\n\n"
							"You can add control buttons to\n"
							"the window header\n\n"
							"The content area becomes automatically\n"
							"scrollable is it's large enough.\n\n"
							" You can scroll the content\n"
							"See the scroll bar on the right!");
}

void lv_ex_chart_1(void)
{
	lv_obj_t * chart;
	// Create a chart
	chart = lv_chart_create(lv_scr_act(), NULL);
	lv_obj_set_size(chart, 200, 150);
	lv_obj_align(chart, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_chart_set_type(chart, LV_CHART_TYPE_POINT | LV_CHART_TYPE_LINE);	// Show lines and points too
	lv_chart_set_series_opa(chart, LV_OPA_70); //Opacity of the data series
	lv_chart_set_series_width(chart, 4);	// Line width and point radious

	lv_chart_set_range(chart, 0, 100);

	// Add two data series
	lv_chart_series_t * ser1 = lv_chart_add_series(chart, LV_COLOR_RED);	
	lv_chart_series_t * ser2 = lv_chart_add_series(chart, LV_COLOR_GREEN);

	// Set the next points on 'dl1'
	lv_chart_set_next(chart, ser1, 10);
	lv_chart_set_next(chart, ser1, 10);
	lv_chart_set_next(chart, ser1, 10);
	lv_chart_set_next(chart, ser1, 10);
	lv_chart_set_next(chart, ser1, 10);
	lv_chart_set_next(chart, ser1, 10);
	lv_chart_set_next(chart, ser1, 10);
	lv_chart_set_next(chart, ser1, 30);
	lv_chart_set_next(chart, ser1, 70);
	lv_chart_set_next(chart, ser1, 90);

	// Directly set points on 'dl2'
	ser2->points[0] = 90;
	ser2->points[1] = 70;
	ser2->points[2] = 65;
	ser2->points[3] = 65;
	ser2->points[4] = 65;
	ser2->points[5] = 65;
	ser2->points[6] = 65;
	ser2->points[7] = 65;
	ser2->points[8] = 65;
	ser2->points[9] = 65;

	lv_chart_refresh(chart);	// Required after direct set
}

static void ddlist_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		char buf[32];
		lv_ddlist_get_selected_str(obj, buf, sizeof(buf));
		printf("Option: %s\n", buf);
	}
}

void lv_ex_ddlist_1(void)
{
	// Create a drop down list
	lv_obj_t * ddlist = lv_ddlist_create(lv_scr_act(), NULL);
	lv_ddlist_set_options(ddlist, "Apple\n"
								"Banana\n"
								"Orange\n"
								"Melon\n"
								"Grape\n"
								"Raspberry");

	lv_ddlist_set_fix_width(ddlist, 150);
	lv_ddlist_set_draw_arrow(ddlist, true);
	lv_obj_align(ddlist, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
	lv_obj_set_event_cb(ddlist, ddlist_event_handler);
}


static void calendar_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_CLICKED) {
		lv_calendar_date_t * date = lv_calendar_get_pressed_date(obj);
		if(date) {
			lv_calendar_set_today_date(obj, date);
		}
	}
}

void lv_ex_calendar_1(void)
{
	lv_obj_t  * calendar = lv_calendar_create(lv_scr_act(), NULL);
	lv_obj_set_size(calendar, 230, 230);
	lv_obj_align(calendar, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_event_cb(calendar, calendar_event_handler);

	// Set the today
	lv_calendar_date_t today;
	today.year = 2018;
	today.month = 10;
	today.day = 23;

	lv_calendar_set_today_date(calendar, &today);
	lv_calendar_set_showed_date(calendar, &today);

	// Highlight some days
	static lv_calendar_date_t highlihted_days[3]; // Only it's pointer will be saved so should be static
	highlihted_days[0].year = 2018;
	highlihted_days[0].month = 10;
	highlihted_days[0].day = 6;

	highlihted_days[1].year = 2018;
	highlihted_days[1].month = 10;
	highlihted_days[1].day = 11;

	highlihted_days[2].year = 2018;
	highlihted_days[2].month = 11;
	highlihted_days[2].day = 22;

	lv_calendar_set_highlighted_dates(calendar, highlihted_days, 3);
}

static void roller_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		char buf[32];
		lv_roller_get_selected_str(obj, buf, sizeof(buf));
		printf("Selected month: %s\n", buf);
	}
}

void lv_ex_roller_1(void)
{
	lv_obj_t *roller1 = lv_roller_create(lv_scr_act(), NULL);
	lv_roller_set_options(roller1,
						"January\n"
						"February\n"
						"March\n"
						"April\n"
						"May\n"
						"June\n"
						"July\n"
						"August\n"
						"September\n"
						"October\n"
						"November\n"
						"December",
						LV_ROLLER_MODE_INIFINITE);

	lv_roller_set_visible_row_count(roller1, 4);
	lv_obj_align(roller1, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_event_cb(roller1, roller_event_handler);
}

void lv_ex_preload_1(void)
{
	// Create a style for the Preloader
	static lv_style_t style;
	lv_style_copy(&style, &lv_style_plain);
	style.line.width = 10;	// 10 px thick arc
	style.line.color = lv_color_hex3(0x258);	// Blueish arc color

	style.body.border.color = lv_color_hex3(0xBBB);	// Gray background color
	style.body.border.width = 10;
	style.body.padding.left = 0;

	// Create a Preloader object
	lv_obj_t * preload = lv_preload_create(lv_scr_act(), NULL);
	lv_obj_set_size(preload, 100, 100);
	lv_obj_align(preload, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_preload_set_style(preload, LV_PRELOAD_STYLE_MAIN, &style);
}

void lv_ex_page_1(void)
{
	// Create a scroll bar style
	static lv_style_t style_sb;
	lv_style_copy(&style_sb, &lv_style_plain);
	style_sb.body.main_color = LV_COLOR_BLACK;
	style_sb.body.grad_color = LV_COLOR_BLACK;
	style_sb.body.border.color = LV_COLOR_WHITE;
	style_sb.body.border.width = 1;
	style_sb.body.border.opa = LV_OPA_70;
	style_sb.body.radius = LV_RADIUS_CIRCLE;
	style_sb.body.opa = LV_OPA_60;
	style_sb.body.padding.right = 3;
	style_sb.body.padding.bottom = 3;
	style_sb.body.padding.inner = 8;	// Scrollbar width

	// Create a page
	lv_obj_t * page = lv_page_create(lv_scr_act(), NULL);
	lv_obj_set_size(page, 150, 200);
	lv_obj_align(page, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_page_set_style(page, LV_PAGE_STYLE_SB, &style_sb);	// Set the scrollbar style

	// Create a label on the page
	lv_obj_t * label = lv_label_create(page, NULL);
	lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);	// Automatically break long lines
	lv_obj_set_width(label, lv_page_get_fit_width(page)); // Set the label width to max value to not show hor. scroll bars
	lv_label_set_text(label, "Lorem ipsum dolor sit amet, consectetur adipiscing elit,\n"
								"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"
								"Ut enim ad minim veniam, quis nostrud exercitation ullamco\n"
								"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure\n"
								"dolor in reprehenderit in voluptate velit esse cillum dolore\n"
								"eu fugiat nulla pariatur.\n"
								"Excepteur sint occaecat cupidatat non proident, sunt in culpa\n"
								"qui officia deserunt mollit anim id est laborum.");
}

static void mbox_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		printf("Button: %s\n", lv_mbox_get_active_btn_text(obj));
	}
}

void lv_ex_mbox_1(void)
{
	static const char * btns[] ={"Apply", "Close", ""};

	lv_obj_t * mbox1 = lv_mbox_create(lv_scr_act(), NULL);
	lv_mbox_set_text(mbox1, "A message box with two buttons.");
	lv_mbox_add_btns(mbox1, btns);
	lv_obj_set_width(mbox1, 200);
	lv_obj_set_event_cb(mbox1, mbox_event_handler);
	lv_obj_align(mbox1, NULL, LV_ALIGN_CENTER, 0, 0);	// Align to the corner
}

void lv_ex_lmeter_1(void)
{
	// Create a style for the line meter
	static lv_style_t style_lmeter;
	lv_style_copy(&style_lmeter, &lv_style_pretty_color);
	style_lmeter.line.width = 2;
	style_lmeter.line.color = LV_COLOR_SILVER;
	style_lmeter.body.main_color = lv_color_hex(0x91bfed);	// Light blue
	style_lmeter.body.grad_color = lv_color_hex(0x04386c);	// Dark blue
	style_lmeter.body.padding.left = 16;	// Line length

	// Create a line meter
	lv_obj_t * lmeter;
	lmeter = lv_lmeter_create(lv_scr_act(), NULL);
	lv_lmeter_set_range(lmeter, 0, 100);	// Set the range
	lv_lmeter_set_value(lmeter, 80);	// Set the current value
	lv_lmeter_set_scale(lmeter, 240, 31);	// Set the angle and number of lines
	lv_lmeter_set_style(lmeter, LV_LMETER_STYLE_MAIN, &style_lmeter);	// Apply the new style
	lv_obj_set_size(lmeter, 150, 150);
	lv_obj_align(lmeter, NULL, LV_ALIGN_CENTER, 0, 0);
}

static void list_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_CLICKED) {
		printf("Clicked: %s\n", lv_list_get_btn_text(obj));
	}
}

void lv_ex_list_1(void)
{
	// Create a list
	lv_obj_t * list1 = lv_list_create(lv_scr_act(), NULL);
	lv_obj_set_size(list1, 160, 200);
	lv_obj_align(list1, NULL, LV_ALIGN_CENTER, 0, 0);

	// Add buttons to the list

	lv_obj_t * list_btn;

	list_btn = lv_list_add_btn(list1, LV_SYMBOL_FILE, "New");
	lv_obj_set_event_cb(list_btn, list_event_handler);

	list_btn = lv_list_add_btn(list1, LV_SYMBOL_DIRECTORY, "Open");
	lv_obj_set_event_cb(list_btn, list_event_handler);

	list_btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, "Delete");
	lv_obj_set_event_cb(list_btn, list_event_handler);

	list_btn = lv_list_add_btn(list1, LV_SYMBOL_EDIT, "Edit");
	lv_obj_set_event_cb(list_btn, list_event_handler);

	list_btn = lv_list_add_btn(list1, LV_SYMBOL_SAVE, "Save");
	lv_obj_set_event_cb(list_btn, list_event_handler);
}

void lv_ex_line_1(void)
{
	// Create an array for the points of the line
	static lv_point_t line_points[] = { {5, 5}, {70, 70}, {120, 10}, {180, 60}, {240, 10} };

	// Create new style (thick dark blue)
	static lv_style_t style_line;
	lv_style_copy(&style_line, &lv_style_plain);
	style_line.line.color = LV_COLOR_MAKE(0x00, 0x3b, 0x75);
	style_line.line.width = 3;
	style_line.line.rounded = 1;

	// Copy the previous line and apply the new style
	lv_obj_t * line1;
	line1 = lv_line_create(lv_scr_act(), NULL);
	lv_line_set_points(line1, line_points, 5);	// Set the points
	lv_line_set_style(line1, LV_LINE_STYLE_MAIN, &style_line);
	lv_obj_align(line1, NULL, LV_ALIGN_CENTER, 0, 0);
}

void lv_ex_led_1(void)
{
	// Create a style for the LED
	static lv_style_t style_led;
	lv_style_copy(&style_led, &lv_style_pretty_color);
	style_led.body.radius = LV_RADIUS_CIRCLE;
	style_led.body.main_color = LV_COLOR_MAKE(0xb5, 0x0f, 0x04);
	style_led.body.grad_color = LV_COLOR_MAKE(0x50, 0x07, 0x02);
	style_led.body.border.color = LV_COLOR_MAKE(0xfa, 0x0f, 0x00);
	style_led.body.border.width = 3;
	style_led.body.border.opa = LV_OPA_30;
	style_led.body.shadow.color = LV_COLOR_MAKE(0xb5, 0x0f, 0x04);
	style_led.body.shadow.width = 5;

	// Create a LED and switch it OFF
	lv_obj_t * led1  = lv_led_create(lv_scr_act(), NULL);
	lv_led_set_style(led1, LV_LED_STYLE_MAIN, &style_led);
	lv_obj_align(led1, NULL, LV_ALIGN_CENTER, -80, 0);
	lv_led_off(led1);

	// Copy the previous LED and set a brightness
	lv_obj_t * led2  = lv_led_create(lv_scr_act(), led1);
	lv_obj_align(led2, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_led_set_bright(led2, 190);

	// Copy the previous LED and switch it ON
	lv_obj_t * led3  = lv_led_create(lv_scr_act(), led1);
	lv_obj_align(led3, NULL, LV_ALIGN_CENTER, 80, 0);
	lv_led_on(led3);
}

void lv_ex_label_1(void)
{
	lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK);	// Break the long lines
	lv_label_set_recolor(label1, true);	// Enable re-coloring by commands in the text
	lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER);	// Center aligned lines
	lv_label_set_text(label1, "#000080 Re-color# #0000ff words# #6666ff of a# label "
								"and  wrap long text automatically.");
	lv_obj_set_width(label1, 150);
	lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);

	lv_obj_t * label2 = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_long_mode(label2, LV_LABEL_LONG_SROLL_CIRC);	// Circular scroll
	lv_obj_set_width(label2, 150);
	lv_label_set_text(label2, "It is a circularly scrolling text. ");
	lv_obj_align(label2, NULL, LV_ALIGN_CENTER, 0, 30);
}

void lv_ex_kb_1(void)
{
	// Create styles for the keyboard
	static lv_style_t rel_style, pr_style;

	lv_style_copy(&rel_style, &lv_style_btn_rel);
	rel_style.body.radius = 0;
	rel_style.body.border.width = 1;

	lv_style_copy(&pr_style, &lv_style_btn_pr);
	pr_style.body.radius = 0;
	pr_style.body.border.width = 1;

	// Create a keyboard and apply the styles
	lv_obj_t *kb = lv_kb_create(lv_scr_act(), NULL);
	lv_kb_set_cursor_manage(kb, true);
	lv_kb_set_style(kb, LV_KB_STYLE_BG, &lv_style_transp_tight);
	lv_kb_set_style(kb, LV_KB_STYLE_BTN_REL, &rel_style);
	lv_kb_set_style(kb, LV_KB_STYLE_BTN_PR, &pr_style);

	// Create a text area. The keyboard will write here
	lv_obj_t *ta = lv_ta_create(lv_scr_act(), NULL);
	lv_obj_align(ta, NULL, LV_ALIGN_IN_TOP_MID, 0, 10);
	lv_ta_set_text(ta, "");

	// Assign the text area to the keyboard
	lv_kb_set_ta(kb, ta);
}

void lv_ex_gauge_1(void)
{
	// Create a style
	static lv_style_t style;
	lv_style_copy(&style, &lv_style_pretty_color);
	style.body.main_color = lv_color_hex3(0x666);	// Line color at the beginning
	style.body.grad_color = lv_color_hex3(0x666);	// Line color at the end
	style.body.padding.left = 10;	// Scale line length
	style.body.padding.inner = 8;	// Scale label padding
	style.body.border.color = lv_color_hex3(0x333);	// Needle middle circle color
	style.line.width = 3;
	style.text.color = lv_color_hex3(0x333);
	style.line.color = LV_COLOR_RED;	// Line color after the critical value

	// Describe the color for the needles
	static lv_color_t needle_colors[3];
	needle_colors[0] = LV_COLOR_BLUE;
	needle_colors[1] = LV_COLOR_ORANGE;
	needle_colors[2] = LV_COLOR_PURPLE;

	// Create a gauge
	lv_obj_t * gauge1 = lv_gauge_create(lv_scr_act(), NULL);
	lv_gauge_set_style(gauge1, LV_GAUGE_STYLE_MAIN, &style);
	lv_gauge_set_needle_count(gauge1, 3, needle_colors);
	lv_obj_set_size(gauge1, 150, 150);
	lv_obj_align(gauge1, NULL, LV_ALIGN_CENTER, 0, 20);

	// Set the values
	lv_gauge_set_value(gauge1, 0, 10);
	lv_gauge_set_value(gauge1, 1, 20);
	lv_gauge_set_value(gauge1, 2, 30);
}

void lv_ex_cont_1(void)
{
	lv_obj_t * cont;

	cont = lv_cont_create(lv_scr_act(), NULL);
	lv_obj_set_auto_realign(cont, true);	// Auto realign when the size changes
	lv_obj_align_origo(cont, NULL, LV_ALIGN_CENTER, 0, 0);	// This parametrs will be sued when realigned
	lv_cont_set_fit(cont, LV_FIT_TIGHT);
	lv_cont_set_layout(cont, LV_LAYOUT_COL_M);

	lv_obj_t * label;
	label = lv_label_create(cont, NULL);
	lv_label_set_text(label, "Short text");

	label = lv_label_create(cont, NULL);
	lv_label_set_text(label, "It is a long text");

	label = lv_label_create(cont, NULL);
	lv_label_set_text(label, "Here is an even longer text");
}

static void cb_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		printf("State: %s\n", lv_cb_is_checked(obj) ? "Checked" : "Unchecked");
	}
}

void lv_ex_cb_1(void)
{
	lv_obj_t * cb = lv_cb_create(lv_scr_act(), NULL);
	lv_cb_set_text(cb, "I agree to terms and conditions.");
	lv_obj_align(cb, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_event_cb(cb, cb_event_handler);
}

static void btnm_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		const char * txt = lv_btnm_get_active_btn_text(obj);

		printf("%s was pressed\n", txt);
	}
}

void lv_ex_btnm_1(void)
{
	static const char * btnm_map[] = {"1", "2", "3", "4", "5", "\n", "6", "7", "8", "9", "0", "\n", "Action1", "Action2", ""};
	lv_obj_t * btnm1 = lv_btnm_create(lv_scr_act(), NULL);
	lv_btnm_set_map(btnm1, btnm_map);
	lv_btnm_set_btn_width(btnm1, 10, 2); // Make "Action1" twice as wide as "Action2"
	lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_event_cb(btnm1, btnm_event_handler);
}

static void btn_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_CLICKED){
		printf("Clicked: %s\n", lv_list_get_btn_text(obj));		
	}
	else if(event == LV_EVENT_VALUE_CHANGED) {
		printf("Toggled: %s\n", lv_list_get_btn_text(obj));		
	}
}

void lv_ex_btn_1(void)
{
	lv_obj_t * label;

	lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
	lv_obj_set_event_cb(btn1, btn_event_handler);
	lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, -40);

	label = lv_label_create(btn1, NULL);
	lv_label_set_text(label, "Button");

	lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), NULL);
	lv_obj_set_event_cb(btn2, btn_event_handler);
	lv_obj_align(btn2, NULL, LV_ALIGN_CENTER, 0, 40);
	lv_btn_set_toggle(btn2, true);
	lv_btn_toggle(btn2);
	lv_btn_set_fit2(btn2, LV_FIT_NONE, LV_FIT_TIGHT);

	label = lv_label_create(btn2, NULL);
	lv_label_set_text(label, "Toggled");
}

void lv_ex_bar_1(void)
{
	lv_obj_t * bar1 = lv_bar_create(lv_scr_act(), NULL);
	lv_obj_set_size(bar1, 200, 30);
	lv_obj_align(bar1, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_bar_set_anim_time(bar1, 1000);
	lv_bar_set_value(bar1, 100, LV_ANIM_ON);
}

void lv_ex_arc_1(void) 
{
	// Create style for the Arcs
	static lv_style_t style;
	lv_style_copy(&style, &lv_style_plain);
	style.line.color = LV_COLOR_BLUE;	// Arc color
	style.line.width = 8;	// Arc width

	// Create an Arc
	lv_obj_t * arc = lv_arc_create(lv_scr_act(), NULL);
	lv_arc_set_style(arc, LV_ARC_STYLE_MAIN, &style);	// Use the new style
	lv_arc_set_angles(arc, 90, 60);
	lv_obj_set_size(arc, 150, 150);
	lv_obj_align(arc, NULL, LV_ALIGN_CENTER, 0, 0);
}

static void slider_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		printf("Value: %d\n", lv_slider_get_value(obj));
	}
}

void lv_ex_slider_1(void)
{
	// Create styles
	static lv_style_t style_bg;
	static lv_style_t style_indic;
	static lv_style_t style_knob;

	lv_style_copy(&style_bg, &lv_style_pretty);
	style_bg.body.main_color =  LV_COLOR_BLACK;
	style_bg.body.grad_color =  LV_COLOR_GRAY;
	style_bg.body.radius = LV_RADIUS_CIRCLE;
	style_bg.body.border.color = LV_COLOR_WHITE;

	lv_style_copy(&style_indic, &lv_style_pretty_color);
	style_indic.body.radius = LV_RADIUS_CIRCLE;
	style_indic.body.shadow.width = 8;
	style_indic.body.shadow.color = style_indic.body.main_color;
	style_indic.body.padding.left = 3;
	style_indic.body.padding.right = 3;
	style_indic.body.padding.top = 3;
	style_indic.body.padding.bottom = 3;

	lv_style_copy(&style_knob, &lv_style_pretty);
	style_knob.body.radius = LV_RADIUS_CIRCLE;
	style_knob.body.opa = LV_OPA_70;
	style_knob.body.padding.top = 10 ;
	style_knob.body.padding.bottom = 10 ;

	// Create a slider
	lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
	lv_slider_set_style(slider, LV_SLIDER_STYLE_BG, &style_bg);
	lv_slider_set_style(slider, LV_SLIDER_STYLE_INDIC,&style_indic);
	lv_slider_set_style(slider, LV_SLIDER_STYLE_KNOB, &style_knob);
	lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_event_cb(slider, slider_event_handler);
}

static void spinbox_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		printf("Value: %d\n", lv_spinbox_get_value(obj));
	}
	else if(event == LV_EVENT_CLICKED) {
		// For simple test: Click the spinbox to increment its value
		lv_spinbox_increment(obj);
	}
}

void lv_ex_spinbox_1(void)
{
	lv_obj_t * spinbox;
	spinbox = lv_spinbox_create(lv_scr_act(), NULL);
	lv_spinbox_set_digit_format(spinbox, 5, 3);
	lv_spinbox_step_prev(spinbox);
	lv_obj_set_width(spinbox, 100);
	lv_obj_align(spinbox, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_event_cb(spinbox, spinbox_event_handler);
}

static void sw_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		printf("State: %s\n", lv_sw_get_state(obj) ? "On" : "Off");
	}
}

void lv_ex_sw_1(void)
{
	// Create styles for the switch
	static lv_style_t bg_style;
	static lv_style_t indic_style;
	static lv_style_t knob_on_style;
	static lv_style_t knob_off_style;

	lv_style_copy(&bg_style, &lv_style_pretty);
	bg_style.body.radius = LV_RADIUS_CIRCLE;
	bg_style.body.padding.top = 6;
	bg_style.body.padding.bottom = 6;

	lv_style_copy(&indic_style, &lv_style_pretty_color);
	indic_style.body.radius = LV_RADIUS_CIRCLE;
	indic_style.body.main_color = lv_color_hex(0x9fc8ef);
	indic_style.body.grad_color = lv_color_hex(0x9fc8ef);
	indic_style.body.padding.left = 0;
	indic_style.body.padding.right = 0;
	indic_style.body.padding.top = 0;
	indic_style.body.padding.bottom = 0;

	lv_style_copy(&knob_off_style, &lv_style_pretty);
	knob_off_style.body.radius = LV_RADIUS_CIRCLE;
	knob_off_style.body.shadow.width = 4;
	knob_off_style.body.shadow.type = LV_SHADOW_BOTTOM;

	lv_style_copy(&knob_on_style, &lv_style_pretty_color);
	knob_on_style.body.radius = LV_RADIUS_CIRCLE;
	knob_on_style.body.shadow.width = 4;
	knob_on_style.body.shadow.type = LV_SHADOW_BOTTOM;

	// Create a switch and apply the styles
	lv_obj_t *sw1 = lv_sw_create(lv_scr_act(), NULL);
	lv_sw_set_style(sw1, LV_SW_STYLE_BG, &bg_style);
	lv_sw_set_style(sw1, LV_SW_STYLE_INDIC, &indic_style);
	lv_sw_set_style(sw1, LV_SW_STYLE_KNOB_ON, &knob_on_style);
	lv_sw_set_style(sw1, LV_SW_STYLE_KNOB_OFF, &knob_off_style);
	lv_obj_align(sw1, NULL, LV_ALIGN_CENTER, 0, -50);
	lv_obj_set_event_cb(sw1, sw_event_handler);

	// Copy the first switch and turn it ON
	lv_obj_t *sw2 = lv_sw_create(lv_scr_act(), sw1);
	lv_sw_on(sw2, LV_ANIM_ON);
	lv_obj_align(sw2, NULL, LV_ALIGN_CENTER, 0, 50);
}

void lv_ex_table_1(void)
{
	// Create a normal cell style
	static lv_style_t style_cell1;
	lv_style_copy(&style_cell1, &lv_style_plain);
	style_cell1.body.border.width = 1;
	style_cell1.body.border.color = LV_COLOR_BLACK;

	// Crealte a header cell style
	static lv_style_t style_cell2;
	lv_style_copy(&style_cell2, &lv_style_plain);
	style_cell2.body.border.width = 1;
	style_cell2.body.border.color = LV_COLOR_BLACK;
	style_cell2.body.main_color = LV_COLOR_SILVER;
	style_cell2.body.grad_color = LV_COLOR_SILVER;

	lv_obj_t * table = lv_table_create(lv_scr_act(), NULL);
	lv_table_set_style(table, LV_TABLE_STYLE_CELL1, &style_cell1);
	lv_table_set_style(table, LV_TABLE_STYLE_CELL2, &style_cell2);
	lv_table_set_style(table, LV_TABLE_STYLE_BG, &lv_style_transp_tight);
	lv_table_set_col_cnt(table, 2);
	lv_table_set_row_cnt(table, 4);
	lv_obj_align(table, NULL, LV_ALIGN_CENTER, 0, 0);

	// Make the cells of the first row center aligned
	lv_table_set_cell_align(table, 0, 0, LV_LABEL_ALIGN_CENTER);
	lv_table_set_cell_align(table, 0, 1, LV_LABEL_ALIGN_CENTER);

	// Make the cells of the first row TYPE = 2 (use `style_cell2`)
	lv_table_set_cell_type(table, 0, 0, 2);
	lv_table_set_cell_type(table, 0, 1, 2);

	// Fill the first column
	lv_table_set_cell_value(table, 0, 0, "Name");
	lv_table_set_cell_value(table, 1, 0, "Apple");
	lv_table_set_cell_value(table, 2, 0, "Banana");
	lv_table_set_cell_value(table, 3, 0, "Citron");

	// Fill the second column
	lv_table_set_cell_value(table, 0, 1, "Price");
	lv_table_set_cell_value(table, 1, 1, "$7");
	lv_table_set_cell_value(table, 2, 1, "$4");
	lv_table_set_cell_value(table, 3, 1, "$6");
}

void lv_ex_tabview_1(void)
{
	// Create a Tab view object
	lv_obj_t *tabview;
	tabview = lv_tabview_create(lv_scr_act(), NULL);

	// Add 3 tabs (the tabs are page (lv_page) and can be scrolled
	lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1");
	lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Tab 2");
	lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Tab 3");


	// Add content to the tabs
	lv_obj_t * label = lv_label_create(tab1, NULL);
	lv_label_set_text(label, "This the first tab\n\n"
								"If the content\n"
								"of a tab\n"
								"become too long\n"
								"the it \n"
								"automatically\n"
								"become\n"
								"scrollable.");

	label = lv_label_create(tab2, NULL);
	lv_label_set_text(label, "Second tab");

	label = lv_label_create(tab3, NULL);
	lv_label_set_text(label, "Third tab");
}

void lv_ex_tileview_1(void)
{
	static lv_point_t valid_pos[] = {{0,0}, {0, 1}, {1,1}};
	lv_obj_t *tileview;
	tileview = lv_tileview_create(lv_scr_act(), NULL);
	lv_tileview_set_valid_positions(tileview, valid_pos, 3);
	lv_tileview_set_edge_flash(tileview, true);

	lv_obj_t * tile1 = lv_obj_create(tileview, NULL);
	lv_obj_set_size(tile1, LV_HOR_RES, LV_VER_RES);
	lv_obj_set_style(tile1, &lv_style_pretty);
	lv_tileview_add_element(tileview, tile1);

	// Tile1: just a label
	lv_obj_t * label = lv_label_create(tile1, NULL);
	lv_label_set_text(label, "Tile 1");
	lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);

	// Tile2: a list
	lv_obj_t * list = lv_list_create(tileview, NULL);
	lv_obj_set_size(list, LV_HOR_RES, LV_VER_RES);
	lv_obj_set_pos(list, 0, LV_VER_RES);
	lv_list_set_scroll_propagation(list, true);
	lv_list_set_sb_mode(list, LV_SB_MODE_OFF);
	lv_tileview_add_element(tileview, list);

	lv_obj_t * list_btn;
	list_btn = lv_list_add_btn(list, NULL, "One");
	lv_tileview_add_element(tileview, list_btn);

	list_btn = lv_list_add_btn(list, NULL, "Two");
	lv_tileview_add_element(tileview, list_btn);

	list_btn = lv_list_add_btn(list, NULL, "Three");
	lv_tileview_add_element(tileview, list_btn);

	list_btn = lv_list_add_btn(list, NULL, "Four");
	lv_tileview_add_element(tileview, list_btn);

	list_btn = lv_list_add_btn(list, NULL, "Five");
	lv_tileview_add_element(tileview, list_btn);

	list_btn = lv_list_add_btn(list, NULL, "Six");
	lv_tileview_add_element(tileview, list_btn);

	list_btn = lv_list_add_btn(list, NULL, "Seven");
	lv_tileview_add_element(tileview, list_btn);

	list_btn = lv_list_add_btn(list, NULL, "Eight");
	lv_tileview_add_element(tileview, list_btn);

	// Tile3: a button
	lv_obj_t * tile3 = lv_obj_create(tileview, tile1);
	lv_obj_set_pos(tile3, LV_HOR_RES, LV_VER_RES);
	lv_tileview_add_element(tileview, tile3);

	lv_obj_t * btn = lv_btn_create(tile3, NULL);
	lv_obj_align(btn, NULL, LV_ALIGN_CENTER, 0, 0);

	label = lv_label_create(btn, NULL);
	lv_label_set_text(label, "Button");
}

void lv_ex_color_picker_1(void)
{
	const lv_coord_t pickerSize = 200;

	// Set the style of the color ring
	static lv_style_t styleMain;
	lv_style_copy(&styleMain, &lv_style_plain);
	styleMain.line.width = 30;
	// Make the background white
	styleMain.body.main_color = styleMain.body.grad_color = LV_COLOR_WHITE;

	// Set the style of the knob
	static lv_style_t styleIndicator;
	lv_style_copy(&styleIndicator, &lv_style_pretty);
	styleIndicator.body.border.color = LV_COLOR_WHITE;
	// Ensure that the knob is fully opaque
	styleIndicator.body.opa = LV_OPA_COVER;
	styleIndicator.body.border.opa = LV_OPA_COVER;

	lv_obj_t * scr = lv_scr_act();

	lv_obj_t * colorPicker = lv_cpicker_create(scr, NULL);
	lv_obj_set_size(colorPicker, pickerSize, pickerSize);
	// Choose the 'DISC' type
	lv_cpicker_set_type(colorPicker, LV_CPICKER_TYPE_DISC);
	lv_obj_align(colorPicker, NULL, LV_ALIGN_CENTER, 0, 0);
	// Set the styles
	lv_cpicker_set_style(colorPicker, LV_CPICKER_STYLE_MAIN, &styleMain);
	lv_cpicker_set_style(colorPicker, LV_CPICKER_STYLE_INDICATOR, &styleIndicator);
	// Change the knob's color to that of the selected color
	lv_cpicker_set_indic_colored(colorPicker, true);
}

void lv_ex_canvas_1(void)
{
    static lv_style_t style;
	
    lv_style_copy(&style, &lv_style_plain);
    style.body.main_color = LV_COLOR_RED;
    style.body.grad_color = LV_COLOR_MAROON;
    style.body.radius = 4;
    style.body.border.width = 2;
    style.body.border.color = LV_COLOR_WHITE;
    style.body.shadow.color = LV_COLOR_WHITE;
    style.body.shadow.width = 4;
    style.line.width = 2;
    style.line.color = LV_COLOR_BLACK;
    style.text.color = LV_COLOR_BLUE;

    static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_WIDTH, CANVAS_HEIGHT)];

    lv_obj_t * canvas = lv_canvas_create(lv_scr_act(), NULL);
    lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
    lv_obj_align(canvas, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_canvas_fill_bg(canvas, LV_COLOR_SILVER);

    lv_canvas_draw_rect(canvas, 70, 60, 100, 70, &style);

    lv_canvas_draw_text(canvas, 40, 20, 100, &style, "Some text on text canvas", LV_LABEL_ALIGN_LEFT);

    /* Test the rotation. It requires an other buffer where the orignal image is stored.
     * So copy the current image to buffer and rotate it to the canvas */
    lv_color_t cbuf_tmp[CANVAS_WIDTH * CANVAS_HEIGHT];
    memcpy(cbuf_tmp, cbuf, sizeof(cbuf_tmp));
    lv_img_dsc_t img;
    img.data = (void *)cbuf_tmp;
    img.header.cf = LV_IMG_CF_TRUE_COLOR;
    img.header.w = CANVAS_WIDTH;
    img.header.h = CANVAS_HEIGHT;

    lv_canvas_fill_bg(canvas, LV_COLOR_SILVER);
    lv_canvas_rotate(canvas, &img, 30, 0, 0, CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2);
}

static void ta_event_handler(lv_obj_t * obj, lv_event_t event)
{
	if(event == LV_EVENT_VALUE_CHANGED) {
		printf("Value: %s\n", lv_ta_get_text(obj));
	}
	else if(event == LV_EVENT_LONG_PRESSED_REPEAT) {
		// For simple test: Long press the Text are to add the text below
		const char  * txt = "\n\nYou can scroll it if the text is long enough.\n";
		static uint16_t i = 0;
		if(txt[i] != '\0') {
			lv_ta_add_char(ta1, txt[i]);
			i++;
		}
	}
}

void lv_ex_ta_1(void)
{
	ta1 = lv_ta_create(lv_scr_act(), NULL);
	lv_obj_set_size(ta1, 200, 100);
	lv_obj_align(ta1, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_ta_set_cursor_type(ta1, LV_CURSOR_BLOCK);
	lv_ta_set_text(ta1, "A text in a Text Area");	// Set an initial text
	lv_obj_set_event_cb(ta1, ta_event_handler);
}

void lv_ex_img_1(void)
{
    lv_obj_t * img1 = lv_img_create(lv_scr_act(), NULL);
	
	LV_IMG_DECLARE(img_logo_vatics)

    lv_img_set_src(img1, &img_logo_vatics);
    lv_obj_align(img1, NULL, LV_ALIGN_CENTER, 0, -20);

    lv_obj_t * img2 = lv_img_create(lv_scr_act(), NULL);
    lv_img_set_src(img2, LV_SYMBOL_OK "Accept");
    lv_obj_align(img2, img1, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
}

void lv_ex_imgbtn_1(void)
{
    static lv_style_t style_pr;
    lv_style_copy(&style_pr, &lv_style_plain);
    style_pr.image.color = LV_COLOR_BLACK;
    style_pr.image.intense = LV_OPA_50;
    style_pr.text.color = lv_color_hex3(0xaaa);

    LV_IMG_DECLARE(img_btn_red);
    LV_IMG_DECLARE(img_btn_green);

    // Create an Image button
    lv_obj_t * imgbtn1 = lv_imgbtn_create(lv_scr_act(), NULL);
    lv_imgbtn_set_src(imgbtn1, LV_BTN_STATE_REL, &img_btn_red);
    lv_imgbtn_set_src(imgbtn1, LV_BTN_STATE_PR, &img_btn_red);
    lv_imgbtn_set_src(imgbtn1, LV_BTN_STATE_TGL_REL, &img_btn_green);
    lv_imgbtn_set_src(imgbtn1, LV_BTN_STATE_TGL_PR, &img_btn_green);
    lv_imgbtn_set_style(imgbtn1, LV_BTN_STATE_PR, &style_pr);	// Use the darker style in the pressed state
    lv_imgbtn_set_style(imgbtn1, LV_BTN_STATE_TGL_PR, &style_pr);
    lv_imgbtn_set_toggle(imgbtn1, true);
    lv_obj_align(imgbtn1, NULL, LV_ALIGN_CENTER, 0, -40);

    /*Create a label on the Image button*/
    lv_obj_t * label = lv_label_create(imgbtn1, NULL);
    lv_label_set_text(label, "Button");
}


lv_obj_t * slider_label;
static void slider_group_event_handler(lv_obj_t * obj, lv_event_t event)
{
    if(event == LV_EVENT_VALUE_CHANGED) {
        static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte */
        snprintf(buf, 4, "%d", lv_slider_get_value(obj));
		lv_label_set_text(slider_label, buf);
    }
}

void lv_ex_group_keyboard_slider_1(void)
{
	lv_group_t * g;
    g = lv_group_create();
	
#ifdef PC_SIMULATOR
	//! Init input device : keyboard
	lv_indev_drv_t indev_drv_kb;
	lv_indev_drv_init(&indev_drv_kb);      /*Basic initialization*/
	indev_drv_kb.type = LV_INDEV_TYPE_KEYPAD;
	indev_drv_kb.read_cb = keyboard_read;
	lv_indev_t * kb_indev = lv_indev_drv_register(&indev_drv_kb);	/*Register the driver in LittlevGL and save the created input device object*/
    lv_indev_set_group(kb_indev, g);
#else
	evdev_init();
	//! Init input device : keyboard
	lv_indev_drv_t indev_drv_kb;
	lv_indev_drv_init(&indev_drv_kb);      /*Basic initialization*/
	indev_drv_kb.type = LV_INDEV_TYPE_KEYPAD;
	indev_drv_kb.read_cb = evdev_read;
	lv_indev_t * kb_indev = lv_indev_drv_register(&indev_drv_kb);	/*Register the driver in LittlevGL and save the created input device object*/
    lv_indev_set_group(kb_indev, g);
#endif
	
	/* Create a slider */
	lv_obj_t * slider;
    slider = lv_slider_create(lv_scr_act(), NULL);
    lv_obj_align(slider, lv_scr_act(), LV_ALIGN_CENTER, 0, 0);
    lv_slider_set_range(slider, -50, 50);
    lv_slider_set_value(slider, 25, false);
	lv_obj_set_event_cb(slider, slider_group_event_handler);
    lv_group_add_obj(g, slider);

	/* Create a label below the slider */
    slider_label = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(slider_label, "25");
    lv_obj_set_auto_realign(slider_label, true);
    lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
    lv_group_add_obj(g, slider_label);
	
}


void lv_ex_img_2(void)
{
	lv_obj_t *img = NULL;
	static lv_img_dsc_t img_desc;
	uint32_t w = 200, h = 200;
	FILE *fp = NULL;

	atexit(exit_handler);
	buf = malloc(w * h * 4 * sizeof *buf);
	img = lv_img_create(lv_scr_act(), NULL);

	fp = fopen(SAMPLE_PICTURE, "rb");

#if defined(PC_SIMULATOR)
	fread(buf, 1, (w * h * 4), fp);
#else
	VMF_CVT_INITOPT_T init;
	VMF_CVT_BUFFER_T buffer;
	VMF_CVT_HANDLE_T *handle;

	memset(&init, 0, sizeof init);
	init.eCvt = VMF_CVT_YCbCr_2_RGB;
	init.eSample = VMF_CVT_YCbCr420;
	init.dwWidth = w;
	init.dwHeight = h;
	handle = VMF_CVT_Init(&init);

	memset(&buffer, 0, sizeof buffer);
	buffer.apbyInBuf[0] = mmap(NULL, (w * h * 1.5), PROT_READ, MAP_PRIVATE, fileno(fp), 0);
	buffer.apbyInBuf[1] = buffer.apbyInBuf[0] + (w * h);
	buffer.apbyInBuf[2] = buffer.apbyInBuf[1] + (w * h / 4);
	buffer.apbyOutBuf[0] = buf;
	VMF_CVT_ProcessOneFrame(handle, &buffer);
	munmap(buffer.apbyInBuf[0], (w * h * 1.5));
#endif

	fclose(fp);

	memset(&img_desc, 0, sizeof img_desc);
	img_desc.header.h = w;
	img_desc.header.w = h;
	img_desc.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
	img_desc.data_size = w * h * 4;
	img_desc.data = buf;
    lv_img_set_src(img, &img_desc);
	lv_obj_align(img, NULL, LV_ALIGN_CENTER, 0, 0);
}

void lv_ex_animation_1(void)
{
	lv_obj_t * scr = lv_disp_get_scr_act(NULL);     /*Get the current screen*/

	/*Create a button to demonstrate user defined animations*/
	lv_obj_t * btn1;
	btn1 = lv_btn_create(scr, NULL);
	lv_obj_set_pos(btn1, 10, 80);       /*Set a position. It will be the animation's destination*/
	lv_obj_set_size(btn1, 80, 50);

	lv_obj_t * label;
	label = lv_label_create(btn1, NULL);
	lv_label_set_text(label, "Move");

	/*Create an animation to move the button continuously left to right*/
	lv_anim_t a;
	a.var = btn1;
	a.start = lv_obj_get_x(btn1);
	a.end = a.start + (100);
	a.exec_cb = (lv_anim_exec_xcb_t)lv_obj_set_x;
	a.path_cb = lv_anim_path_linear;
	a.ready_cb = NULL;
	a.act_time = -1000;                         /*Negative number to set a delay*/
	a.time = 1000;                               /*Animate in 1000 ms*/
	a.playback = 1;                             /*Make the animation backward too when it's ready*/
	a.playback_pause = 0;                       /*Wait before playback*/
	a.repeat = 1;                               /*Repeat the animation*/
	a.repeat_pause = 200;                       /*Wait before repeat*/

	lv_anim_create(&a);
}

void lv_ex_img_3(void)
{
    lv_obj_t * img1 = lv_img_create(lv_scr_act(), NULL);
	
	LV_IMG_DECLARE(img_logo_transp)

    lv_img_set_src(img1, &img_logo_transp);
    lv_obj_align(img1, NULL, LV_ALIGN_CENTER, 0, -20);

	static lv_style_t style;
	lv_style_copy(&style, &lv_style_plain);
	style.image.color = LV_COLOR_RED;
	style.image.intense = LV_OPA_COVER;
	style.image.opa = LV_OPA_COVER;
	lv_obj_t * img2 = lv_img_create(lv_scr_act(), img1);
    lv_obj_set_style(img2, &style);
    lv_obj_align(img2, img1, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
}
