diff options
Diffstat (limited to 'main/src')
3 files changed, 67 insertions, 52 deletions
diff --git a/main/src/ui/conversation_content_view/file_image_widget.vala b/main/src/ui/conversation_content_view/file_image_widget.vala index 2b4d1765..33232e93 100644 --- a/main/src/ui/conversation_content_view/file_image_widget.vala +++ b/main/src/ui/conversation_content_view/file_image_widget.vala @@ -15,7 +15,7 @@ public class FileImageWidget : Widget { } private State state = State.EMPTY; - private Stack stack = new Stack() { transition_duration=600, transition_type=StackTransitionType.CROSSFADE }; + private Stack stack = new Stack() { transition_duration=600, transition_type=StackTransitionType.CROSSFADE, hhomogeneous = false, vhomogeneous = false, interpolate_size = true }; private Overlay overlay = new Overlay(); private bool show_image_overlay_toolbar = false; @@ -106,16 +106,8 @@ public class FileImageWidget : Widget { private void refresh_state() { if ((state == EMPTY || state == PREVIEW) && file_transfer.path != null) { - if (state == EMPTY) { - load_from_file.begin(file_transfer.get_file(), file_transfer.file_name); - show_image_overlay_toolbar = true; - } if (state == PREVIEW) { - Timeout.add(500, () => { - load_from_file.begin(file_transfer.get_file(), file_transfer.file_name); - show_image_overlay_toolbar = true; - return false; - }); - } + load_from_file.begin(file_transfer.get_file(), file_transfer.file_name); + show_image_overlay_toolbar = true; this.set_cursor_from_name("zoom-in"); state = IMAGE; @@ -132,7 +124,7 @@ public class FileImageWidget : Widget { transmission_progress.visible = true; show_image_overlay_toolbar = false; } else if (transmission_progress.visible) { - Timeout.add(500, () => { + Timeout.add(250, () => { transmission_progress.transferred_size = transmission_progress.file_size; transmission_progress.visible = false; show_image_overlay_toolbar = true; @@ -146,7 +138,7 @@ public class FileImageWidget : Widget { } else { transmission_progress.state = FileTransmissionProgress.State.UPLOADING; } - } else if (file_transfer.sfs_sources.is_empty) { + } else if (file_transfer.sfs_sources.is_empty && file_transfer.direction == FileTransfer.DIRECTION_RECEIVED) { transmission_progress.state = UNKNOWN_SOURCE; } else if (file_transfer.state == NOT_STARTED && file_transfer.direction == FileTransfer.DIRECTION_RECEIVED) { transmission_progress.state = DOWNLOAD_NOT_STARTED; diff --git a/main/src/ui/conversation_content_view/file_transmission_progress.c b/main/src/ui/conversation_content_view/file_transmission_progress.c new file mode 100644 index 00000000..65357a35 --- /dev/null +++ b/main/src/ui/conversation_content_view/file_transmission_progress.c @@ -0,0 +1,16 @@ +#include <gsk/gsk.h> + +GskPath *dino_ui_file_transmission_progress_create_progress_arc(GskPath *circle_path, gfloat percentage) { + GskPathMeasure *measure = gsk_path_measure_new(circle_path); + gfloat length = gsk_path_measure_get_length(measure); + GskPathPoint start_point, end_point; + g_return_val_if_fail(gsk_path_measure_get_point(measure, length * 0.75, &start_point), NULL); + percentage += 0.75f; + if (percentage > 1) percentage -= 1.0f; + g_return_val_if_fail(gsk_path_measure_get_point(measure, length * percentage, &end_point), NULL); + GskPathBuilder *builder = gsk_path_builder_new(); + gsk_path_builder_add_segment(builder, circle_path, &start_point, &end_point); + GskPath *arc_path = gsk_path_builder_free_to_path(builder); + gsk_path_measure_unref(measure); + return arc_path; +}
\ No newline at end of file diff --git a/main/src/ui/conversation_content_view/file_transmission_progress.vala b/main/src/ui/conversation_content_view/file_transmission_progress.vala index ce8af78e..a69b547f 100644 --- a/main/src/ui/conversation_content_view/file_transmission_progress.vala +++ b/main/src/ui/conversation_content_view/file_transmission_progress.vala @@ -21,44 +21,30 @@ namespace Dino.Ui { public int64 transferred_size { get; set; } public State state { get; set; } - private CssProvider css_provider = new CssProvider(); + private const int LINE_WIDTH = 4; + private Button button = new Button(); - private uint64 next_update_time = 0; - private int64 last_progress_percent = 0; - private uint update_progress_timeout_id = -1; + private Adw.TimedAnimation progress_animation; construct { - add_css_class("circular-loading-indicator"); - + add_css_class("circular-osd"); button.add_css_class("circular"); - Adw.Bin holder = new Adw.Bin(); - holder.set_child(button); - this.set_child(holder); + button.margin_start = button.margin_end = button.margin_top = button.margin_bottom = LINE_WIDTH; + this.set_child(button); this.button.clicked.connect(on_button_clicked); - this.notify["transferred-size"].connect(on_transferred_size_update); + this.notify["transferred-size"].connect(update_progress); this.notify["state"].connect(on_state_changed); on_state_changed(); + + setup_animation(); } - private void on_transferred_size_update() { - if (update_progress_timeout_id == -1) { - int64 progress_percent = transferred_size * 100 / file_size; - if (progress_percent != last_progress_percent) { - uint64 time_now = get_monotonic_time() / 1000; - if (next_update_time > time_now) { - update_progress_timeout_id = Timeout.add((uint) (next_update_time - time_now), () => { - update_progress(); - update_progress_timeout_id = -1; - return Source.REMOVE; - }); - } else { - update_progress(); - } - } - } + private void setup_animation() { + progress_animation = new Adw.TimedAnimation(this, 0.0, 0.0, 250, new Adw.CallbackAnimationTarget(queue_draw)) { easing = Adw.Easing.LINEAR }; + progress_animation.done.connect(update_progress); } private void on_state_changed() { @@ -80,17 +66,41 @@ namespace Dino.Ui { } private void update_progress() { - this.get_style_context().remove_provider(css_provider); - int64 progress_percent = transferred_size * 100 / file_size; + if (file_size == 0 || progress_animation == null) return; + double next_value = (double)transferred_size / (double)file_size; + if (progress_animation != null && progress_animation.value_to != next_value) { + progress_animation.value_from = progress_animation.value; + progress_animation.value_to = next_value; + progress_animation.reset(); + progress_animation.play(); + } + } - css_provider = Util.force_css(this, @" - .circular-loading-indicator { - background-image: conic-gradient(@accent_color $(progress_percent)%, transparent $(progress_percent)%); - } - "); + private static extern Gsk.Path create_progress_arc(Gsk.Path circle, float percentage); - next_update_time = get_monotonic_time() / 1000 + 500; - last_progress_percent = progress_percent; + public override void snapshot(Gtk.Snapshot snapshot) { + base.snapshot(snapshot); + + if (state == State.DOWNLOADING || state == State.UPLOADING) { + Gdk.RGBA fg_color = get_color(); + get_style_context().lookup_color("accent_color", out fg_color); + + float radius = float.max(int.min(get_width(), get_height()) / 2, 1); + float line_width = (float) LINE_WIDTH; + + var stroke = new Gsk.Stroke(line_width); + stroke.set_line_cap(Gsk.LineCap.ROUND); + + snapshot.translate({get_width() / 2, get_height() / 2}); + + var builder = new Gsk.PathBuilder(); + builder.add_circle({0, 0}, radius - line_width / 2); + var circle_path = builder.to_path(); + if (progress_animation.value > 0.01) { + var arc_path = create_progress_arc(circle_path, (float) progress_animation.value); + snapshot.append_stroke(arc_path, stroke, fg_color); + } + } } private void on_button_clicked() { @@ -109,10 +119,7 @@ namespace Dino.Ui { } public override void dispose() { - if (update_progress_timeout_id != -1) { - Source.remove(update_progress_timeout_id); - update_progress_timeout_id = -1; - } + progress_animation = null; base.dispose(); } } |
