diff options
| -rw-r--r-- | CMakeScripts/DefineDependsandFlags.cmake | 16 | ||||
| -rw-r--r-- | src/ui/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/ui/dialog/tracedialog.cpp | 1008 | ||||
| -rw-r--r-- | src/ui/dialog/tracedialog2.cpp | 357 |
4 files changed, 254 insertions, 1128 deletions
diff --git a/CMakeScripts/DefineDependsandFlags.cmake b/CMakeScripts/DefineDependsandFlags.cmake index 7e6aa453b..b41b18cc9 100644 --- a/CMakeScripts/DefineDependsandFlags.cmake +++ b/CMakeScripts/DefineDependsandFlags.cmake @@ -205,16 +205,12 @@ find_package(PNG REQUIRED) list(APPEND INKSCAPE_INCS_SYS ${PNG_PNG_INCLUDE_DIR}) list(APPEND INKSCAPE_LIBS ${PNG_LIBRARY}) -find_package(Potrace) -if(POTRACE_FOUND) - list(APPEND INKSCAPE_INCS_SYS ${POTRACE_INCLUDE_DIRS}) - list(APPEND INKSCAPE_LIBS ${POTRACE_LIBRARIES}) - set(HAVE_POTRACE ON) - add_definitions(-DHAVE_POTRACE) -else(POTRACE_FOUND) - set(HAVE_POTRACE OFF) - message(STATUS "Could not locate the Potrace library headers: the Trace Bitmap and Paintbucket tools will be disabled") -endif() +find_package(Potrace REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${POTRACE_INCLUDE_DIRS}) +list(APPEND INKSCAPE_LIBS ${POTRACE_LIBRARIES}) +set(HAVE_POTRACE ON) +add_definitions(-DHAVE_POTRACE) + if(WITH_DBUS) pkg_check_modules(DBUS dbus-1 dbus-glib-1) diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index ffe1d1394..56b0ef983 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -471,7 +471,6 @@ set ( ui_flood_and_trace_SRC tools/flood-tool.h tools/flood-tool.cpp dialog/tracedialog.cpp - dialog/tracedialog2.cpp dialog/tracedialog.h toolbar/paintbucket-toolbar.cpp toolbar/paintbucket-toolbar.h diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index 1b9c9d4ff..be214e867 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -1,225 +1,91 @@ // SPDX-License-Identifier: GPL-2.0-or-later /** * @file - * Bitmap tracing settings dialog - implementation. + * Bitmap tracing settings dialog - second implementation. */ /* Authors: - * Bob Jamison <rjamison@titan.com> - * Stéphane Gimenez <dev@gim.name> - * Other dudes from The Inkscape Organization + * Marc Jeanmougin <marc.jeanmougin@telecom-paristech.fr> * - * Copyright (C) 2004-2006 Authors + * Copyright (C) 2019 Authors * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ -#if 0 + #include "tracedialog.h" + +#include <gtkmm.h> +#include <gtkmm/comboboxtext.h> #include <gtkmm/notebook.h> -#include <gtkmm/frame.h> #include <gtkmm/radiobutton.h> -#include "ui/widget/spinbutton.h" -#include "ui/widget/frame.h" +#include <gtkmm/spinbutton.h> +#include <gtkmm/stack.h> + #include <glibmm/i18n.h> -#include "desktop.h" #include "desktop-tracker.h" +#include "desktop.h" #include "selection.h" -#include "trace/potrace/inkscape-potrace.h" #include "inkscape.h" +#include "io/resource.h" +#include "io/sys.h" +#include "trace/autotrace/inkscape-autotrace.h" +#include "trace/potrace/inkscape-potrace.h" +#include "trace/depixelize/inkscape-depixelize.h" + namespace Inkscape { namespace UI { namespace Dialog { +class TraceDialogImpl2 : public TraceDialog { + public: + TraceDialogImpl2(); + ~TraceDialogImpl2() override; -//######################################################################### -//## I M P L E M E N T A T I O N -//######################################################################### - -/** - * A dialog for adjusting bitmap->vector tracing parameters - */ -class TraceDialogImpl : public TraceDialog -{ - - public: - - - /** - * Constructor - */ - TraceDialogImpl(); - - /** - * Destructor - */ - ~TraceDialogImpl() override; - - /** - * Callback from OK or Cancel - */ - void responseCallback(int response_id); - - private: - - /** - * This is the big almighty McGuffin - */ + private: Inkscape::Trace::Tracer tracer; - - /** - * This does potrace processing - * Only preview if do_i_trace is false - */ - void potraceProcess(bool do_i_trace); - - /** - * Abort processing - */ + void traceProcess(bool do_i_trace); void abort(); void previewCallback(); - void previewLiveCallback(); - void onSettingsChange(); - void onSelectionModified( guint flags ); + void traceCallback(); + void onSelectionModified(guint flags); void onSetDefaults(); void setDesktop(SPDesktop *desktop) override; void setTargetDesktop(SPDesktop *desktop); - //############ General items - - Gtk::HBox mainHBox; - - Gtk::Button *mainOkButton; - Gtk::Button *mainCancelButton; - Gtk::Button *mainResetButton; - - //######## Left pannel - - Gtk::VBox leftVBox; - - //#### Notebook - - Gtk::Notebook notebook; - - //## Modes - - Gtk::VBox modePageBox; - Gtk::RadioButtonGroup modeGroup; - - //# Single scan mode - //brightness - UI::Widget::Frame modeBrightnessFrame; - Gtk::VBox modeBrightnessVBox; - Gtk::HBox modeBrightnessBox; - Gtk::RadioButton modeBrightnessRadioButton; - Gtk::Label modeBrightnessSpinnerLabel; - Inkscape::UI::Widget::SpinButton modeBrightnessSpinner; - //edge detection - UI::Widget::Frame modeCannyFrame; - Gtk::HBox modeCannyBox; - Gtk::VBox modeCannyVBox; - Gtk::RadioButton modeCannyRadioButton; - //Gtk::HSeparator modeCannySeparator; - //Gtk::Label modeCannyLoSpinnerLabel; - //Inkscape::UI::Widget::SpinButton modeCannyLoSpinner; - Gtk::Label modeCannyHiSpinnerLabel; - Inkscape::UI::Widget::SpinButton modeCannyHiSpinner; - //quantization - UI::Widget::Frame modeQuantFrame; - Gtk::HBox modeQuantBox; - Gtk::VBox modeQuantVBox; - Gtk::RadioButton modeQuantRadioButton; - Gtk::Label modeQuantNrColorLabel; - Inkscape::UI::Widget::SpinButton modeQuantNrColorSpinner; - //params - Gtk::CheckButton modeInvertButton; - Gtk::HBox modeInvertBox; - - //# Multiple path scanning mode - UI::Widget::Frame modeMultiScanFrame; - Gtk::VBox modeMultiScanVBox; - //brightness - Gtk::HBox modeMultiScanHBox1; - Gtk::RadioButton modeMultiScanBrightnessRadioButton; - Inkscape::UI::Widget::SpinButton modeMultiScanNrColorSpinner; - //colors - Gtk::HBox modeMultiScanHBox2; - Gtk::RadioButton modeMultiScanColorRadioButton; - //grays - Gtk::HBox modeMultiScanHBox3; - Gtk::RadioButton modeMultiScanMonoRadioButton; - Gtk::Label modeMultiScanNrColorLabel; - //params - Gtk::HBox modeMultiScanHBox4; - Gtk::CheckButton modeMultiScanStackButton; - Gtk::CheckButton modeMultiScanSmoothButton; - Gtk::CheckButton modeMultiScanBackgroundButton; - - //## Options - - Gtk::VBox optionsPageBox; - - // potrace parameters - - UI::Widget::Frame optionsFrame; - Gtk::VBox optionsVBox; - Gtk::HBox optionsSpecklesBox; - Gtk::CheckButton optionsSpecklesButton; - Gtk::Label optionsSpecklesSizeLabel; - Inkscape::UI::Widget::SpinButton optionsSpecklesSizeSpinner; - Gtk::HBox optionsCornersBox; - Gtk::CheckButton optionsCornersButton; - Gtk::Label optionsCornersThresholdLabel; - Inkscape::UI::Widget::SpinButton optionsCornersThresholdSpinner; - Gtk::HBox optionsOptimBox; - Gtk::CheckButton optionsOptimButton; - Gtk::Label optionsOptimToleranceLabel; - Inkscape::UI::Widget::SpinButton optionsOptimToleranceSpinner; - - - //#### Credits - - Gtk::VBox potraceCreditsVBox; - Gtk::Label potraceCreditsLabel; - - //######## Right pannel - - Gtk::VBox rightVBox; - - //#### SIOX selection - - Gtk::HBox sioxBox; - Gtk::CheckButton sioxButton; - - //#### Preview - - UI::Widget::Frame previewFrame; - Gtk::VBox previewVBox; - Gtk::Button previewButton; - Gtk::CheckButton previewLiveButton; - gboolean previewLive; - Gtk::Image previewImage; - SPDesktop *desktop; DesktopTracker deskTrack; sigc::connection desktopChangeConn; sigc::connection selectChangedConn; sigc::connection selectModifiedConn; + Glib::RefPtr<Gtk::Builder> builder; + + Glib::RefPtr<Gtk::Adjustment> MS_scans, PA_curves, PA_islands, PA_sparse1, PA_sparse2, SS_AT_ET_T, SS_AT_FI_T, SS_BC_T, SS_CQ_T, + SS_ED_T, optimize, smooth, speckles; + Gtk::ComboBoxText *CBT_SS, *CBT_MS; + Gtk::CheckButton *CB_invert, *CB_MS_smooth, *CB_MS_stack, *CB_MS_rb, *CB_speckles, *CB_smooth, *CB_optimize, + /* *CB_live,*/ *CB_SIOX; + Gtk::RadioButton *RB_PA_voronoi; + Gtk::Button *B_RESET, *B_STOP, *B_OK, *B_Update; + Gtk::Box *mainBox; + Gtk::Stack *choice_scan; + Gtk::Notebook *choice_tab; + Gtk::Image *previewImage; }; -void TraceDialogImpl::setDesktop(SPDesktop *desktop) +void TraceDialogImpl2::setDesktop(SPDesktop *desktop) { Panel::setDesktop(desktop); deskTrack.setBase(desktop); } -void TraceDialogImpl::setTargetDesktop(SPDesktop *desktop) +void TraceDialogImpl2::setTargetDesktop(SPDesktop *desktop) { if (this->desktop != desktop) { if (this->desktop) { @@ -228,642 +94,264 @@ void TraceDialogImpl::setTargetDesktop(SPDesktop *desktop) } this->desktop = desktop; if (desktop && desktop->selection) { - selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange))); - selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &TraceDialogImpl::onSelectionModified))); - + selectModifiedConn = desktop->selection->connectModified( + sigc::hide<0>(sigc::mem_fun(*this, &TraceDialogImpl2::onSelectionModified))); } - onSettingsChange(); } } -//######################################################################### -//## E V E N T S -//######################################################################### - -/** - * This does potrace processing - * Only preview if do_i_trace is false - */ -void TraceDialogImpl::potraceProcess(bool do_i_trace) +void TraceDialogImpl2::traceProcess(bool do_i_trace) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) desktop->setWaitingCursor(); - //##### Get the tracer and engine - Inkscape::Trace::Potrace::PotraceTracingEngine pte; - - /* inversion */ - bool invert = modeInvertButton.get_active(); - pte.setInvert(invert); - - //##### Get the preprocessor settings - /* siox -- performed by Tracer, and before any of the others */ - if (sioxButton.get_active()) + if (CB_SIOX->get_active()) tracer.enableSiox(true); else tracer.enableSiox(false); - /* one of the following */ - if (modeBrightnessRadioButton.get_active()) - pte.setTraceType(Inkscape::Trace::Potrace::TRACE_BRIGHTNESS); - else if (modeMultiScanBrightnessRadioButton.get_active()) - pte.setTraceType(Inkscape::Trace::Potrace::TRACE_BRIGHTNESS_MULTI); - else if (modeCannyRadioButton.get_active()) - pte.setTraceType(Inkscape::Trace::Potrace::TRACE_CANNY); - else if (modeQuantRadioButton.get_active()) - pte.setTraceType(Inkscape::Trace::Potrace::TRACE_QUANT); - else if (modeMultiScanColorRadioButton.get_active()) - { - pte.setTraceType(Inkscape::Trace::Potrace::TRACE_QUANT_COLOR); - pte.setInvert(false); - } - else if (modeMultiScanMonoRadioButton.get_active()) - { - pte.setTraceType(Inkscape::Trace::Potrace::TRACE_QUANT_MONO); - pte.setInvert(false); - } + Glib::ustring type = + choice_scan->get_visible_child_name() == "SingleScan" ? CBT_SS->get_active_text() : CBT_MS->get_active_text(); + + Inkscape::Trace::Potrace::TraceType potraceType; + // Inkscape::Trace::Autotrace::TraceType autotraceType; + + bool use_autotrace = false; + Inkscape::Trace::Autotrace::AutotraceTracingEngine ate; // TODO + + if (type == _("Brightness cutoff")) + potraceType = Inkscape::Trace::Potrace::TRACE_BRIGHTNESS; + else if (type == _("Edge detection")) + potraceType = Inkscape::Trace::Potrace::TRACE_CANNY; + else if (type == _("Color quantization")) + potraceType = Inkscape::Trace::Potrace::TRACE_QUANT; + else if (type == _("Autotrace")) + { + // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE + use_autotrace = true; + ate.opts->color_count = 2; + } + else if (type == _("Centerline tracing (autotrace)")) + { + // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE + use_autotrace = true; + ate.opts->color_count = 2; + ate.opts->centerline = true; + ate.opts->preserve_width = true; + } + else if (type == _("Brightness steps")) + potraceType = Inkscape::Trace::Potrace::TRACE_BRIGHTNESS_MULTI; + else if (type == _("Colors")) + potraceType = Inkscape::Trace::Potrace::TRACE_QUANT_COLOR; + else if (type == _("Grays")) + potraceType = Inkscape::Trace::Potrace::TRACE_QUANT_MONO; + else if (type == _("Autotrace (slower)")) + { + // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE + use_autotrace = true; + ate.opts->color_count = (int)MS_scans->get_value() + 1; + } + else + { + g_warning("Should not happen!"); + } + ate.opts->filter_iterations = (int) SS_AT_FI_T->get_value(); + ate.opts->error_threshold = SS_AT_ET_T->get_value(); + + Inkscape::Trace::Potrace::PotraceTracingEngine pte( + potraceType, CB_invert->get_active(), (int)SS_CQ_T->get_value(), SS_BC_T->get_value(), + 0., // Brightness floor + SS_ED_T->get_value(), (int)MS_scans->get_value(), CB_MS_stack->get_active(), CB_MS_smooth->get_active(), + CB_MS_rb->get_active()); + pte.potraceParams->opticurve = CB_optimize->get_active(); + pte.potraceParams->opttolerance = optimize->get_value(); + pte.potraceParams->alphamax = CB_smooth->get_active() ? smooth->get_value() : 0; + pte.potraceParams->turdsize = CB_speckles->get_active() ? (int)speckles->get_value() : 0; + + + + //Inkscape::Trace::Autotrace::AutotraceTracingEngine ate; // TODO + Inkscape::Trace::Depixelize::DepixelizeTracingEngine dte(RB_PA_voronoi->get_active() ? Inkscape::Trace::Depixelize::TraceType::TRACE_VORONOI : Inkscape::Trace::Depixelize::TraceType::TRACE_BSPLINES, PA_curves->get_value(), (int) PA_islands->get_value(), (int) PA_sparse1->get_value(), PA_sparse2->get_value() ); + - /* params */ - int paramsSpecklesSize = - optionsSpecklesButton.get_active() ? - optionsSpecklesSizeSpinner.get_value_as_int() : - 0; - pte.setParamsTurdSize(paramsSpecklesSize); - double paramsCornersThreshold = - optionsCornersButton.get_active() ? - optionsCornersThresholdSpinner.get_value() : - 0.; - pte.setParamsAlphaMax(paramsCornersThreshold); - bool paramsOptim = optionsOptimButton.get_active(); - pte.setParamsOptiCurve(paramsOptim); - double paramsOptimTolerance = optionsOptimToleranceSpinner.get_value(); - pte.setParamsOptTolerance(paramsOptimTolerance); - - //##### Get the single-scan settings - /* brightness */ - double brightnessThreshold = modeBrightnessSpinner.get_value(); - pte.setBrightnessThreshold(brightnessThreshold); - /* canny */ - double cannyHighThreshold = modeCannyHiSpinner.get_value(); - pte.setCannyHighThreshold(cannyHighThreshold); - /* quantization */ - int quantNrColors = modeQuantNrColorSpinner.get_value_as_int(); - pte.setQuantizationNrColors(quantNrColors); - - //##### Get multiple-scan settings - int multiScanNrColors = modeMultiScanNrColorSpinner.get_value_as_int(); - pte.setMultiScanNrColors(multiScanNrColors); - bool do_i_stack = modeMultiScanStackButton.get_active(); - pte.setMultiScanStack(do_i_stack); - bool do_i_smooth = modeMultiScanSmoothButton.get_active(); - pte.setMultiScanSmooth(do_i_smooth); - bool do_i_remove_background = modeMultiScanBackgroundButton.get_active(); - pte.setMultiScanRemoveBackground(do_i_remove_background); - - //##### Get intermediate bitmap image Glib::RefPtr<Gdk::Pixbuf> pixbuf = tracer.getSelectedImage(); - if (pixbuf) - { - Glib::RefPtr<Gdk::Pixbuf> preview = pte.preview(pixbuf); - if (preview) - { - int width = preview->get_width(); - int height = preview->get_height(); - const Gtk::Allocation& vboxAlloc = previewImage.get_allocation(); - double scaleFX = vboxAlloc.get_width() / (double)width; - double scaleFY = vboxAlloc.get_height() / (double)height; - double scaleFactor = scaleFX > scaleFY ? scaleFY : scaleFX; - int newWidth = (int) (((double)width) * scaleFactor); - int newHeight = (int) (((double)height) * scaleFactor); - Glib::RefPtr<Gdk::Pixbuf> scaledPreview = - preview->scale_simple(newWidth, newHeight, - Gdk::INTERP_NEAREST); - //g_object_unref(preview); - previewImage.set(scaledPreview); - } - } - - //##### Convert - if (do_i_trace) - { - if (mainCancelButton) - mainCancelButton->set_sensitive(true); - if (mainOkButton) - mainOkButton->set_sensitive(false); - tracer.trace(&pte); - if (mainCancelButton) - mainCancelButton->set_sensitive(false); - if (mainOkButton) - mainOkButton->set_sensitive(true); + if (pixbuf) { + Glib::RefPtr<Gdk::Pixbuf> preview = use_autotrace ? ate.preview(pixbuf) : pte.preview(pixbuf); + if (preview) { + int width = preview->get_width(); + int height = preview->get_height(); + const Gtk::Allocation &vboxAlloc = previewImage->get_allocation(); + double scaleFX = vboxAlloc.get_width() / (double)width; + double scaleFY = vboxAlloc.get_height() / (double)height; + double scaleFactor = scaleFX > scaleFY ? scaleFY : scaleFX; + int newWidth = (int)(((double)width) * scaleFactor); + int newHeight = (int)(((double)height) * scaleFactor); + Glib::RefPtr<Gdk::Pixbuf> scaledPreview = preview->scale_simple(newWidth, newHeight, Gdk::INTERP_NEAREST); + // g_object_unref(preview); + previewImage->set(scaledPreview); + } + } + if (do_i_trace){ + if (use_autotrace){ + tracer.trace(&ate); + printf("at\n"); + } else if (choice_tab->get_current_page() == 0){ + tracer.trace(&pte); + printf("pt\n"); + } else if (choice_tab->get_current_page() == 1){ + tracer.trace(&dte); + printf("dt\n"); } + } if (desktop) desktop->clearWaitingCursor(); } - -/** - * Abort processing - */ -void TraceDialogImpl::abort() -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - desktop->setWaitingCursor(); - - if (mainCancelButton) - mainCancelButton->set_sensitive(false); - if (mainOkButton) - mainOkButton->set_sensitive(true); - - //### Make the abort() call to the tracer - tracer.abort(); +void TraceDialogImpl2::abort() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) + desktop->clearWaitingCursor(); + tracer.abort(); } - - -//######################################################################### -//## E V E N T S -//######################################################################### - -/** - * Callback for when any setting changes - */ -void TraceDialogImpl::onSettingsChange() +void TraceDialogImpl2::onSelectionModified(guint flags) { - if (previewLive) { + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) { previewCallback(); } } -void TraceDialogImpl::onSelectionModified( guint flags ) +void TraceDialogImpl2::onSetDefaults() { - if (flags & ( SP_OBJECT_MODIFIED_FLAG | - SP_OBJECT_PARENT_MODIFIED_FLAG | - SP_OBJECT_STYLE_MODIFIED_FLAG) ) { - onSettingsChange(); - } + MS_scans->set_value(8); + PA_curves->set_value(1); + PA_islands->set_value(5); + PA_sparse1->set_value(4); + PA_sparse2->set_value(1); + SS_AT_FI_T->set_value(4); + SS_AT_ET_T->set_value(2); + SS_BC_T->set_value(0.45); + SS_CQ_T->set_value(64); + SS_ED_T->set_value(.65); + optimize->set_value(0.2); + smooth->set_value(1); + speckles->set_value(2); + CB_invert->set_active(false); + CB_MS_smooth->set_active(true); + CB_MS_stack->set_active(true); + CB_MS_rb->set_active(false); + CB_speckles->set_active(true); + CB_smooth->set_active(true); + CB_optimize->set_active(true); + //CB_live->set_active(false); + CB_SIOX->set_active(false); } -/** - * Callback for when users resets defaults - */ -void TraceDialogImpl::onSetDefaults() -{ +void TraceDialogImpl2::previewCallback() { traceProcess(false); } +void TraceDialogImpl2::traceCallback() { traceProcess(true); } - // temporarily disable live update - gboolean wasLive = previewLive; - previewLive = false; - - modeBrightnessRadioButton.set_active(true); - modeBrightnessSpinner.set_value(0.45); - modeCannyHiSpinner.set_value(0.65); - modeMultiScanNrColorSpinner.set_value(8.0); - modeMultiScanNrColorSpinner.set_value(8.0); - optionsSpecklesSizeSpinner.set_value(2); - optionsCornersThresholdSpinner.set_value(1.0); - optionsOptimToleranceSpinner.set_value(0.2); - - modeInvertButton.set_active(false); - modeMultiScanSmoothButton.set_active(true); - modeMultiScanStackButton.set_active(true); - modeMultiScanBackgroundButton.set_active(false); - optionsSpecklesButton.set_active(true); - optionsCornersButton.set_active(true); - optionsOptimButton.set_active(true); - sioxButton.set_active(false); - - previewLive = wasLive; - onSettingsChange(); -} - -/** - * Callback from the Preview button. Can be called from elsewhere. - */ -void TraceDialogImpl::previewCallback() -{ - potraceProcess(false); -} - -/** - * Callback from the Preview Live button. - */ -void TraceDialogImpl::previewLiveCallback() +TraceDialogImpl2::TraceDialogImpl2() + : TraceDialog() { - previewLive = previewLiveButton.get_active(); - previewButton.set_sensitive(!previewLive); - onSettingsChange(); -} - -/** - * Default response from the dialog. Let's intercept it - */ -void TraceDialogImpl::responseCallback(int response_id) -{ - if (response_id == GTK_RESPONSE_OK) { - // for now, we assume potrace, as it's the only one we have - potraceProcess(true); - } else if (response_id == GTK_RESPONSE_CANCEL) { - abort(); - } else if (response_id == GTK_RESPONSE_HELP) { - onSetDefaults(); - } else { - hide(); + const std::string req_widgets[] = { "MS_scans", "PA_curves", "PA_islands", "PA_sparse1", "PA_sparse2", + "SS_AT_FI_T", "SS_AT_ET_T", "SS_BC_T", "SS_CQ_T", "SS_ED_T", + "optimize", "smooth", "speckles", "CB_invert", "CB_MS_smooth", + "CB_MS_stack", "CB_MS_rb", "CB_speckles", "CB_smooth", "CB_optimize", + /*"CB_live",*/ "CB_SIOX", "CBT_SS", "CBT_MS", "B_RESET", + "B_STOP", "B_OK", "mainBox", "choice_tab", "choice_scan", + "previewImage" }; + Glib::ustring gladefile = get_filename(Inkscape::IO::Resource::UIS, "dialog-trace.glade"); + try { + builder = Gtk::Builder::create_from_file(gladefile); + } catch (const Glib::Error &ex) { + g_warning("Glade file loading failed for filter effect dialog"); return; } - -} - - - -//######################################################################### -//## C O N S T R U C T O R / D E S T R U C T O R -//######################################################################### -/** - * Constructor - */ -TraceDialogImpl::TraceDialogImpl() : - TraceDialog() -{ - - Gtk::Box *contents = _getContents(); - -#define MARGIN 2 - //#### begin left panel - - //### begin notebook - - //## begin mode page - - //# begin single scan - - // brightness - - modeBrightnessRadioButton.set_label(_("_Brightness cutoff")); - modeGroup = modeBrightnessRadioButton.get_group(); - modeBrightnessRadioButton.set_use_underline(true); - modeBrightnessBox.pack_start(modeBrightnessRadioButton, false, false, MARGIN); - modeBrightnessRadioButton.set_tooltip_text(_("Trace by a given brightness level")); - - modeBrightnessSpinner.set_digits(3); - modeBrightnessSpinner.set_increments(0.01, 0); - modeBrightnessSpinner.set_range(0.0, 1.0); - modeBrightnessSpinner.set_value(0.45); - modeBrightnessBox.pack_end(modeBrightnessSpinner, false, false, MARGIN); - modeBrightnessSpinner.set_tooltip_text(_("Brightness cutoff for black/white")); - modeBrightnessSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeBrightnessSpinnerLabel.set_label(_("_Threshold:")); - modeBrightnessSpinnerLabel.set_use_underline(true); - modeBrightnessSpinnerLabel.set_mnemonic_widget(modeBrightnessSpinner); - modeBrightnessBox.pack_end(modeBrightnessSpinnerLabel, false, false, MARGIN); - - modeBrightnessVBox.pack_start(modeBrightnessBox, false, false, MARGIN); - - modeBrightnessFrame.set_label(_("Single scan: creates a path")); - - // canny edge detection - // TRANSLATORS: "Canny" is the name of the inventor of this edge detection method - - modeCannyRadioButton.set_label(_("_Edge detection")); - modeCannyRadioButton.set_group(modeGroup); - modeCannyRadioButton.set_use_underline(true); - modeCannyBox.pack_start(modeCannyRadioButton, false, false, MARGIN); - modeCannyRadioButton.set_tooltip_text(_("Trace with optimal edge detection by J. Canny's algorithm")); - modeCannyRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - /* - modeCannyBox.pack_start(modeCannySeparator); - modeCannyLoSpinnerLabel.set_label(_("Low")); - modeCannyBox.pack_start(modeCannyLoSpinnerLabel); - modeCannyLoSpinner.set_digits(5); - modeCannyLoSpinner.set_increments(0.01, 0); - modeCannyLoSpinner.set_range(0.0, 1.0); - modeCannyLoSpinner.set_value(0.1); - modeCannyBox.pack_start(modeCannyLoSpinner); - */ - modeCannyHiSpinner.set_digits(3); - modeCannyHiSpinner.set_increments(0.01, 0); - modeCannyHiSpinner.set_range(0.0, 1.0); - modeCannyHiSpinner.set_value(0.65); - modeCannyBox.pack_end(modeCannyHiSpinner, false, false, MARGIN); - modeCannyHiSpinner.set_tooltip_text(_("Brightness cutoff for adjacent pixels (determines edge thickness)")); - modeCannyHiSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeCannyHiSpinnerLabel.set_label(_("T_hreshold:")); - modeCannyHiSpinnerLabel.set_use_underline(true); - modeCannyHiSpinnerLabel.set_mnemonic_widget(modeCannyHiSpinner); - modeCannyBox.pack_end(modeCannyHiSpinnerLabel, false, false, MARGIN); - - modeBrightnessVBox.pack_start(modeCannyBox, false, false, MARGIN); - - // quantization - // TRANSLATORS: Color Quantization: the process of reducing the number - // of colors in an image by selecting an optimized set of representative - // colors and then re-applying this reduced set to the original image. - - modeQuantRadioButton.set_label(_("Color _quantization")); - modeQuantRadioButton.set_group(modeGroup); - modeQuantRadioButton.set_use_underline(true); - modeQuantBox.pack_start(modeQuantRadioButton, false, false, MARGIN); - modeQuantRadioButton.set_tooltip_text(_("Trace along the boundaries of reduced colors")); - modeQuantRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeQuantNrColorSpinner.set_digits(0); - modeQuantNrColorSpinner.set_increments(1.0, 0); - modeQuantNrColorSpinner.set_range(2.0, 64.0); - modeQuantNrColorSpinner.set_value(8.0); - modeQuantBox.pack_end(modeQuantNrColorSpinner, false, false, MARGIN); - modeQuantNrColorSpinner.set_tooltip_text(_("The number of reduced colors")); - modeQuantNrColorSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeQuantNrColorLabel.set_label(_("_Colors:")); - modeQuantNrColorLabel.set_mnemonic_widget(modeQuantNrColorSpinner); - modeQuantNrColorLabel.set_use_underline(true); - modeQuantBox.pack_end(modeQuantNrColorLabel, false, false, MARGIN); - - modeBrightnessVBox.pack_start(modeQuantBox, false, false, MARGIN); - - // swap black and white - modeInvertButton.set_label(_("_Invert image")); - modeInvertButton.set_active(false); - modeInvertButton.set_use_underline(true); - modeInvertBox.pack_start(modeInvertButton, false, false, MARGIN); - modeBrightnessVBox.pack_start(modeInvertBox, false, false, MARGIN); - modeInvertButton.set_tooltip_text(_("Invert black and white regions")); - modeInvertButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeBrightnessFrame.add(modeBrightnessVBox); - modePageBox.pack_start(modeBrightnessFrame, false, false, 0); - - //# end single scan - - //# begin multiple scan - - modeMultiScanBrightnessRadioButton.set_label(_("B_rightness steps")); - modeMultiScanBrightnessRadioButton.set_group(modeGroup); - modeMultiScanBrightnessRadioButton.set_use_underline(true); - modeMultiScanHBox1.pack_start(modeMultiScanBrightnessRadioButton, false, false, MARGIN); - modeMultiScanBrightnessRadioButton.set_tooltip_text(_("Trace the given number of brightness levels")); - modeMultiScanBrightnessRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeMultiScanNrColorSpinner.set_digits(0); - modeMultiScanNrColorSpinner.set_increments(1.0, 0); - modeMultiScanNrColorSpinner.set_range(2.0, 256.0); - modeMultiScanNrColorSpinner.set_value(8.0); - modeMultiScanHBox1.pack_end(modeMultiScanNrColorSpinner, false, false, MARGIN); - modeMultiScanNrColorLabel.set_label(_("Sc_ans:")); - modeMultiScanNrColorLabel.set_use_underline(true); - modeMultiScanNrColorLabel.set_mnemonic_widget(modeMultiScanNrColorSpinner); - modeMultiScanHBox1.pack_end(modeMultiScanNrColorLabel, false, false, MARGIN); - modeMultiScanNrColorSpinner.set_tooltip_text(_("The desired number of scans")); - modeMultiScanNrColorSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeMultiScanVBox.pack_start(modeMultiScanHBox1, false, false, MARGIN); - - modeMultiScanColorRadioButton.set_label(_("Co_lors")); - modeMultiScanColorRadioButton.set_group(modeGroup); - modeMultiScanColorRadioButton.set_use_underline(true); - modeMultiScanHBox2.pack_start(modeMultiScanColorRadioButton, false, false, MARGIN); - modeMultiScanColorRadioButton.set_tooltip_text(_("Trace the given number of reduced colors")); - modeMultiScanColorRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeMultiScanVBox.pack_start(modeMultiScanHBox2, false, false, MARGIN); - - modeMultiScanMonoRadioButton.set_label(_("_Grays")); - modeMultiScanMonoRadioButton.set_group(modeGroup); - modeMultiScanMonoRadioButton.set_use_underline(true); - modeMultiScanHBox3.pack_start(modeMultiScanMonoRadioButton, false, false, MARGIN); - modeMultiScanMonoRadioButton.set_tooltip_text(_("Same as Colors, but the result is converted to grayscale")); - modeMultiScanMonoRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeMultiScanVBox.pack_start(modeMultiScanHBox3, false, false, MARGIN); - - // TRANSLATORS: "Smooth" is a verb here - modeMultiScanSmoothButton.set_label(_("S_mooth")); - modeMultiScanSmoothButton.set_use_underline(true); - modeMultiScanSmoothButton.set_active(true); - modeMultiScanHBox4.pack_start(modeMultiScanSmoothButton, false, false, MARGIN); - modeMultiScanSmoothButton.set_tooltip_text(_("Apply Gaussian blur to the bitmap before tracing")); - modeMultiScanSmoothButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - // TRANSLATORS: "Stack" is a verb here - modeMultiScanStackButton.set_label(_("Stac_k scans")); - modeMultiScanStackButton.set_use_underline(true); - modeMultiScanStackButton.set_active(true); - modeMultiScanHBox4.pack_start(modeMultiScanStackButton, false, false, MARGIN); - modeMultiScanStackButton.set_tooltip_text(_("Stack scans on top of one another (no gaps) instead of tiling (usually with gaps)")); - modeMultiScanStackButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - - modeMultiScanBackgroundButton.set_label(_("Remo_ve background")); - modeMultiScanBackgroundButton.set_use_underline(true); - modeMultiScanBackgroundButton.set_active(false); - modeMultiScanHBox4.pack_start(modeMultiScanBackgroundButton, false, false, MARGIN); - // TRANSLATORS: "Layer" refers to one of the stacked paths in the multiscan - modeMultiScanBackgroundButton.set_tooltip_text(_("Remove bottom (background) layer when done")); - modeMultiScanBackgroundButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - - modeMultiScanVBox.pack_start(modeMultiScanHBox4, false, false, MARGIN); - - modeMultiScanFrame.set_label(_("Multiple scans: creates a group of paths")); - //modeQuantFrame.set_shadow_type(Gtk::SHADOW_NONE); - modeMultiScanFrame.add(modeMultiScanVBox); - modePageBox.pack_start(modeMultiScanFrame, false, false, 0); - modePageBox.set_border_width(MARGIN); - - //# end multiple scan - - //## end mode page - - notebook.append_page(modePageBox, _("_Mode"), true); - - //## begin option page - - //# potrace parameters - - optionsSpecklesButton.set_label(_("Suppress _speckles")); - optionsSpecklesButton.set_use_underline(true); - optionsSpecklesButton.set_tooltip_text(_("Ignore small spots (speckles) in the bitmap")); - optionsSpecklesButton.set_active(true); - optionsSpecklesButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - optionsSpecklesBox.pack_start(optionsSpecklesButton, false, false, MARGIN); - optionsSpecklesSizeSpinner.set_digits(0); - optionsSpecklesSizeSpinner.set_increments(1, 0); - optionsSpecklesSizeSpinner.set_range(0, 1000); - optionsSpecklesSizeSpinner.set_value(2); - optionsSpecklesSizeSpinner.set_tooltip_text(_("Speckles of up to this many pixels will be suppressed")); - optionsSpecklesSizeSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - optionsSpecklesBox.pack_end(optionsSpecklesSizeSpinner, false, false, MARGIN); - optionsSpecklesSizeLabel.set_label(_("S_ize:")); - optionsSpecklesSizeLabel.set_use_underline(true); - optionsSpecklesSizeLabel.set_mnemonic_widget(optionsSpecklesSizeSpinner); - optionsSpecklesBox.pack_end(optionsSpecklesSizeLabel, false, false, MARGIN); - - optionsCornersButton.set_label(_("Smooth _corners")); - optionsCornersButton.set_use_underline(true); - optionsCornersButton.set_tooltip_text(_("Smooth out sharp corners of the trace")); - optionsCornersButton.set_active(true); - optionsCornersButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - optionsCornersBox.pack_start(optionsCornersButton, false, false, MARGIN); - optionsCornersThresholdSpinner.set_digits(2); - optionsCornersThresholdSpinner.set_increments(0.01, 0); - optionsCornersThresholdSpinner.set_range(0.0, 1.34); - optionsCornersThresholdSpinner.set_value(1.0); - optionsCornersBox.pack_end(optionsCornersThresholdSpinner, false, false, MARGIN); - optionsCornersThresholdSpinner.set_tooltip_text(_("Increase this to smooth corners more")); - optionsCornersThresholdSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - optionsCornersThresholdLabel.set_label(_("_Threshold:")); - optionsCornersThresholdLabel.set_use_underline(true); - optionsCornersThresholdLabel.set_mnemonic_widget(optionsCornersThresholdSpinner); - optionsCornersBox.pack_end(optionsCornersThresholdLabel, false, false, MARGIN); - - optionsOptimButton.set_label(_("Optimize p_aths")); - optionsOptimButton.set_use_underline(true); - optionsOptimButton.set_active(true); - optionsOptimButton.set_tooltip_text(_("Try to optimize paths by joining adjacent Bezier curve segments")); - optionsOptimButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - optionsOptimBox.pack_start(optionsOptimButton, false, false, MARGIN); - optionsOptimToleranceSpinner.set_digits(2); - optionsOptimToleranceSpinner.set_increments(0.05, 0); - optionsOptimToleranceSpinner.set_range(0.0, 5.0); - optionsOptimToleranceSpinner.set_value(0.2); - optionsOptimBox.pack_end(optionsOptimToleranceSpinner, false, false, MARGIN); - optionsOptimToleranceSpinner.set_tooltip_text(_("Increase this to reduce the number of nodes in the trace by more aggressive optimization")); - optionsOptimToleranceSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) ); - optionsOptimToleranceLabel.set_label(_("To_lerance:")); - optionsOptimToleranceLabel.set_use_underline(true); - optionsOptimToleranceLabel.set_mnemonic_widget(optionsOptimToleranceSpinner); - optionsOptimBox.pack_end(optionsOptimToleranceLabel, false, false, MARGIN); - - optionsVBox.pack_start(optionsSpecklesBox, false, false, MARGIN); - optionsVBox.pack_start(optionsCornersBox, false, false, MARGIN); - optionsVBox.pack_start(optionsOptimBox, false, false, MARGIN); - optionsFrame.set_label(_("Options")); - optionsFrame.add(optionsVBox); - optionsPageBox.pack_start(optionsFrame, false, false, 0); - optionsPageBox.set_border_width(MARGIN); - - //## end option page - - notebook.append_page(optionsPageBox, _("O_ptions"), true); - - //### credits - - potraceCreditsLabel.set_text(_("Inkscape bitmap tracing is based on Potrace, created by Peter Selinger.\n\nhttp://potrace.sourceforge.net")); - potraceCreditsLabel.set_line_wrap(true); - potraceCreditsLabel.set_halign(Gtk::ALIGN_START); - potraceCreditsVBox.pack_start(potraceCreditsLabel, false, false, MARGIN); - - potraceCreditsVBox.set_border_width(MARGIN); - notebook.append_page(potraceCreditsVBox, _("Credits")); - - //### end notebook - - leftVBox.pack_start(notebook, true, true, MARGIN); - - //#### end left panel - - mainHBox.pack_start(leftVBox, false, false, 0); - - //#### begin right panel - - rightVBox.set_border_width(MARGIN); - - //## SIOX - - sioxButton.set_label(_("SIOX _foreground selection")); - sioxButton.set_use_underline(true); - sioxBox.pack_start(sioxButton, false, false); - sioxButton.set_tooltip_text(_("Cover the area you want to select as the foreground")); - rightVBox.pack_start(sioxBox, false, false); - - //## preview - Gtk::HBox *previewButtonHBox = Gtk::manage(new Gtk::HBox(false, MARGIN )); - previewLiveButton.set_label(_("Live Preview")); - previewLiveButton.set_use_underline(true); - previewLiveCallback(); - previewLiveButton.signal_clicked().connect( - sigc::mem_fun(*this, &TraceDialogImpl::previewLiveCallback) ); - - previewButton.set_label(_("_Update")); - previewButton.set_use_underline(true); - previewButton.signal_clicked().connect( - sigc::mem_fun(*this, &TraceDialogImpl::previewCallback) ); - previewButtonHBox->pack_start(previewLiveButton, false, false, 0); - previewButtonHBox->pack_end(previewButton, true, true, 0); - previewVBox.pack_end(*previewButtonHBox, false, false, 0); - // I guess it's correct to call the "intermediate bitmap" a preview of the trace - previewButton.set_tooltip_text(_("Preview the intermediate bitmap with the current settings, without actual tracing")); - previewImage.set_size_request(200,200); - //previewImage.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - previewVBox.pack_start(previewImage, true, true, 0); - previewFrame.set_label(_("Preview")); - //previewFrame.set_shadow_type(Gtk::SHADOW_NONE); - previewFrame.add(previewVBox); - - rightVBox.pack_start(previewFrame, true, true, MARGIN); - - //#### end right panel - - mainHBox.pack_start(rightVBox, true, true, 0); - - //#### Global stuff - - contents->pack_start(mainHBox); - mainResetButton = addResponseButton(_("Reset"), GTK_RESPONSE_HELP, true); - mainResetButton ->set_tooltip_text(_("Reset all settings to defaults")); - - //## The OK button - mainCancelButton = addResponseButton(_("_Stop"), GTK_RESPONSE_CANCEL); - if (mainCancelButton) { - mainCancelButton->set_tooltip_text(_("Abort a trace in progress")); - mainCancelButton->set_sensitive(false); + Glib::RefPtr<Glib::Object> test; + for (std::string w : req_widgets) { + test = builder->get_object(w); + if (!test) { + g_warning("Required widget %s does not exist", w.c_str()); + return; + } } - mainOkButton = addResponseButton(_("_OK"), GTK_RESPONSE_OK); - mainOkButton->set_tooltip_text(_("Execute the trace")); - - show_all_children(); - desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TraceDialogImpl::setTargetDesktop) ); +#define GET_O(name) \ + tmp = builder->get_object(#name); \ + name = Glib::RefPtr<Gtk::Adjustment>::cast_dynamic(tmp); + + Glib::RefPtr<Glib::Object> tmp; + +#define GET_W(name) builder->get_widget(#name, name); + GET_O(MS_scans) + GET_O(PA_curves) + GET_O(PA_islands) + GET_O(PA_sparse1) + GET_O(PA_sparse2) + GET_O(SS_AT_FI_T) + GET_O(SS_AT_ET_T) + GET_O(SS_BC_T) + GET_O(SS_CQ_T) + GET_O(SS_ED_T) + GET_O(optimize) + GET_O(smooth) + GET_O(speckles) + + GET_W(CB_invert) + GET_W(CB_MS_smooth) + GET_W(CB_MS_stack) + GET_W(CB_MS_rb) + GET_W(CB_speckles) + GET_W(CB_smooth) + GET_W(CB_optimize) + //GET_W(CB_live) + GET_W(CB_SIOX) + GET_W(RB_PA_voronoi) + GET_W(CBT_SS) + GET_W(CBT_MS) + GET_W(B_RESET) + GET_W(B_STOP) + GET_W(B_OK) + GET_W(B_Update) + GET_W(mainBox) + GET_W(choice_tab) + GET_W(choice_scan) + GET_W(previewImage) +#undef GET_W +#undef GET_O + _getContents()->add(*mainBox); + // show_all_children(); + desktopChangeConn = deskTrack.connectDesktopChanged(sigc::mem_fun(*this, &TraceDialogImpl2::setTargetDesktop)); deskTrack.connect(GTK_WIDGET(gobj())); - //## Connect the signal - signalResponse().connect( - sigc::mem_fun(*this, &TraceDialogImpl::responseCallback)); + B_Update->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::previewCallback)); + B_OK->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::traceCallback)); + B_STOP->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::abort)); + B_RESET->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::onSetDefaults)); } -/** - * Factory method. Use this to create a new TraceDialog - */ -TraceDialog &TraceDialog::getInstance() -{ - TraceDialog *dialog = new TraceDialogImpl(); - return *dialog; -} - -/** - * Constructor - */ -TraceDialogImpl::~TraceDialogImpl() +TraceDialogImpl2::~TraceDialogImpl2() { selectChangedConn.disconnect(); selectModifiedConn.disconnect(); desktopChangeConn.disconnect(); - } -} //namespace Dialog -} //namespace UI -} //namespace Inkscape -//######################################################################### -//## E N D O F F I L E -//######################################################################### +TraceDialog &TraceDialog::getInstance() +{ + TraceDialog *dialog = new TraceDialogImpl2(); + return *dialog; +} + -#endif +} // namespace Dialog +} // namespace UI +} // namespace Inkscape diff --git a/src/ui/dialog/tracedialog2.cpp b/src/ui/dialog/tracedialog2.cpp deleted file mode 100644 index be214e867..000000000 --- a/src/ui/dialog/tracedialog2.cpp +++ /dev/null @@ -1,357 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** - * @file - * Bitmap tracing settings dialog - second implementation. - */ -/* Authors: - * Marc Jeanmougin <marc.jeanmougin@telecom-paristech.fr> - * - * Copyright (C) 2019 Authors - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "tracedialog.h" - -#include <gtkmm.h> -#include <gtkmm/comboboxtext.h> -#include <gtkmm/notebook.h> -#include <gtkmm/radiobutton.h> -#include <gtkmm/spinbutton.h> -#include <gtkmm/stack.h> - - -#include <glibmm/i18n.h> - -#include "desktop-tracker.h" -#include "desktop.h" -#include "selection.h" - -#include "inkscape.h" -#include "io/resource.h" -#include "io/sys.h" -#include "trace/autotrace/inkscape-autotrace.h" -#include "trace/potrace/inkscape-potrace.h" -#include "trace/depixelize/inkscape-depixelize.h" - - - -namespace Inkscape { -namespace UI { -namespace Dialog { - -class TraceDialogImpl2 : public TraceDialog { - public: - TraceDialogImpl2(); - ~TraceDialogImpl2() override; - - private: - Inkscape::Trace::Tracer tracer; - void traceProcess(bool do_i_trace); - void abort(); - - void previewCallback(); - void traceCallback(); - void onSelectionModified(guint flags); - void onSetDefaults(); - - void setDesktop(SPDesktop *desktop) override; - void setTargetDesktop(SPDesktop *desktop); - - SPDesktop *desktop; - DesktopTracker deskTrack; - sigc::connection desktopChangeConn; - sigc::connection selectChangedConn; - sigc::connection selectModifiedConn; - - Glib::RefPtr<Gtk::Builder> builder; - - Glib::RefPtr<Gtk::Adjustment> MS_scans, PA_curves, PA_islands, PA_sparse1, PA_sparse2, SS_AT_ET_T, SS_AT_FI_T, SS_BC_T, SS_CQ_T, - SS_ED_T, optimize, smooth, speckles; - Gtk::ComboBoxText *CBT_SS, *CBT_MS; - Gtk::CheckButton *CB_invert, *CB_MS_smooth, *CB_MS_stack, *CB_MS_rb, *CB_speckles, *CB_smooth, *CB_optimize, - /* *CB_live,*/ *CB_SIOX; - Gtk::RadioButton *RB_PA_voronoi; - Gtk::Button *B_RESET, *B_STOP, *B_OK, *B_Update; - Gtk::Box *mainBox; - Gtk::Stack *choice_scan; - Gtk::Notebook *choice_tab; - Gtk::Image *previewImage; -}; - -void TraceDialogImpl2::setDesktop(SPDesktop *desktop) -{ - Panel::setDesktop(desktop); - deskTrack.setBase(desktop); -} - -void TraceDialogImpl2::setTargetDesktop(SPDesktop *desktop) -{ - if (this->desktop != desktop) { - if (this->desktop) { - selectChangedConn.disconnect(); - selectModifiedConn.disconnect(); - } - this->desktop = desktop; - if (desktop && desktop->selection) { - selectModifiedConn = desktop->selection->connectModified( - sigc::hide<0>(sigc::mem_fun(*this, &TraceDialogImpl2::onSelectionModified))); - } - } -} - -void TraceDialogImpl2::traceProcess(bool do_i_trace) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - desktop->setWaitingCursor(); - - if (CB_SIOX->get_active()) - tracer.enableSiox(true); - else - tracer.enableSiox(false); - - Glib::ustring type = - choice_scan->get_visible_child_name() == "SingleScan" ? CBT_SS->get_active_text() : CBT_MS->get_active_text(); - - Inkscape::Trace::Potrace::TraceType potraceType; - // Inkscape::Trace::Autotrace::TraceType autotraceType; - - bool use_autotrace = false; - Inkscape::Trace::Autotrace::AutotraceTracingEngine ate; // TODO - - if (type == _("Brightness cutoff")) - potraceType = Inkscape::Trace::Potrace::TRACE_BRIGHTNESS; - else if (type == _("Edge detection")) - potraceType = Inkscape::Trace::Potrace::TRACE_CANNY; - else if (type == _("Color quantization")) - potraceType = Inkscape::Trace::Potrace::TRACE_QUANT; - else if (type == _("Autotrace")) - { - // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE - use_autotrace = true; - ate.opts->color_count = 2; - } - else if (type == _("Centerline tracing (autotrace)")) - { - // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE - use_autotrace = true; - ate.opts->color_count = 2; - ate.opts->centerline = true; - ate.opts->preserve_width = true; - } - else if (type == _("Brightness steps")) - potraceType = Inkscape::Trace::Potrace::TRACE_BRIGHTNESS_MULTI; - else if (type == _("Colors")) - potraceType = Inkscape::Trace::Potrace::TRACE_QUANT_COLOR; - else if (type == _("Grays")) - potraceType = Inkscape::Trace::Potrace::TRACE_QUANT_MONO; - else if (type == _("Autotrace (slower)")) - { - // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE - use_autotrace = true; - ate.opts->color_count = (int)MS_scans->get_value() + 1; - } - else - { - g_warning("Should not happen!"); - } - ate.opts->filter_iterations = (int) SS_AT_FI_T->get_value(); - ate.opts->error_threshold = SS_AT_ET_T->get_value(); - - Inkscape::Trace::Potrace::PotraceTracingEngine pte( - potraceType, CB_invert->get_active(), (int)SS_CQ_T->get_value(), SS_BC_T->get_value(), - 0., // Brightness floor - SS_ED_T->get_value(), (int)MS_scans->get_value(), CB_MS_stack->get_active(), CB_MS_smooth->get_active(), - CB_MS_rb->get_active()); - pte.potraceParams->opticurve = CB_optimize->get_active(); - pte.potraceParams->opttolerance = optimize->get_value(); - pte.potraceParams->alphamax = CB_smooth->get_active() ? smooth->get_value() : 0; - pte.potraceParams->turdsize = CB_speckles->get_active() ? (int)speckles->get_value() : 0; - - - - //Inkscape::Trace::Autotrace::AutotraceTracingEngine ate; // TODO - Inkscape::Trace::Depixelize::DepixelizeTracingEngine dte(RB_PA_voronoi->get_active() ? Inkscape::Trace::Depixelize::TraceType::TRACE_VORONOI : Inkscape::Trace::Depixelize::TraceType::TRACE_BSPLINES, PA_curves->get_value(), (int) PA_islands->get_value(), (int) PA_sparse1->get_value(), PA_sparse2->get_value() ); - - - Glib::RefPtr<Gdk::Pixbuf> pixbuf = tracer.getSelectedImage(); - if (pixbuf) { - Glib::RefPtr<Gdk::Pixbuf> preview = use_autotrace ? ate.preview(pixbuf) : pte.preview(pixbuf); - if (preview) { - int width = preview->get_width(); - int height = preview->get_height(); - const Gtk::Allocation &vboxAlloc = previewImage->get_allocation(); - double scaleFX = vboxAlloc.get_width() / (double)width; - double scaleFY = vboxAlloc.get_height() / (double)height; - double scaleFactor = scaleFX > scaleFY ? scaleFY : scaleFX; - int newWidth = (int)(((double)width) * scaleFactor); - int newHeight = (int)(((double)height) * scaleFactor); - Glib::RefPtr<Gdk::Pixbuf> scaledPreview = preview->scale_simple(newWidth, newHeight, Gdk::INTERP_NEAREST); - // g_object_unref(preview); - previewImage->set(scaledPreview); - } - } - if (do_i_trace){ - if (use_autotrace){ - tracer.trace(&ate); - printf("at\n"); - } else if (choice_tab->get_current_page() == 0){ - tracer.trace(&pte); - printf("pt\n"); - } else if (choice_tab->get_current_page() == 1){ - tracer.trace(&dte); - printf("dt\n"); - } - } - - if (desktop) - desktop->clearWaitingCursor(); -} - -void TraceDialogImpl2::abort() -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - desktop->clearWaitingCursor(); - tracer.abort(); -} - -void TraceDialogImpl2::onSelectionModified(guint flags) -{ - if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) { - previewCallback(); - } -} - -void TraceDialogImpl2::onSetDefaults() -{ - MS_scans->set_value(8); - PA_curves->set_value(1); - PA_islands->set_value(5); - PA_sparse1->set_value(4); - PA_sparse2->set_value(1); - SS_AT_FI_T->set_value(4); - SS_AT_ET_T->set_value(2); - SS_BC_T->set_value(0.45); - SS_CQ_T->set_value(64); - SS_ED_T->set_value(.65); - optimize->set_value(0.2); - smooth->set_value(1); - speckles->set_value(2); - CB_invert->set_active(false); - CB_MS_smooth->set_active(true); - CB_MS_stack->set_active(true); - CB_MS_rb->set_active(false); - CB_speckles->set_active(true); - CB_smooth->set_active(true); - CB_optimize->set_active(true); - //CB_live->set_active(false); - CB_SIOX->set_active(false); -} - -void TraceDialogImpl2::previewCallback() { traceProcess(false); } -void TraceDialogImpl2::traceCallback() { traceProcess(true); } - - -TraceDialogImpl2::TraceDialogImpl2() - : TraceDialog() -{ - const std::string req_widgets[] = { "MS_scans", "PA_curves", "PA_islands", "PA_sparse1", "PA_sparse2", - "SS_AT_FI_T", "SS_AT_ET_T", "SS_BC_T", "SS_CQ_T", "SS_ED_T", - "optimize", "smooth", "speckles", "CB_invert", "CB_MS_smooth", - "CB_MS_stack", "CB_MS_rb", "CB_speckles", "CB_smooth", "CB_optimize", - /*"CB_live",*/ "CB_SIOX", "CBT_SS", "CBT_MS", "B_RESET", - "B_STOP", "B_OK", "mainBox", "choice_tab", "choice_scan", - "previewImage" }; - Glib::ustring gladefile = get_filename(Inkscape::IO::Resource::UIS, "dialog-trace.glade"); - try { - builder = Gtk::Builder::create_from_file(gladefile); - } catch (const Glib::Error &ex) { - g_warning("Glade file loading failed for filter effect dialog"); - return; - } - Glib::RefPtr<Glib::Object> test; - for (std::string w : req_widgets) { - test = builder->get_object(w); - if (!test) { - g_warning("Required widget %s does not exist", w.c_str()); - return; - } - } - -#define GET_O(name) \ - tmp = builder->get_object(#name); \ - name = Glib::RefPtr<Gtk::Adjustment>::cast_dynamic(tmp); - - Glib::RefPtr<Glib::Object> tmp; - -#define GET_W(name) builder->get_widget(#name, name); - GET_O(MS_scans) - GET_O(PA_curves) - GET_O(PA_islands) - GET_O(PA_sparse1) - GET_O(PA_sparse2) - GET_O(SS_AT_FI_T) - GET_O(SS_AT_ET_T) - GET_O(SS_BC_T) - GET_O(SS_CQ_T) - GET_O(SS_ED_T) - GET_O(optimize) - GET_O(smooth) - GET_O(speckles) - - GET_W(CB_invert) - GET_W(CB_MS_smooth) - GET_W(CB_MS_stack) - GET_W(CB_MS_rb) - GET_W(CB_speckles) - GET_W(CB_smooth) - GET_W(CB_optimize) - //GET_W(CB_live) - GET_W(CB_SIOX) - GET_W(RB_PA_voronoi) - GET_W(CBT_SS) - GET_W(CBT_MS) - GET_W(B_RESET) - GET_W(B_STOP) - GET_W(B_OK) - GET_W(B_Update) - GET_W(mainBox) - GET_W(choice_tab) - GET_W(choice_scan) - GET_W(previewImage) -#undef GET_W -#undef GET_O - _getContents()->add(*mainBox); - // show_all_children(); - desktopChangeConn = deskTrack.connectDesktopChanged(sigc::mem_fun(*this, &TraceDialogImpl2::setTargetDesktop)); - deskTrack.connect(GTK_WIDGET(gobj())); - - B_Update->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::previewCallback)); - B_OK->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::traceCallback)); - B_STOP->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::abort)); - B_RESET->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::onSetDefaults)); -} - - -TraceDialogImpl2::~TraceDialogImpl2() -{ - selectChangedConn.disconnect(); - selectModifiedConn.disconnect(); - desktopChangeConn.disconnect(); -} - - - -TraceDialog &TraceDialog::getInstance() -{ - TraceDialog *dialog = new TraceDialogImpl2(); - return *dialog; -} - - - -} // namespace Dialog -} // namespace UI -} // namespace Inkscape |
