Skip to content

Commit

Permalink
updated examples in readme and docs to reflect changed API in 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
abhra0897 committed Mar 5, 2023
1 parent 6a03462 commit 7d33d59
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 462 deletions.
157 changes: 39 additions & 118 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,38 +51,24 @@ Following UI widgets are implemented so far:
11. Panel
12. Scene

## Usage
LameUI needs 3 callback functions from user to draw on display and read inputs.
## Usage {#quickstart_page}
LameUI needs 2 callback functions from user to draw on display and read inputs.

1. `draw_pixels_area_cb` to *Display Output*. (**Mandatory**)
2. `render_complete_cb` to *Display Output*. (**Optional**)
3. `read_touch_input_cb` to *Read Inputs*. (**Optional**)
1. `draw_pixels_buff_cb` to *Display Output*. (**Mandatory**)
2. `read_touch_input_cb` to *Read Inputs*. (**Optional**)

### Display Output
**1. `draw_pixels_area_cb`**
Drawing to display is done by callback functions provided by the user.
### **1. `draw_pixels_buff_cb`** [ Display Output ]
Drawing to display is done by callback functions provided by the user. Register this callback using:

```C
void lui_dispdrv_set_draw_pixels_area_cb(lui_dispdrv_t* dispdrv, void (*draw_pixels_area_cb)(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color));
void lui_dispdrv_set_draw_disp_buff_cb(lui_dispdrv_t* dispdrv, void (*draw_pixels_buff_cb)(uint16_t* disp_buff, lui_area_t* area));
```
Note: `lui_dispdrv_set_disp_buff(lui_dispdrv_t* dispdrv, uint16_t* disp_buff, uint16_t size_in_px)` must be called to set the display buffer. Else, `draw_pixels_buff_cb()` callback won't work.
**2. `render_complete_cb`**
LameUI has no frame buffer of its own. Because it's mainly targeted towards MCUs with low RAM. As a result, user need to manage buffering if they need to. Sometimes buffering, and then flushing the entire buffer is faster than writing individual pixels each time.
### **2. `read_touch_input_cb`** [ Read Inputs ]
That's why LameUI calls `void (*render_complete_cb)();` when rendering is complete, given that user provided the callback function. In that callback function, user should flush the buffer. This is useful when user is buffering the draw calls.
For setting the callback function, this function is used:
```C
void lui_dispdrv_set_render_complete_cb(lui_dispdrv_t* dispdrv, void (*render_complete_cb)());
```

Note: Commonly available lcd displays that we use with microcontroller have built-in GRAM, hence, the `render_complete_cb()` is not mandatory for them.

### Read Inputs
**3. `read_touch_input_cb`**

