transformation.cpp revision 2819552fc4546cfb98a51e57d66858a9943c77d6
/**
* \brief Object Transformation dialog
*
* Authors:
* Bryce W. Harrington <bryce@bryceharrington.org>
* buliabyak@gmail.com
*
* Copyright (C) 2004, 2005 Authors
*
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "document.h"
#include "desktop-handles.h"
#include "transformation.h"
#include "align-and-distribute.h"
#include "libnr/nr-matrix-ops.h"
#include "inkscape.h"
#include "selection.h"
#include "selection-chemistry.h"
#include "verbs.h"
#include "prefs-utils.h"
#include "sp-item-transform.h"
#include "macros.h"
#include "sp-item.h"
#include "util/glib-list-iterators.h"
namespace Inkscape {
namespace UI {
namespace Dialog {
void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad)
{
}
guint /*flags*/,
{
}
/*########################################################################
# C O N S T R U C T O R
########################################################################*/
/**
* Constructor for Transformation. This does the initialization
* and layout of the dialog used for transforming SVG objects. It
* consists of 5 pages for the 5 operations it handles:
* 'Move' allows x,y translation of SVG objects
* 'Scale' allows linear resizing of SVG objects
* 'Rotate' allows rotating SVG objects by a degree
* 'Skew' allows skewing SVG objects
* 'Matrix' allows applying a generic affine transform on SVG objects,
* with the user specifying the 6 degrees of freedom manually.
*
* The dialog is implemented as a Gtk::Notebook with five pages.
* The pages are implemented using Inkscape's NotebookPage which
* is used to help make sure all of Inkscape's notebooks follow
* the same style. We then populate the pages with our widgets,
* we use the ScalarUnit class for this.
*
*/
_scalar_move_horizontal (_("_Horizontal"), _("Horizontal displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR,
_scalar_move_vertical (_("_Vertical"), _("Vertical displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR,
_scalar_scale_horizontal(_("_Width"), _("Horizontal size (absolute or percentage of current)"), UNIT_TYPE_DIMENSIONLESS,
_scalar_scale_vertical (_("_Height"), _("Vertical size (absolute or percentage of current)"), UNIT_TYPE_DIMENSIONLESS,
_scalar_skew_horizontal (_("_Horizontal"), _("Horizontal skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"), UNIT_TYPE_LINEAR,
_scalar_skew_vertical (_("_Vertical"), _("Vertical skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"), UNIT_TYPE_LINEAR,
_check_move_relative (_("Rela_tive move"), _("Add the specified relative displacement to the current position; otherwise, edit the current absolute position directly")),
_check_scale_proportional (_("Scale proportionally"), _("Preserve the width/height ratio of the scaled objects")),
_check_apply_separately (_("Apply to each _object separately"), _("Apply the scale/rotate/skew to each selected object separately; otherwise, transform the selection as a whole")),
_check_replace_matrix (_("Edit c_urrent matrix"), _("Edit the current transform= matrix; otherwise, post-multiply transform= by this matrix"))
{
contents->set_spacing(0);
// Notebook for individual transformations
// Apply separately
_check_apply_separately.set_active(prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1));
_check_apply_separately.signal_toggled().connect(sigc::mem_fun(*this, &Transformation::onApplySeparatelyToggled));
// make sure all spinbuttons activate Apply on pressing Enter
if (resetButton) {
resetButton->set_sensitive(true);
}
if (applyButton) {
applyButton->set_sensitive(false);
}
// Connect to the global selection changed & modified signals
g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this);
g_signal_connect (G_OBJECT (INKSCAPE), "modify_selection", G_CALLBACK (on_selection_modified), this);
}
{
}
/*########################################################################
# U T I L I T Y
########################################################################*/
void
{
show();
present();
}
/*########################################################################
# S E T U P L A Y O U T
########################################################################*/
void
{
//_scalar_move_vertical.set_label_image( INKSCAPE_STOCK_ARROWS_HOR );
//_scalar_move_vertical.set_label_image( INKSCAPE_STOCK_ARROWS_VER );
// Relative moves
_check_move_relative.set_active(true);
}
void
{
_check_scale_proportional.set_active(false);
//TODO: add a widget for selecting the fixed point in scaling, or honour rotation center?
}
void
{
//TODO: honour rotation center?
}
void
{
//TODO: honour rotation center?
}
void
{
// Edit existing matrix
_check_replace_matrix.set_active(false);
}
/*########################################################################
# U P D A T E
########################################################################*/
void
{
return;
switch (page) {
case PAGE_MOVE: {
break;
}
case PAGE_SCALE: {
break;
}
case PAGE_ROTATE: {
break;
}
case PAGE_SKEW: {
break;
}
case PAGE_TRANSFORM: {
break;
}
case PAGE_QTY: {
break;
}
}
}
void
{
}
void
{
if (!_check_move_relative.get_active()) {
if (bbox) {
}
} else {
// do nothing, so you can apply the same relative move to many objects in turn
}
_page_move.set_sensitive(true);
} else {
_page_move.set_sensitive(false);
}
}
void
{
if (bbox) {
onScaleXValueChanged(); // to update x/y proportionality if switch is on
_page_scale.set_sensitive(true);
} else {
_page_scale.set_sensitive(false);
}
} else {
_page_scale.set_sensitive(false);
}
}
void
{
_page_rotate.set_sensitive(true);
} else {
_page_rotate.set_sensitive(false);
}
}
void
{
if (bbox) {
_page_skew.set_sensitive(true);
} else {
_page_skew.set_sensitive(false);
}
} else {
_page_skew.set_sensitive(false);
}
}
void
{
if (_check_replace_matrix.get_active()) {
NR::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection
} else {
// do nothing, so you can apply the same matrix to many objects in turn
}
_page_transform.set_sensitive(true);
} else {
_page_transform.set_sensitive(false);
}
}
/*########################################################################
# A P P L Y
########################################################################*/
void
{
return;
switch (page) {
case PAGE_MOVE: {
break;
}
case PAGE_ROTATE: {
break;
}
case PAGE_SCALE: {
break;
}
case PAGE_SKEW: {
break;
}
case PAGE_TRANSFORM: {
break;
}
}
//Let's play with never turning this off
//setResponseSensitive(Gtk::RESPONSE_APPLY, false);
}
void
{
// move selection as a whole
if (_check_move_relative.get_active()) {
sp_selection_move_relative(selection, x, y);
} else {
if (bbox) {
}
}
} else {
if (_check_move_relative.get_active()) {
// shift each object relatively to the previous one
if (fabs(x) > 1e-6) {
++it)
{
if (bbox) {
}
}
//sort bbox by anchors
double move = x;
it ++ )
{
// move each next object by x relative to previous
move += x;
}
}
if (fabs(y) > 1e-6) {
++it)
{
if (bbox) {
}
}
//sort bbox by anchors
double move = y;
it ++ )
{
// move each next object by x relative to previous
move += y;
}
}
} else {
if (bbox) {
}
}
}
_("Move"));
}
void
{
// the values are increments!
if (_units_scale.isAbsolute()) {
if (bbox) {
if (fabs(new_width) < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object
double new_height = scaleY;
}
} else {
double new_height = scaleY;
}
}
} else {
if (bbox) {
// the values are increments!
if (_units_scale.isAbsolute()) {
double new_height = scaleY;
} else {
double new_height = scaleY;
}
}
}
_("Scale"));
}
void
{
}
} else {
if (center) {
}
}
_("Rotate"));
}
void
{
} else { // absolute displacement
if (bbox) {
}
}
}
} else { // transform whole selection
} else { // absolute displacement
}
}
}
_("Skew"));
}
void
{
double a = _scalar_transform_a.getValue();
double b = _scalar_transform_b.getValue();
double c = _scalar_transform_c.getValue();
double d = _scalar_transform_d.getValue();
double e = _scalar_transform_e.getValue();
double f = _scalar_transform_f.getValue();
if (_check_replace_matrix.get_active()) {
}
} else {
}
_("Edit transformation matrix"));
}
/*########################################################################
# V A L U E - C H A N G E D C A L L B A C K S
########################################################################*/
void
{
}
void
{
return;
//g_message("onMoveRelativeToggled: %f, %f px\n", x, y);
if (bbox) {
if (_check_move_relative.get_active()) {
// From absolute to relative
} else {
// From relative to absolute
}
}
}
void
{
return;
}
if (_check_scale_proportional.get_active()) {
} else {
}
}
}
void
{
return;
}
if (_check_scale_proportional.get_active()) {
} else {
}
}
}
void
{
}
void
{
}
void
{
/*
double a = _scalar_transform_a.getValue();
double b = _scalar_transform_b.getValue();
double c = _scalar_transform_c.getValue();
double d = _scalar_transform_d.getValue();
double e = _scalar_transform_e.getValue();
double f = _scalar_transform_f.getValue();
//g_message("onTransformValueChanged: (%f, %f, %f, %f, %f, %f)\n",
// a, b, c, d, e ,f);
*/
}
void
{
return;
double a = _scalar_transform_a.getValue();
double b = _scalar_transform_b.getValue();
double c = _scalar_transform_c.getValue();
double d = _scalar_transform_d.getValue();
double e = _scalar_transform_e.getValue();
double f = _scalar_transform_f.getValue();
NR::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection
if (_check_replace_matrix.get_active()) {
} else {
}
}
void
{
}
void
{
switch (page) {
case PAGE_MOVE: {
} else {
if (bbox) {
}
}
break;
}
case PAGE_ROTATE: {
break;
}
case PAGE_SCALE: {
break;
}
case PAGE_SKEW: {
break;
}
case PAGE_TRANSFORM: {
break;
}
}
}
void
{
prefs_set_int_attribute ("dialogs.transformation", "applyseparately", _check_apply_separately.get_active()? 1 : 0);
}
} // namespace Dialog
} // namespace UI
} // namespace Inkscape
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :