19#include <gtkmm/comboboxtext.h>
20#include <gtkmm/dropdown.h>
21#include <gtkmm/eventcontrollerfocus.h>
22#include <gtkmm/frame.h>
23#include <gtkmm/grid.h>
24#include <gtkmm/picture.h>
25#include <gtkmm/checkbutton.h>
26#include <gtkmm/progressbar.h>
27#include <gtkmm/stack.h>
41constexpr auto cbt_ss_map = std::to_array({
49constexpr auto cbt_ms_map = std::to_array({
65 std::unique_ptr<Trace::TracingEngine>
engine;
69class TraceDialogImpl :
public TraceDialog
73 ~TraceDialogImpl()
override;
76 void selectionModified(Selection *selection,
unsigned flags)
override;
77 void selectionChanged(Selection *selection)
override;
80 TraceData getTraceData()
const;
82 void adjustParamsVisible();
83 void onTraceClicked();
84 void onAbortClicked();
85 bool previewsEnabled()
const;
86 void schedulePreviewUpdate(
int msecs,
bool force =
false);
87 void updatePreview(
bool force =
false);
88 void launchPreviewGeneration();
129TraceData TraceDialogImpl::getTraceData()
const
131 auto current_page =
static_cast<Page>(
choice_tab.get_current_page());
134 bool enable_siox = cb_siox.get_active();
136 auto trace_type = current_page == Page::SingleScan
137 ? cbt_ss_map.at(
CBT_SS.get_selected())
138 : cbt_ms_map.at(
CBT_MS.get_selected());
140 EngineType engine_type;
141 if (current_page == Page::PixelArt) {
142 engine_type = EngineType::Depixelize;
144 switch (trace_type) {
148 engine_type = EngineType::Autotrace;
151 engine_type = EngineType::Potrace;
156 auto setup_potrace = [&,
this] {
157 auto eng = std::make_unique<Trace::Potrace::PotraceTracingEngine>(
164 eng->setOptiCurve(cb_optimize.get_active());
165 eng->setOptTolerance(
optimize->get_value());
168 eng->setAlphaMax(cb_smooth.get_active() ?
smooth->get_value() : 0);
171 eng->setTurdSize(cb_speckles.get_active() ? (
int)
speckles->get_value() : 0);
176 auto setup_autotrace = [&,
this] {
177 auto eng = std::make_unique<Trace::Autotrace::AutotraceTracingEngine>();
179 switch (trace_type) {
181 eng->setColorCount(2);
184 eng->setColorCount(2);
185 eng->setCenterLine(
true);
186 eng->setPreserveWidth(
true);
189 eng->setColorCount((
int)
MS_scans->get_value() + 1);
196 eng->setFilterIterations((
int)
SS_AT_FI_T->get_value());
197 eng->setErrorThreshold(
SS_AT_ET_T->get_value());
202 auto setup_depixelize = [
this] {
203 return std::make_unique<Trace::Depixelize::DepixelizeTracingEngine>(
211 switch (engine_type) {
212 case EngineType::Potrace:
data.engine = setup_potrace();
break;
213 case EngineType::Autotrace:
data.engine = setup_autotrace();
break;
214 case EngineType::Depixelize:
data.engine = setup_depixelize();
break;
215 default: assert(
false);
break;
217 data.sioxEnabled = enable_siox;
227void TraceDialogImpl::selectionModified(Selection *selection,
unsigned flags)
229 auto mask = SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG;
230 if ((flags & mask) == mask) {
233 }
else if (flags & mask) {
235 schedulePreviewUpdate(1000);
239void TraceDialogImpl::setDefaults()
269void TraceDialogImpl::onAbortClicked()
281void TraceDialogImpl::onTraceClicked()
289 auto data = getTraceData();
292 [
this] (
double progress) {
293 progressbar.set_fraction(progress);
297 progressbar.set_fraction(1.0);
298 stack.set_visible_child(boxchild1);
299 if (auto desktop = getDesktop()) desktop->clearWaitingCursor();
300 trace_future.cancel();
315TraceDialogImpl::TraceDialogImpl()
370 bin.set_expand(
true);
372 auto prefs = Preferences::get();
374 _live_preview.set_active(prefs->getBool(getPrefsPath() +
"liveUpdate",
true));
376 B_Update.signal_clicked().connect([
this] { updatePreview(
true); });
377 B_OK.signal_clicked().connect(sigc::mem_fun(*
this, &TraceDialogImpl::onTraceClicked));
378 B_STOP.signal_clicked().connect(sigc::mem_fun(*
this, &TraceDialogImpl::onAbortClicked));
379 B_RESET.signal_clicked().connect(sigc::mem_fun(*
this, &TraceDialogImpl::setDefaults));
382 bin.connectBeforeResize([
this] (
int width,
int height,
int baseline) {
386 double const ratio =
width /
static_cast<double>(
height);
388 constexpr double hysteresis = 0.01;
389 if (ratio < 1 - hysteresis) {
392 orient_box.set_orientation(Gtk::Orientation::VERTICAL);
393 }
else if (ratio > 1 + hysteresis) {
395 orient_box.set_orientation(Gtk::Orientation::HORIZONTAL);
401 CBT_SS.property_selected().signal_changed().connect([
this] { adjustParamsVisible(); });
402 adjustParamsVisible();
406 adj->signal_value_changed().connect([
this] { updatePreview(); });
409 checkbtn->signal_toggled().connect([
this] { updatePreview(); });
412 combo->property_selected().signal_changed().connect([
this] { updatePreview(); });
416 auto focus = Gtk::EventControllerFocus::create();
417 focus->set_propagation_phase(Gtk::PropagationPhase::BUBBLE);
418 add_controller(focus);
419 focus->signal_enter().connect([
this] { updatePreview(); });
422TraceDialogImpl::~TraceDialogImpl()
429bool TraceDialogImpl::previewsEnabled()
const
434void TraceDialogImpl::schedulePreviewUpdate(
int msecs,
bool force)
436 if (!previewsEnabled() && !force) {
448void TraceDialogImpl::updatePreview(
bool force)
450 if (!previewsEnabled() && !force) {
464 auto data = getTraceData();
467 [
this] (Glib::RefPtr<Gdk::Pixbuf>
result) {
468 previewArea.set_paintable(Gdk::Texture::create_for_pixbuf(result));
469 preview_future.cancel();
472 if (preview_pending_recompute) {
484void TraceDialogImpl::adjustParamsVisible()
486 int constexpr start_row = 2;
489 int show1 = start_row +
option;
493 for (
int row = start_row; row < start_row + 5; ++row) {
494 for (
int col = 0; col < 4; ++col) {
495 if (
auto widget =
_param_grid.get_child_at(col, row)) {
496 if (row == show1 || row == show2) {
497 widget->set_visible(
true);
499 widget->set_visible(
false);
508std::unique_ptr<TraceDialog> TraceDialog::create()
510 return std::make_unique<TraceDialogImpl>();
Bin: widget that can hold one child, useful as a base class of custom widgets.
Preference storage class.
static Preferences * get()
Access the singleton Preferences object.
void setBool(Glib::ustring const &pref_path, bool value)
Set a Boolean value.
The set of selected SPObjects for a given document and layer model.
void clearWaitingCursor()
Editable view implementation.
This is the C++ glue between Inkscape and Autotrace.
SymmetricMatrix< N > adj(const ConstBaseSymmetricMatrix< N > &S)
TraceFuture trace(std::unique_ptr< TracingEngine > engine, bool sioxEnabled, std::function< void(double)> onprogress, std::function< void()> onfinished)
Launch an asynchronous trace operation taking as input engine and sioxEnabled.
Glib::RefPtr< Ob > get_object(Glib::RefPtr< Gtk::Builder > const &builder, char const *id)
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
Helper class to stream background task notifications as a series of messages.
Singleton class to access the preferences file in a convenient way.
void append(std::vector< T > &vec, std::vector< T > const &other)
sigc::scoped_connection _page_switched
Gtk::CheckButton & CB_MS_smooth
Glib::RefPtr< Gtk::Adjustment > SS_AT_ET_T
Gtk::Picture & previewArea
Glib::RefPtr< Gtk::Adjustment > smooth
Gtk::CheckButton & CB_MS_stack
Trace::TraceFuture preview_future
Glib::RefPtr< Gtk::Adjustment > SS_AT_FI_T
Glib::RefPtr< Gtk::Builder > builder
Glib::RefPtr< Gtk::Adjustment > PA_curves
Gtk::CheckButton & CB_optimize
Glib::RefPtr< Gtk::Adjustment > optimize
Trace::TraceFuture trace_future
Gtk::CheckButton & CB_optimize1
Gtk::CheckButton & CB_SIOX
Gtk::CheckButton & CB_speckles
Gtk::CheckButton & CB_SIOX1
sigc::connection preview_timeout_conn
Glib::RefPtr< Gtk::Adjustment > SS_BC_T
Gtk::CheckButton & CB_invert
Gtk::CheckButton & _live_preview
Gtk::ProgressBar & progressbar
Gtk::CheckButton & CB_speckles1
Gtk::CheckButton & CB_smooth1
Gtk::CheckButton & CB_MS_rb
Gtk::CheckButton & CB_PA_optimize
Glib::RefPtr< Gtk::Adjustment > MS_scans
Glib::RefPtr< Gtk::Adjustment > PA_islands
Glib::RefPtr< Gtk::Adjustment > SS_ED_T
Glib::RefPtr< Gtk::Adjustment > speckles
Gtk::CheckButton & RB_PA_voronoi
bool preview_pending_recompute
Glib::RefPtr< Gtk::Adjustment > PA_sparse2
Gtk::Frame & _preview_frame
std::unique_ptr< Trace::TracingEngine > engine
Glib::RefPtr< Gtk::Adjustment > PA_sparse1
Gtk::CheckButton & CB_smooth
Glib::RefPtr< Gtk::Adjustment > SS_CQ_T
Gtk::Notebook & choice_tab
Bitmap tracing settings dialog - second implementation.
bool is_widget_effectively_visible(Gtk::Widget const *widget)