LameUI now only supports touch input. Support for D-Pad / Rotary encoder is in my mind, but that's not the priority for now.
LameUI now only supports touch input. Support for D-Pad / Rotary encoder is in my mind, but that's not the priority for now. Register this callback using:
```C
void lui_touch_inputdev_set_read_input_cb(lui_touch_input_dev_t* touch_inputdev, void (*read_touch_input_cb)(lui_touch_input_data_t* touch_inputdata));
Expand All @@ -102,12 +88,19 @@ This is a very simple example using TFT_eSPI library on Arduino framework. In th
#include <SPI.h>
// ... [ Include LameUI library and other required headers too] ...

#define HOR_RES 320
#define VERT_RES 240
#define DISP_BUFF_PX_CNT (HOR_RES * 10)

uint16_t disp_buffer[DISP_BUFF_PX_CNT];

TFT_eSPI tft = TFT_eSPI(); // Invoke library
uint8_t lui_memory[4000];

void draw_pixels_area_cb(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color)
void draw_disp_buff_cb(uint16_t* disp_buff, lui_area_t* area);
{
tft.fillRect(x, y, w, h, color);
tft.setAddrWindow(area->x, area->y, area->w, area->h);
tft.pushColors(disp_buff, (area->w * area->h), 1);
}
void read_touch_input_cb(lui_touch_input_data_t* inputdata)
{
Expand All @@ -130,7 +123,7 @@ void read_touch_input_cb(lui_touch_input_data_t* inputdata)

void setup(void)
{
// Initilaize tft
// Initialize tft
tft.init();
tft.setTouch(touch_cal_data);

Expand All @@ -140,9 +133,9 @@ void setup(void)
// Create a display driver object
lui_dispdrv_t* display_driver = lui_dispdrv_create();
lui_dispdrv_register(display_driver);
lui_dispdrv_set_resolution(display_driver, 240, 320);
lui_dispdrv_set_draw_pixels_area_cb(display_driver, draw_pixels_area_cb);
lui_dispdrv_set_render_complete_cb(display_driver, NULL);
lui_dispdrv_set_resolution(display_driver, HOR_RES, VERT_RES);
lui_dispdrv_set_disp_buff(my_display_driver, disp_buffer, DISP_BUFF_PX_CNT);
lui_dispdrv_set_draw_disp_buff_cb(my_display_driver, draw_disp_buff_cb);

// Create touch input device
lui_touch_input_dev_t* input_device = lui_touch_inputdev_create();
Expand All @@ -164,7 +157,7 @@ void loop()
**[ Part 2 ]**
This is a more detailed LameUI example code. It looks big, but that's only because multiple ways of handling draw calls are shown here. Implementation of `my_draw_pixels_cb()` function can be simplified as per user's need. Also, `my_render_cmplt_cb()` is optional and can be omitted if not needed. The example code itself is pretty simple and well commented.
This example shows how to create a simple text label and button.
```C
#include<stdio.h>
Expand All @@ -174,24 +167,15 @@ This is a more detailed LameUI example code. It looks big, but that's only becau
#define HOR_RES 320
#define VERT_RES 240
// [Mandatory] Display buffer. Buffer pixel count must be multiple of Horizontal Resolution
#define DISP_BUFF_PX_CNT (HOR_RES * 10)
uint16_t disp_buffer[DISP_BUFF_PX_CNT];
// [Mandatory] LameUI memory. Here we are giving it 2KB to work with.
uint8_t lameui_memory[2000];
// [Optional] LameUI does NOT use display buffer. This is used only if user wants
// to buffer on their own.

// Uncomment below line to enable display buffering. Buffering is handled by user and NOT by LameUI.
//#define USE_BUFFERING
#ifdef USE_BUFERING
#define DISPLAY_BUFF_SIZE (HOR_RES * VERT_RES) // Only full screen buffer is possible (no partial buffer)
uint16_t display_buffer[DISPLAY_BUFF_SIZE];
uint32_t display_buff_counter = 0;
#endif

