From 8b78a8791bc539bcffe7159f9d9714d577cb3d7d Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sun, 23 May 2021 20:48:35 +0900 Subject: Renaming of files in preparation for code style tools. Signed-off-by: Michele Calgaro --- chalk/plugins/tools/defaulttools/Makefile.am | 26 +- chalk/plugins/tools/defaulttools/default_tools.cc | 88 -- chalk/plugins/tools/defaulttools/default_tools.cpp | 88 ++ chalk/plugins/tools/defaulttools/kis_tool_brush.cc | 167 ---- .../plugins/tools/defaulttools/kis_tool_brush.cpp | 167 ++++ .../tools/defaulttools/kis_tool_colorpicker.cc | 298 ------- .../tools/defaulttools/kis_tool_colorpicker.cpp | 298 +++++++ .../tools/defaulttools/kis_tool_duplicate.cc | 255 ------ .../tools/defaulttools/kis_tool_duplicate.cpp | 255 ++++++ .../plugins/tools/defaulttools/kis_tool_ellipse.cc | 186 ----- .../tools/defaulttools/kis_tool_ellipse.cpp | 186 +++++ chalk/plugins/tools/defaulttools/kis_tool_fill.cc | 233 ------ chalk/plugins/tools/defaulttools/kis_tool_fill.cpp | 233 ++++++ .../tools/defaulttools/kis_tool_gradient.cc | 309 ------- .../tools/defaulttools/kis_tool_gradient.cpp | 309 +++++++ chalk/plugins/tools/defaulttools/kis_tool_line.cc | 254 ------ chalk/plugins/tools/defaulttools/kis_tool_line.cpp | 254 ++++++ chalk/plugins/tools/defaulttools/kis_tool_move.cc | 181 ---- chalk/plugins/tools/defaulttools/kis_tool_move.cpp | 181 ++++ chalk/plugins/tools/defaulttools/kis_tool_pan.cc | 96 --- chalk/plugins/tools/defaulttools/kis_tool_pan.cpp | 96 +++ .../tools/defaulttools/kis_tool_rectangle.cc | 187 ----- .../tools/defaulttools/kis_tool_rectangle.cpp | 187 +++++ chalk/plugins/tools/defaulttools/kis_tool_text.cc | 198 ----- chalk/plugins/tools/defaulttools/kis_tool_text.cpp | 198 +++++ chalk/plugins/tools/defaulttools/kis_tool_zoom.cc | 191 ----- chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp | 191 +++++ chalk/plugins/tools/selectiontools/Makefile.am | 8 +- .../selectiontools/kis_tool_move_selection.cc | 223 ----- .../selectiontools/kis_tool_move_selection.cpp | 223 +++++ .../tools/selectiontools/kis_tool_select_brush.cc | 168 ---- .../tools/selectiontools/kis_tool_select_brush.cpp | 168 ++++ .../selectiontools/kis_tool_select_contiguous.cc | 234 ------ .../selectiontools/kis_tool_select_contiguous.cpp | 234 ++++++ .../selectiontools/kis_tool_select_elliptical.cc | 321 ------- .../selectiontools/kis_tool_select_elliptical.cpp | 321 +++++++ .../tools/selectiontools/kis_tool_select_eraser.cc | 156 ---- .../selectiontools/kis_tool_select_eraser.cpp | 156 ++++ .../selectiontools/kis_tool_select_outline.cc | 295 ------- .../selectiontools/kis_tool_select_outline.cpp | 295 +++++++ .../selectiontools/kis_tool_select_polygonal.cc | 315 ------- .../selectiontools/kis_tool_select_polygonal.cpp | 315 +++++++ .../selectiontools/kis_tool_select_rectangular.cc | 323 ------- .../selectiontools/kis_tool_select_rectangular.cpp | 323 +++++++ .../tools/selectiontools/selection_tools.cc | 77 -- .../tools/selectiontools/selection_tools.cpp | 77 ++ chalk/plugins/tools/tool_crop/Makefile.am | 4 +- chalk/plugins/tools/tool_crop/kis_tool_crop.cc | 925 --------------------- chalk/plugins/tools/tool_crop/kis_tool_crop.cpp | 925 +++++++++++++++++++++ chalk/plugins/tools/tool_crop/tool_crop.cc | 62 -- chalk/plugins/tools/tool_crop/tool_crop.cpp | 62 ++ chalk/plugins/tools/tool_curves/Makefile.am | 16 +- .../tools/tool_curves/kis_curve_framework.cc | 260 ------ .../tools/tool_curves/kis_curve_framework.cpp | 260 ++++++ chalk/plugins/tools/tool_curves/kis_tool_bezier.cc | 366 -------- .../plugins/tools/tool_curves/kis_tool_bezier.cpp | 366 ++++++++ .../tools/tool_curves/kis_tool_bezier_paint.cc | 115 --- .../tools/tool_curves/kis_tool_bezier_paint.cpp | 115 +++ .../tools/tool_curves/kis_tool_bezier_select.cc | 104 --- .../tools/tool_curves/kis_tool_bezier_select.cpp | 104 +++ chalk/plugins/tools/tool_curves/kis_tool_curve.cc | 593 ------------- chalk/plugins/tools/tool_curves/kis_tool_curve.cpp | 593 +++++++++++++ .../plugins/tools/tool_curves/kis_tool_example.cc | 108 --- .../plugins/tools/tool_curves/kis_tool_example.cpp | 108 +++ .../plugins/tools/tool_curves/kis_tool_moutline.cc | 809 ------------------ .../tools/tool_curves/kis_tool_moutline.cpp | 809 ++++++++++++++++++ chalk/plugins/tools/tool_curves/tool_curves.cc | 67 -- chalk/plugins/tools/tool_curves/tool_curves.cpp | 67 ++ chalk/plugins/tools/tool_filter/Makefile.am | 6 +- chalk/plugins/tools/tool_filter/kis_filterop.cc | 154 ---- chalk/plugins/tools/tool_filter/kis_filterop.cpp | 154 ++++ chalk/plugins/tools/tool_filter/kis_tool_filter.cc | 154 ---- .../plugins/tools/tool_filter/kis_tool_filter.cpp | 154 ++++ chalk/plugins/tools/tool_filter/tool_filter.cc | 68 -- chalk/plugins/tools/tool_filter/tool_filter.cpp | 68 ++ .../plugins/tools/tool_perspectivegrid/Makefile.am | 4 +- .../kis_tool_perspectivegrid.cc | 499 ----------- .../kis_tool_perspectivegrid.cpp | 499 +++++++++++ .../tool_perspectivegrid/tool_perspectivegrid.cc | 62 -- .../tool_perspectivegrid/tool_perspectivegrid.cpp | 62 ++ .../tools/tool_perspectivetransform/Makefile.am | 4 +- .../kis_tool_perspectivetransform.cc | 742 ----------------- .../kis_tool_perspectivetransform.cpp | 742 +++++++++++++++++ .../tool_perspectivetransform.cc | 63 -- .../tool_perspectivetransform.cpp | 63 ++ chalk/plugins/tools/tool_polygon/Makefile.am | 4 +- .../plugins/tools/tool_polygon/kis_tool_polygon.cc | 252 ------ .../tools/tool_polygon/kis_tool_polygon.cpp | 252 ++++++ chalk/plugins/tools/tool_polygon/tool_polygon.cc | 62 -- chalk/plugins/tools/tool_polygon/tool_polygon.cpp | 62 ++ chalk/plugins/tools/tool_polyline/Makefile.am | 4 +- .../tools/tool_polyline/kis_tool_polyline.cc | 271 ------ .../tools/tool_polyline/kis_tool_polyline.cpp | 271 ++++++ chalk/plugins/tools/tool_polyline/tool_polyline.cc | 64 -- .../plugins/tools/tool_polyline/tool_polyline.cpp | 64 ++ chalk/plugins/tools/tool_selectsimilar/Makefile.am | 2 +- .../tool_selectsimilar/kis_tool_selectsimilar.cc | 271 ------ .../tool_selectsimilar/kis_tool_selectsimilar.cpp | 271 ++++++ .../tools/tool_selectsimilar/selectsimilar.cc | 61 -- .../tools/tool_selectsimilar/selectsimilar.cpp | 61 ++ chalk/plugins/tools/tool_star/Makefile.am | 4 +- chalk/plugins/tools/tool_star/kis_tool_star.cc | 245 ------ chalk/plugins/tools/tool_star/kis_tool_star.cpp | 245 ++++++ chalk/plugins/tools/tool_star/tool_star.cc | 62 -- chalk/plugins/tools/tool_star/tool_star.cpp | 62 ++ chalk/plugins/tools/tool_transform/Makefile.am | 4 +- .../tools/tool_transform/kis_tool_transform.cc | 916 -------------------- .../tools/tool_transform/kis_tool_transform.cpp | 916 ++++++++++++++++++++ .../plugins/tools/tool_transform/tool_transform.cc | 64 -- .../tools/tool_transform/tool_transform.cpp | 64 ++ 110 files changed, 12217 insertions(+), 12217 deletions(-) delete mode 100644 chalk/plugins/tools/defaulttools/default_tools.cc create mode 100644 chalk/plugins/tools/defaulttools/default_tools.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_brush.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_brush.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_fill.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_fill.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_gradient.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_line.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_line.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_move.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_move.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_pan.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_pan.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_text.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_text.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_zoom.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp delete mode 100644 chalk/plugins/tools/selectiontools/selection_tools.cc create mode 100644 chalk/plugins/tools/selectiontools/selection_tools.cpp delete mode 100644 chalk/plugins/tools/tool_crop/kis_tool_crop.cc create mode 100644 chalk/plugins/tools/tool_crop/kis_tool_crop.cpp delete mode 100644 chalk/plugins/tools/tool_crop/tool_crop.cc create mode 100644 chalk/plugins/tools/tool_crop/tool_crop.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_curve_framework.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_curve_framework.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_curve.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_curve.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_example.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_example.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_moutline.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp delete mode 100644 chalk/plugins/tools/tool_curves/tool_curves.cc create mode 100644 chalk/plugins/tools/tool_curves/tool_curves.cpp delete mode 100644 chalk/plugins/tools/tool_filter/kis_filterop.cc create mode 100644 chalk/plugins/tools/tool_filter/kis_filterop.cpp delete mode 100644 chalk/plugins/tools/tool_filter/kis_tool_filter.cc create mode 100644 chalk/plugins/tools/tool_filter/kis_tool_filter.cpp delete mode 100644 chalk/plugins/tools/tool_filter/tool_filter.cc create mode 100644 chalk/plugins/tools/tool_filter/tool_filter.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc create mode 100644 chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc create mode 100644 chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc create mode 100644 chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc create mode 100644 chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp delete mode 100644 chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc create mode 100644 chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp delete mode 100644 chalk/plugins/tools/tool_polygon/tool_polygon.cc create mode 100644 chalk/plugins/tools/tool_polygon/tool_polygon.cpp delete mode 100644 chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc create mode 100644 chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp delete mode 100644 chalk/plugins/tools/tool_polyline/tool_polyline.cc create mode 100644 chalk/plugins/tools/tool_polyline/tool_polyline.cpp delete mode 100644 chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc create mode 100644 chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp delete mode 100644 chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc create mode 100644 chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp delete mode 100644 chalk/plugins/tools/tool_star/kis_tool_star.cc create mode 100644 chalk/plugins/tools/tool_star/kis_tool_star.cpp delete mode 100644 chalk/plugins/tools/tool_star/tool_star.cc create mode 100644 chalk/plugins/tools/tool_star/tool_star.cpp delete mode 100644 chalk/plugins/tools/tool_transform/kis_tool_transform.cc create mode 100644 chalk/plugins/tools/tool_transform/kis_tool_transform.cpp delete mode 100644 chalk/plugins/tools/tool_transform/tool_transform.cc create mode 100644 chalk/plugins/tools/tool_transform/tool_transform.cpp (limited to 'chalk/plugins/tools') diff --git a/chalk/plugins/tools/defaulttools/Makefile.am b/chalk/plugins/tools/defaulttools/Makefile.am index c4d790cb..ad9e96a5 100644 --- a/chalk/plugins/tools/defaulttools/Makefile.am +++ b/chalk/plugins/tools/defaulttools/Makefile.am @@ -10,19 +10,19 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalkdefaulttools_la_SOURCES = \ - default_tools.cc \ - kis_tool_colorpicker.cc \ - kis_tool_move.cc \ - kis_tool_zoom.cc \ - kis_tool_brush.cc \ - kis_tool_line.cc \ - kis_tool_duplicate.cc \ - kis_tool_fill.cc \ - kis_tool_rectangle.cc \ - kis_tool_ellipse.cc \ - kis_tool_pan.cc \ - kis_tool_text.cc \ - kis_tool_gradient.cc \ + default_tools.cpp \ + kis_tool_colorpicker.cpp \ + kis_tool_move.cpp \ + kis_tool_zoom.cpp \ + kis_tool_brush.cpp \ + kis_tool_line.cpp \ + kis_tool_duplicate.cpp \ + kis_tool_fill.cpp \ + kis_tool_rectangle.cpp \ + kis_tool_ellipse.cpp \ + kis_tool_pan.cpp \ + kis_tool_text.cpp \ + kis_tool_gradient.cpp \ wdgcolorpicker.ui # Install this plugin in the KDE modules directory diff --git a/chalk/plugins/tools/defaulttools/default_tools.cc b/chalk/plugins/tools/defaulttools/default_tools.cc deleted file mode 100644 index 17e0feff..00000000 --- a/chalk/plugins/tools/defaulttools/default_tools.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* - * default_tools.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "default_tools.h" - -#include "kis_tool_fill.h" -#include "kis_tool_brush.h" -#include "kis_tool_freehand.h" -#include "kis_tool_gradient.h" -#include "kis_tool_rectangle.h" -#include "kis_tool_colorpicker.h" -#include "kis_tool_line.h" -#include "kis_tool_text.h" -#include "kis_tool_duplicate.h" -#include "kis_tool_move.h" -#include "kis_tool_zoom.h" -#include "kis_tool_ellipse.h" -#include "kis_tool_pan.h" - - -typedef KGenericFactory DefaultToolsFactory; -K_EXPORT_COMPONENT_FACTORY( chalkdefaulttools, DefaultToolsFactory( "chalk" ) ) - - -DefaultTools::DefaultTools(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(DefaultToolsFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - - r->add(new KisToolFillFactory()); - r->add(new KisToolGradientFactory()); - r->add(new KisToolBrushFactory()); - r->add(new KisToolColorPickerFactory()); - r->add(new KisToolLineFactory()); - r->add(new KisToolTextFactory()); - r->add(new KisToolDuplicateFactory()); - r->add(new KisToolMoveFactory()); - r->add(new KisToolZoomFactory()); - r->add(new KisToolEllipseFactory()); - r->add(new KisToolRectangleFactory()); - r->add(new KisToolPanFactory()); - - } -} - -DefaultTools::~DefaultTools() -{ -} - -#include "default_tools.moc" diff --git a/chalk/plugins/tools/defaulttools/default_tools.cpp b/chalk/plugins/tools/defaulttools/default_tools.cpp new file mode 100644 index 00000000..6f1bedbb --- /dev/null +++ b/chalk/plugins/tools/defaulttools/default_tools.cpp @@ -0,0 +1,88 @@ +/* + * default_tools.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "default_tools.h" + +#include "kis_tool_fill.h" +#include "kis_tool_brush.h" +#include "kis_tool_freehand.h" +#include "kis_tool_gradient.h" +#include "kis_tool_rectangle.h" +#include "kis_tool_colorpicker.h" +#include "kis_tool_line.h" +#include "kis_tool_text.h" +#include "kis_tool_duplicate.h" +#include "kis_tool_move.h" +#include "kis_tool_zoom.h" +#include "kis_tool_ellipse.h" +#include "kis_tool_pan.h" + + +typedef KGenericFactory DefaultToolsFactory; +K_EXPORT_COMPONENT_FACTORY( chalkdefaulttools, DefaultToolsFactory( "chalk" ) ) + + +DefaultTools::DefaultTools(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(DefaultToolsFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + + r->add(new KisToolFillFactory()); + r->add(new KisToolGradientFactory()); + r->add(new KisToolBrushFactory()); + r->add(new KisToolColorPickerFactory()); + r->add(new KisToolLineFactory()); + r->add(new KisToolTextFactory()); + r->add(new KisToolDuplicateFactory()); + r->add(new KisToolMoveFactory()); + r->add(new KisToolZoomFactory()); + r->add(new KisToolEllipseFactory()); + r->add(new KisToolRectangleFactory()); + r->add(new KisToolPanFactory()); + + } +} + +DefaultTools::~DefaultTools() +{ +} + +#include "default_tools.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_brush.cc b/chalk/plugins/tools/defaulttools/kis_tool_brush.cc deleted file mode 100644 index 7c83a36b..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_brush.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* - * kis_tool_brush.cc - part of Chalk - * - * Copyright (c) 2003-2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_config.h" -#include "kis_brush.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_painter.h" -#include "kis_tool_brush.h" -#include "kis_canvas_subject.h" -#include "kis_boundary.h" -#include "kis_move_event.h" -#include "kis_canvas.h" -#include "kis_layer.h" - -KisToolBrush::KisToolBrush() - : super(i18n("Brush")) -{ - setName("tool_brush"); - setCursor(KisCursor::load("tool_freehand_cursor.png", 5, 5)); - m_rate = 100; // Conveniently hardcoded for now - m_timer = new TQTimer(this); - TQ_CHECK_PTR(m_timer); - - connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeoutPaint())); - -} - -KisToolBrush::~KisToolBrush() -{ - delete m_timer; - m_timer = 0; -} - -void KisToolBrush::timeoutPaint() -{ - if (currentImage() && painter()) { - painter()->paintAt(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt); - currentImage()->activeLayer()->setDirty(painter()->dirtyRect()); - } -} - - -void KisToolBrush::update(KisCanvasSubject *subject) -{ - super::update(subject); -} - -void KisToolBrush::initPaint(KisEvent *e) -{ - super::initPaint(e); - - if (!m_painter) { - kdWarning() << "Didn't create a painter! Something is wrong!\n"; - return; - } - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); - if (!op) return; - - m_subject->canvasController()->kiscanvas()->update(); // remove the outline - - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - - if (op->incremental()) { - m_timer->start( m_rate ); - } -} - - -void KisToolBrush::endPaint() -{ - m_timer->stop(); - super::endPaint(); -} - - -void KisToolBrush::setup(TDEActionCollection *collection) -{ - - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Brush"), - "tool_freehand", TQt::Key_B, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Draw freehand")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolBrush::move(KisMoveEvent *e) { - KisToolFreehand::move(e); - KisConfig cfg; - if (m_mode != PAINT && cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) - paintOutline(e->pos()); -} - -void KisToolBrush::leave(TQEvent */*e*/) { - m_subject->canvasController()->kiscanvas()->update(); // remove the outline -} - - -void KisToolBrush::slotSetPaintingMode( int mode ) -{ - if (mode == TQButton::On) { - // Direct painting - m_paintIncremental = true; - } - else { - m_paintIncremental = false; - } -} - - -TQWidget* KisToolBrush::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - m_chkDirect = new TQCheckBox(i18n("Paint direct"), widget, "chkDirect"); - m_chkDirect->setChecked(true); - connect(m_chkDirect, TQT_SIGNAL(stateChanged(int)), this, TQT_SLOT(slotSetPaintingMode(int))); - - m_optionLayout = new TQGridLayout(NULL, 3, 2, 0, 6); - TQ_CHECK_PTR(m_optionLayout); - - super::addOptionWidgetLayout(m_optionLayout); - m_optionLayout->addWidget(m_chkDirect, 0, 0); - - return widget; -} - -#include "kis_tool_brush.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_brush.cpp b/chalk/plugins/tools/defaulttools/kis_tool_brush.cpp new file mode 100644 index 00000000..96e26202 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_brush.cpp @@ -0,0 +1,167 @@ +/* + * kis_tool_brush.cpp - part of Chalk + * + * Copyright (c) 2003-2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_config.h" +#include "kis_brush.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_painter.h" +#include "kis_tool_brush.h" +#include "kis_canvas_subject.h" +#include "kis_boundary.h" +#include "kis_move_event.h" +#include "kis_canvas.h" +#include "kis_layer.h" + +KisToolBrush::KisToolBrush() + : super(i18n("Brush")) +{ + setName("tool_brush"); + setCursor(KisCursor::load("tool_freehand_cursor.png", 5, 5)); + m_rate = 100; // Conveniently hardcoded for now + m_timer = new TQTimer(this); + TQ_CHECK_PTR(m_timer); + + connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeoutPaint())); + +} + +KisToolBrush::~KisToolBrush() +{ + delete m_timer; + m_timer = 0; +} + +void KisToolBrush::timeoutPaint() +{ + if (currentImage() && painter()) { + painter()->paintAt(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt); + currentImage()->activeLayer()->setDirty(painter()->dirtyRect()); + } +} + + +void KisToolBrush::update(KisCanvasSubject *subject) +{ + super::update(subject); +} + +void KisToolBrush::initPaint(KisEvent *e) +{ + super::initPaint(e); + + if (!m_painter) { + kdWarning() << "Didn't create a painter! Something is wrong!\n"; + return; + } + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); + if (!op) return; + + m_subject->canvasController()->kiscanvas()->update(); // remove the outline + + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + + if (op->incremental()) { + m_timer->start( m_rate ); + } +} + + +void KisToolBrush::endPaint() +{ + m_timer->stop(); + super::endPaint(); +} + + +void KisToolBrush::setup(TDEActionCollection *collection) +{ + + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Brush"), + "tool_freehand", TQt::Key_B, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Draw freehand")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolBrush::move(KisMoveEvent *e) { + KisToolFreehand::move(e); + KisConfig cfg; + if (m_mode != PAINT && cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) + paintOutline(e->pos()); +} + +void KisToolBrush::leave(TQEvent */*e*/) { + m_subject->canvasController()->kiscanvas()->update(); // remove the outline +} + + +void KisToolBrush::slotSetPaintingMode( int mode ) +{ + if (mode == TQButton::On) { + // Direct painting + m_paintIncremental = true; + } + else { + m_paintIncremental = false; + } +} + + +TQWidget* KisToolBrush::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + m_chkDirect = new TQCheckBox(i18n("Paint direct"), widget, "chkDirect"); + m_chkDirect->setChecked(true); + connect(m_chkDirect, TQT_SIGNAL(stateChanged(int)), this, TQT_SLOT(slotSetPaintingMode(int))); + + m_optionLayout = new TQGridLayout(NULL, 3, 2, 0, 6); + TQ_CHECK_PTR(m_optionLayout); + + super::addOptionWidgetLayout(m_optionLayout); + m_optionLayout->addWidget(m_chkDirect, 0, 0); + + return widget; +} + +#include "kis_tool_brush.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc deleted file mode 100644 index 40a09a91..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * Copyright (c) 2002 Patrick Julien - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_layer.h" -#include "kis_cursor.h" -#include "kis_canvas_subject.h" -#include "kis_image.h" -#include "kis_paint_device.h" -#include "kis_tool_colorpicker.h" -#include "kis_tool_colorpicker.moc" -#include "kis_button_press_event.h" -#include "kis_canvas_subject.h" -#include "kis_iterators_pixel.h" -#include "kis_color.h" -#include "kis_resourceserver.h" -#include "kis_palette.h" -#include "wdgcolorpicker.h" - -namespace { - // The location of the sample all visible layers in the combobox - const int SAMPLE_MERGED = 0; -} - -KisToolColorPicker::KisToolColorPicker() - : super (i18n("Color Picker")) -{ - setName("tool_colorpicker"); - setCursor(KisCursor::pickerCursor()); - m_optionsWidget = 0; - m_subject = 0; - m_radius = 1; - m_addPalette = false; - m_updateColor = true; - m_normaliseValues = false; - m_pickedColor = KisColor(); -} - -KisToolColorPicker::~KisToolColorPicker() -{ -} - -void KisToolColorPicker::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolColorPicker::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) - return; - - KisImageSP img; - - if (!m_subject || !(img = m_subject->currentImg())) - return; - - KisPaintDeviceSP dev = img->activeDevice(); - - if (!dev) return; - - bool sampleMerged = m_optionsWidget->cmbSources->currentItem() == SAMPLE_MERGED; - if (!sampleMerged) { - if (!img->activeLayer()) - { - KMessageBox::information(0, i18n("Cannot pick a color as no layer is active.")); - return; - } - if (!img->activeLayer()-> visible()) { - KMessageBox::information(0, i18n("Cannot pick a color as the active layer is not visible.")); - return; - } - } - - TQPoint pos = TQPoint(e->pos().floorX(), e->pos().floorY()); - - if (!img->bounds().contains(pos)) { - return; - } - - if (sampleMerged) { - dev = img->mergedImage(); - } - - if (m_radius == 1) { - m_pickedColor = dev->colorAt (pos.x(), pos.y()); - } else { - // radius 2 ==> 9 pixels, 3 => 9 pixels, etc - static int counts[] = { 0, 1, 9, 25, 45, 69, 109, 145, 193, 249 }; - - KisColorSpace* cs = dev->colorSpace(); - int pixelSize = cs->pixelSize(); - - TQ_UINT8* data = new TQ_UINT8[pixelSize]; - TQ_UINT8** pixels = new TQ_UINT8*[counts[m_radius]]; - TQ_UINT8* weights = new TQ_UINT8[counts[m_radius]]; - - int i = 0; - // dummy init - KisHLineIteratorPixel iter = dev->createHLineIterator(0, 0, 1, false);; - for (int y = - m_radius; y <= m_radius; y++) { - for (int x = - m_radius; x <= m_radius; x++) { - if (x*x + y*y < m_radius * m_radius) { - iter = dev->createHLineIterator(pos.x() + x, pos.y() + y, 1, false); - - pixels[i] = new TQ_UINT8[pixelSize]; - memcpy(pixels[i], iter.rawData(), pixelSize); - - if (x == 0 && y == 0) { - // Because the sum of the weights must be 255, - // we cheat a bit, and weigh the center pixel differently in order - // to sum to 255 in total - // It's -(counts -1), because we'll add the center one implicitly - // through that calculation - weights[i] = 255 - (counts[m_radius]-1) * (255 / counts[m_radius]); - } else { - weights[i] = 255 / counts[m_radius]; - } - i++; - } - } - } - // Weird, I can't do that directly :/ - const TQ_UINT8** cpixels = const_cast(pixels); - cs->mixColors(cpixels, weights, counts[m_radius], data); - m_pickedColor = KisColor(data, cs); - - for (i = 0; i < counts[m_radius]; i++) - delete[] pixels[i]; - delete[] pixels; - delete[] data; - } - - displayPickedColor(); - - if (m_updateColor) { - if (e->button() == Qt::LeftButton) - m_subject->setFGColor(m_pickedColor); - else - m_subject->setBGColor(m_pickedColor); - } - - if (m_addPalette) { - // Convert to RGB to add to palette, we ought to have our own format :( - KisPaletteEntry ent; - ent.color = m_pickedColor.toTQColor(); - // We don't ask for a name, too intrusive here - - KisPalette* palette = m_palettes.at(m_optionsWidget-> cmbPalette->currentItem()); - palette->add(ent); - - if (!palette->save()) { - KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.").arg(palette->filename()), i18n("Palette")); - } - } - } -} - -void KisToolColorPicker::displayPickedColor() -{ - if (m_pickedColor.data() && m_optionsWidget) { - - TQValueVector channels = m_pickedColor.colorSpace()->channels(); - m_optionsWidget->listViewChannels->clear(); - - for (int i = channels.count() - 1; i >= 0 ; --i) { - TQString channelValueText; - - if (m_normaliseValues) { - channelValueText = i18n("%1%").arg(m_pickedColor.colorSpace()->normalisedChannelValueText(m_pickedColor.data(), i)); - } else { - channelValueText = m_pickedColor.colorSpace()->channelValueText(m_pickedColor.data(), i); - } - - m_optionsWidget->listViewChannels->insertItem(new TQListViewItem(m_optionsWidget->listViewChannels, - channels[i]->name(), - channelValueText)); - } - } -} - -void KisToolColorPicker::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Color Picker"), "tool_colorpicker", TQt::Key_P, this, TQT_SLOT(activate()), collection, name()); - m_action->setToolTip(i18n("Color picker")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolColorPicker::createOptionWidget(TQWidget* parent) -{ - m_optionsWidget = new ColorPickerOptionsWidget(parent); - - m_optionsWidget->cbUpdateCurrentColour->setChecked(m_updateColor); - - m_optionsWidget->cmbSources->setCurrentItem(0); - - m_optionsWidget->cbNormaliseValues->setChecked(m_normaliseValues); - m_optionsWidget->cbPalette->setChecked(m_addPalette); - m_optionsWidget->radius->setValue(m_radius); - - m_optionsWidget->listViewChannels->setSorting(-1); - - connect(m_optionsWidget->cbUpdateCurrentColour, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetUpdateColor(bool))); - connect(m_optionsWidget->cbNormaliseValues, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetNormaliseValues(bool))); - connect(m_optionsWidget->cbPalette, TQT_SIGNAL(toggled(bool)), - TQT_SLOT(slotSetAddPalette(bool))); - connect(m_optionsWidget->radius, TQT_SIGNAL(valueChanged(int)), - TQT_SLOT(slotChangeRadius(int))); - - KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer"); - - if (!srv) { - return m_optionsWidget; - } - - TQValueList palettes = srv->resources(); - - for(uint i = 0; i < palettes.count(); i++) { - KisPalette* palette = dynamic_cast(*palettes.at(i)); - if (palette) { - m_optionsWidget->cmbPalette->insertItem(palette->name()); - m_palettes.append(palette); - } - } - - connect(srv, TQT_SIGNAL(resourceAdded(KisResource*)), this, TQT_SLOT(slotAddPalette(KisResource*))); - - return m_optionsWidget; -} - -TQWidget* KisToolColorPicker::optionWidget() -{ - return m_optionsWidget; -} - -void KisToolColorPicker::slotSetUpdateColor(bool state) -{ - m_updateColor = state; -} - - -void KisToolColorPicker::slotSetNormaliseValues(bool state) -{ - m_normaliseValues = state; - displayPickedColor(); -} - -void KisToolColorPicker::slotSetAddPalette(bool state) { - m_addPalette = state; -} - -void KisToolColorPicker::slotChangeRadius(int value) { - m_radius = value; -} - -void KisToolColorPicker::slotAddPalette(KisResource* resource) { - KisPalette* palette = dynamic_cast(resource); - if (palette) { - m_optionsWidget-> cmbPalette->insertItem(palette->name()); - m_palettes.append(palette); - } -} - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp new file mode 100644 index 00000000..40a09a91 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (c) 1999 Matthias Elter + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_layer.h" +#include "kis_cursor.h" +#include "kis_canvas_subject.h" +#include "kis_image.h" +#include "kis_paint_device.h" +#include "kis_tool_colorpicker.h" +#include "kis_tool_colorpicker.moc" +#include "kis_button_press_event.h" +#include "kis_canvas_subject.h" +#include "kis_iterators_pixel.h" +#include "kis_color.h" +#include "kis_resourceserver.h" +#include "kis_palette.h" +#include "wdgcolorpicker.h" + +namespace { + // The location of the sample all visible layers in the combobox + const int SAMPLE_MERGED = 0; +} + +KisToolColorPicker::KisToolColorPicker() + : super (i18n("Color Picker")) +{ + setName("tool_colorpicker"); + setCursor(KisCursor::pickerCursor()); + m_optionsWidget = 0; + m_subject = 0; + m_radius = 1; + m_addPalette = false; + m_updateColor = true; + m_normaliseValues = false; + m_pickedColor = KisColor(); +} + +KisToolColorPicker::~KisToolColorPicker() +{ +} + +void KisToolColorPicker::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolColorPicker::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) + return; + + KisImageSP img; + + if (!m_subject || !(img = m_subject->currentImg())) + return; + + KisPaintDeviceSP dev = img->activeDevice(); + + if (!dev) return; + + bool sampleMerged = m_optionsWidget->cmbSources->currentItem() == SAMPLE_MERGED; + if (!sampleMerged) { + if (!img->activeLayer()) + { + KMessageBox::information(0, i18n("Cannot pick a color as no layer is active.")); + return; + } + if (!img->activeLayer()-> visible()) { + KMessageBox::information(0, i18n("Cannot pick a color as the active layer is not visible.")); + return; + } + } + + TQPoint pos = TQPoint(e->pos().floorX(), e->pos().floorY()); + + if (!img->bounds().contains(pos)) { + return; + } + + if (sampleMerged) { + dev = img->mergedImage(); + } + + if (m_radius == 1) { + m_pickedColor = dev->colorAt (pos.x(), pos.y()); + } else { + // radius 2 ==> 9 pixels, 3 => 9 pixels, etc + static int counts[] = { 0, 1, 9, 25, 45, 69, 109, 145, 193, 249 }; + + KisColorSpace* cs = dev->colorSpace(); + int pixelSize = cs->pixelSize(); + + TQ_UINT8* data = new TQ_UINT8[pixelSize]; + TQ_UINT8** pixels = new TQ_UINT8*[counts[m_radius]]; + TQ_UINT8* weights = new TQ_UINT8[counts[m_radius]]; + + int i = 0; + // dummy init + KisHLineIteratorPixel iter = dev->createHLineIterator(0, 0, 1, false);; + for (int y = - m_radius; y <= m_radius; y++) { + for (int x = - m_radius; x <= m_radius; x++) { + if (x*x + y*y < m_radius * m_radius) { + iter = dev->createHLineIterator(pos.x() + x, pos.y() + y, 1, false); + + pixels[i] = new TQ_UINT8[pixelSize]; + memcpy(pixels[i], iter.rawData(), pixelSize); + + if (x == 0 && y == 0) { + // Because the sum of the weights must be 255, + // we cheat a bit, and weigh the center pixel differently in order + // to sum to 255 in total + // It's -(counts -1), because we'll add the center one implicitly + // through that calculation + weights[i] = 255 - (counts[m_radius]-1) * (255 / counts[m_radius]); + } else { + weights[i] = 255 / counts[m_radius]; + } + i++; + } + } + } + // Weird, I can't do that directly :/ + const TQ_UINT8** cpixels = const_cast(pixels); + cs->mixColors(cpixels, weights, counts[m_radius], data); + m_pickedColor = KisColor(data, cs); + + for (i = 0; i < counts[m_radius]; i++) + delete[] pixels[i]; + delete[] pixels; + delete[] data; + } + + displayPickedColor(); + + if (m_updateColor) { + if (e->button() == Qt::LeftButton) + m_subject->setFGColor(m_pickedColor); + else + m_subject->setBGColor(m_pickedColor); + } + + if (m_addPalette) { + // Convert to RGB to add to palette, we ought to have our own format :( + KisPaletteEntry ent; + ent.color = m_pickedColor.toTQColor(); + // We don't ask for a name, too intrusive here + + KisPalette* palette = m_palettes.at(m_optionsWidget-> cmbPalette->currentItem()); + palette->add(ent); + + if (!palette->save()) { + KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.").arg(palette->filename()), i18n("Palette")); + } + } + } +} + +void KisToolColorPicker::displayPickedColor() +{ + if (m_pickedColor.data() && m_optionsWidget) { + + TQValueVector channels = m_pickedColor.colorSpace()->channels(); + m_optionsWidget->listViewChannels->clear(); + + for (int i = channels.count() - 1; i >= 0 ; --i) { + TQString channelValueText; + + if (m_normaliseValues) { + channelValueText = i18n("%1%").arg(m_pickedColor.colorSpace()->normalisedChannelValueText(m_pickedColor.data(), i)); + } else { + channelValueText = m_pickedColor.colorSpace()->channelValueText(m_pickedColor.data(), i); + } + + m_optionsWidget->listViewChannels->insertItem(new TQListViewItem(m_optionsWidget->listViewChannels, + channels[i]->name(), + channelValueText)); + } + } +} + +void KisToolColorPicker::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Color Picker"), "tool_colorpicker", TQt::Key_P, this, TQT_SLOT(activate()), collection, name()); + m_action->setToolTip(i18n("Color picker")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolColorPicker::createOptionWidget(TQWidget* parent) +{ + m_optionsWidget = new ColorPickerOptionsWidget(parent); + + m_optionsWidget->cbUpdateCurrentColour->setChecked(m_updateColor); + + m_optionsWidget->cmbSources->setCurrentItem(0); + + m_optionsWidget->cbNormaliseValues->setChecked(m_normaliseValues); + m_optionsWidget->cbPalette->setChecked(m_addPalette); + m_optionsWidget->radius->setValue(m_radius); + + m_optionsWidget->listViewChannels->setSorting(-1); + + connect(m_optionsWidget->cbUpdateCurrentColour, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetUpdateColor(bool))); + connect(m_optionsWidget->cbNormaliseValues, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetNormaliseValues(bool))); + connect(m_optionsWidget->cbPalette, TQT_SIGNAL(toggled(bool)), + TQT_SLOT(slotSetAddPalette(bool))); + connect(m_optionsWidget->radius, TQT_SIGNAL(valueChanged(int)), + TQT_SLOT(slotChangeRadius(int))); + + KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer"); + + if (!srv) { + return m_optionsWidget; + } + + TQValueList palettes = srv->resources(); + + for(uint i = 0; i < palettes.count(); i++) { + KisPalette* palette = dynamic_cast(*palettes.at(i)); + if (palette) { + m_optionsWidget->cmbPalette->insertItem(palette->name()); + m_palettes.append(palette); + } + } + + connect(srv, TQT_SIGNAL(resourceAdded(KisResource*)), this, TQT_SLOT(slotAddPalette(KisResource*))); + + return m_optionsWidget; +} + +TQWidget* KisToolColorPicker::optionWidget() +{ + return m_optionsWidget; +} + +void KisToolColorPicker::slotSetUpdateColor(bool state) +{ + m_updateColor = state; +} + + +void KisToolColorPicker::slotSetNormaliseValues(bool state) +{ + m_normaliseValues = state; + displayPickedColor(); +} + +void KisToolColorPicker::slotSetAddPalette(bool state) { + m_addPalette = state; +} + +void KisToolColorPicker::slotChangeRadius(int value) { + m_radius = value; +} + +void KisToolColorPicker::slotAddPalette(KisResource* resource) { + KisPalette* palette = dynamic_cast(resource); + if (palette) { + m_optionsWidget-> cmbPalette->insertItem(palette->name()); + m_palettes.append(palette); + } +} + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc deleted file mode 100644 index 7bb4c54f..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc +++ /dev/null @@ -1,255 +0,0 @@ -/* - * kis_tool_duplicate.cc - part of Chalk - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_brush.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_tool_duplicate.h" -#include "kis_painter.h" -#include "kis_vec.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_canvas_subject.h" -#include "kis_perspective_grid.h" - -#include "kis_canvas_painter.h" -#include "kis_boundary_painter.h" - -KisToolDuplicate::KisToolDuplicate() - : super(i18n("Duplicate Brush")), m_isOffsetNotUptodate(true), m_position(TQPoint(-1,-1)) -{ - setName("tool_duplicate"); - m_subject = 0; - setCursor(KisCursor::load("tool_duplicate_cursor.png", 5, 5)); -} - -KisToolDuplicate::~KisToolDuplicate() -{ -} - -void KisToolDuplicate::activate() -{ - m_position = TQPoint(-1,-1); - super::activate(); - if( m_subject->currentImg()->perspectiveGrid()->countSubGrids() != 1 ) - { - m_perspectiveCorrection->setEnabled( false ); - m_perspectiveCorrection->setChecked( false ); - } else { - m_perspectiveCorrection->setEnabled( true ); - } -} - -void KisToolDuplicate::buttonPress(KisButtonPressEvent *e) -{ - if (e->state() == ShiftButton) { - m_position = e->pos(); - m_isOffsetNotUptodate = true; - } else { - if (m_position != TQPoint(-1, -1)) { - super::buttonPress(e); - } - } -} - - -void KisToolDuplicate::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Duplicate Brush"), - "tool_duplicate", TQt::Key_C, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Duplicate parts of the image. Shift-click to select the point to duplicate from to begin.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolDuplicate::initPaint(KisEvent *e) -{ - if( m_position != TQPoint(-1,-1)) - { - if(m_isOffsetNotUptodate) - { - m_offset = e->pos() - m_position; - m_isOffsetNotUptodate = false; - } - m_paintIncremental = false; - super::initPaint(e); - painter()->setDuplicateOffset( m_offset ); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("duplicate", 0, painter()); - if (op && m_source) { - op->setSource(m_source); - painter()->setPaintOp(op); - } - m_positionStartPainting = e->pos(); - painter()->setDuplicateStart( e->pos() ); - } -} - -void KisToolDuplicate::move(KisMoveEvent *e) -{ - - // Paint the outline where we will (or are) copying from - if( m_position == TQPoint(-1,-1) ) - return; - - TQPoint srcPos; - if (m_mode == PAINT) { - // if we are in perspective correction mode, update the offset when moving - if(m_perspectiveCorrection->isChecked()) - { - double startM[3][3]; - double endM[3][3]; - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - startM[i][j] = 0.; - endM[i][j] = 0.; - } - startM[i][i] = 1.; - endM[i][i] = 1.; - } - - // First look for the grid corresponding to the start point - KisSubPerspectiveGrid* subGridStart = *m_subject->currentImg()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y())); - TQRect r = TQRect(0,0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); - - if(subGridStart) - { - double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight()); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - startM[i][j] = b[3*i+j]; - } - } - - } - // Second look for the grid corresponding to the end point - KisSubPerspectiveGrid* subGridEnd = *m_subject->currentImg()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos); - if(subGridEnd) - { - double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - endM[i][j] = b[3*i+j]; - } - } - } - // Compute the translation in the perspective transformation space: - KisPoint translat; - { - KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_positionStartPainting); - KisPoint currentPositionT = KisPerspectiveMath::matProd(endM, e->pos() ); - KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_positionStartPainting - m_offset); - KisPoint duplicateRealPosition = KisPerspectiveMath::matProd(startM, duplicateStartPoisitionT + (currentPositionT - positionStartPaintingT) ); - KisPoint p = e->pos() - duplicateRealPosition; - srcPos = p.floorTQPoint(); - } - - }else { - srcPos = painter()->duplicateOffset().floorTQPoint(); - } - } else { - if(m_isOffsetNotUptodate) - srcPos = e->pos().floorTQPoint() - m_position.floorTQPoint(); - else - srcPos = m_offset.floorTQPoint(); - } - - TQ_INT32 x; - TQ_INT32 y; - - // like KisPaintOp::splitCoordinate - x = (TQ_INT32)((e->x() < 0) ? e->x() - 1 : e->x()); - y = (TQ_INT32)((e->y() < 0) ? e->y() - 1 : e->y()); - srcPos = TQPoint(x - srcPos.x(), y - srcPos.y()); - - paintOutline(srcPos); - super::move(e); -} - -void KisToolDuplicate::paintAt(const KisPoint &pos, - const double pressure, - const double xtilt, - const double ytilt) -{ - if( m_position != TQPoint(-1,-1)) - { - if(m_isOffsetNotUptodate) - { - m_offset = pos - m_position; - m_isOffsetNotUptodate = false; - } - painter()->setDuplicateHealing( m_healing->isChecked() ); - painter()->setDuplicateHealingRadius( m_healingRadius->value() ); - painter()->setDuplicatePerspectiveCorrection( m_perspectiveCorrection->isChecked() ); - painter()->paintAt( pos, pressure, xtilt, ytilt); - } -} - -TQString KisToolDuplicate::quickHelp() const { - return i18n("To start, shift-click on the place you want to duplicate from. Then you can start painting. An indication of where you are copying from will be displayed while drawing and moving the mouse."); -} - -TQWidget* KisToolDuplicate::createOptionWidget(TQWidget* parent) -{ - TQWidget* widget = KisToolPaint::createOptionWidget(parent); - m_healing = new TQCheckBox(widget); - m_healing->setChecked( false); - addOptionWidgetOption(m_healing, new TQLabel(i18n("Healing"), widget )); - m_healingRadius = new KIntNumInput(widget); - - KisBrush *brush = m_subject->currentBrush(); - int healingradius = 20; - if( brush ) - { - healingradius = 2 * TQMAX(brush->width(),brush->height()); - } - - m_healingRadius->setValue( healingradius ); - addOptionWidgetOption(m_healingRadius, new TQLabel(i18n("Healing radius"), widget )); - m_perspectiveCorrection = new TQCheckBox(widget); - addOptionWidgetOption(m_perspectiveCorrection, new TQLabel(i18n("Correct the perspective"), widget )); - return widget; -} - -#include "kis_tool_duplicate.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp new file mode 100644 index 00000000..0f917e7f --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp @@ -0,0 +1,255 @@ +/* + * kis_tool_duplicate.cpp - part of Chalk + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_brush.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_tool_duplicate.h" +#include "kis_painter.h" +#include "kis_vec.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_canvas_subject.h" +#include "kis_perspective_grid.h" + +#include "kis_canvas_painter.h" +#include "kis_boundary_painter.h" + +KisToolDuplicate::KisToolDuplicate() + : super(i18n("Duplicate Brush")), m_isOffsetNotUptodate(true), m_position(TQPoint(-1,-1)) +{ + setName("tool_duplicate"); + m_subject = 0; + setCursor(KisCursor::load("tool_duplicate_cursor.png", 5, 5)); +} + +KisToolDuplicate::~KisToolDuplicate() +{ +} + +void KisToolDuplicate::activate() +{ + m_position = TQPoint(-1,-1); + super::activate(); + if( m_subject->currentImg()->perspectiveGrid()->countSubGrids() != 1 ) + { + m_perspectiveCorrection->setEnabled( false ); + m_perspectiveCorrection->setChecked( false ); + } else { + m_perspectiveCorrection->setEnabled( true ); + } +} + +void KisToolDuplicate::buttonPress(KisButtonPressEvent *e) +{ + if (e->state() == ShiftButton) { + m_position = e->pos(); + m_isOffsetNotUptodate = true; + } else { + if (m_position != TQPoint(-1, -1)) { + super::buttonPress(e); + } + } +} + + +void KisToolDuplicate::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Duplicate Brush"), + "tool_duplicate", TQt::Key_C, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Duplicate parts of the image. Shift-click to select the point to duplicate from to begin.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolDuplicate::initPaint(KisEvent *e) +{ + if( m_position != TQPoint(-1,-1)) + { + if(m_isOffsetNotUptodate) + { + m_offset = e->pos() - m_position; + m_isOffsetNotUptodate = false; + } + m_paintIncremental = false; + super::initPaint(e); + painter()->setDuplicateOffset( m_offset ); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("duplicate", 0, painter()); + if (op && m_source) { + op->setSource(m_source); + painter()->setPaintOp(op); + } + m_positionStartPainting = e->pos(); + painter()->setDuplicateStart( e->pos() ); + } +} + +void KisToolDuplicate::move(KisMoveEvent *e) +{ + + // Paint the outline where we will (or are) copying from + if( m_position == TQPoint(-1,-1) ) + return; + + TQPoint srcPos; + if (m_mode == PAINT) { + // if we are in perspective correction mode, update the offset when moving + if(m_perspectiveCorrection->isChecked()) + { + double startM[3][3]; + double endM[3][3]; + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + startM[i][j] = 0.; + endM[i][j] = 0.; + } + startM[i][i] = 1.; + endM[i][i] = 1.; + } + + // First look for the grid corresponding to the start point + KisSubPerspectiveGrid* subGridStart = *m_subject->currentImg()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y())); + TQRect r = TQRect(0,0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); + + if(subGridStart) + { + double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight()); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + startM[i][j] = b[3*i+j]; + } + } + + } + // Second look for the grid corresponding to the end point + KisSubPerspectiveGrid* subGridEnd = *m_subject->currentImg()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos); + if(subGridEnd) + { + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + endM[i][j] = b[3*i+j]; + } + } + } + // Compute the translation in the perspective transformation space: + KisPoint translat; + { + KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_positionStartPainting); + KisPoint currentPositionT = KisPerspectiveMath::matProd(endM, e->pos() ); + KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_positionStartPainting - m_offset); + KisPoint duplicateRealPosition = KisPerspectiveMath::matProd(startM, duplicateStartPoisitionT + (currentPositionT - positionStartPaintingT) ); + KisPoint p = e->pos() - duplicateRealPosition; + srcPos = p.floorTQPoint(); + } + + }else { + srcPos = painter()->duplicateOffset().floorTQPoint(); + } + } else { + if(m_isOffsetNotUptodate) + srcPos = e->pos().floorTQPoint() - m_position.floorTQPoint(); + else + srcPos = m_offset.floorTQPoint(); + } + + TQ_INT32 x; + TQ_INT32 y; + + // like KisPaintOp::splitCoordinate + x = (TQ_INT32)((e->x() < 0) ? e->x() - 1 : e->x()); + y = (TQ_INT32)((e->y() < 0) ? e->y() - 1 : e->y()); + srcPos = TQPoint(x - srcPos.x(), y - srcPos.y()); + + paintOutline(srcPos); + super::move(e); +} + +void KisToolDuplicate::paintAt(const KisPoint &pos, + const double pressure, + const double xtilt, + const double ytilt) +{ + if( m_position != TQPoint(-1,-1)) + { + if(m_isOffsetNotUptodate) + { + m_offset = pos - m_position; + m_isOffsetNotUptodate = false; + } + painter()->setDuplicateHealing( m_healing->isChecked() ); + painter()->setDuplicateHealingRadius( m_healingRadius->value() ); + painter()->setDuplicatePerspectiveCorrection( m_perspectiveCorrection->isChecked() ); + painter()->paintAt( pos, pressure, xtilt, ytilt); + } +} + +TQString KisToolDuplicate::quickHelp() const { + return i18n("To start, shift-click on the place you want to duplicate from. Then you can start painting. An indication of where you are copying from will be displayed while drawing and moving the mouse."); +} + +TQWidget* KisToolDuplicate::createOptionWidget(TQWidget* parent) +{ + TQWidget* widget = KisToolPaint::createOptionWidget(parent); + m_healing = new TQCheckBox(widget); + m_healing->setChecked( false); + addOptionWidgetOption(m_healing, new TQLabel(i18n("Healing"), widget )); + m_healingRadius = new KIntNumInput(widget); + + KisBrush *brush = m_subject->currentBrush(); + int healingradius = 20; + if( brush ) + { + healingradius = 2 * TQMAX(brush->width(),brush->height()); + } + + m_healingRadius->setValue( healingradius ); + addOptionWidgetOption(m_healingRadius, new TQLabel(i18n("Healing radius"), widget )); + m_perspectiveCorrection = new TQCheckBox(widget); + addOptionWidgetOption(m_perspectiveCorrection, new TQLabel(i18n("Correct the perspective"), widget )); + return widget; +} + +#include "kis_tool_duplicate.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc deleted file mode 100644 index 919454b2..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * kis_tool_ellipse.cc - part of Krayon - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include - -#include "kis_painter.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_tool_ellipse.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" - -KisToolEllipse::KisToolEllipse() - : super(i18n ("Ellipse")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_ellipse"); - setCursor(KisCursor::load("tool_ellipse_cursor.png", 6, 6)); -} - -KisToolEllipse::~KisToolEllipse() -{ -} - -void KisToolEllipse::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolEllipse::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage && event->button() == Qt::LeftButton) { - m_dragging = true; - m_dragStart = m_dragCenter = m_dragEnd = event->pos(); - draw(m_dragStart, m_dragEnd); - } -} - -void KisToolEllipse::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - // move (alt) or resize ellipse - if (event->state() & TQt::AltButton) { - KisPoint trans = event->pos() - m_dragEnd; - m_dragStart += trans; - m_dragEnd += trans; - } else { - KisPoint diag = event->pos() - (event->state() & TQt::ControlButton - ? m_dragCenter : m_dragStart); - // circle? - if (event->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (event->state() & TQt::ControlButton) { - m_dragStart = m_dragCenter - diag; - m_dragEnd = m_dragCenter + diag; - } else { - m_dragEnd = m_dragStart + diag; - } - } - // draw new lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, - (m_dragStart.y() + m_dragEnd.y()) / 2); - } -} - -void KisToolEllipse::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragging = false; - - if (m_dragStart == m_dragEnd) - return; - - if (!m_currentImage) - return; - - if (!m_currentImage->activeDevice()) - return; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Ellipse")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - painter.paintEllipse(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - KisUndoAdapter *adapter = m_currentImage->undoAdapter(); - if (adapter) { - adapter->addCommand(painter.endTransaction()); - } - } -} - -void KisToolEllipse::draw(const KisPoint& start, const KisPoint& end ) -{ - if (!m_subject || !m_currentImage) - return; - - KisCanvasController *controller = m_subject->canvasController (); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter p (canvas); - - p.setRasterOp (TQt::NotROP); - p.drawEllipse (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); - p.end (); -} - -void KisToolEllipse::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F7)); - m_action = new TDERadioAction(i18n("&Ellipse"), - "tool_ellipse", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Draw an ellipse")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_ellipse.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp new file mode 100644 index 00000000..0488dcb0 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp @@ -0,0 +1,186 @@ +/* + * kis_tool_ellipse.cpp - part of Krayon + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include + +#include "kis_painter.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_tool_ellipse.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" + +KisToolEllipse::KisToolEllipse() + : super(i18n ("Ellipse")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_ellipse"); + setCursor(KisCursor::load("tool_ellipse_cursor.png", 6, 6)); +} + +KisToolEllipse::~KisToolEllipse() +{ +} + +void KisToolEllipse::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolEllipse::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage && event->button() == Qt::LeftButton) { + m_dragging = true; + m_dragStart = m_dragCenter = m_dragEnd = event->pos(); + draw(m_dragStart, m_dragEnd); + } +} + +void KisToolEllipse::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + // move (alt) or resize ellipse + if (event->state() & TQt::AltButton) { + KisPoint trans = event->pos() - m_dragEnd; + m_dragStart += trans; + m_dragEnd += trans; + } else { + KisPoint diag = event->pos() - (event->state() & TQt::ControlButton + ? m_dragCenter : m_dragStart); + // circle? + if (event->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (event->state() & TQt::ControlButton) { + m_dragStart = m_dragCenter - diag; + m_dragEnd = m_dragCenter + diag; + } else { + m_dragEnd = m_dragStart + diag; + } + } + // draw new lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, + (m_dragStart.y() + m_dragEnd.y()) / 2); + } +} + +void KisToolEllipse::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragging = false; + + if (m_dragStart == m_dragEnd) + return; + + if (!m_currentImage) + return; + + if (!m_currentImage->activeDevice()) + return; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Ellipse")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + painter.paintEllipse(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + KisUndoAdapter *adapter = m_currentImage->undoAdapter(); + if (adapter) { + adapter->addCommand(painter.endTransaction()); + } + } +} + +void KisToolEllipse::draw(const KisPoint& start, const KisPoint& end ) +{ + if (!m_subject || !m_currentImage) + return; + + KisCanvasController *controller = m_subject->canvasController (); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter p (canvas); + + p.setRasterOp (TQt::NotROP); + p.drawEllipse (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); + p.end (); +} + +void KisToolEllipse::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F7)); + m_action = new TDERadioAction(i18n("&Ellipse"), + "tool_ellipse", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Draw an ellipse")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_ellipse.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_fill.cc b/chalk/plugins/tools/defaulttools/kis_tool_fill.cc deleted file mode 100644 index df8e4f7c..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_fill.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* - * kis_tool_fill.cc - part of Krayon - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "knuminput.h" - -#include "kis_layer.h" -#include "kis_cursor.h" -#include "kis_painter.h" -#include "kis_tool_brush.h" -#include "kis_cmb_composite.h" -#include "kis_tool_fill.h" -#include "kis_colorspace.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_pattern.h" -#include "kis_fill_painter.h" -#include "kis_progress_display_interface.h" -#include "kis_undo_adapter.h" -#include "kis_canvas_subject.h" -#include "kis_selection.h" - -KisToolFill::KisToolFill() - : super(i18n("Fill")), m_wasPressed(false) -{ - setName("tool_fill"); - m_subject = 0; - m_oldColor = 0; - m_threshold = 15; - m_usePattern = false; - m_unmerged = false; - m_fillOnlySelection = false; - - setCursor(KisCursor::load("tool_fill_cursor.png", 6, 6)); -} - -void KisToolFill::update(KisCanvasSubject *subject) -{ - m_subject = subject; - m_currentImage = subject->currentImg(); - - super::update(m_subject); -} - -KisToolFill::~KisToolFill() -{ -} - -bool KisToolFill::flood(int startX, int startY) -{ - KisPaintDeviceSP device = m_currentImage->activeDevice(); - if (!device) return false; - - if (m_fillOnlySelection) { - TQRect rc = device->selection()->selectedRect(); - KisPaintDeviceSP filled = new KisPaintDevice(device->colorSpace(), "filled"); - KisFillPainter painter(filled); - if (m_usePattern) - painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), - m_subject->currentPattern()); - else - painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), - m_subject->fgColor(), m_opacity); - painter.end(); - KisPainter painter2(device); - if (m_currentImage->undo()) painter2.beginTransaction(i18n("Fill")); - painter2.bltSelection(rc.x(), rc.y() , m_compositeOp, filled, m_opacity, - rc.x(), rc.y(), rc.width(), rc.height()); - - device->setDirty(filled->extent()); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter2.endTransaction()); - } - return true; - } - - KisFillPainter painter(device); - if (m_currentImage->undo()) painter.beginTransaction(i18n("Flood Fill")); - painter.setPaintColor(m_subject->fgColor()); - painter.setOpacity(m_opacity); - painter.setFillThreshold(m_threshold); - painter.setCompositeOp(m_compositeOp); - painter.setPattern(m_subject->currentPattern()); - painter.setSampleMerged(!m_unmerged); - painter.setCareForSelection(true); - - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - if (progress) { - progress->setSubject(&painter, true, true); - } - - if (m_usePattern) - painter.fillPattern(startX, startY); - else - painter.fillColor(startX, startY); - - device->setDirty(painter.dirtyRect()); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - - return true; -} - -void KisToolFill::buttonPress(KisButtonPressEvent *e) -{ - m_startPos = e->pos(); - m_wasPressed = true; -} - -void KisToolFill::buttonRelease(KisButtonReleaseEvent *e) -{ - if (!m_subject) return; - if (!m_currentImage || !m_currentImage->activeDevice()) return; - if (e->button() != Qt::LeftButton) return; - if(!m_wasPressed) return; - m_wasPressed = false; - int x, y; - x = m_startPos.floorX(); - y = m_startPos.floorY(); - if (!m_currentImage->bounds().contains(x, y)) { - return; - } - flood(x, y); - notifyModified(); -} - -TQWidget* KisToolFill::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - - m_lbThreshold = new TQLabel(i18n("Threshold: "), widget); - m_slThreshold = new KIntNumInput( widget, "int_widget"); - m_slThreshold->setRange( 1, 100); - m_slThreshold->setSteps( 3, 3); - m_slThreshold->setValue(m_threshold); - connect(m_slThreshold, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetThreshold(int))); - - m_checkUsePattern = new TQCheckBox(i18n("Use pattern"), widget); - m_checkUsePattern->setChecked(m_usePattern); - connect(m_checkUsePattern, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetUsePattern(bool))); - - m_checkSampleMerged = new TQCheckBox(i18n("Limit to current layer"), widget); - m_checkSampleMerged->setChecked(m_unmerged); - connect(m_checkSampleMerged, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetSampleMerged(bool))); - - m_checkFillSelection = new TQCheckBox(i18n("Fill entire selection"), widget); - m_checkFillSelection->setChecked(m_fillOnlySelection); - connect(m_checkFillSelection, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetFillSelection(bool))); - - addOptionWidgetOption(m_slThreshold, m_lbThreshold); - - addOptionWidgetOption(m_checkFillSelection); - addOptionWidgetOption(m_checkSampleMerged); - addOptionWidgetOption(m_checkUsePattern); - - return widget; -} - -void KisToolFill::slotSetThreshold(int threshold) -{ - m_threshold = threshold; -} - -void KisToolFill::slotSetUsePattern(bool state) -{ - m_usePattern = state; -} - -void KisToolFill::slotSetSampleMerged(bool state) -{ - m_unmerged = state; -} - -void KisToolFill::slotSetFillSelection(bool state) -{ - m_fillOnlySelection = state; - m_slThreshold->setEnabled(!state); - m_checkSampleMerged->setEnabled(!state); -} - -void KisToolFill::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Fill"), - "tool_color_fill", - TQt::Key_F, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Contiguous fill")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_fill.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_fill.cpp b/chalk/plugins/tools/defaulttools/kis_tool_fill.cpp new file mode 100644 index 00000000..ceb78f06 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_fill.cpp @@ -0,0 +1,233 @@ +/* + * kis_tool_fill.cpp - part of Krayon + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "knuminput.h" + +#include "kis_layer.h" +#include "kis_cursor.h" +#include "kis_painter.h" +#include "kis_tool_brush.h" +#include "kis_cmb_composite.h" +#include "kis_tool_fill.h" +#include "kis_colorspace.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_pattern.h" +#include "kis_fill_painter.h" +#include "kis_progress_display_interface.h" +#include "kis_undo_adapter.h" +#include "kis_canvas_subject.h" +#include "kis_selection.h" + +KisToolFill::KisToolFill() + : super(i18n("Fill")), m_wasPressed(false) +{ + setName("tool_fill"); + m_subject = 0; + m_oldColor = 0; + m_threshold = 15; + m_usePattern = false; + m_unmerged = false; + m_fillOnlySelection = false; + + setCursor(KisCursor::load("tool_fill_cursor.png", 6, 6)); +} + +void KisToolFill::update(KisCanvasSubject *subject) +{ + m_subject = subject; + m_currentImage = subject->currentImg(); + + super::update(m_subject); +} + +KisToolFill::~KisToolFill() +{ +} + +bool KisToolFill::flood(int startX, int startY) +{ + KisPaintDeviceSP device = m_currentImage->activeDevice(); + if (!device) return false; + + if (m_fillOnlySelection) { + TQRect rc = device->selection()->selectedRect(); + KisPaintDeviceSP filled = new KisPaintDevice(device->colorSpace(), "filled"); + KisFillPainter painter(filled); + if (m_usePattern) + painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), + m_subject->currentPattern()); + else + painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), + m_subject->fgColor(), m_opacity); + painter.end(); + KisPainter painter2(device); + if (m_currentImage->undo()) painter2.beginTransaction(i18n("Fill")); + painter2.bltSelection(rc.x(), rc.y() , m_compositeOp, filled, m_opacity, + rc.x(), rc.y(), rc.width(), rc.height()); + + device->setDirty(filled->extent()); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter2.endTransaction()); + } + return true; + } + + KisFillPainter painter(device); + if (m_currentImage->undo()) painter.beginTransaction(i18n("Flood Fill")); + painter.setPaintColor(m_subject->fgColor()); + painter.setOpacity(m_opacity); + painter.setFillThreshold(m_threshold); + painter.setCompositeOp(m_compositeOp); + painter.setPattern(m_subject->currentPattern()); + painter.setSampleMerged(!m_unmerged); + painter.setCareForSelection(true); + + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + if (progress) { + progress->setSubject(&painter, true, true); + } + + if (m_usePattern) + painter.fillPattern(startX, startY); + else + painter.fillColor(startX, startY); + + device->setDirty(painter.dirtyRect()); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + + return true; +} + +void KisToolFill::buttonPress(KisButtonPressEvent *e) +{ + m_startPos = e->pos(); + m_wasPressed = true; +} + +void KisToolFill::buttonRelease(KisButtonReleaseEvent *e) +{ + if (!m_subject) return; + if (!m_currentImage || !m_currentImage->activeDevice()) return; + if (e->button() != Qt::LeftButton) return; + if(!m_wasPressed) return; + m_wasPressed = false; + int x, y; + x = m_startPos.floorX(); + y = m_startPos.floorY(); + if (!m_currentImage->bounds().contains(x, y)) { + return; + } + flood(x, y); + notifyModified(); +} + +TQWidget* KisToolFill::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + + m_lbThreshold = new TQLabel(i18n("Threshold: "), widget); + m_slThreshold = new KIntNumInput( widget, "int_widget"); + m_slThreshold->setRange( 1, 100); + m_slThreshold->setSteps( 3, 3); + m_slThreshold->setValue(m_threshold); + connect(m_slThreshold, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetThreshold(int))); + + m_checkUsePattern = new TQCheckBox(i18n("Use pattern"), widget); + m_checkUsePattern->setChecked(m_usePattern); + connect(m_checkUsePattern, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetUsePattern(bool))); + + m_checkSampleMerged = new TQCheckBox(i18n("Limit to current layer"), widget); + m_checkSampleMerged->setChecked(m_unmerged); + connect(m_checkSampleMerged, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetSampleMerged(bool))); + + m_checkFillSelection = new TQCheckBox(i18n("Fill entire selection"), widget); + m_checkFillSelection->setChecked(m_fillOnlySelection); + connect(m_checkFillSelection, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetFillSelection(bool))); + + addOptionWidgetOption(m_slThreshold, m_lbThreshold); + + addOptionWidgetOption(m_checkFillSelection); + addOptionWidgetOption(m_checkSampleMerged); + addOptionWidgetOption(m_checkUsePattern); + + return widget; +} + +void KisToolFill::slotSetThreshold(int threshold) +{ + m_threshold = threshold; +} + +void KisToolFill::slotSetUsePattern(bool state) +{ + m_usePattern = state; +} + +void KisToolFill::slotSetSampleMerged(bool state) +{ + m_unmerged = state; +} + +void KisToolFill::slotSetFillSelection(bool state) +{ + m_fillOnlySelection = state; + m_slThreshold->setEnabled(!state); + m_checkSampleMerged->setEnabled(!state); +} + +void KisToolFill::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Fill"), + "tool_color_fill", + TQt::Key_F, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Contiguous fill")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_fill.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc deleted file mode 100644 index a46fee80..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc +++ /dev/null @@ -1,309 +0,0 @@ -/* - * kis_tool_gradient.cc - part of Chalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2003 Boudewijn Rempt - * Copyright (c) 2004 Adrian Page - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_canvas_subject.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_double_widget.h" -#include "kis_gradient_painter.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_progress_display_interface.h" -#include "kis_tool_gradient.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolGradient::KisToolGradient() - : super(i18n("Gradient")), - m_dragging( false ) -{ - setName("tool_gradient"); - setCursor(KisCursor::load("tool_gradient_cursor.png", 6, 6)); - - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - - m_reverse = false; - m_shape = KisGradientPainter::GradientShapeLinear; - m_repeat = KisGradientPainter::GradientRepeatNone; - m_antiAliasThreshold = 0.2; -} - -KisToolGradient::~KisToolGradient() -{ -} - -void KisToolGradient::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolGradient::paint(KisCanvasPainter& gc) -{ - if (m_dragging) - paintLine(gc); -} - -void KisToolGradient::paint(KisCanvasPainter& gc, const TQRect&) -{ - if (m_dragging) - paintLine(gc); -} - -void KisToolGradient::buttonPress(KisButtonPressEvent *e) -{ - if (!m_subject || !m_subject->currentImg()) { - return; - } - - if (e->button() == Qt::LeftButton) { - m_dragging = true; - m_startPos = e->pos(); - m_endPos = e->pos(); - } -} - -void KisToolGradient::move(KisMoveEvent *e) -{ - if (m_dragging) { - if (m_startPos != m_endPos) { - paintLine(); - } - - if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { - m_endPos = straightLine(e->pos()); - } - else { - m_endPos = e->pos(); - } - - paintLine(); - } -} - -void KisToolGradient::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_dragging && e->button() == Qt::LeftButton) { - - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - m_dragging = false; - - if (m_startPos == m_endPos) { - controller->updateCanvas(); - m_dragging = false; - return; - } - - if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { - m_endPos = straightLine(e->pos()); - } - else { - m_endPos = e->pos(); - } - - KisPaintDeviceSP device; - - if (img && (device = img->activeDevice())) { - - KisGradientPainter painter(device); - - if (img->undo()) painter.beginTransaction(i18n("Gradient")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setGradient(*(m_subject->currentGradient())); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - - if (progress) { - progress->setSubject(&painter, true, true); - } - - bool painted = painter.paintGradient(m_startPos, m_endPos, m_shape, m_repeat, m_antiAliasThreshold, m_reverse, 0, 0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); - - if (painted) { - // does whole thing at moment - device->setDirty(painter.dirtyRect()); - - notifyModified(); - - if (img->undo()) { - img->undoAdapter()->addCommand(painter.endTransaction()); - } - } - - /* remove remains of the line drawn while moving */ - if (controller->kiscanvas()) { - controller->kiscanvas()->update(); - } - - } - } -} - -KisPoint KisToolGradient::straightLine(KisPoint point) -{ - KisPoint comparison = point - m_startPos; - KisPoint result; - - if ( fabs(comparison.x()) > fabs(comparison.y())) { - result.setX(point.x()); - result.setY(m_startPos.y()); - } else { - result.setX( m_startPos.x() ); - result.setY( point.y() ); - } - - return result; -} - -void KisToolGradient::paintLine() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - paintLine(gc); - } -} - -void KisToolGradient::paintLine(KisCanvasPainter& gc) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - - KisPoint start = controller->windowToView(m_startPos); - KisPoint end = controller->windowToView(m_endPos); - - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -TQWidget* KisToolGradient::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - TQ_CHECK_PTR(widget); - - m_lbShape = new TQLabel(i18n("Shape:"), widget); - m_lbRepeat = new TQLabel(i18n("Repeat:"), widget); - - m_ckReverse = new TQCheckBox(i18n("Reverse"), widget, "reverse_check"); - connect(m_ckReverse, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetReverse(bool))); - - m_cmbShape = new TQComboBox(false, widget, "shape_combo"); - connect(m_cmbShape, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetShape(int))); - m_cmbShape->insertItem(i18n("Linear")); - m_cmbShape->insertItem(i18n("Bi-Linear")); - m_cmbShape->insertItem(i18n("Radial")); - m_cmbShape->insertItem(i18n("Square")); - m_cmbShape->insertItem(i18n("Conical")); - m_cmbShape->insertItem(i18n("Conical Symmetric")); - - m_cmbRepeat = new TQComboBox(false, widget, "repeat_combo"); - connect(m_cmbRepeat, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetRepeat(int))); - m_cmbRepeat->insertItem(i18n("None")); - m_cmbRepeat->insertItem(i18n("Forwards")); - m_cmbRepeat->insertItem(i18n("Alternating")); - - addOptionWidgetOption(m_cmbShape, m_lbShape); - - addOptionWidgetOption(m_cmbRepeat, m_lbRepeat); - - addOptionWidgetOption(m_ckReverse); - - m_lbAntiAliasThreshold = new TQLabel(i18n("Anti-alias threshold:"), widget); - - m_slAntiAliasThreshold = new KDoubleNumInput(widget, "threshold_slider"); - m_slAntiAliasThreshold->setRange( 0, 1); - m_slAntiAliasThreshold->setValue(m_antiAliasThreshold); - connect(m_slAntiAliasThreshold, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(slotSetAntiAliasThreshold(double))); - - addOptionWidgetOption(m_slAntiAliasThreshold, m_lbAntiAliasThreshold); - - return widget; -} - -void KisToolGradient::slotSetShape(int shape) -{ - m_shape = static_cast(shape); -} - -void KisToolGradient::slotSetRepeat(int repeat) -{ - m_repeat = static_cast(repeat); -} - -void KisToolGradient::slotSetReverse(bool state) -{ - m_reverse = state; -} - -void KisToolGradient::slotSetAntiAliasThreshold(double value) -{ - m_antiAliasThreshold = value; -} - -void KisToolGradient::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Gradient"), - "tool_gradient", TQt::Key_G, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Draw a gradient")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_gradient.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp new file mode 100644 index 00000000..b8f72a3b --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp @@ -0,0 +1,309 @@ +/* + * kis_tool_gradient.cpp - part of Chalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2003 Boudewijn Rempt + * Copyright (c) 2004 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_canvas_subject.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_double_widget.h" +#include "kis_gradient_painter.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_progress_display_interface.h" +#include "kis_tool_gradient.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolGradient::KisToolGradient() + : super(i18n("Gradient")), + m_dragging( false ) +{ + setName("tool_gradient"); + setCursor(KisCursor::load("tool_gradient_cursor.png", 6, 6)); + + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + + m_reverse = false; + m_shape = KisGradientPainter::GradientShapeLinear; + m_repeat = KisGradientPainter::GradientRepeatNone; + m_antiAliasThreshold = 0.2; +} + +KisToolGradient::~KisToolGradient() +{ +} + +void KisToolGradient::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolGradient::paint(KisCanvasPainter& gc) +{ + if (m_dragging) + paintLine(gc); +} + +void KisToolGradient::paint(KisCanvasPainter& gc, const TQRect&) +{ + if (m_dragging) + paintLine(gc); +} + +void KisToolGradient::buttonPress(KisButtonPressEvent *e) +{ + if (!m_subject || !m_subject->currentImg()) { + return; + } + + if (e->button() == Qt::LeftButton) { + m_dragging = true; + m_startPos = e->pos(); + m_endPos = e->pos(); + } +} + +void KisToolGradient::move(KisMoveEvent *e) +{ + if (m_dragging) { + if (m_startPos != m_endPos) { + paintLine(); + } + + if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { + m_endPos = straightLine(e->pos()); + } + else { + m_endPos = e->pos(); + } + + paintLine(); + } +} + +void KisToolGradient::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_dragging && e->button() == Qt::LeftButton) { + + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + m_dragging = false; + + if (m_startPos == m_endPos) { + controller->updateCanvas(); + m_dragging = false; + return; + } + + if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { + m_endPos = straightLine(e->pos()); + } + else { + m_endPos = e->pos(); + } + + KisPaintDeviceSP device; + + if (img && (device = img->activeDevice())) { + + KisGradientPainter painter(device); + + if (img->undo()) painter.beginTransaction(i18n("Gradient")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setGradient(*(m_subject->currentGradient())); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + + if (progress) { + progress->setSubject(&painter, true, true); + } + + bool painted = painter.paintGradient(m_startPos, m_endPos, m_shape, m_repeat, m_antiAliasThreshold, m_reverse, 0, 0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); + + if (painted) { + // does whole thing at moment + device->setDirty(painter.dirtyRect()); + + notifyModified(); + + if (img->undo()) { + img->undoAdapter()->addCommand(painter.endTransaction()); + } + } + + /* remove remains of the line drawn while moving */ + if (controller->kiscanvas()) { + controller->kiscanvas()->update(); + } + + } + } +} + +KisPoint KisToolGradient::straightLine(KisPoint point) +{ + KisPoint comparison = point - m_startPos; + KisPoint result; + + if ( fabs(comparison.x()) > fabs(comparison.y())) { + result.setX(point.x()); + result.setY(m_startPos.y()); + } else { + result.setX( m_startPos.x() ); + result.setY( point.y() ); + } + + return result; +} + +void KisToolGradient::paintLine() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + paintLine(gc); + } +} + +void KisToolGradient::paintLine(KisCanvasPainter& gc) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + + KisPoint start = controller->windowToView(m_startPos); + KisPoint end = controller->windowToView(m_endPos); + + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +TQWidget* KisToolGradient::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + TQ_CHECK_PTR(widget); + + m_lbShape = new TQLabel(i18n("Shape:"), widget); + m_lbRepeat = new TQLabel(i18n("Repeat:"), widget); + + m_ckReverse = new TQCheckBox(i18n("Reverse"), widget, "reverse_check"); + connect(m_ckReverse, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetReverse(bool))); + + m_cmbShape = new TQComboBox(false, widget, "shape_combo"); + connect(m_cmbShape, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetShape(int))); + m_cmbShape->insertItem(i18n("Linear")); + m_cmbShape->insertItem(i18n("Bi-Linear")); + m_cmbShape->insertItem(i18n("Radial")); + m_cmbShape->insertItem(i18n("Square")); + m_cmbShape->insertItem(i18n("Conical")); + m_cmbShape->insertItem(i18n("Conical Symmetric")); + + m_cmbRepeat = new TQComboBox(false, widget, "repeat_combo"); + connect(m_cmbRepeat, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetRepeat(int))); + m_cmbRepeat->insertItem(i18n("None")); + m_cmbRepeat->insertItem(i18n("Forwards")); + m_cmbRepeat->insertItem(i18n("Alternating")); + + addOptionWidgetOption(m_cmbShape, m_lbShape); + + addOptionWidgetOption(m_cmbRepeat, m_lbRepeat); + + addOptionWidgetOption(m_ckReverse); + + m_lbAntiAliasThreshold = new TQLabel(i18n("Anti-alias threshold:"), widget); + + m_slAntiAliasThreshold = new KDoubleNumInput(widget, "threshold_slider"); + m_slAntiAliasThreshold->setRange( 0, 1); + m_slAntiAliasThreshold->setValue(m_antiAliasThreshold); + connect(m_slAntiAliasThreshold, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(slotSetAntiAliasThreshold(double))); + + addOptionWidgetOption(m_slAntiAliasThreshold, m_lbAntiAliasThreshold); + + return widget; +} + +void KisToolGradient::slotSetShape(int shape) +{ + m_shape = static_cast(shape); +} + +void KisToolGradient::slotSetRepeat(int repeat) +{ + m_repeat = static_cast(repeat); +} + +void KisToolGradient::slotSetReverse(bool state) +{ + m_reverse = state; +} + +void KisToolGradient::slotSetAntiAliasThreshold(double value) +{ + m_antiAliasThreshold = value; +} + +void KisToolGradient::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Gradient"), + "tool_gradient", TQt::Key_G, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Draw a gradient")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_gradient.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_line.cc b/chalk/plugins/tools/defaulttools/kis_tool_line.cc deleted file mode 100644 index 4e118ccc..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_line.cc +++ /dev/null @@ -1,254 +0,0 @@ -/* - * kis_tool_line.cc - part of Krayon - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2003 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_cursor.h" -#include "kis_painter.h" -#include "kis_tool_line.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas_subject.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_layer.h" - -KisToolLine::KisToolLine() - : super(i18n("Line")), - m_dragging( false ) -{ - setName("tool_line"); - setCursor(KisCursor::load("tool_line_cursor.png", 6, 6)); - - m_painter = 0; - m_currentImage = 0; - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); -} - -KisToolLine::~KisToolLine() -{ -} - -void KisToolLine::update(KisCanvasSubject *subject) -{ - m_subject = subject; - m_currentImage = subject->currentImg(); - - super::update(m_subject); -} - - -void KisToolLine::paint(KisCanvasPainter& gc) -{ - if (m_dragging) - paintLine(gc, TQRect()); -} - -void KisToolLine::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_dragging) - paintLine(gc, rc); -} - -void KisToolLine::buttonPress(KisButtonPressEvent *e) -{ - if (!m_subject || !m_currentImage) return; - - if (!m_subject->currentBrush()) return; - - if (e->button() == Qt::LeftButton) { - m_dragging = true; - //KisCanvasController *controller = m_subject->canvasController(); - m_startPos = e->pos(); //controller->windowToView(e->pos()); - m_endPos = e->pos(); //controller->windowToView(e->pos()); - } -} - -void KisToolLine::move(KisMoveEvent *e) -{ - if (m_dragging) { - if (m_startPos != m_endPos) - paintLine(); - //KisCanvasController *controller = m_subject->canvasController(); - - if (e->state() & TQt::AltButton) { - KisPoint trans = e->pos() - m_endPos; - m_startPos += trans; - m_endPos += trans; - } else if (e->state() & TQt::ShiftButton) - m_endPos = straightLine(e->pos()); - else - m_endPos = e->pos();//controller->windowToView(e->pos()); - paintLine(); - } -} - -void KisToolLine::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_dragging && e->button() == Qt::LeftButton) { - m_dragging = false; - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - if (m_startPos == m_endPos) { - controller->updateCanvas(); - m_dragging = false; - return; - } - - if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { - m_endPos = straightLine(e->pos()); - } - else { - m_endPos = e->pos(); - } - - KisPaintDeviceSP device; - if (m_currentImage && - (device = m_currentImage->activeDevice()) && - m_subject && - m_subject->currentBrush()) - { - delete m_painter; - m_painter = new KisPainter( device ); - TQ_CHECK_PTR(m_painter); - - if (m_currentImage->undo()) m_painter->beginTransaction(i18n("Line")); - - m_painter->setPaintColor(m_subject->fgColor()); - m_painter->setBrush(m_subject->currentBrush()); - m_painter->setOpacity(m_opacity); - m_painter->setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); - m_painter->setPaintOp(op); // Painter takes ownership - m_painter->paintLine(m_startPos, PRESSURE_DEFAULT, 0, 0, m_endPos, PRESSURE_DEFAULT, 0, 0); - device->setDirty( m_painter->dirtyRect() ); - notifyModified(); - - /* remove remains of the line drawn while moving */ - if (controller->kiscanvas()) { - controller->kiscanvas()->update(); - } - - if (m_currentImage->undo() && m_painter) { - m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction()); - } - delete m_painter; - m_painter = 0; - } else { - if (m_painter) - controller->updateCanvas(m_painter->dirtyRect()); // Removes the last remaining line. - } - } - -} - -KisPoint KisToolLine::straightLine(KisPoint point) -{ - KisPoint comparison = point - m_startPos; - KisPoint result; - - if ( fabs(comparison.x()) > fabs(comparison.y())) { - result.setX(point.x()); - result.setY(m_startPos.y()); - } else { - result.setX( m_startPos.x() ); - result.setY( point.y() ); - } - - return result; -} - -void KisToolLine::paintLine() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintLine(gc, rc); - } -} - -void KisToolLine::paintLine(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - KisPoint start; - KisPoint end; - -// Q_ASSERT(controller); - start = controller->windowToView(m_startPos); - end = controller->windowToView(m_endPos); -// start.setX(start.x() - controller->horzValue()); -// start.setY(start.y() - controller->vertValue()); -// end.setX(end.x() - controller->horzValue()); -// end.setY(end.y() - controller->vertValue()); -// end.setX((end.x() - start.x())); -// end.setY((end.y() - start.y())); -// start *= m_subject->zoomFactor(); -// end *= m_subject->zoomFactor(); - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolLine::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Line"), - "tool_line", TQt::Key_L, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Draw a line")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQString KisToolLine::quickHelp() const { - return i18n("Alt+Drag will move the origin of the currently displayed line around, Shift+Drag will force you to draw straight lines"); -} - -#include "kis_tool_line.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_line.cpp b/chalk/plugins/tools/defaulttools/kis_tool_line.cpp new file mode 100644 index 00000000..87cb9390 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_line.cpp @@ -0,0 +1,254 @@ +/* + * kis_tool_line.cpp - part of Krayon + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2003 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_cursor.h" +#include "kis_painter.h" +#include "kis_tool_line.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas_subject.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_layer.h" + +KisToolLine::KisToolLine() + : super(i18n("Line")), + m_dragging( false ) +{ + setName("tool_line"); + setCursor(KisCursor::load("tool_line_cursor.png", 6, 6)); + + m_painter = 0; + m_currentImage = 0; + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); +} + +KisToolLine::~KisToolLine() +{ +} + +void KisToolLine::update(KisCanvasSubject *subject) +{ + m_subject = subject; + m_currentImage = subject->currentImg(); + + super::update(m_subject); +} + + +void KisToolLine::paint(KisCanvasPainter& gc) +{ + if (m_dragging) + paintLine(gc, TQRect()); +} + +void KisToolLine::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_dragging) + paintLine(gc, rc); +} + +void KisToolLine::buttonPress(KisButtonPressEvent *e) +{ + if (!m_subject || !m_currentImage) return; + + if (!m_subject->currentBrush()) return; + + if (e->button() == Qt::LeftButton) { + m_dragging = true; + //KisCanvasController *controller = m_subject->canvasController(); + m_startPos = e->pos(); //controller->windowToView(e->pos()); + m_endPos = e->pos(); //controller->windowToView(e->pos()); + } +} + +void KisToolLine::move(KisMoveEvent *e) +{ + if (m_dragging) { + if (m_startPos != m_endPos) + paintLine(); + //KisCanvasController *controller = m_subject->canvasController(); + + if (e->state() & TQt::AltButton) { + KisPoint trans = e->pos() - m_endPos; + m_startPos += trans; + m_endPos += trans; + } else if (e->state() & TQt::ShiftButton) + m_endPos = straightLine(e->pos()); + else + m_endPos = e->pos();//controller->windowToView(e->pos()); + paintLine(); + } +} + +void KisToolLine::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_dragging && e->button() == Qt::LeftButton) { + m_dragging = false; + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + if (m_startPos == m_endPos) { + controller->updateCanvas(); + m_dragging = false; + return; + } + + if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { + m_endPos = straightLine(e->pos()); + } + else { + m_endPos = e->pos(); + } + + KisPaintDeviceSP device; + if (m_currentImage && + (device = m_currentImage->activeDevice()) && + m_subject && + m_subject->currentBrush()) + { + delete m_painter; + m_painter = new KisPainter( device ); + TQ_CHECK_PTR(m_painter); + + if (m_currentImage->undo()) m_painter->beginTransaction(i18n("Line")); + + m_painter->setPaintColor(m_subject->fgColor()); + m_painter->setBrush(m_subject->currentBrush()); + m_painter->setOpacity(m_opacity); + m_painter->setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); + m_painter->setPaintOp(op); // Painter takes ownership + m_painter->paintLine(m_startPos, PRESSURE_DEFAULT, 0, 0, m_endPos, PRESSURE_DEFAULT, 0, 0); + device->setDirty( m_painter->dirtyRect() ); + notifyModified(); + + /* remove remains of the line drawn while moving */ + if (controller->kiscanvas()) { + controller->kiscanvas()->update(); + } + + if (m_currentImage->undo() && m_painter) { + m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction()); + } + delete m_painter; + m_painter = 0; + } else { + if (m_painter) + controller->updateCanvas(m_painter->dirtyRect()); // Removes the last remaining line. + } + } + +} + +KisPoint KisToolLine::straightLine(KisPoint point) +{ + KisPoint comparison = point - m_startPos; + KisPoint result; + + if ( fabs(comparison.x()) > fabs(comparison.y())) { + result.setX(point.x()); + result.setY(m_startPos.y()); + } else { + result.setX( m_startPos.x() ); + result.setY( point.y() ); + } + + return result; +} + +void KisToolLine::paintLine() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintLine(gc, rc); + } +} + +void KisToolLine::paintLine(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + KisPoint start; + KisPoint end; + +// Q_ASSERT(controller); + start = controller->windowToView(m_startPos); + end = controller->windowToView(m_endPos); +// start.setX(start.x() - controller->horzValue()); +// start.setY(start.y() - controller->vertValue()); +// end.setX(end.x() - controller->horzValue()); +// end.setY(end.y() - controller->vertValue()); +// end.setX((end.x() - start.x())); +// end.setY((end.y() - start.y())); +// start *= m_subject->zoomFactor(); +// end *= m_subject->zoomFactor(); + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolLine::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Line"), + "tool_line", TQt::Key_L, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Draw a line")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQString KisToolLine::quickHelp() const { + return i18n("Alt+Drag will move the origin of the currently displayed line around, Shift+Drag will force you to draw straight lines"); +} + +#include "kis_tool_line.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_move.cc b/chalk/plugins/tools/defaulttools/kis_tool_move.cc deleted file mode 100644 index be506578..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_move.cc +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * 1999 Michael Koch - * 2002 Patrick Julien - * 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_paint_device.h" -#include "kis_tool_move.h" -#include "kis_tool_move.moc" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_manager.h" -#include "kis_layer.h" - -KisToolMove::KisToolMove() - : super(i18n("Move Tool")) - , m_subject( 0 ) - , m_keyEvent( 0 ) -{ - setName("tool_move"); - - setCursor(KisCursor::moveCursor()); - m_repeatTimer = new TQTimer(this); - connect( m_repeatTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotMove() ) ); -} - -KisToolMove::~KisToolMove() -{ -} - -void KisToolMove::update(KisCanvasSubject *subject) -{ - m_subject = subject; - m_strategy.reset(subject); - super::update(subject); -} - -void KisToolMove::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - TQPoint pos = e->pos().floorTQPoint(); - KisImageSP img = m_subject->currentImg(); - KisLayerSP dev; - - if (!img || !(dev = img->activeLayer())) - return; - - m_strategy.startDrag(pos); - } -} - -void KisToolMove::move(KisMoveEvent *e) -{ - if (m_subject && e->state() == Qt::LeftButton) { - TQPoint pos = e->pos().floorTQPoint(); - if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { - if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) - pos.setY(m_dragStart.y()); - else - pos.setX(m_dragStart.x()); - } - m_strategy.drag(pos); - } -} - -void KisToolMove::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - m_strategy.endDrag(e->pos().floorTQPoint()); - } -} - -void KisToolMove::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Move"), - "tool_move", - TQt::SHIFT+TQt::Key_V, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Move")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - - -void KisToolMove::keyPress( TQKeyEvent *e ) -{ - m_keyEvent = e; - - if (m_subject) { - - KisImageSP img = m_subject->currentImg(); - KisLayerSP dev; - - if (!img || !(dev = img->activeLayer())) - return; - - m_dragStart = TQPoint( 0, 0 ); - m_strategy.startDrag( m_dragStart ); - m_steps = 1; - m_repeatTimer->start(200); - - } -} - -void KisToolMove::keyRelease(TQKeyEvent *) -{ - m_repeatTimer->stop(); - - if ( m_subject && m_keyEvent) { - - if ( m_keyEvent->key() == TQt::Key_Left ) { - m_strategy.endDrag(TQPoint( -m_steps, 0 )); - } - else if ( m_keyEvent->key() == TQt::Key_Right ) { - m_strategy.endDrag(TQPoint(m_steps, 0) ); - } - else if ( m_keyEvent->key() == TQt::Key_Up ) { - m_strategy.endDrag(TQPoint(0, -m_steps) ); - } - else if ( m_keyEvent->key() == TQt::Key_Down ) { - m_strategy.endDrag(TQPoint(0, m_steps) ); - } - } - m_steps = 0; - m_keyEvent = 0; - -} - -void KisToolMove::slotMove() -{ - if (m_subject && m_keyEvent) { - - if ( m_keyEvent->key() == TQt::Key_Left ) { - m_strategy.drag(TQPoint(-m_steps, 0) ); - } - else if ( m_keyEvent->key() == TQt::Key_Right ) { - m_strategy.drag(TQPoint(m_steps, 0) ); - } - else if ( m_keyEvent->key() == TQt::Key_Up ) { - m_strategy.drag(TQPoint(0, -m_steps) ); - } - else if ( m_keyEvent->key() == TQt::Key_Down ) { - m_strategy.drag(TQPoint(0, m_steps) ); - } - - ++m_steps; - } - -} diff --git a/chalk/plugins/tools/defaulttools/kis_tool_move.cpp b/chalk/plugins/tools/defaulttools/kis_tool_move.cpp new file mode 100644 index 00000000..be506578 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_move.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1999 Matthias Elter + * 1999 Michael Koch + * 2002 Patrick Julien + * 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_paint_device.h" +#include "kis_tool_move.h" +#include "kis_tool_move.moc" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_manager.h" +#include "kis_layer.h" + +KisToolMove::KisToolMove() + : super(i18n("Move Tool")) + , m_subject( 0 ) + , m_keyEvent( 0 ) +{ + setName("tool_move"); + + setCursor(KisCursor::moveCursor()); + m_repeatTimer = new TQTimer(this); + connect( m_repeatTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotMove() ) ); +} + +KisToolMove::~KisToolMove() +{ +} + +void KisToolMove::update(KisCanvasSubject *subject) +{ + m_subject = subject; + m_strategy.reset(subject); + super::update(subject); +} + +void KisToolMove::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + TQPoint pos = e->pos().floorTQPoint(); + KisImageSP img = m_subject->currentImg(); + KisLayerSP dev; + + if (!img || !(dev = img->activeLayer())) + return; + + m_strategy.startDrag(pos); + } +} + +void KisToolMove::move(KisMoveEvent *e) +{ + if (m_subject && e->state() == Qt::LeftButton) { + TQPoint pos = e->pos().floorTQPoint(); + if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { + if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) + pos.setY(m_dragStart.y()); + else + pos.setX(m_dragStart.x()); + } + m_strategy.drag(pos); + } +} + +void KisToolMove::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + m_strategy.endDrag(e->pos().floorTQPoint()); + } +} + +void KisToolMove::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Move"), + "tool_move", + TQt::SHIFT+TQt::Key_V, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Move")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + + +void KisToolMove::keyPress( TQKeyEvent *e ) +{ + m_keyEvent = e; + + if (m_subject) { + + KisImageSP img = m_subject->currentImg(); + KisLayerSP dev; + + if (!img || !(dev = img->activeLayer())) + return; + + m_dragStart = TQPoint( 0, 0 ); + m_strategy.startDrag( m_dragStart ); + m_steps = 1; + m_repeatTimer->start(200); + + } +} + +void KisToolMove::keyRelease(TQKeyEvent *) +{ + m_repeatTimer->stop(); + + if ( m_subject && m_keyEvent) { + + if ( m_keyEvent->key() == TQt::Key_Left ) { + m_strategy.endDrag(TQPoint( -m_steps, 0 )); + } + else if ( m_keyEvent->key() == TQt::Key_Right ) { + m_strategy.endDrag(TQPoint(m_steps, 0) ); + } + else if ( m_keyEvent->key() == TQt::Key_Up ) { + m_strategy.endDrag(TQPoint(0, -m_steps) ); + } + else if ( m_keyEvent->key() == TQt::Key_Down ) { + m_strategy.endDrag(TQPoint(0, m_steps) ); + } + } + m_steps = 0; + m_keyEvent = 0; + +} + +void KisToolMove::slotMove() +{ + if (m_subject && m_keyEvent) { + + if ( m_keyEvent->key() == TQt::Key_Left ) { + m_strategy.drag(TQPoint(-m_steps, 0) ); + } + else if ( m_keyEvent->key() == TQt::Key_Right ) { + m_strategy.drag(TQPoint(m_steps, 0) ); + } + else if ( m_keyEvent->key() == TQt::Key_Up ) { + m_strategy.drag(TQPoint(0, -m_steps) ); + } + else if ( m_keyEvent->key() == TQt::Key_Down ) { + m_strategy.drag(TQPoint(0, m_steps) ); + } + + ++m_steps; + } + +} diff --git a/chalk/plugins/tools/defaulttools/kis_tool_pan.cc b/chalk/plugins/tools/defaulttools/kis_tool_pan.cc deleted file mode 100644 index c95b1000..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_pan.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2004 Adrian Page - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_tool_pan.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" - -KisToolPan::KisToolPan() - : super(i18n("Pan Tool")) -{ - setName("tool_pan"); - m_subject = 0; - m_dragging = false; - m_openHandCursor = KisCursor::openHandCursor(); - m_closedHandCursor = KisCursor::closedHandCursor(); - setCursor(m_openHandCursor); -} - -KisToolPan::~KisToolPan() -{ -} - -void KisToolPan::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolPan::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && !m_dragging && e->button() == Qt::LeftButton) { - KisCanvasController *controller = m_subject->canvasController(); - - m_origScrollX = controller->horzValue(); - m_origScrollY = controller->vertValue(); - m_dragPos = controller->windowToView(e->pos()); - m_dragging = true; - setCursor(m_closedHandCursor); - } -} - -void KisToolPan::move(KisMoveEvent *e) -{ - if (m_subject && m_dragging) { - KisCanvasController *controller = m_subject->canvasController(); - - KisPoint currPos = controller->windowToView(e->pos()); - KisPoint delta = currPos - m_dragPos; - controller->scrollTo(m_origScrollX - delta.floorX(), m_origScrollY - delta.floorY()); - } -} - -void KisToolPan::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_dragging && e->button() == Qt::LeftButton) { - setCursor(m_openHandCursor); - m_dragging = false; - } -} - -void KisToolPan::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Pan"), "tool_pan", TQt::SHIFT+TQt::Key_H, this, TQT_SLOT(activate()), collection, name()); - m_action->setToolTip(i18n("Pan")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_pan.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_pan.cpp b/chalk/plugins/tools/defaulttools/kis_tool_pan.cpp new file mode 100644 index 00000000..c95b1000 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_pan.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_tool_pan.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" + +KisToolPan::KisToolPan() + : super(i18n("Pan Tool")) +{ + setName("tool_pan"); + m_subject = 0; + m_dragging = false; + m_openHandCursor = KisCursor::openHandCursor(); + m_closedHandCursor = KisCursor::closedHandCursor(); + setCursor(m_openHandCursor); +} + +KisToolPan::~KisToolPan() +{ +} + +void KisToolPan::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolPan::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && !m_dragging && e->button() == Qt::LeftButton) { + KisCanvasController *controller = m_subject->canvasController(); + + m_origScrollX = controller->horzValue(); + m_origScrollY = controller->vertValue(); + m_dragPos = controller->windowToView(e->pos()); + m_dragging = true; + setCursor(m_closedHandCursor); + } +} + +void KisToolPan::move(KisMoveEvent *e) +{ + if (m_subject && m_dragging) { + KisCanvasController *controller = m_subject->canvasController(); + + KisPoint currPos = controller->windowToView(e->pos()); + KisPoint delta = currPos - m_dragPos; + controller->scrollTo(m_origScrollX - delta.floorX(), m_origScrollY - delta.floorY()); + } +} + +void KisToolPan::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_dragging && e->button() == Qt::LeftButton) { + setCursor(m_openHandCursor); + m_dragging = false; + } +} + +void KisToolPan::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Pan"), "tool_pan", TQt::SHIFT+TQt::Key_H, this, TQT_SLOT(activate()), collection, name()); + m_action->setToolTip(i18n("Pan")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_pan.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc deleted file mode 100644 index 852d2c0e..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* - * kis_tool_rectangle.cc - part of Chalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include - -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_tool_rectangle.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_layer.h" - -KisToolRectangle::KisToolRectangle() - : super(i18n ("Rectangle")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_rectangle"); - setCursor(KisCursor::load("tool_rectangle_cursor.png", 6, 6)); -} - -KisToolRectangle::~KisToolRectangle() -{ -} - -void KisToolRectangle::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolRectangle::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage && event->button() == Qt::LeftButton) { - m_dragging = true; - m_dragStart = m_dragCenter = m_dragEnd = event->pos(); - draw(m_dragStart, m_dragEnd); - } -} - -void KisToolRectangle::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - // move (alt) or resize rectangle - if (event->state() & TQt::AltButton) { - KisPoint trans = event->pos() - m_dragEnd; - m_dragStart += trans; - m_dragEnd += trans; - } else { - KisPoint diag = event->pos() - (event->state() & TQt::ControlButton - ? m_dragCenter : m_dragStart); - // square? - if (event->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (event->state() & TQt::ControlButton) { - m_dragStart = m_dragCenter - diag; - m_dragEnd = m_dragCenter + diag; - } else { - m_dragEnd = m_dragStart + diag; - } - } - // draw new lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, - (m_dragStart.y() + m_dragEnd.y()) / 2); - } -} - -void KisToolRectangle::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if (!m_currentImage) - return; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - if (m_dragging && event->button() == Qt::LeftButton) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragging = false; - - if (m_dragStart == m_dragEnd) - return; - - if (!m_currentImage) - return; - - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Rectangle")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); - - painter.paintRect(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - } -} - -void KisToolRectangle::draw(const KisPoint& start, const KisPoint& end ) -{ - if (!m_subject) - return; - - KisCanvasController *controller = m_subject->canvasController (); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter p (canvas); - - p.setRasterOp (TQt::NotROP); - p.drawRect (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); - p.end (); -} - -void KisToolRectangle::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Rectangle"), - "tool_rectangle", - TQt::Key_F6, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Draw a rectangle")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_rectangle.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp new file mode 100644 index 00000000..69e306ec --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp @@ -0,0 +1,187 @@ +/* + * kis_tool_rectangle.cpp - part of Chalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include + +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_tool_rectangle.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_layer.h" + +KisToolRectangle::KisToolRectangle() + : super(i18n ("Rectangle")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_rectangle"); + setCursor(KisCursor::load("tool_rectangle_cursor.png", 6, 6)); +} + +KisToolRectangle::~KisToolRectangle() +{ +} + +void KisToolRectangle::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolRectangle::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage && event->button() == Qt::LeftButton) { + m_dragging = true; + m_dragStart = m_dragCenter = m_dragEnd = event->pos(); + draw(m_dragStart, m_dragEnd); + } +} + +void KisToolRectangle::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + // move (alt) or resize rectangle + if (event->state() & TQt::AltButton) { + KisPoint trans = event->pos() - m_dragEnd; + m_dragStart += trans; + m_dragEnd += trans; + } else { + KisPoint diag = event->pos() - (event->state() & TQt::ControlButton + ? m_dragCenter : m_dragStart); + // square? + if (event->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (event->state() & TQt::ControlButton) { + m_dragStart = m_dragCenter - diag; + m_dragEnd = m_dragCenter + diag; + } else { + m_dragEnd = m_dragStart + diag; + } + } + // draw new lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, + (m_dragStart.y() + m_dragEnd.y()) / 2); + } +} + +void KisToolRectangle::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if (!m_currentImage) + return; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + if (m_dragging && event->button() == Qt::LeftButton) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragging = false; + + if (m_dragStart == m_dragEnd) + return; + + if (!m_currentImage) + return; + + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Rectangle")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); + + painter.paintRect(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + } +} + +void KisToolRectangle::draw(const KisPoint& start, const KisPoint& end ) +{ + if (!m_subject) + return; + + KisCanvasController *controller = m_subject->canvasController (); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter p (canvas); + + p.setRasterOp (TQt::NotROP); + p.drawRect (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); + p.end (); +} + +void KisToolRectangle::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Rectangle"), + "tool_rectangle", + TQt::Key_F6, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Draw a rectangle")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_rectangle.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_text.cc b/chalk/plugins/tools/defaulttools/kis_tool_text.cc deleted file mode 100644 index 1a2687f1..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_text.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2004 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "kis_point.h" -#include "kis_image.h" -#include "kis_layer.h" -#include "kis_group_layer.h" -#include "kis_paint_layer.h" -#include "kis_cursor.h" -#include "kis_tool_text.h" -#include "kis_paint_device.h" -#include "kis_canvas_subject.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_color.h" -#include "kis_undo_adapter.h" - -KisToolText::KisToolText() - : super(i18n("Text")) - , m_wasPressed( false ) - , m_windowIsBeingShown( false ) -{ - setName("tool_text"); - m_subject = 0; - setCursor(KisCursor::load("tool_text_cursor.png", 6, 6)); -} - -KisToolText::~KisToolText() -{ -} - -void KisToolText::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(subject); -} - -void KisToolText::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - m_wasPressed = true; - } -} - -void KisToolText::buttonRelease(KisButtonReleaseEvent *e) -{ - if ( m_windowIsBeingShown ) return; - - if (m_subject && e->button() == Qt::LeftButton) { - if(!m_wasPressed) return; - m_wasPressed = false; - KisImageSP img = m_subject->currentImg(); - - m_windowIsBeingShown = true; - bool ok; - TQString text = KInputDialog::getText(i18n("Font Tool"), i18n("Enter text:"), - TQString(), &ok); - if (!ok) { - m_windowIsBeingShown = false; - return; - } - - KisUndoAdapter *undoAdapter = img->undoAdapter(); - if (undoAdapter) { - undoAdapter->beginMacro(i18n("Text")); - } - - TQFontMetrics metrics(m_font); - TQRect boundingRect = TQT_TQRECT_OBJECT(metrics.boundingRect(text)).normalize(); - int xB = - boundingRect.x(); - int yB = - boundingRect.y(); - - if (boundingRect.x() < 0 || boundingRect.y() < 0) - boundingRect.moveBy(- boundingRect.x(), - boundingRect.y()); - - TQPixmap pixels(boundingRect.width(), boundingRect.height()); - { - TQPainter paint(&pixels); - paint.fillRect(boundingRect, TQt::white); - paint.setFont(m_font); - paint.setBrush(TQBrush(TQt::black)); - paint.drawText(xB, yB, text); - } - TQImage image = pixels.convertToImage(); - - TQ_INT32 height = boundingRect.height(); - TQ_INT32 width = boundingRect.width(); - KisPaintLayer *layer = new KisPaintLayer(img, '"' + text + '"', OPACITY_OPAQUE); - KisGroupLayerSP parent = img->rootLayer(); - if (img->activeLayer()) - parent = img->activeLayer()->parent(); - img->addLayer(layer, parent, img->activeLayer()); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - TQRgb pixel = image.pixel(x, y); - // use the 'blackness' as alpha :) - TQ_UINT8 alpha = 255 - tqRed(pixel) * OPACITY_OPAQUE / 255; - TQColor c = m_subject->fgColor().toTQColor(); - layer->paintDevice()->setPixel(x, y, c, alpha); - } - } - - layer->setOpacity(m_opacity); - layer->setCompositeOp(m_compositeOp); - - layer->setVisible(false); - TQ_INT32 x = TQMAX(0, static_cast(e->x() - width/2)); - TQ_INT32 y = TQMAX(0, static_cast(e->y() - height/2)); - layer->setX(x); - layer->setY(y); - layer->setVisible(true); - layer->setDirty(); - - if (undoAdapter) { - undoAdapter->endMacro(); - } - - m_windowIsBeingShown = false; - } -} - -void KisToolText::setFont() { - TDEFontDialog::getFont( m_font, false/*, TQWidget* parent! */ ); - m_lbFontName->setText(TQString(m_font.family() + ", %1").arg(m_font.pointSize())); -} - -TQWidget* KisToolText::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - - m_lbFont = new TQLabel(i18n("Font: "), widget); - - TQHBox *fontBox = new TQHBox(widget); - m_lbFontName = new KSqueezedTextLabel(TQString(m_font.family() + ", %1") - .arg(m_font.pointSize()), fontBox); - m_btnMoreFonts = new TQPushButton("...", fontBox); - - connect(m_btnMoreFonts, TQT_SIGNAL(released()), this, TQT_SLOT(setFont())); - - addOptionWidgetOption(fontBox, m_lbFont); - - return widget; -} - -void KisToolText::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("T&ext"), - "tool_text", - TQt::SHIFT+TQt::Key_T, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Text")); - m_ownAction = true; - } -} - -#include "kis_tool_text.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_text.cpp b/chalk/plugins/tools/defaulttools/kis_tool_text.cpp new file mode 100644 index 00000000..1a2687f1 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_text.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2004 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "kis_point.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_group_layer.h" +#include "kis_paint_layer.h" +#include "kis_cursor.h" +#include "kis_tool_text.h" +#include "kis_paint_device.h" +#include "kis_canvas_subject.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_color.h" +#include "kis_undo_adapter.h" + +KisToolText::KisToolText() + : super(i18n("Text")) + , m_wasPressed( false ) + , m_windowIsBeingShown( false ) +{ + setName("tool_text"); + m_subject = 0; + setCursor(KisCursor::load("tool_text_cursor.png", 6, 6)); +} + +KisToolText::~KisToolText() +{ +} + +void KisToolText::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(subject); +} + +void KisToolText::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + m_wasPressed = true; + } +} + +void KisToolText::buttonRelease(KisButtonReleaseEvent *e) +{ + if ( m_windowIsBeingShown ) return; + + if (m_subject && e->button() == Qt::LeftButton) { + if(!m_wasPressed) return; + m_wasPressed = false; + KisImageSP img = m_subject->currentImg(); + + m_windowIsBeingShown = true; + bool ok; + TQString text = KInputDialog::getText(i18n("Font Tool"), i18n("Enter text:"), + TQString(), &ok); + if (!ok) { + m_windowIsBeingShown = false; + return; + } + + KisUndoAdapter *undoAdapter = img->undoAdapter(); + if (undoAdapter) { + undoAdapter->beginMacro(i18n("Text")); + } + + TQFontMetrics metrics(m_font); + TQRect boundingRect = TQT_TQRECT_OBJECT(metrics.boundingRect(text)).normalize(); + int xB = - boundingRect.x(); + int yB = - boundingRect.y(); + + if (boundingRect.x() < 0 || boundingRect.y() < 0) + boundingRect.moveBy(- boundingRect.x(), - boundingRect.y()); + + TQPixmap pixels(boundingRect.width(), boundingRect.height()); + { + TQPainter paint(&pixels); + paint.fillRect(boundingRect, TQt::white); + paint.setFont(m_font); + paint.setBrush(TQBrush(TQt::black)); + paint.drawText(xB, yB, text); + } + TQImage image = pixels.convertToImage(); + + TQ_INT32 height = boundingRect.height(); + TQ_INT32 width = boundingRect.width(); + KisPaintLayer *layer = new KisPaintLayer(img, '"' + text + '"', OPACITY_OPAQUE); + KisGroupLayerSP parent = img->rootLayer(); + if (img->activeLayer()) + parent = img->activeLayer()->parent(); + img->addLayer(layer, parent, img->activeLayer()); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + TQRgb pixel = image.pixel(x, y); + // use the 'blackness' as alpha :) + TQ_UINT8 alpha = 255 - tqRed(pixel) * OPACITY_OPAQUE / 255; + TQColor c = m_subject->fgColor().toTQColor(); + layer->paintDevice()->setPixel(x, y, c, alpha); + } + } + + layer->setOpacity(m_opacity); + layer->setCompositeOp(m_compositeOp); + + layer->setVisible(false); + TQ_INT32 x = TQMAX(0, static_cast(e->x() - width/2)); + TQ_INT32 y = TQMAX(0, static_cast(e->y() - height/2)); + layer->setX(x); + layer->setY(y); + layer->setVisible(true); + layer->setDirty(); + + if (undoAdapter) { + undoAdapter->endMacro(); + } + + m_windowIsBeingShown = false; + } +} + +void KisToolText::setFont() { + TDEFontDialog::getFont( m_font, false/*, TQWidget* parent! */ ); + m_lbFontName->setText(TQString(m_font.family() + ", %1").arg(m_font.pointSize())); +} + +TQWidget* KisToolText::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + + m_lbFont = new TQLabel(i18n("Font: "), widget); + + TQHBox *fontBox = new TQHBox(widget); + m_lbFontName = new KSqueezedTextLabel(TQString(m_font.family() + ", %1") + .arg(m_font.pointSize()), fontBox); + m_btnMoreFonts = new TQPushButton("...", fontBox); + + connect(m_btnMoreFonts, TQT_SIGNAL(released()), this, TQT_SLOT(setFont())); + + addOptionWidgetOption(fontBox, m_lbFont); + + return widget; +} + +void KisToolText::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("T&ext"), + "tool_text", + TQt::SHIFT+TQt::Key_T, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Text")); + m_ownAction = true; + } +} + +#include "kis_tool_text.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc deleted file mode 100644 index fe449ee4..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * Copyright (c) 2002 Patrick Julien - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include "kis_image.h" -#include "kis_paint_device.h" -#include "kis_paint_layer.h" -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_tool_zoom.h" - - -KisToolZoom::KisToolZoom() - : super(i18n("Zoom Tool")) -{ - setName("tool_zoom"); - m_subject = 0; - m_dragging = false; - m_startPos = TQPoint(0, 0); - m_endPos = TQPoint(0, 0); - m_plusCursor = KisCursor::load("tool_zoom_plus_cursor.png", 8, 8); - m_minusCursor = KisCursor::load("tool_zoom_minus_cursor.png", 8, 8); - setCursor(m_plusCursor); - connect(&m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer())); -} - -KisToolZoom::~KisToolZoom() -{ -} - -void KisToolZoom::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolZoom::paint(KisCanvasPainter& gc) -{ - if (m_dragging) - paintOutline(gc, TQRect()); -} - -void KisToolZoom::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_dragging) - paintOutline(gc, rc); -} - -void KisToolZoom::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && m_subject->currentImg() && !m_dragging) { - if (e->button() == Qt::LeftButton) { - m_startPos = e->pos().floorTQPoint(); - m_endPos = e->pos().floorTQPoint(); - m_dragging = true; - } - } -} - -void KisToolZoom::move(KisMoveEvent *e) -{ - if (m_subject && m_dragging) { - if (m_startPos != m_endPos) - paintOutline(); - - m_endPos = e->pos().floorTQPoint(); - paintOutline(); - } -} - -void KisToolZoom::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_dragging && e->button() == Qt::LeftButton) { - - KisCanvasController *controller = m_subject->canvasController(); - m_endPos = e->pos().floorTQPoint(); - m_dragging = false; - - TQPoint delta = m_endPos - m_startPos; - - if (sqrt(delta.x() * delta.x() + delta.y() * delta.y()) < 10) { - if (e->state() & TQt::ControlButton) { - controller->zoomOut(m_endPos.x(), m_endPos.y()); - } else { - controller->zoomIn(m_endPos.x(), m_endPos.y()); - } - } else { - controller->zoomTo(TQRect(m_startPos, m_endPos)); - } - } -} - -void KisToolZoom::activate() -{ - super::activate(); - m_timer.start(50); -} - -void KisToolZoom::deactivate() -{ - m_timer.stop(); -} - -void KisToolZoom::slotTimer() -{ -#if KDE_IS_VERSION(3,4,0) - int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); -#else - int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier - |TDEApplication::ControlModifier|TDEApplication::Modifier1); -#endif - - if (state & TQt::ControlButton) { - m_subject->canvasController()->setCanvasCursor(m_minusCursor); - } else { - m_subject->canvasController()->setCanvasCursor(m_plusCursor); - } -} - -void KisToolZoom::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolZoom::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::DotLine); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_startPos); - end = controller->windowToView(m_endPos); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(TQRect(start, end)); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolZoom::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Zoom"), "tool_zoom", TQt::Key_Z, this, TQT_SLOT(activate()), collection, name()); - m_action->setToolTip(i18n("Zoom")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_zoom.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp new file mode 100644 index 00000000..fe449ee4 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 1999 Matthias Elter + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "kis_image.h" +#include "kis_paint_device.h" +#include "kis_paint_layer.h" +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_tool_zoom.h" + + +KisToolZoom::KisToolZoom() + : super(i18n("Zoom Tool")) +{ + setName("tool_zoom"); + m_subject = 0; + m_dragging = false; + m_startPos = TQPoint(0, 0); + m_endPos = TQPoint(0, 0); + m_plusCursor = KisCursor::load("tool_zoom_plus_cursor.png", 8, 8); + m_minusCursor = KisCursor::load("tool_zoom_minus_cursor.png", 8, 8); + setCursor(m_plusCursor); + connect(&m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer())); +} + +KisToolZoom::~KisToolZoom() +{ +} + +void KisToolZoom::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolZoom::paint(KisCanvasPainter& gc) +{ + if (m_dragging) + paintOutline(gc, TQRect()); +} + +void KisToolZoom::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_dragging) + paintOutline(gc, rc); +} + +void KisToolZoom::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && m_subject->currentImg() && !m_dragging) { + if (e->button() == Qt::LeftButton) { + m_startPos = e->pos().floorTQPoint(); + m_endPos = e->pos().floorTQPoint(); + m_dragging = true; + } + } +} + +void KisToolZoom::move(KisMoveEvent *e) +{ + if (m_subject && m_dragging) { + if (m_startPos != m_endPos) + paintOutline(); + + m_endPos = e->pos().floorTQPoint(); + paintOutline(); + } +} + +void KisToolZoom::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_dragging && e->button() == Qt::LeftButton) { + + KisCanvasController *controller = m_subject->canvasController(); + m_endPos = e->pos().floorTQPoint(); + m_dragging = false; + + TQPoint delta = m_endPos - m_startPos; + + if (sqrt(delta.x() * delta.x() + delta.y() * delta.y()) < 10) { + if (e->state() & TQt::ControlButton) { + controller->zoomOut(m_endPos.x(), m_endPos.y()); + } else { + controller->zoomIn(m_endPos.x(), m_endPos.y()); + } + } else { + controller->zoomTo(TQRect(m_startPos, m_endPos)); + } + } +} + +void KisToolZoom::activate() +{ + super::activate(); + m_timer.start(50); +} + +void KisToolZoom::deactivate() +{ + m_timer.stop(); +} + +void KisToolZoom::slotTimer() +{ +#if KDE_IS_VERSION(3,4,0) + int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); +#else + int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier + |TDEApplication::ControlModifier|TDEApplication::Modifier1); +#endif + + if (state & TQt::ControlButton) { + m_subject->canvasController()->setCanvasCursor(m_minusCursor); + } else { + m_subject->canvasController()->setCanvasCursor(m_plusCursor); + } +} + +void KisToolZoom::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolZoom::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::DotLine); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_startPos); + end = controller->windowToView(m_endPos); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(TQRect(start, end)); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolZoom::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Zoom"), "tool_zoom", TQt::Key_Z, this, TQT_SLOT(activate()), collection, name()); + m_action->setToolTip(i18n("Zoom")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_zoom.moc" diff --git a/chalk/plugins/tools/selectiontools/Makefile.am b/chalk/plugins/tools/selectiontools/Makefile.am index febfd514..0f1b8474 100644 --- a/chalk/plugins/tools/selectiontools/Makefile.am +++ b/chalk/plugins/tools/selectiontools/Makefile.am @@ -9,10 +9,10 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkselectiontools_la_SOURCES = kis_tool_move_selection.cc \ - kis_tool_select_brush.cc kis_tool_select_contiguous.cc kis_tool_select_elliptical.cc \ - kis_tool_select_eraser.cc kis_tool_select_outline.cc kis_tool_select_polygonal.cc \ - kis_tool_select_rectangular.cc selection_tools.cc +chalkselectiontools_la_SOURCES = kis_tool_move_selection.cpp \ + kis_tool_select_brush.cpp kis_tool_select_contiguous.cpp kis_tool_select_elliptical.cpp \ + kis_tool_select_eraser.cpp kis_tool_select_outline.cpp kis_tool_select_polygonal.cpp \ + kis_tool_select_rectangular.cpp selection_tools.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalkselectiontools.la diff --git a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc deleted file mode 100644 index a1f0902f..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_tool_move_selection.h" - -#include -#include -#include -#include -#include -#include -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_layer.h" -#include "kis_paint_layer.h" -#include "kis_paint_device.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_manager.h" -#include "kis_undo_adapter.h" - -class KisSelectionOffsetCommand : public KNamedCommand { - typedef KNamedCommand super; - -public: - KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos); - virtual ~KisSelectionOffsetCommand(); - - virtual void execute(); - virtual void unexecute(); - -private: - void moveTo(const TQPoint& pos); - -private: - KisSelectionSP m_layer; - TQPoint m_oldPos; - TQPoint m_newPos; -}; - - KisSelectionOffsetCommand::KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos) : - super(i18n("Move Layer")) - { - m_layer = layer; - m_oldPos = oldpos; - m_newPos = newpos; - - } - - KisSelectionOffsetCommand::~KisSelectionOffsetCommand() - { - } - - void KisSelectionOffsetCommand::execute() - { - moveTo(m_newPos); - } - - void KisSelectionOffsetCommand::unexecute() - { - moveTo(m_oldPos); - } - - void KisSelectionOffsetCommand::moveTo(const TQPoint& pos) - { - if (m_layer->undoAdapter()) { - m_layer->undoAdapter()->setUndo(false); - } - - m_layer->setX(pos.x()); - m_layer->setY(pos.y()); - - m_layer->parentPaintDevice()->setDirty(); - - if (m_layer->undoAdapter()) { - m_layer->undoAdapter()->setUndo(true); - } - } - - -KisToolMoveSelection::KisToolMoveSelection() - : super(i18n("Move Selection Tool")) -{ - setName("tool_move_selection"); - m_subject = 0; - setCursor(KisCursor::moveCursor()); -} - -KisToolMoveSelection::~KisToolMoveSelection() -{ -} - -void KisToolMoveSelection::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(subject); - m_dragging = false; -} - -void KisToolMoveSelection::buttonPress(KisButtonPressEvent *e) -{ - m_dragging = false; - if (m_subject && e->button() == Qt::LeftButton) { - TQPoint pos = e->pos().floorTQPoint(); - KisImageSP img = m_subject->currentImg(); - KisPaintLayerSP lay; - - if (!img || !(lay = dynamic_cast( img->activeLayer().data() ))) - return; - - m_dragStart = pos; - - if ( !lay->visible() || !lay->paintDevice()->hasSelection()) - return; - KisSelectionSP sel = lay->paintDevice()->selection(); - - m_dragging = true; - m_dragStart.setX(pos.x()); - m_dragStart.setY(pos.y()); - m_layerStart.setX(sel->getX()); - m_layerStart.setY(sel->getY()); - m_layerPosition = m_layerStart; - - } -} - -void KisToolMoveSelection::move(KisMoveEvent *e) -{ - if (m_subject && m_dragging) { - TQPoint pos = e->pos().floorTQPoint(); - if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { - if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) - pos.setY(m_dragStart.y()); - else - pos.setX(m_dragStart.x()); - } - - KisImageSP img = m_subject->currentImg(); - KisPaintLayerSP lay = dynamic_cast(m_subject->currentImg()->activeLayer().data()); - if(!lay) return; - KisSelectionSP sel = lay->paintDevice()->selection(); - - TQRect rc; - - pos -= m_dragStart; // convert to delta - rc = sel->selectedRect(); - sel->setX(sel->getX() + pos.x()); - sel->setY(sel->getY() + pos.y()); - rc = rc.unite(sel->selectedRect()); - - m_layerPosition = TQPoint(sel->getX(), sel->getY()); - m_dragStart = e->pos().floorTQPoint(); - - lay->paintDevice()->setDirty(rc); - } - -} - -void KisToolMoveSelection::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton && m_dragging) { - m_dragging = false; - KisImageSP img = m_subject->currentImg(); - if(!img) return; - KisPaintLayerSP lay = dynamic_cast(img->activeLayer().data()); - - if (lay->paintDevice()->hasSelection()) { - KisSelectionSP dev = lay->paintDevice()->selection(); - m_dragging = false; - - if (img->undo()) { - KCommand *cmd = new KisSelectionOffsetCommand( dev, m_layerStart, m_layerPosition); - TQ_CHECK_PTR(cmd); - KisUndoAdapter *adapter = img->undoAdapter(); - if (adapter) { - adapter->addCommand(cmd); - } else { - delete cmd; - } - } - img->setModified(); - lay->setDirty(); - } - } -} - -void KisToolMoveSelection::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Move selection"), - "tool_move", - TQt::SHIFT+TQt::Key_V, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Move the selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_move_selection.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp new file mode 100644 index 00000000..a1f0902f --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_tool_move_selection.h" + +#include +#include +#include +#include +#include +#include +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_paint_device.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_manager.h" +#include "kis_undo_adapter.h" + +class KisSelectionOffsetCommand : public KNamedCommand { + typedef KNamedCommand super; + +public: + KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos); + virtual ~KisSelectionOffsetCommand(); + + virtual void execute(); + virtual void unexecute(); + +private: + void moveTo(const TQPoint& pos); + +private: + KisSelectionSP m_layer; + TQPoint m_oldPos; + TQPoint m_newPos; +}; + + KisSelectionOffsetCommand::KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos) : + super(i18n("Move Layer")) + { + m_layer = layer; + m_oldPos = oldpos; + m_newPos = newpos; + + } + + KisSelectionOffsetCommand::~KisSelectionOffsetCommand() + { + } + + void KisSelectionOffsetCommand::execute() + { + moveTo(m_newPos); + } + + void KisSelectionOffsetCommand::unexecute() + { + moveTo(m_oldPos); + } + + void KisSelectionOffsetCommand::moveTo(const TQPoint& pos) + { + if (m_layer->undoAdapter()) { + m_layer->undoAdapter()->setUndo(false); + } + + m_layer->setX(pos.x()); + m_layer->setY(pos.y()); + + m_layer->parentPaintDevice()->setDirty(); + + if (m_layer->undoAdapter()) { + m_layer->undoAdapter()->setUndo(true); + } + } + + +KisToolMoveSelection::KisToolMoveSelection() + : super(i18n("Move Selection Tool")) +{ + setName("tool_move_selection"); + m_subject = 0; + setCursor(KisCursor::moveCursor()); +} + +KisToolMoveSelection::~KisToolMoveSelection() +{ +} + +void KisToolMoveSelection::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(subject); + m_dragging = false; +} + +void KisToolMoveSelection::buttonPress(KisButtonPressEvent *e) +{ + m_dragging = false; + if (m_subject && e->button() == Qt::LeftButton) { + TQPoint pos = e->pos().floorTQPoint(); + KisImageSP img = m_subject->currentImg(); + KisPaintLayerSP lay; + + if (!img || !(lay = dynamic_cast( img->activeLayer().data() ))) + return; + + m_dragStart = pos; + + if ( !lay->visible() || !lay->paintDevice()->hasSelection()) + return; + KisSelectionSP sel = lay->paintDevice()->selection(); + + m_dragging = true; + m_dragStart.setX(pos.x()); + m_dragStart.setY(pos.y()); + m_layerStart.setX(sel->getX()); + m_layerStart.setY(sel->getY()); + m_layerPosition = m_layerStart; + + } +} + +void KisToolMoveSelection::move(KisMoveEvent *e) +{ + if (m_subject && m_dragging) { + TQPoint pos = e->pos().floorTQPoint(); + if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { + if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) + pos.setY(m_dragStart.y()); + else + pos.setX(m_dragStart.x()); + } + + KisImageSP img = m_subject->currentImg(); + KisPaintLayerSP lay = dynamic_cast(m_subject->currentImg()->activeLayer().data()); + if(!lay) return; + KisSelectionSP sel = lay->paintDevice()->selection(); + + TQRect rc; + + pos -= m_dragStart; // convert to delta + rc = sel->selectedRect(); + sel->setX(sel->getX() + pos.x()); + sel->setY(sel->getY() + pos.y()); + rc = rc.unite(sel->selectedRect()); + + m_layerPosition = TQPoint(sel->getX(), sel->getY()); + m_dragStart = e->pos().floorTQPoint(); + + lay->paintDevice()->setDirty(rc); + } + +} + +void KisToolMoveSelection::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton && m_dragging) { + m_dragging = false; + KisImageSP img = m_subject->currentImg(); + if(!img) return; + KisPaintLayerSP lay = dynamic_cast(img->activeLayer().data()); + + if (lay->paintDevice()->hasSelection()) { + KisSelectionSP dev = lay->paintDevice()->selection(); + m_dragging = false; + + if (img->undo()) { + KCommand *cmd = new KisSelectionOffsetCommand( dev, m_layerStart, m_layerPosition); + TQ_CHECK_PTR(cmd); + KisUndoAdapter *adapter = img->undoAdapter(); + if (adapter) { + adapter->addCommand(cmd); + } else { + delete cmd; + } + } + img->setModified(); + lay->setDirty(); + } + } +} + +void KisToolMoveSelection::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Move selection"), + "tool_move", + TQt::SHIFT+TQt::Key_V, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Move the selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_move_selection.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc deleted file mode 100644 index acc90362..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* - * kis_tool_select_brush.cc - part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_brush.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_selection.h" -#include "kis_tool_select_brush.h" -#include "kis_types.h" -#include "kis_layer.h" -#include "kis_view.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" - -KisToolSelectBrush::KisToolSelectBrush() - : super(i18n("SelectBrush")) -{ - setName("tool_select_brush"); - m_optWidget = 0; - setCursor(KisCursor::load("tool_brush_selection_cursor.png", 5, 5)); - m_paintOnSelection = true; -} - -KisToolSelectBrush::~KisToolSelectBrush() -{ -} - -void KisToolSelectBrush::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectBrush::initPaint(KisEvent* /*e*/) -{ - if (!m_currentImage || !m_currentImage->activeDevice()) return; - - m_mode = PAINT; - m_dragDist = 0; - - // Create painter - KisPaintDeviceSP dev = m_currentImage->activeDevice(); - if (m_painter) - delete m_painter; - bool hasSelection = dev->hasSelection(); - if (m_currentImage->undo()) m_transaction = new KisSelectedTransaction(i18n("Selection Brush"), dev); - if(! hasSelection) - { - dev->selection()->clear(); - dev->emitSelectionChanged(); - } - KisSelectionSP selection = dev->selection(); - - m_target = selection; - m_painter = new KisPainter(selection.data()); - TQ_CHECK_PTR(m_painter); - m_painter->setPaintColor(KisColor(TQt::black, selection->colorSpace())); - m_painter->setBrush(m_subject->currentBrush()); - m_painter->setOpacity(OPACITY_OPAQUE);//m_subject->fgColor().colorSpace()->intensity8(m_subject->fgColor().data())); - m_painter->setCompositeOp(COMPOSITE_OVER); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, painter()); - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - - // Set the cursor -- ideally. this should be a mask created from the brush, - // now that X11 can handle colored cursors. -#if 0 - // Setting cursors has no effect until the tool is selected again; this - // should be fixed. - setCursor(KisCursor::brushCursor()); -#endif -} - -void KisToolSelectBrush::endPaint() -{ - m_mode = HOVER; - if (m_currentImage && m_currentImage->activeLayer()) { - if (m_currentImage->undo() && m_painter) { - // If painting in mouse release, make sure painter - // is destructed or end()ed - m_currentImage->undoAdapter()->addCommand(m_transaction); - } - delete m_painter; - m_painter = 0; - if (m_currentImage->activeDevice()) - m_currentImage->activeDevice()->emitSelectionChanged(); - notifyModified(); - } -} - - -void KisToolSelectBrush::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Selection Brush"), - "tool_brush_selection", "Ctrl+Shift+B", this, - TQT_SLOT(activate()), collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Paint a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectBrush::createOptionWidget(TQWidget* parent) -{ - Q_UNUSED(parent); - // Commented out due to the fact that this doesn't actually work if you change the action -#if 0 - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Selection Brush")); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -#endif - return 0; -} - -TQWidget* KisToolSelectBrush::optionWidget() -{ - return m_optWidget; -} - -#include "kis_tool_select_brush.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp new file mode 100644 index 00000000..ba80434f --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp @@ -0,0 +1,168 @@ +/* + * kis_tool_select_brush.cpp - part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_brush.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_selection.h" +#include "kis_tool_select_brush.h" +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_view.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" + +KisToolSelectBrush::KisToolSelectBrush() + : super(i18n("SelectBrush")) +{ + setName("tool_select_brush"); + m_optWidget = 0; + setCursor(KisCursor::load("tool_brush_selection_cursor.png", 5, 5)); + m_paintOnSelection = true; +} + +KisToolSelectBrush::~KisToolSelectBrush() +{ +} + +void KisToolSelectBrush::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectBrush::initPaint(KisEvent* /*e*/) +{ + if (!m_currentImage || !m_currentImage->activeDevice()) return; + + m_mode = PAINT; + m_dragDist = 0; + + // Create painter + KisPaintDeviceSP dev = m_currentImage->activeDevice(); + if (m_painter) + delete m_painter; + bool hasSelection = dev->hasSelection(); + if (m_currentImage->undo()) m_transaction = new KisSelectedTransaction(i18n("Selection Brush"), dev); + if(! hasSelection) + { + dev->selection()->clear(); + dev->emitSelectionChanged(); + } + KisSelectionSP selection = dev->selection(); + + m_target = selection; + m_painter = new KisPainter(selection.data()); + TQ_CHECK_PTR(m_painter); + m_painter->setPaintColor(KisColor(TQt::black, selection->colorSpace())); + m_painter->setBrush(m_subject->currentBrush()); + m_painter->setOpacity(OPACITY_OPAQUE);//m_subject->fgColor().colorSpace()->intensity8(m_subject->fgColor().data())); + m_painter->setCompositeOp(COMPOSITE_OVER); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, painter()); + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + + // Set the cursor -- ideally. this should be a mask created from the brush, + // now that X11 can handle colored cursors. +#if 0 + // Setting cursors has no effect until the tool is selected again; this + // should be fixed. + setCursor(KisCursor::brushCursor()); +#endif +} + +void KisToolSelectBrush::endPaint() +{ + m_mode = HOVER; + if (m_currentImage && m_currentImage->activeLayer()) { + if (m_currentImage->undo() && m_painter) { + // If painting in mouse release, make sure painter + // is destructed or end()ed + m_currentImage->undoAdapter()->addCommand(m_transaction); + } + delete m_painter; + m_painter = 0; + if (m_currentImage->activeDevice()) + m_currentImage->activeDevice()->emitSelectionChanged(); + notifyModified(); + } +} + + +void KisToolSelectBrush::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Selection Brush"), + "tool_brush_selection", "Ctrl+Shift+B", this, + TQT_SLOT(activate()), collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Paint a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectBrush::createOptionWidget(TQWidget* parent) +{ + Q_UNUSED(parent); + // Commented out due to the fact that this doesn't actually work if you change the action +#if 0 + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Selection Brush")); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +#endif + return 0; +} + +TQWidget* KisToolSelectBrush::optionWidget() +{ + return m_optWidget; +} + +#include "kis_tool_select_brush.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc deleted file mode 100644 index 1a4932b7..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - * kis_tool_select_contiguous - part of Krayon^WChalk - * - * Copyright (c) 1999 Michael Koch - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_select_contiguous.h" - -KisToolSelectContiguous::KisToolSelectContiguous() : super(i18n("Contiguous Select")) -{ - setName("tool_select_contiguous"); - m_subject = 0; - m_optWidget = 0; - m_fuzziness = 20; - m_sampleMerged = false; - m_selectAction = SELECTION_ADD; - - setCursor(KisCursor::load("tool_contiguous_selection_cursor.png", 6, 6)); -} - -KisToolSelectContiguous::~KisToolSelectContiguous() -{ -} - -void KisToolSelectContiguous::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectContiguous::buttonPress(KisButtonPressEvent * e) -{ - if (m_subject) { - - KisImageSP img; - KisPaintDeviceSP dev; - TQPoint pos; - - if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) - return; - - if (!(img = m_subject->currentImg())) - return; - - dev = img->activeDevice(); - - if (!dev || !img->activeLayer()->visible()) - return; - - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - - pos = TQPoint(e->pos().floorX(), e->pos().floorY()); - - KisFillPainter fillpainter(dev); - fillpainter.setFillThreshold(m_fuzziness); - fillpainter.setSampleMerged(m_sampleMerged); - KisSelectionSP selection = fillpainter.createFloodSelection(pos.x(), pos.y()); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Contiguous Area Selection"), dev); - - if (!dev->hasSelection()) { - dev->selection()->clear(); - if(m_selectAction==SELECTION_SUBTRACT) - selection->invert(); - } - - switch (m_selectAction) { - case SELECTION_SUBTRACT: - dev->subtractSelection(selection); - break; - case SELECTION_ADD: - default: - dev->addSelection(selection); - break; - - } - - dev->setDirty(selection->selectedRect()); // A bit too wide, but that's not that bad - dev->emitSelectionChanged(); - - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - -} - -void KisToolSelectContiguous::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Contiguous Area Selection"), - "tool_contiguous_selection" , - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Select a contiguous area")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolSelectContiguous::update(KisCanvasSubject *subject) -{ - super::update(subject); - m_subject = subject; -} - -void KisToolSelectContiguous::slotSetFuzziness(int fuzziness) -{ - m_fuzziness = fuzziness; -} - - -void KisToolSelectContiguous::slotSetAction(int action) -{ - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -// XXX: Fix cursors when then are done. -// switch(m_selectAction) { -// case SELECTION_ADD: -// m_subject->setCanvasCursor(KisCursor::pickerPlusCursor()); -// break; -// case SELECTION_SUBTRACT: -// m_subject->setCanvasCursor(KisCursor::pickerMinusCursor()); -// }; -} - - -TQWidget* KisToolSelectContiguous::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Contiguous Area Selection")); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->setSpacing( 6 ); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQHBoxLayout * hbox = new TQHBoxLayout(l); - TQ_CHECK_PTR(hbox); - - TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); - hbox->addWidget(lbl); - - KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); - TQ_CHECK_PTR(input); - - input->setRange(0, 200, 10, true); - input->setValue(20); - hbox->addWidget(input); - connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); - - TQCheckBox* samplemerged = new TQCheckBox(i18n("Sample merged"), m_optWidget); - l->addWidget( samplemerged ); - samplemerged->setChecked(m_sampleMerged); - connect(samplemerged, TQT_SIGNAL(stateChanged(int)), - this, TQT_SLOT(slotSetSampleMerged(int))); - - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectContiguous::optionWidget() -{ - return m_optWidget; -} - -void KisToolSelectContiguous::slotSetSampleMerged(int state) -{ - if (state == TQButton::NoChange) - return; - m_sampleMerged = (state == TQButton::On); -} - -#include "kis_tool_select_contiguous.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp new file mode 100644 index 00000000..1a4932b7 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp @@ -0,0 +1,234 @@ +/* + * kis_tool_select_contiguous - part of Krayon^WChalk + * + * Copyright (c) 1999 Michael Koch + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_select_contiguous.h" + +KisToolSelectContiguous::KisToolSelectContiguous() : super(i18n("Contiguous Select")) +{ + setName("tool_select_contiguous"); + m_subject = 0; + m_optWidget = 0; + m_fuzziness = 20; + m_sampleMerged = false; + m_selectAction = SELECTION_ADD; + + setCursor(KisCursor::load("tool_contiguous_selection_cursor.png", 6, 6)); +} + +KisToolSelectContiguous::~KisToolSelectContiguous() +{ +} + +void KisToolSelectContiguous::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectContiguous::buttonPress(KisButtonPressEvent * e) +{ + if (m_subject) { + + KisImageSP img; + KisPaintDeviceSP dev; + TQPoint pos; + + if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) + return; + + if (!(img = m_subject->currentImg())) + return; + + dev = img->activeDevice(); + + if (!dev || !img->activeLayer()->visible()) + return; + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + + pos = TQPoint(e->pos().floorX(), e->pos().floorY()); + + KisFillPainter fillpainter(dev); + fillpainter.setFillThreshold(m_fuzziness); + fillpainter.setSampleMerged(m_sampleMerged); + KisSelectionSP selection = fillpainter.createFloodSelection(pos.x(), pos.y()); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Contiguous Area Selection"), dev); + + if (!dev->hasSelection()) { + dev->selection()->clear(); + if(m_selectAction==SELECTION_SUBTRACT) + selection->invert(); + } + + switch (m_selectAction) { + case SELECTION_SUBTRACT: + dev->subtractSelection(selection); + break; + case SELECTION_ADD: + default: + dev->addSelection(selection); + break; + + } + + dev->setDirty(selection->selectedRect()); // A bit too wide, but that's not that bad + dev->emitSelectionChanged(); + + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + +} + +void KisToolSelectContiguous::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Contiguous Area Selection"), + "tool_contiguous_selection" , + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Select a contiguous area")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolSelectContiguous::update(KisCanvasSubject *subject) +{ + super::update(subject); + m_subject = subject; +} + +void KisToolSelectContiguous::slotSetFuzziness(int fuzziness) +{ + m_fuzziness = fuzziness; +} + + +void KisToolSelectContiguous::slotSetAction(int action) +{ + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +// XXX: Fix cursors when then are done. +// switch(m_selectAction) { +// case SELECTION_ADD: +// m_subject->setCanvasCursor(KisCursor::pickerPlusCursor()); +// break; +// case SELECTION_SUBTRACT: +// m_subject->setCanvasCursor(KisCursor::pickerMinusCursor()); +// }; +} + + +TQWidget* KisToolSelectContiguous::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Contiguous Area Selection")); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->setSpacing( 6 ); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQHBoxLayout * hbox = new TQHBoxLayout(l); + TQ_CHECK_PTR(hbox); + + TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); + hbox->addWidget(lbl); + + KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); + TQ_CHECK_PTR(input); + + input->setRange(0, 200, 10, true); + input->setValue(20); + hbox->addWidget(input); + connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); + + TQCheckBox* samplemerged = new TQCheckBox(i18n("Sample merged"), m_optWidget); + l->addWidget( samplemerged ); + samplemerged->setChecked(m_sampleMerged); + connect(samplemerged, TQT_SIGNAL(stateChanged(int)), + this, TQT_SLOT(slotSetSampleMerged(int))); + + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectContiguous::optionWidget() +{ + return m_optWidget; +} + +void KisToolSelectContiguous::slotSetSampleMerged(int state) +{ + if (state == TQButton::NoChange) + return; + m_sampleMerged = (state == TQButton::On); +} + +#include "kis_tool_select_contiguous.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc deleted file mode 100644 index def162ef..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc +++ /dev/null @@ -1,321 +0,0 @@ -/* - * kis_tool_select_elliptical.cc -- part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_autobrush_resource.h" -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_painter.h" -#include "kis_tool_select_elliptical.h" -#include "kis_layer.h" -#include "kis_undo_adapter.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectElliptical::KisToolSelectElliptical() - : super(i18n("Elliptical Select")) -{ - setName("tool_select_elliptical"); - setCursor(KisCursor::load("tool_elliptical_selection_cursor.png", 6, 6)); - - m_subject = 0; - m_selecting = false; - m_centerPos = KisPoint(0, 0); - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectElliptical::~KisToolSelectElliptical() -{ -} - -void KisToolSelectElliptical::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectElliptical::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectElliptical::paint(KisCanvasPainter& gc) -{ - if (m_selecting) - paintOutline(gc, TQRect()); -} - -void KisToolSelectElliptical::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_selecting) - paintOutline(gc, rc); -} - -void KisToolSelectElliptical::clearSelection() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - Q_ASSERT(controller); - -// if (img && img->floatingSelection().data() != 0) { -// img->unsetFloatingSelection(); -// controller->canvas()->update(); -// } - - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_selecting = false; - } -} - -void KisToolSelectElliptical::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - clearSelection(); - m_startPos = m_endPos = m_centerPos = e->pos(); - m_selecting = true; - paintOutline(); - } - } -} - -void KisToolSelectElliptical::move(KisMoveEvent *e) -{ - if (m_subject && m_selecting) { - paintOutline(); - // move (alt) or resize ellipse - if (e->state() & TQt::AltButton) { - KisPoint trans = e->pos() - m_endPos; - m_startPos += trans; - m_endPos += trans; - } else { - KisPoint diag = e->pos() - (e->state() & TQt::ControlButton - ? m_centerPos : m_startPos); - // circle? - if (e->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (e->state() & TQt::ControlButton) { - m_startPos = m_centerPos - diag; - m_endPos = m_centerPos + diag; - } else { - m_endPos = m_startPos + diag; - } - } - paintOutline(); - m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, - (m_startPos.y() + m_endPos.y()) / 2); - } -} - -void KisToolSelectElliptical::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_selecting && e->button() == Qt::LeftButton) { - - paintOutline(); - - if (m_startPos == m_endPos) { - clearSelection(); - } else { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - if (m_endPos.y() < 0) - m_endPos.setY(0); - - if (m_endPos.y() > img->height()) - m_endPos.setY(img->height()); - - if (m_endPos.x() < 0) - m_endPos.setX(0); - - if (m_endPos.x() > img->width()) - m_endPos.setX(img->width()); - - if (img && img->activeDevice()) { - KisPaintDeviceSP dev = img->activeDevice(); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Elliptical Selection"), dev); - - bool hasSelection = dev->hasSelection(); - if(! hasSelection) - { - dev->selection()->clear(); - if(m_selectAction==SELECTION_SUBTRACT) - dev->selection()->invert(); - } - TQRect rc( m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); - rc = rc.normalize(); - - KisSelectionSP tmpSel = new KisSelection(dev); - KisAutobrushCircleShape shape(rc.width(),rc.height(), 1, 1); - TQ_UINT8 value; - for (int y = 0; y <= rc.height(); y++) - for (int x = 0; x <= rc.width(); x++) - { - value = MAX_SELECTED - shape.valueAt(x,y); - tmpSel->setSelected( x+rc.x(), y+rc.y(), value); - } - switch(m_selectAction) - { - case SELECTION_ADD: - dev->addSelection(tmpSel); - break; - case SELECTION_SUBTRACT: - dev->subtractSelection(tmpSel); - break; - } - - if(hasSelection) { - dev->setDirty(rc); - dev->emitSelectionChanged(rc); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - } - m_selecting = false; - } -} - -void KisToolSelectElliptical::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolSelectElliptical::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::DotLine); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_startPos).floorTQPoint(); - end = controller->windowToView(m_endPos).floorTQPoint(); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawEllipse(TQRect(start, end)); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolSelectElliptical::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -void KisToolSelectElliptical::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Elliptical Selection"), - "tool_elliptical_selection" , - TQt::Key_J, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Select an elliptical area")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectElliptical::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Elliptical Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectElliptical::optionWidget() -{ - return m_optWidget; -} - - - -#include "kis_tool_select_elliptical.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp new file mode 100644 index 00000000..f85da332 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp @@ -0,0 +1,321 @@ +/* + * kis_tool_select_elliptical.cpp -- part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_autobrush_resource.h" +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_painter.h" +#include "kis_tool_select_elliptical.h" +#include "kis_layer.h" +#include "kis_undo_adapter.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectElliptical::KisToolSelectElliptical() + : super(i18n("Elliptical Select")) +{ + setName("tool_select_elliptical"); + setCursor(KisCursor::load("tool_elliptical_selection_cursor.png", 6, 6)); + + m_subject = 0; + m_selecting = false; + m_centerPos = KisPoint(0, 0); + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectElliptical::~KisToolSelectElliptical() +{ +} + +void KisToolSelectElliptical::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectElliptical::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectElliptical::paint(KisCanvasPainter& gc) +{ + if (m_selecting) + paintOutline(gc, TQRect()); +} + +void KisToolSelectElliptical::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_selecting) + paintOutline(gc, rc); +} + +void KisToolSelectElliptical::clearSelection() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + Q_ASSERT(controller); + +// if (img && img->floatingSelection().data() != 0) { +// img->unsetFloatingSelection(); +// controller->canvas()->update(); +// } + + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_selecting = false; + } +} + +void KisToolSelectElliptical::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + clearSelection(); + m_startPos = m_endPos = m_centerPos = e->pos(); + m_selecting = true; + paintOutline(); + } + } +} + +void KisToolSelectElliptical::move(KisMoveEvent *e) +{ + if (m_subject && m_selecting) { + paintOutline(); + // move (alt) or resize ellipse + if (e->state() & TQt::AltButton) { + KisPoint trans = e->pos() - m_endPos; + m_startPos += trans; + m_endPos += trans; + } else { + KisPoint diag = e->pos() - (e->state() & TQt::ControlButton + ? m_centerPos : m_startPos); + // circle? + if (e->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (e->state() & TQt::ControlButton) { + m_startPos = m_centerPos - diag; + m_endPos = m_centerPos + diag; + } else { + m_endPos = m_startPos + diag; + } + } + paintOutline(); + m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, + (m_startPos.y() + m_endPos.y()) / 2); + } +} + +void KisToolSelectElliptical::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_selecting && e->button() == Qt::LeftButton) { + + paintOutline(); + + if (m_startPos == m_endPos) { + clearSelection(); + } else { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + if (m_endPos.y() < 0) + m_endPos.setY(0); + + if (m_endPos.y() > img->height()) + m_endPos.setY(img->height()); + + if (m_endPos.x() < 0) + m_endPos.setX(0); + + if (m_endPos.x() > img->width()) + m_endPos.setX(img->width()); + + if (img && img->activeDevice()) { + KisPaintDeviceSP dev = img->activeDevice(); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Elliptical Selection"), dev); + + bool hasSelection = dev->hasSelection(); + if(! hasSelection) + { + dev->selection()->clear(); + if(m_selectAction==SELECTION_SUBTRACT) + dev->selection()->invert(); + } + TQRect rc( m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); + rc = rc.normalize(); + + KisSelectionSP tmpSel = new KisSelection(dev); + KisAutobrushCircleShape shape(rc.width(),rc.height(), 1, 1); + TQ_UINT8 value; + for (int y = 0; y <= rc.height(); y++) + for (int x = 0; x <= rc.width(); x++) + { + value = MAX_SELECTED - shape.valueAt(x,y); + tmpSel->setSelected( x+rc.x(), y+rc.y(), value); + } + switch(m_selectAction) + { + case SELECTION_ADD: + dev->addSelection(tmpSel); + break; + case SELECTION_SUBTRACT: + dev->subtractSelection(tmpSel); + break; + } + + if(hasSelection) { + dev->setDirty(rc); + dev->emitSelectionChanged(rc); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + } + m_selecting = false; + } +} + +void KisToolSelectElliptical::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolSelectElliptical::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::DotLine); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_startPos).floorTQPoint(); + end = controller->windowToView(m_endPos).floorTQPoint(); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawEllipse(TQRect(start, end)); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolSelectElliptical::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +void KisToolSelectElliptical::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Elliptical Selection"), + "tool_elliptical_selection" , + TQt::Key_J, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Select an elliptical area")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectElliptical::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Elliptical Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectElliptical::optionWidget() +{ + return m_optWidget; +} + + + +#include "kis_tool_select_elliptical.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc deleted file mode 100644 index af7f8d84..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* - * kis_tool_select_brush.cc - part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_brush.h" -#include "kis_layer.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_selection.h" -#include "kis_tool_select_eraser.h" -#include "kis_types.h" -#include "kis_view.h" -#include "kis_selection_options.h" - -KisToolSelectEraser::KisToolSelectEraser() - : super(i18n("SelectEraser")) -{ - setName("tool_select_eraser"); - setCursor(KisCursor::load("tool_eraser_selection_cursor.png", 5, 5)); - m_optWidget = 0; - m_paintOnSelection = true; -} - -KisToolSelectEraser::~KisToolSelectEraser() -{ -} - -void KisToolSelectEraser::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectEraser::initPaint(KisEvent */*e*/) -{ - if (!m_currentImage || !m_currentImage->activeDevice()) return; - - m_mode = PAINT; - m_dragDist = 0; - - // Create painter - KisPaintDeviceSP dev = m_currentImage->activeDevice(); - - if (dev == 0) return; - - if (m_painter) - delete m_painter; - if(! dev->hasSelection()) - { - dev->selection()->clear(); - dev->emitSelectionChanged(); - } - KisSelectionSP selection = dev->selection(); - - m_target = selection; - m_painter = new KisPainter(selection.data()); - TQ_CHECK_PTR(m_painter); - m_painter->beginTransaction(i18n("Selection Eraser")); - m_painter->setPaintColor(KisColor(TQt::white, selection->colorSpace())); - m_painter->setBrush(m_subject->currentBrush()); - m_painter->setOpacity(OPACITY_OPAQUE); - m_painter->setCompositeOp(COMPOSITE_ERASE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("eraser", 0, painter()); - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - - // Set the cursor -- ideally. this should be a mask created from the brush, - // now that X11 can handle colored cursors. -#if 0 - // Setting cursors has no effect until the tool is selected again; this - // should be fixed. - setCursor(KisCursor::eraserCursor()); -#endif -} - -void KisToolSelectEraser::endPaint() { - super::endPaint(); - if (m_currentImage && m_currentImage->activeDevice()) - m_currentImage->activeDevice()->emitSelectionChanged(); -} -void KisToolSelectEraser::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("Selection &Eraser"), - "tool_eraser_selection", "Ctrl+Shift+E", this, - TQT_SLOT(activate()), collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Erase parts of a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectEraser::createOptionWidget(TQWidget* parent) -{ - Q_UNUSED(parent); - // Commented out due to the fact that this doesn't actually work if you change the action -#if 0 - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Selection Eraser")); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -#endif - return 0; -} - -TQWidget* KisToolSelectEraser::optionWidget() -{ - return m_optWidget; -} - -#include "kis_tool_select_eraser.moc" - diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp new file mode 100644 index 00000000..9cfef0a8 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp @@ -0,0 +1,156 @@ +/* + * kis_tool_select_brush.cpp - part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_brush.h" +#include "kis_layer.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_selection.h" +#include "kis_tool_select_eraser.h" +#include "kis_types.h" +#include "kis_view.h" +#include "kis_selection_options.h" + +KisToolSelectEraser::KisToolSelectEraser() + : super(i18n("SelectEraser")) +{ + setName("tool_select_eraser"); + setCursor(KisCursor::load("tool_eraser_selection_cursor.png", 5, 5)); + m_optWidget = 0; + m_paintOnSelection = true; +} + +KisToolSelectEraser::~KisToolSelectEraser() +{ +} + +void KisToolSelectEraser::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectEraser::initPaint(KisEvent */*e*/) +{ + if (!m_currentImage || !m_currentImage->activeDevice()) return; + + m_mode = PAINT; + m_dragDist = 0; + + // Create painter + KisPaintDeviceSP dev = m_currentImage->activeDevice(); + + if (dev == 0) return; + + if (m_painter) + delete m_painter; + if(! dev->hasSelection()) + { + dev->selection()->clear(); + dev->emitSelectionChanged(); + } + KisSelectionSP selection = dev->selection(); + + m_target = selection; + m_painter = new KisPainter(selection.data()); + TQ_CHECK_PTR(m_painter); + m_painter->beginTransaction(i18n("Selection Eraser")); + m_painter->setPaintColor(KisColor(TQt::white, selection->colorSpace())); + m_painter->setBrush(m_subject->currentBrush()); + m_painter->setOpacity(OPACITY_OPAQUE); + m_painter->setCompositeOp(COMPOSITE_ERASE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("eraser", 0, painter()); + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + + // Set the cursor -- ideally. this should be a mask created from the brush, + // now that X11 can handle colored cursors. +#if 0 + // Setting cursors has no effect until the tool is selected again; this + // should be fixed. + setCursor(KisCursor::eraserCursor()); +#endif +} + +void KisToolSelectEraser::endPaint() { + super::endPaint(); + if (m_currentImage && m_currentImage->activeDevice()) + m_currentImage->activeDevice()->emitSelectionChanged(); +} +void KisToolSelectEraser::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("Selection &Eraser"), + "tool_eraser_selection", "Ctrl+Shift+E", this, + TQT_SLOT(activate()), collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Erase parts of a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectEraser::createOptionWidget(TQWidget* parent) +{ + Q_UNUSED(parent); + // Commented out due to the fact that this doesn't actually work if you change the action +#if 0 + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Selection Eraser")); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +#endif + return 0; +} + +TQWidget* KisToolSelectEraser::optionWidget() +{ + return m_optWidget; +} + +#include "kis_tool_select_eraser.moc" + diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc deleted file mode 100644 index 7f526736..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc +++ /dev/null @@ -1,295 +0,0 @@ -/* - * kis_tool_select_freehand.h - part of Krayon^WChalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kis_selected_transaction.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectOutline::KisToolSelectOutline() - : super(i18n("Select Outline")) -{ - setName("tool_select_outline"); - setCursor(KisCursor::load("tool_outline_selection_cursor.png", 5, 5)); - - m_subject = 0; - m_dragging = false; - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectOutline::~KisToolSelectOutline() -{ -} - -void KisToolSelectOutline::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectOutline::update (KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectOutline::buttonPress(KisButtonPressEvent *event) -{ - if (event->button() == Qt::LeftButton) { - m_dragging = true; - - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.clear(); - m_points.append(m_dragStart); - } -} - -void KisToolSelectOutline::move(KisMoveEvent *event) -{ - if (m_dragging) { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - m_points.append (m_dragEnd); - // draw new lines on canvas - draw(); - } -} - -void KisToolSelectOutline::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - deactivate(); - - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice()) { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = img->activeDevice(); - bool hasSelection = dev->hasSelection(); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Outline Selection"), dev); - KisSelectionSP selection = dev->selection(); - - if (!hasSelection) { - selection->clear(); - } - - KisPainter painter(selection.data()); - - painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.setStrokeStyle(KisPainter::StrokeStyleNone); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(OPACITY_OPAQUE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); - painter.setPaintOp(op); // And now the painter owns the op and will destroy it. - - switch (m_selectAction) { - case SELECTION_ADD: - painter.setCompositeOp(COMPOSITE_OVER); - break; - case SELECTION_SUBTRACT: - painter.setCompositeOp(COMPOSITE_SUBTRACT); - break; - default: - break; - } - - painter.paintPolygon(m_points); - - - if(hasSelection) { - TQRect dirty(painter.dirtyRect()); - dev->setDirty(dirty); - dev->emitSelectionChanged(dirty); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - - m_points.clear(); - } -} - -void KisToolSelectOutline::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolSelectOutline::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolSelectOutline::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolSelectOutline::draw(KisCanvasPainter& gc) -{ - if (!m_subject) - return; - - if (m_dragging && !m_points.empty()) { - TQPen pen(TQt::white, 0, TQt::DotLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } -} - -void KisToolSelectOutline::deactivate() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - TQPen pen(TQt::white, 0, TQt::DotLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - -void KisToolSelectOutline::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Outline Selection"), - "tool_outline_selection", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Select an outline")); - m_ownAction = true; - } -} - - -TQWidget* KisToolSelectOutline::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Outline Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectOutline::optionWidget() -{ - return m_optWidget; -} - -void KisToolSelectOutline::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -#include "kis_tool_select_outline.moc" - diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp new file mode 100644 index 00000000..7f526736 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp @@ -0,0 +1,295 @@ +/* + * kis_tool_select_freehand.h - part of Krayon^WChalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kis_selected_transaction.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectOutline::KisToolSelectOutline() + : super(i18n("Select Outline")) +{ + setName("tool_select_outline"); + setCursor(KisCursor::load("tool_outline_selection_cursor.png", 5, 5)); + + m_subject = 0; + m_dragging = false; + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectOutline::~KisToolSelectOutline() +{ +} + +void KisToolSelectOutline::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectOutline::update (KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectOutline::buttonPress(KisButtonPressEvent *event) +{ + if (event->button() == Qt::LeftButton) { + m_dragging = true; + + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.clear(); + m_points.append(m_dragStart); + } +} + +void KisToolSelectOutline::move(KisMoveEvent *event) +{ + if (m_dragging) { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + m_points.append (m_dragEnd); + // draw new lines on canvas + draw(); + } +} + +void KisToolSelectOutline::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + deactivate(); + + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice()) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = img->activeDevice(); + bool hasSelection = dev->hasSelection(); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Outline Selection"), dev); + KisSelectionSP selection = dev->selection(); + + if (!hasSelection) { + selection->clear(); + } + + KisPainter painter(selection.data()); + + painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); + painter.setFillStyle(KisPainter::FillStyleForegroundColor); + painter.setStrokeStyle(KisPainter::StrokeStyleNone); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(OPACITY_OPAQUE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); + painter.setPaintOp(op); // And now the painter owns the op and will destroy it. + + switch (m_selectAction) { + case SELECTION_ADD: + painter.setCompositeOp(COMPOSITE_OVER); + break; + case SELECTION_SUBTRACT: + painter.setCompositeOp(COMPOSITE_SUBTRACT); + break; + default: + break; + } + + painter.paintPolygon(m_points); + + + if(hasSelection) { + TQRect dirty(painter.dirtyRect()); + dev->setDirty(dirty); + dev->emitSelectionChanged(dirty); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + + m_points.clear(); + } +} + +void KisToolSelectOutline::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolSelectOutline::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolSelectOutline::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolSelectOutline::draw(KisCanvasPainter& gc) +{ + if (!m_subject) + return; + + if (m_dragging && !m_points.empty()) { + TQPen pen(TQt::white, 0, TQt::DotLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } +} + +void KisToolSelectOutline::deactivate() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + TQPen pen(TQt::white, 0, TQt::DotLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + +void KisToolSelectOutline::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Outline Selection"), + "tool_outline_selection", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Select an outline")); + m_ownAction = true; + } +} + + +TQWidget* KisToolSelectOutline::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Outline Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectOutline::optionWidget() +{ + return m_optWidget; +} + +void KisToolSelectOutline::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +#include "kis_tool_select_outline.moc" + diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc deleted file mode 100644 index 8d89eea2..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc +++ /dev/null @@ -1,315 +0,0 @@ -/* - * kis_tool_select_polygonal.h - part of Krayon^WChalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kis_selected_transaction.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectPolygonal::KisToolSelectPolygonal() - : super(i18n("Select Polygonal")) -{ - setName("tool_select_polygonal"); - setCursor(KisCursor::load("tool_polygonal_selection_cursor.png", 6, 6)); - - m_subject = 0; - m_dragging = false; - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectPolygonal::~KisToolSelectPolygonal() -{ -} - -void KisToolSelectPolygonal::activate() -{ - m_points.clear(); - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectPolygonal::deactivate() -{ - draw(); - m_points.clear(); - m_dragging = false; -} - - -void KisToolSelectPolygonal::update (KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectPolygonal::buttonPress(KisButtonPressEvent *event) -{ - if (event->button() == Qt::LeftButton) { - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - draw(); - } - } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { - finish(); - } -} - - -void KisToolSelectPolygonal::doubleClick( KisDoubleClickEvent * ) -{ - finish(); -} - -void KisToolSelectPolygonal::finish() -{ - // erase old lines on canvas - draw(); - m_dragging = false; - - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice()) { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = img->activeDevice(); - - bool hasSelection = dev->hasSelection(); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Polygonal Selection"), dev); - KisSelectionSP selection = dev->selection(); - - if (!hasSelection) - { - selection->clear(); - } - - KisPainter painter(selection.data()); - painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.setStrokeStyle(KisPainter::StrokeStyleNone); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(OPACITY_OPAQUE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); - painter.setPaintOp(op); // And now the painter owns the op and will destroy it. - - switch(m_selectAction) - { - case SELECTION_ADD: - painter.setCompositeOp(COMPOSITE_OVER); - break; - case SELECTION_SUBTRACT: - painter.setCompositeOp(COMPOSITE_SUBTRACT); - break; - default: - break; - } - - painter.paintPolygon(m_points); - - if(hasSelection) { - TQRect rect(painter.dirtyRect()); - dev->setDirty(rect); - dev->emitSelectionChanged(rect); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - - m_points.clear(); - -} - -void KisToolSelectPolygonal::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - draw(); - } -} - -void KisToolSelectPolygonal::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - } - - if (m_dragging && event->button() == Qt::RightButton) { - - } -} - -void KisToolSelectPolygonal::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolSelectPolygonal::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolSelectPolygonal::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolSelectPolygonal::draw(KisCanvasPainter& gc) -{ - if (!m_subject) - return; - - TQPen pen(TQt::white, 0, TQt::DotLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - - -void KisToolSelectPolygonal::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Polygonal Selection"), - "tool_polygonal_selection" , - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Select a polygonal area")); - m_ownAction = true; - } -} - - -TQWidget* KisToolSelectPolygonal::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Polygonal Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectPolygonal::optionWidget() -{ - return m_optWidget; -} - -void KisToolSelectPolygonal::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - - - -#include "kis_tool_select_polygonal.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp new file mode 100644 index 00000000..8d89eea2 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp @@ -0,0 +1,315 @@ +/* + * kis_tool_select_polygonal.h - part of Krayon^WChalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kis_selected_transaction.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectPolygonal::KisToolSelectPolygonal() + : super(i18n("Select Polygonal")) +{ + setName("tool_select_polygonal"); + setCursor(KisCursor::load("tool_polygonal_selection_cursor.png", 6, 6)); + + m_subject = 0; + m_dragging = false; + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectPolygonal::~KisToolSelectPolygonal() +{ +} + +void KisToolSelectPolygonal::activate() +{ + m_points.clear(); + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectPolygonal::deactivate() +{ + draw(); + m_points.clear(); + m_dragging = false; +} + + +void KisToolSelectPolygonal::update (KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectPolygonal::buttonPress(KisButtonPressEvent *event) +{ + if (event->button() == Qt::LeftButton) { + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + draw(); + } + } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { + finish(); + } +} + + +void KisToolSelectPolygonal::doubleClick( KisDoubleClickEvent * ) +{ + finish(); +} + +void KisToolSelectPolygonal::finish() +{ + // erase old lines on canvas + draw(); + m_dragging = false; + + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice()) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = img->activeDevice(); + + bool hasSelection = dev->hasSelection(); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Polygonal Selection"), dev); + KisSelectionSP selection = dev->selection(); + + if (!hasSelection) + { + selection->clear(); + } + + KisPainter painter(selection.data()); + painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); + painter.setFillStyle(KisPainter::FillStyleForegroundColor); + painter.setStrokeStyle(KisPainter::StrokeStyleNone); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(OPACITY_OPAQUE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); + painter.setPaintOp(op); // And now the painter owns the op and will destroy it. + + switch(m_selectAction) + { + case SELECTION_ADD: + painter.setCompositeOp(COMPOSITE_OVER); + break; + case SELECTION_SUBTRACT: + painter.setCompositeOp(COMPOSITE_SUBTRACT); + break; + default: + break; + } + + painter.paintPolygon(m_points); + + if(hasSelection) { + TQRect rect(painter.dirtyRect()); + dev->setDirty(rect); + dev->emitSelectionChanged(rect); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + + m_points.clear(); + +} + +void KisToolSelectPolygonal::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + draw(); + } +} + +void KisToolSelectPolygonal::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + } + + if (m_dragging && event->button() == Qt::RightButton) { + + } +} + +void KisToolSelectPolygonal::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolSelectPolygonal::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolSelectPolygonal::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolSelectPolygonal::draw(KisCanvasPainter& gc) +{ + if (!m_subject) + return; + + TQPen pen(TQt::white, 0, TQt::DotLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + + +void KisToolSelectPolygonal::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Polygonal Selection"), + "tool_polygonal_selection" , + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Select a polygonal area")); + m_ownAction = true; + } +} + + +TQWidget* KisToolSelectPolygonal::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Polygonal Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectPolygonal::optionWidget() +{ + return m_optWidget; +} + +void KisToolSelectPolygonal::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + + + +#include "kis_tool_select_polygonal.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc deleted file mode 100644 index 09d33866..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc +++ /dev/null @@ -1,323 +0,0 @@ - -/* - * kis_tool_select_rectangular.cc -- part of Chalk - * - * Copyright (c) 1999 Michael Koch - * 2001 John Califf - * 2002 Patrick Julien - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_painter.h" -#include "kis_layer.h" -#include "kis_tool_select_rectangular.h" -#include "kis_undo_adapter.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectRectangular::KisToolSelectRectangular() - : super(i18n("Rectangular Select Tool")) -{ - setName("tool_select_rectangular"); - setCursor(KisCursor::load("tool_rectangular_selection_cursor.png", 6, 6)); - m_subject = 0; - m_selecting = false; - m_centerPos = KisPoint(0, 0); - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectRectangular::~KisToolSelectRectangular() -{ -} - -void KisToolSelectRectangular::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectRectangular::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectRectangular::paint(KisCanvasPainter& gc) -{ - if (m_selecting) - paintOutline(gc, TQRect()); -} - -void KisToolSelectRectangular::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_selecting) - paintOutline(gc, rc); -} - -void KisToolSelectRectangular::clearSelection() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - Q_ASSERT(controller); - - m_centerPos = KisPoint(0, 0); - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_selecting = false; - } -} - -void KisToolSelectRectangular::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - clearSelection(); - m_startPos = m_endPos = m_centerPos = e->pos(); - m_selecting = true; - } - } -} - -void KisToolSelectRectangular::move(KisMoveEvent *e) -{ - if (m_subject && m_selecting) { - paintOutline(); - // move (alt) or resize rectangle - if (e->state() & TQt::AltButton) { - KisPoint trans = e->pos() - m_endPos; - m_startPos += trans; - m_endPos += trans; - } else { - KisPoint diag = e->pos() - (e->state() & TQt::ControlButton - ? m_centerPos : m_startPos); - // square? - if (e->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (e->state() & TQt::ControlButton) { - m_startPos = m_centerPos - diag; - m_endPos = m_centerPos + diag; - } else { - m_endPos = m_startPos + diag; - } - } - paintOutline(); - m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, - (m_startPos.y() + m_endPos.y()) / 2); - } -} - -void KisToolSelectRectangular::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_selecting && e->button() == Qt::LeftButton) { - - paintOutline(); - - if (m_startPos == m_endPos) { - clearSelection(); - } else { - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - if (m_endPos.y() < 0) - m_endPos.setY(0); - - if (m_endPos.y() > img->height()) - m_endPos.setY(img->height()); - - if (m_endPos.x() < 0) - m_endPos.setX(0); - - if (m_endPos.x() > img->width()) - m_endPos.setX(img->width()); - if (img && img->activeDevice()) { - - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = img->activeDevice(); - bool hasSelection = dev->hasSelection(); - - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Rectangular Selection"), dev); - KisSelectionSP selection = dev->selection(); - TQRect rc(m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); - rc = rc.normalize(); - - // We don't want the border of the 'rectangle' to be included in our selection - rc.setSize(rc.size() - TQSize(1,1)); - - if(! hasSelection) - { - selection->clear(); - if(m_selectAction==SELECTION_SUBTRACT) - selection->invert(); - } - - KisSelectionSP tmpSel = new KisSelection(dev); - tmpSel->select(rc); - switch(m_selectAction) - { - case SELECTION_ADD: - dev->addSelection(tmpSel); - break; - case SELECTION_SUBTRACT: - dev->subtractSelection(tmpSel); - break; - default: - break; - } - - - if(hasSelection) { - dev->setDirty(rc); - dev->emitSelectionChanged(rc); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - KisCanvasController *controller = m_subject -> canvasController(); - controller -> kiscanvas() -> update(); - - TQApplication::restoreOverrideCursor(); - } - } - - m_selecting = false; - } -} - -void KisToolSelectRectangular::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolSelectRectangular::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::DotLine); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_startPos.floorTQPoint()); - end = controller->windowToView(m_endPos.floorTQPoint()); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(TQRect(start, end)); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolSelectRectangular::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -void KisToolSelectRectangular::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Rectangular Selection"), - "tool_rect_selection", - TQt::Key_R, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Select a rectangular area")); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectRectangular::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Rectangular Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectRectangular::optionWidget() -{ - return m_optWidget; -} - - - - -#include "kis_tool_select_rectangular.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp new file mode 100644 index 00000000..5a6772ba --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp @@ -0,0 +1,323 @@ + +/* + * kis_tool_select_rectangular.cpp -- part of Chalk + * + * Copyright (c) 1999 Michael Koch + * 2001 John Califf + * 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_painter.h" +#include "kis_layer.h" +#include "kis_tool_select_rectangular.h" +#include "kis_undo_adapter.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectRectangular::KisToolSelectRectangular() + : super(i18n("Rectangular Select Tool")) +{ + setName("tool_select_rectangular"); + setCursor(KisCursor::load("tool_rectangular_selection_cursor.png", 6, 6)); + m_subject = 0; + m_selecting = false; + m_centerPos = KisPoint(0, 0); + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectRectangular::~KisToolSelectRectangular() +{ +} + +void KisToolSelectRectangular::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectRectangular::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectRectangular::paint(KisCanvasPainter& gc) +{ + if (m_selecting) + paintOutline(gc, TQRect()); +} + +void KisToolSelectRectangular::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_selecting) + paintOutline(gc, rc); +} + +void KisToolSelectRectangular::clearSelection() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + Q_ASSERT(controller); + + m_centerPos = KisPoint(0, 0); + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_selecting = false; + } +} + +void KisToolSelectRectangular::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + clearSelection(); + m_startPos = m_endPos = m_centerPos = e->pos(); + m_selecting = true; + } + } +} + +void KisToolSelectRectangular::move(KisMoveEvent *e) +{ + if (m_subject && m_selecting) { + paintOutline(); + // move (alt) or resize rectangle + if (e->state() & TQt::AltButton) { + KisPoint trans = e->pos() - m_endPos; + m_startPos += trans; + m_endPos += trans; + } else { + KisPoint diag = e->pos() - (e->state() & TQt::ControlButton + ? m_centerPos : m_startPos); + // square? + if (e->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (e->state() & TQt::ControlButton) { + m_startPos = m_centerPos - diag; + m_endPos = m_centerPos + diag; + } else { + m_endPos = m_startPos + diag; + } + } + paintOutline(); + m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, + (m_startPos.y() + m_endPos.y()) / 2); + } +} + +void KisToolSelectRectangular::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_selecting && e->button() == Qt::LeftButton) { + + paintOutline(); + + if (m_startPos == m_endPos) { + clearSelection(); + } else { + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + if (m_endPos.y() < 0) + m_endPos.setY(0); + + if (m_endPos.y() > img->height()) + m_endPos.setY(img->height()); + + if (m_endPos.x() < 0) + m_endPos.setX(0); + + if (m_endPos.x() > img->width()) + m_endPos.setX(img->width()); + if (img && img->activeDevice()) { + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = img->activeDevice(); + bool hasSelection = dev->hasSelection(); + + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Rectangular Selection"), dev); + KisSelectionSP selection = dev->selection(); + TQRect rc(m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); + rc = rc.normalize(); + + // We don't want the border of the 'rectangle' to be included in our selection + rc.setSize(rc.size() - TQSize(1,1)); + + if(! hasSelection) + { + selection->clear(); + if(m_selectAction==SELECTION_SUBTRACT) + selection->invert(); + } + + KisSelectionSP tmpSel = new KisSelection(dev); + tmpSel->select(rc); + switch(m_selectAction) + { + case SELECTION_ADD: + dev->addSelection(tmpSel); + break; + case SELECTION_SUBTRACT: + dev->subtractSelection(tmpSel); + break; + default: + break; + } + + + if(hasSelection) { + dev->setDirty(rc); + dev->emitSelectionChanged(rc); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + KisCanvasController *controller = m_subject -> canvasController(); + controller -> kiscanvas() -> update(); + + TQApplication::restoreOverrideCursor(); + } + } + + m_selecting = false; + } +} + +void KisToolSelectRectangular::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolSelectRectangular::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::DotLine); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_startPos.floorTQPoint()); + end = controller->windowToView(m_endPos.floorTQPoint()); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(TQRect(start, end)); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolSelectRectangular::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +void KisToolSelectRectangular::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Rectangular Selection"), + "tool_rect_selection", + TQt::Key_R, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Select a rectangular area")); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectRectangular::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Rectangular Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectRectangular::optionWidget() +{ + return m_optWidget; +} + + + + +#include "kis_tool_select_rectangular.moc" diff --git a/chalk/plugins/tools/selectiontools/selection_tools.cc b/chalk/plugins/tools/selectiontools/selection_tools.cc deleted file mode 100644 index 8407a076..00000000 --- a/chalk/plugins/tools/selectiontools/selection_tools.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* - * selection_tools.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "selection_tools.h" - -#include "kis_tool_select_outline.h" -#include "kis_tool_select_polygonal.h" -#include "kis_tool_select_rectangular.h" -#include "kis_tool_select_contiguous.h" -#include "kis_tool_select_elliptical.h" -#include "kis_tool_select_eraser.h" -#include "kis_tool_select_brush.h" -#include "kis_tool_move_selection.h" - -typedef KGenericFactory SelectionToolsFactory; -K_EXPORT_COMPONENT_FACTORY( chalkselectiontools, SelectionToolsFactory( "chalk" ) ) - - -SelectionTools::SelectionTools(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(SelectionToolsFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolSelectOutlineFactory()); - r->add(new KisToolSelectPolygonalFactory()); - r->add(new KisToolSelectRectangularFactory()); - r->add(new KisToolSelectBrushFactory()); - r->add(new KisToolSelectContiguousFactory()); - r->add(new KisToolSelectEllipticalFactory()); - r->add(new KisToolSelectEraserFactory()); - r->add(new KisToolMoveSelectionFactory()); - } -} - -SelectionTools::~SelectionTools() -{ -} - -#include "selection_tools.moc" diff --git a/chalk/plugins/tools/selectiontools/selection_tools.cpp b/chalk/plugins/tools/selectiontools/selection_tools.cpp new file mode 100644 index 00000000..f34a3b34 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/selection_tools.cpp @@ -0,0 +1,77 @@ +/* + * selection_tools.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "selection_tools.h" + +#include "kis_tool_select_outline.h" +#include "kis_tool_select_polygonal.h" +#include "kis_tool_select_rectangular.h" +#include "kis_tool_select_contiguous.h" +#include "kis_tool_select_elliptical.h" +#include "kis_tool_select_eraser.h" +#include "kis_tool_select_brush.h" +#include "kis_tool_move_selection.h" + +typedef KGenericFactory SelectionToolsFactory; +K_EXPORT_COMPONENT_FACTORY( chalkselectiontools, SelectionToolsFactory( "chalk" ) ) + + +SelectionTools::SelectionTools(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(SelectionToolsFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolSelectOutlineFactory()); + r->add(new KisToolSelectPolygonalFactory()); + r->add(new KisToolSelectRectangularFactory()); + r->add(new KisToolSelectBrushFactory()); + r->add(new KisToolSelectContiguousFactory()); + r->add(new KisToolSelectEllipticalFactory()); + r->add(new KisToolSelectEraserFactory()); + r->add(new KisToolMoveSelectionFactory()); + } +} + +SelectionTools::~SelectionTools() +{ +} + +#include "selection_tools.moc" diff --git a/chalk/plugins/tools/tool_crop/Makefile.am b/chalk/plugins/tools/tool_crop/Makefile.am index fe320b84..5bf3c1f6 100644 --- a/chalk/plugins/tools/tool_crop/Makefile.am +++ b/chalk/plugins/tools/tool_crop/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalktoolcrop_la_SOURCES = \ wdg_tool_crop.ui \ - tool_crop.cc \ - kis_tool_crop.cc + tool_crop.cpp \ + kis_tool_crop.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolcrop.la diff --git a/chalk/plugins/tools/tool_crop/kis_tool_crop.cc b/chalk/plugins/tools/tool_crop/kis_tool_crop.cc deleted file mode 100644 index 11a47590..00000000 --- a/chalk/plugins/tools/tool_crop/kis_tool_crop.cc +++ /dev/null @@ -1,925 +0,0 @@ -/* - * kis_tool_crop.cc -- part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2005 Michael Thaler - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_crop.h" -#include "wdg_tool_crop.h" - -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - - - -KisToolCrop::KisToolCrop() - : super(i18n("Crop")) -{ - setName("tool_crop"); - m_cropCursor = KisCursor::load("tool_crop_cursor.png", 6, 6); - setCursor(m_cropCursor); - m_subject = 0; - m_selecting = false; - m_rectCrop = TQRect(0, 0, 0, 0); - m_handleSize = 13; - m_haveCropSelection = false; - m_optWidget = 0; -} - -KisToolCrop::~KisToolCrop() -{ -} - -void KisToolCrop::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolCrop::activate() -{ - super::activate(); - - // No current crop rectangle, try to use the selection of the device to make a rectangle - if (m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) { - KisPaintDeviceSP device = m_subject->currentImg()->activeDevice(); - if (!device->hasSelection()) { - //m_rectCrop = m_subject->currentImg()->bounds(); - //validateSelection(); - m_haveCropSelection = false; - m_selecting = false; - } - else { - - m_rectCrop = device->selection()->selectedRect(); - validateSelection(); - crop(); - } - } -} - -void KisToolCrop::deactivate() -{ - clearRect(); -} - - -void KisToolCrop::paint(KisCanvasPainter& gc) -{ - paintOutlineWithHandles(gc, TQRect()); -} - -void KisToolCrop::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - paintOutlineWithHandles(gc, rc); -} - -void KisToolCrop::clearRect() -{ - kdDebug() << "Clearing\n"; - if (m_subject) { - - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - Q_ASSERT(controller); - - controller->kiscanvas()->update(); - - m_rectCrop = TQRect(0,0,0,0); - - updateWidgetValues(); - m_selecting = false; - } -} - -void KisToolCrop::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - - TQPoint pos = e->pos().floorTQPoint(); - TQRect b = img->bounds(); - - if (pos.x() < b.x()) - pos.setX(b.x()); - else if (pos.x() > b.x() + b.width()) - pos.setX(b.x() + b.width()); - - if (pos.y() < b.y()) - pos.setY(b.y()); - else if (pos.y() > b.y() + b.height()) - pos.setY(b.y() + b.height()); - - m_selecting = true; - - if( !m_haveCropSelection ) //if the selection is not set - { - m_rectCrop = TQRect( pos.x(), pos.y(), 0, 0); - paintOutlineWithHandles(); - } - else - { - KisCanvasController *controller = m_subject->canvasController(); - m_mouseOnHandleType = mouseOnHandle(controller ->windowToView(pos)); - m_dragStart = pos; - } - - updateWidgetValues(); - } - } -} - -void KisToolCrop::move(KisMoveEvent *e) -{ - if ( m_subject && m_subject->currentImg()) - { - if( m_selecting ) //if the user selects - { - if( !m_haveCropSelection ) //if the cropSelection is not yet set - { - paintOutlineWithHandles(); - - m_rectCrop.setBottomRight( e->pos().floorTQPoint()); - - KisImageSP image = m_subject->currentImg(); - - m_rectCrop.setRight( TQMIN(m_rectCrop.right(), image->width())); - m_rectCrop.setBottom( TQMIN(m_rectCrop.bottom(), image->width())); - m_rectCrop = m_rectCrop.normalize(); - - paintOutlineWithHandles(); - } - else //if the crop selection is set - { - m_dragStop = e->pos().floorTQPoint(); - if (m_mouseOnHandleType != None && m_dragStart != m_dragStop ) { - - - TQ_INT32 imageWidth = m_subject->currentImg()->width(); - TQ_INT32 imageHeight = m_subject->currentImg()->height(); - - paintOutlineWithHandles(); - - TQPoint pos = e->pos().floorTQPoint(); - if( m_mouseOnHandleType == Inside ) - { - m_rectCrop.moveBy( ( m_dragStop.x() - m_dragStart.x() ), ( m_dragStop.y() - m_dragStart.y() ) ); - if( m_rectCrop.left() < 0 ) - { - m_rectCrop.moveLeft( 0 ); - } - if( m_rectCrop.right() > imageWidth ) - { - m_rectCrop.moveRight( imageWidth ); - } - if( m_rectCrop.top() < 0 ) - { - m_rectCrop.moveTop( 0 ); - } - if( m_rectCrop.bottom() > imageHeight ) - { - m_rectCrop.moveBottom( imageHeight ); - } - } else if(m_optWidget->boolRatio->isChecked()) - { - TQPoint drag = m_dragStop - m_dragStart; - if( ! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked() ) - { - switch (m_mouseOnHandleType) - { - case (UpperLeft): - { - TQ_INT32 dep = (drag.x() + drag.y()) / 2; - m_rectCrop.setTop( m_rectCrop.top() + dep ); - m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - } - break; - case (LowerRight): - { - TQ_INT32 dep = (drag.x() + drag.y()) / 2; - m_rectCrop.setBottom( m_rectCrop.bottom() + dep ); - m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - break; - } - case (UpperRight): - { - TQ_INT32 dep = (drag.x() - drag.y()) / 2; - m_rectCrop.setTop( m_rectCrop.top() - dep ); - m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - break; - } - case (LowerLeft): - { - TQ_INT32 dep = (drag.x() - drag.y()) / 2; - m_rectCrop.setBottom( m_rectCrop.bottom() - dep ); - m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - break; - } - case (Upper): - m_rectCrop.setTop( pos.y() + m_dy ); - m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); - break; - case (Lower): - m_rectCrop.setBottom( pos.y() + m_dy ); - m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); - break; - case (Left): - m_rectCrop.setLeft( pos.x() + m_dx ); - m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); - break; - case (Right): - m_rectCrop.setRight( pos.x() + m_dx ); - m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); - break; - case (Inside): // never happen - break; - } - } - } else { - if( m_optWidget->boolWidth->isChecked() ) - { - m_rectCrop.setWidth( m_optWidget->intWidth->value() + 1 ); - } else { - switch (m_mouseOnHandleType) - { - case (LowerLeft): - case (Left): - case (UpperLeft): - m_rectCrop.setLeft( pos.x() + m_dx ); - break; - case (Right): - case (UpperRight): - case (LowerRight): - m_rectCrop.setRight( pos.x() + m_dx ); - break; - default: - break; - } - } - if( m_optWidget->boolHeight->isChecked() ) - { - m_rectCrop.setHeight( m_optWidget->intHeight->value() + 1 ); - } else { - switch (m_mouseOnHandleType) - { - case (UpperLeft): - case (Upper): - case (UpperRight): - m_rectCrop.setTop( pos.y() + m_dy ); - break; - case (LowerRight): - case (LowerLeft): - case (Lower): - m_rectCrop.setBottom( pos.y() + m_dy ); - break; - default: - break; - } - } - } - if( m_rectCrop.height() < 0) - { - if( m_mouseOnHandleType == Lower) - m_mouseOnHandleType = Upper; - else if( m_mouseOnHandleType == LowerLeft) - m_mouseOnHandleType = UpperLeft; - else if( m_mouseOnHandleType == LowerRight) - m_mouseOnHandleType = UpperRight; - else if( m_mouseOnHandleType == Upper) - m_mouseOnHandleType = Lower; - else if( m_mouseOnHandleType == UpperLeft) - m_mouseOnHandleType = LowerLeft; - else if( m_mouseOnHandleType == UpperRight) - m_mouseOnHandleType = LowerRight; - } - if( m_rectCrop.width() < 0) - { - if( m_mouseOnHandleType == Right) - m_mouseOnHandleType = Left; - else if( m_mouseOnHandleType == UpperRight) - m_mouseOnHandleType = UpperLeft; - else if( m_mouseOnHandleType == LowerRight) - m_mouseOnHandleType = LowerLeft; - else if( m_mouseOnHandleType == Left) - m_mouseOnHandleType = Right; - else if( m_mouseOnHandleType == UpperLeft) - m_mouseOnHandleType = UpperRight; - else if( m_mouseOnHandleType == LowerLeft) - m_mouseOnHandleType = LowerRight; - } - - m_rectCrop = m_rectCrop.normalize(); - m_rectCrop = m_rectCrop.intersect( TQRect(0,0, imageWidth + 1, imageHeight + 1 ) ); - m_dragStart = e->pos().floorTQPoint(); - paintOutlineWithHandles(); - } - } - updateWidgetValues(); - } - else //if we are not selecting - { - if ( m_haveCropSelection ) //if the crop selection is set - { - KisCanvasController *controller = m_subject->canvasController(); - TQ_INT32 type = mouseOnHandle(controller->windowToView(e->pos().floorTQPoint())); - //set resize cursor if we are on one of the handles - setMoveResizeCursor(type); - } - } - } -} - -void KisToolCrop::updateWidgetValues(bool updateratio) -{ - TQRect r = realRectCrop(); - setOptionWidgetX(r.x()); - setOptionWidgetY(r.y()); - setOptionWidgetWidth(r.width() ); - setOptionWidgetHeight(r.height() ); - if(updateratio && !m_optWidget->boolRatio->isChecked() ) - setOptionWidgetRatio((double)r.width() / (double)r.height() ); -} - -void KisToolCrop::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_subject->currentImg() && m_selecting && e->button() == Qt::LeftButton) { - - m_selecting = false; - m_haveCropSelection = true; - - paintOutlineWithHandles(); - validateSelection(); - paintOutlineWithHandles(); - } -} - -void KisToolCrop::doubleClick(KisDoubleClickEvent *) -{ - if (m_haveCropSelection) crop(); -} - -void KisToolCrop::validateSelection(bool updateratio) -{ - if (m_subject) { - KisImageSP image = m_subject->currentImg(); - - if (image) { - TQ_INT32 imageWidth = image->width(); - TQ_INT32 imageHeight = image->height(); - m_rectCrop.setLeft(TQMAX(0, m_rectCrop.left())); - m_rectCrop.setTop(TQMAX(0, m_rectCrop.top())); - m_rectCrop.setRight(TQMIN(imageWidth, m_rectCrop.right())); - m_rectCrop.setBottom(TQMIN(imageHeight, m_rectCrop.bottom())); - - updateWidgetValues(updateratio); - } - } -} - -void KisToolCrop::paintOutlineWithHandles() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutlineWithHandles(gc, rc); - } -} - -void KisToolCrop::paintOutlineWithHandles(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject && (m_selecting || m_haveCropSelection)) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - pen.setWidth(1); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_rectCrop.topLeft()); - end = controller->windowToView(m_rectCrop.bottomRight()); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - //draw handles - m_handlesRegion = handles(TQRect(start, end)); - - TQ_INT32 startx; - TQ_INT32 starty; - TQ_INT32 endx; - TQ_INT32 endy; - if(start.x()<=end.x()) - { - startx=start.x(); - endx=end.x(); - } - else - { - startx=end.x(); - endx=start.x(); - } - if(start.y()<=end.y()) - { - starty=start.y(); - endy=end.y(); - } - else - { - starty=end.y(); - endy=start.y(); - } - //draw upper line of selection - gc.drawLine(startx + m_handleSize / 2 + 1, starty, startx + (endx - startx - m_handleSize) / 2 + 1, starty); - gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, starty, endx - m_handleSize / 2, starty); - //draw lower line of selection - gc.drawLine(startx + m_handleSize / 2 + 1, endy, startx + (endx - startx - m_handleSize) / 2 + 1, endy); - gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, endy, endx - m_handleSize / 2 , endy); - //draw right line of selection - gc.drawLine(startx, starty + m_handleSize / 2 + 1, startx, starty + (endy - starty - m_handleSize) / 2 + 1); - gc.drawLine(startx, starty + (endy - starty + m_handleSize) / 2 + 1, startx, endy - m_handleSize / 2); - //draw left line of selection - gc.drawLine(endx, starty + m_handleSize / 2 + 1, endx, starty + (endy - starty - m_handleSize) / 2 + 1); - gc.drawLine(endx, starty + (endy - starty + m_handleSize) / 2 + 1, endx, endy - m_handleSize / 2); - - //draw guides - gc.drawLine(0,endy,startx - m_handleSize / 2,endy); - gc.drawLine(startx,endy + m_handleSize / 2 + 1, startx, controller->kiscanvas()->height()); - gc.drawLine(endx,0,endx,starty - m_handleSize / 2); - gc.drawLine(endx + m_handleSize / 2 + 1,starty, controller->kiscanvas()->width(), starty); - TQMemArray rects = m_handlesRegion.rects (); - for (TQMemArray ::ConstIterator it = rects.begin (); it != rects.end (); ++it) - { - gc.fillRect (*it, TQt::black); - } - - - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolCrop::crop() { - // XXX: Should cropping be part of KisImage/KisPaintDevice's API? - - m_haveCropSelection = false; - setCursor(m_cropCursor); - - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - TQRect rc = realRectCrop().normalize(); - - // The visitor adds the undo steps to the macro - if (m_optWidget->cmbType->currentItem() == 0) { - - TQRect dirty = img->bounds(); - - // The layer(s) under the current layer will take care of adding - // undo information to the Crop macro. - if (img->undo()) - img->undoAdapter()->beginMacro(i18n("Crop")); - - KisCropVisitor v(rc, false); - KisLayerSP layer = img->activeLayer(); - layer->accept(v); - layer->setDirty( dirty ); - if (img->undo()) - img->undoAdapter()->endMacro(); - - } - else { - // Resize creates the undo macro itself - img->resize(rc, true); - } - - m_rectCrop = TQRect(0,0,0,0); - - updateWidgetValues(); -} - -void KisToolCrop::setCropX(int x) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setX(x); - - validateSelection(); - paintOutlineWithHandles(); -} - -void KisToolCrop::setCropY(int y) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setY(y); - - validateSelection(); - paintOutlineWithHandles(); - -} - -void KisToolCrop::setCropWidth(int w) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setWidth(w + 1); - - if( m_optWidget->boolRatio->isChecked() ) - { - m_rectCrop.setHeight( (int) ( w / m_optWidget->doubleRatio->value() ) ); - } else { - setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); - } - - validateSelection(); - paintOutlineWithHandles(); - -} - -void KisToolCrop::setCropHeight(int h) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setHeight(h + 1); - - if( m_optWidget->boolRatio->isChecked() ) - { - m_rectCrop.setWidth( (int) ( h * m_optWidget->doubleRatio->value() ) ); - } else { - setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); - } - - validateSelection(); - paintOutlineWithHandles(); - -} - -void KisToolCrop::setRatio(double ) -{ - if( ! (m_optWidget->boolWidth->isChecked() && m_optWidget->boolHeight->isChecked() )) - { - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - if( m_optWidget->boolWidth->isChecked() ) - { - m_rectCrop.setHeight( (int) ( m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); - setOptionWidgetHeight( m_rectCrop.height() ); - } else if(m_optWidget->boolHeight->isChecked()) { - m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); - setOptionWidgetWidth( m_rectCrop.width() ); - } else { - int newwidth = (int) (m_optWidget->doubleRatio->value() * m_rectCrop.height()); - newwidth = (newwidth + m_rectCrop.width()) / 2; - m_rectCrop.setWidth( newwidth + 1); - setOptionWidgetWidth( newwidth ); - m_rectCrop.setHeight( (int) (newwidth / m_optWidget->doubleRatio->value()) + 1 ); - setOptionWidgetHeight( m_rectCrop.height() - 1 ); - } - validateSelection(false); - paintOutlineWithHandles(); - } -} - -void KisToolCrop::setOptionWidgetX(TQ_INT32 x) -{ - // Disable signals otherwise we get the valueChanged signal, which we don't want - // to go through the logic for setting values that way. - m_optWidget->intX->blockSignals(true); - m_optWidget->intX->setValue(x); - m_optWidget->intX->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetY(TQ_INT32 y) -{ - m_optWidget->intY->blockSignals(true); - m_optWidget->intY->setValue(y); - m_optWidget->intY->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetWidth(TQ_INT32 x) -{ - m_optWidget->intWidth->blockSignals(true); - m_optWidget->intWidth->setValue(x); - m_optWidget->intWidth->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetHeight(TQ_INT32 y) -{ - m_optWidget->intHeight->blockSignals(true); - m_optWidget->intHeight->setValue(y); - m_optWidget->intHeight->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetRatio(double ratio) -{ - m_optWidget->doubleRatio->blockSignals(true); - m_optWidget->doubleRatio->setValue(ratio); - m_optWidget->doubleRatio->blockSignals(false); -} - - -TQWidget* KisToolCrop::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new WdgToolCrop(parent); - TQ_CHECK_PTR(m_optWidget); - - connect(m_optWidget->bnCrop, TQT_SIGNAL(clicked()), this, TQT_SLOT(crop())); - - connect(m_optWidget->intX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropX(int))); - connect(m_optWidget->intY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropY(int))); - connect(m_optWidget->intWidth, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropWidth(int))); - connect(m_optWidget->intHeight, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropHeight(int))); - connect(m_optWidget->doubleRatio, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(setRatio( double ))); - - return m_optWidget; -} - -TQWidget* KisToolCrop::optionWidget() -{ - return m_optWidget; -} - -void KisToolCrop::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Crop"), - "tool_crop", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Crop an area")); - m_action->setExclusiveGroup("tools"); - - m_ownAction = true; - } -} - -TQRect toTQRect(double x, double y, int w, int h) -{ - return TQRect(int(x), int(y), w, h); -} - -TQRegion KisToolCrop::handles(TQRect rect) -{ - TQRegion handlesRegion; - - //add handle at the lower right corner - handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0, TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the upper right corner - handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add rectangle at the lower left corner - handlesRegion += toTQRect( 0 - m_handleSize / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add rectangle at the upper left corner - handlesRegion += toTQRect( 0 - m_handleSize / 2.0, 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the lower edge of the rectangle - handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the right edge of the rectangle - handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); - //add handle at the upper edge of the rectangle - handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the left edge of the rectangle - handlesRegion += toTQRect( 0 - m_handleSize / 2.0, ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); - - //move the handles to the correct position - if( rect.width() >= 0 && rect.height() >= 0) - { - handlesRegion.translate ( rect.x(), rect.y() ); - } - else if( rect.width() < 0 && rect.height() >= 0) - { - handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() ); - } - else if( rect.width() >= 0 && rect.height() < 0) - { - handlesRegion.translate ( rect.x(), rect.y() - TQABS( rect.height() ) ); - } - else if( rect.width() < 0 && rect.height() < 0) - { - handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() - TQABS( rect.height() ) ); - } - return handlesRegion; -} - -TQ_INT32 KisToolCrop::mouseOnHandle(TQPoint currentViewPoint) -{ - KisCanvasController *controller = m_subject->canvasController(); - Q_ASSERT(controller); - TQPoint start = controller->windowToView(m_rectCrop.topLeft()); - TQPoint end = controller->windowToView(m_rectCrop.bottomRight()); - - TQ_INT32 startx; - TQ_INT32 starty; - TQ_INT32 endx; - TQ_INT32 endy; - if(start.x()<=end.x()) - { - startx=start.x(); - endx=end.x(); - } - else - { - startx=end.x(); - endx=start.x(); - } - if(start.y()<=end.y()) - { - starty=start.y(); - endy=end.y(); - } - else - { - starty=end.y(); - endy=start.y(); - } - - if ( toTQRect ( startx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx= startx-currentViewPoint.x(); - m_dy = starty - currentViewPoint.y(); - } - return UpperLeft; - } - else if ( toTQRect ( startx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = startx-currentViewPoint.x(); - m_dy = endy-currentViewPoint.y(); - } - return LowerLeft; - } - else if ( toTQRect ( endx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = endx - currentViewPoint.x(); - m_dy = starty - currentViewPoint.y() ; - } - return UpperRight; - } - else if ( toTQRect ( endx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = endx - currentViewPoint.x(); - m_dy= endy - currentViewPoint.y(); - } - return LowerRight; - } - else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dy = starty - currentViewPoint.y() ; - } - return Upper; - } - else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, endy - m_handleSize / 2, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dy = endy - currentViewPoint.y(); - } - return Lower; - } - else if ( toTQRect ( startx - m_handleSize / 2.0, starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = startx - currentViewPoint.x() ; - } - return Left; - } - else if ( toTQRect ( endx - m_handleSize / 2.0 , starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = endx-currentViewPoint.x(); - } - return Right; - } - else if ( toTQRect ( startx , starty, endx - startx , endy - starty ).contains( currentViewPoint ) ) - { - return Inside; - } - else return None; -} - -void KisToolCrop::setMoveResizeCursor (TQ_INT32 handle) -{ - switch (handle) - { - case (UpperLeft): - case (LowerRight): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeFDiagCursor()); - return; - case (LowerLeft): - case (UpperRight): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeBDiagCursor()); - return; - case (Upper): - case (Lower): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeVerCursor()); - return; - case (Left): - case (Right): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeHorCursor()); - return; - case (Inside): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeAllCursor()); - return; - } - m_subject->canvasController()->setCanvasCursor(KisCursor::arrowCursor()); - return; -} - - -#include "kis_tool_crop.moc" diff --git a/chalk/plugins/tools/tool_crop/kis_tool_crop.cpp b/chalk/plugins/tools/tool_crop/kis_tool_crop.cpp new file mode 100644 index 00000000..58454b4f --- /dev/null +++ b/chalk/plugins/tools/tool_crop/kis_tool_crop.cpp @@ -0,0 +1,925 @@ +/* + * kis_tool_crop.cpp -- part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2005 Michael Thaler + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_crop.h" +#include "wdg_tool_crop.h" + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + + + +KisToolCrop::KisToolCrop() + : super(i18n("Crop")) +{ + setName("tool_crop"); + m_cropCursor = KisCursor::load("tool_crop_cursor.png", 6, 6); + setCursor(m_cropCursor); + m_subject = 0; + m_selecting = false; + m_rectCrop = TQRect(0, 0, 0, 0); + m_handleSize = 13; + m_haveCropSelection = false; + m_optWidget = 0; +} + +KisToolCrop::~KisToolCrop() +{ +} + +void KisToolCrop::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolCrop::activate() +{ + super::activate(); + + // No current crop rectangle, try to use the selection of the device to make a rectangle + if (m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) { + KisPaintDeviceSP device = m_subject->currentImg()->activeDevice(); + if (!device->hasSelection()) { + //m_rectCrop = m_subject->currentImg()->bounds(); + //validateSelection(); + m_haveCropSelection = false; + m_selecting = false; + } + else { + + m_rectCrop = device->selection()->selectedRect(); + validateSelection(); + crop(); + } + } +} + +void KisToolCrop::deactivate() +{ + clearRect(); +} + + +void KisToolCrop::paint(KisCanvasPainter& gc) +{ + paintOutlineWithHandles(gc, TQRect()); +} + +void KisToolCrop::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + paintOutlineWithHandles(gc, rc); +} + +void KisToolCrop::clearRect() +{ + kdDebug() << "Clearing\n"; + if (m_subject) { + + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + Q_ASSERT(controller); + + controller->kiscanvas()->update(); + + m_rectCrop = TQRect(0,0,0,0); + + updateWidgetValues(); + m_selecting = false; + } +} + +void KisToolCrop::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + + TQPoint pos = e->pos().floorTQPoint(); + TQRect b = img->bounds(); + + if (pos.x() < b.x()) + pos.setX(b.x()); + else if (pos.x() > b.x() + b.width()) + pos.setX(b.x() + b.width()); + + if (pos.y() < b.y()) + pos.setY(b.y()); + else if (pos.y() > b.y() + b.height()) + pos.setY(b.y() + b.height()); + + m_selecting = true; + + if( !m_haveCropSelection ) //if the selection is not set + { + m_rectCrop = TQRect( pos.x(), pos.y(), 0, 0); + paintOutlineWithHandles(); + } + else + { + KisCanvasController *controller = m_subject->canvasController(); + m_mouseOnHandleType = mouseOnHandle(controller ->windowToView(pos)); + m_dragStart = pos; + } + + updateWidgetValues(); + } + } +} + +void KisToolCrop::move(KisMoveEvent *e) +{ + if ( m_subject && m_subject->currentImg()) + { + if( m_selecting ) //if the user selects + { + if( !m_haveCropSelection ) //if the cropSelection is not yet set + { + paintOutlineWithHandles(); + + m_rectCrop.setBottomRight( e->pos().floorTQPoint()); + + KisImageSP image = m_subject->currentImg(); + + m_rectCrop.setRight( TQMIN(m_rectCrop.right(), image->width())); + m_rectCrop.setBottom( TQMIN(m_rectCrop.bottom(), image->width())); + m_rectCrop = m_rectCrop.normalize(); + + paintOutlineWithHandles(); + } + else //if the crop selection is set + { + m_dragStop = e->pos().floorTQPoint(); + if (m_mouseOnHandleType != None && m_dragStart != m_dragStop ) { + + + TQ_INT32 imageWidth = m_subject->currentImg()->width(); + TQ_INT32 imageHeight = m_subject->currentImg()->height(); + + paintOutlineWithHandles(); + + TQPoint pos = e->pos().floorTQPoint(); + if( m_mouseOnHandleType == Inside ) + { + m_rectCrop.moveBy( ( m_dragStop.x() - m_dragStart.x() ), ( m_dragStop.y() - m_dragStart.y() ) ); + if( m_rectCrop.left() < 0 ) + { + m_rectCrop.moveLeft( 0 ); + } + if( m_rectCrop.right() > imageWidth ) + { + m_rectCrop.moveRight( imageWidth ); + } + if( m_rectCrop.top() < 0 ) + { + m_rectCrop.moveTop( 0 ); + } + if( m_rectCrop.bottom() > imageHeight ) + { + m_rectCrop.moveBottom( imageHeight ); + } + } else if(m_optWidget->boolRatio->isChecked()) + { + TQPoint drag = m_dragStop - m_dragStart; + if( ! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked() ) + { + switch (m_mouseOnHandleType) + { + case (UpperLeft): + { + TQ_INT32 dep = (drag.x() + drag.y()) / 2; + m_rectCrop.setTop( m_rectCrop.top() + dep ); + m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + } + break; + case (LowerRight): + { + TQ_INT32 dep = (drag.x() + drag.y()) / 2; + m_rectCrop.setBottom( m_rectCrop.bottom() + dep ); + m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + break; + } + case (UpperRight): + { + TQ_INT32 dep = (drag.x() - drag.y()) / 2; + m_rectCrop.setTop( m_rectCrop.top() - dep ); + m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + break; + } + case (LowerLeft): + { + TQ_INT32 dep = (drag.x() - drag.y()) / 2; + m_rectCrop.setBottom( m_rectCrop.bottom() - dep ); + m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + break; + } + case (Upper): + m_rectCrop.setTop( pos.y() + m_dy ); + m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); + break; + case (Lower): + m_rectCrop.setBottom( pos.y() + m_dy ); + m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); + break; + case (Left): + m_rectCrop.setLeft( pos.x() + m_dx ); + m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); + break; + case (Right): + m_rectCrop.setRight( pos.x() + m_dx ); + m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); + break; + case (Inside): // never happen + break; + } + } + } else { + if( m_optWidget->boolWidth->isChecked() ) + { + m_rectCrop.setWidth( m_optWidget->intWidth->value() + 1 ); + } else { + switch (m_mouseOnHandleType) + { + case (LowerLeft): + case (Left): + case (UpperLeft): + m_rectCrop.setLeft( pos.x() + m_dx ); + break; + case (Right): + case (UpperRight): + case (LowerRight): + m_rectCrop.setRight( pos.x() + m_dx ); + break; + default: + break; + } + } + if( m_optWidget->boolHeight->isChecked() ) + { + m_rectCrop.setHeight( m_optWidget->intHeight->value() + 1 ); + } else { + switch (m_mouseOnHandleType) + { + case (UpperLeft): + case (Upper): + case (UpperRight): + m_rectCrop.setTop( pos.y() + m_dy ); + break; + case (LowerRight): + case (LowerLeft): + case (Lower): + m_rectCrop.setBottom( pos.y() + m_dy ); + break; + default: + break; + } + } + } + if( m_rectCrop.height() < 0) + { + if( m_mouseOnHandleType == Lower) + m_mouseOnHandleType = Upper; + else if( m_mouseOnHandleType == LowerLeft) + m_mouseOnHandleType = UpperLeft; + else if( m_mouseOnHandleType == LowerRight) + m_mouseOnHandleType = UpperRight; + else if( m_mouseOnHandleType == Upper) + m_mouseOnHandleType = Lower; + else if( m_mouseOnHandleType == UpperLeft) + m_mouseOnHandleType = LowerLeft; + else if( m_mouseOnHandleType == UpperRight) + m_mouseOnHandleType = LowerRight; + } + if( m_rectCrop.width() < 0) + { + if( m_mouseOnHandleType == Right) + m_mouseOnHandleType = Left; + else if( m_mouseOnHandleType == UpperRight) + m_mouseOnHandleType = UpperLeft; + else if( m_mouseOnHandleType == LowerRight) + m_mouseOnHandleType = LowerLeft; + else if( m_mouseOnHandleType == Left) + m_mouseOnHandleType = Right; + else if( m_mouseOnHandleType == UpperLeft) + m_mouseOnHandleType = UpperRight; + else if( m_mouseOnHandleType == LowerLeft) + m_mouseOnHandleType = LowerRight; + } + + m_rectCrop = m_rectCrop.normalize(); + m_rectCrop = m_rectCrop.intersect( TQRect(0,0, imageWidth + 1, imageHeight + 1 ) ); + m_dragStart = e->pos().floorTQPoint(); + paintOutlineWithHandles(); + } + } + updateWidgetValues(); + } + else //if we are not selecting + { + if ( m_haveCropSelection ) //if the crop selection is set + { + KisCanvasController *controller = m_subject->canvasController(); + TQ_INT32 type = mouseOnHandle(controller->windowToView(e->pos().floorTQPoint())); + //set resize cursor if we are on one of the handles + setMoveResizeCursor(type); + } + } + } +} + +void KisToolCrop::updateWidgetValues(bool updateratio) +{ + TQRect r = realRectCrop(); + setOptionWidgetX(r.x()); + setOptionWidgetY(r.y()); + setOptionWidgetWidth(r.width() ); + setOptionWidgetHeight(r.height() ); + if(updateratio && !m_optWidget->boolRatio->isChecked() ) + setOptionWidgetRatio((double)r.width() / (double)r.height() ); +} + +void KisToolCrop::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_subject->currentImg() && m_selecting && e->button() == Qt::LeftButton) { + + m_selecting = false; + m_haveCropSelection = true; + + paintOutlineWithHandles(); + validateSelection(); + paintOutlineWithHandles(); + } +} + +void KisToolCrop::doubleClick(KisDoubleClickEvent *) +{ + if (m_haveCropSelection) crop(); +} + +void KisToolCrop::validateSelection(bool updateratio) +{ + if (m_subject) { + KisImageSP image = m_subject->currentImg(); + + if (image) { + TQ_INT32 imageWidth = image->width(); + TQ_INT32 imageHeight = image->height(); + m_rectCrop.setLeft(TQMAX(0, m_rectCrop.left())); + m_rectCrop.setTop(TQMAX(0, m_rectCrop.top())); + m_rectCrop.setRight(TQMIN(imageWidth, m_rectCrop.right())); + m_rectCrop.setBottom(TQMIN(imageHeight, m_rectCrop.bottom())); + + updateWidgetValues(updateratio); + } + } +} + +void KisToolCrop::paintOutlineWithHandles() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutlineWithHandles(gc, rc); + } +} + +void KisToolCrop::paintOutlineWithHandles(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject && (m_selecting || m_haveCropSelection)) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + pen.setWidth(1); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_rectCrop.topLeft()); + end = controller->windowToView(m_rectCrop.bottomRight()); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + //draw handles + m_handlesRegion = handles(TQRect(start, end)); + + TQ_INT32 startx; + TQ_INT32 starty; + TQ_INT32 endx; + TQ_INT32 endy; + if(start.x()<=end.x()) + { + startx=start.x(); + endx=end.x(); + } + else + { + startx=end.x(); + endx=start.x(); + } + if(start.y()<=end.y()) + { + starty=start.y(); + endy=end.y(); + } + else + { + starty=end.y(); + endy=start.y(); + } + //draw upper line of selection + gc.drawLine(startx + m_handleSize / 2 + 1, starty, startx + (endx - startx - m_handleSize) / 2 + 1, starty); + gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, starty, endx - m_handleSize / 2, starty); + //draw lower line of selection + gc.drawLine(startx + m_handleSize / 2 + 1, endy, startx + (endx - startx - m_handleSize) / 2 + 1, endy); + gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, endy, endx - m_handleSize / 2 , endy); + //draw right line of selection + gc.drawLine(startx, starty + m_handleSize / 2 + 1, startx, starty + (endy - starty - m_handleSize) / 2 + 1); + gc.drawLine(startx, starty + (endy - starty + m_handleSize) / 2 + 1, startx, endy - m_handleSize / 2); + //draw left line of selection + gc.drawLine(endx, starty + m_handleSize / 2 + 1, endx, starty + (endy - starty - m_handleSize) / 2 + 1); + gc.drawLine(endx, starty + (endy - starty + m_handleSize) / 2 + 1, endx, endy - m_handleSize / 2); + + //draw guides + gc.drawLine(0,endy,startx - m_handleSize / 2,endy); + gc.drawLine(startx,endy + m_handleSize / 2 + 1, startx, controller->kiscanvas()->height()); + gc.drawLine(endx,0,endx,starty - m_handleSize / 2); + gc.drawLine(endx + m_handleSize / 2 + 1,starty, controller->kiscanvas()->width(), starty); + TQMemArray rects = m_handlesRegion.rects (); + for (TQMemArray ::ConstIterator it = rects.begin (); it != rects.end (); ++it) + { + gc.fillRect (*it, TQt::black); + } + + + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolCrop::crop() { + // XXX: Should cropping be part of KisImage/KisPaintDevice's API? + + m_haveCropSelection = false; + setCursor(m_cropCursor); + + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + TQRect rc = realRectCrop().normalize(); + + // The visitor adds the undo steps to the macro + if (m_optWidget->cmbType->currentItem() == 0) { + + TQRect dirty = img->bounds(); + + // The layer(s) under the current layer will take care of adding + // undo information to the Crop macro. + if (img->undo()) + img->undoAdapter()->beginMacro(i18n("Crop")); + + KisCropVisitor v(rc, false); + KisLayerSP layer = img->activeLayer(); + layer->accept(v); + layer->setDirty( dirty ); + if (img->undo()) + img->undoAdapter()->endMacro(); + + } + else { + // Resize creates the undo macro itself + img->resize(rc, true); + } + + m_rectCrop = TQRect(0,0,0,0); + + updateWidgetValues(); +} + +void KisToolCrop::setCropX(int x) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setX(x); + + validateSelection(); + paintOutlineWithHandles(); +} + +void KisToolCrop::setCropY(int y) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setY(y); + + validateSelection(); + paintOutlineWithHandles(); + +} + +void KisToolCrop::setCropWidth(int w) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setWidth(w + 1); + + if( m_optWidget->boolRatio->isChecked() ) + { + m_rectCrop.setHeight( (int) ( w / m_optWidget->doubleRatio->value() ) ); + } else { + setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); + } + + validateSelection(); + paintOutlineWithHandles(); + +} + +void KisToolCrop::setCropHeight(int h) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setHeight(h + 1); + + if( m_optWidget->boolRatio->isChecked() ) + { + m_rectCrop.setWidth( (int) ( h * m_optWidget->doubleRatio->value() ) ); + } else { + setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); + } + + validateSelection(); + paintOutlineWithHandles(); + +} + +void KisToolCrop::setRatio(double ) +{ + if( ! (m_optWidget->boolWidth->isChecked() && m_optWidget->boolHeight->isChecked() )) + { + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + if( m_optWidget->boolWidth->isChecked() ) + { + m_rectCrop.setHeight( (int) ( m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); + setOptionWidgetHeight( m_rectCrop.height() ); + } else if(m_optWidget->boolHeight->isChecked()) { + m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); + setOptionWidgetWidth( m_rectCrop.width() ); + } else { + int newwidth = (int) (m_optWidget->doubleRatio->value() * m_rectCrop.height()); + newwidth = (newwidth + m_rectCrop.width()) / 2; + m_rectCrop.setWidth( newwidth + 1); + setOptionWidgetWidth( newwidth ); + m_rectCrop.setHeight( (int) (newwidth / m_optWidget->doubleRatio->value()) + 1 ); + setOptionWidgetHeight( m_rectCrop.height() - 1 ); + } + validateSelection(false); + paintOutlineWithHandles(); + } +} + +void KisToolCrop::setOptionWidgetX(TQ_INT32 x) +{ + // Disable signals otherwise we get the valueChanged signal, which we don't want + // to go through the logic for setting values that way. + m_optWidget->intX->blockSignals(true); + m_optWidget->intX->setValue(x); + m_optWidget->intX->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetY(TQ_INT32 y) +{ + m_optWidget->intY->blockSignals(true); + m_optWidget->intY->setValue(y); + m_optWidget->intY->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetWidth(TQ_INT32 x) +{ + m_optWidget->intWidth->blockSignals(true); + m_optWidget->intWidth->setValue(x); + m_optWidget->intWidth->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetHeight(TQ_INT32 y) +{ + m_optWidget->intHeight->blockSignals(true); + m_optWidget->intHeight->setValue(y); + m_optWidget->intHeight->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetRatio(double ratio) +{ + m_optWidget->doubleRatio->blockSignals(true); + m_optWidget->doubleRatio->setValue(ratio); + m_optWidget->doubleRatio->blockSignals(false); +} + + +TQWidget* KisToolCrop::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new WdgToolCrop(parent); + TQ_CHECK_PTR(m_optWidget); + + connect(m_optWidget->bnCrop, TQT_SIGNAL(clicked()), this, TQT_SLOT(crop())); + + connect(m_optWidget->intX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropX(int))); + connect(m_optWidget->intY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropY(int))); + connect(m_optWidget->intWidth, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropWidth(int))); + connect(m_optWidget->intHeight, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropHeight(int))); + connect(m_optWidget->doubleRatio, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(setRatio( double ))); + + return m_optWidget; +} + +TQWidget* KisToolCrop::optionWidget() +{ + return m_optWidget; +} + +void KisToolCrop::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Crop"), + "tool_crop", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Crop an area")); + m_action->setExclusiveGroup("tools"); + + m_ownAction = true; + } +} + +TQRect toTQRect(double x, double y, int w, int h) +{ + return TQRect(int(x), int(y), w, h); +} + +TQRegion KisToolCrop::handles(TQRect rect) +{ + TQRegion handlesRegion; + + //add handle at the lower right corner + handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0, TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the upper right corner + handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add rectangle at the lower left corner + handlesRegion += toTQRect( 0 - m_handleSize / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add rectangle at the upper left corner + handlesRegion += toTQRect( 0 - m_handleSize / 2.0, 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the lower edge of the rectangle + handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the right edge of the rectangle + handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); + //add handle at the upper edge of the rectangle + handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the left edge of the rectangle + handlesRegion += toTQRect( 0 - m_handleSize / 2.0, ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); + + //move the handles to the correct position + if( rect.width() >= 0 && rect.height() >= 0) + { + handlesRegion.translate ( rect.x(), rect.y() ); + } + else if( rect.width() < 0 && rect.height() >= 0) + { + handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() ); + } + else if( rect.width() >= 0 && rect.height() < 0) + { + handlesRegion.translate ( rect.x(), rect.y() - TQABS( rect.height() ) ); + } + else if( rect.width() < 0 && rect.height() < 0) + { + handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() - TQABS( rect.height() ) ); + } + return handlesRegion; +} + +TQ_INT32 KisToolCrop::mouseOnHandle(TQPoint currentViewPoint) +{ + KisCanvasController *controller = m_subject->canvasController(); + Q_ASSERT(controller); + TQPoint start = controller->windowToView(m_rectCrop.topLeft()); + TQPoint end = controller->windowToView(m_rectCrop.bottomRight()); + + TQ_INT32 startx; + TQ_INT32 starty; + TQ_INT32 endx; + TQ_INT32 endy; + if(start.x()<=end.x()) + { + startx=start.x(); + endx=end.x(); + } + else + { + startx=end.x(); + endx=start.x(); + } + if(start.y()<=end.y()) + { + starty=start.y(); + endy=end.y(); + } + else + { + starty=end.y(); + endy=start.y(); + } + + if ( toTQRect ( startx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx= startx-currentViewPoint.x(); + m_dy = starty - currentViewPoint.y(); + } + return UpperLeft; + } + else if ( toTQRect ( startx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = startx-currentViewPoint.x(); + m_dy = endy-currentViewPoint.y(); + } + return LowerLeft; + } + else if ( toTQRect ( endx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = endx - currentViewPoint.x(); + m_dy = starty - currentViewPoint.y() ; + } + return UpperRight; + } + else if ( toTQRect ( endx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = endx - currentViewPoint.x(); + m_dy= endy - currentViewPoint.y(); + } + return LowerRight; + } + else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dy = starty - currentViewPoint.y() ; + } + return Upper; + } + else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, endy - m_handleSize / 2, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dy = endy - currentViewPoint.y(); + } + return Lower; + } + else if ( toTQRect ( startx - m_handleSize / 2.0, starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = startx - currentViewPoint.x() ; + } + return Left; + } + else if ( toTQRect ( endx - m_handleSize / 2.0 , starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = endx-currentViewPoint.x(); + } + return Right; + } + else if ( toTQRect ( startx , starty, endx - startx , endy - starty ).contains( currentViewPoint ) ) + { + return Inside; + } + else return None; +} + +void KisToolCrop::setMoveResizeCursor (TQ_INT32 handle) +{ + switch (handle) + { + case (UpperLeft): + case (LowerRight): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeFDiagCursor()); + return; + case (LowerLeft): + case (UpperRight): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeBDiagCursor()); + return; + case (Upper): + case (Lower): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeVerCursor()); + return; + case (Left): + case (Right): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeHorCursor()); + return; + case (Inside): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeAllCursor()); + return; + } + m_subject->canvasController()->setCanvasCursor(KisCursor::arrowCursor()); + return; +} + + +#include "kis_tool_crop.moc" diff --git a/chalk/plugins/tools/tool_crop/tool_crop.cc b/chalk/plugins/tools/tool_crop/tool_crop.cc deleted file mode 100644 index 97f6e0e8..00000000 --- a/chalk/plugins/tools/tool_crop/tool_crop.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_crop.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_crop.h" -#include "kis_tool_crop.h" - - -typedef KGenericFactory ToolCropFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolcrop, ToolCropFactory( "chalk" ) ) - - -ToolCrop::ToolCrop(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolCropFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolCropFactory()); - } - -} - -ToolCrop::~ToolCrop() -{ -} - -#include "tool_crop.moc" diff --git a/chalk/plugins/tools/tool_crop/tool_crop.cpp b/chalk/plugins/tools/tool_crop/tool_crop.cpp new file mode 100644 index 00000000..30df11ec --- /dev/null +++ b/chalk/plugins/tools/tool_crop/tool_crop.cpp @@ -0,0 +1,62 @@ +/* + * tool_crop.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_crop.h" +#include "kis_tool_crop.h" + + +typedef KGenericFactory ToolCropFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolcrop, ToolCropFactory( "chalk" ) ) + + +ToolCrop::ToolCrop(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolCropFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolCropFactory()); + } + +} + +ToolCrop::~ToolCrop() +{ +} + +#include "tool_crop.moc" diff --git a/chalk/plugins/tools/tool_curves/Makefile.am b/chalk/plugins/tools/tool_curves/Makefile.am index 92366e55..75a515f2 100644 --- a/chalk/plugins/tools/tool_curves/Makefile.am +++ b/chalk/plugins/tools/tool_curves/Makefile.am @@ -10,15 +10,15 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolcurves_la_SOURCES = \ - kis_curve_framework.cc \ - kis_tool_curve.cc \ - tool_curves.cc \ + kis_curve_framework.cpp \ + kis_tool_curve.cpp \ + tool_curves.cpp \ wdg_tool_example.ui \ - kis_tool_example.cc \ - kis_tool_bezier.cc \ - kis_tool_bezier_paint.cc \ - kis_tool_bezier_select.cc \ - kis_tool_moutline.cc + kis_tool_example.cpp \ + kis_tool_bezier.cpp \ + kis_tool_bezier_paint.cpp \ + kis_tool_bezier_select.cpp \ + kis_tool_moutline.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolcurves.la diff --git a/chalk/plugins/tools/tool_curves/kis_curve_framework.cc b/chalk/plugins/tools/tool_curves/kis_curve_framework.cc deleted file mode 100644 index 8a9b4c88..00000000 --- a/chalk/plugins/tools/tool_curves/kis_curve_framework.cc +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include "kis_point.h" - -#include "kis_curve_framework.h" - -/* **************************** * - * KisCurve methods definitions * - * **************************** */ - -KisCurve::iterator KisCurve::addPivot (KisCurve::iterator it, const KisPoint& point) -{ - return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,NOHINTS))); -} - -KisCurve::iterator KisCurve::pushPivot (const KisPoint& point) -{ - return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,NOHINTS))), true); -} - -KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const KisPoint& point, bool pivot, bool selected, int hint) -{ - return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,pivot,selected, hint))); -} - -KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const CurvePoint& point) -{ - return iterator(*this,m_curve.insert(it.position(), point)); -} - -KisCurve::iterator KisCurve::pushPoint (const KisPoint& point, bool pivot, bool selected,int hint) -{ - return iterator(*this,m_curve.append(CurvePoint(point,pivot,selected,hint))); -} - -KisCurve::iterator KisCurve::pushPoint (const CurvePoint& point) -{ - return iterator(*this,m_curve.append(point)); -} - -KisCurve KisCurve::pivots() -{ - KisCurve temp; - - for (iterator it = begin(); it != end(); it = it.nextPivot()) - temp.pushPoint((*it)); - - return temp; -} - -KisCurve KisCurve::selectedPivots(bool selected) -{ - KisCurve temp; - - for (iterator it = begin(); it != end(); it = it.nextPivot()) - if ((*it).isSelected() == selected) - temp.pushPoint((*it)); - - return temp; -} - -KisCurve KisCurve::subCurve(const KisPoint& tend) -{ - return subCurve(find(tend).previousPivot(),find(tend)); -} - -KisCurve KisCurve::subCurve(const CurvePoint& tend) -{ - return subCurve(find(tend).previousPivot(),find(tend)); -} - -KisCurve KisCurve::subCurve(iterator tend) -{ - return subCurve(tend.previousPivot(),tend); -} - -KisCurve KisCurve::subCurve(const KisPoint& tstart, const KisPoint& tend) -{ - return subCurve(find(tstart),find(tend)); -} - -KisCurve KisCurve::subCurve(const CurvePoint& tstart, const CurvePoint& tend) -{ - return subCurve(find(tstart),find(tend)); -} - -KisCurve KisCurve::subCurve(iterator tstart, iterator tend) -{ - KisCurve temp; - - while (tstart != tend && tstart != m_curve.end()) - temp.pushPoint((*++tstart)); - - return temp; -} - -void KisCurve::deleteFirstPivot () -{ - if (!m_curve.isEmpty()) { - m_curve.pop_front(); - while (m_curve.count() > 1 && !first().isPivot()) - m_curve.pop_front(); - } -} - -void KisCurve::deleteLastPivot () -{ - if (!m_curve.isEmpty()) { - m_curve.pop_back(); - while (m_curve.count() > 1 && !last().isPivot()) - m_curve.pop_back(); - } -} - -KisCurve::iterator KisCurve::deleteCurve (const KisPoint& pos1, const KisPoint& pos2) -{ - return deleteCurve (CurvePoint(pos1),CurvePoint(pos2)); -} - -KisCurve::iterator KisCurve::deleteCurve (const CurvePoint& pos1, const CurvePoint& pos2) -{ - return deleteCurve (find(pos1),find(pos2)); -} - -KisCurve::iterator KisCurve::deleteCurve (KisCurve::iterator pos1, KisCurve::iterator pos2) -{ - if (pos1 == pos2) - return end(); - iterator pos = pos1; - pos++; - while (pos != pos2 && pos != end()) { - pos = m_curve.erase(pos.position()); - } - return pos; -} - -KisCurve::iterator KisCurve::selectPivot(const KisPoint& pt, bool isSelected) -{ - return selectPivot(find(CurvePoint(pt,true)),isSelected); -} - -KisCurve::iterator KisCurve::selectPivot(const CurvePoint& pt, bool isSelected) -{ - return selectPivot(find(pt),isSelected); -} - -KisCurve::iterator KisCurve::selectPivot(KisCurve::iterator it, bool isSelected) -{ - bool sel = false; - if (m_standardkeepselected) { - if (m_actionOptions & KEEPSELECTEDOPTION) - sel = true; - } - KisCurve selected = pivots(); - for (iterator i = selected.begin(); i != selected.end(); i++) - (*find((*i))).setSelected(sel); - (*it).setSelected(isSelected); - - return it; -} - -KisCurve::iterator KisCurve::movePivot(const KisPoint& oldPt, const KisPoint& newPt) -{ - return movePivot(CurvePoint(oldPt,true), newPt); -} - -KisCurve::iterator KisCurve::movePivot(const CurvePoint& oldPt, const KisPoint& newPt) -{ - return movePivot(find(oldPt), newPt); -} - -KisCurve::iterator KisCurve::movePivot(KisCurve::iterator it, const KisPoint& newPt) -{ - if (!(*it).isPivot()) - return end(); - - (*it).setPoint(newPt); - - if ((*it) != first()) { - deleteCurve (it.previousPivot(), it); - calculateCurve (it.previousPivot(), it, it); - } - if ((*it) != last()) { - deleteCurve (it, it.nextPivot()); - calculateCurve (it, it.nextPivot(), it.nextPivot()); - } - - return it; -} - -void KisCurve::deletePivot (const KisPoint& pt) -{ - deletePivot(CurvePoint(pt)); -} - -void KisCurve::deletePivot (const CurvePoint& pt) -{ - deletePivot(find(pt)); -} - -void KisCurve::deletePivot (KisCurve::iterator it) -{ - if (!(*it).isPivot()) - return; - - iterator start = it.previousPivot(); - iterator end = it.nextPivot(); - - if (end == m_curve.end()) - deleteLastPivot(); - else if (start == it) - deleteFirstPivot(); - else { - deleteCurve(start,end); - calculateCurve(start,end,end); - } -} - -// Probably it can be optimized - it is smooth though. -void KisCurve::moveSelected (const KisPoint& trans) -{ - KisPoint p; - KisCurve sel = selectedPivots(); - - for (iterator it = sel.begin(); it != sel.end(); it++) { - p = (*it).point() + trans; - movePivot((*it),p); - } -} - -void KisCurve::deleteSelected () -{ - KisCurve sel = selectedPivots(); - for (iterator it = sel.begin(); it != sel.end(); it++) - deletePivot((*it)); -} - -void KisCurve::selectAll(bool sel) -{ - for (iterator i = begin(); i != end(); i = i.nextPivot()) - (*i).setSelected(sel); -} diff --git a/chalk/plugins/tools/tool_curves/kis_curve_framework.cpp b/chalk/plugins/tools/tool_curves/kis_curve_framework.cpp new file mode 100644 index 00000000..8a9b4c88 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_curve_framework.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "kis_point.h" + +#include "kis_curve_framework.h" + +/* **************************** * + * KisCurve methods definitions * + * **************************** */ + +KisCurve::iterator KisCurve::addPivot (KisCurve::iterator it, const KisPoint& point) +{ + return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,NOHINTS))); +} + +KisCurve::iterator KisCurve::pushPivot (const KisPoint& point) +{ + return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,NOHINTS))), true); +} + +KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const KisPoint& point, bool pivot, bool selected, int hint) +{ + return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,pivot,selected, hint))); +} + +KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const CurvePoint& point) +{ + return iterator(*this,m_curve.insert(it.position(), point)); +} + +KisCurve::iterator KisCurve::pushPoint (const KisPoint& point, bool pivot, bool selected,int hint) +{ + return iterator(*this,m_curve.append(CurvePoint(point,pivot,selected,hint))); +} + +KisCurve::iterator KisCurve::pushPoint (const CurvePoint& point) +{ + return iterator(*this,m_curve.append(point)); +} + +KisCurve KisCurve::pivots() +{ + KisCurve temp; + + for (iterator it = begin(); it != end(); it = it.nextPivot()) + temp.pushPoint((*it)); + + return temp; +} + +KisCurve KisCurve::selectedPivots(bool selected) +{ + KisCurve temp; + + for (iterator it = begin(); it != end(); it = it.nextPivot()) + if ((*it).isSelected() == selected) + temp.pushPoint((*it)); + + return temp; +} + +KisCurve KisCurve::subCurve(const KisPoint& tend) +{ + return subCurve(find(tend).previousPivot(),find(tend)); +} + +KisCurve KisCurve::subCurve(const CurvePoint& tend) +{ + return subCurve(find(tend).previousPivot(),find(tend)); +} + +KisCurve KisCurve::subCurve(iterator tend) +{ + return subCurve(tend.previousPivot(),tend); +} + +KisCurve KisCurve::subCurve(const KisPoint& tstart, const KisPoint& tend) +{ + return subCurve(find(tstart),find(tend)); +} + +KisCurve KisCurve::subCurve(const CurvePoint& tstart, const CurvePoint& tend) +{ + return subCurve(find(tstart),find(tend)); +} + +KisCurve KisCurve::subCurve(iterator tstart, iterator tend) +{ + KisCurve temp; + + while (tstart != tend && tstart != m_curve.end()) + temp.pushPoint((*++tstart)); + + return temp; +} + +void KisCurve::deleteFirstPivot () +{ + if (!m_curve.isEmpty()) { + m_curve.pop_front(); + while (m_curve.count() > 1 && !first().isPivot()) + m_curve.pop_front(); + } +} + +void KisCurve::deleteLastPivot () +{ + if (!m_curve.isEmpty()) { + m_curve.pop_back(); + while (m_curve.count() > 1 && !last().isPivot()) + m_curve.pop_back(); + } +} + +KisCurve::iterator KisCurve::deleteCurve (const KisPoint& pos1, const KisPoint& pos2) +{ + return deleteCurve (CurvePoint(pos1),CurvePoint(pos2)); +} + +KisCurve::iterator KisCurve::deleteCurve (const CurvePoint& pos1, const CurvePoint& pos2) +{ + return deleteCurve (find(pos1),find(pos2)); +} + +KisCurve::iterator KisCurve::deleteCurve (KisCurve::iterator pos1, KisCurve::iterator pos2) +{ + if (pos1 == pos2) + return end(); + iterator pos = pos1; + pos++; + while (pos != pos2 && pos != end()) { + pos = m_curve.erase(pos.position()); + } + return pos; +} + +KisCurve::iterator KisCurve::selectPivot(const KisPoint& pt, bool isSelected) +{ + return selectPivot(find(CurvePoint(pt,true)),isSelected); +} + +KisCurve::iterator KisCurve::selectPivot(const CurvePoint& pt, bool isSelected) +{ + return selectPivot(find(pt),isSelected); +} + +KisCurve::iterator KisCurve::selectPivot(KisCurve::iterator it, bool isSelected) +{ + bool sel = false; + if (m_standardkeepselected) { + if (m_actionOptions & KEEPSELECTEDOPTION) + sel = true; + } + KisCurve selected = pivots(); + for (iterator i = selected.begin(); i != selected.end(); i++) + (*find((*i))).setSelected(sel); + (*it).setSelected(isSelected); + + return it; +} + +KisCurve::iterator KisCurve::movePivot(const KisPoint& oldPt, const KisPoint& newPt) +{ + return movePivot(CurvePoint(oldPt,true), newPt); +} + +KisCurve::iterator KisCurve::movePivot(const CurvePoint& oldPt, const KisPoint& newPt) +{ + return movePivot(find(oldPt), newPt); +} + +KisCurve::iterator KisCurve::movePivot(KisCurve::iterator it, const KisPoint& newPt) +{ + if (!(*it).isPivot()) + return end(); + + (*it).setPoint(newPt); + + if ((*it) != first()) { + deleteCurve (it.previousPivot(), it); + calculateCurve (it.previousPivot(), it, it); + } + if ((*it) != last()) { + deleteCurve (it, it.nextPivot()); + calculateCurve (it, it.nextPivot(), it.nextPivot()); + } + + return it; +} + +void KisCurve::deletePivot (const KisPoint& pt) +{ + deletePivot(CurvePoint(pt)); +} + +void KisCurve::deletePivot (const CurvePoint& pt) +{ + deletePivot(find(pt)); +} + +void KisCurve::deletePivot (KisCurve::iterator it) +{ + if (!(*it).isPivot()) + return; + + iterator start = it.previousPivot(); + iterator end = it.nextPivot(); + + if (end == m_curve.end()) + deleteLastPivot(); + else if (start == it) + deleteFirstPivot(); + else { + deleteCurve(start,end); + calculateCurve(start,end,end); + } +} + +// Probably it can be optimized - it is smooth though. +void KisCurve::moveSelected (const KisPoint& trans) +{ + KisPoint p; + KisCurve sel = selectedPivots(); + + for (iterator it = sel.begin(); it != sel.end(); it++) { + p = (*it).point() + trans; + movePivot((*it),p); + } +} + +void KisCurve::deleteSelected () +{ + KisCurve sel = selectedPivots(); + for (iterator it = sel.begin(); it != sel.end(); it++) + deletePivot((*it)); +} + +void KisCurve::selectAll(bool sel) +{ + for (iterator i = begin(); i != end(); i = i.nextPivot()) + (*i).setSelected(sel); +} diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc deleted file mode 100644 index e4c1d05d..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc +++ /dev/null @@ -1,366 +0,0 @@ -/* - * kis_tool_bezier.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_vec.h" - -#include "kis_curve_framework.h" -#include "kis_tool_bezier.h" - -KisCurve::iterator KisCurveBezier::groupEndpoint (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERNEXTCONTROLHINT) - temp -= 1; - if ((*it).hint() == BEZIERPREVCONTROLHINT) - temp += 1; - return temp; -} - -KisCurve::iterator KisCurveBezier::groupPrevControl (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERENDHINT) - temp -= 1; - if ((*it).hint() == BEZIERNEXTCONTROLHINT) - temp -= 2; - return temp; -} - -KisCurve::iterator KisCurveBezier::groupNextControl (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERENDHINT) - temp += 1; - if ((*it).hint() == BEZIERPREVCONTROLHINT) - temp += 2; - return temp; -} - -bool KisCurveBezier::groupSelected (KisCurve::iterator it) const -{ - if ((*groupPrevControl(it)).isSelected() || (*groupEndpoint(it)).isSelected() || (*groupNextControl(it)).isSelected()) - return true; - return false; -} - -KisCurve::iterator KisCurveBezier::nextGroupEndpoint (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERPREVCONTROLHINT) { - temp += 2; - temp = temp.nextPivot(); - } - if ((*it).hint() == BEZIERENDHINT) { - temp += 1; - temp = temp.nextPivot(); - } - if ((*it).hint() == BEZIERNEXTCONTROLHINT) { - temp = temp.nextPivot(); - } - temp = temp.nextPivot(); - return temp; -} - -KisCurve::iterator KisCurveBezier::prevGroupEndpoint (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERNEXTCONTROLHINT) { - temp -= 1; - temp = temp.previousPivot().previousPivot(); - } - if ((*it).hint() == BEZIERENDHINT) { - temp = temp.previousPivot().previousPivot(); - } - if ((*it).hint() == BEZIERPREVCONTROLHINT) { - temp = temp.previousPivot(); - } - temp = temp.previousPivot(); - return temp; -} - -KisPoint KisCurveBezier::midpoint (const KisPoint& P1, const KisPoint& P2) -{ - KisPoint temp; - temp.setX((P1.x()+P2.x())/2); - temp.setY((P1.y()+P2.y())/2); - return temp; -} - -void KisCurveBezier::recursiveCurve (const KisPoint& P1, const KisPoint& P2, const KisPoint& P3, - const KisPoint& P4, int level, KisCurve::iterator it) -{ - if (level > m_maxLevel) { - addPoint(it,midpoint(P1,P4),false,false,LINEHINT); - return; - } - - KisPoint L1, L2, L3, L4; - KisPoint H, R1, R2, R3, R4; - - L1 = P1; - L2 = midpoint(P1, P2); - H = midpoint(P2, P3); - R3 = midpoint(P3, P4); - R4 = P4; - L3 = midpoint(L2, H); - R2 = midpoint(R3, H); - L4 = midpoint(L3, R2); - R1 = L4; - recursiveCurve(L1, L2, L3, L4, level + 1, it); - recursiveCurve(R1, R2, R3, R4, level + 1, it); -} - -void KisCurveBezier::calculateCurve(KisCurve::iterator tstart, KisCurve::iterator tend, KisCurve::iterator) -{ - if (pivots().count() < 4) - return; - - iterator origin, dest, control1, control2; - - if ((*tstart).hint() == BEZIERENDHINT) { - origin = tstart; - control1 = tstart.nextPivot(); - } else if ((*tstart).hint() == BEZIERNEXTCONTROLHINT) { - origin = tstart.previousPivot(); - control1 = tstart; - } else if ((*tstart).hint() == BEZIERPREVCONTROLHINT) { - origin = tstart.nextPivot(); - control1 = origin.nextPivot(); - } else - return; - - if ((*tend).hint() == BEZIERENDHINT) { - dest = tend; - control2 = tend.previousPivot(); - } else if ((*tend).hint() == BEZIERPREVCONTROLHINT) { - dest = tend.nextPivot(); - control2 = tend; - } else if ((*tend).hint() == BEZIERNEXTCONTROLHINT) { - dest = tend.previousPivot(); - control2 = dest.previousPivot(); - } else - return; - - deleteCurve(control1,control2); - recursiveCurve((*origin).point(),(*control1).point(),(*control2).point(),(*dest).point(),1,control2); - -} - -KisCurve::iterator KisCurveBezier::pushPivot (const KisPoint& point) -{ - iterator it; - - it = pushPoint(point,true,false,BEZIERENDHINT); - if (count() > 1) - addPoint(it,point,true,false,BEZIERPREVCONTROLHINT); - - it = pushPoint(point,true,false,BEZIERNEXTCONTROLHINT); - - return selectPivot(it); -} - -KisCurve::iterator KisCurveBezier::movePivot(KisCurve::iterator it, const KisPoint& newPt) -{ - if (!(*it).isPivot()) - return end(); - - int hint = (*it).hint(); - iterator thisEnd, prevEnd, nextEnd; - - thisEnd = groupEndpoint(it); - prevEnd = prevGroupEndpoint(it); - nextEnd = nextGroupEndpoint(it); - - if (hint == BEZIERENDHINT) { - KisPoint trans = newPt - (*it).point(); - (*thisEnd).setPoint((*thisEnd).point()+trans); - (*thisEnd.previous()).setPoint((*thisEnd.previous()).point()+trans); - (*thisEnd.next()).setPoint((*thisEnd.next()).point()+trans); - } else if (!(m_actionOptions & KEEPSELECTEDOPTION)) - (*it).setPoint(newPt); - if (!(m_actionOptions & KEEPSELECTEDOPTION) && hint != BEZIERENDHINT) { - if (nextEnd == end() || (m_actionOptions & SYMMETRICALCONTROLSOPTION)) { - KisPoint trans = (*it).point() - (*thisEnd).point(); - trans = KisPoint(-trans.x()*2,-trans.y()*2); - if (hint == BEZIERNEXTCONTROLHINT) - (*groupPrevControl(it)).setPoint(newPt+trans); - else - (*groupNextControl(it)).setPoint(newPt+trans); - } - } - - if (nextEnd != end() && count() > 4) - calculateCurve (thisEnd,nextEnd,iterator()); - if (prevEnd != thisEnd && count() > 4) - calculateCurve (prevEnd,thisEnd,iterator()); - - return it; -} - -void KisCurveBezier::deletePivot (KisCurve::iterator it) -{ - if (!(*it).isPivot()) - return; - - iterator prevControl,thisEnd,nextControl; - - prevControl = prevGroupEndpoint(it).nextPivot(); - thisEnd = groupEndpoint(it); - nextControl = nextGroupEndpoint(it).previousPivot(); - - if ((*thisEnd) == first()) { - deleteFirstPivot(); - deleteFirstPivot(); - deleteFirstPivot(); - } else if ((*thisEnd.next()) == last()) { - deleteLastPivot(); - deleteLastPivot(); - deleteLastPivot(); - } else { - deleteCurve(prevControl,nextControl); - calculateCurve(prevControl,nextControl,iterator()); - } -} - -KisToolBezier::KisToolBezier(const TQString& UIName) - : super(UIName) -{ - m_derivated = new KisCurveBezier; - m_curve = m_derivated; - - m_supportMinimalDraw = false; - - m_transactionMessage = i18n("Bezier Curve"); -} - -KisToolBezier::~KisToolBezier() -{ - -} - -KisCurve::iterator KisToolBezier::handleUnderMouse(const TQPoint& pos) -{ - TQPoint qpos; - KisCurve pivs = m_curve->pivots(), inHandle; - KisCurve::iterator it; - int hint; - for (it = pivs.begin(); it != pivs.end(); it++) { - qpos = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); - hint = (*it).hint(); - if (hint != BEZIERENDHINT && !m_derivated->groupSelected(it)) - continue; - if (hint == BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) - continue; - if (pivotRect(qpos).contains(pos)) { - inHandle.pushPoint((*it)); - if (hint == BEZIERENDHINT && !(m_actionOptions & SHIFTOPTION)) - break; - if (hint != BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) - break; - } - } - if (inHandle.isEmpty()) - return m_curve->end(); - - return m_curve->find(inHandle.last()); -} - -KisCurve::iterator KisToolBezier::drawPoint (KisCanvasPainter& gc, KisCurve::iterator point) -{ - if ((*point).hint() != BEZIERENDHINT) - return ++point; - - KisCanvasController *controller = m_subject->canvasController(); - - // Now draw the bezier - - KisCurve::iterator origin,control1,control2,destination; - - origin = point; - control1 = origin.next(); - control2 = control1.nextPivot(); - destination = control2.next(); - - if (control2 != m_curve->end()) { - point = control2; - TQPointArray vec(4); - vec[0] = controller->windowToView((*origin).point().toTQPoint()); - vec[1] = controller->windowToView((*control1).point().toTQPoint()); - vec[2] = controller->windowToView((*control2).point().toTQPoint()); - vec[3] = controller->windowToView((*destination).point().toTQPoint()); - gc.drawCubicBezier(vec); - } - - point += 1; - - return point; -} - -void KisToolBezier::drawPivotHandle (KisCanvasPainter& gc, KisCurve::iterator point) -{ - if ((*point).hint() != BEZIERENDHINT) - return; - - KisCanvasController *controller = m_subject->canvasController(); - - TQPoint endpPos = controller->windowToView((*point).point().toTQPoint()); - - if (!m_derivated->groupSelected(point)) { - gc.setPen(m_pivotPen); - gc.drawRoundRect(pivotRect(endpPos),m_pivotRounding,m_pivotRounding); - } else { - TQPoint nextControlPos = controller->windowToView((*point.next()).point().toTQPoint()); - TQPoint prevControlPos = controller->windowToView((*point.previousPivot()).point().toTQPoint()); - - gc.setPen(m_selectedPivotPen); - gc.drawRoundRect(selectedPivotRect(endpPos),m_selectedPivotRounding,m_selectedPivotRounding); - if ((prevControlPos != endpPos || nextControlPos != endpPos) && !(m_actionOptions & CONTROLOPTION)) { - gc.drawRoundRect(pivotRect(nextControlPos),m_pivotRounding,m_pivotRounding); - gc.drawLine(endpPos,nextControlPos); - gc.drawRoundRect(pivotRect(prevControlPos),m_pivotRounding,m_pivotRounding); - gc.drawLine(prevControlPos,endpPos); - } - } - - gc.setPen(m_drawingPen); -} - -#include "kis_tool_bezier.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp new file mode 100644 index 00000000..9195dfbd --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp @@ -0,0 +1,366 @@ +/* + * kis_tool_bezier.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_vec.h" + +#include "kis_curve_framework.h" +#include "kis_tool_bezier.h" + +KisCurve::iterator KisCurveBezier::groupEndpoint (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERNEXTCONTROLHINT) + temp -= 1; + if ((*it).hint() == BEZIERPREVCONTROLHINT) + temp += 1; + return temp; +} + +KisCurve::iterator KisCurveBezier::groupPrevControl (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERENDHINT) + temp -= 1; + if ((*it).hint() == BEZIERNEXTCONTROLHINT) + temp -= 2; + return temp; +} + +KisCurve::iterator KisCurveBezier::groupNextControl (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERENDHINT) + temp += 1; + if ((*it).hint() == BEZIERPREVCONTROLHINT) + temp += 2; + return temp; +} + +bool KisCurveBezier::groupSelected (KisCurve::iterator it) const +{ + if ((*groupPrevControl(it)).isSelected() || (*groupEndpoint(it)).isSelected() || (*groupNextControl(it)).isSelected()) + return true; + return false; +} + +KisCurve::iterator KisCurveBezier::nextGroupEndpoint (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERPREVCONTROLHINT) { + temp += 2; + temp = temp.nextPivot(); + } + if ((*it).hint() == BEZIERENDHINT) { + temp += 1; + temp = temp.nextPivot(); + } + if ((*it).hint() == BEZIERNEXTCONTROLHINT) { + temp = temp.nextPivot(); + } + temp = temp.nextPivot(); + return temp; +} + +KisCurve::iterator KisCurveBezier::prevGroupEndpoint (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERNEXTCONTROLHINT) { + temp -= 1; + temp = temp.previousPivot().previousPivot(); + } + if ((*it).hint() == BEZIERENDHINT) { + temp = temp.previousPivot().previousPivot(); + } + if ((*it).hint() == BEZIERPREVCONTROLHINT) { + temp = temp.previousPivot(); + } + temp = temp.previousPivot(); + return temp; +} + +KisPoint KisCurveBezier::midpoint (const KisPoint& P1, const KisPoint& P2) +{ + KisPoint temp; + temp.setX((P1.x()+P2.x())/2); + temp.setY((P1.y()+P2.y())/2); + return temp; +} + +void KisCurveBezier::recursiveCurve (const KisPoint& P1, const KisPoint& P2, const KisPoint& P3, + const KisPoint& P4, int level, KisCurve::iterator it) +{ + if (level > m_maxLevel) { + addPoint(it,midpoint(P1,P4),false,false,LINEHINT); + return; + } + + KisPoint L1, L2, L3, L4; + KisPoint H, R1, R2, R3, R4; + + L1 = P1; + L2 = midpoint(P1, P2); + H = midpoint(P2, P3); + R3 = midpoint(P3, P4); + R4 = P4; + L3 = midpoint(L2, H); + R2 = midpoint(R3, H); + L4 = midpoint(L3, R2); + R1 = L4; + recursiveCurve(L1, L2, L3, L4, level + 1, it); + recursiveCurve(R1, R2, R3, R4, level + 1, it); +} + +void KisCurveBezier::calculateCurve(KisCurve::iterator tstart, KisCurve::iterator tend, KisCurve::iterator) +{ + if (pivots().count() < 4) + return; + + iterator origin, dest, control1, control2; + + if ((*tstart).hint() == BEZIERENDHINT) { + origin = tstart; + control1 = tstart.nextPivot(); + } else if ((*tstart).hint() == BEZIERNEXTCONTROLHINT) { + origin = tstart.previousPivot(); + control1 = tstart; + } else if ((*tstart).hint() == BEZIERPREVCONTROLHINT) { + origin = tstart.nextPivot(); + control1 = origin.nextPivot(); + } else + return; + + if ((*tend).hint() == BEZIERENDHINT) { + dest = tend; + control2 = tend.previousPivot(); + } else if ((*tend).hint() == BEZIERPREVCONTROLHINT) { + dest = tend.nextPivot(); + control2 = tend; + } else if ((*tend).hint() == BEZIERNEXTCONTROLHINT) { + dest = tend.previousPivot(); + control2 = dest.previousPivot(); + } else + return; + + deleteCurve(control1,control2); + recursiveCurve((*origin).point(),(*control1).point(),(*control2).point(),(*dest).point(),1,control2); + +} + +KisCurve::iterator KisCurveBezier::pushPivot (const KisPoint& point) +{ + iterator it; + + it = pushPoint(point,true,false,BEZIERENDHINT); + if (count() > 1) + addPoint(it,point,true,false,BEZIERPREVCONTROLHINT); + + it = pushPoint(point,true,false,BEZIERNEXTCONTROLHINT); + + return selectPivot(it); +} + +KisCurve::iterator KisCurveBezier::movePivot(KisCurve::iterator it, const KisPoint& newPt) +{ + if (!(*it).isPivot()) + return end(); + + int hint = (*it).hint(); + iterator thisEnd, prevEnd, nextEnd; + + thisEnd = groupEndpoint(it); + prevEnd = prevGroupEndpoint(it); + nextEnd = nextGroupEndpoint(it); + + if (hint == BEZIERENDHINT) { + KisPoint trans = newPt - (*it).point(); + (*thisEnd).setPoint((*thisEnd).point()+trans); + (*thisEnd.previous()).setPoint((*thisEnd.previous()).point()+trans); + (*thisEnd.next()).setPoint((*thisEnd.next()).point()+trans); + } else if (!(m_actionOptions & KEEPSELECTEDOPTION)) + (*it).setPoint(newPt); + if (!(m_actionOptions & KEEPSELECTEDOPTION) && hint != BEZIERENDHINT) { + if (nextEnd == end() || (m_actionOptions & SYMMETRICALCONTROLSOPTION)) { + KisPoint trans = (*it).point() - (*thisEnd).point(); + trans = KisPoint(-trans.x()*2,-trans.y()*2); + if (hint == BEZIERNEXTCONTROLHINT) + (*groupPrevControl(it)).setPoint(newPt+trans); + else + (*groupNextControl(it)).setPoint(newPt+trans); + } + } + + if (nextEnd != end() && count() > 4) + calculateCurve (thisEnd,nextEnd,iterator()); + if (prevEnd != thisEnd && count() > 4) + calculateCurve (prevEnd,thisEnd,iterator()); + + return it; +} + +void KisCurveBezier::deletePivot (KisCurve::iterator it) +{ + if (!(*it).isPivot()) + return; + + iterator prevControl,thisEnd,nextControl; + + prevControl = prevGroupEndpoint(it).nextPivot(); + thisEnd = groupEndpoint(it); + nextControl = nextGroupEndpoint(it).previousPivot(); + + if ((*thisEnd) == first()) { + deleteFirstPivot(); + deleteFirstPivot(); + deleteFirstPivot(); + } else if ((*thisEnd.next()) == last()) { + deleteLastPivot(); + deleteLastPivot(); + deleteLastPivot(); + } else { + deleteCurve(prevControl,nextControl); + calculateCurve(prevControl,nextControl,iterator()); + } +} + +KisToolBezier::KisToolBezier(const TQString& UIName) + : super(UIName) +{ + m_derivated = new KisCurveBezier; + m_curve = m_derivated; + + m_supportMinimalDraw = false; + + m_transactionMessage = i18n("Bezier Curve"); +} + +KisToolBezier::~KisToolBezier() +{ + +} + +KisCurve::iterator KisToolBezier::handleUnderMouse(const TQPoint& pos) +{ + TQPoint qpos; + KisCurve pivs = m_curve->pivots(), inHandle; + KisCurve::iterator it; + int hint; + for (it = pivs.begin(); it != pivs.end(); it++) { + qpos = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); + hint = (*it).hint(); + if (hint != BEZIERENDHINT && !m_derivated->groupSelected(it)) + continue; + if (hint == BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) + continue; + if (pivotRect(qpos).contains(pos)) { + inHandle.pushPoint((*it)); + if (hint == BEZIERENDHINT && !(m_actionOptions & SHIFTOPTION)) + break; + if (hint != BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) + break; + } + } + if (inHandle.isEmpty()) + return m_curve->end(); + + return m_curve->find(inHandle.last()); +} + +KisCurve::iterator KisToolBezier::drawPoint (KisCanvasPainter& gc, KisCurve::iterator point) +{ + if ((*point).hint() != BEZIERENDHINT) + return ++point; + + KisCanvasController *controller = m_subject->canvasController(); + + // Now draw the bezier + + KisCurve::iterator origin,control1,control2,destination; + + origin = point; + control1 = origin.next(); + control2 = control1.nextPivot(); + destination = control2.next(); + + if (control2 != m_curve->end()) { + point = control2; + TQPointArray vec(4); + vec[0] = controller->windowToView((*origin).point().toTQPoint()); + vec[1] = controller->windowToView((*control1).point().toTQPoint()); + vec[2] = controller->windowToView((*control2).point().toTQPoint()); + vec[3] = controller->windowToView((*destination).point().toTQPoint()); + gc.drawCubicBezier(vec); + } + + point += 1; + + return point; +} + +void KisToolBezier::drawPivotHandle (KisCanvasPainter& gc, KisCurve::iterator point) +{ + if ((*point).hint() != BEZIERENDHINT) + return; + + KisCanvasController *controller = m_subject->canvasController(); + + TQPoint endpPos = controller->windowToView((*point).point().toTQPoint()); + + if (!m_derivated->groupSelected(point)) { + gc.setPen(m_pivotPen); + gc.drawRoundRect(pivotRect(endpPos),m_pivotRounding,m_pivotRounding); + } else { + TQPoint nextControlPos = controller->windowToView((*point.next()).point().toTQPoint()); + TQPoint prevControlPos = controller->windowToView((*point.previousPivot()).point().toTQPoint()); + + gc.setPen(m_selectedPivotPen); + gc.drawRoundRect(selectedPivotRect(endpPos),m_selectedPivotRounding,m_selectedPivotRounding); + if ((prevControlPos != endpPos || nextControlPos != endpPos) && !(m_actionOptions & CONTROLOPTION)) { + gc.drawRoundRect(pivotRect(nextControlPos),m_pivotRounding,m_pivotRounding); + gc.drawLine(endpPos,nextControlPos); + gc.drawRoundRect(pivotRect(prevControlPos),m_pivotRounding,m_pivotRounding); + gc.drawLine(prevControlPos,endpPos); + } + } + + gc.setPen(m_drawingPen); +} + +#include "kis_tool_bezier.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc deleted file mode 100644 index 06f34f8c..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* - * kis_tool_curve.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_cmb_composite.h" -#include "kis_colorspace.h" -#include "kis_config.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_global.h" -#include "kis_image.h" -#include "kis_int_spinbox.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_point.h" -#include "kis_tool_controller.h" -#include "kis_tool_paint.h" - -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_canvas_subject.h" - -#include "kis_curve_framework.h" -#include "kis_tool_bezier_paint.h" - -KisToolBezierPaint::KisToolBezierPaint() - : super(i18n("Bezier Painting Tool")) -{ - setName("tool_bezier_paint"); - m_cursor = "tool_bezier_cursor.png"; - setCursor(KisCursor::load(m_cursor, 6, 6)); -} - -KisToolBezierPaint::~KisToolBezierPaint() -{ - -} - -KisCurve::iterator KisToolBezierPaint::paintPoint (KisPainter& painter, KisCurve::iterator point) -{ - KisCurve::iterator origin,destination,control1,control2; - switch ((*point).hint()) { - case BEZIERENDHINT: - origin = point++; - control1 = point; - control2 = control1.nextPivot(); - destination = control2.next(); - if (m_curve->count() > 4 && (*point) != m_curve->last()) { - point = point.nextPivot().next(); - painter.paintAt((*origin).point(),PRESSURE_DEFAULT,0,0); - painter.paintBezierCurve((*origin).point(),PRESSURE_DEFAULT,0,0,(*control1).point(), - (*control2).point(),(*destination).point(),PRESSURE_DEFAULT,0,0,0); - } - break; - default: - point = super::paintPoint(painter,point); - } - - return point; -} - -void KisToolBezierPaint::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Bezier"), - "tool_bezier_paint", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw cubic beziers. Keep Alt, Control or Shift pressed for options. Return or double-click to finish.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_bezier_paint.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp new file mode 100644 index 00000000..a8d1514b --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp @@ -0,0 +1,115 @@ +/* + * kis_tool_curve.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_cmb_composite.h" +#include "kis_colorspace.h" +#include "kis_config.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_global.h" +#include "kis_image.h" +#include "kis_int_spinbox.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_point.h" +#include "kis_tool_controller.h" +#include "kis_tool_paint.h" + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_canvas_subject.h" + +#include "kis_curve_framework.h" +#include "kis_tool_bezier_paint.h" + +KisToolBezierPaint::KisToolBezierPaint() + : super(i18n("Bezier Painting Tool")) +{ + setName("tool_bezier_paint"); + m_cursor = "tool_bezier_cursor.png"; + setCursor(KisCursor::load(m_cursor, 6, 6)); +} + +KisToolBezierPaint::~KisToolBezierPaint() +{ + +} + +KisCurve::iterator KisToolBezierPaint::paintPoint (KisPainter& painter, KisCurve::iterator point) +{ + KisCurve::iterator origin,destination,control1,control2; + switch ((*point).hint()) { + case BEZIERENDHINT: + origin = point++; + control1 = point; + control2 = control1.nextPivot(); + destination = control2.next(); + if (m_curve->count() > 4 && (*point) != m_curve->last()) { + point = point.nextPivot().next(); + painter.paintAt((*origin).point(),PRESSURE_DEFAULT,0,0); + painter.paintBezierCurve((*origin).point(),PRESSURE_DEFAULT,0,0,(*control1).point(), + (*control2).point(),(*destination).point(),PRESSURE_DEFAULT,0,0,0); + } + break; + default: + point = super::paintPoint(painter,point); + } + + return point; +} + +void KisToolBezierPaint::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Bezier"), + "tool_bezier_paint", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw cubic beziers. Keep Alt, Control or Shift pressed for options. Return or double-click to finish.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_bezier_paint.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc deleted file mode 100644 index 72418920..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * kis_tool_curve.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_cmb_composite.h" -#include "kis_colorspace.h" -#include "kis_config.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_global.h" -#include "kis_image.h" -#include "kis_int_spinbox.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_point.h" -#include "kis_tool_controller.h" -#include "kis_tool_paint.h" - -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_canvas_subject.h" - -#include "kis_curve_framework.h" -#include "kis_tool_bezier_select.h" - -KisToolBezierSelect::KisToolBezierSelect() - : super(i18n("Bezier Selection Tool")) -{ - setName("tool_bezier_select"); - m_cursor = "tool_bezier_cursor.png"; - setCursor(KisCursor::load(m_cursor, 6, 6)); -} - -KisToolBezierSelect::~KisToolBezierSelect() -{ - -} - -TQValueVector KisToolBezierSelect::convertCurve() -{ - TQValueVector points; - - for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) { - if (((*i).hint() != BEZIERPREVCONTROLHINT) && ((*i).hint() != BEZIERNEXTCONTROLHINT)) - points.append((*i).point()); - } - - return points; -} - -void KisToolBezierSelect::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Bezier"), - "tool_bezier_select", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Select areas of the image with bezier paths.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_bezier_select.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp new file mode 100644 index 00000000..65735860 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp @@ -0,0 +1,104 @@ +/* + * kis_tool_curve.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_cmb_composite.h" +#include "kis_colorspace.h" +#include "kis_config.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_global.h" +#include "kis_image.h" +#include "kis_int_spinbox.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_point.h" +#include "kis_tool_controller.h" +#include "kis_tool_paint.h" + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_canvas_subject.h" + +#include "kis_curve_framework.h" +#include "kis_tool_bezier_select.h" + +KisToolBezierSelect::KisToolBezierSelect() + : super(i18n("Bezier Selection Tool")) +{ + setName("tool_bezier_select"); + m_cursor = "tool_bezier_cursor.png"; + setCursor(KisCursor::load(m_cursor, 6, 6)); +} + +KisToolBezierSelect::~KisToolBezierSelect() +{ + +} + +TQValueVector KisToolBezierSelect::convertCurve() +{ + TQValueVector points; + + for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) { + if (((*i).hint() != BEZIERPREVCONTROLHINT) && ((*i).hint() != BEZIERNEXTCONTROLHINT)) + points.append((*i).point()); + } + + return points; +} + +void KisToolBezierSelect::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Bezier"), + "tool_bezier_select", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Select areas of the image with bezier paths.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_bezier_select.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_curve.cc b/chalk/plugins/tools/tool_curves/kis_tool_curve.cc deleted file mode 100644 index 7449e581..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_curve.cc +++ /dev/null @@ -1,593 +0,0 @@ -/* - * kis_tool_curve.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_tool_controller.h" -#include "kis_vec.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" -#include "kis_paintop_registry.h" - -#include "kis_curve_framework.h" -#include "kis_tool_curve.h" - -TQRect KisToolCurve::pivotRect (const TQPoint& pos) -{ - return TQRect (pos-TQPoint(4,4),pos+TQPoint(4,4)); -} - -TQRect KisToolCurve::selectedPivotRect (const TQPoint& pos) -{ - return TQRect (pos-TQPoint(5,5),pos+TQPoint(5,5)); -} - -KisToolCurve::KisToolCurve(const TQString& UIName) - : super(UIName) -{ - m_UIName = UIName; - m_currentImage = 0; - m_optWidget = 0; - - m_curve = 0; - - m_dragging = false; - m_draggingCursor = false; - m_drawPivots = true; - m_drawingPen = TQPen(TQt::white, 0, TQt::SolidLine); - m_pivotPen = TQPen(TQt::gray, 0, TQt::SolidLine); - m_selectedPivotPen = TQPen(TQt::yellow, 0, TQt::SolidLine); - m_pivotRounding = m_selectedPivotRounding = 55; - - m_actionOptions = NOOPTIONS; - m_supportMinimalDraw = true; - m_selectAction = SELECTION_ADD; -} - -KisToolCurve::~KisToolCurve() -{ - -} - -void KisToolCurve::update (KisCanvasSubject *subject) -{ - super::update(subject); - if (m_subject) - m_currentImage = m_subject->currentImg(); -} - -void KisToolCurve::deactivate() -{ - draw(false); - if (m_curve) { - m_curve->clear(); - m_curve->endActionOptions(); - } - - m_actionOptions = NOOPTIONS; - m_dragging = false; - m_drawPivots = true; -} - -void KisToolCurve::buttonPress(KisButtonPressEvent *event) -{ - updateOptions(event->state()); - if (!m_currentImage) - return; - if (event->button() == Qt::LeftButton) { - m_dragging = true; - m_currentPoint = event->pos(); - PointPair temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !(m_actionOptions)) { - draw(true, true); - m_curve->selectAll(false); - draw(true, true); - draw(m_curve->end()); - m_previous = m_curve->find(m_curve->last()); - m_current = m_curve->pushPivot(event->pos()); - if (m_curve->pivots().count() > 1) - m_curve->calculateCurve(m_previous,m_current,m_current); - draw(m_current); - } else { - draw(true, true); - if (temp.second) - m_current = m_curve->selectPivot(temp.first); - else - m_current = selectByMouse(temp.first); - - if (!(*m_current).isSelected()) - m_dragging = false; - draw(true, true); - } - } -} - -void KisToolCurve::keyPress(TQKeyEvent *event) -{ - if (event->key() == TQt::Key_Return) { - m_dragging = false; - commitCurve(); - } else - if (event->key() == TQt::Key_Escape) { - m_dragging = false; - draw(false); - m_curve->clear(); - } else - if (event->key() == TQt::Key_Delete) { - draw(false); - m_dragging = false; - m_curve->deleteSelected(); - m_current = m_curve->find(m_curve->last()); - m_previous = m_curve->selectPivot(m_current); - draw(false); - } -} - -void KisToolCurve::keyRelease(TQKeyEvent *) -{ - -} - -void KisToolCurve::buttonRelease(KisButtonReleaseEvent *event) -{ - updateOptions(event->state()); - m_dragging = false; -} - -void KisToolCurve::doubleClick(KisDoubleClickEvent *) -{ - commitCurve(); -} - -void KisToolCurve::move(KisMoveEvent *event) -{ - updateOptions(event->state()); - PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !m_dragging) { - if (m_draggingCursor) { - setCursor(KisCursor::load(m_cursor, 6, 6)); - m_draggingCursor = false; - } - } else { - setCursor(KisCursor::load("tool_curve_dragging.png", 6, 6)); - m_draggingCursor = true; - } - if (m_dragging) { - draw(); - KisPoint trans = event->pos() - m_currentPoint; - m_curve->moveSelected(trans); - m_currentPoint = event->pos(); - draw(); - } -} - -double pointToSegmentDistance(const KisPoint& p, const KisPoint& l0, const KisPoint& l1) -{ - double lineLength = sqrt((l1.x() - l0.x()) * (l1.x() - l0.x()) + (l1.y() - l0.y()) * (l1.y() - l0.y())); - double distance = 0; - KisVector2D v0(l0), v1(l1), v(p), seg(v0-v1), dist0(v0-p), dist1(v1-p); - - if (seg.length() < dist0.length() || - seg.length() < dist1.length()) // the point doesn't perpendicolarly intersecate the segment (or it's too far from the segment) - return (double)INT_MAX; - - if (lineLength > DBL_EPSILON) { - distance = ((l0.y() - l1.y()) * p.x() + (l1.x() - l0.x()) * p.y() + l0.x() * l1.y() - l1.x() * l0.y()) / lineLength; - distance = fabs(distance); - } - - return distance; -} - -PointPair KisToolCurve::pointUnderMouse(const TQPoint& pos) -{ - KisCurve::iterator it, next; - TQPoint pos1, pos2; - it = handleUnderMouse(pos); - if (it != m_curve->end()) - return PointPair(it,true); - - for (it = m_curve->begin(); it != m_curve->end(); it++) { - next = it.next(); - if (next == m_curve->end() || it == m_curve->end()) - return PointPair(m_curve->end(),false); - if ((*it).hint() > LINEHINT || (*next).hint() > LINEHINT) - continue; - pos1 = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); - pos2 = m_subject->canvasController()->windowToView((*next).point().toTQPoint()); - if (pos1 == pos2) - continue; - if (pointToSegmentDistance(pos,pos1,pos2) <= MAXDISTANCE) - break; - } - - return PointPair(it,false); -} - -KisCurve::iterator KisToolCurve::handleUnderMouse(const TQPoint& pos) -{ - KisCurve pivs = m_curve->pivots(), inHandle; - KisCurve::iterator it; - for (it = pivs.begin(); it != pivs.end(); it++) { - if (pivotRect(m_subject->canvasController()->windowToView((*it).point().toTQPoint())).contains(pos)) - inHandle.pushPoint((*it)); - } - if (inHandle.isEmpty()) - return m_curve->end(); - return m_curve->find(inHandle.last()); -} - -KisCurve::iterator KisToolCurve::selectByMouse(KisCurve::iterator it) -{ - KisCurve::iterator prevPivot, nextPivot; - - if ((*it).isPivot()) - prevPivot = it; - else - prevPivot = it.previousPivot(); - nextPivot = it.nextPivot(); - - m_curve->selectPivot(prevPivot); - (*nextPivot).setSelected(true); - - return prevPivot; -} - -int KisToolCurve::updateOptions(int key) -{ - int options = 0x0000; - - if (key & TQt::ControlButton) - options |= CONTROLOPTION; - - if (key & TQt::ShiftButton) - options |= SHIFTOPTION; - - if (key & TQt::AltButton) - options |= ALTOPTION; - - if (options != m_actionOptions) { - draw(false); - m_actionOptions = options; - m_curve->setActionOptions(m_actionOptions); - draw(false); - } - - return m_actionOptions; -} - -void KisToolCurve::draw(bool m, bool o) -{ - draw(KisCurve::iterator(), o, m); -} - -void KisToolCurve::draw(KisCurve::iterator inf, bool pivotonly, bool minimal) -{ - if (m_curve->isEmpty()) - return; - KisCanvasPainter *gc; - KisCanvasController *controller; - KisCanvas *canvas; - if (m_subject && m_currentImage) { - controller = m_subject->canvasController(); - canvas = controller->kiscanvas(); - gc = new KisCanvasPainter(canvas); - } else - return; - - gc->setPen(m_drawingPen); - gc->setRasterOp(TQt::XorROP); - - KisCurve::iterator it, finish; - - if (minimal && m_supportMinimalDraw) { - if (pivotonly) { - KisCurve p = m_curve->pivots(); - for (KisCurve::iterator i = p.begin(); i != p.end(); i++) - drawPivotHandle (*gc, i); - delete gc; - return; - } - if (inf.target() != 0) { - if (inf != m_curve->end()) { - it = inf.previousPivot(); - finish = inf.nextPivot(); - } else { - it = --m_curve->end(); - finish = m_curve->end(); - } - } else { - KisCurve sel = m_curve->selectedPivots(); - if (sel.isEmpty()) { - delete gc; - return; - } - for (KisCurve::iterator i = sel.begin(); i != sel.end(); i++) { - it = m_curve->find(*i).previousPivot(); - finish = m_curve->find(*i).nextPivot(); - if ((*finish).isSelected()) - finish = finish.previousPivot(); - while (it != finish) { - if ((*it).isPivot()) - drawPivotHandle (*gc, it); - it = drawPoint (*gc, it); - } - } - delete gc; - return; - } - } else { - it = m_curve->begin(); - finish = m_curve->end(); - } - while (it != finish) { - if ((*it).isPivot()) - drawPivotHandle (*gc, it); - it = drawPoint (*gc, it); - } - - delete gc; -} - -KisCurve::iterator KisToolCurve::drawPoint(KisCanvasPainter& gc, KisCurve::iterator point) -{ - KisCanvasController *controller = m_subject->canvasController(); - - TQPoint pos1, pos2; - pos1 = controller->windowToView((*point).point().toTQPoint()); - - switch ((*point).hint()) { - case POINTHINT: - gc.drawPoint(pos1); - point += 1; - break; - case LINEHINT: - gc.drawPoint(pos1); - if (++point != m_curve->end() && (*point).hint() <= LINEHINT) { - pos2 = controller->windowToView((*point).point().toTQPoint()); - gc.drawLine(pos1,pos2); - } - break; - default: - point += 1; - } - - return point; -} - -void KisToolCurve::drawPivotHandle(KisCanvasPainter& gc, KisCurve::iterator point) -{ - KisCanvasController *controller = m_subject->canvasController(); - - if (m_drawPivots) { - TQPoint pos = controller->windowToView((*point).point().toTQPoint()); - if ((*point).isSelected()) { - gc.setPen(m_selectedPivotPen); - gc.drawRoundRect(selectedPivotRect(pos),m_selectedPivotRounding,m_selectedPivotRounding); - } else { - gc.setPen(m_pivotPen); - gc.drawRoundRect(pivotRect(pos),m_pivotRounding,m_pivotRounding); - } - gc.setPen(m_drawingPen); - } -} - -void KisToolCurve::paint(KisCanvasPainter&) -{ - draw(false); -} - -void KisToolCurve::paint(KisCanvasPainter&, const TQRect&) -{ - draw(false); -} - -void KisToolCurve::commitCurve() -{ - if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) - paintCurve(); - else if (toolType() == TOOL_SELECT) - selectCurve(); - else - kdDebug(0) << "NO SUPPORT FOR THIS TYPE OF TOOL" << endl; - - m_curve->clear(); - m_curve->endActionOptions(); -} - -void KisToolCurve::paintCurve() -{ - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (m_transactionMessage); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - -// Call paintPoint - KisCurve::iterator it = m_curve->begin(); - while (it != m_curve->end()) - it = paintPoint(painter,it); -// Finish - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - - draw(false); -} - -KisCurve::iterator KisToolCurve::paintPoint (KisPainter& painter, KisCurve::iterator point) -{ - KisCurve::iterator next = point; next+=1; - switch ((*point).hint()) { - case POINTHINT: - painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); - break; - case LINEHINT: - if (next != m_curve->end() && (*next).hint() <= LINEHINT) - painter.paintLine((*point++).point(), PRESSURE_DEFAULT, 0, 0, (*next).point(), PRESSURE_DEFAULT, 0, 0); - else - painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); - break; - default: - point += 1; - } - - return point; -} - -TQValueVector KisToolCurve::convertCurve() -{ - TQValueVector points; - - for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) - if ((*i).hint() != NOHINTS) - points.append((*i).point()); - - return points; -} - -void KisToolCurve::selectCurve() -{ - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = m_currentImage->activeDevice(); - bool hasSelection = dev->hasSelection(); - KisSelectedTransaction *t = 0; - if (m_currentImage->undo()) t = new KisSelectedTransaction(m_transactionMessage, dev); - KisSelectionSP selection = dev->selection(); - - if (!hasSelection) { - selection->clear(); - } - - KisPainter painter(selection.data()); - - painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.setStrokeStyle(KisPainter::StrokeStyleNone); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(OPACITY_OPAQUE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); - painter.setPaintOp(op); // And now the painter owns the op and will destroy it. - - switch (m_selectAction) { - case SELECTION_ADD: - painter.setCompositeOp(COMPOSITE_OVER); - break; - case SELECTION_SUBTRACT: - painter.setCompositeOp(COMPOSITE_SUBTRACT); - break; - default: - break; - } - - painter.paintPolygon(convertCurve()); - - - if(hasSelection) { - TQRect dirty(painter.dirtyRect()); - dev->setDirty(dirty); - dev->emitSelectionChanged(dirty); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (m_currentImage->undo()) - m_currentImage->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - - draw(false); -} - -TQWidget* KisToolCurve::createOptionWidget(TQWidget* parent) -{ - if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) - return super::createOptionWidget(parent); - else if (toolType() == TOOL_SELECT) - return createSelectionOptionWidget(parent); - else - kdDebug(0) << "NO SUPPORT FOR THIS TOOL TYPE" << endl; - return 0; -} - -void KisToolCurve::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -TQWidget* KisToolCurve::createSelectionOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(m_UIName); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolCurve::optionWidget() -{ - if (toolType() == TOOL_SELECT) - return m_optWidget; - else - return super::optionWidget(); -} - -#include "kis_tool_curve.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_curve.cpp b/chalk/plugins/tools/tool_curves/kis_tool_curve.cpp new file mode 100644 index 00000000..ea1f9a77 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_curve.cpp @@ -0,0 +1,593 @@ +/* + * kis_tool_curve.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_tool_controller.h" +#include "kis_vec.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" +#include "kis_paintop_registry.h" + +#include "kis_curve_framework.h" +#include "kis_tool_curve.h" + +TQRect KisToolCurve::pivotRect (const TQPoint& pos) +{ + return TQRect (pos-TQPoint(4,4),pos+TQPoint(4,4)); +} + +TQRect KisToolCurve::selectedPivotRect (const TQPoint& pos) +{ + return TQRect (pos-TQPoint(5,5),pos+TQPoint(5,5)); +} + +KisToolCurve::KisToolCurve(const TQString& UIName) + : super(UIName) +{ + m_UIName = UIName; + m_currentImage = 0; + m_optWidget = 0; + + m_curve = 0; + + m_dragging = false; + m_draggingCursor = false; + m_drawPivots = true; + m_drawingPen = TQPen(TQt::white, 0, TQt::SolidLine); + m_pivotPen = TQPen(TQt::gray, 0, TQt::SolidLine); + m_selectedPivotPen = TQPen(TQt::yellow, 0, TQt::SolidLine); + m_pivotRounding = m_selectedPivotRounding = 55; + + m_actionOptions = NOOPTIONS; + m_supportMinimalDraw = true; + m_selectAction = SELECTION_ADD; +} + +KisToolCurve::~KisToolCurve() +{ + +} + +void KisToolCurve::update (KisCanvasSubject *subject) +{ + super::update(subject); + if (m_subject) + m_currentImage = m_subject->currentImg(); +} + +void KisToolCurve::deactivate() +{ + draw(false); + if (m_curve) { + m_curve->clear(); + m_curve->endActionOptions(); + } + + m_actionOptions = NOOPTIONS; + m_dragging = false; + m_drawPivots = true; +} + +void KisToolCurve::buttonPress(KisButtonPressEvent *event) +{ + updateOptions(event->state()); + if (!m_currentImage) + return; + if (event->button() == Qt::LeftButton) { + m_dragging = true; + m_currentPoint = event->pos(); + PointPair temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !(m_actionOptions)) { + draw(true, true); + m_curve->selectAll(false); + draw(true, true); + draw(m_curve->end()); + m_previous = m_curve->find(m_curve->last()); + m_current = m_curve->pushPivot(event->pos()); + if (m_curve->pivots().count() > 1) + m_curve->calculateCurve(m_previous,m_current,m_current); + draw(m_current); + } else { + draw(true, true); + if (temp.second) + m_current = m_curve->selectPivot(temp.first); + else + m_current = selectByMouse(temp.first); + + if (!(*m_current).isSelected()) + m_dragging = false; + draw(true, true); + } + } +} + +void KisToolCurve::keyPress(TQKeyEvent *event) +{ + if (event->key() == TQt::Key_Return) { + m_dragging = false; + commitCurve(); + } else + if (event->key() == TQt::Key_Escape) { + m_dragging = false; + draw(false); + m_curve->clear(); + } else + if (event->key() == TQt::Key_Delete) { + draw(false); + m_dragging = false; + m_curve->deleteSelected(); + m_current = m_curve->find(m_curve->last()); + m_previous = m_curve->selectPivot(m_current); + draw(false); + } +} + +void KisToolCurve::keyRelease(TQKeyEvent *) +{ + +} + +void KisToolCurve::buttonRelease(KisButtonReleaseEvent *event) +{ + updateOptions(event->state()); + m_dragging = false; +} + +void KisToolCurve::doubleClick(KisDoubleClickEvent *) +{ + commitCurve(); +} + +void KisToolCurve::move(KisMoveEvent *event) +{ + updateOptions(event->state()); + PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !m_dragging) { + if (m_draggingCursor) { + setCursor(KisCursor::load(m_cursor, 6, 6)); + m_draggingCursor = false; + } + } else { + setCursor(KisCursor::load("tool_curve_dragging.png", 6, 6)); + m_draggingCursor = true; + } + if (m_dragging) { + draw(); + KisPoint trans = event->pos() - m_currentPoint; + m_curve->moveSelected(trans); + m_currentPoint = event->pos(); + draw(); + } +} + +double pointToSegmentDistance(const KisPoint& p, const KisPoint& l0, const KisPoint& l1) +{ + double lineLength = sqrt((l1.x() - l0.x()) * (l1.x() - l0.x()) + (l1.y() - l0.y()) * (l1.y() - l0.y())); + double distance = 0; + KisVector2D v0(l0), v1(l1), v(p), seg(v0-v1), dist0(v0-p), dist1(v1-p); + + if (seg.length() < dist0.length() || + seg.length() < dist1.length()) // the point doesn't perpendicolarly intersecate the segment (or it's too far from the segment) + return (double)INT_MAX; + + if (lineLength > DBL_EPSILON) { + distance = ((l0.y() - l1.y()) * p.x() + (l1.x() - l0.x()) * p.y() + l0.x() * l1.y() - l1.x() * l0.y()) / lineLength; + distance = fabs(distance); + } + + return distance; +} + +PointPair KisToolCurve::pointUnderMouse(const TQPoint& pos) +{ + KisCurve::iterator it, next; + TQPoint pos1, pos2; + it = handleUnderMouse(pos); + if (it != m_curve->end()) + return PointPair(it,true); + + for (it = m_curve->begin(); it != m_curve->end(); it++) { + next = it.next(); + if (next == m_curve->end() || it == m_curve->end()) + return PointPair(m_curve->end(),false); + if ((*it).hint() > LINEHINT || (*next).hint() > LINEHINT) + continue; + pos1 = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); + pos2 = m_subject->canvasController()->windowToView((*next).point().toTQPoint()); + if (pos1 == pos2) + continue; + if (pointToSegmentDistance(pos,pos1,pos2) <= MAXDISTANCE) + break; + } + + return PointPair(it,false); +} + +KisCurve::iterator KisToolCurve::handleUnderMouse(const TQPoint& pos) +{ + KisCurve pivs = m_curve->pivots(), inHandle; + KisCurve::iterator it; + for (it = pivs.begin(); it != pivs.end(); it++) { + if (pivotRect(m_subject->canvasController()->windowToView((*it).point().toTQPoint())).contains(pos)) + inHandle.pushPoint((*it)); + } + if (inHandle.isEmpty()) + return m_curve->end(); + return m_curve->find(inHandle.last()); +} + +KisCurve::iterator KisToolCurve::selectByMouse(KisCurve::iterator it) +{ + KisCurve::iterator prevPivot, nextPivot; + + if ((*it).isPivot()) + prevPivot = it; + else + prevPivot = it.previousPivot(); + nextPivot = it.nextPivot(); + + m_curve->selectPivot(prevPivot); + (*nextPivot).setSelected(true); + + return prevPivot; +} + +int KisToolCurve::updateOptions(int key) +{ + int options = 0x0000; + + if (key & TQt::ControlButton) + options |= CONTROLOPTION; + + if (key & TQt::ShiftButton) + options |= SHIFTOPTION; + + if (key & TQt::AltButton) + options |= ALTOPTION; + + if (options != m_actionOptions) { + draw(false); + m_actionOptions = options; + m_curve->setActionOptions(m_actionOptions); + draw(false); + } + + return m_actionOptions; +} + +void KisToolCurve::draw(bool m, bool o) +{ + draw(KisCurve::iterator(), o, m); +} + +void KisToolCurve::draw(KisCurve::iterator inf, bool pivotonly, bool minimal) +{ + if (m_curve->isEmpty()) + return; + KisCanvasPainter *gc; + KisCanvasController *controller; + KisCanvas *canvas; + if (m_subject && m_currentImage) { + controller = m_subject->canvasController(); + canvas = controller->kiscanvas(); + gc = new KisCanvasPainter(canvas); + } else + return; + + gc->setPen(m_drawingPen); + gc->setRasterOp(TQt::XorROP); + + KisCurve::iterator it, finish; + + if (minimal && m_supportMinimalDraw) { + if (pivotonly) { + KisCurve p = m_curve->pivots(); + for (KisCurve::iterator i = p.begin(); i != p.end(); i++) + drawPivotHandle (*gc, i); + delete gc; + return; + } + if (inf.target() != 0) { + if (inf != m_curve->end()) { + it = inf.previousPivot(); + finish = inf.nextPivot(); + } else { + it = --m_curve->end(); + finish = m_curve->end(); + } + } else { + KisCurve sel = m_curve->selectedPivots(); + if (sel.isEmpty()) { + delete gc; + return; + } + for (KisCurve::iterator i = sel.begin(); i != sel.end(); i++) { + it = m_curve->find(*i).previousPivot(); + finish = m_curve->find(*i).nextPivot(); + if ((*finish).isSelected()) + finish = finish.previousPivot(); + while (it != finish) { + if ((*it).isPivot()) + drawPivotHandle (*gc, it); + it = drawPoint (*gc, it); + } + } + delete gc; + return; + } + } else { + it = m_curve->begin(); + finish = m_curve->end(); + } + while (it != finish) { + if ((*it).isPivot()) + drawPivotHandle (*gc, it); + it = drawPoint (*gc, it); + } + + delete gc; +} + +KisCurve::iterator KisToolCurve::drawPoint(KisCanvasPainter& gc, KisCurve::iterator point) +{ + KisCanvasController *controller = m_subject->canvasController(); + + TQPoint pos1, pos2; + pos1 = controller->windowToView((*point).point().toTQPoint()); + + switch ((*point).hint()) { + case POINTHINT: + gc.drawPoint(pos1); + point += 1; + break; + case LINEHINT: + gc.drawPoint(pos1); + if (++point != m_curve->end() && (*point).hint() <= LINEHINT) { + pos2 = controller->windowToView((*point).point().toTQPoint()); + gc.drawLine(pos1,pos2); + } + break; + default: + point += 1; + } + + return point; +} + +void KisToolCurve::drawPivotHandle(KisCanvasPainter& gc, KisCurve::iterator point) +{ + KisCanvasController *controller = m_subject->canvasController(); + + if (m_drawPivots) { + TQPoint pos = controller->windowToView((*point).point().toTQPoint()); + if ((*point).isSelected()) { + gc.setPen(m_selectedPivotPen); + gc.drawRoundRect(selectedPivotRect(pos),m_selectedPivotRounding,m_selectedPivotRounding); + } else { + gc.setPen(m_pivotPen); + gc.drawRoundRect(pivotRect(pos),m_pivotRounding,m_pivotRounding); + } + gc.setPen(m_drawingPen); + } +} + +void KisToolCurve::paint(KisCanvasPainter&) +{ + draw(false); +} + +void KisToolCurve::paint(KisCanvasPainter&, const TQRect&) +{ + draw(false); +} + +void KisToolCurve::commitCurve() +{ + if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) + paintCurve(); + else if (toolType() == TOOL_SELECT) + selectCurve(); + else + kdDebug(0) << "NO SUPPORT FOR THIS TYPE OF TOOL" << endl; + + m_curve->clear(); + m_curve->endActionOptions(); +} + +void KisToolCurve::paintCurve() +{ + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (m_transactionMessage); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + +// Call paintPoint + KisCurve::iterator it = m_curve->begin(); + while (it != m_curve->end()) + it = paintPoint(painter,it); +// Finish + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + + draw(false); +} + +KisCurve::iterator KisToolCurve::paintPoint (KisPainter& painter, KisCurve::iterator point) +{ + KisCurve::iterator next = point; next+=1; + switch ((*point).hint()) { + case POINTHINT: + painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); + break; + case LINEHINT: + if (next != m_curve->end() && (*next).hint() <= LINEHINT) + painter.paintLine((*point++).point(), PRESSURE_DEFAULT, 0, 0, (*next).point(), PRESSURE_DEFAULT, 0, 0); + else + painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); + break; + default: + point += 1; + } + + return point; +} + +TQValueVector KisToolCurve::convertCurve() +{ + TQValueVector points; + + for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) + if ((*i).hint() != NOHINTS) + points.append((*i).point()); + + return points; +} + +void KisToolCurve::selectCurve() +{ + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = m_currentImage->activeDevice(); + bool hasSelection = dev->hasSelection(); + KisSelectedTransaction *t = 0; + if (m_currentImage->undo()) t = new KisSelectedTransaction(m_transactionMessage, dev); + KisSelectionSP selection = dev->selection(); + + if (!hasSelection) { + selection->clear(); + } + + KisPainter painter(selection.data()); + + painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); + painter.setFillStyle(KisPainter::FillStyleForegroundColor); + painter.setStrokeStyle(KisPainter::StrokeStyleNone); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(OPACITY_OPAQUE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); + painter.setPaintOp(op); // And now the painter owns the op and will destroy it. + + switch (m_selectAction) { + case SELECTION_ADD: + painter.setCompositeOp(COMPOSITE_OVER); + break; + case SELECTION_SUBTRACT: + painter.setCompositeOp(COMPOSITE_SUBTRACT); + break; + default: + break; + } + + painter.paintPolygon(convertCurve()); + + + if(hasSelection) { + TQRect dirty(painter.dirtyRect()); + dev->setDirty(dirty); + dev->emitSelectionChanged(dirty); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (m_currentImage->undo()) + m_currentImage->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + + draw(false); +} + +TQWidget* KisToolCurve::createOptionWidget(TQWidget* parent) +{ + if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) + return super::createOptionWidget(parent); + else if (toolType() == TOOL_SELECT) + return createSelectionOptionWidget(parent); + else + kdDebug(0) << "NO SUPPORT FOR THIS TOOL TYPE" << endl; + return 0; +} + +void KisToolCurve::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +TQWidget* KisToolCurve::createSelectionOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(m_UIName); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolCurve::optionWidget() +{ + if (toolType() == TOOL_SELECT) + return m_optWidget; + else + return super::optionWidget(); +} + +#include "kis_tool_curve.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_example.cc b/chalk/plugins/tools/tool_curves/kis_tool_example.cc deleted file mode 100644 index 75e3da2b..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_example.cc +++ /dev/null @@ -1,108 +0,0 @@ -/* - * kis_tool_example.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_vec.h" - -#include "kis_curve_framework.h" - -#include "kis_tool_example.h" - - -class KisCurveExample : public KisCurve { - - typedef KisCurve super; - -public: - - KisCurveExample() : super() {} - - ~KisCurveExample() {} - - virtual iterator pushPivot (const KisPoint&); - -}; - -KisCurve::iterator KisCurveExample::pushPivot (const KisPoint& point) -{ - return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,LINEHINT))), true); -} - -KisToolExample::KisToolExample() - : super(i18n("Tool for Curves - Example")) -{ - setName("tool_example"); - m_cursor = "tool_example_cursor.png"; - setCursor(KisCursor::load(m_cursor, 6, 6)); - - m_curve = new KisCurveExample; -} - -KisToolExample::~KisToolExample() -{ - -} - -void KisToolExample::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Example"), - "tool_example", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("This is a test tool for the Curve Framework.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_example.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_example.cpp b/chalk/plugins/tools/tool_curves/kis_tool_example.cpp new file mode 100644 index 00000000..a21bb808 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_example.cpp @@ -0,0 +1,108 @@ +/* + * kis_tool_example.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_vec.h" + +#include "kis_curve_framework.h" + +#include "kis_tool_example.h" + + +class KisCurveExample : public KisCurve { + + typedef KisCurve super; + +public: + + KisCurveExample() : super() {} + + ~KisCurveExample() {} + + virtual iterator pushPivot (const KisPoint&); + +}; + +KisCurve::iterator KisCurveExample::pushPivot (const KisPoint& point) +{ + return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,LINEHINT))), true); +} + +KisToolExample::KisToolExample() + : super(i18n("Tool for Curves - Example")) +{ + setName("tool_example"); + m_cursor = "tool_example_cursor.png"; + setCursor(KisCursor::load(m_cursor, 6, 6)); + + m_curve = new KisCurveExample; +} + +KisToolExample::~KisToolExample() +{ + +} + +void KisToolExample::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Example"), + "tool_example", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("This is a test tool for the Curve Framework.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_example.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc deleted file mode 100644 index 178ff278..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc +++ /dev/null @@ -1,809 +0,0 @@ -/* - * kis_tool_moutline.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_iterators_pixel.h" -#include "kis_colorspace.h" -#include "kis_channelinfo.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_tool_controller.h" -#include "kis_vec.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" -#include "kis_paintop_registry.h" -#include "kis_convolution_painter.h" - -#include "kis_tool_moutline.h" - -using namespace std; - -#define RMS(a, b) (sqrt ((a) * (a) + (b) * (b))) -#define ROUND(x) ((int) ((x) + 0.5)) - -const int NOEDGE = 0x0000; - -const int ORTHOGONAL_COST = 10; // 1*10 -const int DIAGONAL_COST = 14; // sqrt(2)*10 -const int MALUS = 20; // This applies to NOEDGE nodes - -const int DEFAULTDIST = 40; // Default distance between two automatic pivots -const int MAXDIST = 55; // Max distance -const int MINDIST = 15; -const int PAGESTEP = 5; - -class Node { - - TQPoint m_pos; - int m_gCost; - int m_hCost; - int m_tCost; - bool m_malus; - TQPoint m_parent; - -public: - - Node() - { - m_pos = m_parent = TQPoint(-1,-1); - m_gCost = m_hCost = m_tCost = 0; - m_malus = false; - } - - Node(const Node& node) - { - m_pos = node.pos(); - m_gCost = node.gCost(); - m_hCost = node.hCost(); - m_tCost = node.tCost(); - m_malus = node.malus(); - m_parent = node.parent(); - } - - Node(const TQPoint& parent, const TQPoint& pos, int g, int h, bool malus) - : m_pos(pos), m_hCost(h), m_malus(malus) - { - setGCost(g); - m_parent = parent; - } - ~Node () - { - } - - int gCost () const {return m_gCost;} - int hCost () const {return m_hCost;} - int tCost () const {return m_tCost;} - bool malus () const {return m_malus;} - TQPoint pos () const {return m_pos;} - int col () const {return m_pos.x();} - int row () const {return m_pos.y();} - TQPoint parent () const {return m_parent;} - - void setGCost (int g) - { - m_gCost = g+(m_malus?MALUS:0); - m_tCost = m_gCost+m_hCost; - } - void setHCost (int h) - { - m_hCost = h; - m_tCost = m_gCost+m_hCost; - } - void setPos (const TQPoint& pos) - { - m_pos = pos; - } - void setMalus (bool malus) - { - m_malus = malus; - } - void clear () - { - m_pos = TQPoint(-1,-1); - } - - bool operator== (const Node& n2) const - { - return m_pos == n2.pos(); - } - bool operator!= (const Node& n2) const - { - return m_pos != n2.pos(); - } - bool operator== (const TQPoint& n2) const - { - return m_pos == n2; - } - bool operator!= (const TQPoint& n2) const - { - return m_pos != n2; - } - bool operator< (const Node& n2) const - { - return m_tCost < n2.tCost(); - } - bool operator> (const Node& n2) const - { - return m_tCost > n2.tCost(); - } - - TQValueList getNeighbor(const GrayMatrix& src, const Node& end) - { - TQPoint tmpdist; - TQValueList temp; - int dcol, drow; - int g, h; - bool malus; - int x[8] = { 1, 1, 0,-1,-1,-1, 0, 1}, - y[8] = { 0,-1,-1,-1, 0, 1, 1, 1}; - - for (int i = 0; i < 8; i++) { - dcol = m_pos.x() + x[i]; - drow = m_pos.y() + y[i]; - tmpdist = TQPoint(dcol,drow) - end.pos(); - // I use src[0] here because all cols have same number of rows - if (dcol == (int)src.count() || dcol < 0 || - drow == (int)src[0].count() || drow < 0) - continue; - if (src[dcol][drow]) - malus = false; - else - malus = true; - if (i%2) - g = m_gCost + DIAGONAL_COST; - else - g = m_gCost + ORTHOGONAL_COST; - h = ORTHOGONAL_COST * (abs(tmpdist.x()) + abs(tmpdist.y())); - temp.append(Node(m_pos,TQPoint(dcol,drow),g,h,malus)); - } - return temp; - } - -}; - -KisKernelSP createKernel( TQ_INT32 i0, TQ_INT32 i1, TQ_INT32 i2, - TQ_INT32 i3, TQ_INT32 i4, TQ_INT32 i5, - TQ_INT32 i6, TQ_INT32 i7, TQ_INT32 i8, - TQ_INT32 factor, TQ_INT32 offset ) -{ - KisKernelSP kernel = new KisKernel(); - kernel->width = 3; - kernel->height = 3; - - kernel->factor = factor; - kernel->offset = offset; - - kernel->data = new TQ_INT32[9]; - kernel->data[0] = i0; - kernel->data[1] = i1; - kernel->data[2] = i2; - kernel->data[3] = i3; - kernel->data[4] = i4; - kernel->data[5] = i5; - kernel->data[6] = i6; - kernel->data[7] = i7; - kernel->data[8] = i8; - - return kernel; -} - -KisCurveMagnetic::KisCurveMagnetic (KisToolMagnetic *parent) - : m_parent(parent) -{ - m_standardkeepselected = false; -} - -KisCurveMagnetic::~KisCurveMagnetic () -{ - -} - -KisCurve::iterator KisCurveMagnetic::addPivot (KisCurve::iterator it, const KisPoint& point) -{ - return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,LINEHINT))); -} - -KisCurve::iterator KisCurveMagnetic::pushPivot (const KisPoint& point) -{ - iterator it; - - it = pushPoint(point,true,false,LINEHINT); -// if (count() == 1 && !m_parent->editingMode()) -// addPoint(it,point,true,false,LINEHINT); - - return selectPivot(it); -} - -void KisCurveMagnetic::calculateCurve (KisCurve::iterator p1, KisCurve::iterator p2, KisCurve::iterator it) -{ - if (p1 == m_curve.end() || p2 == m_curve.end()) // It happens sometimes, for example on the first click - return; - if (m_parent->editingMode()) - return; - TQPoint start = (*p1).point().roundTQPoint(); - TQPoint end = (*p2).point().roundTQPoint(); - TQRect rc = TQRect(start,end).normalize(); - rc.setTopLeft(rc.topLeft()+TQPoint(-8,-8)); // Enlarge the view, so problems with gaussian blur can be removed - rc.setBottomRight(rc.bottomRight()+TQPoint(8,8)); // and we are able to find paths that go beyond the rect. - - KisPaintDeviceSP src = m_parent->m_currentImage->activeDevice(); - GrayMatrix dst = GrayMatrix(rc.width(),GrayCol(rc.height())); - - detectEdges (rc, src, dst); - reduceMatrix (rc, dst, 3, 3, 3, 3); - - Node startNode, endNode; - multiset openSet; - NodeMatrix openMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); - NodeMatrix closedMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); - - TQPoint tl(rc.topLeft().x(),rc.topLeft().y()); - start -= tl; // Relative to the matrix - end -= tl; // Relative to the matrix - - findEdge (start.x(), start.y(), dst, startNode); - openMatrix[startNode.col()][startNode.row()] = *openSet.insert(startNode); - endNode.setPos(end); - - while (!openSet.empty()) { - Node current = *openSet.begin(); - - openSet.erase(openSet.begin()); - openMatrix[current.col()][current.row()].clear(); - - TQValueList successors = current.getNeighbor(dst,endNode); - for (TQValueList::iterator i = successors.begin(); i != successors.end(); i++) { - int col = (*i).col(); - int row = (*i).row(); - if ((*i) == endNode) { - while (current.parent() != TQPoint(-1,-1)) { - it = addPoint(it,KisPoint(tl+current.pos()),false,false,LINEHINT); - current = closedMatrix[current.parent().x()][current.parent().y()]; - } - return; - } - Node *openNode = &openMatrix[col][row]; - if (*openNode != TQPoint(-1,-1)) { - if (*i > *openNode) - continue; - else { - openSet.erase(tqFind(openSet.begin(),openSet.end(),*openNode)); - openNode->clear(); // Clear the Node - } - } - Node *closedNode = &closedMatrix[col][row]; - if (*closedNode != TQPoint(-1,-1)) { - if ((*i) > (*closedNode)) - continue; - else { - openMatrix[col][row] = *openSet.insert(*closedNode); - closedNode->clear(); // Clear the Node - continue; - } - } - openMatrix[col][row] = *openSet.insert(*i); - } - closedMatrix[current.col()][current.row()] = current; - } -} - -void KisCurveMagnetic::findEdge (int col, int row, const GrayMatrix& src, Node& node) -{ - int x = -1; - int y = -1; - - // tmpdist out of range - KisVector2D mindist(5.0,5.0), tmpdist(1000.0,1000.0); - for (int i = -5; i < 6; i++) { - for (int j = -5; j < 6; j++) { - if (src[col+i][row+j] != NOEDGE) { - tmpdist = KisVector2D(i,j); - if (tmpdist.length() < mindist.length()) - mindist = tmpdist; - } - } - } - if (tmpdist.x() == 1000.0) - mindist = KisVector2D(0.0,0.0); - - x = (int)(col + mindist.x()); - y = (int)(row + mindist.y()); - - node.setPos(TQPoint(x,y)); -} - -void KisCurveMagnetic::reduceMatrix (TQRect& rc, GrayMatrix& m, int top, int right, int bottom, int left) -{ - TQPoint topleft(top, left); - TQPoint bottomright(bottom, right); - - rc.setTopLeft(rc.topLeft()+topleft); - rc.setBottomRight(rc.bottomRight()-bottomright); - - if (left) - m.erase(m.begin(),m.begin()+left); - if (right) - m.erase(m.end()-right,m.end()); - if (top) { - for (uint i = 0; i < m.count(); i++) - m[i].erase(m[i].begin(),m[i].begin()+top); - } - if (bottom) { - for (uint i = 0; i < m.count(); i++) - m[i].erase(m[i].end()-bottom,m[i].end()); - } -} - -void KisCurveMagnetic::detectEdges (const TQRect & rect, KisPaintDeviceSP src, GrayMatrix& dst) -{ - GrayMatrix graysrc(rect.width(),GrayCol(rect.height())); - GrayMatrix xdeltas(rect.width(),GrayCol(rect.height())); - GrayMatrix ydeltas(rect.width(),GrayCol(rect.height())); - GrayMatrix magnitude(rect.width(),GrayCol(rect.height())); - KisPaintDeviceSP smooth = new KisPaintDevice(src->colorSpace()); - - gaussianBlur(rect, src, smooth); - toGrayScale(rect, smooth, graysrc); - getDeltas(graysrc, xdeltas, ydeltas); - getMagnitude(xdeltas, ydeltas, magnitude); - nonMaxSupp(magnitude, xdeltas, ydeltas, dst); -} - -void KisCurveMagnetic::gaussianBlur (const TQRect& rect, KisPaintDeviceSP src, KisPaintDeviceSP dst) -{ - int grectx = rect.x(); - int grecty = rect.y(); - int grectw = rect.width(); - int grecth = rect.height(); - if (dst != src) { - KisPainter gc(dst); - gc.bitBlt(grectx, grecty, COMPOSITE_COPY, src, grectx, grecty, grectw, grecth); - gc.end(); - } - - KisConvolutionPainter painter( dst ); - // FIXME createKernel could create dynamic gaussian kernels having sigma as argument - KisKernelSP kernel = createKernel( 1, 1, 1, 1, 24, 1, 1, 1, 1, 32, 0); - painter.applyMatrix(kernel, grectx, grecty, grectw, grecth, BORDER_AVOID); -} - -void KisCurveMagnetic::toGrayScale (const TQRect& rect, KisPaintDeviceSP src, GrayMatrix& dst) -{ - int grectx = rect.x(); - int grecty = rect.y(); - int grectw = rect.width(); - int grecth = rect.height(); - TQColor c; - KisColorSpace *cs = src->colorSpace(); - - for (int row = 0; row < grecth; row++) { - KisHLineIteratorPixel srcIt = src->createHLineIterator(grectx, grecty+row, grectw, false); - for (int col = 0; col < grectw; col++) { - cs->toTQColor(srcIt.rawData(),&c); - dst[col][row] = tqGray(c.rgb()); - ++srcIt; - } - } -} - -void KisCurveMagnetic::getDeltas (const GrayMatrix& src, GrayMatrix& xdelta, GrayMatrix& ydelta) -{ - uint start = 1, xend = src[0].count()-1, yend = src.count()-1; - TQ_INT16 deri; - for (uint col = 0; col < src.count(); col++) { - for (uint row = 0; row < src[col].count(); row++) { - if (row >= start && row < xend) { - deri = src[col][row+1] - src[col][row-1]; - xdelta[col][row] = deri; - } else - xdelta[col][row] = 0; - if (col >= start && col < yend) { - deri = src[col+1][row] - src[col-1][row]; - ydelta[col][row] = deri; - } else - ydelta[col][row] = 0; - } - } -} - -void KisCurveMagnetic::getMagnitude (const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& gradient) -{ - for (uint col = 0; col < xdelta.count(); col++) { - for (uint row = 0; row < xdelta[col].count(); row++) - gradient[col][row] = (TQ_INT16)(ROUND(RMS(xdelta[col][row],ydelta[col][row]))); - } -} - -void KisCurveMagnetic::nonMaxSupp (const GrayMatrix& magnitude, const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& nms) -{ - // Directions: - // 1: 0 - 22.5 degrees - // 2: 22.5 - 67.5 degrees - // 3: 67.5 - 90 degrees - // Second direction is relative to a quadrant. The quadrant is known by looking at x and y derivatives - // First quadrant: Gx < 0 & Gy >= 0 - // Second quadrant: Gx < 0 & Gy < 0 - // Third quadrant: Gx >= 0 & Gy < 0 - // Fourth quadrant: Gx >= 0 & Gy >= 0 - // For this reason: first direction is relative to Gy only and third direction to Gx only - - double theta; // theta = invtan (|Gy| / |Gx|) This give the direction relative to a quadrant - TQ_INT16 mag; // Current magnitude - TQ_INT16 lmag; // Magnitude at the left (So this pixel is "more internal" than the current - TQ_INT16 rmag; // Magnitude at the right (So this pixel is "more external") - double xdel; // Current xdelta - double ydel; // Current ydelta - TQ_INT16 result; - - for (uint col = 0; col < magnitude.count(); col++) { - for (uint row = 0; row < magnitude[col].count(); row++) { - mag = magnitude[col][row]; - if (!mag || row == 0 || row == (magnitude[col].count()-1) || - col == 0 || col == (magnitude.count()-1)) - { - result = NOEDGE; - } else { - xdel = (double)xdelta[col][row]; - ydel = (double)ydelta[col][row]; - theta = atan(fabs(ydel)/fabs(xdel)); - if (theta < 0) - theta = fabs(theta)+M_PI_2; - theta = (theta * 360.0) / (2.0*M_PI); // Radians -> degrees - if (theta >= 0 && theta < 22.5) { // .0 - .3926990816 - if (ydel >= 0) { - lmag = magnitude[col][row-1]; - rmag = magnitude[col][row+1]; - } else { - lmag = magnitude[col][row+1]; - rmag = magnitude[col][row-1]; - } - } - if (theta >= 22.5 && theta < 67.5) { // .3926990816 - 1.1780972449 - if (xdel >= 0) { - if (ydel >= 0) { - lmag = magnitude[col-1][row-1]; - rmag = magnitude[col+1][row+1]; - } else { - lmag = magnitude[col+1][row-1]; - rmag = magnitude[col-1][row+1]; - } - } else { - if (ydel >= 0) { - lmag = magnitude[col-1][row+1]; - rmag = magnitude[col+1][row-1]; - } else { - lmag = magnitude[col+1][row+1]; - rmag = magnitude[col-1][row-1]; - } - } - } - if (theta >= 67.5 && theta <= 90.0) { // 1.1780972449 - 1.5707963266 - if (xdel >= 0) { - lmag = magnitude[col+1][row]; - rmag = magnitude[col-1][row]; - } else { - lmag = magnitude[col-1][row]; - rmag = magnitude[col+1][row]; - } - } - - if ((mag < lmag) || (mag < rmag)) { - result = NOEDGE; - } else { - if (rmag == mag) // If the external magnitude is equal to the current, suppress current. - result = NOEDGE; - else - result = (mag > 255) ? 255 : mag; - } - } - nms[col][row] = result; - } - } -} - -KisToolMagnetic::KisToolMagnetic () - : super("Magnetic Outline Tool") -{ - setName("tool_moutline"); - setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); - - m_editingMode = false; - m_editingCursor = m_draggingCursor = false; - - m_mode = 0; - m_curve = m_derived = 0; - m_current = m_previous = 0; - - m_distance = DEFAULTDIST; - - m_transactionMessage = i18n("Magnetic Outline Selection"); -} - -KisToolMagnetic::~KisToolMagnetic () -{ - m_curve = 0; - delete m_derived; -} - -void KisToolMagnetic::update (KisCanvasSubject *subject) -{ - super::update(subject); -} - -void KisToolMagnetic::activate () -{ - super::activate(); - if (!m_derived) { - m_derived = new KisCurveMagnetic(this); - m_curve = m_derived; - } -} - -void KisToolMagnetic::deactivate () -{ - m_curve->endActionOptions(); - m_actionOptions = NOOPTIONS; - m_dragging = false; - m_drawPivots = true; -} - -void KisToolMagnetic::keyPress(TQKeyEvent *event) -{ - if (event->key() == TQt::Key_Control) { - draw(false); - if (m_editingMode) { - m_editingMode = false; - if (m_current != 0) - m_curve->selectPivot(m_current,false); - m_mode->setText(i18n("Automatic Mode")); - } else { - m_editingMode = true; - m_mode->setText(i18n("Manual Mode")); - } - draw(false); - } else if (event->key() == TQt::Key_Delete && m_curve->count()) { - draw(false); - m_dragging = false; - if (m_curve->pivots().count() == 2) - m_curve->clear(); - else { - if ((*m_current) == m_curve->last() && !(m_editingMode)) { - m_curve->deletePivot(m_current.previousPivot()); - m_previous = m_current.previousPivot(); - } else { - m_editingMode = false; - m_curve->deletePivot(m_current); - m_previous = m_current = m_curve->selectPivot(m_curve->lastIterator()); - m_editingMode = true; - } - } - draw(false); - } else - super::keyPress(event); -} - -void KisToolMagnetic::buttonRelease(KisButtonReleaseEvent *event) -{ - if (m_editingMode) { - draw(m_current); - m_editingMode = false; - if (!m_curve->isEmpty()) - m_curve->movePivot(m_current, m_currentPoint); - m_editingMode = true; - draw(m_current); - } - super::buttonRelease(event); -} - -void KisToolMagnetic::buttonPress(KisButtonPressEvent *event) -{ - updateOptions(event->state()); - if (!m_currentImage) - return; - if (event->button() == Qt::LeftButton) { - m_dragging = true; - m_currentPoint = event->pos(); - PointPair temp(m_curve->end(),false); - if (m_editingMode) - temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !(m_actionOptions)) { - if (m_editingMode) { - draw(true, true); - m_curve->selectAll(false); - draw(true, true); - } - draw(m_curve->end()); - if (!m_curve->isEmpty()) { - m_previous = m_current; - m_current = m_curve->pushPivot(event->pos()); - } else { - m_previous = m_current = m_curve->pushPivot(event->pos()); - } - if (m_curve->pivots().count() > 1) - m_curve->calculateCurve(m_previous,m_current,m_current); - if (m_editingMode) - draw(); - else { - if ((*m_previous).point() == (*m_current).point()) - draw(m_curve->end()); - else - draw(); - } - } else if (temp.first != m_curve->end() && m_editingMode) { - if (temp.second) { - draw(true, true); - m_current = m_curve->selectPivot(temp.first); - draw(true, true); - } else { - draw(false); - m_current = selectByMouse(temp.first); - draw(false); - } - if (!(*m_current).isSelected()) - m_dragging = false; - } - } -} - -void KisToolMagnetic::move(KisMoveEvent *event) -{ - updateOptions(event->state()); - if (m_currentPoint == event->pos().floorTQPoint()) - return; - if (m_editingMode) { - PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !m_dragging) { - if (m_editingCursor || m_draggingCursor) { - setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); - m_editingCursor = m_draggingCursor = false; - } - } else { - if (!m_draggingCursor && temp.second) { - setCursor(KisCursor::load("tool_moutline_dragging.png", 6, 6)); - m_editingCursor = false; - m_draggingCursor = true; - } - if (!m_editingCursor && !temp.second) { - setCursor(KisCursor::load("tool_moutline_editing.png", 6, 6)); - m_editingCursor = true; - m_draggingCursor = false; - } - } - if (!m_dragging) - return; - } else { - if (m_editingCursor || m_draggingCursor) { - setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); - m_editingCursor = m_draggingCursor = false; - } - } - if (m_curve->selectedPivots().isEmpty()) - return; - - KisPoint trans = event->pos() - m_currentPoint; - KisPoint dist; - dist = (*m_current).point() - (*m_current.previousPivot()).point(); - if ((m_distance >= MINDIST && (fabs(dist.x()) + fabs(dist.y())) > m_distance && !(m_editingMode)) - || m_curve->pivots().count() == 1) { - draw(m_curve->end()); - m_previous = m_current; - m_current = m_curve->pushPivot(event->pos()); - } else if ((*m_previous).point() == (*m_current).point() && (*m_previous).point() == m_curve->last().point()) - draw(m_curve->end()); - else - draw(m_current); - m_curve->movePivot(m_current,event->pos()); - m_currentPoint = event->pos().floorTQPoint(); - draw(m_current); -} - -KisCurve::iterator KisToolMagnetic::selectByMouse(KisCurve::iterator it) -{ - KisCurve::iterator currPivot = m_curve->selectPivot(m_curve->addPivot(it, KisPoint(0,0))); - m_curve->movePivot(currPivot,(*it).point()); - - return currPivot; -} - -void KisToolMagnetic::slotCommitCurve () -{ - if (!m_curve->isEmpty()) - commitCurve(); -} - -void KisToolMagnetic::slotSetDistance (int dist) -{ - m_distance = dist; -} - -TQWidget* KisToolMagnetic::createOptionWidget(TQWidget* parent) -{ - m_optWidget = super::createOptionWidget(parent); - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - TQGridLayout *box = new TQGridLayout(l, 2, 2, 3); - box->setColStretch(0, 1); - box->setColStretch(1, 1); - TQ_CHECK_PTR(box); - - m_mode = new TQLabel(i18n("Automatic mode"), m_optWidget); - m_lbDistance = new TQLabel(i18n("Distance: "), m_optWidget); - TQPushButton *finish = new TQPushButton(i18n("To Selection"), m_optWidget); - m_slDistance = new TQSlider(MINDIST, MAXDIST, PAGESTEP, m_distance, Qt::Horizontal, m_optWidget); - - connect(m_slDistance, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetDistance(int))); - connect(finish, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCommitCurve())); - - box->addWidget(m_lbDistance, 0, 0); - box->addWidget(m_slDistance, 0, 1); - box->addWidget(m_mode, 1, 0); - box->addWidget(finish, 1, 1); - - return m_optWidget; -} - -void KisToolMagnetic::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("Magnetic Outline"), - "tool_moutline", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Magnetic Selection: move around an edge to select it. Hit Ctrl to enter/quit manual mode, and double click to finish.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_moutline.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp new file mode 100644 index 00000000..ebf82634 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp @@ -0,0 +1,809 @@ +/* + * kis_tool_moutline.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_iterators_pixel.h" +#include "kis_colorspace.h" +#include "kis_channelinfo.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_tool_controller.h" +#include "kis_vec.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" +#include "kis_paintop_registry.h" +#include "kis_convolution_painter.h" + +#include "kis_tool_moutline.h" + +using namespace std; + +#define RMS(a, b) (sqrt ((a) * (a) + (b) * (b))) +#define ROUND(x) ((int) ((x) + 0.5)) + +const int NOEDGE = 0x0000; + +const int ORTHOGONAL_COST = 10; // 1*10 +const int DIAGONAL_COST = 14; // sqrt(2)*10 +const int MALUS = 20; // This applies to NOEDGE nodes + +const int DEFAULTDIST = 40; // Default distance between two automatic pivots +const int MAXDIST = 55; // Max distance +const int MINDIST = 15; +const int PAGESTEP = 5; + +class Node { + + TQPoint m_pos; + int m_gCost; + int m_hCost; + int m_tCost; + bool m_malus; + TQPoint m_parent; + +public: + + Node() + { + m_pos = m_parent = TQPoint(-1,-1); + m_gCost = m_hCost = m_tCost = 0; + m_malus = false; + } + + Node(const Node& node) + { + m_pos = node.pos(); + m_gCost = node.gCost(); + m_hCost = node.hCost(); + m_tCost = node.tCost(); + m_malus = node.malus(); + m_parent = node.parent(); + } + + Node(const TQPoint& parent, const TQPoint& pos, int g, int h, bool malus) + : m_pos(pos), m_hCost(h), m_malus(malus) + { + setGCost(g); + m_parent = parent; + } + ~Node () + { + } + + int gCost () const {return m_gCost;} + int hCost () const {return m_hCost;} + int tCost () const {return m_tCost;} + bool malus () const {return m_malus;} + TQPoint pos () const {return m_pos;} + int col () const {return m_pos.x();} + int row () const {return m_pos.y();} + TQPoint parent () const {return m_parent;} + + void setGCost (int g) + { + m_gCost = g+(m_malus?MALUS:0); + m_tCost = m_gCost+m_hCost; + } + void setHCost (int h) + { + m_hCost = h; + m_tCost = m_gCost+m_hCost; + } + void setPos (const TQPoint& pos) + { + m_pos = pos; + } + void setMalus (bool malus) + { + m_malus = malus; + } + void clear () + { + m_pos = TQPoint(-1,-1); + } + + bool operator== (const Node& n2) const + { + return m_pos == n2.pos(); + } + bool operator!= (const Node& n2) const + { + return m_pos != n2.pos(); + } + bool operator== (const TQPoint& n2) const + { + return m_pos == n2; + } + bool operator!= (const TQPoint& n2) const + { + return m_pos != n2; + } + bool operator< (const Node& n2) const + { + return m_tCost < n2.tCost(); + } + bool operator> (const Node& n2) const + { + return m_tCost > n2.tCost(); + } + + TQValueList getNeighbor(const GrayMatrix& src, const Node& end) + { + TQPoint tmpdist; + TQValueList temp; + int dcol, drow; + int g, h; + bool malus; + int x[8] = { 1, 1, 0,-1,-1,-1, 0, 1}, + y[8] = { 0,-1,-1,-1, 0, 1, 1, 1}; + + for (int i = 0; i < 8; i++) { + dcol = m_pos.x() + x[i]; + drow = m_pos.y() + y[i]; + tmpdist = TQPoint(dcol,drow) - end.pos(); + // I use src[0] here because all cols have same number of rows + if (dcol == (int)src.count() || dcol < 0 || + drow == (int)src[0].count() || drow < 0) + continue; + if (src[dcol][drow]) + malus = false; + else + malus = true; + if (i%2) + g = m_gCost + DIAGONAL_COST; + else + g = m_gCost + ORTHOGONAL_COST; + h = ORTHOGONAL_COST * (abs(tmpdist.x()) + abs(tmpdist.y())); + temp.append(Node(m_pos,TQPoint(dcol,drow),g,h,malus)); + } + return temp; + } + +}; + +KisKernelSP createKernel( TQ_INT32 i0, TQ_INT32 i1, TQ_INT32 i2, + TQ_INT32 i3, TQ_INT32 i4, TQ_INT32 i5, + TQ_INT32 i6, TQ_INT32 i7, TQ_INT32 i8, + TQ_INT32 factor, TQ_INT32 offset ) +{ + KisKernelSP kernel = new KisKernel(); + kernel->width = 3; + kernel->height = 3; + + kernel->factor = factor; + kernel->offset = offset; + + kernel->data = new TQ_INT32[9]; + kernel->data[0] = i0; + kernel->data[1] = i1; + kernel->data[2] = i2; + kernel->data[3] = i3; + kernel->data[4] = i4; + kernel->data[5] = i5; + kernel->data[6] = i6; + kernel->data[7] = i7; + kernel->data[8] = i8; + + return kernel; +} + +KisCurveMagnetic::KisCurveMagnetic (KisToolMagnetic *parent) + : m_parent(parent) +{ + m_standardkeepselected = false; +} + +KisCurveMagnetic::~KisCurveMagnetic () +{ + +} + +KisCurve::iterator KisCurveMagnetic::addPivot (KisCurve::iterator it, const KisPoint& point) +{ + return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,LINEHINT))); +} + +KisCurve::iterator KisCurveMagnetic::pushPivot (const KisPoint& point) +{ + iterator it; + + it = pushPoint(point,true,false,LINEHINT); +// if (count() == 1 && !m_parent->editingMode()) +// addPoint(it,point,true,false,LINEHINT); + + return selectPivot(it); +} + +void KisCurveMagnetic::calculateCurve (KisCurve::iterator p1, KisCurve::iterator p2, KisCurve::iterator it) +{ + if (p1 == m_curve.end() || p2 == m_curve.end()) // It happens sometimes, for example on the first click + return; + if (m_parent->editingMode()) + return; + TQPoint start = (*p1).point().roundTQPoint(); + TQPoint end = (*p2).point().roundTQPoint(); + TQRect rc = TQRect(start,end).normalize(); + rc.setTopLeft(rc.topLeft()+TQPoint(-8,-8)); // Enlarge the view, so problems with gaussian blur can be removed + rc.setBottomRight(rc.bottomRight()+TQPoint(8,8)); // and we are able to find paths that go beyond the rect. + + KisPaintDeviceSP src = m_parent->m_currentImage->activeDevice(); + GrayMatrix dst = GrayMatrix(rc.width(),GrayCol(rc.height())); + + detectEdges (rc, src, dst); + reduceMatrix (rc, dst, 3, 3, 3, 3); + + Node startNode, endNode; + multiset openSet; + NodeMatrix openMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); + NodeMatrix closedMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); + + TQPoint tl(rc.topLeft().x(),rc.topLeft().y()); + start -= tl; // Relative to the matrix + end -= tl; // Relative to the matrix + + findEdge (start.x(), start.y(), dst, startNode); + openMatrix[startNode.col()][startNode.row()] = *openSet.insert(startNode); + endNode.setPos(end); + + while (!openSet.empty()) { + Node current = *openSet.begin(); + + openSet.erase(openSet.begin()); + openMatrix[current.col()][current.row()].clear(); + + TQValueList successors = current.getNeighbor(dst,endNode); + for (TQValueList::iterator i = successors.begin(); i != successors.end(); i++) { + int col = (*i).col(); + int row = (*i).row(); + if ((*i) == endNode) { + while (current.parent() != TQPoint(-1,-1)) { + it = addPoint(it,KisPoint(tl+current.pos()),false,false,LINEHINT); + current = closedMatrix[current.parent().x()][current.parent().y()]; + } + return; + } + Node *openNode = &openMatrix[col][row]; + if (*openNode != TQPoint(-1,-1)) { + if (*i > *openNode) + continue; + else { + openSet.erase(tqFind(openSet.begin(),openSet.end(),*openNode)); + openNode->clear(); // Clear the Node + } + } + Node *closedNode = &closedMatrix[col][row]; + if (*closedNode != TQPoint(-1,-1)) { + if ((*i) > (*closedNode)) + continue; + else { + openMatrix[col][row] = *openSet.insert(*closedNode); + closedNode->clear(); // Clear the Node + continue; + } + } + openMatrix[col][row] = *openSet.insert(*i); + } + closedMatrix[current.col()][current.row()] = current; + } +} + +void KisCurveMagnetic::findEdge (int col, int row, const GrayMatrix& src, Node& node) +{ + int x = -1; + int y = -1; + + // tmpdist out of range + KisVector2D mindist(5.0,5.0), tmpdist(1000.0,1000.0); + for (int i = -5; i < 6; i++) { + for (int j = -5; j < 6; j++) { + if (src[col+i][row+j] != NOEDGE) { + tmpdist = KisVector2D(i,j); + if (tmpdist.length() < mindist.length()) + mindist = tmpdist; + } + } + } + if (tmpdist.x() == 1000.0) + mindist = KisVector2D(0.0,0.0); + + x = (int)(col + mindist.x()); + y = (int)(row + mindist.y()); + + node.setPos(TQPoint(x,y)); +} + +void KisCurveMagnetic::reduceMatrix (TQRect& rc, GrayMatrix& m, int top, int right, int bottom, int left) +{ + TQPoint topleft(top, left); + TQPoint bottomright(bottom, right); + + rc.setTopLeft(rc.topLeft()+topleft); + rc.setBottomRight(rc.bottomRight()-bottomright); + + if (left) + m.erase(m.begin(),m.begin()+left); + if (right) + m.erase(m.end()-right,m.end()); + if (top) { + for (uint i = 0; i < m.count(); i++) + m[i].erase(m[i].begin(),m[i].begin()+top); + } + if (bottom) { + for (uint i = 0; i < m.count(); i++) + m[i].erase(m[i].end()-bottom,m[i].end()); + } +} + +void KisCurveMagnetic::detectEdges (const TQRect & rect, KisPaintDeviceSP src, GrayMatrix& dst) +{ + GrayMatrix graysrc(rect.width(),GrayCol(rect.height())); + GrayMatrix xdeltas(rect.width(),GrayCol(rect.height())); + GrayMatrix ydeltas(rect.width(),GrayCol(rect.height())); + GrayMatrix magnitude(rect.width(),GrayCol(rect.height())); + KisPaintDeviceSP smooth = new KisPaintDevice(src->colorSpace()); + + gaussianBlur(rect, src, smooth); + toGrayScale(rect, smooth, graysrc); + getDeltas(graysrc, xdeltas, ydeltas); + getMagnitude(xdeltas, ydeltas, magnitude); + nonMaxSupp(magnitude, xdeltas, ydeltas, dst); +} + +void KisCurveMagnetic::gaussianBlur (const TQRect& rect, KisPaintDeviceSP src, KisPaintDeviceSP dst) +{ + int grectx = rect.x(); + int grecty = rect.y(); + int grectw = rect.width(); + int grecth = rect.height(); + if (dst != src) { + KisPainter gc(dst); + gc.bitBlt(grectx, grecty, COMPOSITE_COPY, src, grectx, grecty, grectw, grecth); + gc.end(); + } + + KisConvolutionPainter painter( dst ); + // FIXME createKernel could create dynamic gaussian kernels having sigma as argument + KisKernelSP kernel = createKernel( 1, 1, 1, 1, 24, 1, 1, 1, 1, 32, 0); + painter.applyMatrix(kernel, grectx, grecty, grectw, grecth, BORDER_AVOID); +} + +void KisCurveMagnetic::toGrayScale (const TQRect& rect, KisPaintDeviceSP src, GrayMatrix& dst) +{ + int grectx = rect.x(); + int grecty = rect.y(); + int grectw = rect.width(); + int grecth = rect.height(); + TQColor c; + KisColorSpace *cs = src->colorSpace(); + + for (int row = 0; row < grecth; row++) { + KisHLineIteratorPixel srcIt = src->createHLineIterator(grectx, grecty+row, grectw, false); + for (int col = 0; col < grectw; col++) { + cs->toTQColor(srcIt.rawData(),&c); + dst[col][row] = tqGray(c.rgb()); + ++srcIt; + } + } +} + +void KisCurveMagnetic::getDeltas (const GrayMatrix& src, GrayMatrix& xdelta, GrayMatrix& ydelta) +{ + uint start = 1, xend = src[0].count()-1, yend = src.count()-1; + TQ_INT16 deri; + for (uint col = 0; col < src.count(); col++) { + for (uint row = 0; row < src[col].count(); row++) { + if (row >= start && row < xend) { + deri = src[col][row+1] - src[col][row-1]; + xdelta[col][row] = deri; + } else + xdelta[col][row] = 0; + if (col >= start && col < yend) { + deri = src[col+1][row] - src[col-1][row]; + ydelta[col][row] = deri; + } else + ydelta[col][row] = 0; + } + } +} + +void KisCurveMagnetic::getMagnitude (const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& gradient) +{ + for (uint col = 0; col < xdelta.count(); col++) { + for (uint row = 0; row < xdelta[col].count(); row++) + gradient[col][row] = (TQ_INT16)(ROUND(RMS(xdelta[col][row],ydelta[col][row]))); + } +} + +void KisCurveMagnetic::nonMaxSupp (const GrayMatrix& magnitude, const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& nms) +{ + // Directions: + // 1: 0 - 22.5 degrees + // 2: 22.5 - 67.5 degrees + // 3: 67.5 - 90 degrees + // Second direction is relative to a quadrant. The quadrant is known by looking at x and y derivatives + // First quadrant: Gx < 0 & Gy >= 0 + // Second quadrant: Gx < 0 & Gy < 0 + // Third quadrant: Gx >= 0 & Gy < 0 + // Fourth quadrant: Gx >= 0 & Gy >= 0 + // For this reason: first direction is relative to Gy only and third direction to Gx only + + double theta; // theta = invtan (|Gy| / |Gx|) This give the direction relative to a quadrant + TQ_INT16 mag; // Current magnitude + TQ_INT16 lmag; // Magnitude at the left (So this pixel is "more internal" than the current + TQ_INT16 rmag; // Magnitude at the right (So this pixel is "more external") + double xdel; // Current xdelta + double ydel; // Current ydelta + TQ_INT16 result; + + for (uint col = 0; col < magnitude.count(); col++) { + for (uint row = 0; row < magnitude[col].count(); row++) { + mag = magnitude[col][row]; + if (!mag || row == 0 || row == (magnitude[col].count()-1) || + col == 0 || col == (magnitude.count()-1)) + { + result = NOEDGE; + } else { + xdel = (double)xdelta[col][row]; + ydel = (double)ydelta[col][row]; + theta = atan(fabs(ydel)/fabs(xdel)); + if (theta < 0) + theta = fabs(theta)+M_PI_2; + theta = (theta * 360.0) / (2.0*M_PI); // Radians -> degrees + if (theta >= 0 && theta < 22.5) { // .0 - .3926990816 + if (ydel >= 0) { + lmag = magnitude[col][row-1]; + rmag = magnitude[col][row+1]; + } else { + lmag = magnitude[col][row+1]; + rmag = magnitude[col][row-1]; + } + } + if (theta >= 22.5 && theta < 67.5) { // .3926990816 - 1.1780972449 + if (xdel >= 0) { + if (ydel >= 0) { + lmag = magnitude[col-1][row-1]; + rmag = magnitude[col+1][row+1]; + } else { + lmag = magnitude[col+1][row-1]; + rmag = magnitude[col-1][row+1]; + } + } else { + if (ydel >= 0) { + lmag = magnitude[col-1][row+1]; + rmag = magnitude[col+1][row-1]; + } else { + lmag = magnitude[col+1][row+1]; + rmag = magnitude[col-1][row-1]; + } + } + } + if (theta >= 67.5 && theta <= 90.0) { // 1.1780972449 - 1.5707963266 + if (xdel >= 0) { + lmag = magnitude[col+1][row]; + rmag = magnitude[col-1][row]; + } else { + lmag = magnitude[col-1][row]; + rmag = magnitude[col+1][row]; + } + } + + if ((mag < lmag) || (mag < rmag)) { + result = NOEDGE; + } else { + if (rmag == mag) // If the external magnitude is equal to the current, suppress current. + result = NOEDGE; + else + result = (mag > 255) ? 255 : mag; + } + } + nms[col][row] = result; + } + } +} + +KisToolMagnetic::KisToolMagnetic () + : super("Magnetic Outline Tool") +{ + setName("tool_moutline"); + setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); + + m_editingMode = false; + m_editingCursor = m_draggingCursor = false; + + m_mode = 0; + m_curve = m_derived = 0; + m_current = m_previous = 0; + + m_distance = DEFAULTDIST; + + m_transactionMessage = i18n("Magnetic Outline Selection"); +} + +KisToolMagnetic::~KisToolMagnetic () +{ + m_curve = 0; + delete m_derived; +} + +void KisToolMagnetic::update (KisCanvasSubject *subject) +{ + super::update(subject); +} + +void KisToolMagnetic::activate () +{ + super::activate(); + if (!m_derived) { + m_derived = new KisCurveMagnetic(this); + m_curve = m_derived; + } +} + +void KisToolMagnetic::deactivate () +{ + m_curve->endActionOptions(); + m_actionOptions = NOOPTIONS; + m_dragging = false; + m_drawPivots = true; +} + +void KisToolMagnetic::keyPress(TQKeyEvent *event) +{ + if (event->key() == TQt::Key_Control) { + draw(false); + if (m_editingMode) { + m_editingMode = false; + if (m_current != 0) + m_curve->selectPivot(m_current,false); + m_mode->setText(i18n("Automatic Mode")); + } else { + m_editingMode = true; + m_mode->setText(i18n("Manual Mode")); + } + draw(false); + } else if (event->key() == TQt::Key_Delete && m_curve->count()) { + draw(false); + m_dragging = false; + if (m_curve->pivots().count() == 2) + m_curve->clear(); + else { + if ((*m_current) == m_curve->last() && !(m_editingMode)) { + m_curve->deletePivot(m_current.previousPivot()); + m_previous = m_current.previousPivot(); + } else { + m_editingMode = false; + m_curve->deletePivot(m_current); + m_previous = m_current = m_curve->selectPivot(m_curve->lastIterator()); + m_editingMode = true; + } + } + draw(false); + } else + super::keyPress(event); +} + +void KisToolMagnetic::buttonRelease(KisButtonReleaseEvent *event) +{ + if (m_editingMode) { + draw(m_current); + m_editingMode = false; + if (!m_curve->isEmpty()) + m_curve->movePivot(m_current, m_currentPoint); + m_editingMode = true; + draw(m_current); + } + super::buttonRelease(event); +} + +void KisToolMagnetic::buttonPress(KisButtonPressEvent *event) +{ + updateOptions(event->state()); + if (!m_currentImage) + return; + if (event->button() == Qt::LeftButton) { + m_dragging = true; + m_currentPoint = event->pos(); + PointPair temp(m_curve->end(),false); + if (m_editingMode) + temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !(m_actionOptions)) { + if (m_editingMode) { + draw(true, true); + m_curve->selectAll(false); + draw(true, true); + } + draw(m_curve->end()); + if (!m_curve->isEmpty()) { + m_previous = m_current; + m_current = m_curve->pushPivot(event->pos()); + } else { + m_previous = m_current = m_curve->pushPivot(event->pos()); + } + if (m_curve->pivots().count() > 1) + m_curve->calculateCurve(m_previous,m_current,m_current); + if (m_editingMode) + draw(); + else { + if ((*m_previous).point() == (*m_current).point()) + draw(m_curve->end()); + else + draw(); + } + } else if (temp.first != m_curve->end() && m_editingMode) { + if (temp.second) { + draw(true, true); + m_current = m_curve->selectPivot(temp.first); + draw(true, true); + } else { + draw(false); + m_current = selectByMouse(temp.first); + draw(false); + } + if (!(*m_current).isSelected()) + m_dragging = false; + } + } +} + +void KisToolMagnetic::move(KisMoveEvent *event) +{ + updateOptions(event->state()); + if (m_currentPoint == event->pos().floorTQPoint()) + return; + if (m_editingMode) { + PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !m_dragging) { + if (m_editingCursor || m_draggingCursor) { + setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); + m_editingCursor = m_draggingCursor = false; + } + } else { + if (!m_draggingCursor && temp.second) { + setCursor(KisCursor::load("tool_moutline_dragging.png", 6, 6)); + m_editingCursor = false; + m_draggingCursor = true; + } + if (!m_editingCursor && !temp.second) { + setCursor(KisCursor::load("tool_moutline_editing.png", 6, 6)); + m_editingCursor = true; + m_draggingCursor = false; + } + } + if (!m_dragging) + return; + } else { + if (m_editingCursor || m_draggingCursor) { + setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); + m_editingCursor = m_draggingCursor = false; + } + } + if (m_curve->selectedPivots().isEmpty()) + return; + + KisPoint trans = event->pos() - m_currentPoint; + KisPoint dist; + dist = (*m_current).point() - (*m_current.previousPivot()).point(); + if ((m_distance >= MINDIST && (fabs(dist.x()) + fabs(dist.y())) > m_distance && !(m_editingMode)) + || m_curve->pivots().count() == 1) { + draw(m_curve->end()); + m_previous = m_current; + m_current = m_curve->pushPivot(event->pos()); + } else if ((*m_previous).point() == (*m_current).point() && (*m_previous).point() == m_curve->last().point()) + draw(m_curve->end()); + else + draw(m_current); + m_curve->movePivot(m_current,event->pos()); + m_currentPoint = event->pos().floorTQPoint(); + draw(m_current); +} + +KisCurve::iterator KisToolMagnetic::selectByMouse(KisCurve::iterator it) +{ + KisCurve::iterator currPivot = m_curve->selectPivot(m_curve->addPivot(it, KisPoint(0,0))); + m_curve->movePivot(currPivot,(*it).point()); + + return currPivot; +} + +void KisToolMagnetic::slotCommitCurve () +{ + if (!m_curve->isEmpty()) + commitCurve(); +} + +void KisToolMagnetic::slotSetDistance (int dist) +{ + m_distance = dist; +} + +TQWidget* KisToolMagnetic::createOptionWidget(TQWidget* parent) +{ + m_optWidget = super::createOptionWidget(parent); + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + TQGridLayout *box = new TQGridLayout(l, 2, 2, 3); + box->setColStretch(0, 1); + box->setColStretch(1, 1); + TQ_CHECK_PTR(box); + + m_mode = new TQLabel(i18n("Automatic mode"), m_optWidget); + m_lbDistance = new TQLabel(i18n("Distance: "), m_optWidget); + TQPushButton *finish = new TQPushButton(i18n("To Selection"), m_optWidget); + m_slDistance = new TQSlider(MINDIST, MAXDIST, PAGESTEP, m_distance, Qt::Horizontal, m_optWidget); + + connect(m_slDistance, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetDistance(int))); + connect(finish, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCommitCurve())); + + box->addWidget(m_lbDistance, 0, 0); + box->addWidget(m_slDistance, 0, 1); + box->addWidget(m_mode, 1, 0); + box->addWidget(finish, 1, 1); + + return m_optWidget; +} + +void KisToolMagnetic::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("Magnetic Outline"), + "tool_moutline", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Magnetic Selection: move around an edge to select it. Hit Ctrl to enter/quit manual mode, and double click to finish.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_moutline.moc" diff --git a/chalk/plugins/tools/tool_curves/tool_curves.cc b/chalk/plugins/tools/tool_curves/tool_curves.cc deleted file mode 100644 index b21f5aae..00000000 --- a/chalk/plugins/tools/tool_curves/tool_curves.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * tool_bezier.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_curves.h" -#include "kis_tool_bezier_paint.h" -#include "kis_tool_bezier_select.h" -#include "kis_tool_moutline.h" - - -typedef KGenericFactory ToolCurvesFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolcurves, ToolCurvesFactory( "chalk" ) ) - - -ToolCurves::ToolCurves(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolCurvesFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast( parent ); - r->add(new KisToolBezierPaintFactory()); - r->add(new KisToolBezierSelectFactory()); - r->add(new KisToolMagneticFactory()); - } - -} - -ToolCurves::~ToolCurves() -{ -} - -#include "tool_curves.moc" diff --git a/chalk/plugins/tools/tool_curves/tool_curves.cpp b/chalk/plugins/tools/tool_curves/tool_curves.cpp new file mode 100644 index 00000000..28f65604 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/tool_curves.cpp @@ -0,0 +1,67 @@ +/* + * tool_bezier.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_curves.h" +#include "kis_tool_bezier_paint.h" +#include "kis_tool_bezier_select.h" +#include "kis_tool_moutline.h" + + +typedef KGenericFactory ToolCurvesFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolcurves, ToolCurvesFactory( "chalk" ) ) + + +ToolCurves::ToolCurves(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolCurvesFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast( parent ); + r->add(new KisToolBezierPaintFactory()); + r->add(new KisToolBezierSelectFactory()); + r->add(new KisToolMagneticFactory()); + } + +} + +ToolCurves::~ToolCurves() +{ +} + +#include "tool_curves.moc" diff --git a/chalk/plugins/tools/tool_filter/Makefile.am b/chalk/plugins/tools/tool_filter/Makefile.am index d99a3924..b12ab69b 100644 --- a/chalk/plugins/tools/tool_filter/Makefile.am +++ b/chalk/plugins/tools/tool_filter/Makefile.am @@ -10,9 +10,9 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolfilter_la_SOURCES = \ - kis_filterop.cc \ - kis_tool_filter.cc \ - tool_filter.cc + kis_filterop.cpp \ + kis_tool_filter.cpp \ + tool_filter.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolfilter.la diff --git a/chalk/plugins/tools/tool_filter/kis_filterop.cc b/chalk/plugins/tools/tool_filter/kis_filterop.cc deleted file mode 100644 index d3378730..00000000 --- a/chalk/plugins/tools/tool_filter/kis_filterop.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_iterators_pixel.h" -#include "kis_paintop.h" -#include "kis_colorspace.h" -#include "kis_selection.h" -#include "kis_filterop.h" - - -KisPaintOp * KisFilterOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) -{ - KisPaintOp * op = new KisFilterOp(painter); - return op; -} - - -KisFilterOp::KisFilterOp(KisPainter * painter) - : super(painter) -{ - m_filterConfiguration = 0; -} - -KisFilterOp::~KisFilterOp() -{ - delete m_filterConfiguration; -} - -void KisFilterOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ - if (!m_painter) return; - - KisFilterSP filter = m_painter->filter(); - if (!filter) return; - - if ( ! m_source ) return; - - KisBrush * brush = m_painter->brush(); - if (!brush) return; - - KisColorSpace * colorSpace = m_source->colorSpace(); - - KisPoint hotSpot = brush->hotSpot(info); - KisPoint pt = pos - hotSpot; - - // Split the coordinates into integer plus fractional parts. The integer - // is where the dab will be positioned and the fractional part determines - // the sub-pixel positioning. - TQ_INT32 x; - double xFraction; - TQ_INT32 y; - double yFraction; - - splitCoordinate(pt.x(), &x, &xFraction); - splitCoordinate(pt.y(), &y, &yFraction); - - // Filters always work with a mask, never with an image; that - // wouldn't be useful at all. - KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); - - m_painter->setPressure(info.pressure); - - TQ_INT32 maskWidth = mask->width(); - TQ_INT32 maskHeight = mask->height(); - - // Create a temporary paint device - KisPaintDeviceSP tmpDev = new KisPaintDevice(colorSpace, "filterop tmpdev"); - TQ_CHECK_PTR(tmpDev); - - // Copy the layer data onto the new paint device - - KisPainter p( tmpDev ); - p.bitBlt( 0, 0, COMPOSITE_COPY, m_source, OPACITY_OPAQUE, x, y, maskWidth, maskHeight ); - - // Filter the paint device - filter->disableProgress(); - filter->process( tmpDev, tmpDev, m_filterConfiguration, TQRect( 0, 0, maskWidth, maskHeight )); - filter->enableProgress(); - - // Apply the mask on the paint device (filter before mask because edge pixels may be important) - for (int y = 0; y < maskHeight; y++) - { - KisHLineIterator hiter = tmpDev->createHLineIterator(0, y, maskWidth, false); - int x=0; - while(! hiter.isDone()) - { - TQ_UINT8 alpha = mask->alphaAt( x++, y ); - colorSpace->setAlpha(hiter.rawData(), alpha, 1); - - ++hiter; - } - } - - // Blit the paint device onto the layer - TQRect dabRect = TQRect(0, 0, maskWidth, maskHeight); - TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); - - KisImage * image = m_painter->device()->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - TQ_INT32 sx = dstRect.x() - x; - TQ_INT32 sy = dstRect.y() - y; - TQ_INT32 sw = dstRect.width(); - TQ_INT32 sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), m_painter->opacity(), sx, sy, sw, sh); - } - - m_painter->addDirtyRect(dstRect); -} - -void KisFilterOp::setFilterConfiguration(KisFilterConfiguration* filterConfiguration) -{ - delete m_filterConfiguration; - m_filterConfiguration = filterConfiguration; -} diff --git a/chalk/plugins/tools/tool_filter/kis_filterop.cpp b/chalk/plugins/tools/tool_filter/kis_filterop.cpp new file mode 100644 index 00000000..d3378730 --- /dev/null +++ b/chalk/plugins/tools/tool_filter/kis_filterop.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_iterators_pixel.h" +#include "kis_paintop.h" +#include "kis_colorspace.h" +#include "kis_selection.h" +#include "kis_filterop.h" + + +KisPaintOp * KisFilterOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisFilterOp(painter); + return op; +} + + +KisFilterOp::KisFilterOp(KisPainter * painter) + : super(painter) +{ + m_filterConfiguration = 0; +} + +KisFilterOp::~KisFilterOp() +{ + delete m_filterConfiguration; +} + +void KisFilterOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ + if (!m_painter) return; + + KisFilterSP filter = m_painter->filter(); + if (!filter) return; + + if ( ! m_source ) return; + + KisBrush * brush = m_painter->brush(); + if (!brush) return; + + KisColorSpace * colorSpace = m_source->colorSpace(); + + KisPoint hotSpot = brush->hotSpot(info); + KisPoint pt = pos - hotSpot; + + // Split the coordinates into integer plus fractional parts. The integer + // is where the dab will be positioned and the fractional part determines + // the sub-pixel positioning. + TQ_INT32 x; + double xFraction; + TQ_INT32 y; + double yFraction; + + splitCoordinate(pt.x(), &x, &xFraction); + splitCoordinate(pt.y(), &y, &yFraction); + + // Filters always work with a mask, never with an image; that + // wouldn't be useful at all. + KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); + + m_painter->setPressure(info.pressure); + + TQ_INT32 maskWidth = mask->width(); + TQ_INT32 maskHeight = mask->height(); + + // Create a temporary paint device + KisPaintDeviceSP tmpDev = new KisPaintDevice(colorSpace, "filterop tmpdev"); + TQ_CHECK_PTR(tmpDev); + + // Copy the layer data onto the new paint device + + KisPainter p( tmpDev ); + p.bitBlt( 0, 0, COMPOSITE_COPY, m_source, OPACITY_OPAQUE, x, y, maskWidth, maskHeight ); + + // Filter the paint device + filter->disableProgress(); + filter->process( tmpDev, tmpDev, m_filterConfiguration, TQRect( 0, 0, maskWidth, maskHeight )); + filter->enableProgress(); + + // Apply the mask on the paint device (filter before mask because edge pixels may be important) + for (int y = 0; y < maskHeight; y++) + { + KisHLineIterator hiter = tmpDev->createHLineIterator(0, y, maskWidth, false); + int x=0; + while(! hiter.isDone()) + { + TQ_UINT8 alpha = mask->alphaAt( x++, y ); + colorSpace->setAlpha(hiter.rawData(), alpha, 1); + + ++hiter; + } + } + + // Blit the paint device onto the layer + TQRect dabRect = TQRect(0, 0, maskWidth, maskHeight); + TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); + + KisImage * image = m_painter->device()->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + TQ_INT32 sx = dstRect.x() - x; + TQ_INT32 sy = dstRect.y() - y; + TQ_INT32 sw = dstRect.width(); + TQ_INT32 sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), m_painter->opacity(), sx, sy, sw, sh); + } + + m_painter->addDirtyRect(dstRect); +} + +void KisFilterOp::setFilterConfiguration(KisFilterConfiguration* filterConfiguration) +{ + delete m_filterConfiguration; + m_filterConfiguration = filterConfiguration; +} diff --git a/chalk/plugins/tools/tool_filter/kis_tool_filter.cc b/chalk/plugins/tools/tool_filter/kis_tool_filter.cc deleted file mode 100644 index 07133d3b..00000000 --- a/chalk/plugins/tools/tool_filter/kis_tool_filter.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* - * kis_tool_filter.cc - part of Chalk - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kis_filter_config_widget.h" -#include "kis_tool_filter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -KisToolFilter::KisToolFilter() - : super(i18n("Filter Brush")), m_filterConfigurationWidget(0) -{ - setName("tool_filter"); - m_subject = 0; - setCursor(KisCursor::load("tool_filter_cursor.png", 5, 5)); -} - -KisToolFilter::~KisToolFilter() -{ -} - -void KisToolFilter::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Filter Brush"), - "tool_filter", 0, this, - TQT_SLOT(activate()), collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Paint with filters")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolFilter::initPaint(KisEvent *e) -{ - // Some filters want to paint directly on the current state of - // the canvas, others cannot handle that and need a temporary layer - // so they can work on the old data before painting started. - m_paintIncremental = m_filter->supportsIncrementalPainting(); - - super::initPaint(e); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("filter", 0, painter()); - op->setSource ( m_source ); - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - painter()->setFilter( m_filter ); - - // XXX: Isn't there a better way to set the config? The filter config widget needs to - // to go into the tool options widget, and just the data carried over to the filter. - // I've got a bit of a problem with core classes having too much GUI about them. - // BSAR. - dynamic_cast(op)->setFilterConfiguration( m_filter->configuration( m_filterConfigurationWidget) ); -} - -TQWidget* KisToolFilter::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - - m_cbFilter = new KisCmbIDList(widget); - TQ_CHECK_PTR(m_cbFilter); - - TQLabel* lbFilter = new TQLabel(i18n("Filter:"), widget); - TQ_CHECK_PTR(lbFilter); - - // Check which filters support painting - KisIDList l = KisFilterRegistry::instance()->listKeys(); - KisIDList l2; - KisIDList::iterator it; - for (it = l.begin(); it != l.end(); ++it) { - KisFilterSP f = KisFilterRegistry::instance()->get(*it); - if (f->supportsPainting()) { - l2.push_back(*it); - } - } - m_cbFilter ->setIDList( l2 ); - - addOptionWidgetOption(m_cbFilter, lbFilter); - - m_optionLayout = new TQGridLayout(widget, 1, 1, 0, 6); - TQ_CHECK_PTR(m_optionLayout); - super::addOptionWidgetLayout(m_optionLayout); - - connect(m_cbFilter, TQT_SIGNAL(activated ( const KisID& )), this, TQT_SLOT( changeFilter( const KisID& ) ) ); - changeFilter( m_cbFilter->currentItem () ); - - return widget; -} - -void KisToolFilter::changeFilter( const KisID & id) -{ - m_filter = KisFilterRegistry::instance()->get( id ); - Q_ASSERT(m_filter != 0); - if( m_filterConfigurationWidget != 0 ) - { - m_optionLayout->remove ( m_filterConfigurationWidget ); - delete m_filterConfigurationWidget; - } - - m_source = m_currentImage->activeDevice(); - if (!m_source) return; - - m_filterConfigurationWidget = m_filter->createConfigurationWidget( optionWidget(), m_source ); - if( m_filterConfigurationWidget != 0 ) - { - m_optionLayout->addMultiCellWidget ( m_filterConfigurationWidget, 2, 2, 0, 1 ); - m_filterConfigurationWidget->show(); - } -} - -#include "kis_tool_filter.moc" diff --git a/chalk/plugins/tools/tool_filter/kis_tool_filter.cpp b/chalk/plugins/tools/tool_filter/kis_tool_filter.cpp new file mode 100644 index 00000000..14e2d616 --- /dev/null +++ b/chalk/plugins/tools/tool_filter/kis_tool_filter.cpp @@ -0,0 +1,154 @@ +/* + * kis_tool_filter.cpp - part of Chalk + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "kis_filter_config_widget.h" +#include "kis_tool_filter.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +KisToolFilter::KisToolFilter() + : super(i18n("Filter Brush")), m_filterConfigurationWidget(0) +{ + setName("tool_filter"); + m_subject = 0; + setCursor(KisCursor::load("tool_filter_cursor.png", 5, 5)); +} + +KisToolFilter::~KisToolFilter() +{ +} + +void KisToolFilter::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Filter Brush"), + "tool_filter", 0, this, + TQT_SLOT(activate()), collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Paint with filters")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolFilter::initPaint(KisEvent *e) +{ + // Some filters want to paint directly on the current state of + // the canvas, others cannot handle that and need a temporary layer + // so they can work on the old data before painting started. + m_paintIncremental = m_filter->supportsIncrementalPainting(); + + super::initPaint(e); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("filter", 0, painter()); + op->setSource ( m_source ); + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + painter()->setFilter( m_filter ); + + // XXX: Isn't there a better way to set the config? The filter config widget needs to + // to go into the tool options widget, and just the data carried over to the filter. + // I've got a bit of a problem with core classes having too much GUI about them. + // BSAR. + dynamic_cast(op)->setFilterConfiguration( m_filter->configuration( m_filterConfigurationWidget) ); +} + +TQWidget* KisToolFilter::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + + m_cbFilter = new KisCmbIDList(widget); + TQ_CHECK_PTR(m_cbFilter); + + TQLabel* lbFilter = new TQLabel(i18n("Filter:"), widget); + TQ_CHECK_PTR(lbFilter); + + // Check which filters support painting + KisIDList l = KisFilterRegistry::instance()->listKeys(); + KisIDList l2; + KisIDList::iterator it; + for (it = l.begin(); it != l.end(); ++it) { + KisFilterSP f = KisFilterRegistry::instance()->get(*it); + if (f->supportsPainting()) { + l2.push_back(*it); + } + } + m_cbFilter ->setIDList( l2 ); + + addOptionWidgetOption(m_cbFilter, lbFilter); + + m_optionLayout = new TQGridLayout(widget, 1, 1, 0, 6); + TQ_CHECK_PTR(m_optionLayout); + super::addOptionWidgetLayout(m_optionLayout); + + connect(m_cbFilter, TQT_SIGNAL(activated ( const KisID& )), this, TQT_SLOT( changeFilter( const KisID& ) ) ); + changeFilter( m_cbFilter->currentItem () ); + + return widget; +} + +void KisToolFilter::changeFilter( const KisID & id) +{ + m_filter = KisFilterRegistry::instance()->get( id ); + Q_ASSERT(m_filter != 0); + if( m_filterConfigurationWidget != 0 ) + { + m_optionLayout->remove ( m_filterConfigurationWidget ); + delete m_filterConfigurationWidget; + } + + m_source = m_currentImage->activeDevice(); + if (!m_source) return; + + m_filterConfigurationWidget = m_filter->createConfigurationWidget( optionWidget(), m_source ); + if( m_filterConfigurationWidget != 0 ) + { + m_optionLayout->addMultiCellWidget ( m_filterConfigurationWidget, 2, 2, 0, 1 ); + m_filterConfigurationWidget->show(); + } +} + +#include "kis_tool_filter.moc" diff --git a/chalk/plugins/tools/tool_filter/tool_filter.cc b/chalk/plugins/tools/tool_filter/tool_filter.cc deleted file mode 100644 index bda2357e..00000000 --- a/chalk/plugins/tools/tool_filter/tool_filter.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * tool_filter.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "tool_filter.h" -#include "kis_filterop.h" -#include "kis_tool_filter.h" - - -typedef KGenericFactory ToolFilterFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolfilter, ToolFilterFactory( "chalk" ) ) - - -ToolFilter::ToolFilter(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolFilterFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add( new KisToolFilterFactory()); - - // XXX: Put this in a separate plugin? - KisPaintOpRegistry * pr = KisPaintOpRegistry::instance(); - pr->add( new KisFilterOpFactory ); - - } -} - -ToolFilter::~ToolFilter() -{ -} - -#include "tool_filter.moc" diff --git a/chalk/plugins/tools/tool_filter/tool_filter.cpp b/chalk/plugins/tools/tool_filter/tool_filter.cpp new file mode 100644 index 00000000..484a7d9f --- /dev/null +++ b/chalk/plugins/tools/tool_filter/tool_filter.cpp @@ -0,0 +1,68 @@ +/* + * tool_filter.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tool_filter.h" +#include "kis_filterop.h" +#include "kis_tool_filter.h" + + +typedef KGenericFactory ToolFilterFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolfilter, ToolFilterFactory( "chalk" ) ) + + +ToolFilter::ToolFilter(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolFilterFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add( new KisToolFilterFactory()); + + // XXX: Put this in a separate plugin? + KisPaintOpRegistry * pr = KisPaintOpRegistry::instance(); + pr->add( new KisFilterOpFactory ); + + } +} + +ToolFilter::~ToolFilter() +{ +} + +#include "tool_filter.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/Makefile.am b/chalk/plugins/tools/tool_perspectivegrid/Makefile.am index 8544c078..c15df268 100644 --- a/chalk/plugins/tools/tool_perspectivegrid/Makefile.am +++ b/chalk/plugins/tools/tool_perspectivegrid/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolperspectivegrid_la_SOURCES = \ - tool_perspectivegrid.cc \ - kis_tool_perspectivegrid.cc + tool_perspectivegrid.cpp \ + kis_tool_perspectivegrid.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolperspectivegrid.la diff --git a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc deleted file mode 100644 index 2dbe56d3..00000000 --- a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc +++ /dev/null @@ -1,499 +0,0 @@ -/* - * kis_tool_perspectivegrid.cc - part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -KisToolPerspectiveGrid::KisToolPerspectiveGrid() - : super(i18n("Perspective Grid")), m_handleSize(13), m_handleHalfSize(6) - -{ - setName("tool_perspectivegrid"); - - m_subject = 0; - m_dragging = false; -} - -KisToolPerspectiveGrid::~KisToolPerspectiveGrid() -{ -} - -void KisToolPerspectiveGrid::activate() -{ - m_subject->perspectiveGridManager()->startEdition(); - if( ! m_subject->currentImg()->perspectiveGrid()->hasSubGrids() ) - { - m_mode = MODE_CREATION; - m_points.clear(); - } else { - m_mode = MODE_EDITING; - drawGrid(); - } - super::activate(); -} - -void KisToolPerspectiveGrid::deactivate() -{ - m_subject->perspectiveGridManager()->stopEdition(); - m_subject->perspectiveGridManager()->setGridVisible( true); - if( m_mode == MODE_CREATION ) - { - drawGridCreation(); - m_points.clear(); - m_dragging = false; - } else { - drawGrid(); - } -} - - -void KisToolPerspectiveGrid::update (KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -bool KisToolPerspectiveGrid::mouseNear(const TQPoint& mousep, const TQPoint point) -{ - return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); -} - -void KisToolPerspectiveGrid::buttonPress(KisButtonPressEvent *event) -{ - KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); - if(!pGrid->hasSubGrids() && m_mode != MODE_CREATION) - { // it's possible that the perspectiv grid was cleared - m_mode = MODE_CREATION; - m_points.clear(); - } - if( m_mode == MODE_CREATION && event->button() == Qt::LeftButton) - { - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - drawGridCreation(); - } - } else if(m_mode == MODE_EDITING && event->button() == Qt::LeftButton){ - // Look for the handle which was pressed - if (!m_subject) - return; - KisCanvasController *controller = m_subject->canvasController(); - Q_ASSERT(controller); - TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); - - for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) - { - KisSubPerspectiveGrid* grid = *it; - if( mouseNear( mousep, controller->windowToView(grid->topLeft()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPLEFT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->topLeft(); - break; - } - else if( mouseNear( mousep, controller->windowToView(grid->topRight()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->topRight(); - break; - } - else if( mouseNear( mousep, controller->windowToView(grid->bottomLeft()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->bottomLeft(); - break; - } - else if( mouseNear( mousep, controller->windowToView(grid->bottomRight()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->bottomRight(); - break; - } - else if( !grid->leftGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->bottomLeft() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS LEFT HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomLeft() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, grid->topLeft() , grid->bottomLeft(), m_selectedNode2); - m_dragEnd = event->pos(); - newsubgrid->setRightGrid( grid); - grid->setLeftGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - else if( !grid->rightGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topRight() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS RIGHT HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->topRight() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->topRight(), m_selectedNode1, m_selectedNode2, grid->bottomRight()); - m_dragEnd = event->pos(); - newsubgrid->setLeftGrid( grid); - grid->setRightGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - else if( !grid->topGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->topRight() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS TOP HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->topRight() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, m_selectedNode2, grid->topRight(), grid->topLeft() ); - m_dragEnd = event->pos(); - newsubgrid->setBottomGrid( grid); - grid->setTopGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - else if( !grid->bottomGrid() && mouseNear( mousep, controller->windowToView( ((*grid->bottomLeft() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS BOTTOM HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->bottomLeft() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->bottomLeft(), grid->bottomRight(), m_selectedNode2, m_selectedNode1); - m_dragEnd = event->pos(); - newsubgrid->setTopGrid( grid); - grid->setBottomGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - } - } -} - - -void KisToolPerspectiveGrid::move(KisMoveEvent *event) -{ - if( m_mode == MODE_CREATION ) - { - if (m_dragging) { - // erase old lines on canvas - drawGridCreation(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - drawGridCreation(); - } - } else { - if( m_mode == MODE_DRAGING_NODE) - { - drawGrid(); - m_selectedNode1->setX( event->pos().x() ); - m_selectedNode1->setY( event->pos().y() ); - drawGrid(); - } - if( m_mode == MODE_DRAGING_TRANSLATING_TWONODES) - { - drawGrid(); - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - *m_selectedNode1 += translate;; - *m_selectedNode2 += translate;; - drawGrid(); - } - } -} - -void KisToolPerspectiveGrid::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if( m_mode == MODE_CREATION ) - { - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - if( m_points.size() == 4) - { // wow we have a grid, isn't that cool ? - drawGridCreation(); // Clean - m_subject->currentImg()->perspectiveGrid()->addNewSubGrid( new KisSubPerspectiveGrid( new KisPerspectiveGridNode(m_points[0]), new KisPerspectiveGridNode(m_points[1]), new KisPerspectiveGridNode(m_points[2]), new KisPerspectiveGridNode(m_points[3]) ) ); - drawGrid(); - m_mode = MODE_EDITING; - } - } - } else { - m_mode = MODE_EDITING; - m_selectedNode1 = 0; - m_selectedNode2 = 0; - } - -/* if (m_dragging && event->button() == RightButton) { - - }*/ -} - -void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc) -{ - if( m_mode == MODE_CREATION ) - { - drawGridCreation(gc); - } else { - drawGrid(gc); - } -} - -void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc, const TQRect&) -{ - if( m_mode == MODE_CREATION ) - { - drawGridCreation(gc); - } else { - drawGrid(gc); - } -} - -void KisToolPerspectiveGrid::drawGridCreation() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - drawGridCreation(gc); - } -} - - -void KisToolPerspectiveGrid::drawGridCreation(KisCanvasPainter& gc) -{ - if (!m_subject) - return; - - TQPen pen(TQt::white); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - -void KisToolPerspectiveGrid::drawSmallRectangle(KisCanvasPainter& gc, TQPoint p) -{ - gc.drawRect( p.x() - m_handleHalfSize - 1, p.y() - m_handleHalfSize - 1, m_handleSize, m_handleSize); -} - -void KisToolPerspectiveGrid::drawGrid(KisCanvasPainter& gc) -{ - - if (!m_subject) - return; - - KisCanvasController *controller = m_subject->canvasController(); - - TQPen pen(TQt::white); - TQPoint startPos; - TQPoint endPos; - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); - - for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) - { - KisSubPerspectiveGrid* grid = *it; - int index = grid->index(); - bool drawLeft = !(grid->leftGrid() && (index > grid->leftGrid()->index() ) ); - bool drawRight = !(grid->rightGrid() && (index > grid->rightGrid()->index() ) ); - bool drawTop = !(grid->topGrid() && (index > grid->topGrid()->index() ) ); - bool drawBottom = !(grid->bottomGrid() && (index > grid->bottomGrid()->index() ) ); - if(drawTop) { - startPos = controller->windowToView(grid->topLeft()->roundTQPoint()); - endPos = controller->windowToView(grid->topRight()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->topGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - if(drawLeft) { - drawSmallRectangle(gc, startPos); - } - if(drawRight) { - drawSmallRectangle(gc, endPos); - } - } - if(drawRight) { - startPos = controller->windowToView(grid->topRight()->roundTQPoint()); - endPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->rightGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - } - if(drawBottom) { - startPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); - endPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->bottomGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - if(drawLeft) { - drawSmallRectangle(gc, endPos); - } - if(drawRight) { - drawSmallRectangle(gc, startPos); - } - } - if(drawLeft) { - startPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); - endPos = controller->windowToView(grid->topLeft()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->leftGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - } - KisPoint tbVpf = grid->topBottomVanishingPoint(); - if( fabs(tbVpf.x()) < 30000000. && fabs(tbVpf.y()) < 30000000.) - { - TQPoint tbVp = controller->windowToView(tbVpf.roundTQPoint()); - gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() - m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() + m_handleHalfSize); - gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() + m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() - m_handleHalfSize); - } - KisPoint lrVpf = grid->leftRightVanishingPoint(); - if( fabs(lrVpf.x()) < 30000000. && fabs(lrVpf.y()) < 30000000.) - { // Don't display it, if it is too far, or you get funny results - TQPoint lrVp = controller->windowToView(lrVpf.roundTQPoint()); - gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() - m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() + m_handleHalfSize); - gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() + m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() - m_handleHalfSize); - } - } -} - -void KisToolPerspectiveGrid::drawGrid() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - drawGrid(gc); - } - -} - - -void KisToolPerspectiveGrid::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Perspective Grid"), - "tool_perspectivegrid" , - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Edit the perspective grid")); - m_ownAction = true; - } -} - - -// TQWidget* KisToolPerspectiveGrid::createOptionWidget(TQWidget* parent) -// { -// return 0; -// } -// -// TQWidget* KisToolPerspectiveGrid::optionWidget() -// { -// return 0; -// } - - -#include "kis_tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp new file mode 100644 index 00000000..7d5df0f2 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp @@ -0,0 +1,499 @@ +/* + * kis_tool_perspectivegrid.cpp - part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +KisToolPerspectiveGrid::KisToolPerspectiveGrid() + : super(i18n("Perspective Grid")), m_handleSize(13), m_handleHalfSize(6) + +{ + setName("tool_perspectivegrid"); + + m_subject = 0; + m_dragging = false; +} + +KisToolPerspectiveGrid::~KisToolPerspectiveGrid() +{ +} + +void KisToolPerspectiveGrid::activate() +{ + m_subject->perspectiveGridManager()->startEdition(); + if( ! m_subject->currentImg()->perspectiveGrid()->hasSubGrids() ) + { + m_mode = MODE_CREATION; + m_points.clear(); + } else { + m_mode = MODE_EDITING; + drawGrid(); + } + super::activate(); +} + +void KisToolPerspectiveGrid::deactivate() +{ + m_subject->perspectiveGridManager()->stopEdition(); + m_subject->perspectiveGridManager()->setGridVisible( true); + if( m_mode == MODE_CREATION ) + { + drawGridCreation(); + m_points.clear(); + m_dragging = false; + } else { + drawGrid(); + } +} + + +void KisToolPerspectiveGrid::update (KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +bool KisToolPerspectiveGrid::mouseNear(const TQPoint& mousep, const TQPoint point) +{ + return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); +} + +void KisToolPerspectiveGrid::buttonPress(KisButtonPressEvent *event) +{ + KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); + if(!pGrid->hasSubGrids() && m_mode != MODE_CREATION) + { // it's possible that the perspectiv grid was cleared + m_mode = MODE_CREATION; + m_points.clear(); + } + if( m_mode == MODE_CREATION && event->button() == Qt::LeftButton) + { + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + drawGridCreation(); + } + } else if(m_mode == MODE_EDITING && event->button() == Qt::LeftButton){ + // Look for the handle which was pressed + if (!m_subject) + return; + KisCanvasController *controller = m_subject->canvasController(); + Q_ASSERT(controller); + TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); + + for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) + { + KisSubPerspectiveGrid* grid = *it; + if( mouseNear( mousep, controller->windowToView(grid->topLeft()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPLEFT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->topLeft(); + break; + } + else if( mouseNear( mousep, controller->windowToView(grid->topRight()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->topRight(); + break; + } + else if( mouseNear( mousep, controller->windowToView(grid->bottomLeft()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->bottomLeft(); + break; + } + else if( mouseNear( mousep, controller->windowToView(grid->bottomRight()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->bottomRight(); + break; + } + else if( !grid->leftGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->bottomLeft() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS LEFT HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomLeft() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, grid->topLeft() , grid->bottomLeft(), m_selectedNode2); + m_dragEnd = event->pos(); + newsubgrid->setRightGrid( grid); + grid->setLeftGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + else if( !grid->rightGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topRight() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS RIGHT HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->topRight() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->topRight(), m_selectedNode1, m_selectedNode2, grid->bottomRight()); + m_dragEnd = event->pos(); + newsubgrid->setLeftGrid( grid); + grid->setRightGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + else if( !grid->topGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->topRight() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS TOP HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->topRight() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, m_selectedNode2, grid->topRight(), grid->topLeft() ); + m_dragEnd = event->pos(); + newsubgrid->setBottomGrid( grid); + grid->setTopGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + else if( !grid->bottomGrid() && mouseNear( mousep, controller->windowToView( ((*grid->bottomLeft() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS BOTTOM HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->bottomLeft() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->bottomLeft(), grid->bottomRight(), m_selectedNode2, m_selectedNode1); + m_dragEnd = event->pos(); + newsubgrid->setTopGrid( grid); + grid->setBottomGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + } + } +} + + +void KisToolPerspectiveGrid::move(KisMoveEvent *event) +{ + if( m_mode == MODE_CREATION ) + { + if (m_dragging) { + // erase old lines on canvas + drawGridCreation(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + drawGridCreation(); + } + } else { + if( m_mode == MODE_DRAGING_NODE) + { + drawGrid(); + m_selectedNode1->setX( event->pos().x() ); + m_selectedNode1->setY( event->pos().y() ); + drawGrid(); + } + if( m_mode == MODE_DRAGING_TRANSLATING_TWONODES) + { + drawGrid(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + *m_selectedNode1 += translate;; + *m_selectedNode2 += translate;; + drawGrid(); + } + } +} + +void KisToolPerspectiveGrid::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if( m_mode == MODE_CREATION ) + { + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + if( m_points.size() == 4) + { // wow we have a grid, isn't that cool ? + drawGridCreation(); // Clean + m_subject->currentImg()->perspectiveGrid()->addNewSubGrid( new KisSubPerspectiveGrid( new KisPerspectiveGridNode(m_points[0]), new KisPerspectiveGridNode(m_points[1]), new KisPerspectiveGridNode(m_points[2]), new KisPerspectiveGridNode(m_points[3]) ) ); + drawGrid(); + m_mode = MODE_EDITING; + } + } + } else { + m_mode = MODE_EDITING; + m_selectedNode1 = 0; + m_selectedNode2 = 0; + } + +/* if (m_dragging && event->button() == RightButton) { + + }*/ +} + +void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc) +{ + if( m_mode == MODE_CREATION ) + { + drawGridCreation(gc); + } else { + drawGrid(gc); + } +} + +void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc, const TQRect&) +{ + if( m_mode == MODE_CREATION ) + { + drawGridCreation(gc); + } else { + drawGrid(gc); + } +} + +void KisToolPerspectiveGrid::drawGridCreation() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + drawGridCreation(gc); + } +} + + +void KisToolPerspectiveGrid::drawGridCreation(KisCanvasPainter& gc) +{ + if (!m_subject) + return; + + TQPen pen(TQt::white); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + +void KisToolPerspectiveGrid::drawSmallRectangle(KisCanvasPainter& gc, TQPoint p) +{ + gc.drawRect( p.x() - m_handleHalfSize - 1, p.y() - m_handleHalfSize - 1, m_handleSize, m_handleSize); +} + +void KisToolPerspectiveGrid::drawGrid(KisCanvasPainter& gc) +{ + + if (!m_subject) + return; + + KisCanvasController *controller = m_subject->canvasController(); + + TQPen pen(TQt::white); + TQPoint startPos; + TQPoint endPos; + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); + + for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) + { + KisSubPerspectiveGrid* grid = *it; + int index = grid->index(); + bool drawLeft = !(grid->leftGrid() && (index > grid->leftGrid()->index() ) ); + bool drawRight = !(grid->rightGrid() && (index > grid->rightGrid()->index() ) ); + bool drawTop = !(grid->topGrid() && (index > grid->topGrid()->index() ) ); + bool drawBottom = !(grid->bottomGrid() && (index > grid->bottomGrid()->index() ) ); + if(drawTop) { + startPos = controller->windowToView(grid->topLeft()->roundTQPoint()); + endPos = controller->windowToView(grid->topRight()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->topGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + if(drawLeft) { + drawSmallRectangle(gc, startPos); + } + if(drawRight) { + drawSmallRectangle(gc, endPos); + } + } + if(drawRight) { + startPos = controller->windowToView(grid->topRight()->roundTQPoint()); + endPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->rightGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + } + if(drawBottom) { + startPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); + endPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->bottomGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + if(drawLeft) { + drawSmallRectangle(gc, endPos); + } + if(drawRight) { + drawSmallRectangle(gc, startPos); + } + } + if(drawLeft) { + startPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); + endPos = controller->windowToView(grid->topLeft()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->leftGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + } + KisPoint tbVpf = grid->topBottomVanishingPoint(); + if( fabs(tbVpf.x()) < 30000000. && fabs(tbVpf.y()) < 30000000.) + { + TQPoint tbVp = controller->windowToView(tbVpf.roundTQPoint()); + gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() - m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() + m_handleHalfSize); + gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() + m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() - m_handleHalfSize); + } + KisPoint lrVpf = grid->leftRightVanishingPoint(); + if( fabs(lrVpf.x()) < 30000000. && fabs(lrVpf.y()) < 30000000.) + { // Don't display it, if it is too far, or you get funny results + TQPoint lrVp = controller->windowToView(lrVpf.roundTQPoint()); + gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() - m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() + m_handleHalfSize); + gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() + m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() - m_handleHalfSize); + } + } +} + +void KisToolPerspectiveGrid::drawGrid() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + drawGrid(gc); + } + +} + + +void KisToolPerspectiveGrid::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Perspective Grid"), + "tool_perspectivegrid" , + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Edit the perspective grid")); + m_ownAction = true; + } +} + + +// TQWidget* KisToolPerspectiveGrid::createOptionWidget(TQWidget* parent) +// { +// return 0; +// } +// +// TQWidget* KisToolPerspectiveGrid::optionWidget() +// { +// return 0; +// } + + +#include "kis_tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc deleted file mode 100644 index f2800a59..00000000 --- a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_perspectivegrid.cc -- Part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_perspectivegrid.h" -#include "kis_tool_perspectivegrid.h" - - -typedef KGenericFactory ToolPerspectiveGridFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivegrid, ToolPerspectiveGridFactory( "chalk" ) ) - - -ToolPerspectiveGrid::ToolPerspectiveGrid(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPerspectiveGridFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolPerspectiveGridFactory()); - } - -} - -ToolPerspectiveGrid::~ToolPerspectiveGrid() -{ -} - -#include "tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp new file mode 100644 index 00000000..2f326965 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp @@ -0,0 +1,62 @@ +/* + * tool_perspectivegrid.cpp -- Part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_perspectivegrid.h" +#include "kis_tool_perspectivegrid.h" + + +typedef KGenericFactory ToolPerspectiveGridFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivegrid, ToolPerspectiveGridFactory( "chalk" ) ) + + +ToolPerspectiveGrid::ToolPerspectiveGrid(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPerspectiveGridFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolPerspectiveGridFactory()); + } + +} + +ToolPerspectiveGrid::~ToolPerspectiveGrid() +{ +} + +#include "tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/Makefile.am b/chalk/plugins/tools/tool_perspectivetransform/Makefile.am index 08c8d707..275f6413 100644 --- a/chalk/plugins/tools/tool_perspectivetransform/Makefile.am +++ b/chalk/plugins/tools/tool_perspectivetransform/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolperspectivetransform_la_SOURCES = \ - tool_perspectivetransform.cc \ - kis_tool_perspectivetransform.cc + tool_perspectivetransform.cpp \ + kis_tool_perspectivetransform.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolperspectivetransform.la diff --git a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc deleted file mode 100644 index ae334e62..00000000 --- a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc +++ /dev/null @@ -1,742 +0,0 @@ -/* - * kis_tool_transform.cc -- part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * Based on the transform tool from : - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2005 Casper Boemann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_tool_perspectivetransform.h" - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include "wdg_tool_transform.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -namespace { - class PerspectiveTransformCmd : public KisSelectedTransaction { - typedef KisSelectedTransaction super; - - public: - PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect); - virtual ~PerspectiveTransformCmd(); - - public: - virtual void execute(); - virtual void unexecute(); - void transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const; - KisSelectionSP origSelection(TQRect& initialRect) const; - KisPaintDeviceSP theDevice(); - KisPaintDeviceSP origDevice(); - - private: - TQRect m_initialRect; - KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright; - KisToolPerspectiveTransform *m_tool; - KisSelectionSP m_origSelection; - KisPaintDeviceSP m_device; - KisPaintDeviceSP m_origDevice; - }; - - PerspectiveTransformCmd::PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect) : - super(i18n("Perspective Transform"), device), m_initialRect(initialRect) - , m_topleft(topleft), m_topright(topright), m_bottomleft(bottomleft), m_bottomright(bottomright) - , m_tool(tool), m_origSelection(origSel), m_device(device), m_origDevice(origDevice) - { - } - - PerspectiveTransformCmd::~PerspectiveTransformCmd() - { - } - - void PerspectiveTransformCmd::transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const - { - topleft = m_topleft; - topright = m_topright; - bottomleft = m_bottomleft; - bottomright = m_bottomright; - } - - KisSelectionSP PerspectiveTransformCmd::origSelection(TQRect& initialRect) const - { - initialRect = m_initialRect; - return m_origSelection; - } - - void PerspectiveTransformCmd::execute() - { - super::execute(); - } - - void PerspectiveTransformCmd::unexecute() - { - super::unexecute(); - } - - KisPaintDeviceSP PerspectiveTransformCmd::theDevice() - { - return m_device; - } - - KisPaintDeviceSP PerspectiveTransformCmd::origDevice() - { - return m_origDevice; - } -} - -KisToolPerspectiveTransform::KisToolPerspectiveTransform() - : super(i18n("Perspective Transform")) -{ - setName("tool_perspectivetransform"); - setCursor(KisCursor::selectCursor()); - m_subject = 0; - m_origDevice = 0; - m_origSelection = 0; - m_handleHalfSize = 8; - m_handleSize = 2 * m_handleHalfSize; - m_handleSelected = NOHANDLE; -} - -KisToolPerspectiveTransform::~KisToolPerspectiveTransform() -{ -} - -void KisToolPerspectiveTransform::deactivate() -{ - if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); - - KisImageSP img = m_subject->currentImg(); - if (!img) return; - - paintOutline(); - - disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolPerspectiveTransform::activate() -{ - super::activate(); - m_currentSelectedPoint = 0; - if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) - { - //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); - m_subject->undoAdapter()->setCommandHistoryListener( this ); - -// KisToolControllerInterface *controller = m_subject->toolController(); -// if (controller) -// controller->setCurrentTool(this); - - PerspectiveTransformCmd * cmd=0; - - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - // One of our commands is on top - if(cmd &&cmd->theDevice() == m_subject->currentImg()->activeDevice()) - { - m_interractionMode = EDITRECTINTERRACTION; - // and it even has the same device - // We should ask for tool args and orig selection - m_origDevice = cmd->origDevice(); - cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); - m_origSelection = cmd->origSelection(m_initialRect); - paintOutline(); - } - else - { - m_interractionMode = DRAWRECTINTERRACTION; - m_points.clear(); - initHandles(); - } - } - connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolPerspectiveTransform::initHandles() -{ -// TQ_INT32 x,y,w,h; - KisImageSP img = m_subject->currentImg(); - - KisPaintDeviceSP dev = img->activeDevice(); - if (!dev ) return; - - // Create a lazy copy of the current state - m_origDevice = new KisPaintDevice(*dev.data()); - Q_ASSERT(m_origDevice); - - if(dev->hasSelection()) - { - KisSelectionSP sel = dev->selection(); - m_origSelection = new KisSelection(*sel.data()); - m_initialRect = sel->selectedExactRect(); - } - else { - m_initialRect = dev->exactBounds(); - } - m_topleft = KisPoint(m_initialRect.topLeft()); - m_topright = KisPoint(m_initialRect.topRight()); - m_bottomleft = KisPoint(m_initialRect.bottomLeft()); - m_bottomright = KisPoint(m_initialRect.bottomRight()); - - m_subject->canvasController() ->updateCanvas(); -} - -void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc) -{ - paintOutline(gc, TQRect()); -} - -void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - paintOutline(gc, rc); -} - -bool KisToolPerspectiveTransform::mouseNear(const TQPoint& mousep, const TQPoint point) -{ - return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); -} - -void KisToolPerspectiveTransform::buttonPress(KisButtonPressEvent *event) -{ - if (m_subject) { - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - if (m_points.isEmpty()) - { - m_dragging = false; - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - paintOutline(); - } else { - m_dragging = true; - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - paintOutline(); - } - } - case EDITRECTINTERRACTION: - { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && event->button() == Qt::LeftButton) { - m_actualyMoveWhileSelected = false; - m_dragEnd = event->pos(); - KisCanvasController *controller = m_subject->canvasController(); - TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); - if( mouseNear( mousep, controller->windowToView(m_topleft.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPLEFT HANDLE " << endl; - m_currentSelectedPoint = &m_topleft; - } - else if( mouseNear( mousep, controller->windowToView(m_topright.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; - m_currentSelectedPoint = &m_topright; - } - else if( mouseNear( mousep, controller->windowToView(m_bottomleft.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; - m_currentSelectedPoint = &m_bottomleft; - } - else if( mouseNear( mousep, controller->windowToView(m_bottomright.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; - m_currentSelectedPoint = &m_bottomright; - } else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_topright)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOP HANDLE " << endl; - m_handleSelected = TOPHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS LEFT HANDLE " << endl; - m_handleSelected = LEFTHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomleft+m_bottomright)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOM HANDLE " << endl; - m_handleSelected = BOTTOMHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomright+m_topright)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS RIGHT HANDLE " << endl; - m_handleSelected = RIGHTHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft + m_bottomright+m_topright)*0.25).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS MIDDLE HANDLE " << endl; - m_handleSelected = MIDDLEHANDLE; - } - } - } - } - } -} - -void KisToolPerspectiveTransform::move(KisMoveEvent *event) -{ - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - if (m_dragging) { - // erase old lines on canvas - paintOutline(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - paintOutline(); - } - } - - case EDITRECTINTERRACTION: - { - if(m_currentSelectedPoint) - { - paintOutline(); - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - *m_currentSelectedPoint += translate;; - paintOutline(); - m_actualyMoveWhileSelected = true; - } - else if(m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE) - { - paintOutline(); - - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - - double matrixFrom[3][3]; - double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - matrixFrom[i][j] = b[3*i+j]; - } - } - delete b; - - KisPoint topLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topLeft()) ); - KisPoint topRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topRight()) ); - KisPoint bottomLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomLeft()) ); - KisPoint bottomRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomRight()) ); - TQRect dstRect = m_initialRect; - switch(m_handleSelected) - { - case TOPHANDLE: - dstRect.setTop( static_cast( dstRect.top() + translate.y() ) ) ; - break; - case LEFTHANDLE: - dstRect.setLeft( static_cast( dstRect.left() + translate.x() ) ); - break; - case BOTTOMHANDLE: - dstRect.setBottom( static_cast( dstRect.bottom() + translate.y() ) ); - break; - case RIGHTHANDLE: - dstRect.setRight( static_cast( dstRect.right() + translate.x() ) ); - break; - case MIDDLEHANDLE: - case NOHANDLE: - kdDebug() << "Should NOT happen" << endl; - } - double matrixTo[3][3]; - b = KisPerspectiveMath::computeMatrixTransfoToPerspective(topLeft, topRight, bottomLeft, bottomRight, dstRect ); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - matrixTo[i][j] = b[3*i+j]; - } - } - delete b; - m_topleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topLeft())); - m_topright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topRight())); - m_bottomleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomLeft())); - m_bottomright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomRight())); - - paintOutline(); - m_actualyMoveWhileSelected = true; - } else if (m_handleSelected == MIDDLEHANDLE) { - paintOutline(); - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - m_topleft += translate; - m_topright += translate; - m_bottomleft += translate; - m_bottomright += translate; - paintOutline(); - m_actualyMoveWhileSelected = true; - } - } - }; -} - -void KisToolPerspectiveTransform::buttonRelease(KisButtonReleaseEvent * event) -{ - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - if( event->button() == Qt::LeftButton) - { - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - if (m_dragging && event->button() == Qt::LeftButton) { - paintOutline(); - m_dragging = false; - m_points.append (m_dragEnd); - if( m_points.size() == 4) - { - // from the points, select which is topleft ? topright ? bottomright ? and bottomleft ? - m_topleft = m_points[0]; - m_topright = m_points[1]; - m_bottomleft = m_points[3]; - m_bottomright = m_points[2]; - double matrix[3][3]; - double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect ); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; - matrix[i][j] = b[3*i+j]; - } - } - m_topleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topLeft())); - m_topright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topRight())); - m_bottomleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomLeft())); - m_bottomright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomRight())); - m_interractionMode = EDITRECTINTERRACTION; - paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } else { - paintOutline(); - } - } - } - break; - case EDITRECTINTERRACTION: - { - if(m_currentSelectedPoint ) - { - m_currentSelectedPoint = 0; - if(m_actualyMoveWhileSelected) - { - paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } - } - if(m_handleSelected != NOHANDLE) - { - m_handleSelected = NOHANDLE; - if(m_actualyMoveWhileSelected) - { -// paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } - } - } - break; - } - } -} - -void KisToolPerspectiveTransform::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolPerspectiveTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - pen.setWidth(1); - Q_ASSERT(controller); - - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - kdDebug() << "DRAWRECTINTERRACTION paintOutline " << m_points.size() << endl; - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } - break; - case EDITRECTINTERRACTION: - { - TQPoint topleft = controller->windowToView(m_topleft ).roundTQPoint(); - TQPoint topright = controller->windowToView(m_topright).roundTQPoint(); - TQPoint bottomleft = controller->windowToView(m_bottomleft).roundTQPoint(); - TQPoint bottomright = controller->windowToView(m_bottomright).roundTQPoint(); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); - gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); - gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); - gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); - gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); - gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); - gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); - gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); - gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); - gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); - gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); - gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); - gc.drawRect((bottomleft.x()+bottomright.x()+topleft.x()+topright.x())/4-4, (bottomleft.y()+bottomright.y()+topleft.y()+topright.y())/4-4, 8, 8); - } - break; - } - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolPerspectiveTransform::transform() -{ - KisImageSP img = m_subject->currentImg(); - - if (!img || !img->activeDevice()) - return; - - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - - // This mementoes the current state of the active device. - PerspectiveTransformCmd * transaction = new PerspectiveTransformCmd(this, img->activeDevice(), m_origDevice, - m_topleft, m_topright, m_bottomleft, m_bottomright, m_origSelection, m_initialRect); - - // Copy the original state back. - TQRect rc = m_origDevice->extent(); - rc = rc.normalize(); - img->activeDevice()->clear(); - KisPainter gc(img->activeDevice()); - gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); - gc.end(); - - // Also restore the original selection. - if(m_origSelection) - { - TQRect rc = m_origSelection->selectedRect(); - rc = rc.normalize(); - img->activeDevice()->selection()->clear(); - KisPainter sgc(img->activeDevice()->selection().data()); - sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); - sgc.end(); - } - else - if(img->activeDevice()->hasSelection()) - img->activeDevice()->selection()->clear(); - - // Perform the transform. Since we copied the original state back, this doesn't degrade - // after many tweaks. Since we started the transaction before the copy back, the memento - // has the previous state. - KisPerspectiveTransformWorker t(img->activeDevice(),m_topleft, m_topright, m_bottomleft, m_bottomright, progress); - t.run(); - - // If canceled, go back to the memento - if(t.isCanceled()) - { - transaction->unexecute(); - delete transaction; - return; - } - - img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent - - // Else add the command -- this will have the memento from the previous state, - // and the transformed state from the original device we cached in our activated() - // method. - if (transaction) { - if (img->undo()) - img->undoAdapter()->addCommand(transaction); - else - delete transaction; - } -} - -void KisToolPerspectiveTransform::notifyCommandAdded( KCommand * command) -{ - PerspectiveTransformCmd * cmd = dynamic_cast(command); - if (cmd == 0) { - // The last added command wasn't one of ours; - // we should reset to the new state of the canvas. - // In effect we should treat this as if the tool has been just activated - initHandles(); - } -} - -void KisToolPerspectiveTransform::notifyCommandExecuted( KCommand * command) -{ - Q_UNUSED(command); - PerspectiveTransformCmd * cmd=0; - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - if (cmd == 0) { - // The command now on the top of the stack isn't one of ours - // We should treat this as if the tool has been just activated - initHandles(); - } - else - { - // One of our commands is now on top - // We should ask for tool args and orig selection - m_origDevice = cmd->origDevice(); - cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); - m_origSelection = cmd->origSelection(m_initialRect); - m_subject->canvasController() ->updateCanvas(); - } -} - -void KisToolPerspectiveTransform::slotLayerActivated(KisLayerSP) -{ - activate(); -} - - -TQWidget* KisToolPerspectiveTransform::createOptionWidget(TQWidget* /*parent*/) -{ -#if 0 - m_optWidget = new WdgToolPerspectiveTransform(parent); - TQ_CHECK_PTR(m_optWidget); - - m_optWidget->cmbFilter->clear(); - m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); - - m_optWidget->cmbFilter->setCurrentText("Mitchell"); - connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), - this, TQT_SLOT(slotSetFilter(const KisID &))); - - KisID filterID = m_optWidget->cmbFilter->currentItem(); - m_filter = KisFilterStrategyRegistry::instance()->get(filterID); - -/* - connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); - connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); - connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); - connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); -*/ - m_optWidget->intStartX->hide(); - m_optWidget->intStartY->hide(); - m_optWidget->intEndX->hide(); - m_optWidget->intEndY->hide(); - m_optWidget->textLabel1->hide(); - m_optWidget->textLabel2->hide(); - m_optWidget->textLabel3->hide(); - m_optWidget->textLabel4->hide(); -#endif - return 0; -} - -TQWidget* KisToolPerspectiveTransform::optionWidget() -{ - return 0; -} - -void KisToolPerspectiveTransform::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Perspective Transform"), - "tool_perspectivetransform", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Perspective transform a layer or a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp new file mode 100644 index 00000000..e73f5da3 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp @@ -0,0 +1,742 @@ +/* + * kis_tool_transform.cpp -- part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * Based on the transform tool from : + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2005 Casper Boemann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_tool_perspectivetransform.h" + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "wdg_tool_transform.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +namespace { + class PerspectiveTransformCmd : public KisSelectedTransaction { + typedef KisSelectedTransaction super; + + public: + PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect); + virtual ~PerspectiveTransformCmd(); + + public: + virtual void execute(); + virtual void unexecute(); + void transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const; + KisSelectionSP origSelection(TQRect& initialRect) const; + KisPaintDeviceSP theDevice(); + KisPaintDeviceSP origDevice(); + + private: + TQRect m_initialRect; + KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright; + KisToolPerspectiveTransform *m_tool; + KisSelectionSP m_origSelection; + KisPaintDeviceSP m_device; + KisPaintDeviceSP m_origDevice; + }; + + PerspectiveTransformCmd::PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect) : + super(i18n("Perspective Transform"), device), m_initialRect(initialRect) + , m_topleft(topleft), m_topright(topright), m_bottomleft(bottomleft), m_bottomright(bottomright) + , m_tool(tool), m_origSelection(origSel), m_device(device), m_origDevice(origDevice) + { + } + + PerspectiveTransformCmd::~PerspectiveTransformCmd() + { + } + + void PerspectiveTransformCmd::transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const + { + topleft = m_topleft; + topright = m_topright; + bottomleft = m_bottomleft; + bottomright = m_bottomright; + } + + KisSelectionSP PerspectiveTransformCmd::origSelection(TQRect& initialRect) const + { + initialRect = m_initialRect; + return m_origSelection; + } + + void PerspectiveTransformCmd::execute() + { + super::execute(); + } + + void PerspectiveTransformCmd::unexecute() + { + super::unexecute(); + } + + KisPaintDeviceSP PerspectiveTransformCmd::theDevice() + { + return m_device; + } + + KisPaintDeviceSP PerspectiveTransformCmd::origDevice() + { + return m_origDevice; + } +} + +KisToolPerspectiveTransform::KisToolPerspectiveTransform() + : super(i18n("Perspective Transform")) +{ + setName("tool_perspectivetransform"); + setCursor(KisCursor::selectCursor()); + m_subject = 0; + m_origDevice = 0; + m_origSelection = 0; + m_handleHalfSize = 8; + m_handleSize = 2 * m_handleHalfSize; + m_handleSelected = NOHANDLE; +} + +KisToolPerspectiveTransform::~KisToolPerspectiveTransform() +{ +} + +void KisToolPerspectiveTransform::deactivate() +{ + if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); + + KisImageSP img = m_subject->currentImg(); + if (!img) return; + + paintOutline(); + + disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolPerspectiveTransform::activate() +{ + super::activate(); + m_currentSelectedPoint = 0; + if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) + { + //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); + m_subject->undoAdapter()->setCommandHistoryListener( this ); + +// KisToolControllerInterface *controller = m_subject->toolController(); +// if (controller) +// controller->setCurrentTool(this); + + PerspectiveTransformCmd * cmd=0; + + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + // One of our commands is on top + if(cmd &&cmd->theDevice() == m_subject->currentImg()->activeDevice()) + { + m_interractionMode = EDITRECTINTERRACTION; + // and it even has the same device + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); + m_origSelection = cmd->origSelection(m_initialRect); + paintOutline(); + } + else + { + m_interractionMode = DRAWRECTINTERRACTION; + m_points.clear(); + initHandles(); + } + } + connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolPerspectiveTransform::initHandles() +{ +// TQ_INT32 x,y,w,h; + KisImageSP img = m_subject->currentImg(); + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev ) return; + + // Create a lazy copy of the current state + m_origDevice = new KisPaintDevice(*dev.data()); + Q_ASSERT(m_origDevice); + + if(dev->hasSelection()) + { + KisSelectionSP sel = dev->selection(); + m_origSelection = new KisSelection(*sel.data()); + m_initialRect = sel->selectedExactRect(); + } + else { + m_initialRect = dev->exactBounds(); + } + m_topleft = KisPoint(m_initialRect.topLeft()); + m_topright = KisPoint(m_initialRect.topRight()); + m_bottomleft = KisPoint(m_initialRect.bottomLeft()); + m_bottomright = KisPoint(m_initialRect.bottomRight()); + + m_subject->canvasController() ->updateCanvas(); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc) +{ + paintOutline(gc, TQRect()); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + paintOutline(gc, rc); +} + +bool KisToolPerspectiveTransform::mouseNear(const TQPoint& mousep, const TQPoint point) +{ + return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); +} + +void KisToolPerspectiveTransform::buttonPress(KisButtonPressEvent *event) +{ + if (m_subject) { + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_points.isEmpty()) + { + m_dragging = false; + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + paintOutline(); + } else { + m_dragging = true; + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + paintOutline(); + } + } + case EDITRECTINTERRACTION: + { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && event->button() == Qt::LeftButton) { + m_actualyMoveWhileSelected = false; + m_dragEnd = event->pos(); + KisCanvasController *controller = m_subject->canvasController(); + TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); + if( mouseNear( mousep, controller->windowToView(m_topleft.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_topleft; + } + else if( mouseNear( mousep, controller->windowToView(m_topright.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_topright; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomleft.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomleft; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomright.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomright; + } else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_topright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOP HANDLE " << endl; + m_handleSelected = TOPHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS LEFT HANDLE " << endl; + m_handleSelected = LEFTHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomleft+m_bottomright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOM HANDLE " << endl; + m_handleSelected = BOTTOMHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomright+m_topright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS RIGHT HANDLE " << endl; + m_handleSelected = RIGHTHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft + m_bottomright+m_topright)*0.25).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS MIDDLE HANDLE " << endl; + m_handleSelected = MIDDLEHANDLE; + } + } + } + } + } +} + +void KisToolPerspectiveTransform::move(KisMoveEvent *event) +{ + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_dragging) { + // erase old lines on canvas + paintOutline(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + paintOutline(); + } + } + + case EDITRECTINTERRACTION: + { + if(m_currentSelectedPoint) + { + paintOutline(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + *m_currentSelectedPoint += translate;; + paintOutline(); + m_actualyMoveWhileSelected = true; + } + else if(m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE) + { + paintOutline(); + + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + + double matrixFrom[3][3]; + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + matrixFrom[i][j] = b[3*i+j]; + } + } + delete b; + + KisPoint topLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topLeft()) ); + KisPoint topRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topRight()) ); + KisPoint bottomLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomLeft()) ); + KisPoint bottomRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomRight()) ); + TQRect dstRect = m_initialRect; + switch(m_handleSelected) + { + case TOPHANDLE: + dstRect.setTop( static_cast( dstRect.top() + translate.y() ) ) ; + break; + case LEFTHANDLE: + dstRect.setLeft( static_cast( dstRect.left() + translate.x() ) ); + break; + case BOTTOMHANDLE: + dstRect.setBottom( static_cast( dstRect.bottom() + translate.y() ) ); + break; + case RIGHTHANDLE: + dstRect.setRight( static_cast( dstRect.right() + translate.x() ) ); + break; + case MIDDLEHANDLE: + case NOHANDLE: + kdDebug() << "Should NOT happen" << endl; + } + double matrixTo[3][3]; + b = KisPerspectiveMath::computeMatrixTransfoToPerspective(topLeft, topRight, bottomLeft, bottomRight, dstRect ); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + matrixTo[i][j] = b[3*i+j]; + } + } + delete b; + m_topleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topLeft())); + m_topright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topRight())); + m_bottomleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomLeft())); + m_bottomright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomRight())); + + paintOutline(); + m_actualyMoveWhileSelected = true; + } else if (m_handleSelected == MIDDLEHANDLE) { + paintOutline(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + m_topleft += translate; + m_topright += translate; + m_bottomleft += translate; + m_bottomright += translate; + paintOutline(); + m_actualyMoveWhileSelected = true; + } + } + }; +} + +void KisToolPerspectiveTransform::buttonRelease(KisButtonReleaseEvent * event) +{ + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + if( event->button() == Qt::LeftButton) + { + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_dragging && event->button() == Qt::LeftButton) { + paintOutline(); + m_dragging = false; + m_points.append (m_dragEnd); + if( m_points.size() == 4) + { + // from the points, select which is topleft ? topright ? bottomright ? and bottomleft ? + m_topleft = m_points[0]; + m_topright = m_points[1]; + m_bottomleft = m_points[3]; + m_bottomright = m_points[2]; + double matrix[3][3]; + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect ); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; + matrix[i][j] = b[3*i+j]; + } + } + m_topleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topLeft())); + m_topright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topRight())); + m_bottomleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomLeft())); + m_bottomright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomRight())); + m_interractionMode = EDITRECTINTERRACTION; + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } else { + paintOutline(); + } + } + } + break; + case EDITRECTINTERRACTION: + { + if(m_currentSelectedPoint ) + { + m_currentSelectedPoint = 0; + if(m_actualyMoveWhileSelected) + { + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } + if(m_handleSelected != NOHANDLE) + { + m_handleSelected = NOHANDLE; + if(m_actualyMoveWhileSelected) + { +// paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } + } + break; + } + } +} + +void KisToolPerspectiveTransform::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolPerspectiveTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + pen.setWidth(1); + Q_ASSERT(controller); + + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + kdDebug() << "DRAWRECTINTERRACTION paintOutline " << m_points.size() << endl; + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } + break; + case EDITRECTINTERRACTION: + { + TQPoint topleft = controller->windowToView(m_topleft ).roundTQPoint(); + TQPoint topright = controller->windowToView(m_topright).roundTQPoint(); + TQPoint bottomleft = controller->windowToView(m_bottomleft).roundTQPoint(); + TQPoint bottomright = controller->windowToView(m_bottomright).roundTQPoint(); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); + gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); + gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); + gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); + gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); + gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); + gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); + gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); + gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); + gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); + gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); + gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); + gc.drawRect((bottomleft.x()+bottomright.x()+topleft.x()+topright.x())/4-4, (bottomleft.y()+bottomright.y()+topleft.y()+topright.y())/4-4, 8, 8); + } + break; + } + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolPerspectiveTransform::transform() +{ + KisImageSP img = m_subject->currentImg(); + + if (!img || !img->activeDevice()) + return; + + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + + // This mementoes the current state of the active device. + PerspectiveTransformCmd * transaction = new PerspectiveTransformCmd(this, img->activeDevice(), m_origDevice, + m_topleft, m_topright, m_bottomleft, m_bottomright, m_origSelection, m_initialRect); + + // Copy the original state back. + TQRect rc = m_origDevice->extent(); + rc = rc.normalize(); + img->activeDevice()->clear(); + KisPainter gc(img->activeDevice()); + gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); + gc.end(); + + // Also restore the original selection. + if(m_origSelection) + { + TQRect rc = m_origSelection->selectedRect(); + rc = rc.normalize(); + img->activeDevice()->selection()->clear(); + KisPainter sgc(img->activeDevice()->selection().data()); + sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); + sgc.end(); + } + else + if(img->activeDevice()->hasSelection()) + img->activeDevice()->selection()->clear(); + + // Perform the transform. Since we copied the original state back, this doesn't degrade + // after many tweaks. Since we started the transaction before the copy back, the memento + // has the previous state. + KisPerspectiveTransformWorker t(img->activeDevice(),m_topleft, m_topright, m_bottomleft, m_bottomright, progress); + t.run(); + + // If canceled, go back to the memento + if(t.isCanceled()) + { + transaction->unexecute(); + delete transaction; + return; + } + + img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent + + // Else add the command -- this will have the memento from the previous state, + // and the transformed state from the original device we cached in our activated() + // method. + if (transaction) { + if (img->undo()) + img->undoAdapter()->addCommand(transaction); + else + delete transaction; + } +} + +void KisToolPerspectiveTransform::notifyCommandAdded( KCommand * command) +{ + PerspectiveTransformCmd * cmd = dynamic_cast(command); + if (cmd == 0) { + // The last added command wasn't one of ours; + // we should reset to the new state of the canvas. + // In effect we should treat this as if the tool has been just activated + initHandles(); + } +} + +void KisToolPerspectiveTransform::notifyCommandExecuted( KCommand * command) +{ + Q_UNUSED(command); + PerspectiveTransformCmd * cmd=0; + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + if (cmd == 0) { + // The command now on the top of the stack isn't one of ours + // We should treat this as if the tool has been just activated + initHandles(); + } + else + { + // One of our commands is now on top + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); + m_origSelection = cmd->origSelection(m_initialRect); + m_subject->canvasController() ->updateCanvas(); + } +} + +void KisToolPerspectiveTransform::slotLayerActivated(KisLayerSP) +{ + activate(); +} + + +TQWidget* KisToolPerspectiveTransform::createOptionWidget(TQWidget* /*parent*/) +{ +#if 0 + m_optWidget = new WdgToolPerspectiveTransform(parent); + TQ_CHECK_PTR(m_optWidget); + + m_optWidget->cmbFilter->clear(); + m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + + m_optWidget->cmbFilter->setCurrentText("Mitchell"); + connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(slotSetFilter(const KisID &))); + + KisID filterID = m_optWidget->cmbFilter->currentItem(); + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); + +/* + connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); + connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); + connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); + connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); +*/ + m_optWidget->intStartX->hide(); + m_optWidget->intStartY->hide(); + m_optWidget->intEndX->hide(); + m_optWidget->intEndY->hide(); + m_optWidget->textLabel1->hide(); + m_optWidget->textLabel2->hide(); + m_optWidget->textLabel3->hide(); + m_optWidget->textLabel4->hide(); +#endif + return 0; +} + +TQWidget* KisToolPerspectiveTransform::optionWidget() +{ + return 0; +} + +void KisToolPerspectiveTransform::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Perspective Transform"), + "tool_perspectivetransform", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Perspective transform a layer or a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc deleted file mode 100644 index 0c4023cc..00000000 --- a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * tool_perspectivetransform.cc -- Part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_perspectivetransform.h" -#include "kis_tool_perspectivetransform.h" - - -typedef KGenericFactory ToolPerspectiveTransformFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivetransform, ToolPerspectiveTransformFactory( "chalk" ) ) - - -ToolPerspectiveTransform::ToolPerspectiveTransform(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPerspectiveTransformFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - kdDebug() << " add perspective transform tool to the registry" << endl; - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolPerspectiveTransformFactory()); - } - -} - -ToolPerspectiveTransform::~ToolPerspectiveTransform() -{ -} - -#include "tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp new file mode 100644 index 00000000..73705264 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp @@ -0,0 +1,63 @@ +/* + * tool_perspectivetransform.cpp -- Part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_perspectivetransform.h" +#include "kis_tool_perspectivetransform.h" + + +typedef KGenericFactory ToolPerspectiveTransformFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivetransform, ToolPerspectiveTransformFactory( "chalk" ) ) + + +ToolPerspectiveTransform::ToolPerspectiveTransform(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPerspectiveTransformFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + kdDebug() << " add perspective transform tool to the registry" << endl; + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolPerspectiveTransformFactory()); + } + +} + +ToolPerspectiveTransform::~ToolPerspectiveTransform() +{ +} + +#include "tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_polygon/Makefile.am b/chalk/plugins/tools/tool_polygon/Makefile.am index 555f59a0..4ad417da 100644 --- a/chalk/plugins/tools/tool_polygon/Makefile.am +++ b/chalk/plugins/tools/tool_polygon/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolpolygon_la_SOURCES = \ - tool_polygon.cc \ - kis_tool_polygon.cc + tool_polygon.cpp \ + kis_tool_polygon.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolpolygon.la diff --git a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc deleted file mode 100644 index a7371e49..00000000 --- a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc +++ /dev/null @@ -1,252 +0,0 @@ -/* - * kis_tool_polygon.cc -- part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_doc.h" -#include "kis_view.h" -#include "kis_painter.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" - -#include "kis_tool_polygon.h" - -KisToolPolygon::KisToolPolygon() - : super(i18n ("Polygon")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_polygon"); - setCursor(KisCursor::load("tool_polygon_cursor.png", 6, 6)); -} - -KisToolPolygon::~KisToolPolygon() -{ -} - -void KisToolPolygon::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolPolygon::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage) { - if (event->button() == Qt::LeftButton && event->state() != ShiftButton) { - - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - draw(); - } - } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { - finish(); - } - } -} - -void KisToolPolygon::finish() -{ - // erase old lines on canvas - draw(); - m_dragging = false; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polygon")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - painter.paintPolygon(m_points); - - m_points.clear(); - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } -} - -void KisToolPolygon::doubleClick( KisDoubleClickEvent * ) -{ - finish(); -} - -void KisToolPolygon::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - draw(); - } -} - -void KisToolPolygon::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - } - - if (m_dragging && event->button() == Qt::RightButton) { - - } -} - -void KisToolPolygon::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolPolygon::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolPolygon::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolPolygon::draw(KisCanvasPainter& gc) -{ - if (!m_subject || !m_currentImage) - return; - - TQPen pen(TQt::white, 0, TQt::SolidLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - - - -void KisToolPolygon::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Polygon"), - "tool_polygon", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw a polygon. Shift-mouseclick ends the polygon.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolPolygon::keyPress(TQKeyEvent *e) -{ - if (e->key()==TQt::Key_Escape) { - // erase old lines on canvas - draw(); - m_dragging = false; - m_points.clear(); - } -} - - -#include "kis_tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp new file mode 100644 index 00000000..601fc690 --- /dev/null +++ b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp @@ -0,0 +1,252 @@ +/* + * kis_tool_polygon.cpp -- part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_doc.h" +#include "kis_view.h" +#include "kis_painter.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" + +#include "kis_tool_polygon.h" + +KisToolPolygon::KisToolPolygon() + : super(i18n ("Polygon")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_polygon"); + setCursor(KisCursor::load("tool_polygon_cursor.png", 6, 6)); +} + +KisToolPolygon::~KisToolPolygon() +{ +} + +void KisToolPolygon::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolPolygon::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage) { + if (event->button() == Qt::LeftButton && event->state() != ShiftButton) { + + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + draw(); + } + } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { + finish(); + } + } +} + +void KisToolPolygon::finish() +{ + // erase old lines on canvas + draw(); + m_dragging = false; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polygon")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + painter.paintPolygon(m_points); + + m_points.clear(); + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } +} + +void KisToolPolygon::doubleClick( KisDoubleClickEvent * ) +{ + finish(); +} + +void KisToolPolygon::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + draw(); + } +} + +void KisToolPolygon::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + } + + if (m_dragging && event->button() == Qt::RightButton) { + + } +} + +void KisToolPolygon::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolPolygon::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolPolygon::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolPolygon::draw(KisCanvasPainter& gc) +{ + if (!m_subject || !m_currentImage) + return; + + TQPen pen(TQt::white, 0, TQt::SolidLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + + + +void KisToolPolygon::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Polygon"), + "tool_polygon", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw a polygon. Shift-mouseclick ends the polygon.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolPolygon::keyPress(TQKeyEvent *e) +{ + if (e->key()==TQt::Key_Escape) { + // erase old lines on canvas + draw(); + m_dragging = false; + m_points.clear(); + } +} + + +#include "kis_tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon.cc b/chalk/plugins/tools/tool_polygon/tool_polygon.cc deleted file mode 100644 index 626a773d..00000000 --- a/chalk/plugins/tools/tool_polygon/tool_polygon.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_polygon.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "tool_polygon.h" -#include "tool_polygon.moc" -#include "kis_tool_polygon.h" - - -typedef KGenericFactory ToolPolygonFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolpolygon, ToolPolygonFactory( "chalk" ) ) - - -ToolPolygon::ToolPolygon(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPolygonFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast( parent ); - r->add(new KisToolPolygonFactory()); - } - -} - -ToolPolygon::~ToolPolygon() -{ -} - -//#include "tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon.cpp b/chalk/plugins/tools/tool_polygon/tool_polygon.cpp new file mode 100644 index 00000000..f903551f --- /dev/null +++ b/chalk/plugins/tools/tool_polygon/tool_polygon.cpp @@ -0,0 +1,62 @@ +/* + * tool_polygon.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "tool_polygon.h" +#include "tool_polygon.moc" +#include "kis_tool_polygon.h" + + +typedef KGenericFactory ToolPolygonFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolpolygon, ToolPolygonFactory( "chalk" ) ) + + +ToolPolygon::ToolPolygon(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPolygonFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast( parent ); + r->add(new KisToolPolygonFactory()); + } + +} + +ToolPolygon::~ToolPolygon() +{ +} + +//#include "tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polyline/Makefile.am b/chalk/plugins/tools/tool_polyline/Makefile.am index 1812b13b..87fa1ce2 100644 --- a/chalk/plugins/tools/tool_polyline/Makefile.am +++ b/chalk/plugins/tools/tool_polyline/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolpolyline_la_SOURCES = \ - tool_polyline.cc \ - kis_tool_polyline.cc + tool_polyline.cpp \ + kis_tool_polyline.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolpolyline.la diff --git a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc deleted file mode 100644 index c99513f4..00000000 --- a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc +++ /dev/null @@ -1,271 +0,0 @@ -/* - * kis_tool_polyline.cc -- part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_doc.h" -#include "kis_view.h" -#include "kis_painter.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" - -#include "kis_tool_polyline.h" - -KisToolPolyline::KisToolPolyline() - : super(i18n ("Polyline")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_polyline"); - setCursor(KisCursor::load("tool_polyline_cursor.png", 6, 6)); -} - -KisToolPolyline::~KisToolPolyline() -{ -} - -void KisToolPolyline::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolPolyline::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage) { - if (event->button() == Qt::LeftButton && event->state() != TQt::ShiftButton ) { - - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - draw(); - } - } else if (event->button() == Qt::LeftButton && event->state() == TQt::ShiftButton ) { - finish(); - } - } -} - -void KisToolPolyline::deactivate() -{ - draw(); - m_points.clear(); - m_dragging = false; -} - -void KisToolPolyline::finish() -{ - // erase old lines on canvas - draw(); - m_dragging = false; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polyline")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - KisPoint start,end; - KisPointVector::iterator it; - for( it = m_points.begin(); it != m_points.end(); ++it ) - { - if( it == m_points.begin() ) - { - start = (*it); - } else { - end = (*it); - painter.paintLine(start, PRESSURE_DEFAULT, 0, 0, end, PRESSURE_DEFAULT, 0, 0); - start = end; - } - } - m_points.clear(); - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - -} -void KisToolPolyline::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - draw(); - } -} - -void KisToolPolyline::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - } - - if (m_dragging && event->button() == Qt::RightButton) { - - } -} - - -void KisToolPolyline::doubleClick(KisDoubleClickEvent *) -{ - finish(); -} - - -void KisToolPolyline::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolPolyline::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolPolyline::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolPolyline::draw(KisCanvasPainter& gc) -{ - if (!m_subject || !m_currentImage) - return; - - TQPen pen(TQt::white, 0, TQt::SolidLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - -void KisToolPolyline::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Polyline"), - "polyline", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw a polyline. Shift-mouseclick ends the polyline.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQString KisToolPolyline::quickHelp() const -{ - return i18n("Press shift-mouseclick to end the polyline."); -} - -void KisToolPolyline::keyPress(TQKeyEvent *e) -{ - if (e->key()==TQt::Key_Escape) { - // erase old lines on canvas - draw(); - m_dragging = false; - m_points.clear(); - } -} - -#include "kis_tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp new file mode 100644 index 00000000..ab89cf3f --- /dev/null +++ b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp @@ -0,0 +1,271 @@ +/* + * kis_tool_polyline.cpp -- part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_doc.h" +#include "kis_view.h" +#include "kis_painter.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" + +#include "kis_tool_polyline.h" + +KisToolPolyline::KisToolPolyline() + : super(i18n ("Polyline")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_polyline"); + setCursor(KisCursor::load("tool_polyline_cursor.png", 6, 6)); +} + +KisToolPolyline::~KisToolPolyline() +{ +} + +void KisToolPolyline::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolPolyline::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage) { + if (event->button() == Qt::LeftButton && event->state() != TQt::ShiftButton ) { + + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + draw(); + } + } else if (event->button() == Qt::LeftButton && event->state() == TQt::ShiftButton ) { + finish(); + } + } +} + +void KisToolPolyline::deactivate() +{ + draw(); + m_points.clear(); + m_dragging = false; +} + +void KisToolPolyline::finish() +{ + // erase old lines on canvas + draw(); + m_dragging = false; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polyline")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + KisPoint start,end; + KisPointVector::iterator it; + for( it = m_points.begin(); it != m_points.end(); ++it ) + { + if( it == m_points.begin() ) + { + start = (*it); + } else { + end = (*it); + painter.paintLine(start, PRESSURE_DEFAULT, 0, 0, end, PRESSURE_DEFAULT, 0, 0); + start = end; + } + } + m_points.clear(); + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + +} +void KisToolPolyline::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + draw(); + } +} + +void KisToolPolyline::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + } + + if (m_dragging && event->button() == Qt::RightButton) { + + } +} + + +void KisToolPolyline::doubleClick(KisDoubleClickEvent *) +{ + finish(); +} + + +void KisToolPolyline::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolPolyline::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolPolyline::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolPolyline::draw(KisCanvasPainter& gc) +{ + if (!m_subject || !m_currentImage) + return; + + TQPen pen(TQt::white, 0, TQt::SolidLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + +void KisToolPolyline::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Polyline"), + "polyline", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw a polyline. Shift-mouseclick ends the polyline.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQString KisToolPolyline::quickHelp() const +{ + return i18n("Press shift-mouseclick to end the polyline."); +} + +void KisToolPolyline::keyPress(TQKeyEvent *e) +{ + if (e->key()==TQt::Key_Escape) { + // erase old lines on canvas + draw(); + m_dragging = false; + m_points.clear(); + } +} + +#include "kis_tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_polyline/tool_polyline.cc b/chalk/plugins/tools/tool_polyline/tool_polyline.cc deleted file mode 100644 index a5bfa27f..00000000 --- a/chalk/plugins/tools/tool_polyline/tool_polyline.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * tool_polyline.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "tool_polyline.h" -#include "kis_tool_polyline.h" - - -typedef KGenericFactory ToolPolylineFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolpolyline, ToolPolylineFactory( "chalk" ) ) - - -ToolPolyline::ToolPolyline(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPolylineFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - - r->add(new KisToolPolylineFactory()); - } - -} - -ToolPolyline::~ToolPolyline() -{ -} - -#include "tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_polyline/tool_polyline.cpp b/chalk/plugins/tools/tool_polyline/tool_polyline.cpp new file mode 100644 index 00000000..d6abff71 --- /dev/null +++ b/chalk/plugins/tools/tool_polyline/tool_polyline.cpp @@ -0,0 +1,64 @@ +/* + * tool_polyline.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tool_polyline.h" +#include "kis_tool_polyline.h" + + +typedef KGenericFactory ToolPolylineFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolpolyline, ToolPolylineFactory( "chalk" ) ) + + +ToolPolyline::ToolPolyline(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPolylineFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + + r->add(new KisToolPolylineFactory()); + } + +} + +ToolPolyline::~ToolPolyline() +{ +} + +#include "tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_selectsimilar/Makefile.am b/chalk/plugins/tools/tool_selectsimilar/Makefile.am index 5c1897f4..224f67ba 100644 --- a/chalk/plugins/tools/tool_selectsimilar/Makefile.am +++ b/chalk/plugins/tools/tool_selectsimilar/Makefile.am @@ -9,7 +9,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) -chalktoolselectsimilar_la_SOURCES = selectsimilar.cc kis_tool_selectsimilar.cc +chalktoolselectsimilar_la_SOURCES = selectsimilar.cpp kis_tool_selectsimilar.cpp noinst_HEADERS = selectsimilar.h kis_tool_selectsimilar.h kde_module_LTLIBRARIES = chalktoolselectsimilar.la diff --git a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc deleted file mode 100644 index 65b05957..00000000 --- a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2005 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_selectsimilar.h" - -void selectByColor(KisPaintDeviceSP dev, KisSelectionSP selection, const TQ_UINT8 * c, int fuzziness, enumSelectionMode mode) -{ - // XXX: Multithread this! - TQ_INT32 x, y, w, h; - - dev->exactBounds(x, y, w, h); - - KisColorSpace * cs = dev->colorSpace(); - - for (int y2 = y; y2 < y + h; ++y2) { - KisHLineIterator hiter = dev->createHLineIterator(x, y2, w, false); - KisHLineIterator selIter = selection->createHLineIterator(x, y2, w, true); - while (!hiter.isDone()) { - //if (dev->colorSpace()->hasAlpha()) - // opacity = dev->colorSpace()->getAlpha(hiter.rawData()); - - TQ_UINT8 match = cs->difference(c, hiter.rawData()); - - if (mode == SELECTION_ADD) { - if (match <= fuzziness) { - *(selIter.rawData()) = MAX_SELECTED; - } - } - else if (mode == SELECTION_SUBTRACT) { - if (match <= fuzziness) { - *(selIter.rawData()) = MIN_SELECTED; - } - } - ++hiter; - ++selIter; - } - } - -} - - - -KisToolSelectSimilar::KisToolSelectSimilar() - : super(i18n("Select Similar Colors")) -{ - setName("tool_select_similar"); - m_addCursor = KisCursor::load("tool_similar_selection_plus_cursor.png", 1, 21); - m_subtractCursor = KisCursor::load("tool_similar_selection_minus_cursor.png", 1, 21); - setCursor(m_addCursor); - m_subject = 0; - m_optWidget = 0; - m_selectionOptionsWidget = 0; - m_fuzziness = 20; - m_currentSelectAction = m_defaultSelectAction = SELECTION_ADD; - m_timer = new TQTimer(this); - connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer()) ); -} - -KisToolSelectSimilar::~KisToolSelectSimilar() -{ -} - -void KisToolSelectSimilar::activate() -{ - KisToolNonPaint::activate(); - m_timer->start(50); - setPickerCursor(m_currentSelectAction); - - if (m_selectionOptionsWidget) { - m_selectionOptionsWidget->slotActivated(); - } -} - -void KisToolSelectSimilar::deactivate() -{ - m_timer->stop(); -} - -void KisToolSelectSimilar::buttonPress(KisButtonPressEvent *e) -{ - - if (m_subject) { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisImageSP img; - KisPaintDeviceSP dev; - TQPoint pos; - TQ_UINT8 opacity = OPACITY_OPAQUE; - - if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) - return; - - if (!(img = m_subject->currentImg())) - return; - - dev = img->activeDevice(); - - if (!dev || !img->activeLayer()->visible()) - return; - - pos = TQPoint(e->pos().floorX(), e->pos().floorY()); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Similar Selection"),dev); - - KisColor c = dev->colorAt(pos.x(), pos.y()); - opacity = dev->colorSpace()->getAlpha(c.data()); - - // XXX we should make this configurable: "allow to select transparent" - // if (opacity > OPACITY_TRANSPARENT) - selectByColor(dev, dev->selection(), c.data(), m_fuzziness, m_currentSelectAction); - - dev->setDirty(); - dev->emitSelectionChanged(); - - if(img->undo()) - img->undoAdapter()->addCommand(t); - m_subject->canvasController()->updateCanvas(); - - TQApplication::restoreOverrideCursor(); - } -} - -void KisToolSelectSimilar::slotTimer() -{ -#if KDE_IS_VERSION(3,4,0) - int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); -#else - int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier - |TDEApplication::ControlModifier|TDEApplication::Modifier1); -#endif - enumSelectionMode action; - - if (state == TQt::ShiftButton) - action = SELECTION_ADD; - else if (state == TQt::ControlButton) - action = SELECTION_SUBTRACT; - else - action = m_defaultSelectAction; - - if (action != m_currentSelectAction) { - m_currentSelectAction = action; - setPickerCursor(action); - } -} - -void KisToolSelectSimilar::setPickerCursor(enumSelectionMode action) -{ - switch (action) { - case SELECTION_ADD: - m_subject->canvasController()->setCanvasCursor(m_addCursor); - break; - case SELECTION_SUBTRACT: - m_subject->canvasController()->setCanvasCursor(m_subtractCursor); - } -} - -void KisToolSelectSimilar::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Similar Selection"), "tool_similar_selection", "Ctrl+E", this, TQT_SLOT(activate()), collection, name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Select similar colors")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolSelectSimilar::update(KisCanvasSubject *subject) -{ - super::update(subject); - m_subject = subject; -} - -void KisToolSelectSimilar::slotSetFuzziness(int fuzziness) -{ - m_fuzziness = fuzziness; -} - -void KisToolSelectSimilar::slotSetAction(int action) -{ - m_defaultSelectAction = (enumSelectionMode)action; -} - -TQWidget* KisToolSelectSimilar::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new TQWidget(parent); - TQ_CHECK_PTR(m_optWidget); - - m_optWidget->setCaption(i18n("Similar Selection")); - - TQVBoxLayout * l = new TQVBoxLayout(m_optWidget, 0, 6); - TQ_CHECK_PTR(l); - - m_selectionOptionsWidget = new KisSelectionOptions(m_optWidget, m_subject); - TQ_CHECK_PTR(m_selectionOptionsWidget); - - l->addWidget(m_selectionOptionsWidget); - connect (m_selectionOptionsWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQHBoxLayout * hbox = new TQHBoxLayout(l); - TQ_CHECK_PTR(hbox); - - TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); - TQ_CHECK_PTR(lbl); - - hbox->addWidget(lbl); - - KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); - TQ_CHECK_PTR(input); - - input->setRange(0, 200, 10, true); - input->setValue(20); - hbox->addWidget(input); - connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); - - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectSimilar::optionWidget() -{ - return m_optWidget; -} - -#include "kis_tool_selectsimilar.moc" diff --git a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp new file mode 100644 index 00000000..65b05957 --- /dev/null +++ b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (c) 1999 Matthias Elter + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_selectsimilar.h" + +void selectByColor(KisPaintDeviceSP dev, KisSelectionSP selection, const TQ_UINT8 * c, int fuzziness, enumSelectionMode mode) +{ + // XXX: Multithread this! + TQ_INT32 x, y, w, h; + + dev->exactBounds(x, y, w, h); + + KisColorSpace * cs = dev->colorSpace(); + + for (int y2 = y; y2 < y + h; ++y2) { + KisHLineIterator hiter = dev->createHLineIterator(x, y2, w, false); + KisHLineIterator selIter = selection->createHLineIterator(x, y2, w, true); + while (!hiter.isDone()) { + //if (dev->colorSpace()->hasAlpha()) + // opacity = dev->colorSpace()->getAlpha(hiter.rawData()); + + TQ_UINT8 match = cs->difference(c, hiter.rawData()); + + if (mode == SELECTION_ADD) { + if (match <= fuzziness) { + *(selIter.rawData()) = MAX_SELECTED; + } + } + else if (mode == SELECTION_SUBTRACT) { + if (match <= fuzziness) { + *(selIter.rawData()) = MIN_SELECTED; + } + } + ++hiter; + ++selIter; + } + } + +} + + + +KisToolSelectSimilar::KisToolSelectSimilar() + : super(i18n("Select Similar Colors")) +{ + setName("tool_select_similar"); + m_addCursor = KisCursor::load("tool_similar_selection_plus_cursor.png", 1, 21); + m_subtractCursor = KisCursor::load("tool_similar_selection_minus_cursor.png", 1, 21); + setCursor(m_addCursor); + m_subject = 0; + m_optWidget = 0; + m_selectionOptionsWidget = 0; + m_fuzziness = 20; + m_currentSelectAction = m_defaultSelectAction = SELECTION_ADD; + m_timer = new TQTimer(this); + connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer()) ); +} + +KisToolSelectSimilar::~KisToolSelectSimilar() +{ +} + +void KisToolSelectSimilar::activate() +{ + KisToolNonPaint::activate(); + m_timer->start(50); + setPickerCursor(m_currentSelectAction); + + if (m_selectionOptionsWidget) { + m_selectionOptionsWidget->slotActivated(); + } +} + +void KisToolSelectSimilar::deactivate() +{ + m_timer->stop(); +} + +void KisToolSelectSimilar::buttonPress(KisButtonPressEvent *e) +{ + + if (m_subject) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisImageSP img; + KisPaintDeviceSP dev; + TQPoint pos; + TQ_UINT8 opacity = OPACITY_OPAQUE; + + if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) + return; + + if (!(img = m_subject->currentImg())) + return; + + dev = img->activeDevice(); + + if (!dev || !img->activeLayer()->visible()) + return; + + pos = TQPoint(e->pos().floorX(), e->pos().floorY()); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Similar Selection"),dev); + + KisColor c = dev->colorAt(pos.x(), pos.y()); + opacity = dev->colorSpace()->getAlpha(c.data()); + + // XXX we should make this configurable: "allow to select transparent" + // if (opacity > OPACITY_TRANSPARENT) + selectByColor(dev, dev->selection(), c.data(), m_fuzziness, m_currentSelectAction); + + dev->setDirty(); + dev->emitSelectionChanged(); + + if(img->undo()) + img->undoAdapter()->addCommand(t); + m_subject->canvasController()->updateCanvas(); + + TQApplication::restoreOverrideCursor(); + } +} + +void KisToolSelectSimilar::slotTimer() +{ +#if KDE_IS_VERSION(3,4,0) + int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); +#else + int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier + |TDEApplication::ControlModifier|TDEApplication::Modifier1); +#endif + enumSelectionMode action; + + if (state == TQt::ShiftButton) + action = SELECTION_ADD; + else if (state == TQt::ControlButton) + action = SELECTION_SUBTRACT; + else + action = m_defaultSelectAction; + + if (action != m_currentSelectAction) { + m_currentSelectAction = action; + setPickerCursor(action); + } +} + +void KisToolSelectSimilar::setPickerCursor(enumSelectionMode action) +{ + switch (action) { + case SELECTION_ADD: + m_subject->canvasController()->setCanvasCursor(m_addCursor); + break; + case SELECTION_SUBTRACT: + m_subject->canvasController()->setCanvasCursor(m_subtractCursor); + } +} + +void KisToolSelectSimilar::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Similar Selection"), "tool_similar_selection", "Ctrl+E", this, TQT_SLOT(activate()), collection, name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Select similar colors")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolSelectSimilar::update(KisCanvasSubject *subject) +{ + super::update(subject); + m_subject = subject; +} + +void KisToolSelectSimilar::slotSetFuzziness(int fuzziness) +{ + m_fuzziness = fuzziness; +} + +void KisToolSelectSimilar::slotSetAction(int action) +{ + m_defaultSelectAction = (enumSelectionMode)action; +} + +TQWidget* KisToolSelectSimilar::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new TQWidget(parent); + TQ_CHECK_PTR(m_optWidget); + + m_optWidget->setCaption(i18n("Similar Selection")); + + TQVBoxLayout * l = new TQVBoxLayout(m_optWidget, 0, 6); + TQ_CHECK_PTR(l); + + m_selectionOptionsWidget = new KisSelectionOptions(m_optWidget, m_subject); + TQ_CHECK_PTR(m_selectionOptionsWidget); + + l->addWidget(m_selectionOptionsWidget); + connect (m_selectionOptionsWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQHBoxLayout * hbox = new TQHBoxLayout(l); + TQ_CHECK_PTR(hbox); + + TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); + TQ_CHECK_PTR(lbl); + + hbox->addWidget(lbl); + + KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); + TQ_CHECK_PTR(input); + + input->setRange(0, 200, 10, true); + input->setValue(20); + hbox->addWidget(input); + connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); + + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectSimilar::optionWidget() +{ + return m_optWidget; +} + +#include "kis_tool_selectsimilar.moc" diff --git a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc deleted file mode 100644 index af807017..00000000 --- a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * selectsimilar.h -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "selectsimilar.h" -#include "kis_tool_selectsimilar.h" - -typedef KGenericFactory SelectSimilarFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolselectsimilar, SelectSimilarFactory( "chalk" ) ) - -SelectSimilar::SelectSimilar(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(SelectSimilarFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolSelectSimilarFactory()); - } -} - -SelectSimilar::~SelectSimilar() -{ -} - -#include "selectsimilar.moc" - diff --git a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp new file mode 100644 index 00000000..af807017 --- /dev/null +++ b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp @@ -0,0 +1,61 @@ +/* + * selectsimilar.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "selectsimilar.h" +#include "kis_tool_selectsimilar.h" + +typedef KGenericFactory SelectSimilarFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolselectsimilar, SelectSimilarFactory( "chalk" ) ) + +SelectSimilar::SelectSimilar(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(SelectSimilarFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolSelectSimilarFactory()); + } +} + +SelectSimilar::~SelectSimilar() +{ +} + +#include "selectsimilar.moc" + diff --git a/chalk/plugins/tools/tool_star/Makefile.am b/chalk/plugins/tools/tool_star/Makefile.am index ed88d27e..1f4627dd 100644 --- a/chalk/plugins/tools/tool_star/Makefile.am +++ b/chalk/plugins/tools/tool_star/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalktoolstar_la_SOURCES = \ wdg_tool_star.ui \ - tool_star.cc \ - kis_tool_star.cc + tool_star.cpp \ + kis_tool_star.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolstar.la diff --git a/chalk/plugins/tools/tool_star/kis_tool_star.cc b/chalk/plugins/tools/tool_star/kis_tool_star.cc deleted file mode 100644 index cd4bb0b2..00000000 --- a/chalk/plugins/tools/tool_star/kis_tool_star.cc +++ /dev/null @@ -1,245 +0,0 @@ -/* - * kis_tool_star.cc -- part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_doc.h" -#include "kis_view.h" -#include "kis_painter.h" -#include "kis_int_spinbox.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_int_spinbox.h" - -#include "kis_tool_star.h" -#include "wdg_tool_star.h" - -KisToolStar::KisToolStar() - : super(i18n("Star")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_star"); - setCursor(KisCursor::load("tool_star_cursor.png", 6, 6)); - m_innerOuterRatio=40; - m_vertices=5; -} - -KisToolStar::~KisToolStar() -{ -} - -void KisToolStar::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolStar::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage && event->button() == Qt::LeftButton) { - m_dragging = true; - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_vertices = m_optWidget->verticesSpinBox->value(); - m_innerOuterRatio = m_optWidget->ratioSpinBox->value(); - } -} - -void KisToolStar::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - // move (alt) or resize star - if (event->state() & TQt::AltButton) { - KisPoint trans = event->pos() - m_dragEnd; - m_dragStart += trans; - m_dragEnd += trans; - } else { - m_dragEnd = event->pos(); - } - // draw new lines on canvas - draw(m_dragStart, m_dragEnd); - } -} - -void KisToolStar::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragging = false; - - if (m_dragStart == m_dragEnd) - return; - - if (!m_currentImage) - return; - - if (!m_currentImage->activeDevice()) - return; - - KisPaintDeviceSP device = m_currentImage->activeDevice ();; - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n("Star")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - vKisPoint coord = starCoordinates(m_vertices, m_dragStart.x(), m_dragStart.y(), m_dragEnd.x(), m_dragEnd.y()); - - painter.paintPolygon(coord); - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - } -} - -void KisToolStar::draw(const KisPoint& start, const KisPoint& end ) -{ - if (!m_subject || !m_currentImage) - return; - - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter p (canvas); - TQPen pen(TQt::SolidLine); - - KisPoint startPos; - KisPoint endPos; - startPos = controller->windowToView(start); - endPos = controller->windowToView(end); - - p.setRasterOp(TQt::NotROP); - - vKisPoint points = starCoordinates(m_vertices, startPos.x(), startPos.y(), endPos.x(), endPos.y()); - - for (uint i = 0; i < points.count() - 1; i++) { - p.drawLine(points[i].floorTQPoint(), points[i + 1].floorTQPoint()); - } - p.drawLine(points[points.count() - 1].floorTQPoint(), points[0].floorTQPoint()); - - p.end (); -} - -void KisToolStar::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Star"), - "tool_star", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw a star")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -vKisPoint KisToolStar::starCoordinates(int N, double mx, double my, double x, double y) -{ - double R=0, r=0; - TQ_INT32 n=0; - double angle; - - vKisPoint starCoordinatesArray(2*N); - - // the radius of the outer edges - R=sqrt((x-mx)*(x-mx)+(y-my)*(y-my)); - - // the radius of the inner edges - r=R*m_innerOuterRatio/100.0; - - // the angle - angle=-atan2((x-mx),(y-my)); - - //set outer edges - for(n=0;nratioSpinBox->setValue(m_innerOuterRatio); - - TQGridLayout *optionLayout = new TQGridLayout(widget, 1, 1); - super::addOptionWidgetLayout(optionLayout); - - optionLayout->addWidget(m_optWidget, 0, 0); - - return widget; -} - -#include "kis_tool_star.moc" diff --git a/chalk/plugins/tools/tool_star/kis_tool_star.cpp b/chalk/plugins/tools/tool_star/kis_tool_star.cpp new file mode 100644 index 00000000..3a260545 --- /dev/null +++ b/chalk/plugins/tools/tool_star/kis_tool_star.cpp @@ -0,0 +1,245 @@ +/* + * kis_tool_star.cpp -- part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_doc.h" +#include "kis_view.h" +#include "kis_painter.h" +#include "kis_int_spinbox.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_int_spinbox.h" + +#include "kis_tool_star.h" +#include "wdg_tool_star.h" + +KisToolStar::KisToolStar() + : super(i18n("Star")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_star"); + setCursor(KisCursor::load("tool_star_cursor.png", 6, 6)); + m_innerOuterRatio=40; + m_vertices=5; +} + +KisToolStar::~KisToolStar() +{ +} + +void KisToolStar::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolStar::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage && event->button() == Qt::LeftButton) { + m_dragging = true; + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_vertices = m_optWidget->verticesSpinBox->value(); + m_innerOuterRatio = m_optWidget->ratioSpinBox->value(); + } +} + +void KisToolStar::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + // move (alt) or resize star + if (event->state() & TQt::AltButton) { + KisPoint trans = event->pos() - m_dragEnd; + m_dragStart += trans; + m_dragEnd += trans; + } else { + m_dragEnd = event->pos(); + } + // draw new lines on canvas + draw(m_dragStart, m_dragEnd); + } +} + +void KisToolStar::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragging = false; + + if (m_dragStart == m_dragEnd) + return; + + if (!m_currentImage) + return; + + if (!m_currentImage->activeDevice()) + return; + + KisPaintDeviceSP device = m_currentImage->activeDevice ();; + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n("Star")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + vKisPoint coord = starCoordinates(m_vertices, m_dragStart.x(), m_dragStart.y(), m_dragEnd.x(), m_dragEnd.y()); + + painter.paintPolygon(coord); + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + } +} + +void KisToolStar::draw(const KisPoint& start, const KisPoint& end ) +{ + if (!m_subject || !m_currentImage) + return; + + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter p (canvas); + TQPen pen(TQt::SolidLine); + + KisPoint startPos; + KisPoint endPos; + startPos = controller->windowToView(start); + endPos = controller->windowToView(end); + + p.setRasterOp(TQt::NotROP); + + vKisPoint points = starCoordinates(m_vertices, startPos.x(), startPos.y(), endPos.x(), endPos.y()); + + for (uint i = 0; i < points.count() - 1; i++) { + p.drawLine(points[i].floorTQPoint(), points[i + 1].floorTQPoint()); + } + p.drawLine(points[points.count() - 1].floorTQPoint(), points[0].floorTQPoint()); + + p.end (); +} + +void KisToolStar::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Star"), + "tool_star", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw a star")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +vKisPoint KisToolStar::starCoordinates(int N, double mx, double my, double x, double y) +{ + double R=0, r=0; + TQ_INT32 n=0; + double angle; + + vKisPoint starCoordinatesArray(2*N); + + // the radius of the outer edges + R=sqrt((x-mx)*(x-mx)+(y-my)*(y-my)); + + // the radius of the inner edges + r=R*m_innerOuterRatio/100.0; + + // the angle + angle=-atan2((x-mx),(y-my)); + + //set outer edges + for(n=0;nratioSpinBox->setValue(m_innerOuterRatio); + + TQGridLayout *optionLayout = new TQGridLayout(widget, 1, 1); + super::addOptionWidgetLayout(optionLayout); + + optionLayout->addWidget(m_optWidget, 0, 0); + + return widget; +} + +#include "kis_tool_star.moc" diff --git a/chalk/plugins/tools/tool_star/tool_star.cc b/chalk/plugins/tools/tool_star/tool_star.cc deleted file mode 100644 index 9ac1b62f..00000000 --- a/chalk/plugins/tools/tool_star/tool_star.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_star.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_star.h" -#include "kis_tool_star.h" - - -typedef KGenericFactory ToolStarFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolstar, ToolStarFactory( "chalk" ) ) - - -ToolStar::ToolStar(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolStarFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast( parent ); - r->add(new KisToolStarFactory()); - } - -} - -ToolStar::~ToolStar() -{ -} - -#include "tool_star.moc" diff --git a/chalk/plugins/tools/tool_star/tool_star.cpp b/chalk/plugins/tools/tool_star/tool_star.cpp new file mode 100644 index 00000000..7309e8a1 --- /dev/null +++ b/chalk/plugins/tools/tool_star/tool_star.cpp @@ -0,0 +1,62 @@ +/* + * tool_star.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_star.h" +#include "kis_tool_star.h" + + +typedef KGenericFactory ToolStarFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolstar, ToolStarFactory( "chalk" ) ) + + +ToolStar::ToolStar(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolStarFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast( parent ); + r->add(new KisToolStarFactory()); + } + +} + +ToolStar::~ToolStar() +{ +} + +#include "tool_star.moc" diff --git a/chalk/plugins/tools/tool_transform/Makefile.am b/chalk/plugins/tools/tool_transform/Makefile.am index 12a32774..a5adea17 100644 --- a/chalk/plugins/tools/tool_transform/Makefile.am +++ b/chalk/plugins/tools/tool_transform/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalktooltransform_la_SOURCES = \ wdg_tool_transform.ui \ - tool_transform.cc \ - kis_tool_transform.cc + tool_transform.cpp \ + kis_tool_transform.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktooltransform.la diff --git a/chalk/plugins/tools/tool_transform/kis_tool_transform.cc b/chalk/plugins/tools/tool_transform/kis_tool_transform.cc deleted file mode 100644 index de20ce7f..00000000 --- a/chalk/plugins/tools/tool_transform/kis_tool_transform.cc +++ /dev/null @@ -1,916 +0,0 @@ -/* - * kis_tool_transform.cc -- part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2005 Casper Boemann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_transform.h" -#include "wdg_tool_transform.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -namespace { - class TransformCmd : public KisSelectedTransaction { - typedef KisSelectedTransaction super; - - public: - TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos); - virtual ~TransformCmd(); - - public: - virtual void execute(); - virtual void unexecute(); - void transformArgs(double &sx, double &sy, double &tx, double &ty, double &a); - KisSelectionSP origSelection(TQPoint &startPos, TQPoint &endPos); - KisPaintDeviceSP theDevice(); - KisPaintDeviceSP origDevice(); - - private: - double m_scaleX; - double m_scaleY; - double m_translateX; - double m_translateY; - double m_a; - KisToolTransform *m_tool; - KisSelectionSP m_origSelection; - TQPoint m_startPos; - TQPoint m_endPos; - KisPaintDeviceSP m_device; - KisPaintDeviceSP m_origDevice; - }; - - TransformCmd::TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos) : - super(i18n("Transform"), device) - , m_scaleX(scaleX) - , m_scaleY(scaleY) - , m_translateX(tX) - , m_translateY(tY) - , m_a(a) - , m_tool(tool) - , m_origSelection(origSel) - , m_startPos(startPos) - , m_endPos(endPos) - , m_device(device) - , m_origDevice(origDevice) - { - } - - TransformCmd::~TransformCmd() - { - } - - void TransformCmd::transformArgs(double &sx, double &sy, double &tx, double &ty, double &a) - { - sx = m_scaleX; - sy = m_scaleY; - tx= m_translateX; - ty = m_translateY; - a = m_a; - } - - KisSelectionSP TransformCmd::origSelection(TQPoint &startPos, TQPoint &endPos) - { - startPos = m_startPos; - endPos = m_endPos; - return m_origSelection; - } - - void TransformCmd::execute() - { - super::execute(); - } - - void TransformCmd::unexecute() - { - super::unexecute(); - } - - KisPaintDeviceSP TransformCmd::theDevice() - { - return m_device; - } - - KisPaintDeviceSP TransformCmd::origDevice() - { - return m_origDevice; - } -} - -KisToolTransform::KisToolTransform() - : super(i18n("Transform")) - , m_wasPressed( false ) -{ - setName("tool_transform"); - setCursor(KisCursor::selectCursor()); - m_subject = 0; - m_selecting = false; - m_startPos = TQPoint(0, 0); - m_endPos = TQPoint(0, 0); - m_optWidget = 0; - m_sizeCursors[0] = KisCursor::sizeVerCursor(); - m_sizeCursors[1] = KisCursor::sizeBDiagCursor(); - m_sizeCursors[2] = KisCursor::sizeHorCursor(); - m_sizeCursors[3] = KisCursor::sizeFDiagCursor(); - m_sizeCursors[4] = KisCursor::sizeVerCursor(); - m_sizeCursors[5] = KisCursor::sizeBDiagCursor(); - m_sizeCursors[6] = KisCursor::sizeHorCursor(); - m_sizeCursors[7] = KisCursor::sizeFDiagCursor(); - m_origDevice = 0; - m_origSelection = 0; - -} - -KisToolTransform::~KisToolTransform() -{ -} - -void KisToolTransform::deactivate() -{ - if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); - - KisImageSP img = m_subject->currentImg(); - if (!img) return; - - paintOutline(); - - disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolTransform::activate() -{ - if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) - { - //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); - m_subject->undoAdapter()->setCommandHistoryListener( this ); - - KisToolControllerInterface *controller = m_subject->toolController(); - - if (controller) - controller->setCurrentTool(this); - - TransformCmd * cmd=0; - - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - if (cmd == 0) { - initHandles(); - } - else - { - // One of our commands is on top - if(cmd->theDevice() == m_subject->currentImg()->activeDevice()) - { - // and it even has the same device - // We should ask for tool args and orig selection - m_origDevice = cmd->origDevice(); - cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); - m_origSelection = cmd->origSelection(m_startPos, m_endPos); - m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; - m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; - paintOutline(); - } - else - initHandles(); - } - } - connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolTransform::initHandles() -{ - TQ_INT32 x,y,w,h; - KisImageSP img = m_subject->currentImg(); - - KisPaintDeviceSP dev = img->activeDevice(); - if (!dev ) return; - - // Create a lazy copy of the current state - m_origDevice = new KisPaintDevice(*dev.data()); - Q_ASSERT(m_origDevice); - - if(dev->hasSelection()) - { - KisSelectionSP sel = dev->selection(); - m_origSelection = new KisSelection(*sel.data()); - TQRect r = sel->selectedExactRect(); - r.rect(&x, &y, &w, &h); - } - else { - dev->exactBounds(x,y,w,h); - m_origSelection = 0; - } - m_startPos = TQPoint(x, y); - m_endPos = TQPoint(x+w-1, y+h-1); - m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; - m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; - - m_a = 0.0; - m_scaleX = 1.0; - m_scaleY = 1.0; - m_translateX = m_org_cenX; - m_translateY = m_org_cenY; - - m_subject->canvasController() ->updateCanvas(); -} - -void KisToolTransform::paint(KisCanvasPainter& gc) -{ - paintOutline(gc, TQRect()); -} - -void KisToolTransform::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - paintOutline(gc, rc); -} - - -void KisToolTransform::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - m_wasPressed = true; - } - - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - switch(m_function) - { - case ROTATE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); - m_clickangle = -m_a - atan2(m_clickoffset.x(),m_clickoffset.y()); - m_clickoffset = TQPoint(0, 0); - break; - case MOVE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); - break; - case TOPSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_topleft + m_topright)/2); - break; - case TOPRIGHTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_topright; - break; - case RIGHTSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_topright + m_bottomright)/2); - break; - case BOTTOMRIGHTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_bottomright; - break; - case BOTTOMSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_bottomleft + m_bottomright)/2); - break; - case BOTTOMLEFTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_bottomleft; - break; - case LEFTSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_topleft + m_bottomleft)/2); - break; - case TOPLEFTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_topleft; - break; - } - m_selecting = true; - m_actualyMoveWhileSelected = false; - } - } -} - -int KisToolTransform::det(TQPoint v,TQPoint w) -{ - return v.x()*w.y()-v.y()*w.x(); -} -int KisToolTransform::distsq(TQPoint v,TQPoint w) -{ - v -= w; - return v.x()*v.x() + v.y()*v.y(); -} - -void KisToolTransform::setFunctionalCursor() -{ - int rotOctant = 8 + int(8.5 + m_a* 4 / M_PI); - - int s; - if(m_scaleX*m_scaleY<0) - s = -1; - else - s=1; - - switch(m_function) - { - case MOVE: - setCursor(KisCursor::moveCursor()); - break; - case ROTATE: - setCursor(KisCursor::rotateCursor()); - break; - case TOPSCALE: - setCursor(m_sizeCursors[(0*s +rotOctant)%8]); - break; - case TOPRIGHTSCALE: - setCursor(m_sizeCursors[(1*s +rotOctant)%8]); - break; - case RIGHTSCALE: - setCursor(m_sizeCursors[(2*s +rotOctant)%8]); - break; - case BOTTOMRIGHTSCALE: - setCursor(m_sizeCursors[(3*s +rotOctant)%8]); - break; - case BOTTOMSCALE: - setCursor(m_sizeCursors[(4*s +rotOctant)%8]); - break; - case BOTTOMLEFTSCALE: - setCursor(m_sizeCursors[(5*s +rotOctant)%8]); - break; - case LEFTSCALE: - setCursor(m_sizeCursors[(6*s +rotOctant)%8]); - break; - case TOPLEFTSCALE: - setCursor(m_sizeCursors[(7*s +rotOctant)%8]); - break; - } -} - -void KisToolTransform::move(KisMoveEvent *e) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - - Q_ASSERT(controller); - TQPoint topleft = m_topleft; - TQPoint topright = m_topright; - TQPoint bottomleft = m_bottomleft; - TQPoint bottomright = m_bottomright; - - TQPoint mousePos = e->pos().floorTQPoint(); - - if (m_subject && m_selecting) { - paintOutline(); - m_actualyMoveWhileSelected = true; - mousePos -= m_clickoffset; - - // transform mousePos coords, so it seems like it isn't rotated and centered at 0,0 - double newX = invrotX(mousePos.x() - m_translateX, mousePos.y() - m_translateY); - double newY = invrotY(mousePos.x() - m_translateX, mousePos.y() - m_translateY); - double dx=0, dy=0; - double oldScaleX = m_scaleX; - double oldScaleY = m_scaleY; - - if(m_function == MOVE) - { - m_translateX += mousePos.x() - m_translateX; - m_translateY += mousePos.y() - m_translateY; - } - - if(m_function == ROTATE) - { - m_a = -atan2(mousePos.x() - m_translateX, mousePos.y() - m_translateY) - - m_clickangle; - } - - if(m_function == TOPSCALE) - { - dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - } - } - - if(m_function == TOPRIGHTSCALE) - { - dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); - - // enforce same aspect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); - } - } - } - - if(m_function == RIGHTSCALE) - { - dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - } - } - - if(m_function == BOTTOMRIGHTSCALE) - { - dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); - } - } - } - - if(m_function == BOTTOMSCALE) - { - dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - } - } - - if(m_function == BOTTOMLEFTSCALE) - { - dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); - } - } - } - - if(m_function == LEFTSCALE) - { - dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - } - } - - if(m_function == TOPLEFTSCALE) - { - dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); - } - } - } - - m_translateX += rotX(dx, dy); - m_translateY += rotY(dx, dy); - - paintOutline(); - } - else - { - if(det(mousePos - topleft, topright - topleft)>0) - m_function = ROTATE; - else if(det(mousePos - topright, bottomright - topright)>0) - m_function = ROTATE; - else if(det(mousePos - bottomright, bottomleft - bottomright)>0) - m_function = ROTATE; - else if(det(mousePos - bottomleft, topleft - bottomleft)>0) - m_function = ROTATE; - else - m_function = MOVE; - - int handleradius = int( 25 / (m_subject->zoomFactor() * m_subject->zoomFactor()) ); - - if(distsq(mousePos, (m_topleft + m_topright)/2)<=handleradius) - m_function = TOPSCALE; - if(distsq(mousePos, m_topright)<=handleradius) - m_function = TOPRIGHTSCALE; - if(distsq(mousePos, (m_topright + m_bottomright)/2)<=handleradius) - m_function = RIGHTSCALE; - if(distsq(mousePos, m_bottomright)<=handleradius) - m_function = BOTTOMRIGHTSCALE; - if(distsq(mousePos, (m_bottomleft + m_bottomright)/2)<=handleradius) - m_function = BOTTOMSCALE; - if(distsq(mousePos, m_bottomleft)<=handleradius) - m_function = BOTTOMLEFTSCALE; - if(distsq(mousePos, (m_topleft + m_bottomleft)/2)<=handleradius) - m_function = LEFTSCALE; - if(distsq(mousePos, m_topleft)<=handleradius) - m_function = TOPLEFTSCALE; - - setFunctionalCursor(); - } - } -} - -void KisToolTransform::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - if(!m_wasPressed) return; - m_wasPressed = false; - - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - m_selecting = false; - - if(m_actualyMoveWhileSelected) - { - paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } - } -} - -void KisToolTransform::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolTransform::recalcOutline() -{ - double x,y; - - m_sina = sin(m_a); - m_cosa = cos(m_a); - - x = (m_startPos.x() - m_org_cenX) * m_scaleX; - y = (m_startPos.y() - m_org_cenY) * m_scaleY; - m_topleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); - - x = (m_endPos.x() - m_org_cenX) * m_scaleX; - y = (m_startPos.y() - m_org_cenY) * m_scaleY; - m_topright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); - - x = (m_startPos.x() - m_org_cenX) * m_scaleX; - y = (m_endPos.y() - m_org_cenY) * m_scaleY; - m_bottomleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); - - x = (m_endPos.x() - m_org_cenX) * m_scaleX; - y = (m_endPos.y() - m_org_cenY) * m_scaleY; - m_bottomright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); -} - -void KisToolTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - pen.setWidth(1); - Q_ASSERT(controller); - - recalcOutline(); - TQPoint topleft = controller->windowToView(m_topleft); - TQPoint topright = controller->windowToView(m_topright); - TQPoint bottomleft = controller->windowToView(m_bottomleft); - TQPoint bottomright = controller->windowToView(m_bottomright); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); - gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); - gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); - gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); - gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); - gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); - gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); - gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); - gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); - gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); - gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); - gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolTransform::transform() -{ - - KisImageSP img = m_subject->currentImg(); - - if (!img || !img->activeDevice()) - return; - - double tx = m_translateX - rotX(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); - double ty = m_translateY - rotY(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - - // This mementoes the current state of the active device. - TransformCmd * transaction = new TransformCmd(this, img->activeDevice(), m_origDevice, - m_scaleX, m_scaleY, m_translateX, m_translateY, m_a, m_origSelection, m_startPos, m_endPos); - - // Copy the original state back. - TQRect rc = m_origDevice->extent(); - rc = rc.normalize(); - img->activeDevice()->clear(); - KisPainter gc(img->activeDevice()); - gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); - gc.end(); - - // Also restore the original selection. - if(m_origSelection) - { - //TQRect rc = m_origSelection->extent(); - TQRect rc = m_origSelection->selectedRect(); - rc = rc.normalize(); - img->activeDevice()->selection()->clear(); - KisPainter sgc(img->activeDevice()->selection().data()); - sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); - sgc.end(); - } - else - if(img->activeDevice()->hasSelection()) - img->activeDevice()->selection()->clear(); - - // Perform the transform. Since we copied the original state back, this doesn't degrade - // after many tweaks. Since we started the transaction before the copy back, the memento - // has the previous state. - KisTransformWorker t(img->activeDevice(), m_scaleX, m_scaleY, 0, 0, m_a, int(tx), int(ty), progress, m_filter); - t.run(); - - // If canceled, go back to the memento - if(t.isCanceled()) - { - transaction->unexecute(); - delete transaction; - return; - } - - img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent - - // Else add the command -- this will have the memento from the previous state, - // and the transformed state from the original device we cached in our activated() - // method. - if (transaction) { - if (img->undo()) - img->undoAdapter()->addCommand(transaction); - else - delete transaction; - } -} - -void KisToolTransform::notifyCommandAdded( KCommand * command) -{ - TransformCmd * cmd = dynamic_cast(command); - if (cmd == 0) { - // The last added command wasn't one of ours; - // we should reset to the new state of the canvas. - // In effect we should treat this as if the tool has been just activated - initHandles(); - } -} - -void KisToolTransform::notifyCommandExecuted( KCommand * command) -{ - Q_UNUSED(command); - TransformCmd * cmd=0; - - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - if (cmd == 0) { - // The command now on the top of the stack isn't one of ours - // We should treat this as if the tool has been just activated - initHandles(); - } - else - { - // One of our commands is now on top - // We should ask for tool args and orig selection - cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); - m_origSelection = cmd->origSelection(m_startPos, m_endPos); - m_origDevice = cmd->origDevice(); - m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; - m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; - m_subject->canvasController() ->updateCanvas(); - } -} - -void KisToolTransform::slotSetFilter(const KisID &filterID) -{ - m_filter = KisFilterStrategyRegistry::instance()->get(filterID); -} - -void KisToolTransform::slotLayerActivated(KisLayerSP) -{ - activate(); -} - - -TQWidget* KisToolTransform::createOptionWidget(TQWidget* parent) -{ - - m_optWidget = new WdgToolTransform(parent); - TQ_CHECK_PTR(m_optWidget); - - m_optWidget->cmbFilter->clear(); - m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); - - m_optWidget->cmbFilter->setCurrentText("Mitchell"); - connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), - this, TQT_SLOT(slotSetFilter(const KisID &))); - - KisID filterID = m_optWidget->cmbFilter->currentItem(); - m_filter = KisFilterStrategyRegistry::instance()->get(filterID); - -/* - connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); - connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); - connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); - connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); -*/ - m_optWidget->intStartX->hide(); - m_optWidget->intStartY->hide(); - m_optWidget->intEndX->hide(); - m_optWidget->intEndY->hide(); - m_optWidget->textLabel1->hide(); - m_optWidget->textLabel2->hide(); - m_optWidget->textLabel3->hide(); - m_optWidget->textLabel4->hide(); - return m_optWidget; -} - -TQWidget* KisToolTransform::optionWidget() -{ - return m_optWidget; -} - -void KisToolTransform::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Transform"), - "tool_transform", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Transform a layer or a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_transform.moc" diff --git a/chalk/plugins/tools/tool_transform/kis_tool_transform.cpp b/chalk/plugins/tools/tool_transform/kis_tool_transform.cpp new file mode 100644 index 00000000..88a67566 --- /dev/null +++ b/chalk/plugins/tools/tool_transform/kis_tool_transform.cpp @@ -0,0 +1,916 @@ +/* + * kis_tool_transform.cpp -- part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2005 Casper Boemann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_transform.h" +#include "wdg_tool_transform.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +namespace { + class TransformCmd : public KisSelectedTransaction { + typedef KisSelectedTransaction super; + + public: + TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos); + virtual ~TransformCmd(); + + public: + virtual void execute(); + virtual void unexecute(); + void transformArgs(double &sx, double &sy, double &tx, double &ty, double &a); + KisSelectionSP origSelection(TQPoint &startPos, TQPoint &endPos); + KisPaintDeviceSP theDevice(); + KisPaintDeviceSP origDevice(); + + private: + double m_scaleX; + double m_scaleY; + double m_translateX; + double m_translateY; + double m_a; + KisToolTransform *m_tool; + KisSelectionSP m_origSelection; + TQPoint m_startPos; + TQPoint m_endPos; + KisPaintDeviceSP m_device; + KisPaintDeviceSP m_origDevice; + }; + + TransformCmd::TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos) : + super(i18n("Transform"), device) + , m_scaleX(scaleX) + , m_scaleY(scaleY) + , m_translateX(tX) + , m_translateY(tY) + , m_a(a) + , m_tool(tool) + , m_origSelection(origSel) + , m_startPos(startPos) + , m_endPos(endPos) + , m_device(device) + , m_origDevice(origDevice) + { + } + + TransformCmd::~TransformCmd() + { + } + + void TransformCmd::transformArgs(double &sx, double &sy, double &tx, double &ty, double &a) + { + sx = m_scaleX; + sy = m_scaleY; + tx= m_translateX; + ty = m_translateY; + a = m_a; + } + + KisSelectionSP TransformCmd::origSelection(TQPoint &startPos, TQPoint &endPos) + { + startPos = m_startPos; + endPos = m_endPos; + return m_origSelection; + } + + void TransformCmd::execute() + { + super::execute(); + } + + void TransformCmd::unexecute() + { + super::unexecute(); + } + + KisPaintDeviceSP TransformCmd::theDevice() + { + return m_device; + } + + KisPaintDeviceSP TransformCmd::origDevice() + { + return m_origDevice; + } +} + +KisToolTransform::KisToolTransform() + : super(i18n("Transform")) + , m_wasPressed( false ) +{ + setName("tool_transform"); + setCursor(KisCursor::selectCursor()); + m_subject = 0; + m_selecting = false; + m_startPos = TQPoint(0, 0); + m_endPos = TQPoint(0, 0); + m_optWidget = 0; + m_sizeCursors[0] = KisCursor::sizeVerCursor(); + m_sizeCursors[1] = KisCursor::sizeBDiagCursor(); + m_sizeCursors[2] = KisCursor::sizeHorCursor(); + m_sizeCursors[3] = KisCursor::sizeFDiagCursor(); + m_sizeCursors[4] = KisCursor::sizeVerCursor(); + m_sizeCursors[5] = KisCursor::sizeBDiagCursor(); + m_sizeCursors[6] = KisCursor::sizeHorCursor(); + m_sizeCursors[7] = KisCursor::sizeFDiagCursor(); + m_origDevice = 0; + m_origSelection = 0; + +} + +KisToolTransform::~KisToolTransform() +{ +} + +void KisToolTransform::deactivate() +{ + if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); + + KisImageSP img = m_subject->currentImg(); + if (!img) return; + + paintOutline(); + + disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolTransform::activate() +{ + if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) + { + //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); + m_subject->undoAdapter()->setCommandHistoryListener( this ); + + KisToolControllerInterface *controller = m_subject->toolController(); + + if (controller) + controller->setCurrentTool(this); + + TransformCmd * cmd=0; + + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + if (cmd == 0) { + initHandles(); + } + else + { + // One of our commands is on top + if(cmd->theDevice() == m_subject->currentImg()->activeDevice()) + { + // and it even has the same device + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); + m_origSelection = cmd->origSelection(m_startPos, m_endPos); + m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; + m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; + paintOutline(); + } + else + initHandles(); + } + } + connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolTransform::initHandles() +{ + TQ_INT32 x,y,w,h; + KisImageSP img = m_subject->currentImg(); + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev ) return; + + // Create a lazy copy of the current state + m_origDevice = new KisPaintDevice(*dev.data()); + Q_ASSERT(m_origDevice); + + if(dev->hasSelection()) + { + KisSelectionSP sel = dev->selection(); + m_origSelection = new KisSelection(*sel.data()); + TQRect r = sel->selectedExactRect(); + r.rect(&x, &y, &w, &h); + } + else { + dev->exactBounds(x,y,w,h); + m_origSelection = 0; + } + m_startPos = TQPoint(x, y); + m_endPos = TQPoint(x+w-1, y+h-1); + m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; + m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; + + m_a = 0.0; + m_scaleX = 1.0; + m_scaleY = 1.0; + m_translateX = m_org_cenX; + m_translateY = m_org_cenY; + + m_subject->canvasController() ->updateCanvas(); +} + +void KisToolTransform::paint(KisCanvasPainter& gc) +{ + paintOutline(gc, TQRect()); +} + +void KisToolTransform::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + paintOutline(gc, rc); +} + + +void KisToolTransform::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + m_wasPressed = true; + } + + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + switch(m_function) + { + case ROTATE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); + m_clickangle = -m_a - atan2(m_clickoffset.x(),m_clickoffset.y()); + m_clickoffset = TQPoint(0, 0); + break; + case MOVE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); + break; + case TOPSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_topleft + m_topright)/2); + break; + case TOPRIGHTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_topright; + break; + case RIGHTSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_topright + m_bottomright)/2); + break; + case BOTTOMRIGHTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_bottomright; + break; + case BOTTOMSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_bottomleft + m_bottomright)/2); + break; + case BOTTOMLEFTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_bottomleft; + break; + case LEFTSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_topleft + m_bottomleft)/2); + break; + case TOPLEFTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_topleft; + break; + } + m_selecting = true; + m_actualyMoveWhileSelected = false; + } + } +} + +int KisToolTransform::det(TQPoint v,TQPoint w) +{ + return v.x()*w.y()-v.y()*w.x(); +} +int KisToolTransform::distsq(TQPoint v,TQPoint w) +{ + v -= w; + return v.x()*v.x() + v.y()*v.y(); +} + +void KisToolTransform::setFunctionalCursor() +{ + int rotOctant = 8 + int(8.5 + m_a* 4 / M_PI); + + int s; + if(m_scaleX*m_scaleY<0) + s = -1; + else + s=1; + + switch(m_function) + { + case MOVE: + setCursor(KisCursor::moveCursor()); + break; + case ROTATE: + setCursor(KisCursor::rotateCursor()); + break; + case TOPSCALE: + setCursor(m_sizeCursors[(0*s +rotOctant)%8]); + break; + case TOPRIGHTSCALE: + setCursor(m_sizeCursors[(1*s +rotOctant)%8]); + break; + case RIGHTSCALE: + setCursor(m_sizeCursors[(2*s +rotOctant)%8]); + break; + case BOTTOMRIGHTSCALE: + setCursor(m_sizeCursors[(3*s +rotOctant)%8]); + break; + case BOTTOMSCALE: + setCursor(m_sizeCursors[(4*s +rotOctant)%8]); + break; + case BOTTOMLEFTSCALE: + setCursor(m_sizeCursors[(5*s +rotOctant)%8]); + break; + case LEFTSCALE: + setCursor(m_sizeCursors[(6*s +rotOctant)%8]); + break; + case TOPLEFTSCALE: + setCursor(m_sizeCursors[(7*s +rotOctant)%8]); + break; + } +} + +void KisToolTransform::move(KisMoveEvent *e) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + + Q_ASSERT(controller); + TQPoint topleft = m_topleft; + TQPoint topright = m_topright; + TQPoint bottomleft = m_bottomleft; + TQPoint bottomright = m_bottomright; + + TQPoint mousePos = e->pos().floorTQPoint(); + + if (m_subject && m_selecting) { + paintOutline(); + m_actualyMoveWhileSelected = true; + mousePos -= m_clickoffset; + + // transform mousePos coords, so it seems like it isn't rotated and centered at 0,0 + double newX = invrotX(mousePos.x() - m_translateX, mousePos.y() - m_translateY); + double newY = invrotY(mousePos.x() - m_translateX, mousePos.y() - m_translateY); + double dx=0, dy=0; + double oldScaleX = m_scaleX; + double oldScaleY = m_scaleY; + + if(m_function == MOVE) + { + m_translateX += mousePos.x() - m_translateX; + m_translateY += mousePos.y() - m_translateY; + } + + if(m_function == ROTATE) + { + m_a = -atan2(mousePos.x() - m_translateX, mousePos.y() - m_translateY) + - m_clickangle; + } + + if(m_function == TOPSCALE) + { + dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + } + } + + if(m_function == TOPRIGHTSCALE) + { + dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); + + // enforce same aspect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); + } + } + } + + if(m_function == RIGHTSCALE) + { + dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + } + } + + if(m_function == BOTTOMRIGHTSCALE) + { + dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); + } + } + } + + if(m_function == BOTTOMSCALE) + { + dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + } + } + + if(m_function == BOTTOMLEFTSCALE) + { + dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); + } + } + } + + if(m_function == LEFTSCALE) + { + dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + } + } + + if(m_function == TOPLEFTSCALE) + { + dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); + } + } + } + + m_translateX += rotX(dx, dy); + m_translateY += rotY(dx, dy); + + paintOutline(); + } + else + { + if(det(mousePos - topleft, topright - topleft)>0) + m_function = ROTATE; + else if(det(mousePos - topright, bottomright - topright)>0) + m_function = ROTATE; + else if(det(mousePos - bottomright, bottomleft - bottomright)>0) + m_function = ROTATE; + else if(det(mousePos - bottomleft, topleft - bottomleft)>0) + m_function = ROTATE; + else + m_function = MOVE; + + int handleradius = int( 25 / (m_subject->zoomFactor() * m_subject->zoomFactor()) ); + + if(distsq(mousePos, (m_topleft + m_topright)/2)<=handleradius) + m_function = TOPSCALE; + if(distsq(mousePos, m_topright)<=handleradius) + m_function = TOPRIGHTSCALE; + if(distsq(mousePos, (m_topright + m_bottomright)/2)<=handleradius) + m_function = RIGHTSCALE; + if(distsq(mousePos, m_bottomright)<=handleradius) + m_function = BOTTOMRIGHTSCALE; + if(distsq(mousePos, (m_bottomleft + m_bottomright)/2)<=handleradius) + m_function = BOTTOMSCALE; + if(distsq(mousePos, m_bottomleft)<=handleradius) + m_function = BOTTOMLEFTSCALE; + if(distsq(mousePos, (m_topleft + m_bottomleft)/2)<=handleradius) + m_function = LEFTSCALE; + if(distsq(mousePos, m_topleft)<=handleradius) + m_function = TOPLEFTSCALE; + + setFunctionalCursor(); + } + } +} + +void KisToolTransform::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + if(!m_wasPressed) return; + m_wasPressed = false; + + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + m_selecting = false; + + if(m_actualyMoveWhileSelected) + { + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } +} + +void KisToolTransform::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolTransform::recalcOutline() +{ + double x,y; + + m_sina = sin(m_a); + m_cosa = cos(m_a); + + x = (m_startPos.x() - m_org_cenX) * m_scaleX; + y = (m_startPos.y() - m_org_cenY) * m_scaleY; + m_topleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); + + x = (m_endPos.x() - m_org_cenX) * m_scaleX; + y = (m_startPos.y() - m_org_cenY) * m_scaleY; + m_topright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); + + x = (m_startPos.x() - m_org_cenX) * m_scaleX; + y = (m_endPos.y() - m_org_cenY) * m_scaleY; + m_bottomleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); + + x = (m_endPos.x() - m_org_cenX) * m_scaleX; + y = (m_endPos.y() - m_org_cenY) * m_scaleY; + m_bottomright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); +} + +void KisToolTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + pen.setWidth(1); + Q_ASSERT(controller); + + recalcOutline(); + TQPoint topleft = controller->windowToView(m_topleft); + TQPoint topright = controller->windowToView(m_topright); + TQPoint bottomleft = controller->windowToView(m_bottomleft); + TQPoint bottomright = controller->windowToView(m_bottomright); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); + gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); + gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); + gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); + gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); + gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); + gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); + gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); + gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); + gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); + gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); + gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolTransform::transform() +{ + + KisImageSP img = m_subject->currentImg(); + + if (!img || !img->activeDevice()) + return; + + double tx = m_translateX - rotX(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); + double ty = m_translateY - rotY(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + + // This mementoes the current state of the active device. + TransformCmd * transaction = new TransformCmd(this, img->activeDevice(), m_origDevice, + m_scaleX, m_scaleY, m_translateX, m_translateY, m_a, m_origSelection, m_startPos, m_endPos); + + // Copy the original state back. + TQRect rc = m_origDevice->extent(); + rc = rc.normalize(); + img->activeDevice()->clear(); + KisPainter gc(img->activeDevice()); + gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); + gc.end(); + + // Also restore the original selection. + if(m_origSelection) + { + //TQRect rc = m_origSelection->extent(); + TQRect rc = m_origSelection->selectedRect(); + rc = rc.normalize(); + img->activeDevice()->selection()->clear(); + KisPainter sgc(img->activeDevice()->selection().data()); + sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); + sgc.end(); + } + else + if(img->activeDevice()->hasSelection()) + img->activeDevice()->selection()->clear(); + + // Perform the transform. Since we copied the original state back, this doesn't degrade + // after many tweaks. Since we started the transaction before the copy back, the memento + // has the previous state. + KisTransformWorker t(img->activeDevice(), m_scaleX, m_scaleY, 0, 0, m_a, int(tx), int(ty), progress, m_filter); + t.run(); + + // If canceled, go back to the memento + if(t.isCanceled()) + { + transaction->unexecute(); + delete transaction; + return; + } + + img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent + + // Else add the command -- this will have the memento from the previous state, + // and the transformed state from the original device we cached in our activated() + // method. + if (transaction) { + if (img->undo()) + img->undoAdapter()->addCommand(transaction); + else + delete transaction; + } +} + +void KisToolTransform::notifyCommandAdded( KCommand * command) +{ + TransformCmd * cmd = dynamic_cast(command); + if (cmd == 0) { + // The last added command wasn't one of ours; + // we should reset to the new state of the canvas. + // In effect we should treat this as if the tool has been just activated + initHandles(); + } +} + +void KisToolTransform::notifyCommandExecuted( KCommand * command) +{ + Q_UNUSED(command); + TransformCmd * cmd=0; + + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + if (cmd == 0) { + // The command now on the top of the stack isn't one of ours + // We should treat this as if the tool has been just activated + initHandles(); + } + else + { + // One of our commands is now on top + // We should ask for tool args and orig selection + cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); + m_origSelection = cmd->origSelection(m_startPos, m_endPos); + m_origDevice = cmd->origDevice(); + m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; + m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; + m_subject->canvasController() ->updateCanvas(); + } +} + +void KisToolTransform::slotSetFilter(const KisID &filterID) +{ + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); +} + +void KisToolTransform::slotLayerActivated(KisLayerSP) +{ + activate(); +} + + +TQWidget* KisToolTransform::createOptionWidget(TQWidget* parent) +{ + + m_optWidget = new WdgToolTransform(parent); + TQ_CHECK_PTR(m_optWidget); + + m_optWidget->cmbFilter->clear(); + m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + + m_optWidget->cmbFilter->setCurrentText("Mitchell"); + connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(slotSetFilter(const KisID &))); + + KisID filterID = m_optWidget->cmbFilter->currentItem(); + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); + +/* + connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); + connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); + connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); + connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); +*/ + m_optWidget->intStartX->hide(); + m_optWidget->intStartY->hide(); + m_optWidget->intEndX->hide(); + m_optWidget->intEndY->hide(); + m_optWidget->textLabel1->hide(); + m_optWidget->textLabel2->hide(); + m_optWidget->textLabel3->hide(); + m_optWidget->textLabel4->hide(); + return m_optWidget; +} + +TQWidget* KisToolTransform::optionWidget() +{ + return m_optWidget; +} + +void KisToolTransform::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Transform"), + "tool_transform", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Transform a layer or a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_transform.moc" diff --git a/chalk/plugins/tools/tool_transform/tool_transform.cc b/chalk/plugins/tools/tool_transform/tool_transform.cc deleted file mode 100644 index 82941e92..00000000 --- a/chalk/plugins/tools/tool_transform/tool_transform.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * tool_transform.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_transform.h" -#include "kis_tool_transform.h" - - -typedef KGenericFactory ToolTransformFactory; -K_EXPORT_COMPONENT_FACTORY( chalktooltransform, ToolTransformFactory( "chalk" ) ) - - -ToolTransform::ToolTransform(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolTransformFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - KisToolTransformFactory * f = new KisToolTransformFactory(); - TQ_CHECK_PTR(f); - r->add(f); - } - -} - -ToolTransform::~ToolTransform() -{ -} - -#include "tool_transform.moc" diff --git a/chalk/plugins/tools/tool_transform/tool_transform.cpp b/chalk/plugins/tools/tool_transform/tool_transform.cpp new file mode 100644 index 00000000..0f0dde27 --- /dev/null +++ b/chalk/plugins/tools/tool_transform/tool_transform.cpp @@ -0,0 +1,64 @@ +/* + * tool_transform.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_transform.h" +#include "kis_tool_transform.h" + + +typedef KGenericFactory ToolTransformFactory; +K_EXPORT_COMPONENT_FACTORY( chalktooltransform, ToolTransformFactory( "chalk" ) ) + + +ToolTransform::ToolTransform(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolTransformFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + KisToolTransformFactory * f = new KisToolTransformFactory(); + TQ_CHECK_PTR(f); + r->add(f); + } + +} + +ToolTransform::~ToolTransform() +{ +} + +#include "tool_transform.moc" -- cgit v1.2.1