static void view_animate_at_time (view_t *view, double time) { ply_boot_splash_plugin_t *plugin; ply_list_node_t *node; double logo_opacity; long logo_x, logo_y; long logo_width, logo_height; unsigned long screen_width, screen_height; unsigned long star_width, star_height; plugin = view->plugin; logo_width = ply_image_get_width (plugin->logo_image); logo_height = ply_image_get_height (plugin->logo_image); screen_width = ply_pixel_display_get_width (view->display); screen_height = ply_pixel_display_get_height (view->display); logo_x = (screen_width / 2) - (logo_width / 2); logo_y = (screen_height / 2) - (logo_height / 2); star_width = ply_image_get_width (plugin->star_image); star_height = ply_image_get_height (plugin->star_image); node = ply_list_get_first_node (view->stars); while (node != NULL) { ply_list_node_t *next_node; star_t *star; star = (star_t *) ply_list_node_get_data (node); next_node = ply_list_get_next_node (view->stars, node); star->opacity = .5 * sin (((plugin->now - star->start_time) / star->speed) * (2 * M_PI)) + .5; star->opacity = CLAMP (star->opacity, 0, 1.0); ply_pixel_display_draw_area (view->display, star->x, star->y, star_width, star_height); node = next_node; } logo_opacity = .5 * sin ((time / 5) * (2 * M_PI)) + .8; logo_opacity = CLAMP (logo_opacity, 0, 1.0); if (plugin->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN) logo_opacity = 1.0; if (fabs (logo_opacity - view->logo_opacity) <= DBL_MIN) return; view->logo_opacity = logo_opacity; ply_pixel_display_draw_area (view->display, logo_x, logo_y, logo_width, logo_height); }
static void draw_normal_view (view_t *view, ply_pixel_buffer_t *pixel_buffer, int x, int y, int width, int height) { ply_boot_splash_plugin_t *plugin; ply_list_node_t *node; ply_rectangle_t logo_area; ply_rectangle_t star_area; uint32_t *logo_data, *star_data; unsigned long screen_width, screen_height; plugin = view->plugin; if (!plugin->is_animating) return; logo_area.width = ply_image_get_width (plugin->logo_image); logo_area.height = ply_image_get_height (plugin->logo_image); logo_data = ply_image_get_data (plugin->logo_image); screen_width = ply_pixel_display_get_width (view->display); screen_height = ply_pixel_display_get_height (view->display); logo_area.x = (screen_width / 2) - (logo_area.width / 2); logo_area.y = (screen_height / 2) - (logo_area.height / 2); star_data = ply_image_get_data (plugin->star_image); star_area.width = ply_image_get_width (plugin->star_image); star_area.height = ply_image_get_height (plugin->star_image); node = ply_list_get_first_node (view->stars); while (node != NULL) { ply_list_node_t *next_node; star_t *star; star = (star_t *) ply_list_node_get_data (node); next_node = ply_list_get_next_node (view->stars, node); star_area.x = star->x; star_area.y = star->y; ply_pixel_buffer_fill_with_argb32_data_at_opacity (pixel_buffer, &star_area, star_data, star->opacity); node = next_node; } ply_pixel_buffer_fill_with_argb32_data_at_opacity (pixel_buffer, &logo_area, logo_data, view->logo_opacity); }
static void view_show_prompt (view_t *view, const char *prompt) { ply_boot_splash_plugin_t *plugin; int x, y; int entry_width, entry_height; assert (view != NULL); plugin = view->plugin; if (ply_entry_is_hidden (view->entry)) { unsigned long screen_width, screen_height; screen_width = ply_pixel_display_get_width (view->display); screen_height = ply_pixel_display_get_height (view->display); view->box_area.width = ply_image_get_width (plugin->box_image); view->box_area.height = ply_image_get_height (plugin->box_image); view->box_area.x = screen_width / 2.0 - view->box_area.width / 2.0; view->box_area.y = screen_height / 2.0 - view->box_area.height / 2.0; view->lock_area.width = ply_image_get_width (plugin->lock_image); view->lock_area.height = ply_image_get_height (plugin->lock_image); entry_width = ply_entry_get_width (view->entry); entry_height = ply_entry_get_height (view->entry); x = screen_width / 2.0 - (view->lock_area.width + entry_width) / 2.0 + view->lock_area.width; y = screen_height / 2.0 - entry_height / 2.0; view->lock_area.x = screen_width / 2.0 - (view->lock_area.width + entry_width) / 2.0; view->lock_area.y = screen_height / 2.0 - view->lock_area.height / 2.0; ply_entry_show (view->entry, plugin->loop, view->display, x, y); } if (prompt != NULL) { int label_width, label_height; ply_label_set_text (view->label, prompt); label_width = ply_label_get_width (view->label); label_height = ply_label_get_height (view->label); x = view->box_area.x + view->lock_area.width / 2; y = view->box_area.y + view->box_area.height; ply_label_show (view->label, view->display, x, y); } }
static void draw_logo (view_t *view, ply_pixel_buffer_t *pixel_buffer) { ply_boot_splash_plugin_t *plugin; uint32_t *logo_data; unsigned long screen_width, screen_height; long width, height; plugin = view->plugin; screen_width = ply_pixel_display_get_width (view->display); screen_height = ply_pixel_display_get_height (view->display); width = ply_image_get_width (plugin->logo_image); height = ply_image_get_height (plugin->logo_image); logo_data = ply_image_get_data (plugin->logo_image); view->logo_area.x = (screen_width / 2) - (width / 2); view->logo_area.y = (screen_height / 2) - (height / 2); view->logo_area.width = width; view->logo_area.height = height; ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &view->logo_area, 0, 0, logo_data); }
static void image_fade_merge (ply_image_t* frame0, ply_image_t* frame1, float fade, int width, int height, uint32_t *reply_data) { int frame0_width = ply_image_get_width (frame0); int frame0_height = ply_image_get_height (frame0); int frame1_width = ply_image_get_width (frame1); int frame1_height = ply_image_get_height (frame1); uint32_t *frame0_data = ply_image_get_data (frame0); uint32_t *frame1_data = ply_image_get_data (frame1); int x, y, i; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { uint32_t pixel0, pixel1, pixelout; if (y < frame0_height && x < frame0_width) pixel0 = frame0_data[y*frame0_width+x]; else pixel0 = 0; if (y < frame1_height && x < frame1_width) pixel1 = frame1_data[y*frame1_width+x]; else pixel1 = 0; pixelout = 0; for (i = 0; i < 4; i++) { int subval0 = (pixel0 >> (i * 8)) & 0xFF; int subval1 = (pixel1 >> (i * 8)) & 0xFF; int subvalout = subval0 * (1-fade) + subval1 * fade; pixelout |= (subvalout & 0xFF) << (i * 8); } reply_data[y*width+x] = pixelout; } } }
bool ply_entry_load (ply_entry_t *entry) { if (!ply_image_load (entry->text_field_image)) return false; if (!ply_image_load (entry->bullet_image)) return false; entry->area.width = ply_image_get_width (entry->text_field_image); entry->area.height = ply_image_get_height (entry->text_field_image); entry->max_number_of_visible_bullets = get_max_number_of_visible_bullets (entry); return true; }
static bool ply_progress_animation_add_frame (ply_progress_animation_t *progress_animation, const char *filename) { ply_image_t *image; image = ply_image_new (filename); if (!ply_image_load (image)) { ply_image_free (image); return false; } ply_array_add_element (progress_animation->frames, image); progress_animation->area.width = MAX (progress_animation->area.width, (size_t) ply_image_get_width (image)); progress_animation->area.height = MAX (progress_animation->area.height, (size_t) ply_image_get_height (image)); return true; }
static bool ply_throbber_add_frame (ply_throbber_t *throbber, const char *filename) { ply_image_t *image; image = ply_image_new (filename); if (!ply_image_load (image)) { ply_image_free (image); return false; } ply_array_add_element (throbber->frames, image); throbber->width = MAX (throbber->width, ply_image_get_width (image)); throbber->height = MAX (throbber->height, ply_image_get_height (image)); return true; }
static bool ply_animation_add_frame (ply_animation_t *animation, const char *filename) { ply_image_t *image; image = ply_image_new (filename); if (!ply_image_load (image)) { ply_image_free (image); return false; } ply_array_add_element (animation->frames, image); animation->width = MAX (animation->width, ply_image_get_width (image)); animation->height = MAX (animation->height, ply_image_get_height (image)); return true; }
static bool animate_at_time (ply_animation_t *animation, double time) { int number_of_frames; ply_image_t * const * frames; bool should_continue; number_of_frames = ply_array_get_size (animation->frames); if (number_of_frames == 0) return false; should_continue = true; if (animation->frame_number > number_of_frames - 1) return false; if (animation->stop_requested) should_continue = false; frames = (ply_image_t * const *) ply_array_get_elements (animation->frames); animation->frame_area.x = animation->x; animation->frame_area.y = animation->y; animation->frame_area.width = ply_image_get_width (frames[animation->frame_number]); animation->frame_area.height = ply_image_get_height (frames[animation->frame_number]); ply_pixel_display_draw_area (animation->display, animation->x, animation->y, animation->frame_area.width, animation->frame_area.height); animation->frame_number++; return should_continue; }
static bool animate_at_time (ply_throbber_t *throbber, double time) { int number_of_frames; ply_image_t * const * frames; bool should_continue; number_of_frames = ply_array_get_size (throbber->frames); if (number_of_frames == 0) return true; should_continue = true; throbber->frame_number = (.5 * sin (time) + .5) * number_of_frames; if (throbber->stop_trigger != NULL) { if (throbber->frame_number == number_of_frames - 1) should_continue = false; } frames = (ply_image_t * const *) ply_array_get_elements (throbber->frames); throbber->frame_area.x = throbber->x; throbber->frame_area.y = throbber->y; throbber->frame_area.width = ply_image_get_width (frames[throbber->frame_number]); throbber->frame_area.height = ply_image_get_height (frames[throbber->frame_number]); ply_pixel_display_draw_area (throbber->display, throbber->x, throbber->y, throbber->frame_area.width, throbber->frame_area.height); return should_continue; }
void ply_progress_animation_draw (ply_progress_animation_t *progress_animation) { int number_of_frames; int frame_number; ply_image_t * const * frames; uint32_t *previous_frame_data, *frame_data; if (progress_animation->is_hidden) return; number_of_frames = ply_array_get_size (progress_animation->frames); if (number_of_frames == 0) return; frame_number = progress_animation->percent_done * (number_of_frames - 1); if (progress_animation->previous_frame_number != frame_number && progress_animation->transition != PLY_PROGRESS_ANIMATION_TRANSITION_NONE && progress_animation->transition_duration > 0.0) { progress_animation->is_transitioning = true; progress_animation->transition_start_time = ply_get_timestamp (); } frames = (ply_image_t * const *) ply_array_get_elements (progress_animation->frames); progress_animation->frame_area.x = progress_animation->area.x; progress_animation->frame_area.y = progress_animation->area.y; frame_data = ply_image_get_data (frames[frame_number]); if (progress_animation->is_transitioning) { double now; double fade_percentage; double fade_out_opacity; int width, height; uint32_t* faded_data; now = ply_get_timestamp (); fade_percentage = (now - progress_animation->transition_start_time) / progress_animation->transition_duration; if (fade_percentage >= 1.0) progress_animation->is_transitioning = false; fade_percentage = CLAMP (fade_percentage, 0.0, 1.0); if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE) { width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); progress_animation->frame_area.width = width; progress_animation->frame_area.height = height; ply_pixel_buffer_free (progress_animation->last_rendered_frame); progress_animation->last_rendered_frame = ply_pixel_buffer_new (width, height); faded_data = ply_pixel_buffer_get_argb32_data (progress_animation->last_rendered_frame); image_fade_merge (frames[frame_number - 1], frames[frame_number], fade_percentage, width, height, faded_data); ply_pixel_display_draw_area (progress_animation->display, progress_animation->frame_area.x, progress_animation->frame_area.y, progress_animation->frame_area.width, progress_animation->frame_area.height); } else { ply_rectangle_t fill_area; previous_frame_data = ply_image_get_data (frames[frame_number - 1]); if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER) { ply_pixel_buffer_free (progress_animation->last_rendered_frame); progress_animation->frame_area.width = ply_image_get_width (frames[frame_number - 1]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number - 1]); progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width, progress_animation->frame_area.height); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data (progress_animation->last_rendered_frame, &fill_area, 0, 0, previous_frame_data); } else { fade_out_opacity = 1.0 - fade_percentage; progress_animation->frame_area.width = ply_image_get_width (frames[frame_number - 1]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number - 1]); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data_at_opacity (progress_animation->last_rendered_frame, &fill_area, 0, 0, previous_frame_data, fade_out_opacity); } progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data_at_opacity (progress_animation->last_rendered_frame, &fill_area, 0, 0, frame_data, fade_percentage); width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); progress_animation->frame_area.width = width; progress_animation->frame_area.height = height; } } else { ply_rectangle_t fill_area; ply_pixel_buffer_free (progress_animation->last_rendered_frame); progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]); progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width, progress_animation->frame_area.height); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data (progress_animation->last_rendered_frame, &fill_area, 0, 0, frame_data); } progress_animation->previous_frame_number = frame_number; ply_pixel_display_draw_area (progress_animation->display, progress_animation->frame_area.x, progress_animation->frame_area.y, progress_animation->frame_area.width, progress_animation->frame_area.height); }
static void view_add_star (view_t *view) { ply_boot_splash_plugin_t *plugin; ply_rectangle_t logo_area; star_t *star; unsigned int x, y; unsigned int width, height; unsigned long screen_width, screen_height; ply_list_node_t *node; assert (view != NULL); plugin = view->plugin; screen_width = ply_pixel_display_get_width (view->display); screen_height = ply_pixel_display_get_height (view->display); width = ply_image_get_width (plugin->logo_image); height = ply_image_get_height (plugin->logo_image); logo_area.x = (screen_width / 2) - (width / 2); logo_area.y = (screen_height / 2) - (height / 2); logo_area.width = width; logo_area.height = height; width = ply_image_get_width (plugin->star_image); height = ply_image_get_height (plugin->star_image); node = NULL; do { x = rand () % screen_width; y = rand () % screen_height; if ((x <= logo_area.x + logo_area.width) && (x >= logo_area.x) && (y >= logo_area.y) && (y <= logo_area.y + logo_area.height)) continue; if ((x + width >= logo_area.x) && (x + width <= logo_area.x + logo_area.width) && (y + height >= logo_area.y) && (y + height <= logo_area.y + logo_area.height)) continue; node = ply_list_get_first_node (view->stars); while (node != NULL) { ply_list_node_t *next_node; star = (star_t *) ply_list_node_get_data (node); next_node = ply_list_get_next_node (view->stars, node); if ((x <= star->x + width) && (x >= star->x) && (y >= star->y) && (y <= star->y + height)) break; if ((x + width >= star->x) && (x + width <= star->x + width) && (y + height >= star->y) && (y + height <= star->y + height)) break; node = next_node; } } while (node != NULL); star = star_new (x, y, (double) ((rand () % 50) + 1)); ply_list_append_data (view->stars, star); }
static void on_draw (view_t *view, ply_pixel_buffer_t *pixel_buffer, int x, int y, int width, int height) { ply_boot_splash_plugin_t *plugin; ply_rectangle_t area; area.x = x; area.y = y; area.width = width; area.height = height; plugin = view->plugin; draw_background (view, pixel_buffer, x, y, width, height); if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY || plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY ) { uint32_t *box_data, *lock_data; box_data = ply_image_get_data (plugin->box_image); ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &view->box_area, 0, 0, box_data); ply_entry_draw_area (view->entry, pixel_buffer, x, y, width, height); ply_label_draw_area (view->label, pixel_buffer, x, y, width, height); lock_data = ply_image_get_data (plugin->lock_image); ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &view->lock_area, 0, 0, lock_data); } else { if (!ply_progress_animation_is_hidden (view->progress_animation)) ply_progress_animation_draw_area (view->progress_animation, pixel_buffer, x, y, width, height); else if (!ply_animation_is_stopped (view->end_animation)) ply_animation_draw_area (view->end_animation, pixel_buffer, x, y, width, height); if (plugin->corner_image != NULL) { ply_rectangle_t screen_area; ply_rectangle_t image_area; ply_pixel_buffer_get_size (pixel_buffer, &screen_area); image_area.width = ply_image_get_width (plugin->corner_image); image_area.height = ply_image_get_height (plugin->corner_image); image_area.x = screen_area.width - image_area.width - 20; image_area.y = screen_area.height - image_area.height - 20; ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &image_area, 0, 0, ply_image_get_data (plugin->corner_image)); } } ply_label_draw_area (view->message_label, pixel_buffer, x, y, width, height); }
void ply_entry_draw_area (ply_entry_t *entry, ply_pixel_buffer_t *pixel_buffer, long x, long y, unsigned long width, unsigned long height) { ply_rectangle_t bullet_area; uint32_t *text_field_data, *bullet_data; int i, number_of_visible_bullets; if (entry->is_hidden) return; text_field_data = ply_image_get_data (entry->text_field_image); ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &entry->area, 0, 0, text_field_data); if (entry->is_password) { bullet_data = ply_image_get_data (entry->bullet_image); bullet_area.width = ply_image_get_width (entry->bullet_image); bullet_area.height = ply_image_get_height (entry->bullet_image); if (entry->number_of_bullets < entry->max_number_of_visible_bullets) number_of_visible_bullets = entry->number_of_bullets; else { number_of_visible_bullets = entry->max_number_of_visible_bullets; /* We've got more bullets than we can show in the available space, so * draw a little half bullet to indicate some bullets are offscreen */ bullet_area.x = entry->area.x; bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0; ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &bullet_area, bullet_area.width / 2.0, 0, bullet_data); } for (i = 0; i < number_of_visible_bullets; i++) { bullet_area.x = entry->area.x + i * bullet_area.width + bullet_area.width / 2.0; bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0; ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &bullet_area, 0, 0, bullet_data); } } else { ply_label_set_text (entry->label, entry->text); ply_label_draw_area (entry->label, pixel_buffer, entry->area.x, entry->area.y, entry->area.width, entry->area.height); } }