//----------- callback function prototypes ------------
void my_draw_pixels_cb (uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
void my_render_cmplt_cb();
void my_draw_disp_buff_cb (uint16_t* disp_buff, lui_area_t* area);
void my_input_read_cb (lui_touch_input_data_t *input);
void button_1_cb(lui_obj_t* button_obj);
//-----------------------------------------------------
Expand All @@ -207,12 +191,8 @@ int main ()
lui_dispdrv_t *my_display_driver = lui_dispdrv_create();
lui_dispdrv_register(my_display_driver);
lui_dispdrv_set_resolution(my_display_driver, HOR_RES, VERT_RES);
lui_dispdrv_set_draw_pixels_area_cb(my_display_driver, my_draw_pixels_cb);
// Setting render complete callback is optional.
// Only needed if user is buffering the draw calls.
#ifdef USE_BUFERING
lui_dispdrv_set_render_complete_cb(my_display_driver, my_render_cmplt_cb);
#endif
lui_dispdrv_set_disp_buff(my_display_driver, disp_buffer, DISP_BUFF_PX_CNT);
lui_dispdrv_set_draw_disp_buff_cb(my_display_driver, my_draw_disp_buff_cb);
//[Optional] creating input device object
lui_touch_input_dev_t *my_input_device = lui_touch_inputdev_create();
Expand Down Expand Up @@ -251,81 +231,22 @@ int main ()
// LameUI has no built-in timer. So, update LameUI periodically.
// lui_update() function reads inputs, checks if anything needs to be drawn, and fires callbacks if and when needed.
lui_update();
sleep_ms(30);
sleep_ms(15);
}
return 0;
}
//----------- callback function definitions ------------
void my_draw_pixels_cb (uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
{
// Assuming user has at least one of these functions:
// 1. display_put_pixel(x, y, color); // Draw a single pixel
// 2. display_put_pixels(x1, y1, x2, y2, color) // Fill an area with same color
// 3. display_fill(color_buffer, x1, y1, x2, y2); // Fill an area with different colors from a buffer


#ifdef USE_BUFERING
// When using buffering, we'll put pixels inside a full-screen buffer.
// Fill the display with buffer when either the buffer is full, or when
// the `render_complete` callback is fired by LameUI.

uint16_t temp_x = 0;
uint16_t temp_y = 0;
// Prepare the display buffer
// After the loop ends, the prepared buffer is flushed
for (temp_y = y; temp_y <= y + height - 1; temp_y++)
{
for (temp_x = x; temp_x <= x + width - 1; temp_x++)
{
display_buffer[HOR_RES * y + x] = color;
// increase the buffer counter
display_buff_counter++;

// If size reached max buffer size, flush it now
if (display_buff_counter >= DISPLAY_BUFF_SIZE)
{
display_fill(display_buffer, 0, 0, HOR_RES, VERT_RES) // Filling an area with multiple colors from a buffer
display_buff_counter = 0; //reset the counter
}
}
}

#else
// When not using buffering, directly draw those pixels.
// There are 2 ways. Uncomment the method user wants to use.

//------------------ [ Method 1] -----------------------------------
// Draw pixels one by 1. This is the easiest way to implement, but also slow.
//------------------------------------------------------------------
// for (uint16_t h = 0; h < height; h++)
// {
// for (uint16_t w = 0; w < width; w++)
// {
// display_put_pixel(x, y, color); // Filling a single pixel with a color
// }
// }
//------------------ [ Method 2] -----------------------------------
// Another even better way is to draw an area with same color, since most displays
// used in embedded systems support setting drawing area and then pass a color
// to fill that area. This saves rendering time.
//------------------------------------------------------------------
display_put_pixels(x, y, x + width - 1, y + height - 1, color); // Filling an area with same color

#endif
}

#ifdef USE_BUFERING
void my_render_cmplt_cb()
void my_draw_disp_buff_cb(uint16_t* disp_buff, lui_area_t* area);
{
display_fill(display_buffer, 0, 0, HOR_RES, VERT_RES) // display_fill(buffer, x1, y1, x2, y2)
display_buff_counter = 0; //reset the counter
uint16_t x = area->x; // start x
uint16_t y = area->y; // start y
uint16_t w = area->w; // width
uint16_t h = area->h; // height
display_draw_buffer(disp_buff, x, y, w, h);
}
#endif
void my_input_read_cb (lui_touch_input_data_t *input)
{
Expand Down Expand Up @@ -372,4 +293,4 @@ void button_1_cb(lui_obj_t* button_obj)
## Simple Examples
- Check example code fragments inside [lame_ui.h](lame_ui.h). Or visit [documentatin page](https://abhra0897.github.io/LameUI_docs/2.0/html/html/examples_page.html).
- See the Quick Start section
- go to the Simulator repo and see the example there: https://github.com/abhra0897/LameUI_simulation/blob/experimental/src/main.c. That example has all the UI elements. Ignore the parts that are related to OpenGL.
- go to the [Simulator repo](https://github.com/abhra0897/LameUI_simulation/) and see the examples there in the `src` dir. Ignore the parts that are related to OpenGL.
Loading

0 comments on commit 7d33d59

Please # to comment.