BigW Consortium Gitlab

Commit 42f040f8 by Gabor

Merge branch 'beta'

parents 4fd0dfc7 f776a8f1
......@@ -63,7 +63,7 @@ See the [example HAL](https://github.com/littlevgl/hal) repository!
* your_systick_init();
* your_disp_init();
* your_indev_init();
* **lvgl_init()**;
* **lv_init()**;
10. To **test** create a label: `lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);`
11. In the main *while(1)* call `ptask_handler();` and make a few milliseconds delay (e.g. `your_delay_ms(5);`)
12. Compile the code and load it to your embedded hardware
......
......@@ -146,6 +146,14 @@ const lv_app_dsc_t * lv_app_benchmark_init(void)
static void my_app_run(lv_app_inst_t * app, void * conf)
{
/*Initialize the application*/
my_app_data_t * ad = app->app_data;
ad->opa = 0;
ad->recolor = 0;
ad->shdw = 0;
ad->upscalse = 0;
ad->wp = 0;
}
/**
......
......@@ -17,18 +17,19 @@
#define LV_HOR_RES (320 * LV_DOWNSCALE)
#define LV_VER_RES (240 * LV_DOWNSCALE)
#define LV_DPI (80 * LV_DOWNSCALE)
/* Buffered rendering: >= LV_DOWNSCALE * LV_HOR_RES or 0 to disable buffering*/
#define LV_VDB_SIZE (LV_HOR_RES * 30)
/* Enable antialaiassing
/* Enable anti-aliasing
* If enabled everything will half-sized
* Use LV_DOWNSCALE to compensate
* the down scaling effect of antialiassing*/
* Use LV_DOWNSCALE to compensate he down scaling effect of anti-aliasing*/
#define LV_ANTIALIAS 1
#define LV_DOWNSCALE (1 << LV_ANTIALIAS) /*Set the downscaling value*/
/*Set the downscaling value*/
#define LV_DOWNSCALE (1 << LV_ANTIALIAS)
/* Buffered rendering: >= LV_DOWNSCALE * LV_HOR_RES or 0 to disable buffering*/
#define LV_VDB_SIZE (LV_HOR_RES * LV_VER_RES / 20)
#if LV_VDB_SIZE
/* Double virtual buffering
* One for rendering another to transfer former rendered image to frame buffer in the background*/
#define LV_VDB_DOUBLE 0
#endif
#define LV_REFR_PERIOD 40 /*Screen refresh period in milliseconds*/
#define LV_INV_FIFO_SIZE 32 /*The average number of objects on a screen */
......@@ -47,9 +48,11 @@
/*lv_obj (base object) settings*/
#define LV_OBJ_FREE_NUM 1 /*Enable the free number attribute*/
#define LV_OBJ_FREE_P 1 /*Enable the free pointer attribute*/
#define LV_OBJ_GROUP 1 /*Enable object groups*/
/*Others*/
#define LV_COLOR_TRANSP COLOR_LIME
#define LV_COLOR_TRANSP COLOR_LIME /*This could mean transparent pixel*/
#define USE_LV_EXAMPLE 1 /*Enable examples (lvgl/lv_examples/). Disable to save memory*/
/*==================
* LV OBJ X USAGE
......@@ -145,6 +148,9 @@
/*List (dependencies: lv_page, lv_btn, lv_label, lv_img)*/
#define USE_LV_LIST 1
#if USE_LV_LIST != 0
#define LV_LIST_FOCUS_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
#endif
/*Drop down list (dependencies: lv_page, lv_label)*/
#define USE_LV_DDLIST 1
......
......@@ -123,8 +123,7 @@ void lv_vfill(const area_t * cords_p, const area_t * mask_p,
cord_t map_width = area_get_width(&vdb_rel_a);
if(color_map[0].full != color.full || last_width != map_width) {
uint16_t i;
for(i =0; i < map_width; i++) {
for(i = 0; i < map_width; i++) {
color_map[i].full = color.full;
}
......@@ -133,7 +132,6 @@ void lv_vfill(const area_t * cords_p, const area_t * mask_p,
cord_t row;
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; row++) {
disp_color_cpy(&vdb_buf_tmp[vdb_rel_a.x1], color_map, map_width, opa);
vdb_buf_tmp += vdb_width;
}
#endif
......
/**
* @file lv_ex_hello_world.c
*
*/
/*
* Greetings,
* this is the first example in the tutorial hence this is the most simple one.
* It only creates a Label, set its text, and align to the middle.
*
* Be sure in lv_conf.h LV_APP_ENEBLE is 0 (just for simplicity)
*/
/*********************
* INCLUDES
*********************/
#include "lv_ex_hello_world.h"
#if USE_LV_EXAMPLE != 0
#include "lvgl/lvgl.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Create a simple 'Hello world!' label
*/
void lv_ex_hello_world(void)
{
/*Create a Label on the current screen*/
lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
/*Modify the Label's text*/
lv_label_set_text(label1, "Hello world!");
/* Align the Label to the center
* NULL means align on parent (which is the screen now)
* 0, 0 at the and means an x, y offset after alignment*/
lv_obj_align_us(label1, NULL, LV_ALIGN_CENTER, 0, 0);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*USE_LV_EXAMPLE != 0*/
/**
* @file lv_ex_hello_world.h
*
*/
#ifndef LV_EX_HELLO_WORLD_H
#define LV_EX_HELLO_WORLD_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#if USE_LV_EXAMPLE != 0
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_ex_hello_world(void);
/**********************
* MACROS
**********************/
#endif /*USE_LV_EXAMPLE != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_HELLO_WORLD_H*/
/**
* @file lv_hello_world.c
*
*/
/*
* The basic building blocks (components or widgets) in LittlevGL are the graphical objects.
* For example:
* - Buttons
* - Labels
* - Charts
* - Sliders etc
*
* In this part you can learn the basics of the objects like creating, positioning, sizing etc.
* You will also meet some different object types and their attributes.
*
* Regardless to the object type the 'lv_obj_t' variable type is used stores the objects
* and you can refer to an object with an lv_obj_t pointer (lv_obj_t *)
*
* INHERITANCE
* -------------
* Similarly to object oriented languages some kind of inheritance is used
* among the object types.
*
* Every object is derived from the 'Basic object'. (lv_obj)
*
* The types are backward compatible which means a type can use all the ancestor
* attributes/functions too.
*
* For example a 'Button' is derived from 'Container' which is derived from 'Basic objects'.
* Therefore a button can use container attributes like automatically fit size to the content.
*
* PARENT-CHILD
* -------------
* A parent can be considered as the container of its children.
* Every object has exactly one parent object (except screens).
* A parent can have unlimited number of children.
* There is no limitation for the type of the parent.
*
* The children are visible only on their parent. The parts outside will be cropped (not displayed)
*
* If the parent is moved the children will be moved with it.
*
* The earlier created object (and its children) will drawn earlier.
* Using this layers can be built.
*
* LEARN MORE
* -------------
* - General overview: http://www.gl.littlev.hu/objects
* - Detailed description of types: http://www.gl.littlev.hu/object-types
*
* NOTES
* -------------
* - Be sure 'LV_OBJ_FREE_P' is enabled in 'lv_conf.h'
*/
/*********************
* INCLUDES
*********************/
#include "lv_ex_objects.h"
#if USE_LV_EXAMPLE != 0
#include "lvgl/lvgl.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_action_res_t btn_rel_action(lv_obj_t * btn, lv_dispi_t * dispi);
static lv_action_res_t ddlist_action(lv_obj_t * ddlist, lv_dispi_t * dispi);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the Object usage example
*/
void lv_ex_objects(void)
{
/********************
* CREATE A SCREEN
*******************/
/* Create a new screen and load it
* Screen can be created from any type object
* Now a Page is used which is an objects with scrollable content*/
lv_obj_t * scr = lv_page_create(NULL, NULL);
lv_scr_load(scr);
/****************
* ADD A TITLE
****************/
lv_obj_t * label = lv_label_create(scr, NULL); /*First parameters (scr) is the parent*/
lv_label_set_text(label, "Object usage demo"); /*Set the text*/
lv_obj_set_x(label, 50); /*Labels are inherited from Basic object so 'lv_obj_...' functions can be used*/
/********************
* CREATE TWO BUTTONS
********************/
/*Create a button*/
lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL); /*Create a button on the currently loaded screen*/
lv_btn_set_rel_action(btn1, btn_rel_action); /*Set function to call when the button is released*/
lv_obj_align(btn1, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the label*/
label = lv_label_create(btn1, NULL); /*Create a label on the button (the 'label' variable can be reused)*/
lv_label_set_text(label, "Button 1");
/*Copy the previous button*/
lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), btn1); /*Second parameter is an object to copy*/
lv_obj_align(btn2, btn1, LV_ALIGN_OUT_RIGHT_MID, 50, 0);/*Align next to the prev. button.*/
label = lv_label_create(btn2, NULL); /*Create a label on the button*/
lv_label_set_text(label, "Button 2");
/****************
* ADD A SLIDER
****************/
/*Add a slider (inheritance: lv_obj -> lv_bar -> lv_slider)*/
lv_obj_t * slider = lv_slider_create(scr, NULL); /*Create a slider*/
lv_obj_set_size(slider, lv_obj_get_width(lv_scr_act()) / 3, LV_DPI / 3); /*Set the size*/
lv_obj_align(slider, btn1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the first button*/
lv_bar_set_value(slider, 30); /*Slider is a 'bar' so set its value like a 'bar'*/
/***********************
* ADD A DROP DOWN LIST
************************/
lv_obj_t * ddlist = lv_ddlist_create(lv_scr_act(), NULL);
lv_obj_align(ddlist, slider, LV_ALIGN_OUT_RIGHT_TOP, 20, 0); /*Align next to the slider*/
lv_obj_set_free_p(ddlist, slider); /*Save the pointer of the slider in the ddlist (used in 'ddlist_action()')*/
lv_ddlist_set_options_str(ddlist, "None\nLittle\nHalf\nA lot\nAll"); /*Set the options*/
lv_ddlist_set_action(ddlist, ddlist_action); /*Set function to call on new option choose*/
lv_obj_set_top(ddlist, true); /*Enable the drop down list always be on the top*/
/****************
* CREATE A CHART
****************/
lv_obj_t * chart = lv_chart_create(lv_scr_act(), NULL); /*Craete the chart*/
lv_obj_set_size(chart, lv_obj_get_width(scr) / 2, lv_obj_get_width(scr) / 4); /*Set the size*/
lv_obj_align(chart, slider, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the slider*/
lv_chart_set_dl_width(chart, 3 * LV_DOWNSCALE); /*Set the line width (LV_DOWNSCALE compensates anti-aliasing if enabled)*/
/*Add a RED data line and set some points*/
lv_chart_dl_t * dl1 = lv_chart_add_data_line(chart, COLOR_RED);
lv_chart_set_next(chart, dl1, 10);
lv_chart_set_next(chart, dl1, 25);
lv_chart_set_next(chart, dl1, 45);
lv_chart_set_next(chart, dl1, 80);
/*Add a BLUE data line and set some points*/
lv_chart_dl_t * dl2 = lv_chart_add_data_line(chart, COLOR_MAKE(0x40, 0x70, 0xC0));
lv_chart_set_next(chart, dl2, 10);
lv_chart_set_next(chart, dl2, 25);
lv_chart_set_next(chart, dl2, 45);
lv_chart_set_next(chart, dl2, 80);
lv_chart_set_next(chart, dl2, 75);
lv_chart_set_next(chart, dl2, 505);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Called when a button is released
* @param btn pointer to the released button
* @param dispi pointer to caller display input (e.g. touchpad)
* @return LV_ACTION_RES_OK because the object is not deleted in this function
*/
static lv_action_res_t btn_rel_action(lv_obj_t * btn, lv_dispi_t * dispi)
{
/*Increase the button width*/
cord_t width = lv_obj_get_width(btn);
lv_obj_set_width(btn, width + 20);
return LV_ACTION_RES_OK;
}
/**
* Called when a new option is chosen in the drop down list
* @param ddlist pointer to the drop down list
* @param dispi pointer to caller display input (e.g. touchpad)
* @return LV_ACTION_RES_OK because the object is not deleted in this function
*/
static lv_action_res_t ddlist_action(lv_obj_t * ddlist, lv_dispi_t * dispi)
{
uint16_t opt = lv_ddlist_get_selected(ddlist); /*Get the id of selected option*/
lv_obj_t * slider = lv_obj_get_free_p(ddlist); /*Get the saved slider*/
lv_bar_set_value(slider, (opt * 100) / 4); /*Modify the slider value according to the selection*/
return LV_ACTION_RES_OK;
}
#endif /*USE_LV_EXAMPLE != 0*/
/**
* @file lv_ex_objects.h
*
*/
#ifndef LV_EX_OBJECTS_H
#define LV_EX_OBJECTS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#if USE_LV_EXAMPLE != 0
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_ex_objects(void);
/**********************
* MACROS
**********************/
#endif /*USE_LV_EXAMPLE != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_OBJ_USAGE_H*/
/**
* @file lv_ex_styles.h
*
*/
/*
* You can modify the appearance of the graphical objects with styles.
* A style is simple 'lv_style_t' variable.
* Objects save the address of this variable so it has to be 'static or 'global'.
*
* A style contains various attributes to describe rectangle, image or text like
* objects at same time. To know which attribute is used by an object see:
* http://www.gl.littlev.hu/object-types
*
* To set a new style for an object use: 'lv_obj_set_style(obj, &style);
* If NULL is set as style then the object will inherit the parents style.
* For example is you create a style for button the label appearance can be defined there as well.
*
* You can use built-in styles. 'lv_style_get(LV_STYLE_... , &copy)' will give you a pointer to built in style
* and copy it to variable (second parameter) if it is not NULL.
* By default the objects use the built-in styles.
* The built-in styles can be modified in run time to give a new default skin to your GUI.
*
* Learn more here: http://www.gl.littlev.hu/objects#style
* */
/*********************
* INCLUDES
*********************/
#include "lv_ex_styles.h"
#if USE_LV_EXAMPLE != 0
#include "lvgl/lvgl.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Create a simple 'Hello world!' label
*/
void lv_ex_styles(void)
{
/****************************************
* BASE OBJECT + LABEL WITH DEFAULT STYLE
****************************************/
lv_obj_t * obj1;
obj1 = lv_obj_create(lv_scr_act(), NULL); /*Create a simple objects*/
lv_obj_set_pos(obj1, 10, 10);
lv_obj_t * label = lv_label_create(obj1, NULL);
/*Add a label to the object*/
lv_label_set_text(label, "Default");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
/****************************************
* BASE OBJECT WITH PRETTY COLOR STYLE
****************************************/
lv_obj_t * obj2;
obj2 = lv_obj_create(lv_scr_act(), NULL);
lv_obj_align(obj2, obj1, LV_ALIGN_OUT_RIGHT_MID, 20, 0); /*Align next to the previous object*/
lv_obj_set_style(obj2, lv_style_get(LV_STYLE_PRETTY_COLOR, NULL)); /*Set built in style*/
label = lv_label_create(obj2, NULL);
/* Add a label to the object.
* Labels by default inherit the parent's style */
lv_label_set_text(label, "Pretty\ncolor");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
/*****************************
* BASE OBJECT WITH NEW STYLE
*****************************/
/* Create a new style */
static lv_style_t style_new; /*Styles can't be local variables*/
lv_style_get(LV_STYLE_PRETTY_COLOR, &style_new); /*Copy a built-in style as a starting point*/
style_new.radius = LV_RADIUS_CIRCLE; /*Fully round corners*/
style_new.swidth = 8; /*8 px shadow*/
style_new.bwidth = 2; /*2 px border width*/
style_new.mcolor = COLOR_WHITE; /*White main color*/
style_new.gcolor = color_mix(COLOR_BLUE, COLOR_WHITE, OPA_40); /*light blue gradient color*/
style_new.scolor = COLOR_MAKE(0xa0, 0xa0, 0xa0); /*Light gray shadow color*/
style_new.ccolor = color_mix(COLOR_BLUE, COLOR_WHITE, OPA_90); /*Blue content color (text color)*/
style_new.letter_space = 10; /*10 px letter space*/
style_new.txt_align = LV_TXT_ALIGN_MID; /*Middel text align*/
/*Create a base object and apply the new style*/
lv_obj_t * obj3;
obj3 = lv_obj_create(lv_scr_act(), NULL);
lv_obj_align(obj3, obj2, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
lv_obj_set_style(obj3, &style_new);
/* Add a label to the object.
* Labels by default inherit the parent's style */
label = lv_label_create(obj3, NULL);
lv_label_set_text(label, "New\nstyle");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
/************************
* CREATE A STYLED LED
***********************/
/*Create a style for the LED*/
static lv_style_t style_led;
lv_style_get(LV_STYLE_PRETTY_COLOR, &style_led);
style_led.swidth = 15;
style_led.radius = LV_RADIUS_CIRCLE;
style_led.bwidth = 3;
style_led.bopa = OPA_30;
style_led.mcolor = COLOR_MAKE(0xb5, 0x0f, 0x04);
style_led.gcolor = COLOR_MAKE(0x50, 0x07, 0x02);
style_led.bcolor = COLOR_MAKE(0xfa, 0x0f, 0x00);
style_led.scolor = COLOR_MAKE(0xb5, 0x0f, 0x04);
/*Create a LED and switch it ON*/
lv_obj_t * led1 = lv_led_create(lv_scr_act(), NULL);
lv_obj_set_style(led1, &style_led);
lv_obj_align_us(led1, obj1, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
lv_led_on(led1);
/*Copy the previous LED and set a brightness*/
lv_obj_t * led2 = lv_led_create(lv_scr_act(), led1);
lv_obj_align_us(led2, obj2, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
lv_led_set_bright(led2, 190);
/*Copy the previous LED and switch it OFF*/
lv_obj_t * led3 = lv_led_create(lv_scr_act(), led1);
lv_obj_align_us(led3, obj3, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
lv_led_off(led3);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*USE_LV_EXAMPLE != 0*/
/**
* @file style_usage.h
*
*/
#ifndef STYLE_USAGE_H
#define STYLE_USAGE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#if USE_LV_EXAMPLE != 0
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_ex_styles(void);
/**********************
* MACROS
**********************/
#endif /*USE_LV_EXAMPLE != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_HELLO_WORLD_H*/
/**
* @file lv_ex_encoder_ctrl.h
*
*/
#ifndef LV_EX_ENCODER_CTRL_H
#define LV_EX_ENCODER_CTRL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#if USE_LV_EXAMPLE != 0
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_ex_encoder_ctrl(void);
/**********************
* MACROS
**********************/
#endif /*USE_LV_EXAMPLE != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*ENCODER_CTRL_H*/
# EXAMPLES FOR LITTLEV GRAPHICS LIBRARY
## Introduction
In the folders you will find simple hardware independent examples to know the key features of Littlev Graphics Library.
The examples are organized in consistent way and can be used as a **Tutorial**.
Every example consist of least an *example_name.c* and *example_name.h* files. You can load an example in your *main* function with **example_name_init()**. The header file has to be included too.
You will find **detailed explanation** in the *c* and *h* files.
The examples can be enabled/disabled in *lv_conf.h* with **USE_LV_EXAMPLES**.
## 1_x Getting started
With examples in this section you can learn the basics from a simple *Hello world* label to a complex full featured GUI with animations and other effects. You will learn about
- creating, deleting graphical objects
- modify their attributes
- change their style
- and even creating a new object type
## 2_x GUI control without Touchpad
You can control your GUI not only with Touchpad. The most simple way to put real buttons next to the graphical ones and simulate *touch pad-like press* on the display. An other way is to organize the objects in groups and *focus* on one of objects. Then you can control the object-in-focus with simple character instructions. Or using a cursor and mouse is also possible. So an external control device can be
- push buttons
- encoders
- keyboard
- or a mouse
In this section you will find examples for them!
## 3_x Applications
The applications are high level components to do complex thing with a nice user interface. An application can be for example
- WiFi network manager
- File system browser
- System monitor
- Terminal etc.
Here you will find examples how to run application, and communicate with them.
## Final words
If you also have codes which could be useful for others, please share it via *Pull requests* on *GitHub*!
Thank you in advance!
/**
* @file lv_group.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_group.h"
#if LV_OBJ_GROUP != 0
#include <stddef.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void style_mod_def(lv_style_t * style);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Create a new object group
* @return pointer to the new object group
*/
lv_group_t * lv_group_create(void)
{
lv_group_t * group = dm_alloc(sizeof(lv_group_t));
ll_init(&group->obj_ll, sizeof(lv_obj_t *));
group->style_mod = style_mod_def;
group->obj_focus = NULL;
group->frozen = 0;
return group;
}
/**
* Add an object to a group
* @param group pointer to a group
* @param obj pointer to an object to add
*/
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
{
obj->group_p = group;
lv_obj_t ** next = ll_ins_tail(&group->obj_ll);
*next = obj;
/* If the head and the tail is equal then there is only one object in the linked list.
* In this case automatically activate it*/
if(ll_get_head(&group->obj_ll) == next) {
lv_group_focus_next(group);
}
}
/**
* Remove an object from its group
* @param obj pointer to an objectto remove
*/
void lv_group_rem_obj(lv_obj_t * obj)
{
lv_group_t * g = obj->group_p;
if(g == NULL) return;
lv_obj_t ** i;
LL_READ(g->obj_ll, i) {
if(*i == obj) {
ll_rem(&g->obj_ll, i);
break;
}
}
if(*g->obj_focus == obj) {
g->obj_focus = NULL;
lv_group_focus_next(g);
}
}
/**
* Focus on an object (defocus the current)
* @param obj pointer to an object to focus on
*/
void lv_group_focus_obj(lv_obj_t * obj)
{
lv_group_t * g = obj->group_p;
if(g == NULL) return;
if(g->frozen != 0) return;
lv_obj_t ** i;
LL_READ(g->obj_ll, i) {
if(*i == obj) {
if(g->obj_focus != NULL) {
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_inv(*g->obj_focus);
}
g->obj_focus = i;
if(g->obj_focus != NULL){
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_inv(*g->obj_focus);
}
break;
}
}
}
/**
* Focus the next object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_next(lv_group_t * group)
{
if(group->frozen != 0) return;
if(group->obj_focus != NULL) {
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
lv_obj_t ** obj_next;
if(group->obj_focus == NULL) obj_next = ll_get_head(&group->obj_ll);
else obj_next = ll_get_next(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = ll_get_head(&group->obj_ll);
group->obj_focus = obj_next;
if(group->obj_focus != NULL){
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
}
/**
* Focus the previous object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_prev(lv_group_t * group)
{
if(group->frozen != 0) return;
if(group->obj_focus != NULL) {
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
lv_obj_t ** obj_next;
if(group->obj_focus == NULL) obj_next = ll_get_tail(&group->obj_ll);
else obj_next = ll_get_prev(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = ll_get_tail(&group->obj_ll);
group->obj_focus = obj_next;
if(group->obj_focus != NULL){
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
}
/**
* Do not let to change the focus from the current object
* @param group pointer to a group
* @param en true: freeze, false: release freezing (normal mode)
*/
void lv_group_focus_freeze(lv_group_t * group, bool en)
{
if(en == false) group->frozen = 0;
else group->frozen = 1;
}
/**
* Send a control character to the focuses object of a group
* @param group pointer to a group
* @param c a control character (use LV_GROUP_KEY_.. to navigate)
*/
void lv_group_send(lv_group_t * group, char c)
{
lv_obj_t * act = lv_group_get_focused(group);
if(act == NULL) return;
act->signal_f(act, LV_SIGNAL_CONTROLL, &c);
}
/**
* Set a function for a group which will modify the object's style if it is in focus
* @param group pointer to a group
* @param style_cb the style modifier function pointer
*/
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style))
{
group->style_mod = style_cb;
if(group->obj_focus != NULL) lv_obj_inv(*group->obj_focus);
}
/**
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group
* @param style pointer to a style to modify
* @return a copy of the input style but modified with the 'style_mod' function
*/
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
{
lv_style_cpy(&group->style_tmp, style);
if(group->style_mod != NULL) group->style_mod(&group->style_tmp);
else style_mod_def(&group->style_tmp);
return &group->style_tmp;
}
/**
* Get the focused object or NULL if there isn't one
* @param group pointer to a group
* @return pointer to the focused object
*/
lv_obj_t * lv_group_get_focused(lv_group_t * group)
{
if(group == NULL) return NULL;
if(group->obj_focus == NULL) return NULL;
return *group->obj_focus;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Default style modifier function
* @param style pointer to a style to modify. (Typically &group->style_tmp) It will be OVERWRITTEN.
*/
static void style_mod_def(lv_style_t * style)
{
/*Make the style a little bit orange*/
style->bcolor = COLOR_ORANGE;
style->bopa = OPA_COVER;
if(style->bwidth == 0 && style->empty == 0) style->bwidth = 2 * LV_DOWNSCALE; /*Add border to not transparent styles*/
else style->bwidth = style->bwidth * 2; /*Make the border thicker*/
style->mcolor = color_mix(style->mcolor, COLOR_ORANGE, OPA_80);
style->gcolor = color_mix(style->gcolor, COLOR_ORANGE, OPA_80);
}
#endif /*LV_OBJ_GROUP != 0*/
/**
* @file lv_group.h
*
*/
#ifndef LV_GROUP_H
#define LV_GROUP_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#include "lv_obj.h"
/*********************
* DEFINES
*********************/
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
/*For compatibility in signal function define the keys regardless to LV_OBJ_GROUP*/
#define LV_GROUP_KEY_UP 17 /*0x11*/
#define LV_GROUP_KEY_DOWN 18 /*0x12*/
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/
#define LV_GROUP_KEY_LEFT 20 /*0x14*/
#define LV_GROUP_KEY_ESC 33 /*0x1B*/
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
#if LV_OBJ_GROUP != 0
/**********************
* TYPEDEFS
**********************/
typedef struct
{
ll_dsc_t obj_ll;
lv_obj_t ** obj_focus;
void (*style_mod)(lv_style_t * style);
lv_style_t style_tmp;
uint8_t frozen:1;
}lv_group_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
lv_group_t * lv_group_create(void);
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
void lv_group_rem_obj(lv_obj_t * obj);
void lv_group_focus_obj(lv_obj_t * obj);
void lv_group_focus_next(lv_group_t * group);
void lv_group_focus_prev(lv_group_t * group);
void lv_group_focus_freeze(lv_group_t * group, bool en);
void lv_group_send(lv_group_t * group, char c);
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
lv_obj_t * lv_group_get_focused(lv_group_t * group);
/**********************
* MACROS
**********************/
#endif /*LV_OBJ_GROUP != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_GROUP_H*/
......@@ -12,8 +12,10 @@
#include "lvgl/lv_obj/lv_dispi.h"
#include "lvgl/lv_obj/lv_obj.h"
#include "lvgl/lv_obj/lv_refr.h"
#include "lvgl/lv_obj/lv_group.h"
#include "lvgl/lv_app/lv_app.h"
#include "lvgl/lv_draw/lv_draw_rbasic.h"
#include "lv_group.h"
#include "misc/gfx/anim.h"
#include "hal/indev/indev.h"
#include <stdint.h>
......@@ -141,10 +143,14 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
#if LV_OBJ_FREE_NUM != 0
new_obj->free_num = 0;
#endif
#if LV_OBJ_FREE_P != 0
new_obj->free_p = NULL;
#endif
#if LV_OBJ_GROUP != 0
new_obj->group_p = NULL;
#endif
/*Set attributes*/
new_obj->click_en = 0;
new_obj->drag_en = 0;
......@@ -187,6 +193,9 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
#if LV_OBJ_FREE_P != 0
new_obj->free_p = NULL;
#endif
#if LV_OBJ_GROUP != 0
new_obj->group_p = NULL;
#endif
/*Set attributes*/
new_obj->click_en = 1;
......@@ -198,7 +207,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
new_obj->protect = LV_PROTECT_NONE;
new_obj->ext = NULL;
}
if(copy != NULL) {
......@@ -223,6 +231,13 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
new_obj->style_p = copy->style_p;
#if LV_OBJ_GROUP != 0
/*Add to the same group*/
if(copy->group_p != NULL) {
lv_group_add_obj(copy->group_p, new_obj);
}
#endif
lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy));
}
......@@ -405,12 +420,14 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
old_pos.x = lv_obj_get_x(obj);
old_pos.y = lv_obj_get_y(obj);
lv_obj_t * old_par = obj->par;
ll_chg_list(&obj->par->child_ll, &parent->child_ll, obj);
obj->par = parent;
lv_obj_set_pos(obj, old_pos.x, old_pos.y);
/*Notify the original parent because one of its children is lost*/
obj->par->signal_f(obj->par, LV_SIGNAL_CHILD_CHG, NULL);
old_par->signal_f(old_par, LV_SIGNAL_CHILD_CHG, NULL);
/*Notify the new parent about the child*/
parent->signal_f(parent, LV_SIGNAL_CHILD_CHG, obj);
......@@ -1234,20 +1251,28 @@ cord_t lv_obj_get_ext_size(lv_obj_t * obj)
*/
lv_style_t * lv_obj_get_style(lv_obj_t * obj)
{
if(obj->style_p != NULL) return obj->style_p;
else {
lv_style_t * style_act = obj->style_p;
if(style_act == NULL) {
lv_obj_t * par = obj->par;
while(par != NULL) {
if(par->style_p != NULL) {
if(par->style_p->glass == 0) return par->style_p;
if(par->style_p->glass == 0) {
style_act = par->style_p;
break;
}
}
par = par->par;
}
}
/*Never reach this, at least the screen has to be a style*/
return NULL;
#if LV_OBJ_GROUP != 0
if(obj->group_p != NULL) {
if(lv_group_get_focused(obj->group_p) == obj) {
style_act = lv_group_mod_style(obj->group_p, style_act);
}
}
#endif
return style_act;
}
/*-----------------
......@@ -1395,6 +1420,18 @@ void * lv_obj_get_free_p(lv_obj_t * obj)
}
#endif
#if LV_OBJ_GROUP != 0
/**
* Get the group of the object
* @param obj pointer to an object
* @return the pointer to group of the object
*/
void * lv_obj_get_group(lv_obj_t * obj)
{
return obj->group_p;
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
......@@ -1471,9 +1508,7 @@ static void lv_style_refr_core(void * style_p, lv_obj_t * obj)
lv_obj_t * i;
LL_READ(obj->child_ll, i) {
if(i->style_p == style_p || style_p == NULL) {
lv_obj_inv(i);
i->signal_f(i, LV_SIGNAL_STYLE_CHG, NULL);
lv_obj_inv(i);
lv_child_refr_style(i);
}
lv_style_refr_core(style_p, i);
......@@ -1523,13 +1558,16 @@ static void lv_obj_del_child(lv_obj_t * obj)
/*Remove the animations from this object*/
anim_del(obj, NULL);
/*Delete from the group*/
#if LV_OBJ_GROUP != 0
if(obj->group_p != NULL) lv_group_rem_obj(obj);
#endif
/*Remove the object from parent's children list*/
lv_obj_t * par = lv_obj_get_parent(obj);
ll_rem(&(par->child_ll), obj);
/* All children deleted.
* Now clean up the object specific data*/
/* Clean up the object specific data*/
obj->signal_f(obj, LV_SIGNAL_CLEANUP, NULL);
/*Delete the base objects*/
......
......@@ -72,19 +72,27 @@ typedef bool (* lv_design_f_t) (struct __LV_OBJ_T * obj, const area_t * mask_p,
typedef enum
{
/*General signals*/
LV_SIGNAL_CLEANUP,
LV_SIGNAL_CHILD_CHG,
LV_SIGNAL_CORD_CHG,
LV_SIGNAL_STYLE_CHG,
LV_SIGNAL_REFR_EXT_SIZE,
/*Display input related*/
LV_SIGNAL_PRESSED,
LV_SIGNAL_PRESSING,
LV_SIGNAL_PRESSING,
LV_SIGNAL_PRESS_LOST,
LV_SIGNAL_RELEASED,
LV_SIGNAL_LONG_PRESS,
LV_SIGNAL_LONG_PRESS_REP,
LV_SIGNAL_DRAG_BEGIN,
LV_SIGNAL_DRAG_END,
LV_SIGNAL_CHILD_CHG,
LV_SIGNAL_CORD_CHG,
LV_SIGNAL_STYLE_CHG,
LV_SIGNAL_REFR_EXT_SIZE,
LV_SIGNAL_DRAG_END,
/*Group related*/
LV_SIGNAL_FOCUS,
LV_SIGNAL_DEFOCUS,
LV_SIGNAL_CONTROLL,
}lv_signal_t;
typedef bool (* lv_signal_f_t) (struct __LV_OBJ_T * obj, lv_signal_t sign, void * param);
......@@ -106,6 +114,8 @@ typedef struct __LV_OBJ_T
void * free_p; /*Application specific pointer (set it freely)*/
#endif
void * group_p; /*Pointer to the group of the object*/
/*Attributes and states*/
uint8_t click_en :1; /*1: Can be pressed by a display input device*/
uint8_t drag_en :1; /*1: Enable the dragging*/
......@@ -159,13 +169,6 @@ typedef enum
LV_ALIGN_OUT_RIGHT_BOTTOM,
}lv_align_t;
typedef struct
{
color_t color;
opa_t opa;
}lv_objs_t;
typedef enum
{
LV_ANIM_NONE = 0,
......@@ -473,6 +476,7 @@ void lv_obj_set_free_num(lv_obj_t * obj, uint8_t free_num);
*/
void lv_obj_set_free_p(lv_obj_t * obj, void * free_p);
#endif
/**
* Animate an object
* @param obj pointer to an object to animate
......@@ -665,6 +669,14 @@ uint8_t lv_obj_get_free_num(lv_obj_t * obj);
void * lv_obj_get_free_p(lv_obj_t * obj);
#endif
#if LV_OBJ_GROUP != 0
/**
* Get the group of the object
* @param obj pointer to an object
* @return the pointer to group of the object
*/
void * lv_obj_get_group(lv_obj_t * obj);
#endif
/**********************
* MACROS
**********************/
......
......@@ -70,7 +70,6 @@ void lv_refr_init(void)
ptask_t* task;
task = ptask_create(lv_refr_task, LV_REFR_PERIOD, PTASK_PRIO_MID, NULL);
dm_assert(task);
}
/**
......@@ -130,7 +129,7 @@ void lv_inv_area(const area_t * area_p)
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
* time_ms: refresh time in [ms]
* px_num: not the drawn pixels but the number of affected pixels of the screen
* (more pixels are drawn with opacity areas)
* (more pixels are drawn because of overlapping objects)
*/
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t))
{
......@@ -257,15 +256,8 @@ static void lv_refr_area_no_vdb(const area_t * area_p)
*/
static void lv_refr_area_with_vdb(const area_t * area_p)
{
lv_vdb_t * vdb_p = lv_vdb_get();
/*Always use the full row*/
vdb_p->area.x1 = area_p->x1;
vdb_p->area.y1 = area_p->y1;
vdb_p->area.x2 = area_p->x2;
/*Calculate the max row num*/
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (vdb_p->area.x2 - vdb_p->area.x1 + 1);
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (area_get_width(area_p));
if(max_row > area_get_height(area_p)) max_row = area_get_height(area_p);
/*Round the row number with downscale*/
......@@ -273,20 +265,28 @@ static void lv_refr_area_with_vdb(const area_t * area_p)
max_row &= (~0x1);
#endif
/*Refresh all rows*/
cord_t row = area_p->y1;
/*Always use the full row*/
cord_t row;
cord_t row_last = 0;
for(row = area_p->y1; row + max_row - 1 <= area_p->y2; row += max_row) {
lv_vdb_t * vdb_p = lv_vdb_get();
/*Calc. the next y coordinates of VDB*/
vdb_p->area.x1 = area_p->x1;
vdb_p->area.x2 = area_p->x2;
vdb_p->area.y1 = row;
vdb_p->area.y2 = row + max_row - 1;
row_last = row + max_row - 1;
lv_refr_area_part_vdb(area_p);
}
/*If the last y coordinates are not handled yet ...*/
if(area_p->y2 != vdb_p->area.y2) {
if(area_p->y2 != row_last) {
lv_vdb_t * vdb_p = lv_vdb_get();
/*Calc. the next y coordinates of VDB*/
vdb_p->area.x1 = area_p->x1;
vdb_p->area.x2 = area_p->x2;
vdb_p->area.y1 = row;
vdb_p->area.y2 = area_p->y2;
......
......@@ -8,18 +8,31 @@
*********************/
#include "lv_conf.h"
#include "lv_style.h"
#include "lv_obj.h"
#include "misc/mem/dyn_mem.h"
/*********************
* DEFINES
*********************/
#define LV_STYLE_ANIM_RES 255 /*Animation max in 1024 steps*/
#define LV_STYLE_ANIM_SHIFT 8 /*log2(LV_STYLE_ANIM_RES)*/
#define VAL_PROP(v1, v2, r) v1 + (((v2-v1) * r) >> LV_STYLE_ANIM_SHIFT)
#define STYLE_ATTR_ANIM(attr, r) if(start->attr != end->attr) act->attr = VAL_PROP(start->attr, end->attr, r)
/**********************
* TYPEDEFS
**********************/
typedef struct {
const lv_style_t * style_start;
const lv_style_t * style_end;
lv_style_t * style_anim;
}lv_style_anim_dsc_t;
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val);
/**********************
* STATIC VARIABLES
......@@ -229,6 +242,84 @@ void lv_style_cpy(lv_style_t * dest, const lv_style_t * src)
memcpy(dest, src, sizeof(lv_style_t));
}
/**
* Create an animation from a pre-configured 'lv_style_anim_t' variable
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
*/
void lv_style_anim_create(lv_style_anim_t * anim)
{
lv_style_anim_dsc_t * dsc;
dsc = dm_alloc(sizeof(lv_style_anim_dsc_t));
dsc->style_anim = anim->style_anim;
dsc->style_start = anim->style_start;
dsc->style_end = anim->style_end;
anim_t a;
a.var = (void*)dsc;
a.start = 0;
a.end = LV_STYLE_ANIM_RES;
a.fp = (anim_fp_t)lv_style_aimator;
a.path = anim_get_path(ANIM_PATH_LIN);
a.end_cb = anim->end_cb;
a.act_time = anim->act_time;
a.time = anim->time;
a.playback = anim->playback;
a.playback_pause = anim->playback_pause;
a.repeat = anim->repeat;
a.repeat_pause = anim->repeat_pause;
anim_create(&a);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Used by the style animations to set the values of a style according to start and end style.
* @param dsc the 'animated variable' set by lv_style_anim_create()
* @param val the current state of the animation between 0 and LV_STYLE_ANIM_RES
*/
static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val)
{
const lv_style_t * start = dsc->style_start;
const lv_style_t * end = dsc->style_end;
lv_style_t * act = dsc->style_anim;
STYLE_ATTR_ANIM(opa, val);
STYLE_ATTR_ANIM(radius, val);
STYLE_ATTR_ANIM(bwidth, val);
STYLE_ATTR_ANIM(swidth, val);
STYLE_ATTR_ANIM(hpad, val);
STYLE_ATTR_ANIM(vpad, val);
STYLE_ATTR_ANIM(opad, val);
STYLE_ATTR_ANIM(line_space, val);
STYLE_ATTR_ANIM(letter_space, val);
STYLE_ATTR_ANIM(line_width, val);
STYLE_ATTR_ANIM(img_recolor, val);
act->mcolor = color_mix(end->mcolor, start->mcolor, val);
act->gcolor = color_mix(end->gcolor, start->gcolor, val);
act->bcolor = color_mix(end->bcolor, start->bcolor, val);
act->scolor = color_mix(end->scolor, start->scolor, val);
act->ccolor = color_mix(end->ccolor, start->ccolor, val);
if(val == 0) {
act->empty = start->empty;
act->glass = start->glass;
act->font = start->font;
act->stype = start->stype;
act->txt_align = start->txt_align;
}
if(val == LV_STYLE_ANIM_RES) {
act->empty = end->empty;
act->glass = end->glass;
act->font = end->font;
act->stype = end->stype;
act->txt_align = end->txt_align;
}
lv_style_refr_objs(dsc->style_anim);
}
......@@ -17,6 +17,7 @@ extern "C" {
#include "misc/gfx/color.h"
#include "misc/gfx/area.h"
#include "misc/gfx/font.h"
#include "misc/gfx/anim.h"
/*********************
* DEFINES
......@@ -83,6 +84,34 @@ typedef enum {
}lv_style_name_t;
typedef struct {
const lv_style_t * style_start; /*Pointer to the starting style*/
const lv_style_t * style_end; /*Pointer to the destination style*/
lv_style_t * style_anim; /*Pointer to a style to animate*/
anim_cb_t end_cb; /*Call it when the animation is ready*/
int16_t time; /*Animation time in ms*/
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
uint16_t playback_pause; /*Wait before play back*/
uint16_t repeat_pause; /*Wait before repeat*/
uint8_t playback :1; /*When the animation is ready play it back*/
uint8_t repeat :1; /*Repeat the animation infinitely*/
}lv_style_anim_t;
/* Example initialization
lv_style_anim_t a;
a.style_anim = &style_to_anim;
a.style_start = &style_1;
a.style_end = &style_2;
a.act_time = 0;
a.time = 1000;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
a.end_cb = NULL;
lv_style_anim_create(&a);
*/
/**********************
* GLOBAL PROTOTYPES
**********************/
......@@ -99,8 +128,20 @@ void lv_style_init (void);
*/
lv_style_t * lv_style_get(lv_style_name_t style_name, lv_style_t * copy);
/**
* Copy a style to an other
* @param dest pointer to the destination style
* @param src pointer to the source style
*/
void lv_style_cpy(lv_style_t * dest, const lv_style_t * src);
/**
* Create an animation from a pre-configured 'lv_style_anim_t' variable
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
*/
void lv_style_anim_create(lv_style_anim_t * anim);
/**********************
* MACROS
......
......@@ -20,7 +20,13 @@
/**********************
* TYPEDEFS
**********************/
#if LV_VDB_DOUBLE != 0
typedef enum {
LV_VDB_STATE_FREE = 0,
LV_VDB_STATE_ACTIVE,
LV_VDB_STATE_FLUSH,
} lv_vdb_state_t;
#endif
/**********************
* STATIC PROTOTYPES
**********************/
......@@ -28,7 +34,12 @@
/**********************
* STATIC VARIABLES
**********************/
#if LV_VDB_DOUBLE == 0
static lv_vdb_t vdb;
#else
static lv_vdb_t vdb[2];
static volatile lv_vdb_state_t vdb_state[2] = {LV_VDB_STATE_FREE, LV_VDB_STATE_FREE};
#endif
/**********************
* MACROS
......@@ -39,21 +50,53 @@ static lv_vdb_t vdb;
**********************/
/**
* Get the vdb variable
* @return pointer to the vdb variable
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
* @return pointer to the 'vdb' variable
*/
lv_vdb_t * lv_vdb_get(void)
{
#if LV_VDB_DOUBLE == 0
return &vdb;
#else
/*If already there is an active do nothing*/
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) return &vdb[0];
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) return &vdb[1];
/*Try to allocate a free VDB*/
if(vdb_state[0] == LV_VDB_STATE_FREE) {
vdb_state[0] = LV_VDB_STATE_ACTIVE;
return &vdb[0];
}
if(vdb_state[1] == LV_VDB_STATE_FREE) {
vdb_state[1] = LV_VDB_STATE_ACTIVE;
return &vdb[1];
}
return NULL; /*There wasn't free VDB (never happen)*/
#endif
}
/**
* Flush the content of the vdb
* Flush the content of the VDB
*/
void lv_vdb_flush(void)
{
lv_vdb_t * vdb_act = lv_vdb_get();
if(vdb_act == NULL) return;
#if LV_VDB_DOUBLE != 0
/* Wait the pending flush before starting this one
* (Don't forget: 'lv_vdb_flush_ready' has to be called when flushing is ready)*/
while(vdb_state[0] == LV_VDB_STATE_FLUSH || vdb_state[1] == LV_VDB_STATE_FLUSH);
/*Turn the active VDB to flushing*/
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) vdb_state[0] = LV_VDB_STATE_FLUSH;
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH;
#endif
#if LV_ANTIALIAS == 0
disp_map(vdb.area.x1, vdb.area.y1, vdb.area.x2, vdb.area.y2, vdb.buf);
disp_map(vdb_act->area.x1, vdb_act->area.y1, vdb_act->area.x2, vdb_act->area.y2, vdb_act->buf);
#else
/* Get the average of 2x2 pixels and put the result back to the VDB
* The reading goes much faster then the write back
......@@ -68,12 +111,12 @@ void lv_vdb_flush(void)
* */
cord_t x;
cord_t y;
cord_t w = area_get_width(&vdb.area);
color_t * in1_buf = vdb.buf; /*Pointer to the first row*/
color_t * in2_buf = vdb.buf + w; /*Pointer to the second row*/
color_t * out_buf = vdb.buf; /*Store the result here*/
for(y = vdb.area.y1; y < vdb.area.y2; y += 2) {
for(x = vdb.area.x1; x < vdb.area.x2; x += 2) {
cord_t w = area_get_width(&vdb_act->area);
color_t * in1_buf = vdb_act->buf; /*Pointer to the first row*/
color_t * in2_buf = vdb_act->buf + w; /*Pointer to the second row*/
color_t * out_buf = vdb_act->buf; /*Store the result here*/
for(y = vdb_act->area.y1; y < vdb_act->area.y2; y += 2) {
for(x = vdb_act->area.x1; x < vdb_act->area.x2; x += 2) {
/*If the pixels are the same do not calculate the average */
if(in1_buf->full == (in1_buf + 1)->full &&
......@@ -103,7 +146,19 @@ void lv_vdb_flush(void)
/* Now the full the VDB is filtered and the result is stored in the first quarter of it
* Write out the filtered map to the display*/
disp_map(vdb.area.x1 >> 1, vdb.area.y1 >> 1, vdb.area.x2 >> 1, vdb.area.y2 >> 1, vdb.buf);
disp_map(vdb_act->area.x1 >> 1, vdb_act->area.y1 >> 1, vdb_act->area.x2 >> 1, vdb_act->area.y2 >> 1, vdb_act->buf);
#endif
}
/**
* In 'LV_VDB_DOUBLE' mode has to be called when the 'disp_map'
* is ready with copying the map to a frame buffer.
*/
void lv_vdb_flush_ready(void)
{
#if LV_VDB_DOUBLE != 0
if(vdb_state[0] == LV_VDB_STATE_FLUSH) vdb_state[0] = LV_VDB_STATE_FREE;
if(vdb_state[1] == LV_VDB_STATE_FLUSH) vdb_state[1] = LV_VDB_STATE_FREE;
#endif
}
......
......@@ -34,15 +34,13 @@ typedef struct
color_t buf[LV_VDB_SIZE];
}lv_vdb_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Get the vdb variable
* @return pointer to the vdb variable
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
* @return pointer to the 'vdb' variable
*/
lv_vdb_t * lv_vdb_get(void);
......@@ -51,6 +49,13 @@ lv_vdb_t * lv_vdb_get(void);
*/
void lv_vdb_flush(void);
/**
* In 'LV_VDB_DOUBLE' mode has to be called when 'disp_map()'
* is ready with copying the map to a frame buffer.
*/
void lv_vdb_flush_ready(void);
/**********************
* MACROS
**********************/
......
......@@ -10,11 +10,11 @@
#include "lv_conf.h"
#if USE_LV_BTN != 0
#include "lvgl/lv_obj/lv_obj.h"
#include "lv_btn.h"
#include "../lv_obj/lv_group.h"
#include "../lv_draw/lv_draw.h"
#include "misc/gfx/area.h"
#include "misc/gfx/color.h"
#include "../lv_draw/lv_draw.h"
#include "lv_btn.h"
#include <stdbool.h>
#include <string.h>
......@@ -185,6 +185,31 @@ bool lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
if(ext->lpr_rep_action != NULL && state != LV_BTN_STATE_INA) {
valid = ext->lpr_rep_action(btn, param);
}
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
valid = ext->rel_action(btn, param);
}
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_REL);
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
valid = ext->rel_action(btn, param);
}
} else if(c == LV_GROUP_KEY_ENTER) {
if(lv_btn_get_tgl(btn) != false) {
lv_btn_state_t state = lv_btn_get_state(btn);
if(state == LV_BTN_STATE_REL) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
else if(state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TPR);
else if(state == LV_BTN_STATE_TREL) lv_btn_set_state(btn, LV_BTN_STATE_REL);
else if(state == LV_BTN_STATE_TPR) lv_btn_set_state(btn, LV_BTN_STATE_PR);
}
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
valid = ext->rel_action(btn, param);
}
}
}
}
......@@ -322,6 +347,50 @@ bool lv_btn_get_tgl(lv_obj_t * btn)
}
/**
* Get the release action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->rel_action;
}
/**
* Get the press action of a button
* @param btn pointer to a button object
* @return pointer to the press action function
*/
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->pr_action;
}
/**
* Get the long press action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->lpr_action;
}
/**
* Get the long press repeat action of a button
* @param btn pointer to a button object
* @return pointer to the long press repeat action function
*/
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->lpr_rep_action;
}
/**
* Get the style of a button in a given state
* @param btn pointer to a button object
* @param state a state from 'lv_btn_state_t' in which style should be get
......
......@@ -149,6 +149,32 @@ lv_btn_state_t lv_btn_get_state(lv_obj_t * btn);
bool lv_btn_get_tgl(lv_obj_t * btn);
/**
* Get the release action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn);
/**
* Get the press action of a button
* @param btn pointer to a button object
* @return pointer to the press action function
*/
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn);
/**
* Get the long press action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn);
/**
* Get the long press repeat action of a button
* @param btn pointer to a button object
* @return pointer to the long press repeat action function
*/
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn);
/**
* Get the style of a button in a given state
* @param btn pointer to a button object
* @param state a state from 'lv_btn_state_t' in which style should be get
......
......@@ -10,9 +10,10 @@
#if USE_LV_BTNM != 0
#include "lv_btnm.h"
#include "misc/gfx/text.h"
#include "../lv_obj/lv_group.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_obj/lv_refr.h"
#include "misc/gfx/text.h"
/*********************
* DEFINES
......@@ -29,6 +30,7 @@
static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_t mode);
static uint8_t lv_btnm_get_width_unit(const char * btn_str);
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p);
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id);
static void lv_btnm_create_btns(lv_obj_t * btnm, const char ** map);
/**********************
......@@ -155,18 +157,8 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
}
else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_LONG_PRESS_REP) {
if(ext->cb != NULL && ext->btn_pr != LV_BTNM_PR_NONE) {
uint16_t txt_i = 0;
uint16_t btn_i = 0;
/* Search the text of ext->btn_pr the buttons text in the map
* Skip "\n"-s*/
while(btn_i != ext->btn_pr) {
btn_i ++;
txt_i ++;
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
}
ext->cb(btnm, txt_i);
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
}
if(sign == LV_SIGNAL_RELEASED && ext->btn_pr != LV_BTNM_PR_NONE) {
......@@ -181,11 +173,30 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
ext->btn_pr = LV_BTNM_PR_NONE;
}
}
else if(sign == LV_SIGNAL_PRESS_LOST) {
} else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {
ext->btn_pr = LV_BTNM_PR_NONE;
lv_obj_inv(btnm);
} else if(sign == LV_SIGNAL_FOCUS) {
ext->btn_pr = 0;
lv_obj_inv(btnm);
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
else ext->btn_pr++;
if(ext->btn_pr >= ext->btn_cnt - 1) ext->btn_pr = ext->btn_cnt - 1;
lv_obj_inv(btnm);
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
if(ext->btn_pr > 0) ext->btn_pr--;
lv_obj_inv(btnm);
} else if(c == LV_GROUP_KEY_ENTER) {
if(ext->cb != NULL) {
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
}
}
}
}
......@@ -405,7 +416,12 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
uint16_t btn_i = 0;
uint16_t txt_i = 0;
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++) {
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++, txt_i ++) {
/*Search the next valid text in the map*/
while(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
if(ext->map_p[txt_i][1] == '\177') continue;
lv_obj_get_cords(btnm, &area_btnm);
area_cpy(&area_tmp, &ext->btn_areas[btn_i]);
......@@ -422,9 +438,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
lv_draw_rect(&area_tmp, mask, btn_style);
/*Search the next valid text in the map*/
while(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
/*Calculate the size of the text*/
const font_t * font = btn_style->font;
point_t txt_size;
......@@ -438,11 +451,8 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
area_tmp.y2 = area_tmp.y1 + txt_size.y;
lv_draw_label(&area_tmp, mask, btn_style, ext->map_p[txt_i], TXT_FLAG_NONE, NULL);
txt_i ++;
}
}
return true;
}
......@@ -486,6 +496,12 @@ static uint8_t lv_btnm_get_width_unit(const char * btn_str)
return 1;
}
/**
* Gives the button id of a button under a given point
* @param btnm pointer to a button matrix object
* @param p a point with absolute coordinates
* @return the id of the button or LV_BTNM_PR_NONE.
*/
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
{
area_t btnm_cords;
......@@ -510,5 +526,33 @@ static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
return i;
}
/**
* Get the text of a button
* @param btnm pointer to a button matrix object
* @param btn_id button id
* @return text id in ext->map_p or LV_BTNM_PR_NONE if 'btn_id' was invalid
*/
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id)
{
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
if(btn_id > ext->btn_cnt) return LV_BTNM_PR_NONE;
uint16_t txt_i = 0;
uint16_t btn_i = 0;
/* Search the text of ext->btn_pr the buttons text in the map
* Skip "\n"-s*/
while(btn_i != btn_id) {
btn_i ++;
txt_i ++;
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
}
if(btn_i == ext->btn_cnt) return LV_BTNM_PR_NONE;
return txt_i;
}
#endif
......@@ -10,6 +10,7 @@
#if USE_LV_CB != 0
#include "lv_cb.h"
#include "../lv_obj/lv_group.h"
/*********************
* DEFINES
......@@ -23,11 +24,14 @@
* STATIC PROTOTYPES
**********************/
static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mode);
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode);
/**********************
* STATIC VARIABLES
**********************/
static lv_design_f_t ancestor_design_f;
static lv_design_f_t ancestor_bg_design_f;
static lv_design_f_t ancestor_bullet_design_f;
/**********************
* MACROS
**********************/
......@@ -57,7 +61,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
ext->bullet = NULL;
ext->label = NULL;
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_cb);
if(ancestor_bg_design_f == NULL) ancestor_bg_design_f = lv_obj_get_design_f(new_cb);
lv_obj_set_signal_f(new_cb, lv_cb_signal);
lv_obj_set_design_f(new_cb, lv_cb_design);
......@@ -65,6 +69,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
/*Init the new checkbox object*/
if(copy == NULL) {
ext->bullet = lv_btn_create(new_cb, NULL);
if(ancestor_bullet_design_f == NULL) ancestor_bullet_design_f = lv_obj_get_design_f(ext->bullet);
lv_btn_set_styles(new_cb, lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
lv_style_get(LV_STYLE_TRANSP, NULL));
......@@ -88,6 +93,8 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
/*Refresh the style with new signal function*/
lv_obj_refr_style(new_cb);
}
lv_obj_set_design_f(ext->bullet, lv_bullet_design);
return new_cb;
}
......@@ -114,11 +121,17 @@ bool lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
if(valid != false) {
if(sign == LV_SIGNAL_STYLE_CHG) {
lv_obj_set_size(ext->bullet, font_get_height(style->font), font_get_height(style->font));
}
if(sign == LV_SIGNAL_PRESSED ||
} else if(sign == LV_SIGNAL_PRESSED ||
sign == LV_SIGNAL_RELEASED ||
sign == LV_SIGNAL_PRESS_LOST) {
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
} else if(sign == LV_SIGNAL_CONTROLL) {
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN ||
c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP ||
c == LV_GROUP_KEY_ENTER) {
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
}
}
}
......@@ -186,19 +199,62 @@ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mo
{
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return ancestor_design_f(cb, mask, mode);
return ancestor_bg_design_f(cb, mask, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN || mode == LV_DESIGN_DRAW_POST) {
lv_cb_ext_t * cb_ext = lv_obj_get_ext(cb);
lv_btn_ext_t * bullet_ext = lv_obj_get_ext(cb_ext->bullet);
/*Be sure he state of the bullet is the same as the parent button*/
/*Be sure the state of the bullet is the same as the parent button*/
bullet_ext->state = cb_ext->bg_btn.state;
return ancestor_design_f(cb, mask, mode);
return ancestor_bg_design_f(cb, mask, mode);
} else {
return ancestor_bg_design_f(cb, mask, mode);
}
/*Draw the object*/
return true;
}
/**
* Handle the drawing related tasks of the check boxes
* @param bullet pointer to an object
* @param mask the object will be drawn only in this area
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
* (return 'true' if yes)
* LV_DESIGN_DRAW: draw the object (always return 'true')
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return true/false, depends on 'mode'
*/
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode)
{
if(mode == LV_DESIGN_COVER_CHK) {
return ancestor_bullet_design_f(bullet, mask, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
#if LV_OBJ_GROUP != 0
/* If the check box is the active in a group and
* the background is not visible (transparent or empty)
* then activate the style of the bullet*/
lv_style_t * style_ori = lv_obj_get_style(bullet);
lv_obj_t * bg = lv_obj_get_parent(bullet);
lv_style_t * style_page = lv_obj_get_style(bg);
lv_group_t * g = lv_obj_get_group(bg);
if(style_page->empty != 0 || style_page->opa == OPA_TRANSP) { /*Background is visible?*/
if(lv_group_get_focused(g) == bg) {
lv_style_t * style_mod;
style_mod = lv_group_mod_style(g, style_ori);
bullet->style_p = style_mod; /*Temporally change the style to the activated */
}
}
#endif
ancestor_bullet_design_f(bullet, mask, mode);
#if LV_OBJ_GROUP != 0
bullet->style_p = style_ori; /*Revert the style*/
#endif
} else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_bullet_design_f(bullet, mask, mode);
}
return true;
}
......
/**
* @file lv_rect.c
* @file lv_cont.c
*
*/
......@@ -465,10 +465,19 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
h_row = lv_obj_get_height(child_rc); /*Not set previously because of the early break*/
}
}
/*If here is only one object in the row then align it to the middle*/
/*If there is only one object in the row then align it to the middle*/
else if (obj_num == 1) {
lv_obj_align(child_rs, cont, LV_ALIGN_IN_TOP_MID, 0, act_y);
}
/*If are two object in the row then align them proportionally*/
else if (obj_num == 2) {
lv_obj_t * obj1 = child_rs;
lv_obj_t * obj2 = ll_get_prev(&cont->child_ll, child_rs);
w_row = lv_obj_get_width(obj1) + lv_obj_get_width(obj2);
cord_t pad = (w_obj - w_row) / 3;
lv_obj_align(obj1, cont, LV_ALIGN_IN_TOP_LEFT, pad, act_y);
lv_obj_align(obj2, cont, LV_ALIGN_IN_TOP_RIGHT, -pad, act_y);
}
/* Align the children (from child_rs to child_rc)*/
else {
w_row -= style->opad * obj_num;
......
......@@ -13,6 +13,7 @@
#include "lv_ddlist.h"
#include "../lv_draw/lv_draw.h"
#include "misc/gfx/anim.h"
#include "../lv_obj/lv_group.h"
/*********************
* DEFINES
......@@ -70,6 +71,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
ext->opened = 0;
ext->auto_size = 0;
ext->sel_opt = 0;
ext->num_opt = 0;
ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
ext->style_sel = lv_style_get(LV_STYLE_PLAIN_COLOR, NULL);
......@@ -83,7 +85,8 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
if(copy == NULL) {
lv_obj_t * scrl = lv_page_get_scrl(new_ddlist);
lv_obj_set_drag(scrl, false);
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));;
lv_cont_set_fit(scrl, true, true);
ext->opt_label = lv_label_create(new_ddlist, NULL);
lv_cont_set_fit(new_ddlist, true, false);
......@@ -100,6 +103,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
ext->sel_opt = copy_ext->sel_opt;
ext->auto_size = copy_ext->auto_size;
ext->cb = copy_ext->cb;
ext->num_opt = copy_ext->num_opt;
/*Refresh the style with new signal function*/
lv_obj_refr_style(new_ddlist);
......@@ -129,7 +133,44 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param)
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
lv_obj_set_style(ext->opt_label, lv_obj_get_style(ddlist));
lv_ddlist_refr_size(ddlist, 0);
}
} else if(sign == LV_SIGNAL_FOCUS) {
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
if(ext->opened == false) {
ext->opened = true;
lv_ddlist_refr_size(ddlist, true);
}
} else if(sign == LV_SIGNAL_DEFOCUS) {
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
if(ext->opened != false) {
ext->opened = false;
lv_ddlist_refr_size(ddlist, true);
}
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
if(ext->sel_opt +1 < ext->num_opt) {
ext->sel_opt ++;
lv_obj_inv(ddlist);
if(ext->cb != NULL) {
ext->cb(ddlist, NULL);
}
}
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
if(ext->sel_opt > 0) {
ext->sel_opt --;
lv_obj_inv(ddlist);
if(ext->cb != NULL) {
ext->cb(ddlist, NULL);
}
}
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ESC) {
if(ext->opened != false) ext->opened = false;
if(ext->opened == false) ext->opened = true;
lv_ddlist_refr_size(ddlist, true);
}
}
}
return valid;
......@@ -158,6 +199,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
i++;
}
ext->num_opt = i;
lv_ddlist_refr_size(ddlist, 0);
}
......@@ -169,6 +212,15 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
void lv_ddlist_set_options_str(lv_obj_t * ddlist, const char * options)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
/*Count the '\n'-s to determine the number of options*/
ext->num_opt = 0;
uint16_t i;
for(i = 0; options[i] != '\0'; i++) {
if(options[i] == '\n') ext->num_opt++;
}
ext->num_opt++; /*Last option in the at row*/
lv_label_set_text(ext->opt_label, options);
lv_ddlist_refr_size(ddlist, 0);
}
......@@ -352,13 +404,12 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_m
const font_t * font = style->font;
cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS;
area_t rect_area;
lv_style_t * style_page_scrl = lv_obj_get_style(lv_page_get_scrl(ddlist));
rect_area.y1 = ext->opt_label->cords.y1;
rect_area.y1 += ext->sel_opt * (font_h + style->line_space);
rect_area.y1 -= style->line_space / 2;
rect_area.y2 = rect_area.y1 + font_h + style->line_space;
rect_area.x1 = ext->opt_label->cords.x1 - style_page_scrl->hpad;
rect_area.x1 = ext->opt_label->cords.x1 - style->hpad;
rect_area.x2 = rect_area.x1 + lv_obj_get_width(lv_page_get_scrl(ddlist));
lv_draw_rect(&rect_area, mask, ext->style_sel);
......@@ -417,7 +468,7 @@ static lv_action_res_t lv_ddlist_rel_action(lv_obj_t * ddlist, lv_dispi_t * disp
}
/**
* Refresh the size of drop down list according its start (open or closed)
* Refresh the size of drop down list according its status (open or closed)
* @param ddlist pointer to a drop down list object
* @param anim_time animations time for open/close [ms]
*/
......
......@@ -43,7 +43,8 @@ typedef struct
/*New data for this type */
lv_obj_t * opt_label; /*Label for the options*/
lv_style_t * style_sel; /*Style of the selected option*/
lv_action_t cb; /*Pointer to function to call when an option is slected*/
lv_action_t cb; /*Pointer to function to call when an option is selected*/
uint16_t num_opt; /*Number of options*/
uint16_t sel_opt; /*Index of the current option*/
uint16_t anim_time; /*Open/Close animation time [ms]*/
uint8_t opened :1; /*1: The list is opened*/
......
......@@ -13,6 +13,7 @@
#include "misc/math/math_base.h"
#include "lv_label.h"
#include "../lv_obj/lv_obj.h"
#include "../lv_obj/lv_group.h"
#include "misc/gfx/text.h"
#include "misc/gfx/anim.h"
#include "../lv_draw/lv_draw.h"
......@@ -83,6 +84,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, lv_obj_t * copy)
ext->txt = NULL;
ext->static_txt = 0;
ext->recolor = 0;
ext->no_break = 0;
ext->dot_end = LV_LABEL_DOT_END_INV;
ext->long_mode = LV_LABEL_LONG_EXPAND;
ext->offset.x = 0;
......@@ -307,6 +309,19 @@ void lv_label_set_recolor(lv_obj_t * label, bool recolor)
lv_label_refr_text(label);
}
/**
* Set the label the ignore (or accept) line breaks on '\n'
* @param label pointer to a label object
* @param en true: ignore line breaks, false: make line breaks on '\n'
*/
void lv_label_set_no_break(lv_obj_t * label, bool en)
{
lv_label_ext_t * ext = lv_obj_get_ext(label);
ext->no_break = en == false ? 0 : 1;
lv_label_refr_text(label);
}
/*=====================
* Getter functions
*====================*/
......@@ -366,6 +381,7 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos)
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
/*If the width will be expanded the set the max length to very big */
if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) {
......@@ -401,6 +417,8 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos)
}
if(x > style->letter_space) x-= style->letter_space;
if(style->txt_align == LV_TXT_ALIGN_MID) {
cord_t line_w;
line_w = txt_get_width(&txt[line_start], new_line_start - line_start,
......@@ -434,6 +452,7 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos)
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
/*If the width will be expanded set the max length to very big */
if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) {
......@@ -468,11 +487,9 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos)
}
x += (font_get_width(font, txt[i]) >> FONT_ANTIALIAS) + style->letter_space;
if(pos->x < x) break;
}
return i;
}
......@@ -496,25 +513,27 @@ static bool lv_label_design(lv_obj_t * label, const area_t * mask, lv_design_mod
/* A label never covers an area */
if(mode == LV_DESIGN_COVER_CHK) return false;
else if(mode == LV_DESIGN_DRAW_MAIN) {
/*TEST: draw a background for the label*/
area_t cords;
lv_style_t * style = lv_obj_get_style(label);
lv_obj_get_cords(label, &cords);
#if LV_OBJ_GROUP != 0
lv_group_t * g = lv_obj_get_group(label);
if(lv_group_get_focused(g) == label) {
lv_draw_rect(&cords, mask, style);
}
#endif
/*TEST: draw a background for the label*/
//lv_vfill(&label->cords, mask, COLOR_LIME, OPA_COVER);
area_t cords;
lv_obj_get_cords(label, &cords);
lv_label_ext_t * ext = lv_obj_get_ext(label);
txt_flag_t flag = TXT_FLAG_NONE;
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
if(strcmp("Folder1", ext->txt) == 0) {
uint8_t i;
i = 0;
i++;
}
lv_draw_label(&cords, mask, lv_obj_get_style(label), ext->txt, flag, &ext->offset);
lv_draw_label(&cords, mask, style, ext->txt, flag, &ext->offset);
}
return true;
}
......@@ -546,6 +565,7 @@ static void lv_label_refr_text(lv_obj_t * label)
txt_flag_t flag = TXT_FLAG_NONE;
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
txt_get_size(&size, ext->txt, font, style->letter_space, style->line_space, max_w, flag);
/*Refresh the full size in expand mode*/
......
......@@ -48,10 +48,11 @@ typedef struct
lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/
char dot_tmp[LV_LABEL_DOT_NUM + 1]; /*Store the character which are replaced by dots (Handled by the library)*/
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
point_t offset;
point_t offset; /*Text draw position offset*/
uint8_t static_txt :1; /*Flag to indicate the text is static*/
uint8_t recolor :1; /*Enable in-line letter re-coloring*/
uint8_t expand :1; /*Force expand size when solving line length (used by the library with LV_LABEL_LONG_ROLL)*/
uint8_t expand :1; /*Ignore real width (used by the library with LV_LABEL_LONG_ROLL)*/
uint8_t no_break :1; /*Ignore new line characters*/
}lv_label_ext_t;
/**********************
......@@ -119,12 +120,13 @@ void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode);
*/
void lv_label_set_recolor(lv_obj_t * label, bool recolor);
/**
* Enable the password mode
* Set the label the ignore (or accept) line breaks on '\n'
* @param label pointer to a label object
* @param pwd true: enable password mode, false: disable
* @param en true: ignore line breaks, false: make line breaks on '\n'
*/
void lv_label_set_pwd_mode(lv_obj_t * label, bool pwd);
void lv_label_set_no_break(lv_obj_t * label, bool en);
/**
* Get the text of a label
......
......@@ -142,6 +142,20 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style);
const char * lv_list_get_element_text(lv_obj_t * liste);
/**
* Get the label object from a list element
* @param liste pointer to a list element (button)
* @return pointer to the label from the list element or NULL if not found
*/
lv_obj_t * lv_list_get_element_label(lv_obj_t * liste);
/**
* Get the image object from a list element
* @param liste pointer to a list element (button)
* @return pointer to the image from the list element or NULL if not found
*/
lv_obj_t * lv_list_get_element_img(lv_obj_t * liste);
/**
* Get the scroll bar outside attribute
* @param list pointer to list object
* @param en true: scroll bar outside the buttons, false: scroll bar inside
......
......@@ -11,6 +11,7 @@
#if USE_LV_MBOX != 0
#include "lv_mbox.h"
#include "lvgl/lv_obj/lv_group.h"
#include "misc/gfx/anim.h"
#include "misc/math/math_base.h"
......@@ -132,13 +133,11 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
area_get_height(param) != lv_obj_get_height(mbox)) {
lv_mbox_realign(mbox);
}
}
else if(sign == LV_SIGNAL_LONG_PRESS) {
} else if(sign == LV_SIGNAL_LONG_PRESS) {
lv_mbox_start_auto_close(mbox, 0);
lv_dispi_wait_release(param);
valid = false;
}
else if(sign == LV_SIGNAL_STYLE_CHG) {
} else if(sign == LV_SIGNAL_STYLE_CHG) {
/*Refresh all the buttons*/
if(ext->btnh != NULL) {
lv_obj_t * btn;
......@@ -150,6 +149,90 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
btn = lv_obj_get_child(ext->btnh, btn);
}
}
} else if(sign == LV_SIGNAL_FOCUS) {
/*Get the first button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
lv_obj_t * btn_prev = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
btn_prev = btn;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn_prev != NULL) {
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
}
}
} else if(sign == LV_SIGNAL_DEFOCUS) {
/*Get the 'pressed' button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
}
}
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_mbox_ext_t * ext = lv_obj_get_ext(mbox);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
/*Get the last pressed button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
lv_obj_t * btn_prev = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn_prev = btn;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn_prev != NULL && btn != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
}
}
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
/*Get the last pressed button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn != NULL) {
lv_obj_t * btn_prev = lv_obj_get_child(ext->btnh, btn);
if(btn_prev != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
}
}
}
} else if(c == LV_GROUP_KEY_ENTER) {
/*Get the 'pressed' button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn != NULL) {
lv_action_t rel_action;
rel_action = lv_btn_get_rel_action(btn);
if(rel_action != NULL) rel_action(btn, NULL);
}
}
}
}
}
......
......@@ -10,12 +10,14 @@
#if USE_LV_SLIDER != 0
#include "lv_slider.h"
#include "lvgl/lv_obj/lv_group.h"
#include "misc/math/math_base.h"
#include "../lv_draw/lv_draw.h"
/*********************
* DEFINES
*********************/
#define LV_SLIDER_SIZE_MIN (2 * LV_DOWNSCALE) /*hpad and vpad cannot make the bar or indicator smaller then this [px]*/
/**********************
* TYPEDEFS
......@@ -52,7 +54,6 @@ static lv_design_f_t ancestor_design_f;
lv_obj_t * lv_slider_create(lv_obj_t * par, lv_obj_t * copy)
{
/*Create the ancestor slider*/
/*TODO modify it to the ancestor create function */
lv_obj_t * new_slider = lv_bar_create(par, copy);
dm_assert(new_slider);
......@@ -102,7 +103,6 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
bool valid;
/* Include the ancient signal function */
/* TODO update it to the ancestor's signal function*/
valid = lv_bar_signal(slider, sign, param);
/* The object can be deleted so check its validity and then
......@@ -145,10 +145,19 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
lv_obj_get_height(slider) != area_get_height(param)) {
slider->signal_f(slider, LV_SIGNAL_REFR_EXT_SIZE, NULL);
}
}
else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
} else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
cord_t x = MATH_MIN(w, h);
if(slider->ext_size < x) slider->ext_size = x;
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_slider_ext_t * ext = lv_obj_get_ext(slider);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
lv_bar_set_value(slider, lv_bar_get_value(slider) + 1);
if(ext->cb != NULL) ext->cb(slider, NULL);
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
lv_bar_set_value(slider, lv_bar_get_value(slider) - 1);
if(ext->cb != NULL) ext->cb(slider, NULL);
}
}
}
......@@ -238,24 +247,47 @@ static bool lv_slider_design(lv_obj_t * slider, const area_t * mask, lv_design_m
lv_style_t * style_knob = lv_slider_get_style_knob(slider);
lv_style_t * style_indic = lv_bar_get_style_indic(slider);
/*Draw the bar*/
area_t area_bar;
area_cpy(&area_bar, &slider->cords);
area_bar.x1 += style_knob->hpad;
area_bar.x2 -= style_knob->hpad;
area_bar.y1 += style_knob->vpad;
area_bar.y2 -= style_knob->vpad;
/*Be sure at least vpad/hpad width bar will remain*/
cord_t vpad_bar = style_indic->vpad;
cord_t hpad_bar = style_indic->hpad;
if(vpad_bar * 2 + LV_SLIDER_SIZE_MIN > area_get_height(&area_bar)) {
vpad_bar = (area_get_height(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
}
if(hpad_bar * 2 + LV_SLIDER_SIZE_MIN > area_get_width(&area_bar)) {
hpad_bar = (area_get_width(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
}
area_bar.x1 += hpad_bar;
area_bar.x2 -= hpad_bar;
area_bar.y1 += vpad_bar;
area_bar.y2 -= vpad_bar;
lv_draw_rect(&area_bar, mask, style_slider);
/*Draw the indicator*/
area_t area_indic;
area_cpy(&area_indic, &area_bar);
area_indic.x1 += style_indic->hpad;
area_indic.x2 -= style_indic->hpad;
area_indic.y1 += style_indic->vpad;
area_indic.y2 -= style_indic->vpad;
/*Be sure at least vpad/hpad width indicator will remain*/
cord_t vpad_indic = style_indic->vpad;
cord_t hpad_indic = style_indic->hpad;
if(vpad_indic * 2 + LV_SLIDER_SIZE_MIN > area_get_height(&area_bar)) {
vpad_indic = (area_get_height(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
}
if(hpad_indic * 2 + LV_SLIDER_SIZE_MIN > area_get_width(&area_bar)) {
hpad_indic = (area_get_width(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
}
area_indic.x1 += hpad_indic;
area_indic.x2 -= hpad_indic;
area_indic.y1 += vpad_indic;
area_indic.y2 -= vpad_indic;
cord_t slider_w = area_get_width(&slider->cords);
cord_t slider_h = area_get_height(&slider->cords);
cord_t act_value = lv_bar_get_value(slider);
cord_t min_value = lv_bar_get_min_value(slider);
cord_t max_value = lv_bar_get_max_value(slider);
......
......@@ -11,6 +11,7 @@
#if USE_LV_TA != 0
#include "lv_ta.h"
#include "lvgl/lv_obj/lv_group.h"
#include "misc/gfx/anim.h"
#include "../lv_draw/lv_draw.h"
......@@ -114,6 +115,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy)
lv_ta_ext_t * copy_ext = lv_obj_get_ext(copy);
ext->label = lv_label_create(new_ta, copy_ext->label);
ext->cursor_show = copy_ext->cursor_show;
ext->pwd_mode = copy_ext->pwd_mode;
lv_page_glue_obj(ext->label, true);
/*Refresh the style with new signal function*/
......@@ -158,32 +160,39 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
if(valid != false) {
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
lv_style_t * style = lv_obj_get_style(ta);
switch(sign) {
case LV_SIGNAL_CLEANUP:
/* Nothing to clean up.
* (The created label will be deleted automatically) */
break;
case LV_SIGNAL_STYLE_CHG:
if(ext->label) {
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
(style->hpad + style->hpad));
lv_label_set_text(ext->label, NULL);
}
break;
if(sign == LV_SIGNAL_CLEANUP) {
if(ext->pwd_tmp != NULL) dm_free(ext->pwd_tmp);
/* (The created label will be deleted automatically) */
} else if(sign == LV_SIGNAL_STYLE_CHG) {
if(ext->label) {
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
(style->hpad + style->hpad));
lv_label_set_text(ext->label, NULL);
}
} else if(sign == LV_SIGNAL_CORD_CHG) {
/*Set the label width according to the text area width*/
case LV_SIGNAL_CORD_CHG:
if(ext->label != NULL) {
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
(style->hpad + style->hpad));
if(ext->label != NULL) {
if(lv_obj_get_width(ta) != area_get_width(param) ||
lv_obj_get_height(ta) != area_get_height(param)) {
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 * style->hpad);
lv_label_set_text(ext->label, NULL);
}
break;
default:
break;
}
}
}
} else if (sign == LV_SIGNAL_CONTROLL) {
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT) {
lv_ta_cursor_right(ta);
} else if(c == LV_GROUP_KEY_LEFT) {
lv_ta_cursor_left(ta);
} else if(c == LV_GROUP_KEY_UP) {
lv_ta_cursor_up(ta);
} else if(c == LV_GROUP_KEY_DOWN) {
lv_ta_cursor_down(ta);
}
}
}
return valid;
}
......@@ -305,6 +314,12 @@ void lv_ta_set_text(lv_obj_t * ta, const char * txt)
lv_label_set_text(ext->label, txt);
lv_ta_set_cursor_pos(ta, LV_TA_CUR_LAST);
/*Don't let 'width == 0' because cursor will not be visible*/
if(lv_obj_get_width(ext->label) == 0) {
lv_style_t * style = lv_obj_get_style(ext->label);
lv_obj_set_width(ext->label, style->line_width);
}
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x(ta);
......@@ -346,6 +361,11 @@ void lv_ta_del(lv_obj_t * ta)
/*Refresh the label*/
lv_label_set_text(ext->label, buf);
/*Don't let 'width == 0' because cursor will not be visible*/
if(lv_obj_get_width(ext->label) == 0) {
lv_style_t * style = lv_obj_get_style(ext->label);
lv_obj_set_width(ext->label, style->line_width);
}
/*Move the cursor to the place of the deleted character*/
lv_ta_set_cursor_pos(ta, lv_ta_get_cursor_pos(ta) - 1);
......@@ -397,6 +417,16 @@ void lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos)
lv_obj_set_y(label_par, -(cur_pos.y - lv_obj_get_height(ta) +
font_h + 2 * style_scrl->vpad));
}
/*Check the left (use the font_h as general unit)*/
if(lv_obj_get_x(label_par) + cur_pos.x < font_h) {
lv_obj_set_x(label_par, - cur_pos.x + font_h);
}
/*Check the right (use the font_h as general unit)*/
if(label_cords.x1 + cur_pos.x + font_h + style_scrl->hpad > ta_cords.x2) {
lv_obj_set_x(label_par, -(cur_pos.x - lv_obj_get_width(ta) +
font_h + 2 * style_scrl->hpad));
}
lv_obj_inv(ta);
}
......@@ -526,6 +556,36 @@ void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en)
ext->pwd_mode = en == false ? 0 : 1;
}
/**
* Configure the text area to one line or back to normal
* @param ta pointer to a Text area object
* @param en true: one line, false: normal
*/
void lv_ta_set_one_line(lv_obj_t * ta, bool en)
{
if(en != false) {
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
lv_style_t * style_ta = lv_obj_get_style(ta);
lv_style_t * style_label = lv_obj_get_style(ext->label);
lv_cont_set_fit(lv_page_get_scrl(ta), true, true);
lv_obj_set_height(ta, font_get_height(style_label->font) + style_ta->vpad * 2);
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_EXPAND);
lv_label_set_no_break(ext->label, true);
lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->hpad, style_ta->vpad);
} else {
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
lv_style_t * style_ta = lv_obj_get_style(ta);
lv_cont_set_fit(lv_page_get_scrl(ta), false, true);
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK);
lv_label_set_no_break(ext->label, false);
lv_obj_set_height(ta, LV_TA_DEF_HEIGHT);
lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->hpad, style_ta->vpad);
}
}
/*=====================
* Getter functions
*====================*/
......@@ -657,9 +717,9 @@ static bool lv_ta_scrling_design(lv_obj_t * scrling, const area_t * mask, lv_des
area_t cur_area;
lv_style_t * labels_p = lv_obj_get_style(ta_ext->label);
cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1;
cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 - scrl_style->line_width / 2 ;
cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1;
cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + scrl_style->line_width ;
cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + scrl_style->line_width / 2 + (scrl_style->line_width & 0x1);
cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + (font_get_height(labels_p->font) >> FONT_ANTIALIAS);
lv_style_t cur_rects;
......
......@@ -148,6 +148,13 @@ void lv_ta_set_cursor_show(lv_obj_t * ta, bool show);
void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en);
/**
* Configure the Text area to one line or back to normal
* @param ta pointer to a text area object
* @param en true: one line, false: normal
*/
void lv_ta_set_one_line(lv_obj_t * ta, bool en);
/**
* Get the text of the i the text area
* @param ta obj pointer to a text area object
* @return pointer to the text
......
......@@ -17,6 +17,7 @@ extern "C" {
/*Test misc. module version*/
#include "misc/misc.h"
#include "lv_obj/lv_obj.h"
#include "lv_obj/lv_group.h"
#include "lv_objx/lv_btn.h"
#include "lv_objx/lv_img.h"
#include "lv_objx/lv_label.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment