/* * 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"