app: add a GimpBusyBox near the "Line Art Detection" label in…

… Bucket Fill tool options.
This will provide feedback when the line art closure is being computed,
which may be useful on big images where it may take some time. Otherwise
painter may be left hanging without knowing what takes time.
This commit is contained in:
Jehan 2019-03-04 16:06:59 +01:00
parent daa09ef602
commit bc187cc5cc
5 changed files with 115 additions and 34 deletions

View File

@ -35,6 +35,7 @@
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimplineart.h"
#include "gimpmarshal.h"
#include "gimppickable.h"
#include "gimpprojection.h"
#include "gimpviewable.h"
@ -42,6 +43,13 @@
#include "gimp-intl.h"
enum
{
COMPUTING_START,
COMPUTING_END,
LAST_SIGNAL,
};
enum
{
PROP_0,
@ -282,11 +290,30 @@ static void gimp_edgelset_next8 (const GeglBuffer *buffer,
G_DEFINE_TYPE_WITH_CODE (GimpLineArt, gimp_line_art, GIMP_TYPE_OBJECT,
G_ADD_PRIVATE (GimpLineArt))
static guint gimp_line_art_signals[LAST_SIGNAL] = { 0 };
static void
gimp_line_art_class_init (GimpLineArtClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
gimp_line_art_signals[COMPUTING_START] =
g_signal_new ("computing-start",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpLineArtClass, computing_start),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_line_art_signals[COMPUTING_END] =
g_signal_new ("computing-end",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpLineArtClass, computing_end),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
object_class->finalize = gimp_line_art_finalize;
object_class->set_property = gimp_line_art_set_property;
object_class->get_property = gimp_line_art_get_property;
@ -538,6 +565,7 @@ gimp_line_art_compute (GimpLineArt *line_art)
G_CALLBACK (gimp_line_art_input_invalidate_preview),
line_art);
line_art->priv->async = gimp_line_art_prepare_async (line_art, +1);
g_signal_emit (line_art, gimp_line_art_signals[COMPUTING_START], 0);
g_signal_handlers_unblock_by_func (
line_art->priv->input,
G_CALLBACK (gimp_line_art_input_invalidate_preview),
@ -553,6 +581,8 @@ static void
gimp_line_art_compute_cb (GimpAsync *async,
GimpLineArt *line_art)
{
g_signal_emit (line_art, gimp_line_art_signals[COMPUTING_END], 0);
if (gimp_async_is_canceled (async))
return;

View File

@ -45,6 +45,11 @@ struct _GimpLineArt
struct _GimpLineArtClass
{
GimpObjectClass parent_class;
/* Signals */
void (* computing_start) (GimpLineArt *line_art);
void (* computing_end) (GimpLineArt *line_art);
};

View File

@ -364,13 +364,14 @@ gimp_bucket_fill_options_gui (GimpToolOptions *tool_options)
GimpBucketFillOptions *options = GIMP_BUCKET_FILL_OPTIONS (tool_options);
GObject *config = G_OBJECT (tool_options);
GtkWidget *vbox = gimp_paint_options_gui (tool_options);
GtkWidget *vbox2;
GtkWidget *box2;
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *widget;
GtkWidget *scale;
GtkWidget *combo;
gchar *str;
gboolean bold;
GdkModifierType extend_mask = gimp_get_extend_selection_mask ();
GdkModifierType toggle_mask = GDK_MOD1_MASK;
@ -404,86 +405,105 @@ gimp_bucket_fill_options_gui (GimpToolOptions *tool_options)
options->priv->similar_color_frame = frame;
gtk_widget_show (frame);
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame), vbox2);
gtk_widget_show (vbox2);
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame), box2);
gtk_widget_show (box2);
/* the fill transparent areas toggle */
button = gimp_prop_check_button_new (config, "fill-transparent", NULL);
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
gtk_widget_show (button);
widget = gimp_prop_check_button_new (config, "fill-transparent", NULL);
gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
/* the sample merged toggle */
button = gimp_prop_check_button_new (config, "sample-merged", NULL);
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
gtk_widget_show (button);
widget = gimp_prop_check_button_new (config, "sample-merged", NULL);
gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
/* the diagonal neighbors toggle */
button = gimp_prop_check_button_new (config, "diagonal-neighbors", NULL);
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
options->priv->diagonal_neighbors_checkbox = button;
gtk_widget_show (button);
widget = gimp_prop_check_button_new (config, "diagonal-neighbors", NULL);
gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
options->priv->diagonal_neighbors_checkbox = widget;
gtk_widget_show (widget);
/* the antialias toggle */
button = gimp_prop_check_button_new (config, "antialias", NULL);
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
gtk_widget_show (button);
widget = gimp_prop_check_button_new (config, "antialias", NULL);
gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
/* the threshold scale */
scale = gimp_prop_spin_scale_new (config, "threshold", NULL,
1.0, 16.0, 1);
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2), scale, FALSE, FALSE, 0);
options->priv->threshold_scale = scale;
gtk_widget_show (scale);
/* the fill criterion combo */
combo = gimp_prop_enum_combo_box_new (config, "fill-criterion", 0, 0);
gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Fill by"));
gtk_box_pack_start (GTK_BOX (vbox2), combo, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2), combo, FALSE, FALSE, 0);
gtk_widget_show (combo);
/* Line art frame */
frame = gimp_frame_new (_("Line Art Detection"));
frame = gimp_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
options->priv->line_art_frame = frame;
gtk_widget_show (frame);
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame), vbox2);
gtk_widget_show (vbox2);
/* Line art: label widget */
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
gtk_frame_set_label_widget (GTK_FRAME (frame), box2);
gtk_widget_show (box2);
widget = gtk_label_new (_("Line Art Detection"));
gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
gtk_widget_style_get (GTK_WIDGET (frame),
"label-bold", &bold,
NULL);
gimp_label_set_attributes (GTK_LABEL (widget),
PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
-1);
gtk_widget_show (widget);
options->line_art_busy_box = gimp_busy_box_new (_("(computing...)"));
gtk_box_pack_start (GTK_BOX (box2), options->line_art_busy_box,
FALSE, FALSE, 0);
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame), box2);
gtk_widget_show (box2);
/* Line Art: source combo (replace sample merged!) */
combo = gimp_prop_enum_combo_box_new (config, "line-art-source", 0, 0);
gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Source"));
gtk_box_pack_start (GTK_BOX (vbox2), combo, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2), combo, FALSE, FALSE, 0);
gtk_widget_show (combo);
/* the fill transparent areas toggle */
button = gimp_prop_check_button_new (config, "fill-transparent", NULL);
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
gtk_widget_show (button);
widget = gimp_prop_check_button_new (config, "fill-transparent", NULL);
gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
/* the antialias toggle */
button = gimp_prop_check_button_new (config, "antialias", NULL);
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
gtk_widget_show (button);
widget = gimp_prop_check_button_new (config, "antialias", NULL);
gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
/* Line Art: max growing size */
scale = gimp_prop_spin_scale_new (config, "line-art-max-grow", NULL,
1, 5, 0);
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2), scale, FALSE, FALSE, 0);
gtk_widget_show (scale);
/* Line Art: stroke threshold */
scale = gimp_prop_spin_scale_new (config, "line-art-threshold", NULL,
0.05, 0.1, 2);
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2), scale, FALSE, FALSE, 0);
gtk_widget_show (scale);
/* Line Art: max gap length */
scale = gimp_prop_spin_scale_new (config, "line-art-max-gap-length", NULL,
1, 5, 0);
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2), scale, FALSE, FALSE, 0);
gtk_widget_show (scale);
gimp_bucket_fill_options_update_area (options);

