/**
* @file
* Bitmap tracing settings dialog - implementation.
*/
/* Authors:
* Bob Jamison <rjamison@titan.com>
* Stéphane Gimenez <dev@gim.name>
* Other dudes from The Inkscape Organization
*
* Copyright (C) 2004-2006 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "tracedialog.h"
#include <gtkmm/notebook.h>
#include "ui/widget/spinbutton.h"
#include <gtkmm/radiobutton.h>
#include "desktop.h"
#include "desktop-tracker.h"
#include "selection.h"
#include "trace/potrace/inkscape-potrace.h"
#include "inkscape.h"
namespace Inkscape {
namespace UI {
namespace Dialog {
//#########################################################################
//## I M P L E M E N T A T I O N
//#########################################################################
/**
* A dialog for adjusting bitmap->vector tracing parameters
*/
{
public:
/**
* Constructor
*/
/**
* Destructor
*/
~TraceDialogImpl();
/**
* Callback from OK or Cancel
*/
void responseCallback(int response_id);
private:
/**
* This is the big almighty McGuffin
*/
/**
* This does potrace processing
* Only preview if do_i_trace is false
*/
void potraceProcess(bool do_i_trace);
/**
* Abort processing
*/
void abort();
void previewCallback();
void previewLiveCallback();
void onSettingsChange();
void onSetDefaults();
//############ General items
//######## Left pannel
//#### Notebook
//## Modes
//# Single scan mode
//brightness
//edge detection
//Gtk::HSeparator modeCannySeparator;
//Gtk::Label modeCannyLoSpinnerLabel;
//Inkscape::UI::Widget::SpinButton modeCannyLoSpinner;
//quantization
//params
//# Multiple path scanning mode
//brightness
//colors
//grays
//params
//## Options
// potrace parameters
//#### Credits
//######## Right pannel
//#### SIOX selection
//#### Preview
};
{
}
{
if (this->desktop) {
}
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)));
}
}
}
//#########################################################################
//## E V E N T S
//#########################################################################
/**
* This does potrace processing
* Only preview if do_i_trace is false
*/
{
if (desktop)
//##### Get the tracer and engine
/* inversion */
//##### Get the preprocessor settings
/* siox -- performed by Tracer, and before any of the others */
if (sioxButton.get_active())
tracer.enableSiox(true);
else
tracer.enableSiox(false);
/* one of the following */
else if (modeMultiScanBrightnessRadioButton.get_active())
else if (modeCannyRadioButton.get_active())
else if (modeQuantRadioButton.get_active())
else if (modeMultiScanColorRadioButton.get_active())
{
}
else if (modeMultiScanMonoRadioButton.get_active())
{
}
/* params */
int paramsSpecklesSize =
0;
double paramsCornersThreshold =
0.;
//##### Get the single-scan settings
/* brightness */
/* canny */
/* quantization */
//##### Get multiple-scan settings
//##### Get intermediate bitmap image
if (pixbuf)
{
if (preview)
{
//g_object_unref(preview);
}
}
//##### Convert
if (do_i_trace)
{
if (mainCancelButton)
mainCancelButton->set_sensitive(true);
if (mainOkButton)
mainOkButton->set_sensitive(false);
if (mainCancelButton)
mainCancelButton->set_sensitive(false);
if (mainOkButton)
mainOkButton->set_sensitive(true);
}
if (desktop)
}
/**
* Abort processing
*/
{
if (desktop)
if (mainCancelButton)
mainCancelButton->set_sensitive(false);
if (mainOkButton)
mainOkButton->set_sensitive(true);
//### Make the abort() call to the tracer
}
//#########################################################################
//## E V E N T S
//#########################################################################
/**
* Callback for when any setting changes
*/
{
if (previewLive) {
}
}
{
if (flags & ( SP_OBJECT_MODIFIED_FLAG |
}
}
/**
* Callback for when users resets defaults
*/
{
// temporarily disable live update
previewLive = false;
modeInvertButton.set_active(false);
optionsSpecklesButton.set_active(true);
optionsCornersButton.set_active(true);
optionsOptimButton.set_active(true);
sioxButton.set_active(false);
}
/**
* Callback from the Preview button. Can be called from elsewhere.
*/
{
potraceProcess(false);
}
/**
* Callback from the Preview Live button.
*/
{
}
/**
* Default response from the dialog. Let's intercept it
*/
{
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) {
} else {
hide();
return;
}
}
//#########################################################################
//## C O N S T R U C T O R / D E S T R U C T O R
//#########################################################################
/**
* Constructor
*/
{
//#### begin left panel
//### begin notebook
//## begin mode page
//# begin single scan
// brightness
modeBrightnessSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
// canny edge detection
// TRANSLATORS: "Canny" is the name of the inventor of this edge detection method
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_tooltip_text(_("Brightness cutoff for adjacent pixels (determines edge thickness)"));
modeCannyHiSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
// 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.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeQuantNrColorSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
// swap black and white
modeInvertButton.set_active(false);
modeInvertButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
//# end single scan
//# begin multiple scan
modeMultiScanBrightnessRadioButton.set_tooltip_text(_("Trace the given number of brightness levels"));
modeMultiScanBrightnessRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanNrColorSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanColorRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanMonoRadioButton.set_tooltip_text(_("Same as Colors, but the result is converted to grayscale"));
modeMultiScanMonoRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
// TRANSLATORS: "Smooth" is a verb here
modeMultiScanSmoothButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
// TRANSLATORS: "Stack" is a verb here
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) );
// TRANSLATORS: "Layer" refers to one of the stacked paths in the multiscan
modeMultiScanBackgroundButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
//modeQuantFrame.set_shadow_type(Gtk::SHADOW_NONE);
//# end multiple scan
//## end mode page
//## begin option page
//# potrace parameters
optionsSpecklesButton.set_active(true);
optionsSpecklesButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
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) );
optionsCornersButton.set_active(true);
optionsCornersButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
optionsCornersThresholdSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
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) );
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) );
//## end option page
//### credits
potraceCreditsLabel.set_text(_("Inkscape bitmap tracing\nis based on Potrace,\ncreated by Peter Selinger\n\nhttp://potrace.sourceforge.net"));
//### end notebook
//#### end left panel
//#### begin right panel
//## SIOX
sioxButton.set_use_underline(true);
//## preview
previewButton.set_use_underline(true);
// 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_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
//previewFrame.set_shadow_type(Gtk::SHADOW_NONE);
//#### end right panel
//#### Global stuff
//## The OK button
if (mainCancelButton) {
mainCancelButton->set_sensitive(false);
}
desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TraceDialogImpl::setTargetDesktop) );
//## Connect the signal
}
/**
* Factory method. Use this to create a new TraceDialog
*/
{
return *dialog;
}
/**
* Constructor
*/
{
}
} //namespace Dialog
} //namespace UI
} //namespace Inkscape
//#########################################################################
//## E N D O F F I L E
//#########################################################################