Commit 6d336838 authored by Wolthera van Hövell's avatar Wolthera van Hövell 🐛

Add very simple 'colorselection' dialog with a widget containing spinboxes.

Right now the spinbox widget is able to adapt itself to all colorspaces, and having it
as a separate widget makes it into a nice building block for other uses too.

I can't actually connect this to anything, because all our color buttons seem to be K and Ko,
so that will be the big task tomorrow...

Ref: T2337, T2438
Auditors: rempt
parent 7ce94758
......@@ -66,6 +66,7 @@ set(kritaui_LIB_SRCS
dialogs/kis_dlg_png_import.cpp
dialogs/kis_dlg_import_image_sequence.cpp
dialogs/kis_delayed_save_dialog.cpp
dialogs/kis_internal_color_selector.cpp
flake/kis_node_dummies_graph.cpp
flake/kis_dummies_facade_base.cpp
flake/kis_dummies_facade.cpp
......@@ -246,6 +247,7 @@ set(kritaui_LIB_SRCS
widgets/kis_lod_availability_widget.cpp
widgets/kis_color_label_selector_widget.cpp
widgets/kis_color_filter_combo.cpp
widgets/kis_spinbox_color_selector.cpp
input/kis_input_manager.cpp
input/kis_input_manager_p.cpp
input/kis_extended_modifiers_mapper.cpp
......@@ -447,6 +449,7 @@ ki18n_wrap_ui(kritaui_LIB_SRCS
forms/wdgimportimagesequence.ui
forms/KisDetailsPaneBase.ui
forms/KisOpenPaneBase.ui
forms/wdgdlginternalcolorselector.ui
dialogs/kis_delayed_save_dialog.ui
input/config/kis_input_configuration_page.ui
input/config/kis_edit_profiles_dialog.ui
......
/*
* Copyright (C) Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>, (C) 2016
*
* 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 <QList>
#include <QAbstractSpinBox>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include "KoColorSpaceRegistry.h"
#include "kis_signal_compressor.h"
#include "kis_canvas_resource_provider.h"
#include "KoColorDisplayRendererInterface.h"
#include "kis_display_color_converter.h"
#include "kis_spinbox_color_selector.h"
#include "kis_internal_color_selector.h"
struct KisInternalColorSelector::Private
{
bool allowUpdates = true;
KoColor currentColor;
const KoColorSpace *currentColorSpace;
KisCanvas2 *canvas;
KisSpinboxColorSelector *spinBoxSelector;
KisSignalCompressor *compressColorChanges;
};
KisInternalColorSelector::KisInternalColorSelector(QWidget *parent, const QString &caption)
: QDialog(parent)
,m_d(new Private)
{
setModal(false);
setWindowTitle(caption);
m_d->currentColor = KoColor();
m_d->currentColorSpace = m_d->currentColor.colorSpace();
m_d->spinBoxSelector = new KisSpinboxColorSelector;
m_d->spinBoxSelector->slotSetColorSpace(m_d->currentColorSpace);
ui->base->addWidget(m_d->spinBoxSelector);
connect(m_d->spinBoxSelector, SIGNAL(sigNewColor(KoColor)), this, SLOT(slotColorUpdated(KoColor)));
connect(this, SIGNAL(signalForegroundColorChosen(KoColor)), this, SLOT(slotLockSelector()));
m_d->compressColorChanges = new KisSignalCompressor(500 /* ms */, KisSignalCompressor::POSTPONE, this);
connect(m_d->compressColorChanges, SIGNAL(timeout()), this, SLOT(sentUpdateWithNewColor()));
}
KisInternalColorSelector::~KisInternalColorSelector()
{
delete ui;
//TODO: Does the scoped pointer also need to be deleted???
}
void KisInternalColorSelector::setCanvas(KisCanvas2 *canvas)
{
if (m_d->canvas) {
m_d->canvas->disconnectCanvasObserver(this);
}
m_d->canvas = canvas;
if (m_d->canvas) {
//basics//
connect(m_d->canvas->imageView()->resourceProvider(), SIGNAL(sigFGColorChanged(KoColor)), this, SLOT(slotColorUpdated(KoColor)));
connect(this, SIGNAL(signalForegroundColorChosen(KoColor)), m_d->canvas->imageView()->resourceProvider(), SLOT(slotSetFGColor(KoColor)));
//display color converter//
connect(m_d->canvas->displayColorConverter(), SIGNAL(displayConfigurationChanged()), this, SLOT(slotConfigurationChanged()));
}
}
void KisInternalColorSelector::unsetCanvas()
{
setEnabled(false);
m_d->canvas = 0;
}
void KisInternalColorSelector::slotColorUpdated(KoColor newColor)
{
//if the update did not come from this selector...
if (m_d->allowUpdates) {
m_d->currentColor = newColor;
updateAllElements();
} else {
emit(signalForegroundColorChosen(m_d->currentColor));
m_d->compressColorChanges->start();
}
}
void KisInternalColorSelector::slotColorSpaceChanged(const KoColorSpace *cs)
{
if (cs == m_d->currentColorSpace) {
return;
}
m_d->currentColorSpace = KoColorSpaceRegistry::instance()->colorSpace(cs->colorModelId().id(), cs->colorDepthId().id(), cs->profile());
//Empty the layout.
m_d->spinBoxSelector->slotSetColorSpace(m_d->currentColorSpace);
}
void KisInternalColorSelector::slotConfigurationChanged()
{
if (!m_d->canvas) {
return;
}
//m_d->canvas->displayColorConverter()->
//slotColorSpaceChanged(m_d->canvas->image()->colorSpace());
}
void KisInternalColorSelector::slotLockSelector()
{
m_d->allowUpdates = false;
}
void KisInternalColorSelector::updateAllElements()
{
//update everything!!!
m_d->spinBoxSelector->slotSetColor(m_d->currentColor);
}
void KisInternalColorSelector::endUpdateWithNewColor()
{
m_d->allowUpdates = true;
}
/*
* Copyright (C) Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>, (C) 2016
*
* 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 KISINTERNALCOLORSELECTOR_H
#define KISINTERNALCOLORSELECTOR_H
#include "kritaui_export.h"
#include "kis_mainwindow_observer.h"
#include "kis_canvas2.h"
#include "KoColor.h"
#include "KoColorSpace.h"
#include <QScopedPointer>
#include "ui_wdgdlginternalcolorselector.h"
/**
* @brief The KisInternalColorSelector class
*
* A non-modal color selector dialog that is not a plugin and can thus be used for filters.
*/
class KRITAUI_EXPORT KisInternalColorSelector : public QDialog, public KisMainwindowObserver
{
Q_OBJECT
public:
KisInternalColorSelector(QWidget* parent, const QString &caption);
~KisInternalColorSelector();
/**
* @brief setCanvas
* reimplemented from the canvasobserver class.
* @param canvas
*/
virtual void setCanvas(KisCanvas2 *canvas);
/**
* @brief unsetCanvas
* reimplemented from the canvas observer class.
*/
virtual void unsetCanvas();
Q_SIGNALS:
/**
* @brief signalForegroundColorChosen
* The most important signal. This will sent out when a color has been picked from the selector.
* There will be a small delay to make sure that the selector causes too many updates.
*
* Do not connect this to slotColorUpdated.
* @param color The new color chosen
*/
void signalForegroundColorChosen(KoColor color);
public Q_SLOTS:
/**
* @brief slotColorUpdated
* Very important slot. Is connected to krita's resources to make sure it has
* the currently active color. It's very important that this function is able to understand
* when the signal came from itself.
* @param newColor This is the new color.
*/
void slotColorUpdated(KoColor newColor);
private Q_SLOTS:
/**
* @brief slotLockSelector
* This slot will prevent the color from being updated.
*/
void slotLockSelector();
/**
* @brief slotColorSpaceChanged
* Color space has changed.
*/
void slotColorSpaceChanged(const KoColorSpace *cs);
/**
* @brief slotConfigurationChanged
* Wrapper slot for changes to the colorspace.
*/
void slotConfigurationChanged();
void endUpdateWithNewColor();
private:
Ui::WdgDlgInternalColorSelector *ui; //the UI
struct Private; //The private struct
const QScopedPointer<Private> m_d; //the private pointer
/**
* @brief updateAllElements
* Updates each widget with the new element, and if it's responsible for the update sents
* a signal out that there's a new color.
*/
void updateAllElements();
};
#endif // KISINTERNALCOLORSELECTOR_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WdgDlgInternalColorSelector</class>
<widget class="QDialog" name="WdgDlgInternalColorSelector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="base"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>WdgDlgInternalColorSelector</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>WdgDlgInternalColorSelector</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -83,7 +83,6 @@ KisOpenGLImageTextures::KisOpenGLImageTextures(KisImageWSP image,
, m_proofingTransform(0)
, m_createNewProofingTransform(true)
, m_tilesDestinationColorSpace(0)
, m_createNewProofingTransform(true)
, m_internalColorManagementActive(true)
, m_checkerTexture(0)
, m_glFuncs(0)
......
/*
* Copyright (C) Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>, (C) 2016
*
* 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 "kis_spinbox_color_selector.h"
#include <QFormLayout>
#include <QAbstractSpinBox>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include "kis_signal_compressor.h"
#include "KoChannelInfo.h"
#include "KoColorSpaceTraits.h"
#include "KoColorSpaceMaths.h"
#include "KoColorSpaceRegistry.h"
struct KisSpinboxColorSelector::Private
{
bool allowUpdates = false;
QList <QSpinBox*> spinBoxList;
QList <QDoubleSpinBox*> doubleSpinBoxList;
KoColor color;
const KoColorSpace *cs;
KisSignalCompressor *compressUpdates;
};
KisSpinboxColorSelector::KisSpinboxColorSelector(QWidget *parent) : QWidget(parent) , m_d(new Private)
{
QFormLayout *layout = new QFormLayout();
this->setLayout(layout);
m_d->compressUpdates = new KisSignalCompressor(500 /* ms */, KisSignalCompressor::POSTPONE, this);
connect(m_d->compressUpdates, SIGNAL(timeout()), this, SLOT(slotFinishUpdate()));
}
KisSpinboxColorSelector::~KisSpinboxColorSelector()
{
}
void KisSpinboxColorSelector::slotSetColor(KoColor color)
{
m_d->color = color;
}
void KisSpinboxColorSelector::slotSetColorSpace(const KoColorSpace *cs)
{
if (cs == m_d->cs) {
return;
}
m_d->cs = KoColorSpaceRegistry::instance()->colorSpace(cs->colorModelId().id(), cs->colorDepthId().id(), cs->profile());
//remake spinboxes
Q_FOREACH (QSpinBox *input, m_d->spinBoxList) {
this->layout()->removeWidget(input);
delete input;
}
m_d->spinBoxList.clear();
Q_FOREACH (QDoubleSpinBox *input, m_d->doubleSpinBoxList) {
this->layout()->removeWidget(input);
delete input;
}
m_d->doubleSpinBoxList.clear();
QList<KoChannelInfo *> channels = KoChannelInfo::displayOrderSorted(m_d->cs->channels());
Q_FOREACH (KoChannelInfo* channel, channels) {
if (channel->channelType() == KoChannelInfo::COLOR) {
switch (channel->channelValueType()) {
case KoChannelInfo::UINT8: {
QSpinBox *input = new QSpinBox(this);
input->setMinimum(0);
input->setMaximum(0xFF);
m_d->spinBoxList.append(input);
this->layout()->addWidget(input);
if (input) {
connect(input, SIGNAL(updated()), this, SLOT(updateFromSpinBoxes()));
}
}
break;
case KoChannelInfo::UINT16: {
QSpinBox *input = new QSpinBox(this);
input->setMinimum(0);
input->setMaximum(0xFFFF);
m_d->spinBoxList.append(input);
this->layout()->addWidget(input);
if (input) {
connect(input, SIGNAL(updated()), this, SLOT(updateFromSpinBoxes()));
}
}
break;
case KoChannelInfo::UINT32: {
QSpinBox *input = new QSpinBox(this);
input->setMinimum(0);
input->setMaximum(0xFFFFFFFF);
m_d->spinBoxList.append(input);
this->layout()->addWidget(input);
if (input) {
connect(input, SIGNAL(updated()), this, SLOT(updateFromSpinBoxes()));
}
}
break;
case KoChannelInfo::FLOAT16:
case KoChannelInfo::FLOAT32: {
QDoubleSpinBox *input = new QDoubleSpinBox(this);
input->setMinimum(0);
input->setMaximum(1.0);
m_d->doubleSpinBoxList.append(input);
this->layout()->addWidget(input);
if (input) {
connect(input, SIGNAL(updated()), this, SLOT(updateFromSpinBoxes()));
}
}
break;
default:
Q_ASSERT(false);
}
}
}
}
void KisSpinboxColorSelector::createColorFromSpinboxValues()
{
KoColor newColor;
int channelcount = m_d->cs->channelCount();
quint8 *data;
QVector <float> channelValues(channelcount);
channelValues.fill(1.0);
QList<KoChannelInfo *> channels = KoChannelInfo::displayOrderSorted(m_d->cs->channels());
for (int i=0; i<channelcount; i++) {
if (m_d->spinBoxList.at(i)) {
if (channels.at(i)->channelValueType()==KoChannelInfo::UINT8){
channelValues[i] = KoColorSpaceMaths<quint8,float>::scaleToA(m_d->spinBoxList.at(i)->value());
} else if (channels.at(i)->channelValueType()==KoChannelInfo::UINT16){
channelValues[i] = KoColorSpaceMaths<quint16,float>::scaleToA(m_d->spinBoxList.at(i)->value());
}
} else if (m_d->doubleSpinBoxList.at(i)){
channelValues[i] = m_d->doubleSpinBoxList.at(i)->value();
}
}
m_d->cs->fromNormalisedChannelsValue(data, channelValues);
newColor.setColor(data, m_d->cs);
newColor.setOpacity(m_d->color.opacityU8());
m_d->color = newColor;
}
void KisSpinboxColorSelector::slotUpdateFromSpinBoxes()
{
m_d->allowUpdates = false;
createColorFromSpinboxValues();
emit sigNewColor(m_d->color);
m_d->compressUpdates->start();
}
void KisSpinboxColorSelector::slotFinishUpdate()
{
m_d->allowUpdates = true;
}
void KisSpinboxColorSelector::updateSpinboxesWithNewValues()
{
int channelcount = m_d->cs->channelCount();
QVector <float> channelValues(channelcount);
channelValues.fill(1.0);
m_d->cs->normalisedChannelsValue(m_d->color.data(), channelValues);
QList<KoChannelInfo *> channels = KoChannelInfo::displayOrderSorted(m_d->cs->channels());
for (int i=0; i<channelcount; i++) {
if (m_d->spinBoxList.at(i)) {
if (channels.at(i)->channelValueType() == KoChannelInfo::UINT8) {
m_d->spinBoxList.at(i)->setValue(KoColorSpaceMaths<float, quint8>::scaleToA(channelValues[i]));
} else if (channels.at(i)->channelValueType() == KoChannelInfo::UINT16) {
m_d->spinBoxList.at(i)->setValue(KoColorSpaceMaths<float, quint16>::scaleToA(channelValues[i]));
}
} else if (m_d->doubleSpinBoxList.at(i)) {
m_d->doubleSpinBoxList.at(i)->setValue(channelValues[i]);
}
}
}
/*
* Copyright (C) Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>, (C) 2016
*
* 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 KISSPINBOXCOLORSELECTOR_H
#define KISSPINBOXCOLORSELECTOR_H
#include <QWidget>
#include "kritaui_export.h"
#include <QScopedPointer>
#include "KoColor.h"
#include "KoColorSpace.h"
/**
* @brief The KisSpinboxColorSelector class
* This will give a widget with spinboxes depending on the color space
* Take responsibility for changing the color space.
*/
class KRITAUI_EXPORT KisSpinboxColorSelector : public QWidget
{
Q_OBJECT
public:
explicit KisSpinboxColorSelector(QWidget *parent = 0);
~KisSpinboxColorSelector();
Q_SIGNALS:
void sigNewColor(KoColor color);
public Q_SLOTS:
void slotSetColorSpace(const KoColorSpace *cs);
void slotSetColor(KoColor color);
private Q_SLOTS:
void slotUpdateFromSpinBoxes();
void slotFinishUpdate();
private:
struct Private;
const QScopedPointer<Private> m_d;
void createColorFromSpinboxValues();
void updateSpinboxesWithNewValues();
};
#endif // KISSPINBOXCOLORSELECTOR_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment