Circular progress bars are common in industrial / automobile applications. This section will explain how users may utilize LT768x to implement circular progress bars by simple codes.
In this example, we will call a command function that can skip the unneeded part of a picture, and only copy the needed part to LT768x SDRAM.
Take below picture as an example:
In the picture, the "unneeded" part is marked in black color. Users may simply call the below function to retrieve all the picture data execept for those in black.
void LT768_BTE_Memory_Copy_Chroma_key
(
unsigned long S0_Addr // Starting address (SDRAM) of S0 picture
,unsigned short S0_W // Width of the S0 picture
,unsigned short XS0 // Left-top X coordinate of the S0 picture
,unsigned short YS0 // Left-top Y coordinate of the S0 picture
,unsigned long Des_Addr // Starting address (SDRAM) of DT picture
,unsigned short Des_W // Width of the S0 picture
,unsigned short XDes // Left-top X coordinate of the DT picture
,unsigned short YDes // Left-top Y coordinate of the DT picture
,unsigned long Background_color // Color (chroma key) to be taken as transparent
,unsigned short X_W // Width of the active window
,unsigned short Y_H // Height of the active window
)
Note: S0 -> Source; DT -> Destination
Back to our progress bar example, there are three picutures used:
(1) P1: Background picture
(2) P2: Internal circular progress bar picture
(3) P3: External circular progress bar picture
These three pictures are all in the same resolution.
The background picture (P1) will be loaded to the display layer of LT768x SDRAM. We can get the progress bar data from P2 and P3, and then copy those data to combine with the background picture in the display layer to show different progresses on the LCD display.
How to capture a needed portion of the progress bar? Let's take the internal circular progress bar as an example. Firstly, narrow down the processing area, as shown below:
Next, fill "black" color to this area except for the portion that we want to show on the display. As illustrated in the below picture, the area inside the yellow boarder line is filled in black color; whereas, the area within the orange boarder line remains unchanged.
Now, when the function, LT768_BTE_Memory_Copy_Chroma_key, is called, the black area will be skipped, and only the non-black data within the orange boarder line will be moved to the display layer.
In the demo codes, the main function is: void CircularProgressBar(void)
Also, there are two subroutines:
void Fill_Black_Color(unsigned short X,unsigned short Y,unsigned short R,unsigned short angle)
=> As its name implies, this subroutine will fill black color to designated area.
void Show_DoubleCircular(unsigned short in_angle,unsigned short out_angle)
=> This function will move the needed data to the display layer to show the progress bars.
Codes are listed below for reference:
//------------------------------------------------ Circular Progress Bar ------------------------------------------------
// This example utilizes pictures with 800*480 resolution.
/*---------------------------------------------------------------------------------------*/
/* Function: Fill_Black_Color */
/* */
/* Parameters: */
/* X: X center of the circular progress bar */
/* Y: Y center of the circular progress bar */
/* R: Radius of the circular progress bar */
/* angle: rotation angle (progress) */
/* Returns: None */
/* Description: Fill black color to designated area, based on the rotation angle */
/*---------------------------------------------------------------------------------------*/
void Fill_Black_Color(unsigned short X,unsigned short Y,unsigned short R,unsigned short angle)
{
float a = 0;
float tan_x = 0;
float tan_y = 0;
int x,y;
a = angle;
if(a<=180)
{
LT768_DrawSquare_Fill(X,Y-R,X+R,Y+R,Black); // Fill black color to the area of 180~360 degree
if(a<=45)
{
tan_x = tan(a*(3.1415926/180));
x = X - (R)*tan_x;
LT768_DrawPentagon_Fill(X-R,Y-R, X,Y-R, X,Y, x,Y+R, X-R,Y+R ,Black);
}
else if((a>45)&&(a<=90))
{
tan_y = R*tan((90-a)*(3.1415926/180));
y = Y + tan_y;
LT768_DrawQuadrilateral_Fill(X-R,Y-R, X,Y-R, X,Y, X-R,y,Black);
}
else if((a>90)&&(a<=135))
{
tan_y = R*tan((a-90)*(3.1415926/180));
y = Y - tan_y;
LT768_DrawQuadrilateral_Fill(X-R,Y-R, X,Y-R, X,Y, X-R,y,Black);
}
else if((a>135)&&(a<=180))
{
tan_x = R*tan((180-a)*(3.1415926/180));
x = X - tan_x;
LT768_DrawTriangle_Fill(x,Y-R, X,Y-R, X,Y, Black);
}
}
else
{
if((a>180)&&(a<=225))
{
tan_x = R*tan((a-180)*(3.1415926/180));
x = X + tan_x;
LT768_DrawPentagon_Fill(X,Y, x,Y-R, X+R,Y-R, X+R,Y+R, X,Y+R ,Black);
}
else if((a>225)&&(a<=270))
{
tan_y = R*tan((270-a)*(3.1415926/180));
y = Y - tan_y;
LT768_DrawQuadrilateral_Fill(X,Y, X+R,y, X+R,Y+R, X,Y+R,Black);
}
else if((a>270)&&(a<=315))
{
tan_y = R*tan((a-270)*(3.1415926/180));
y = Y + tan_y;
LT768_DrawQuadrilateral_Fill(X,Y, X+R,y, X+R,Y+R, X,Y+R,Black);
}
else if((a>315)&&(a<=360))
{
tan_x = R*tan((360-a)*(3.1415926/180));
x = X + tan_x;
LT768_DrawTriangle_Fill(X,Y, x,Y+R, X,Y+R, Black);
}
}
}
/*---------------------------------------------------------------------------------------*/
/* Function: Show_DoubleCircular */
/* */
/* Parameters: None */
/* Returns: None */
/* Description: Display two circular progress bars */
/*---------------------------------------------------------------------------------------*/
/*
{800, 480, 0x00000000, 0x000BB800},//Base.bmp
{800, 480, 0x000BB800, 0x000BB800},//Inside.bmp
{800, 480, 0x00177000, 0x000BB800},//Outside.bmp
*/
// LAYER_3: (1) Store the processed data of internal progress bar; (2) Remove background, then copy to LAYER_2
// LAYER_4: (1) Store the processed data of external progress bar; (2) Remove background, then copy to LAYER_2
// LAYER_2: Finally copy the data of LAYER2 to display layer (LAYER_1)
// Circle center: The two circular progress bars shares the same center, (266, 266)
void Show_DoubleCircular(unsigned short in_angle,unsigned short out_angle)
{
//Canvas_Image_Start_address(LAYER_3);
LT768_BTE_Memory_Copy(LAYER_5,LCD_XSIZE_TFT,23,23, LAYER_5,LCD_XSIZE_TFT,23,23, LAYER_2,LCD_XSIZE_TFT,23,23, 0x0c,486,457);
Canvas_Image_Start_address(LAYER_3);
LT768_BTE_Memory_Copy(LAYER_6,LCD_XSIZE_TFT,104,104, LAYER_6,LCD_XSIZE_TFT,104,104, LAYER_3,LCD_XSIZE_TFT,104,104, 0x0c,324,324);
Fill_Black_Color(266,266,162,in_angle);
LT768_BTE_Memory_Copy_Chroma_key(
LAYER_3,LCD_XSIZE_TFT,104,104, // Copy non-black data in the designated area of LAYER_3
LAYER_2,LCD_XSIZE_TFT,104,104, // to LAYER_2
Black,324,324
);
Canvas_Image_Start_address(LAYER_4);
LT768_BTE_Memory_Copy(LAYER_7,LCD_XSIZE_TFT,23,23, LAYER_7,LCD_XSIZE_TFT,23,23, LAYER_4,LCD_XSIZE_TFT,23,23, 0x0c,486,457);
LT768_DrawCircle_Fill(266,266,162,Black); // Fill black color to the internal progress bar area
Fill_Black_Color(266,266,243,out_angle);
LT768_BTE_Memory_Copy_Chroma_key(
LAYER_4,LCD_XSIZE_TFT,23,23, // Copy non-black data in the designated area of LAYER_4
LAYER_2,LCD_XSIZE_TFT,23,23, // to LAYER_2
Black,486,457
);
// Renew the display layer by updated data in LAYER_2
LT768_BTE_Memory_Copy(LAYER_2,LCD_XSIZE_TFT,23,23, LAYER_2,LCD_XSIZE_TFT,23,23, LAYER_1,LCD_XSIZE_TFT,23,23, 0x0c,486,457);
}
/*----------------------------------------------------------------------------------------*/
/* Function: CircularProgressBar */
/* */
/* Parameters: None */
/* Returns: None */
/* Description: */
/* (1) Load background & progress bar pictures to SDRAM layers */
/* (2) Process these data and update the display by designated angles in loop */
/*----------------------------------------------------------------------------------------*/
void CircularProgressBar(void)
{
// LAYER_1: Display layer - Load background picture (800*480)
// LAYER_2: Load the background picture, only for 510*480
// LAYER_3: Load the internal progress bar picture, only for 510*480
// LAYER_4: Load the external progress bar picture only for 510*480
// LAYER_5: Buffer for LAYER_2
// LAYER_6: Buffer for LAYER_3
// LAYER_7: Buffer for LAYER_4
int i = 36 ; // Start angle of the internal progress bar
int j = 257; // Start angle of the external progress bar
Select_Main_Window_16bpp(); // Set main window color depth
Main_Image_Start_Address(LAYER_1); // Set main window start address - Display layer
Main_Image_Width(LCD_XSIZE_TFT); // Set main window width
Main_Window_Start_XY(0,0); // Set main window start coordinate
Canvas_Image_Start_address(LAYER_1); // Set canvas start address
Canvas_image_width(LCD_XSIZE_TFT); // Set canvas width
Active_Window_XY(0,0); // Set active window start coordinate
Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); // Set active window area
LT768_DMA_24bit_Block(1,0,0,0,800,480,800,0); // Load the background piccture from the flash
Canvas_Image_Start_address(LAYER_2);
Canvas_image_width(LCD_XSIZE_TFT);
LT768_DMA_24bit_Block(1,0,0,0,510,480,800,0); // Load the dynamic area of background picture to
Canvas_Image_Start_address(LAYER_5); // LAYER_2 & LAYER_5
Canvas_image_width(LCD_XSIZE_TFT);
LT768_DMA_24bit_Block(1,0,0,0,510,480,800,0);
Canvas_Image_Start_address(LAYER_3);
Canvas_image_width(LCD_XSIZE_TFT);
LT768_DMA_24bit_Block(1,0,0,0,510,480,800,800*480*2); // Load the dynamic area of internal progress bar picture to
Canvas_Image_Start_address(LAYER_6); // LAYER_3 & LAYER_6
Canvas_image_width(LCD_XSIZE_TFT);
LT768_DMA_24bit_Block(1,0,0,0,510,480,800,800*480*2);
Canvas_Image_Start_address(LAYER_4);
Canvas_image_width(LCD_XSIZE_TFT);
LT768_DMA_24bit_Block(1,0,0,0,510,480,800,800*480*2*2); // Load the dynamic area of external progress bar picture to
Canvas_Image_Start_address(LAYER_7); // LAYER_4 & LAYER_7
Canvas_image_width(LCD_XSIZE_TFT);
LT768_DMA_24bit_Block(1,0,0,0,510,480,800,800*480*2*2);
while(1)
{
Show_DoubleCircular(i,j);// Refresh circular progress bars
i+=10; // Refresh step: 15 degree
if(i>257) i = 36; // Once reach the maximum angle, reset to the start angle
j-=10; // Refresh step: 15 degree
if(j<36) j = 257; // Once reach the minimum angle, reset to the start angle
}
}
//-----------------------------------------------------------------------------------------------------------------------
Running result is shown below: