1
0
mirror of https://github.com/azure-rtos/guix.git synced 2025-01-28 07:03:11 +08:00
guix/samples/demo_guix_industrial/sequence_window.c
2021-10-13 06:50:21 +00:00

693 lines
24 KiB
C

/* This is a small demo of the high-performance GUIX graphics framework. */
#include "demo_guix_industrial.h"
#define SEQUENCE_TIMER 10
#define SEQUENCE_TIMER_TICKS (40 / GX_SYSTEM_TIMER_MS)
#define LEFT_PROGRESS_BAR_INCREMENT 3
#define TASK_PROPERTY_ANIMATION_STEPS 10
#define TASK_ICON_ANIMATION_STEPS 8
#define TASK_TITLE_ANIMATION_STEPS 8
#define TASK_TITLE_ANIMATION_SHIFT 60
#define TASK_TITLE_ANIMATION_START_X 19
/* Define task IDs. */
enum task_ids {
TASK_ID_INSPECTING = 0,
TASK_ID_ASSEMBLING,
TASK_ID_WELDING,
TASK_ID_PALLETIZING,
TASK_COUNT
};
/* Define task information struture. */
typedef struct TASK_INFO_STRUCT {
INT task_id;
GX_PIXELMAP_BUTTON* task_button;
GX_RESOURCE_ID task_text_id;
GX_RESOURCE_ID task_icon_id;
GX_RESOURCE_ID progress_1_text_id;
GX_RESOURCE_ID progress_2_text_id;
GX_RESOURCE_ID progress_3_text_id;
GX_RESOURCE_ID progress_4_text_id;
}TASK_INFO;
/* Define progress information structure. */
typedef struct PROGRESS_INFO_STRUCT {
INT current_val;
GX_PROGRESS_BAR *progress_bar;
GX_NUMERIC_PROMPT *value_prompt;
GX_PROMPT *percent_flag_prompt;
GX_ICON *complete_icon;
}PROGRESS_INFO;
/* Define property information structure. */
typedef struct PROPERTY_INFO_STRUCT {
INT values[TASK_COUNT];
GX_WIDGET *widget;
}PROPERTY_INFO;
static int timer_minute;
static int timer_second;
static int timer_tick;
static int current_task_property_animation_step = TASK_PROPERTY_ANIMATION_STEPS;
static int current_task_title_animation_step = TASK_TITLE_ANIMATION_STEPS;
static int current_task_icon_animation_step = TASK_ICON_ANIMATION_STEPS;
static int current_task_id = TASK_ID_INSPECTING;
static int task_title_blend_alpha = 255;
extern USHORT toggle_animation_flag;
PROGRESS_INFO left_progress_info_list[] = {
{
0,
&sequence_window.sequence_window_progress_1,
&sequence_window.sequence_window_progress_1_value,
&sequence_window.sequence_window_progress_1_percent_flag,
&sequence_window.sequence_window_complete_icon_1
},
{
0,
&sequence_window.sequence_window_progress_2,
&sequence_window.sequence_window_progress_2_value,
&sequence_window.sequence_window_progress_2_percent_flag,
&sequence_window.sequence_window_complete_icon_2
},
{
0,
&sequence_window.sequence_window_progress_3,
&sequence_window.sequence_window_progress_3_value,
&sequence_window.sequence_window_progress_3_percent_flag,
&sequence_window.sequence_window_complete_icon_3
},
{
0,
&sequence_window.sequence_window_progress_4,
&sequence_window.sequence_window_progress_4_value,
&sequence_window.sequence_window_progress_4_percent_flag,
&sequence_window.sequence_window_complete_icon_4
}
};
TASK_INFO task_info_list[] =
{
{
TASK_ID_INSPECTING,
&main_screen.main_screen_button_inspecting,
GX_STRING_ID_INSPECTING,
GX_PIXELMAP_ID_CIRCLE_ICON_INSPECTING,
GX_STRING_ID_SURFACE,
GX_STRING_ID_COMPONENTS,
GX_STRING_ID_TRACING_PATTERN,
GX_STRING_ID_CIRCUIT_TEST
},
{
TASK_ID_ASSEMBLING,
&main_screen.main_screen_button_inspecting,
GX_STRING_ID_ASSEMBLING,
GX_PIXELMAP_ID_CIRCLE_ICON_ASSEMBLING,
GX_STRING_ID_ROTATE_AXIS,
GX_STRING_ID_DRIVE_PRESS,
GX_STRING_ID_FORCE_JOIN,
GX_STRING_ID_ASSEMBLING
},
{
TASK_ID_WELDING,
&main_screen.main_screen_button_welding,
GX_STRING_ID_WELDING,
GX_PIXELMAP_ID_CIRCLE_ICON_WELDING,
GX_STRING_ID_CURRENT_CHECK,
GX_STRING_ID_TARGET_CLAMPS,
GX_STRING_ID_BRAZING_FLUX,
GX_STRING_ID_GROUND_FLUSH
},
{
TASK_ID_PALLETIZING,
&main_screen.main_screen_button_palletizing,
GX_STRING_ID_PALLETIZING,
GX_PIXELMAP_ID_CIRCLE_ICON_PALLET,
GX_STRING_ID_LEVEL_SURFACE,
GX_STRING_ID_ARM_AUXILIARY,
GX_STRING_ID_PALLET_FRICTION,
GX_STRING_ID_UNITSET
}
};
PROPERTY_INFO property_prompt_value_list[] = {
{{ 75, 70, 79, 68 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_SX },
{{ 72, 69, 74, 63 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_SY },
{{ -1050, -1050, 9290, -1050 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_RX },
{{ 13650, 13650, 3870, 13650 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_RY },
{{ 112, 423, 1822, 205 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_UP },
{{ 8, 217, 1436, 129 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_DN },
{{ 814, 756, 903, 816 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_X },
{{ 734, 680, 588, 734}, (GX_WIDGET*)&sequence_window.sequence_window_prompt_Y },
{{ 387, 360, 373, 388 }, (GX_WIDGET*)&sequence_window.sequence_window_prompt_Z }
};
PROPERTY_INFO property_radial_progress_value_list[] ={
{{ -220, -270, -200, -250 }, (GX_WIDGET*)&sequence_window.sequence_window_radial_progress_speed },
{{ -160, -170, -150, -160 }, (GX_WIDGET*)&sequence_window.sequence_window_radial_progress_rotation },
{{ -90, -40, -50, -80 },(GX_WIDGET*)&sequence_window.sequence_window_radial_progress_force }
};
VOID sequence_window_init();
VOID task_set(int new_mode);
TASK_INFO* task_info_get(INT task_id);
VOID task_time_update();
VOID task_progress_information_init();
VOID task_progress_information_update();
VOID task_properties_init();
VOID task_properties_update();
VOID task_title_animation_init();
VOID task_title_animation_update();
VOID task_icon_animation_update();
UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length);
/******************************************************************************************/
/* Retrieve tasl information according to task id. */
/******************************************************************************************/
TASK_INFO *task_info_get(INT task_id)
{
if (task_id < sizeof(task_info_list) / sizeof(TASK_INFO))
{
return &task_info_list[task_id];
}
return GX_NULL;
}
/******************************************************************************************/
/* Override event processing of "sequence_window" to handle signals from my child widgets.*/
/******************************************************************************************/
UINT sequence_window_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
{
switch (event_ptr->gx_event_type)
{
case GX_EVENT_TIMER:
if (event_ptr->gx_event_payload.gx_event_timer_id == SEQUENCE_TIMER)
{
sequence_animation_update();
}
break;
case GX_SIGNAL(ID_INSPECTING, GX_EVENT_CLICKED):
task_set(TASK_ID_INSPECTING);
break;
case GX_SIGNAL(ID_ASSEMBLING, GX_EVENT_CLICKED):
task_set(TASK_ID_ASSEMBLING);
break;
case GX_SIGNAL(ID_WELDING, GX_EVENT_CLICKED):
task_set(TASK_ID_WELDING);
break;
case GX_SIGNAL(ID_PALLETIZING, GX_EVENT_CLICKED):
task_set(TASK_ID_PALLETIZING);
break;
default:
return gx_window_event_process(window, event_ptr);
}
return 0;
}
/******************************************************************************************/
/* Override drawing of "task_icon" to draw the icon with specified blending alpha. */
/******************************************************************************************/
VOID task_icon_draw(GX_ICON *icon)
{
GX_BRUSH *brush;
GX_PIXELMAP *map;
GX_RECTANGLE *size;
INT angle;
TASK_INFO *tinfo;
if ((toggle_animation_flag == ANIMATION_NONE))
{
gx_context_brush_get(&brush);
brush->gx_brush_alpha = task_title_blend_alpha;
}
/* Call default icon draw. */
gx_icon_draw(icon);
tinfo = task_info_get(current_task_id);
if (!tinfo)
{
return;
}
/* Retrieve task icon pixelmap. */
gx_context_pixelmap_get(tinfo->task_icon_id, &map);
size = &icon->gx_widget_size;
if (current_task_icon_animation_step < TASK_ICON_ANIMATION_STEPS)
{
if (map)
{
angle = -90 * (current_task_icon_animation_step - TASK_ICON_ANIMATION_STEPS) / TASK_ICON_ANIMATION_STEPS;
/* Rotate task icon. */
gx_canvas_pixelmap_rotate(size->gx_rectangle_left, size->gx_rectangle_top, map, angle, -1, -1);
}
}
else
{
/* Draw task icon. */
gx_canvas_pixelmap_draw(size->gx_rectangle_left, size->gx_rectangle_top, map);
}
}
/******************************************************************************************/
/* Override drawing of "task_title" to draw the prompt with specified blending alpha. */
/******************************************************************************************/
VOID task_title_draw(GX_PROMPT *prompt)
{
GX_BRUSH *brush;
if ((toggle_animation_flag == ANIMATION_NONE))
{
gx_context_brush_get(&brush);
brush->gx_brush_alpha = task_title_blend_alpha;
}
gx_prompt_draw(prompt);
}
/******************************************************************************************/
/* Initiate widget values in sequence window. */
/******************************************************************************************/
VOID sequence_window_init()
{
timer_minute = 0;
timer_second = 0;
timer_tick = 0;
/* Init timer values. */
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_minute, timer_minute);
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_second, timer_second);
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_tick, timer_tick);
gx_sprite_current_frame_set(&sequence_window.sequence_window_sprite, 0);
task_set(TASK_ID_INSPECTING);
}
/******************************************************************************************/
/* Start sequence animation. */
/******************************************************************************************/
VOID sequence_animation_start()
{
/* Create a sequence timer. */
gx_system_timer_start(&sequence_window, SEQUENCE_TIMER, SEQUENCE_TIMER_TICKS, SEQUENCE_TIMER_TICKS);
gx_sprite_start(&sequence_window.sequence_window_sprite, 0);
}
/******************************************************************************************/
/* Process one step for sequence animation. */
/******************************************************************************************/
VOID sequence_animation_update()
{
task_time_update();
task_title_animation_update();
task_icon_animation_update();
task_properties_update();
task_progress_information_update();
}
/******************************************************************************************/
/* Stop sequence animation. */
/******************************************************************************************/
VOID sequence_animation_stop()
{
gx_system_timer_stop(&sequence_window, SEQUENCE_TIMER);
gx_sprite_stop(&sequence_window.sequence_window_sprite);
}
/******************************************************************************************/
/* Set sequence mode. */
/******************************************************************************************/
VOID task_set(int new_task_id)
{
TASK_INFO *tinfo;
if (new_task_id > TASK_ID_PALLETIZING)
{
screen_toggle_animation_start((GX_WINDOW*)&complete_window, (GX_WINDOW*)&sequence_window);
return;
}
current_task_id = new_task_id;
tinfo = task_info_get(new_task_id);
if (!tinfo)
{
return;
}
button_indicator_attach(tinfo->task_button);
/* Set title text. */
gx_prompt_text_id_set(&sequence_window.sequence_window_progress_1_title, tinfo->progress_1_text_id);
gx_prompt_text_id_set(&sequence_window.sequence_window_progress_2_title, tinfo->progress_2_text_id);
gx_prompt_text_id_set(&sequence_window.sequence_window_progress_3_title, tinfo->progress_3_text_id);
gx_prompt_text_id_set(&sequence_window.sequence_window_progress_4_title, tinfo->progress_4_text_id);
gx_prompt_text_id_set(&sequence_window.sequence_window_task_title, tinfo->task_text_id);
task_progress_information_init();
task_properties_init();
task_title_animation_init();
}
/******************************************************************************************/
/* Update task time. */
/******************************************************************************************/
VOID task_time_update()
{
int ms;
if (timer_tick < GX_TICKS_SECOND)
{
timer_tick += SEQUENCE_TIMER_TICKS;
ms = timer_tick * GX_SYSTEM_TIMER_MS / 10;
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_tick, ms);
}
else if (timer_second < 59)
{
timer_tick = 0;
timer_second++;
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_tick, timer_tick);
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_second, timer_second);
}
else if (timer_minute < 59)
{
timer_second = 0;
timer_minute++;
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_second, timer_tick);
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_minute, timer_second);
}
else
{
timer_minute = 0;
gx_numeric_prompt_value_set(&sequence_window.sequence_window_timer_minute, timer_second);
}
}
/******************************************************************************************/
/* Initialize progress information in left and bottom. */
/******************************************************************************************/
VOID task_progress_information_init()
{
PROGRESS_INFO *pinfo;
INT stage;
for (stage = 0; stage < sizeof(left_progress_info_list) / sizeof(PROGRESS_INFO); stage++)
{
pinfo = &left_progress_info_list[stage];
pinfo->current_val = 0;
/* Init progress bar value. */
gx_progress_bar_value_set(pinfo->progress_bar, 0);
/* Init progress value prompt value. */
gx_numeric_prompt_value_set(pinfo->value_prompt, 0);
/* Show progress value prompt. */
gx_widget_show(pinfo->value_prompt);
/* Show percentage flag. */
gx_widget_show(pinfo->percent_flag_prompt);
/* Hide progress complete icon. */
gx_widget_hide(pinfo->complete_icon);
}
/* Init bottom progress bar values. */
gx_progress_bar_value_set(&sequence_window.sequence_window_bottom_progress, 0);
gx_numeric_prompt_value_set(&sequence_window.sequence_window_bottom_progress_value, 0);
}
/******************************************************************************************/
/* Update progress information in left and bottom. */
/******************************************************************************************/
VOID task_progress_information_update()
{
INT progress_val = 0;
PROGRESS_INFO *pinfo;
TASK_INFO *tinfo = task_info_get(current_task_id);
INT stage;
INT total_stage = sizeof(left_progress_info_list) / sizeof(PROGRESS_INFO);
if (!tinfo)
{
return;
}
for (stage = 0; stage < total_stage; stage++)
{
/* Update progress information when stage is 0 or previous stage is 25% completed. */
if (stage == 0 || (left_progress_info_list[stage - 1].current_val >= 25))
{
pinfo = &left_progress_info_list[stage];
if (pinfo->current_val < 100)
{
pinfo->current_val += LEFT_PROGRESS_BAR_INCREMENT;
/* Update progress bar value. */
gx_progress_bar_value_set(pinfo->progress_bar, pinfo->current_val);
gx_numeric_prompt_value_set(pinfo->value_prompt, pinfo->current_val);
if (pinfo->current_val >= 100)
{
gx_widget_hide(pinfo->value_prompt);
gx_widget_hide(pinfo->percent_flag_prompt);
gx_widget_show(pinfo->complete_icon);
}
}
}
}
progress_val = (tinfo->task_id * 100 / TASK_COUNT);
if (left_progress_info_list[total_stage - 1].current_val)
{
progress_val += (75 + left_progress_info_list[total_stage - 1].current_val) * 25 / 175;
}
else
{
progress_val += (left_progress_info_list[0].current_val) * 25 / 175;
}
/* Start next task when last stage completed. */
if (left_progress_info_list[total_stage - 1].current_val >= 100)
{
task_set(current_task_id + 1);
}
/* Update bottom progress information. */
gx_progress_bar_value_set(&sequence_window.sequence_window_bottom_progress, progress_val);
gx_numeric_prompt_value_set(&sequence_window.sequence_window_bottom_progress_value, progress_val);
}
/******************************************************************************************/
/* Initialize task title animation. */
/******************************************************************************************/
VOID task_title_animation_init()
{
GX_RECTANGLE *size;
INT shift;
current_task_title_animation_step = 0;
task_title_blend_alpha = 255;
size = &sequence_window.sequence_window_task_title.gx_widget_size;
if (size->gx_rectangle_left != TASK_TITLE_ANIMATION_START_X)
{
shift = TASK_TITLE_ANIMATION_START_X - size->gx_rectangle_left;
gx_widget_shift((GX_WIDGET*)&sequence_window.sequence_window_task_title, shift, 0, GX_TRUE);
gx_widget_shift((GX_WIDGET*)&sequence_window.sequence_window_task_icon, shift, 0, GX_TRUE);
}
}
/******************************************************************************************/
/* Udpate task title animation. */
/******************************************************************************************/
VOID task_title_animation_update()
{
INT shift;
if (current_task_title_animation_step < TASK_TITLE_ANIMATION_STEPS)
{
current_task_title_animation_step++;
if (current_task_title_animation_step <= TASK_TITLE_ANIMATION_STEPS / 2)
{
shift = TASK_TITLE_ANIMATION_SHIFT;
task_title_blend_alpha -= 50;
}
else
{
shift = -TASK_TITLE_ANIMATION_SHIFT;
task_title_blend_alpha += 50;
}
gx_widget_shift((GX_WIDGET *)&sequence_window.sequence_window_task_title, shift, 0, GX_TRUE);
gx_widget_shift((GX_WIDGET *)&sequence_window.sequence_window_task_icon, shift, 0, GX_TRUE);
if (current_task_title_animation_step == TASK_TITLE_ANIMATION_STEPS)
{
/* Start mode icon animation. */
current_task_icon_animation_step = 0;
}
}
}
/******************************************************************************************/
/* Update mode icon animation. */
/******************************************************************************************/
VOID task_icon_animation_update()
{
if (current_task_icon_animation_step < TASK_ICON_ANIMATION_STEPS)
{
current_task_icon_animation_step++;
gx_system_dirty_mark(&sequence_window.sequence_window_task_icon);
}
}
/******************************************************************************************/
/* Initialize task perperty values. */
/******************************************************************************************/
VOID task_properties_init()
{
INT index;
PROPERTY_INFO *pinfo;
for (index = 0; index < sizeof(property_prompt_value_list) / sizeof(PROPERTY_INFO); index++)
{
pinfo = &property_prompt_value_list[index];
gx_numeric_prompt_value_set((GX_NUMERIC_PROMPT *)pinfo->widget, pinfo->values[0]);
}
for (index = 0; index < sizeof(property_radial_progress_value_list) / sizeof(PROPERTY_INFO); index++)
{
pinfo = &property_radial_progress_value_list[index];
gx_radial_progress_bar_value_set((GX_RADIAL_PROGRESS_BAR *)pinfo->widget, 0);
}
current_task_property_animation_step = 0;
}
/******************************************************************************************/
/* Update task property values. */
/******************************************************************************************/
VOID task_properties_update()
{
INT start_val;
INT target_val;
INT value;
INT index;
PROPERTY_INFO *pinfo;
if (current_task_property_animation_step < TASK_PROPERTY_ANIMATION_STEPS)
{
current_task_property_animation_step++;
for (index = 0; index < sizeof(property_prompt_value_list) / sizeof(PROPERTY_INFO); index++)
{
pinfo = &property_prompt_value_list[index];
target_val = pinfo->values[current_task_id];
if (current_task_id == 0)
{
start_val = pinfo->values[TASK_COUNT - 1];
}
else
{
start_val = pinfo->values[current_task_id - 1];
}
value = start_val + (target_val - start_val) * current_task_property_animation_step / TASK_PROPERTY_ANIMATION_STEPS;
gx_numeric_prompt_value_set((GX_NUMERIC_PROMPT*)pinfo->widget, value);
}
for (index = 0; index < sizeof(property_radial_progress_value_list) / sizeof(PROPERTY_INFO); index++)
{
pinfo = &property_radial_progress_value_list[index];
target_val = pinfo->values[current_task_id];
value = target_val * current_task_property_animation_step / TASK_PROPERTY_ANIMATION_STEPS;
gx_radial_progress_bar_value_set((GX_RADIAL_PROGRESS_BAR*)pinfo->widget, value);
}
}
}
/******************************************************************************************/
/* Define a value format function for timer prompts. */
/******************************************************************************************/
VOID timer_value_format(GX_NUMERIC_PROMPT *prompt, INT value)
{
gx_utility_ltoa(value, prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
if (value < 10)
{
prompt->gx_numeric_prompt_buffer[1] = prompt->gx_numeric_prompt_buffer[0];
prompt->gx_numeric_prompt_buffer[0] = '0';
prompt->gx_numeric_prompt_buffer[2] = '\0';
}
}
/******************************************************************************************/
/* Define a value format function for value prompts in mode windows. */
/******************************************************************************************/
VOID mode_value_format(GX_NUMERIC_PROMPT *prompt, INT value)
{
INT index;
gx_utility_ltoa(value / 100, prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
index = string_length_get(prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE - 1);
prompt->gx_numeric_prompt_buffer[index++] = '.';
if (value < 0)
{
value *= -1;
}
gx_utility_ltoa(value % 100, prompt->gx_numeric_prompt_buffer + index, GX_NUMERIC_PROMPT_BUFFER_SIZE - index);
}
/******************************************************************************************/
/* Define a value format function for position value prompts. */
/******************************************************************************************/
VOID position_value_format(GX_NUMERIC_PROMPT *prompt, INT value)
{
INT index;
gx_utility_ltoa(value / 10, prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
index = string_length_get(prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
prompt->gx_numeric_prompt_buffer[index++] = '.';
gx_utility_ltoa(value % 10, prompt->gx_numeric_prompt_buffer + index, GX_NUMERIC_PROMPT_BUFFER_SIZE - index);
}