View File

@ -46,6 +46,7 @@ struct _GimpBucketFillOptions
gboolean antialias;
gdouble threshold;
GtkWidget *line_art_busy_box;
GimpLineArtSource line_art_source;
gdouble line_art_threshold;
gint line_art_max_grow;

View File

@ -116,6 +116,9 @@ static void gimp_bucket_fill_tool_options_notify (GimpTool *t
GimpToolOptions *options,
const GParamSpec *pspec);
static void gimp_bucket_fill_tool_line_art_computing_start (GimpBucketFillTool *tool);
static void gimp_bucket_fill_tool_line_art_computing_end (GimpBucketFillTool *tool);
static void gimp_bucket_fill_tool_start (GimpBucketFillTool *tool,
const GimpCoords *coords,
GimpDisplay *display);
@ -226,6 +229,12 @@ gimp_bucket_fill_tool_constructed (GObject *object)
g_object_bind_property (options, "line-art-max-gap-length",
line_art, "segment-max-length",
G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT);
g_signal_connect_swapped (line_art, "computing-start",
G_CALLBACK (gimp_bucket_fill_tool_line_art_computing_start),
tool);
g_signal_connect_swapped (line_art, "computing-end",
G_CALLBACK (gimp_bucket_fill_tool_line_art_computing_end),
tool);
bucket_tool->priv->line_art = line_art;
gimp_bucket_fill_tool_reset_line_art (bucket_tool);
@ -833,6 +842,22 @@ gimp_bucket_fill_tool_options_notify (GimpTool *tool,
}
}
static void
gimp_bucket_fill_tool_line_art_computing_start (GimpBucketFillTool *tool)
{
GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool);
gtk_widget_show (options->line_art_busy_box);
}
static void
gimp_bucket_fill_tool_line_art_computing_end (GimpBucketFillTool *tool)
{
GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool);
gtk_widget_hide (options->line_art_busy_box);
}
static void
gimp_bucket_fill_tool_reset_line_art (GimpBucketFillTool *tool)
{