You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/chalk/plugins/tools/tool_curves/kis_curve_framework.h

355 lines
11 KiB

/*
* Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.it>
*
* 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.
*/
#ifndef KIS_CURVE_FRAMEWORK_H_
#define KIS_CURVE_FRAMEWORK_H_
#include "kis_point.h"
const int NOHINTS = 0x0000;
const int POINTHINT = 0x0001;
const int LINEHINT = 0x0002;
const int NOOPTIONS = 0x0000;
const int SHIFTOPTION = 0x0001;
const int CONTROLOPTION = 0x0002;
const int ALTOPTION = 0x0004;
const int KEEPSELECTEDOPTION = CONTROLOPTION;
class CurvePoint {
KisPoint m_point;
bool m_pivot;
bool m_selected; // Only pivots can be selected
int m_hint;
public:
/* Constructors and Destructor */
CurvePoint ();
CurvePoint (const KisPoint&, bool = false, bool = false, int = POINTHINT);
CurvePoint (double, double, bool = false, bool = false, int = POINTHINT);
~CurvePoint () {}
public:
/* Generic Functions */
bool operator!= (KisPoint p2) const { if (p2 != m_point) return true; else return false; }
bool operator!= (CurvePoint p2) const { if (p2.point() != m_point ||
p2.isPivot() != m_pivot ||
p2.hint() != m_hint) return true; else return false; }
bool operator== (KisPoint p2) const { if (p2 == m_point) return true; else return false; }
bool operator== (CurvePoint p2) const { if (p2.point() == m_point &&
p2.isPivot() == m_pivot &&
p2.hint() == m_hint) return true; else return false; }
KisPoint point() const {return m_point;}
void setPoint(const KisPoint&);
void setPoint(double, double);
bool isPivot() const {return m_pivot;}
bool isSelected() const {return m_selected;}
int hint() const {return m_hint;}
void setPivot(bool p) {m_pivot = p;}
void setSelected(bool s) {m_selected = ((m_pivot) ? s : false);} /* Only pivots can be selected */
void setHint(int h) {m_hint = h;}
};
typedef TQValueList<CurvePoint> PointList;
typedef TQValueList<CurvePoint>::iterator BaseIterator;
class CurveIterator;
class KisCurve {
public:
KisCurve () {m_actionOptions = NOOPTIONS; m_standardkeepselected = true;}
virtual ~KisCurve () {m_curve.clear();}
friend class CurveIterator;
typedef CurveIterator iterator;
protected:
/* I need it to be mutable because my iterator needs to access
m_curve's end() and begin() functions using a const KisCurve
(see below in CurveIterator) */
mutable PointList m_curve;
int m_actionOptions;
bool m_standardkeepselected;
bool checkIterator (iterator checking) const;
public:
void setActionOptions (int options) {m_actionOptions = options;}
void endActionOptions () {m_actionOptions = NOOPTIONS;}
CurvePoint& operator[](int i) {return m_curve[i];}
iterator addPoint(iterator, const CurvePoint&);
iterator addPoint(iterator, const KisPoint&, bool = false, bool = false, int = POINTHINT);
iterator pushPoint(const CurvePoint&);
iterator pushPoint(const KisPoint&, bool = false, bool = false, int = POINTHINT);
virtual iterator addPivot(iterator, const KisPoint&);
virtual iterator pushPivot(const KisPoint&);
int count() const {return m_curve.count();}
bool isEmpty() const {return m_curve.isEmpty();}
CurvePoint first() {return m_curve.front();}
CurvePoint last() {return m_curve.back();}
void clear() {m_curve.clear();}
/* These needs iterators so they are implemented inline after the definition of CurveIterator */
iterator begin() const;
iterator lastIterator() const;
iterator end() const;
iterator find(const CurvePoint& pt);
iterator find(const KisPoint& pt);
iterator find(iterator it, const CurvePoint& pt);
iterator find(iterator it, const KisPoint& pt);
KisCurve pivots();
KisCurve selectedPivots(bool = true);
KisCurve subCurve(const KisPoint&);
KisCurve subCurve(const CurvePoint&);
KisCurve subCurve(iterator);
KisCurve subCurve(const KisPoint&, const KisPoint&);
KisCurve subCurve(const CurvePoint&, const CurvePoint&);
KisCurve subCurve(iterator,iterator);
/* Core virtual functions */
virtual void deleteFirstPivot();
virtual void deleteLastPivot();
virtual iterator deleteCurve(const KisPoint&, const KisPoint&);
virtual iterator deleteCurve(const CurvePoint&, const CurvePoint&);
virtual iterator deleteCurve(iterator, iterator);
/* Core of the Core, calculateCurve is the only function that *needs* an implementation in the derived curves */
virtual void calculateCurve(const KisPoint&, const KisPoint&, iterator);
virtual void calculateCurve(const CurvePoint&, const CurvePoint&, iterator);
virtual void calculateCurve(iterator, iterator, iterator);
virtual void calculateCurve(iterator*);
virtual void calculateCurve();
virtual iterator selectPivot(const CurvePoint&, bool = true);
virtual iterator selectPivot(const KisPoint&, bool = true);
virtual iterator selectPivot(iterator, bool = true);
virtual iterator movePivot(const CurvePoint&, const KisPoint&);
virtual iterator movePivot(const KisPoint&, const KisPoint&);
virtual iterator movePivot(iterator, const KisPoint&);
virtual void deletePivot(const CurvePoint&);
virtual void deletePivot(const KisPoint&);
virtual void deletePivot(iterator);
virtual void moveSelected(const KisPoint&);
virtual void deleteSelected();
virtual void selectAll(bool = true);
};
class CurveIterator {
const KisCurve *m_target;
BaseIterator m_position;
public:
CurveIterator () { m_target = 0; m_position = 0;}
CurveIterator (const KisCurve &target)
{m_target = &target;}
CurveIterator (const CurveIterator &it)
{m_position = it.position(); m_target = it.target();}
CurveIterator (const KisCurve &target, BaseIterator it)
{m_position = it; m_target = &target;}
~CurveIterator () {}
bool operator==(BaseIterator it) {return m_position == it;}
bool operator==(CurveIterator it) {return m_position == it.position();}
bool operator!=(BaseIterator it) {return m_position != it;}
bool operator!=(CurveIterator it) {return m_position != it.position();}
CurveIterator operator++() {++m_position;return *this;}
CurveIterator operator++(int) {CurveIterator temp = *this; m_position++; return temp;}
CurveIterator operator--() {--m_position;return *this;}
CurveIterator operator--(int) {CurveIterator temp = *this; m_position--; return temp;}
CurveIterator operator+=(int i) {m_position+=i;return *this;}
CurveIterator operator-=(int i) {m_position-=i;return *this;}
CurveIterator operator=(const BaseIterator &it) {m_position=it; return *this;}
CurvePoint& operator*() {return (*m_position);}
const KisCurve* target() const {return m_target;}
BaseIterator position() const {return m_position;}
CurveIterator next()
{
CurveIterator it = *this;
return ++it;
}
CurveIterator previous()
{
CurveIterator it = *this;
return --it;
}
CurveIterator previousPivot()
{
CurveIterator it = *this;
while (it != m_target->m_curve.begin()) {
it-=1;
if ((*it).isPivot())
return it;
}
return it;
}
CurveIterator nextPivot()
{
CurveIterator it = *this;
while (it != m_target->m_curve.end()) {
it+=1;
if ((*it).isPivot())
return it;
}
return it;
}
};
/* ************************************* *
* CurvePoint inline methods definitions *
* ************************************* */
inline CurvePoint::CurvePoint ()
: m_pivot(0), m_selected(0), m_hint(POINTHINT)
{
}
inline CurvePoint::CurvePoint (const KisPoint& pt, bool p, bool s, int h)
: m_pivot(p), m_selected((p) ? s : false), m_hint(h)
{
m_point = pt;
}
inline CurvePoint::CurvePoint (double x, double y, bool p, bool s, int h)
: m_pivot(p), m_selected((p) ? s : false), m_hint(h)
{
KisPoint tmp(x,y);
m_point = tmp;
}
inline void CurvePoint::setPoint(const KisPoint& p)
{
m_point = p;
}
inline void CurvePoint::setPoint(double x, double y)
{
KisPoint tmp(x,y);
m_point = tmp;
}
/* *********************************** *
* KisCurve inline methods definitions *
* *********************************** */
inline bool KisCurve::checkIterator (KisCurve::iterator checking) const
{
if (checking.target() != this)
return false;
else
return true;
}
inline KisCurve::iterator KisCurve::begin() const
{
return iterator(*this,m_curve.begin());
}
inline KisCurve::iterator KisCurve::lastIterator() const
{
return (iterator(*this,--m_curve.end()));
}
inline KisCurve::iterator KisCurve::end() const
{
return iterator(*this,m_curve.end());
}
inline KisCurve::iterator KisCurve::find (const CurvePoint& pt)
{
return iterator(*this,m_curve.find(pt));
}
inline KisCurve::iterator KisCurve::find (const KisPoint& pt)
{
return iterator(*this,m_curve.find(CurvePoint(pt)));
}
inline KisCurve::iterator KisCurve::find (KisCurve::iterator it, const CurvePoint& pt)
{
return iterator(*this,m_curve.find(it.position(),pt));
}
inline KisCurve::iterator KisCurve::find (iterator it, const KisPoint& pt)
{
return iterator(*this,m_curve.find(it.position(),CurvePoint(pt)));
}
inline void KisCurve::calculateCurve(const KisPoint& start, const KisPoint& end, KisCurve::iterator it)
{
calculateCurve(find(CurvePoint(start)),find(CurvePoint(end)),it);
}
inline void KisCurve::calculateCurve(const CurvePoint& start, const CurvePoint& end, KisCurve::iterator it)
{
calculateCurve(find(start),find(end),it);
}
inline void KisCurve::calculateCurve(KisCurve::iterator, KisCurve::iterator, KisCurve::iterator)
{
return;
}
/* Really generic functions, provided if someone _really_ needs them: array of iterators and no iterators. */
inline void KisCurve::calculateCurve(KisCurve::iterator*) {return;}
inline void KisCurve::calculateCurve() {return;}
#endif // KIS_CURVE_FRAMEWORK_H_