Add feedback via HUD progress pulse on slow inline image paste
This commit is contained in:
parent
4d0ed05a2b
commit
50a1691b2f
2 changed files with 70 additions and 16 deletions
|
|
@ -28,6 +28,10 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
private const string DEFAULT_TITLE = _("New Message");
|
||||
|
||||
|
||||
/** For providing feedback on slow operation for large inline image paste. */
|
||||
private const int SHOW_BACKGROUND_WORK_TIMEOUT_MSEC = 500;
|
||||
private const int PULSE_TIMEOUT_MSEC = 250;
|
||||
|
||||
public enum ComposeType {
|
||||
NEW_MESSAGE,
|
||||
REPLY,
|
||||
|
|
@ -386,6 +390,9 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
[GtkChild]
|
||||
private Gtk.Label info_label;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ProgressBar background_progress;
|
||||
|
||||
private GLib.SimpleActionGroup composer_actions = new GLib.SimpleActionGroup();
|
||||
private GLib.SimpleActionGroup editor_actions = new GLib.SimpleActionGroup();
|
||||
|
||||
|
|
@ -468,6 +475,12 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
|
||||
private Application.Client application;
|
||||
|
||||
// Timeout for showing the slow image paste pulsing bar
|
||||
private Geary.TimeoutManager show_background_work_timeout = null;
|
||||
|
||||
// Timer for pulsing progress bar
|
||||
private Geary.TimeoutManager background_work_pulse;
|
||||
|
||||
|
||||
public Widget(Application.Client application,
|
||||
Geary.Account initial_account,
|
||||
|
|
@ -593,6 +606,14 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
this.editor.mouse_target_changed.connect(on_mouse_target_changed);
|
||||
this.editor.selection_changed.connect(on_selection_changed);
|
||||
|
||||
this.show_background_work_timeout = new Geary.TimeoutManager.milliseconds(
|
||||
SHOW_BACKGROUND_WORK_TIMEOUT_MSEC, this.on_background_work_timeout
|
||||
);
|
||||
this.background_work_pulse = new Geary.TimeoutManager.milliseconds(
|
||||
PULSE_TIMEOUT_MSEC, this.background_progress.pulse
|
||||
);
|
||||
this.background_work_pulse.repetition = FOREVER;
|
||||
|
||||
load_entry_completions();
|
||||
}
|
||||
|
||||
|
|
@ -885,6 +906,9 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
on_account_unavailable
|
||||
);
|
||||
|
||||
this.show_background_work_timeout.reset();
|
||||
this.background_work_pulse.reset();
|
||||
|
||||
base.destroy();
|
||||
}
|
||||
|
||||
|
|
@ -2036,30 +2060,36 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
private void paste_image() {
|
||||
// The slow operations here are creating the PNG and, to a lesser extent,
|
||||
// requesting the image from the clipboard
|
||||
this.container.top_window.application.mark_busy();
|
||||
this.show_background_work_timeout.start();
|
||||
|
||||
get_clipboard(Gdk.SELECTION_CLIPBOARD).request_image((clipboard, pixbuf) => {
|
||||
if (pixbuf != null) {
|
||||
try {
|
||||
uint8[] buffer;
|
||||
pixbuf.save_to_buffer(out buffer, "png");
|
||||
Geary.Memory.ByteBuffer byte_buffer = new Geary.Memory.ByteBuffer(buffer, buffer.length);
|
||||
MemoryOutputStream os = new MemoryOutputStream(null);
|
||||
pixbuf.save_to_stream_async.begin(os, "png", null, (obj, res) => {
|
||||
try {
|
||||
pixbuf.save_to_stream_async.end(res);
|
||||
os.close();
|
||||
|
||||
GLib.DateTime time_now = new GLib.DateTime.now();
|
||||
string filename = PASTED_IMAGE_FILENAME_TEMPLATE.printf(time_now.hash());
|
||||
Geary.Memory.ByteBuffer byte_buffer = new Geary.Memory.ByteBuffer.from_memory_output_stream(os);
|
||||
|
||||
string unique_filename;
|
||||
add_inline_part(byte_buffer, filename, out unique_filename);
|
||||
this.editor.insert_image(
|
||||
Components.WebView.INTERNAL_URL_PREFIX + unique_filename
|
||||
);
|
||||
} catch (Error error) {
|
||||
warning("Failed to paste image %s", error.message);
|
||||
}
|
||||
GLib.DateTime time_now = new GLib.DateTime.now();
|
||||
string filename = PASTED_IMAGE_FILENAME_TEMPLATE.printf(time_now.hash());
|
||||
|
||||
string unique_filename;
|
||||
add_inline_part(byte_buffer, filename, out unique_filename);
|
||||
this.editor.insert_image(
|
||||
Components.WebView.INTERNAL_URL_PREFIX + unique_filename
|
||||
);
|
||||
} catch (Error err) {
|
||||
warning("Failed to convert pasted clipboard image to PNG");
|
||||
}
|
||||
|
||||
stop_background_work_pulse();
|
||||
});
|
||||
} else {
|
||||
warning("Failed to get image from clipboard");
|
||||
stop_background_work_pulse();
|
||||
}
|
||||
this.container.top_window.application.unmark_busy();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -2807,4 +2837,18 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
Components.WebView.INTERNAL_URL_PREFIX + unique_filename
|
||||
);
|
||||
}
|
||||
|
||||
/** Shows and starts pulsing the progress meter. */
|
||||
private void on_background_work_timeout() {
|
||||
this.background_progress.fraction = 0.0;
|
||||
this.background_work_pulse.start();
|
||||
this.background_progress.show();
|
||||
}
|
||||
|
||||
/** Hides and stops pulsing the progress meter. */
|
||||
private void stop_background_work_pulse() {
|
||||
this.background_progress.hide();
|
||||
this.background_work_pulse.reset();
|
||||
this.show_background_work_timeout.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -850,6 +850,16 @@
|
|||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="overlay">
|
||||
<object class="GtkProgressBar" id="background_progress">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<style>
|
||||
<class name="osd"/>
|
||||
<class name="top"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue