Commit 596ae919 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Make KisColorDataList local to KisFavoriteResourceManager

parent c0b36a41
......@@ -78,7 +78,6 @@ set(kritaui_LIB_SRCS
kis_clipboard.cc
kis_config.cc
kis_config_notifier.cpp
kis_color_data_list.cpp
kis_control_frame.cpp
kis_composite_ops_model.cc
kis_paint_ops_model.cpp
......
/* This file is part of the KDE project
Copyright 2009 Vera Lukman <shicmap@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kis_color_data_list.h"
#ifndef _MSC_EXTENSIONS
const int KisColorDataList::MAX_RECENT_COLOR;
#endif
KisColorDataList::KisColorDataList()
:m_priorityList(0)
{
m_key = 0;
m_priorityList = new KisMinHeap <KoColor, MAX_RECENT_COLOR> ();
}
KisColorDataList::~KisColorDataList()
{
delete m_priorityList;
m_priorityList = 0 ;
}
void KisColorDataList::appendNew(const KoColor& data)
{
if (size() >= KisColorDataList::MAX_RECENT_COLOR) removeLeastUsed();
PriorityNode<KoColor> * node;
node = new PriorityNode <KoColor>();
node->data = data;
node->key = m_key++;
m_priorityList->append(node);
int pos = guiInsertPos(data);
pos >= m_guiList.size() ? m_guiList.append(node)
: m_guiList.insert(pos, node);
node = 0;
}
void KisColorDataList::append(const KoColor& data)
{
int pos = findPos(data);
if (pos > -1) updateKey(pos);
else appendNew(data);
}
void KisColorDataList::removeLeastUsed()
{
Q_ASSERT_X(size() >= 0, "KisColorDataList::removeLeastUsed", "index out of bound");
if (size() <= 0) return;
int pos = findPos(m_priorityList->valueAt(0));
m_guiList.removeAt(pos);
m_priorityList->remove(0);
}
const KoColor& KisColorDataList::guiColor(int pos)
{
Q_ASSERT_X(pos < size(), "KisColorDataList::guiColor", "index out of bound");
Q_ASSERT_X(pos >= 0, "KisColorDataList::guiColor", "negative index");
return m_guiList.at(pos)->data;
}
void KisColorDataList::printGuiList()
{
QColor* color = new QColor();
for (int pos = 0; pos < size() ; pos++)
{
m_guiList.at(pos)->data.toQColor(color);
}
}
int KisColorDataList::guiInsertPos(const KoColor& color)
{
int low = 0, high = size() - 1, mid = (low + high)/2;
while (low < high)
{
hsvComparison (color, m_guiList[mid]->data) == -1 ? high = mid
: low = mid + 1;
mid = (low + high)/2;
}
if (m_guiList.size() > 0)
{
if (hsvComparison (color, m_guiList[mid]->data) == 1) ++mid;
}
return mid;
}
int KisColorDataList::hsvComparison(const KoColor& c1, const KoColor& c2)
{
QColor qc1 = c1.toQColor();
QColor qc2 = c2.toQColor();
if (qc1.hue() < qc2.hue()) return -1;
if (qc1.hue() > qc2.hue()) return 1;
// hue is the same, ok let's compare saturation
if (qc1.saturation() < qc2.saturation()) return -1;
if (qc1.saturation() > qc2.saturation()) return 1;
// oh, also saturation is same?
if (qc1.value() < qc2.value()) return -1;
if (qc1.value() > qc2.value()) return 1;
// user selected two similar colors
return 0;
}
int KisColorDataList::findPos (const KoColor& color)
{
int low = 0, high = size(), mid = 0;
while (low < high)
{
mid = (low + high)/2;
if (hsvComparison(color,m_guiList.at(mid)->data) == 0) return mid;
else if (hsvComparison(color,m_guiList.at(mid)->data) < 0) high = mid;
else low = mid + 1;
}
return -1;
}
void KisColorDataList::updateKey (int guiPos)
{
if (m_guiList.at(guiPos)->key == m_key-1) return;
m_priorityList->changeKey(m_guiList.at(guiPos)->pos, m_key++);
}
/* This file is part of the KDE project
Copyright 2009 Vera Lukman <shicmap@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KIS_COLOR_DATA_LIST_H
#define KIS_COLOR_DATA_LIST_H
#include "kis_min_heap.h"
#include <KoColor.h>
#include <QColor>
#include <QList>
class KisColorDataList
{
public:
static const int MAX_RECENT_COLOR = 12;
KisColorDataList();
~KisColorDataList();
inline int size () { return m_guiList.size(); };
inline void printPriorityList () { m_priorityList->printHeap(); };
inline int leastUsedGuiPos() { return findPos(m_priorityList->valueAt(0)); };
void printGuiList();
const KoColor& guiColor (int pos);
void append(const KoColor&);
void appendNew(const KoColor&);
void removeLeastUsed();
void updateKey (int guiPos);
/*find position of the color on the gui list*/
int findPos (const KoColor&);
private:
KisMinHeap <KoColor, MAX_RECENT_COLOR> *m_priorityList;
QList <PriorityNode <KoColor>*> m_guiList;
int m_key;
int guiInsertPos(const KoColor&);
/*compares c1 and c2 based on HSV.
c1 < c2, returns -1
c1 = c2, returns 0
c1 > c2, returns 1 */
int hsvComparison (const KoColor& c1, const KoColor& c2);
};
#endif // KIS_COLOR_DATA_LIST_H
......@@ -34,12 +34,138 @@
#include "kis_palette_manager.h"
#include "kis_view2.h"
#include "kis_resource_server_provider.h"
#include "kis_min_heap.h"
#ifndef _MSC_EXTENSIONS
const int KisFavoriteResourceManager::MAX_FAVORITE_PRESETS;
//const int KisFavoriteResourceManager::MAX_RECENT_COLORS;
#endif
class KisFavoriteResourceManager::ColorDataList
{
public:
static const int MAX_RECENT_COLOR = 12;
ColorDataList() {
m_key = 0;
}
~ColorDataList() {
}
int size() {
return m_guiList.size();
}
int leastUsedGuiPos() {
return findPos(m_priorityList.valueAt(0));
}
const KoColor& guiColor(int pos) {
Q_ASSERT_X(pos < size(), "ColorDataList::guiColor", "index out of bound");
Q_ASSERT_X(pos >= 0, "ColorDataList::guiColor", "negative index");
return m_guiList.at(pos)->data;
}
void append(const KoColor& data) {
int pos = findPos(data);
if (pos > -1) updateKey(pos);
else appendNew(data);
}
void appendNew(const KoColor& data) {
if (size() >= ColorDataList::MAX_RECENT_COLOR) removeLeastUsed();
PriorityNode<KoColor> * node;
node = new PriorityNode <KoColor>();
node->data = data;
node->key = m_key++;
m_priorityList.append(node);
int pos = guiInsertPos(data);
pos >= m_guiList.size() ? m_guiList.append(node)
: m_guiList.insert(pos, node);
node = 0;
}
void removeLeastUsed() {
Q_ASSERT_X(size() >= 0, "ColorDataList::removeLeastUsed", "index out of bound");
if (size() <= 0) return;
int pos = findPos(m_priorityList.valueAt(0));
m_guiList.removeAt(pos);
m_priorityList.remove(0);
}
void updateKey(int guiPos) {
if (m_guiList.at(guiPos)->key == m_key - 1) return;
m_priorityList.changeKey(m_guiList.at(guiPos)->pos, m_key++);
}
/*find position of the color on the gui list*/
int findPos(const KoColor& color) {
int low = 0, high = size(), mid = 0;
while (low < high) {
mid = (low + high) / 2;
if (hsvComparison(color, m_guiList.at(mid)->data) == 0) return mid;
else if (hsvComparison(color, m_guiList.at(mid)->data) < 0) high = mid;
else low = mid + 1;
}
return -1;
}
private:
int m_key;
int guiInsertPos(const KoColor& color) {
int low = 0, high = size() - 1, mid = (low + high) / 2;
while (low < high) {
hsvComparison(color, m_guiList[mid]->data) == -1 ? high = mid
: low = mid + 1;
mid = (low + high) / 2;
}
if (m_guiList.size() > 0) {
if (hsvComparison(color, m_guiList[mid]->data) == 1) ++mid;
}
return mid;
}
/*compares c1 and c2 based on HSV.
c1 < c2, returns -1
c1 = c2, returns 0
c1 > c2, returns 1 */
int hsvComparison(const KoColor& c1, const KoColor& c2) {
QColor qc1 = c1.toQColor();
QColor qc2 = c2.toQColor();
if (qc1.hue() < qc2.hue()) return -1;
if (qc1.hue() > qc2.hue()) return 1;
// hue is the same, ok let's compare saturation
if (qc1.saturation() < qc2.saturation()) return -1;
if (qc1.saturation() > qc2.saturation()) return 1;
// oh, also saturation is same?
if (qc1.value() < qc2.value()) return -1;
if (qc1.value() > qc2.value()) return 1;
// user selected two similar colors
return 0;
}
KisMinHeap <KoColor, MAX_RECENT_COLOR> m_priorityList;
QList <PriorityNode <KoColor>*> m_guiList;
};
KisFavoriteResourceManager::KisFavoriteResourceManager(KisPaintopBox *paintopBox)
: m_favoriteBrushManager(0)
, m_popupPalette(0)
......@@ -51,7 +177,7 @@ KisFavoriteResourceManager::KisFavoriteResourceManager(KisPaintopBox *paintopBox
KConfigGroup group(KGlobal::config(), "favoriteList");
m_favoritePresetsList = (group.readEntry("favoritePresets")).split(',', QString::SkipEmptyParts);
m_colorList = new KisColorDataList();
m_colorList = new ColorDataList();
KoResourceServer<KisPaintOpPreset>* rServer = KisResourceServerProvider::instance()->paintOpPresetServer();
rServer->addObserver(this);
......@@ -85,12 +211,11 @@ QList<QImage> KisFavoriteResourceManager::favoritePresetImages()
{
QList<QImage> images;
KoResourceServer<KisPaintOpPreset>* rServer = KisResourceServerProvider::instance()->paintOpPresetServer();
foreach(const QString& name, m_favoritePresetsList) {
foreach(const QString & name, m_favoritePresetsList) {
KoResource* resource = rServer->resourceByName(name);
if(!resource) {
if (!resource) {
removeFavoritePreset(name);
}
else {
} else {
images.append(resource->image());
}
}
......@@ -127,18 +252,15 @@ int KisFavoriteResourceManager::addFavoritePreset(const QString& name)
int pos = isFavoriteBrushSaved(name);
if (pos > -1) //brush is saved
{
if (pos > -1) { //brush is saved
return pos;
}
else //brush hasn't been saved yet
{
if (isFavoritePresetsFull())
{
else { //brush hasn't been saved yet
if (isFavoritePresetsFull()) {
return -2; //list is full!
}
else
{
} else {
m_favoritePresetsList.append(name);
saveFavoritePresets();
m_popupPalette->update();
......@@ -154,11 +276,9 @@ int KisFavoriteResourceManager::isFavoriteBrushSaved(const QString& name)
void KisFavoriteResourceManager::removeFavoritePreset(int pos)
{
if (pos < 0 || pos > m_favoritePresetsList.size())
{
if (pos < 0 || pos > m_favoritePresetsList.size()) {
return;
}
else {
} else {
m_favoritePresetsList.removeAt(pos);
saveFavoritePresets();
m_popupPalette->update();
......@@ -186,8 +306,7 @@ void KisFavoriteResourceManager::saveFavoritePresets()
QString favoriteList;
for (int pos = 0; pos < m_favoritePresetsList.size(); pos++)
{
for (int pos = 0; pos < m_favoritePresetsList.size(); pos++) {
favoriteList.append(m_favoritePresetsList.at(pos));
favoriteList.append(",");
}
......@@ -199,62 +318,43 @@ void KisFavoriteResourceManager::saveFavoritePresets()
//Recent Colors
void KisFavoriteResourceManager::slotUpdateRecentColor(int pos)
{
// qDebug() << "[KisFavoriteResourceManager] selected color: " << recentColorAt(pos)
// << "(r)" << recentColorAt(pos).red() << "(g)" << recentColorAt(pos).green()
// << "(b)" << recentColorAt(pos).blue();
addRecentColorUpdate(pos);
if (m_popupPalette)
m_popupPalette->showPopupPalette(false); //automatically close the palette after a button is clicked.
}
void KisFavoriteResourceManager::slotAddRecentColor(const KoColor& color)
{
addRecentColor(color);
}
void KisFavoriteResourceManager::slotChangeFGColorSelector(KoColor c)
{
QColor color;
color = c.toQColor();
//qDebug() << "[KisFavoriteResourceManager] slotChangeFGColorSelector | color " << color ;
emit sigChangeFGColorSelector(color);
}
void KisFavoriteResourceManager::addRecentColorUpdate(int guipos)
{
// Do not update the key, the colour might be selected but it is not used yet. So we are not supposed
// to update the colour priority when we select it.
m_colorList->updateKey(guipos);
if (m_popupPalette)
{
m_popupPalette->setSelectedColor(guipos);
m_colorList->updateKey(pos);
if (m_popupPalette) {
m_popupPalette->setSelectedColor(pos);
m_popupPalette->update();
}
emit sigSetFGColor(m_colorList->guiColor(guipos));
printColors();
emit sigSetFGColor(m_colorList->guiColor(pos));
if (m_popupPalette) {
m_popupPalette->showPopupPalette(false); //automatically close the palette after a button is clicked.
}
}
void KisFavoriteResourceManager::addRecentColor(const KoColor& color)
void KisFavoriteResourceManager::slotAddRecentColor(const KoColor& color)
{
m_colorList->append(color);
int pos = m_colorList->findPos(color);
if (m_popupPalette)
{
if (m_popupPalette) {
m_popupPalette->setSelectedColor(pos);
m_popupPalette->update();
}
printColors();
}
void KisFavoriteResourceManager::slotChangeFGColorSelector(KoColor c)
{
QColor color;
color = c.toQColor();
emit sigChangeFGColorSelector(color);
}
void KisFavoriteResourceManager::removingResource(KisPaintOpPreset* resource)
{
if(m_blockUpdates) {
if (m_blockUpdates) {
return;
}
removeFavoritePreset(resource->name());
......@@ -273,10 +373,21 @@ void KisFavoriteResourceManager::setBlockUpdates(bool block)
m_blockUpdates = block;
}
void KisFavoriteResourceManager::syncTaggedResourceView(){}
void KisFavoriteResourceManager::syncTaggedResourceView() {}
void KisFavoriteResourceManager::syncTagAddition(const QString& /*tag*/){}
void KisFavoriteResourceManager::syncTagAddition(const QString& /*tag*/) {}
void KisFavoriteResourceManager::syncTagRemoval(const QString& /*tag*/){}
void KisFavoriteResourceManager::syncTagRemoval(const QString& /*tag*/) {}
int KisFavoriteResourceManager::recentColorsTotal()
{
return m_colorList->size();
}
const KoColor& KisFavoriteResourceManager::recentColorAt(int pos)
{
return m_colorList->guiColor(pos);
}
#include "kis_favorite_resource_manager.moc"
......@@ -21,11 +21,12 @@
#include <QObject>
#include <kis_types.h>
#include "kis_color_data_list.h"
#include <QQueue>
#include <QList>
#include "KoResourceServerObserver.h"
#include <KoColor.h>
class QString;
class QColor;
class QStringList;
......@@ -51,32 +52,27 @@ public:
virtual void unsetResourceServer();
static const int MAX_FAVORITE_PRESETS = 10;
// static const int MAX_RECENT_COLORS = 3;
/************************************Popup Palette************************************/
void showPaletteManager();
QList<QImage> favoritePresetImages();
/**********************************Favorite Brushes***********************************/
/**Checks if newBrush is saved as a favorite brush.
Returns -1 if the newBrush is not yet saved, then newBrush will be appended
Returns the position of the brush on the list otherwise**/
/**
* Checks if newBrush is saved as a favorite brush.
* @returns -1 if the newBrush is not yet saved, then newBrush will be appended
* or the position of the brush on the list otherwise
*/
int addFavoritePreset(const QString& name);
void removeFavoritePreset(int);
void removeFavoritePreset(const QString& name);
//returns -1 if paintop is not in the list, returns the paintop position otherwise
/// @return -1 if paintop is not in the list, returns the paintop position otherwise
int isFavoriteBrushSaved(const QString& name);
int numFavoritePresets();
QStringList favoritePresetList();
/***********************************Recent Colors************************************/
inline int recentColorsTotal() { return m_colorList->size(); } ;
inline const KoColor& recentColorAt(int pos) { return m_colorList->guiColor(pos); };
int recentColorsTotal();
const KoColor& recentColorAt(int pos);
// Reimplemented from KoResourceServerObserver
virtual void removingResource(KisPaintOpPreset* resource);
......@@ -85,13 +81,15 @@ public:
virtual void syncTaggedResourceView();
virtual void syncTagAddition(const QString& tag);
virtual void syncTagRemoval(const QString& tag);
/**
Set palette to block updates, paintops won't be deleted when they are deleted from server
Used when overwriting a resource
**/
* Set palette to block updates, paintops won't be deleted when they are deleted from server
* Used when overwriting a resource
*/
void setBlockUpdates(bool block);
signals:
void sigSetFGColor(const KoColor& c);
// This is a flag to handle a bug:
......@@ -104,6 +102,7 @@ signals:
void sigChangeFGColorSelector(const QColor&);
public slots:
void slotChangeActivePaintop(int);
/*update the priority of a colour in m_colorList, used only by m_popupPalette*/
......@@ -115,25 +114,21 @@ public slots:
void slotChangeFGColorSelector(KoColor c);
private:
KisPaletteManager* m_favoriteBrushManager;
KisPopupPalette* m_popupPalette;
KisPaintopBox* m_paintopBox;
KisPaletteManager *m_favoriteBrushManager;
KisPopupPalette *m_popupPalette;
KisPaintopBox *m_paintopBox;
QStringList m_favoritePresetsList;
/**The list of recently used colors**/
KisColorDataList * m_colorList;
class ColorDataList;
ColorDataList *m_colorList;
bool m_blockUpdates;
bool isFavoritePresetsFull();
void saveFavoritePresets();