diff options
Diffstat (limited to 'chalk/plugins/filters/levelfilter/kgradientslider.cpp')
-rw-r--r-- | chalk/plugins/filters/levelfilter/kgradientslider.cpp | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/chalk/plugins/filters/levelfilter/kgradientslider.cpp b/chalk/plugins/filters/levelfilter/kgradientslider.cpp new file mode 100644 index 000000000..b36e5ce97 --- /dev/null +++ b/chalk/plugins/filters/levelfilter/kgradientslider.cpp @@ -0,0 +1,338 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Frederic Coiffier <fcoiffie@gmail.com> + * + * 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. + */ + +// C++ includes. + +#include <cmath> +#include <cstdlib> + +// TQt includes. + +#include <tqpixmap.h> +#include <tqpainter.h> +#include <tqpoint.h> +#include <tqpen.h> + +// Local includes. + +#include "kgradientslider.h" + +KGradientSlider::KGradientSlider(TQWidget *parent, const char *name, WFlags f) + : TQWidget(parent, name, f) +{ + m_dragging = false; + + setMouseTracking(true); + setPaletteBackgroundColor(TQt::NoBackground); + setMaximumSize(255, 28); + + m_blackcursor = 0; + m_whitecursor = 255; + m_gamma = 1.0; + m_gammaEnabled = false; + setFocusPolicy(TQ_StrongFocus); +} + +KGradientSlider::~KGradientSlider() +{ +} + +void KGradientSlider::paintEvent(TQPaintEvent *) +{ + int x, y; + int wWidth = width(); + int wHeight = height(); + + int gradientHeight = (wHeight / 3); + + // A TQPixmap is used for enable the double buffering. + /*if (!m_dragging) {*/ + TQPixmap pm(size()); + TQPainter p1; + p1.begin(TQT_TQPAINTDEVICE(&pm), this); + + pm.fill(); + + // Draw first gradient + y = 0; + p1.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); + for( x=0; x<255; ++x ) + { + int gray = (255 * x) / wWidth; + p1.setPen(TQColor(gray, gray, gray)); + p1.drawLine(x, y, x, y + gradientHeight - 1); + } + + // Draw second gradient + y = (wHeight / 3); + if (m_blackcursor > 0) { + p1.fillRect(0, y, (int)m_blackcursor, gradientHeight, TQBrush(TQt::black)); + } + if (m_whitecursor < 255) { + p1.fillRect((int)m_whitecursor, y, 255, gradientHeight, TQBrush(TQt::white)); + } + for(x = (int)m_blackcursor; x < (int)m_whitecursor; ++x ) + { + double inten = (double)(x - m_blackcursor) / (double)(m_whitecursor - m_blackcursor); + inten = pow (inten, (1.0 / m_gamma)); + int gray = (int)(255 * inten); + p1.setPen(TQColor(gray, gray, gray)); + p1.drawLine(x, y, x, y + gradientHeight - 1); + } + + // Draw cursors + y = (2 * wHeight / 3); + TQPointArray *a = new TQPointArray(3); + p1.setPen(TQt::black); + + a->setPoint(0, m_blackcursor, y); + a->setPoint(1, m_blackcursor + 3, wHeight - 1); + a->setPoint(2, m_blackcursor - 3, wHeight - 1); + p1.setBrush(TQt::black); + p1.drawPolygon(*a); + + if (m_gammaEnabled) { + a->setPoint(0, m_gammacursor, y); + a->setPoint(1, m_gammacursor + 3, wHeight - 1); + a->setPoint(2, m_gammacursor - 3, wHeight - 1); + p1.setBrush(TQt::gray); + p1.drawPolygon(*a); + } + + a->setPoint(0, m_whitecursor, y); + a->setPoint(1, m_whitecursor + 3, wHeight - 1); + a->setPoint(2, m_whitecursor - 3, wHeight - 1); + p1.setBrush(TQt::white); + p1.drawPolygon(*a); + + p1.end(); + bitBlt(this, 0, 0, &pm); +} + +void KGradientSlider::mousePressEvent ( TQMouseEvent * e ) +{ + eCursor closest_cursor; + int distance; + + if (e->button() != Qt::LeftButton) + return; + + unsigned int x = e->pos().x(); + + distance = 1000; // just a big number + + if (abs((int)(x - m_blackcursor)) < distance) + { + distance = abs((int)(x - m_blackcursor)); + closest_cursor = BlackCursor; + } + + if (abs((int)(x - m_whitecursor)) < distance) + { + distance = abs((int)(x - m_whitecursor)); + closest_cursor = WhiteCursor; + } + + if (m_gammaEnabled && (abs((int)(x - m_gammacursor)) < distance)) + { + distance = abs((int)(x - m_gammacursor)); + closest_cursor = GammaCursor; + } + + if (distance > 20) + { + return; + } + + + m_dragging = true; + + // Determine cursor values and the leftmost and rightmost points. + + switch (closest_cursor) { + case BlackCursor: + m_blackcursor = x; + m_grab_cursor = closest_cursor; + m_leftmost = 0; + m_rightmost = m_whitecursor; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + break; + case WhiteCursor: + m_whitecursor = x; + m_grab_cursor = closest_cursor; + m_leftmost = m_blackcursor; + m_rightmost = 255; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + break; + case GammaCursor: + m_gammacursor = x; + m_grab_cursor = closest_cursor; + m_leftmost = m_blackcursor; + m_rightmost = m_whitecursor; + + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = (x - mid) / delta; + m_gamma = 1.0 / pow (10, tmp); + break; + } + repaint(false); +} + +void KGradientSlider::mouseReleaseEvent ( TQMouseEvent * e ) +{ + if (e->button() != Qt::LeftButton) + return; + + m_dragging = false; + repaint(false); + + switch (m_grab_cursor) { + case BlackCursor: + emit modifiedBlack(m_blackcursor); + break; + case WhiteCursor: + emit modifiedWhite(m_whitecursor); + break; + case GammaCursor: + emit modifiedGamma(m_gamma); + break; + } +} + +void KGradientSlider::mouseMoveEvent ( TQMouseEvent * e ) +{ + unsigned int x = abs(e->pos().x()); + + if (m_dragging == true) // Else, drag the selected point + { + if (x <= m_leftmost) + x = m_leftmost; + + if(x >= m_rightmost) + x = m_rightmost; + + /*if(x > 255) + x = 255; + + if(x < 0) + x = 0;*/ + + switch (m_grab_cursor) { + case BlackCursor: + if (m_blackcursor != x) + { + m_blackcursor = x; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + } + break; + case WhiteCursor: + if (m_whitecursor != x) + { + m_whitecursor = x; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + } + break; + case GammaCursor: + if (m_gammacursor != x) + { + m_gammacursor = x; + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = (x - mid) / delta; + m_gamma = 1.0 / pow (10, tmp); + } + break; + } + } + + repaint(false); +} + +void KGradientSlider::leaveEvent( TQEvent * ) +{ +} + + +void KGradientSlider::enableGamma(bool b) +{ + m_gammaEnabled = b; + repaint(false); +} + +double KGradientSlider::getGamma(void) +{ + return m_gamma; +} + +void KGradientSlider::modifyBlack(int v) { + if (v >= 0 && v <= (int)m_whitecursor) { + m_blackcursor = (unsigned int)v; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + repaint(false); + } +} +void KGradientSlider::modifyWhite(int v) { + if (v >= (int)m_blackcursor && v <= 255) { + m_whitecursor = (unsigned int)v; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + repaint(false); + } +} +void KGradientSlider::modifyGamma(double v) { + m_gamma = v; + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + repaint(false); +} + +#include "kgradientslider.moc" |