char *image_dir;
char *frames_prefix;
+ ply_progress_animation_transition_t transition;
+ double transition_duration;
+
ply_window_t *window;
ply_frame_buffer_t *frame_buffer;
ply_frame_buffer_area_t area;
ply_frame_buffer_area_t frame_area;
double percent_done;
+ int previous_frame_number;
+
+ double transition_start_time;
uint32_t is_hidden : 1;
+ uint32_t is_transitioning : 1;
};
ply_progress_animation_t *
ply_progress_animation_new (const char *image_dir,
- const char *frames_prefix)
+ const char *frames_prefix)
{
ply_progress_animation_t *progress_animation;
progress_animation->frame_area.y = 0;
progress_animation->frame_area.width = 0;
progress_animation->frame_area.height = 0;
+ progress_animation->previous_frame_number = 0;
return progress_animation;
}
+void
+ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
+ ply_progress_animation_transition_t transition,
+ double duration)
+{
+ progress_animation->transition = transition;
+ progress_animation->transition_duration = duration;
+}
+
static void
ply_progress_animation_remove_frames (ply_progress_animation_t *progress_animation)
{
int number_of_frames;
int frame_number;
ply_image_t * const * frames;
- uint32_t *frame_data;
+ uint32_t *previous_frame_data, *frame_data;
if (progress_animation->is_hidden)
return;
if (progress_animation->frame_area.width > 0)
draw_background (progress_animation);
+ 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.height = ply_image_get_height (frames[frame_number]);
frame_data = ply_image_get_data (frames[frame_number]);
- ply_frame_buffer_fill_with_argb32_data (progress_animation->frame_buffer,
- &progress_animation->frame_area, 0, 0,
- frame_data);
+ if (progress_animation->is_transitioning)
+ {
+ double now;
+ double fade_percentage;
+ double fade_out_opacity;
+ 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);
+
+ previous_frame_data = ply_image_get_data (frames[frame_number - 1]);
+ if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER)
+ fade_out_opacity = 1.0;
+ else
+ fade_out_opacity = 1.0 - fade_percentage;
+
+ ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer,
+ &progress_animation->frame_area, 0, 0,
+ previous_frame_data, fade_out_opacity);
+ ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer,
+ &progress_animation->frame_area, 0, 0,
+ frame_data, fade_percentage);
+ }
+ else
+ {
+ ply_frame_buffer_fill_with_argb32_data (progress_animation->frame_buffer,
+ &progress_animation->frame_area, 0, 0,
+ frame_data);
+ }
ply_frame_buffer_unpause_updates (progress_animation->frame_buffer);
+
+ progress_animation->previous_frame_number = frame_number;
}
static bool
typedef struct _ply_progress_animation ply_progress_animation_t;
+typedef enum
+{
+ PLY_PROGRESS_ANIMATION_TRANSITION_NONE,
+ PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER,
+ PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE,
+} ply_progress_animation_transition_t;
+
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_progress_animation_t *ply_progress_animation_new (const char *image_dir,
const char *frames_prefix);
void ply_progress_animation_free (ply_progress_animation_t *progress_animation);
bool ply_progress_animation_load (ply_progress_animation_t *progress_animation);
+void ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
+ ply_progress_animation_transition_t transition,
+ double duration);
void ply_progress_animation_show (ply_progress_animation_t *progress_animation,
ply_window_t *window,
long x,
double animation_vertical_alignment;
char *animation_dir;
+ ply_progress_animation_transition_t transition;
+ double transition_duration;
+
uint32_t background_start_color;
uint32_t background_end_color;
ply_boot_splash_plugin_t *plugin;
char *image_dir, *image_path;
char *alignment;
+ char *transition;
+ char *transition_duration;
char *color;
srand ((int) ply_get_timestamp ());
plugin->animation_vertical_alignment = .5;
free (alignment);
+
+ plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_NONE;
+ transition = ply_key_file_get_value (key_file, "two-step", "Transition");
+ if (transition != NULL)
+ {
+ if (strcmp (transition, "fade-over") == 0)
+ plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER;
+ else if (strcmp (transition, "cross-fade") == 0)
+ plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE;
+ }
+ free (transition);
+
+ transition_duration = ply_key_file_get_value (key_file, "two-step", "TransitionDuration");
+ if (transition_duration != NULL)
+ plugin->transition_duration = strtod (transition_duration, NULL);
+ else
+ plugin->transition_duration = 0.0;
+ free (transition_duration);
+
color = ply_key_file_get_value (key_file, "two-step", "BackgroundStartColor");
if (color != NULL)
"throbber-");
plugin->progress_animation = ply_progress_animation_new (plugin->animation_dir,
"progress-");
+ ply_progress_animation_set_transition (plugin->progress_animation,
+ plugin->transition,
+ plugin->transition_duration);
ply_trace ("loading lock image");
if (!ply_image_load (plugin->lock_image))