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