summaryrefslogtreecommitdiffstats
path: root/krita/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
diff options
context:
space:
mode:
Diffstat (limited to 'krita/plugins/tools/selectiontools/kis_tool_select_elliptical.cc')
-rw-r--r--krita/plugins/tools/selectiontools/kis_tool_select_elliptical.cc321
1 files changed, 321 insertions, 0 deletions
diff --git a/krita/plugins/tools/selectiontools/kis_tool_select_elliptical.cc b/krita/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
new file mode 100644
index 00000000..226277b2
--- /dev/null
+++ b/krita/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
@@ -0,0 +1,321 @@
+/*
+ * kis_tool_select_elliptical.cc -- part of Krita
+ *
+ * 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 <qapplication.h>
+#include <qpainter.h>
+#include <qpen.h>
+#include <qlayout.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#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, QRect());
+}
+
+void KisToolSelectElliptical::paint(KisCanvasPainter& gc, const QRect& 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() == 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() & Qt::AltButton) {
+ KisPoint trans = e->pos() - m_endPos;
+ m_startPos += trans;
+ m_endPos += trans;
+ } else {
+ KisPoint diag = e->pos() - (e->state() & Qt::ControlButton
+ ? m_centerPos : m_startPos);
+ // circle?
+ if (e->state() & Qt::ShiftButton) {
+ double size = QMAX(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() & Qt::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() == LeftButton) {
+
+ paintOutline();
+
+ if (m_startPos == m_endPos) {
+ clearSelection();
+ } else {
+ QApplication::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();
+ }
+ QRect rc( m_startPos.floorQPoint(), m_endPos.floorQPoint());
+ rc = rc.normalize();
+
+ KisSelectionSP tmpSel = new KisSelection(dev);
+ KisAutobrushCircleShape shape(rc.width(),rc.height(), 1, 1);
+ Q_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);
+
+ QApplication::restoreOverrideCursor();
+ }
+ }
+ m_selecting = false;
+ }
+}
+
+void KisToolSelectElliptical::paintOutline()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ QRect rc;
+
+ paintOutline(gc, rc);
+ }
+}
+
+void KisToolSelectElliptical::paintOutline(KisCanvasPainter& gc, const QRect&)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ QPen old = gc.pen();
+ QPen pen(Qt::DotLine);
+ QPoint start;
+ QPoint end;
+
+ Q_ASSERT(controller);
+ start = controller->windowToView(m_startPos).floorQPoint();
+ end = controller->windowToView(m_endPos).floorQPoint();
+
+ gc.setRasterOp(Qt::NotROP);
+ gc.setPen(pen);
+ gc.drawEllipse(QRect(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(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Elliptical Selection"),
+ "tool_elliptical_selection" ,
+ Qt::Key_J,
+ this,
+ SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Select an elliptical area"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+QWidget* KisToolSelectElliptical::createOptionWidget(QWidget* parent)
+{
+ m_optWidget = new KisSelectionOptions(parent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Elliptical Selection"));
+
+ connect (m_optWidget, SIGNAL(actionChanged(int)), this, SLOT(slotSetAction(int)));
+
+ QVBoxLayout * l = dynamic_cast<QVBoxLayout*>(m_optWidget->layout());
+ l->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+QWidget* KisToolSelectElliptical::optionWidget()
+{
+ return m_optWidget;
+}
+
+
+
+#include "kis_tool_select_elliptical.moc"