1 /*******************************************************************************************************
2  nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
3 
4  Copyright (C) 2011-2016 Markus Diem <markus@nomacs.org>
5  Copyright (C) 2011-2016 Stefan Fiel <stefan@nomacs.org>
6  Copyright (C) 2011-2016 Florian Kleber <florian@nomacs.org>
7 
8  This file is part of nomacs.
9 
10  nomacs is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  nomacs is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 
23  related links:
24  [1] https://nomacs.org/
25  [2] https://github.com/nomacs/
26  [3] http://download.nomacs.org
27  *******************************************************************************************************/
28 
29 #include "DkManipulatorWidgets.h"
30 #include "DkActionManager.h"
31 #include "DkWidgets.h"
32 #include "DkTimer.h"
33 #include "DkUtils.h"
34 #include "DkSettings.h"
35 #include "DkImageStorage.h"
36 #include "DkBasicWidgets.h"
37 #include "DkManipulatorsIpl.h"
38 
39 #pragma warning(push, 0)	// no warnings from includes
40 #include <QVBoxLayout>
41 #include <QLabel>
42 #include <QButtonGroup>
43 #include <QCheckBox>
44 #include <QComboBox>
45 #pragma warning(pop)
46 
47 namespace nmc {
48 
49 // DkManipulatorWidget --------------------------------------------------------------------
DkManipulatorWidget(QWidget * parent)50 DkManipulatorWidget::DkManipulatorWidget(QWidget* parent) : DkFadeWidget(parent) {
51 
52 	// create widgets
53 	DkActionManager& am = DkActionManager::instance();
54 	mWidgets << new DkTinyPlanetWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_tiny_planet), this);
55 	mWidgets << new DkBlurWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_blur), this);
56 	mWidgets << new DkUnsharpMaskWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_unsharp_mask), this);
57 	mWidgets << new DkRotateWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_rotate), this);
58 	mWidgets << new DkResizeWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_resize), this);
59 	mWidgets << new DkThresholdWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_threshold), this);
60 	mWidgets << new DkHueWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_hue), this);
61 	mWidgets << new DkColorWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_color), this);
62 	mWidgets << new DkExposureWidget(am.manipulatorManager().manipulatorExt(DkManipulatorManager::m_exposure), this);
63 
64 	setObjectName("DkPreferenceTabs");
65 	createLayout();
66 
67 	for (QWidget* w : mWidgets)
68 		w->setObjectName("darkManipulator");
69 
70 	for (QAction* a : am.manipulatorActions())
71 		connect(a, SIGNAL(triggered()), this, SLOT(selectManipulator()), Qt::UniqueConnection);
72 }
73 
createLayout()74 void DkManipulatorWidget::createLayout() {
75 
76 	// actions
77 	QWidget* actionWidget = new QWidget(this);
78 	QVBoxLayout* aLayout = new QVBoxLayout(actionWidget);
79 	aLayout->setAlignment(Qt::AlignTop);
80 	aLayout->setContentsMargins(0, 0, 0, 0);
81 	aLayout->setSpacing(0);
82 
83 	QButtonGroup* group = new QButtonGroup(this);
84 
85 	DkActionManager& am = DkActionManager::instance();
86 	//for (QAction* a : am.manipulatorActions()) {	// if you want to get all
87 	for (int idx = DkManipulatorManager::m_end; idx < DkManipulatorManager::m_ext_end; idx++) {
88 
89 		auto mpl = am.manipulatorManager().manipulatorExt((DkManipulatorManager::ManipulatorExtId)idx);
90 
91 		DkTabEntryWidget* entry = new DkTabEntryWidget(mpl->action()->icon(), mpl->name(), this);
92 		connect(entry, SIGNAL(clicked()), mpl->action(), SIGNAL(triggered()), Qt::UniqueConnection);
93 
94 		aLayout->addWidget(entry);
95 		group->addButton(entry);
96 	}
97 
98 	QString scrollbarStyle =
99 		QString("QScrollBar:vertical {border: 1px solid " + DkUtils::colorToString(DkSettingsManager::param().display().hudFgdColor) + "; background: rgba(0,0,0,0); width: 7px; margin: 0 0 0 0;}")
100 		+ QString("QScrollBar::handle:vertical {background: " + DkUtils::colorToString(DkSettingsManager::param().display().hudFgdColor) + "; min-height: 0px;}")
101 		+ QString("QScrollBar::add-line:vertical {height: 0px;}")
102 		+ QString("QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: rgba(0,0,0,0); width: 1px;}")
103 		+ QString("QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {height: 0;}");
104 
105 	QScrollArea* actionScroller = new QScrollArea(this);
106 	actionScroller->setStyleSheet(scrollbarStyle + actionScroller->styleSheet());
107 	actionScroller->setWidgetResizable(true);
108 	actionScroller->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
109 	actionScroller->setWidget(actionWidget);
110 	actionScroller->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
111 
112 	// preview
113 	mTitleLabel = new QLabel(this);
114 	mTitleLabel->setObjectName("DkManipulatorSettingsTitle");
115 	mPreview = new QLabel(this);
116 	mPreview->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
117 
118 	// undo
119 	QPixmap pm = DkImage::colorizePixmap(QIcon(":/nomacs/img/rotate-cc.svg").pixmap(QSize(32, 32)), QColor(255, 255, 255));
120 	QPushButton* undoButton = new QPushButton(pm, "", this);
121 	undoButton->setFlat(true);
122 	undoButton->setIconSize(QSize(32, 32));
123 	undoButton->setObjectName("DkRestartButton");
124 	undoButton->setStatusTip(tr("Undo"));
125 	connect(undoButton, SIGNAL(clicked()), am.action(DkActionManager::menu_edit_undo), SIGNAL(triggered()));
126 
127 	pm = DkImage::colorizePixmap(QIcon(":/nomacs/img/rotate-cw.svg").pixmap(QSize(32, 32)), QColor(255, 255, 255));
128 	QPushButton* redoButton = new QPushButton(pm, "", this);
129 	redoButton->setFlat(true);
130 	redoButton->setIconSize(QSize(32, 32));
131 	redoButton->setObjectName("DkRestartButton");
132 	redoButton->setStatusTip(tr("Redo"));
133 	connect(redoButton, SIGNAL(clicked()), am.action(DkActionManager::menu_edit_redo), SIGNAL(triggered()));
134 
135 	QWidget* buttonWidget = new QWidget(this);
136 	QHBoxLayout* buttonLayout = new QHBoxLayout(buttonWidget);
137 	buttonLayout->setContentsMargins(0, 0, 0, 0);
138 	buttonLayout->addWidget(undoButton);
139 	buttonLayout->addWidget(redoButton);
140 
141 	QWidget* mplWidget = new QWidget(this);
142 	QVBoxLayout* mplLayout = new QVBoxLayout(mplWidget);
143 	mplLayout->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
144 	mplLayout->addWidget(mTitleLabel);
145 	for (QWidget* w : mWidgets)
146 		mplLayout->addWidget(w);
147 	mplLayout->addWidget(mPreview);
148 	mplLayout->addWidget(buttonWidget);
149 
150 	QVBoxLayout* layout = new QVBoxLayout(this);
151 	layout->setContentsMargins(0, 0, 0, 0);
152 	layout->addWidget(actionScroller);
153 	layout->addWidget(mplWidget);
154 }
155 
scaledPreview(const QImage & img) const156 QImage DkManipulatorWidget::scaledPreview(const QImage& img) const {
157 
158 	QImage imgR;
159 
160 	if (img.height() > img.width())
161 		imgR = img.scaledToHeight(qMin(img.height(), mMaxPreview));
162 	else
163 		imgR = img.scaledToWidth(qMin(img.width(), mMaxPreview));
164 
165 	return imgR;
166 }
167 
setImage(QSharedPointer<DkImageContainerT> imgC)168 void DkManipulatorWidget::setImage(QSharedPointer<DkImageContainerT> imgC) {
169 	mImgC = imgC;
170 
171 	if (mImgC) {
172 
173 		QImage img = mImgC->imageScaledToWidth(qMin(mPreview->width(), mMaxPreview));
174 		img = scaledPreview(img);
175 
176 		mPreview->setPixmap(QPixmap::fromImage(img));
177 		mPreview->show();
178 	}
179 	else
180 		mPreview->hide();
181 }
182 
selectManipulator()183 void DkManipulatorWidget::selectManipulator() {
184 
185 	QAction* action = dynamic_cast<QAction*>(QObject::sender());
186 
187 	DkActionManager& am = DkActionManager::instance();
188 	QSharedPointer<DkBaseManipulator> mpl = am.manipulatorManager().manipulator(action);
189 	QSharedPointer<DkBaseManipulatorExt> mplExt = qSharedPointerDynamicCast<DkBaseManipulatorExt>(mpl);
190 
191 	// compute preview
192 	if (mpl && mImgC) {
193 		DkTimer dt;
194 		QImage img = mpl->apply(mImgC->imageScaledToWidth(qMin(mPreview->width(), mMaxPreview)));
195 		img = scaledPreview(img);
196 
197 		if (!img.isNull())
198 			mPreview->setPixmap(QPixmap::fromImage(img));
199 		qDebug() << "preview computed in " << dt;
200 	}
201 
202 	for (QWidget* w : mWidgets)
203 		w->hide();
204 
205 	if (!mplExt) {
206 		mTitleLabel->hide();
207 		return;
208 	}
209 
210 	if (!mplExt->widget()) {
211 		qCritical() << action->text() << "does not have a corresponding UI";
212 		return;
213 	}
214 
215 	mplExt->widget()->show();
216 	mTitleLabel->setText(mpl->name());
217 }
218 
219 // DkMainpulatorDoc --------------------------------------------------------------------
DkEditDock(const QString & title,QWidget * parent,Qt::WindowFlags flags)220 DkEditDock::DkEditDock(const QString& title, QWidget* parent, Qt::WindowFlags flags) : DkDockWidget(title, parent, flags) {
221 
222 	setObjectName("DkEditDock");
223 	createLayout();
224 }
225 
createLayout()226 void DkEditDock::createLayout() {
227 
228 	mMplWidget = new DkManipulatorWidget(this);
229 	setWidget(mMplWidget);
230 }
231 
setImage(QSharedPointer<DkImageContainerT> imgC)232 void DkEditDock::setImage(QSharedPointer<DkImageContainerT> imgC) {
233 	mMplWidget->setImage(imgC);
234 }
235 
236 // DkManipulatorWidget --------------------------------------------------------------------
DkBaseManipulatorWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)237 DkBaseManipulatorWidget::DkBaseManipulatorWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkFadeWidget(parent) {
238 	mBaseManipulator = manipulator;
239 }
240 
baseManipulator() const241 QSharedPointer<DkBaseManipulatorExt> DkBaseManipulatorWidget::baseManipulator() const {
242 	return mBaseManipulator;
243 }
244 
245 // DkTinyPlanetWidget --------------------------------------------------------------------
DkTinyPlanetWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)246 DkTinyPlanetWidget::DkTinyPlanetWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
247 	createLayout();
248 	QMetaObject::connectSlotsByName(this);
249 
250 	manipulator->setWidget(this);
251 }
252 
createLayout()253 void DkTinyPlanetWidget::createLayout() {
254 
255 	// post processing sliders
256 	DkSlider* scaleSlider = new DkSlider(tr("Planet Size"), this);
257 	scaleSlider->setObjectName("scaleSlider");
258 	scaleSlider->setMinimum(1);
259 	scaleSlider->setMaximum(1000);
260 	scaleSlider->setValue(manipulator()->size());
261 
262 	DkSlider* angleSlider = new DkSlider(tr("Angle"), this);
263 	angleSlider->setObjectName("angleSlider");
264 	angleSlider->setValue(manipulator()->angle());
265 	angleSlider->setMinimum(-180);
266 	angleSlider->setMaximum(179);
267 
268 	QCheckBox* invertBox = new QCheckBox(tr("Invert Planet"), this);
269 	invertBox->setObjectName("invertBox");
270 	invertBox->setChecked(manipulator()->inverted());
271 
272 	QVBoxLayout* sliderLayout = new QVBoxLayout(this);
273 	sliderLayout->addWidget(scaleSlider);
274 	sliderLayout->addWidget(angleSlider);
275 	sliderLayout->addWidget(invertBox);
276 }
277 
on_scaleSlider_valueChanged(int val)278 void DkTinyPlanetWidget::on_scaleSlider_valueChanged(int val) {
279 	manipulator()->setSize(val);
280 }
281 
on_angleSlider_valueChanged(int val)282 void DkTinyPlanetWidget::on_angleSlider_valueChanged(int val) {
283 	manipulator()->setAngle(val);
284 }
285 
on_invertBox_toggled(bool val)286 void DkTinyPlanetWidget::on_invertBox_toggled(bool val) {
287 	manipulator()->setInverted(val);
288 }
289 
manipulator() const290 QSharedPointer<DkTinyPlanetManipulator> DkTinyPlanetWidget::manipulator() const {
291 	return qSharedPointerDynamicCast<DkTinyPlanetManipulator>(baseManipulator());
292 }
293 
294 // DkBlurWidget --------------------------------------------------------------------
DkBlurWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)295 DkBlurWidget::DkBlurWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
296 
297 	createLayout();
298 	QMetaObject::connectSlotsByName(this);
299 
300 	manipulator->setWidget(this);
301 }
302 
createLayout()303 void DkBlurWidget::createLayout() {
304 
305 	// post processing sliders
306 	DkSlider* sigmaSlider = new DkSlider(tr("Sigma"), this);
307 	sigmaSlider->setObjectName("sigmaSlider");
308 	sigmaSlider->setValue(manipulator()->sigma());
309 	sigmaSlider->setMaximum(50);
310 
311 	QVBoxLayout* sliderLayout = new QVBoxLayout(this);
312 	sliderLayout->addWidget(sigmaSlider);
313 }
314 
on_sigmaSlider_valueChanged(int val)315 void DkBlurWidget::on_sigmaSlider_valueChanged(int val) {
316 	manipulator()->setSigma(val);
317 }
318 
manipulator() const319 QSharedPointer<DkBlurManipulator> DkBlurWidget::manipulator() const {
320 	return qSharedPointerDynamicCast<DkBlurManipulator>(baseManipulator());
321 }
322 
323 // DkUnsharpMaskWidget --------------------------------------------------------------------
DkUnsharpMaskWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)324 DkUnsharpMaskWidget::DkUnsharpMaskWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
325 	createLayout();
326 	QMetaObject::connectSlotsByName(this);
327 
328 	manipulator->setWidget(this);
329 }
330 
createLayout()331 void DkUnsharpMaskWidget::createLayout() {
332 
333 	// post processing sliders
334 	DkSlider* sigmaSlider = new DkSlider(tr("Sigma"), this);
335 	sigmaSlider->setObjectName("sigmaSlider");
336 	sigmaSlider->setValue(manipulator()->sigma());
337 	//darkenSlider->hide();
338 
339 	DkSlider* amountSlider = new DkSlider(tr("Amount"), this);
340 	amountSlider->setObjectName("amountSlider");
341 	amountSlider->setValue(manipulator()->amount());
342 
343 	QVBoxLayout* sliderLayout = new QVBoxLayout(this);
344 	sliderLayout->addWidget(sigmaSlider);
345 	sliderLayout->addWidget(amountSlider);
346 }
347 
on_sigmaSlider_valueChanged(int val)348 void DkUnsharpMaskWidget::on_sigmaSlider_valueChanged(int val) {
349 	manipulator()->setSigma(val);
350 }
351 
on_amountSlider_valueChanged(int val)352 void DkUnsharpMaskWidget::on_amountSlider_valueChanged(int val) {
353 	manipulator()->setAmount(val);
354 }
355 
manipulator() const356 QSharedPointer<DkUnsharpMaskManipulator> DkUnsharpMaskWidget::manipulator() const {
357 	return qSharedPointerDynamicCast<DkUnsharpMaskManipulator>(baseManipulator());
358 }
359 
360 // DkRotateWidget --------------------------------------------------------------------
DkRotateWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)361 DkRotateWidget::DkRotateWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
362 	createLayout();
363 	QMetaObject::connectSlotsByName(this);
364 
365 	manipulator->setWidget(this);
366 }
367 
manipulator() const368 QSharedPointer<DkRotateManipulator> DkRotateWidget::manipulator() const {
369 	return qSharedPointerDynamicCast<DkRotateManipulator>(baseManipulator());
370 }
371 
createLayout()372 void DkRotateWidget::createLayout() {
373 
374 	DkSlider* angleSlider = new DkSlider(tr("Angle"), this);
375 	angleSlider->setObjectName("angleSlider");
376 	angleSlider->setValue(manipulator()->angle());
377 	angleSlider->setMinimum(-180);
378 	angleSlider->setMaximum(180);
379 
380 	QVBoxLayout* sliderLayout = new QVBoxLayout(this);
381 	sliderLayout->addWidget(angleSlider);
382 }
383 
on_angleSlider_valueChanged(int val)384 void DkRotateWidget::on_angleSlider_valueChanged(int val) {
385 	manipulator()->setAngle(val);
386 }
387 
388 // DkRotateWidget --------------------------------------------------------------------
DkResizeWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)389 DkResizeWidget::DkResizeWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
390 	createLayout();
391 	QMetaObject::connectSlotsByName(this);
392 
393 	manipulator->setWidget(this);
394 
395 	// I would have loved setObjectName to be virtual : )
396 	connect(this, SIGNAL(objectNameChanged(const QString&)), this, SLOT(onObjectNameChanged(const QString&)));
397 }
398 
manipulator() const399 QSharedPointer<DkResizeManipulator> DkResizeWidget::manipulator() const {
400 	return qSharedPointerDynamicCast<DkResizeManipulator>(baseManipulator());
401 }
402 
onObjectNameChanged(const QString & name)403 void DkResizeWidget::onObjectNameChanged(const QString & name) {
404 
405 	if (name == "darkManipulator") {
406 		// this is a hack: if we don't do this, nmc--DkBaseManipulatorWidget#darkManipulator QComboBox QAbstractItemView get's applied
407 		// I have the feeling, that this is a Qt issue
408 		// without this line, all styles are applied to the QComboBox but not to its drop down list (QAbstractItemView)
409 		mIplBox->setStyleSheet(mIplBox->styleSheet() + " ");
410 	}
411 }
412 
createLayout()413 void DkResizeWidget::createLayout() {
414 
415 	DkDoubleSlider* scaleSlider = new DkDoubleSlider(tr("Scale"), this);
416 	scaleSlider->setObjectName("scaleFactorSlider");
417 	scaleSlider->setMinimum(0.1);
418 	scaleSlider->setCenterValue(1.0);
419 	scaleSlider->setMaximum(10);
420 	scaleSlider->setValue(manipulator()->scaleFactor());
421 
422 	mIplBox = new QComboBox(this);
423 	mIplBox->setObjectName("iplBox");
424 	mIplBox->setView(new QListView());	// needed for style
425 	mIplBox->addItem(tr("Nearest Neighbor"), DkImage::ipl_nearest);
426 	mIplBox->addItem(tr("Area (best for downscaling)"), DkImage::ipl_area);
427 	mIplBox->addItem(tr("Linear"), DkImage::ipl_linear);
428 	mIplBox->addItem(tr("Bicubic (4x4 interpolatia)"), DkImage::ipl_cubic);
429 	mIplBox->addItem(tr("Lanczos (8x8 interpolation)"), DkImage::ipl_lanczos);
430 	mIplBox->setCurrentIndex(1);
431 
432 	QCheckBox* cbGamma = new QCheckBox(tr("Gamma Correction"), this);
433 	cbGamma->setObjectName("gammaCorrection");
434 
435 	QVBoxLayout* sliderLayout = new QVBoxLayout(this);
436 	sliderLayout->setSpacing(10);
437 	sliderLayout->addWidget(scaleSlider);
438 	sliderLayout->addWidget(mIplBox);
439 	sliderLayout->addWidget(cbGamma);
440 }
441 
on_scaleFactorSlider_valueChanged(double val)442 void DkResizeWidget::on_scaleFactorSlider_valueChanged(double val) {
443 	manipulator()->setScaleFactor(val);
444 }
445 
on_iplBox_currentIndexChanged(int idx)446 void DkResizeWidget::on_iplBox_currentIndexChanged(int idx) {
447 	manipulator()->setInterpolation(mIplBox->itemData(idx).toInt());
448 }
449 
on_gammaCorrection_toggled(bool checked)450 void DkResizeWidget::on_gammaCorrection_toggled(bool checked) {
451 	manipulator()->setCorrectGamma(checked);
452 }
453 
454 // DkThresholdWidget --------------------------------------------------------------------
DkThresholdWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)455 DkThresholdWidget::DkThresholdWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
456 	createLayout();
457 	QMetaObject::connectSlotsByName(this);
458 
459 	manipulator->setWidget(this);
460 }
461 
manipulator() const462 QSharedPointer<DkThresholdManipulator> DkThresholdWidget::manipulator() const {
463 	return qSharedPointerDynamicCast<DkThresholdManipulator>(baseManipulator());
464 }
465 
on_colBox_toggled(bool checked)466 void DkThresholdWidget::on_colBox_toggled(bool checked) {
467 	manipulator()->setColor(checked);
468 }
469 
createLayout()470 void DkThresholdWidget::createLayout() {
471 
472 	DkSlider* thrSlider = new DkSlider(tr("Threshold"), this);
473 	thrSlider->setObjectName("thrSlider");
474 	thrSlider->setValue(manipulator()->threshold());
475 	thrSlider->setMinimum(0);
476 	thrSlider->setMaximum(255);
477 	thrSlider->setValue(manipulator()->threshold());
478 
479 	QCheckBox* colBox = new QCheckBox(tr("Color"), this);
480 	colBox->setObjectName("colBox");
481 	colBox->setChecked(manipulator()->color());
482 
483 	QVBoxLayout* layout = new QVBoxLayout(this);
484 	layout->addWidget(thrSlider);
485 	layout->addWidget(colBox);
486 }
on_thrSlider_valueChanged(int val)487 void DkThresholdWidget::on_thrSlider_valueChanged(int val) {
488 	manipulator()->setThreshold(val);
489 }
490 
491 // -------------------------------------------------------------------- DkColorWidget
DkColorWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)492 DkColorWidget::DkColorWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
493 	createLayout();
494 
495 	QMetaObject::connectSlotsByName(this);
496 
497 	manipulator->setWidget(this);
498 	setMinimumHeight(150);
499 }
500 
manipulator() const501 QSharedPointer<DkColorManipulator> DkColorWidget::manipulator() const {
502 	return qSharedPointerDynamicCast<DkColorManipulator>(baseManipulator());
503 }
504 
createLayout()505 void DkColorWidget::createLayout() {
506 
507 	DkColorPicker* cp = new DkColorPicker(this);
508 	cp->setObjectName("colPicker");
509 
510 	QVBoxLayout* l = new QVBoxLayout(this);
511 	l->setContentsMargins(0, 0, 0, 0);
512 	l->addWidget(cp);
513 }
514 
on_colPicker_colorSelected(const QColor & col)515 void DkColorWidget::on_colPicker_colorSelected(const QColor& col) {
516 	manipulator()->setColor(col);
517 }
518 
519 // DkHueWidget --------------------------------------------------------------------
DkHueWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)520 DkHueWidget::DkHueWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
521 	createLayout();
522 	QMetaObject::connectSlotsByName(this);
523 
524 	manipulator->setWidget(this);
525 }
526 
527 
manipulator() const528 QSharedPointer<DkHueManipulator> DkHueWidget::manipulator() const {
529 	return qSharedPointerDynamicCast<DkHueManipulator>(baseManipulator());
530 }
531 
createLayout()532 void DkHueWidget::createLayout() {
533 
534 	DkSlider* hueSlider = new DkSlider(tr("Hue"), this);
535 	hueSlider->setObjectName("hueSlider");
536 	hueSlider->getSlider()->setObjectName("DkHueSlider");
537 	hueSlider->setValue(manipulator()->hue());
538 	hueSlider->setMinimum(-180);
539 	hueSlider->setMaximum(180);
540 
541 	DkSlider* satSlider = new DkSlider(tr("Saturation"), this);
542 	satSlider->setObjectName("satSlider");
543 	satSlider->getSlider()->setObjectName("DkSaturationSlider");
544 	satSlider->setValue(manipulator()->saturation());
545 	satSlider->setMinimum(-100);
546 	satSlider->setMaximum(100);
547 
548 	DkSlider* brightnessSlider = new DkSlider(tr("Brightness"), this);
549 	brightnessSlider->setObjectName("brightnessSlider");
550 	brightnessSlider->getSlider()->setObjectName("DkBrightnessSlider");
551 	brightnessSlider->setValue(manipulator()->hue());
552 	brightnessSlider->setMinimum(-100);
553 	brightnessSlider->setMaximum(100);
554 
555 	QVBoxLayout* sliderLayout = new QVBoxLayout(this);
556 	sliderLayout->addWidget(hueSlider);
557 	sliderLayout->addWidget(satSlider);
558 	sliderLayout->addWidget(brightnessSlider);
559 }
560 
on_hueSlider_valueChanged(int val)561 void DkHueWidget::on_hueSlider_valueChanged(int val) {
562 	manipulator()->setHue(val);
563 }
564 
on_satSlider_valueChanged(int val)565 void DkHueWidget::on_satSlider_valueChanged(int val) {
566 	manipulator()->setSaturation(val);
567 }
568 
on_brightnessSlider_valueChanged(int val)569 void DkHueWidget::on_brightnessSlider_valueChanged(int val) {
570 	manipulator()->setValue(val);
571 }
572 
573 // DkExposureWidget --------------------------------------------------------------------
DkExposureWidget(QSharedPointer<DkBaseManipulatorExt> manipulator,QWidget * parent)574 DkExposureWidget::DkExposureWidget(QSharedPointer<DkBaseManipulatorExt> manipulator, QWidget* parent) : DkBaseManipulatorWidget(manipulator, parent) {
575 	createLayout();
576 	QMetaObject::connectSlotsByName(this);
577 
578 	manipulator->setWidget(this);
579 }
580 
manipulator() const581 QSharedPointer<DkExposureManipulator> DkExposureWidget::manipulator() const {
582 	return qSharedPointerDynamicCast<DkExposureManipulator>(baseManipulator());
583 }
584 
createLayout()585 void DkExposureWidget::createLayout() {
586 
587 	DkDoubleSlider* exposureSlider = new DkDoubleSlider(tr("Exposure"), this);
588 	exposureSlider->setObjectName("exposureSlider");
589 	exposureSlider->setMinimum(-3);
590 	exposureSlider->setMaximum(3);
591 	exposureSlider->setTickInterval(0.0005);
592 	exposureSlider->setValue(manipulator()->exposure());
593 
594 	DkDoubleSlider* offsetSlider = new DkDoubleSlider(tr("Offset"), this);
595 	offsetSlider->setObjectName("offsetSlider");
596 	offsetSlider->setMinimum(-0.5);
597 	offsetSlider->setMaximum(0.5);
598 	offsetSlider->setTickInterval(0.001);
599 	offsetSlider->setValue(manipulator()->offset());
600 
601 	DkDoubleSlider* gammaSlider = new DkDoubleSlider(tr("Gamma"), this);
602 	gammaSlider->setObjectName("gammaSlider");
603 	gammaSlider->setMinimum(0);
604 	gammaSlider->setCenterValue(1);
605 	gammaSlider->setMaximum(10);
606 	gammaSlider->setTickInterval(0.001);
607 	gammaSlider->setSliderInverted(true);
608 	gammaSlider->setValue(manipulator()->gamma());
609 
610 	QVBoxLayout* sliderLayout = new QVBoxLayout(this);
611 	sliderLayout->addWidget(exposureSlider);
612 	sliderLayout->addWidget(offsetSlider);
613 	sliderLayout->addWidget(gammaSlider);
614 }
615 
on_exposureSlider_valueChanged(double val)616 void DkExposureWidget::on_exposureSlider_valueChanged(double val) {
617 
618 	double tv = val*val;
619 	if (val < 0)
620 		tv *= -1.0;
621 	manipulator()->setExposure(tv);
622 }
623 
on_offsetSlider_valueChanged(double val)624 void DkExposureWidget::on_offsetSlider_valueChanged(double val) {
625 	manipulator()->setOffset(val);
626 }
627 
on_gammaSlider_valueChanged(double val)628 void DkExposureWidget::on_gammaSlider_valueChanged(double val) {
629 	manipulator()->setGamma(val);
630 }
631 
632 }