24#include <QButtonGroup>
31#include <klocalizedstring.h>
54#include "ui_KoStrokeConfigWidget.h"
78 QGridLayout *mainLayout =
new QGridLayout(
this);
79 mainLayout->setContentsMargins(2, 2, 2, 2);
87 button =
new QToolButton(
this);
89 button->setCheckable(
true);
90 button->setToolTip(i18n(
"Butt cap"));
92 mainLayout->addWidget(
button, 2, 0);
94 button =
new QToolButton(
this);
96 button->setCheckable(
true);
97 button->setToolTip(i18n(
"Round cap"));
99 mainLayout->addWidget(
button, 2, 1);
101 button =
new QToolButton(
this);
103 button->setCheckable(
true);
104 button->setToolTip(i18n(
"Square cap"));
106 mainLayout->addWidget(
button, 2, 2, Qt::AlignLeft);
112 button =
new QToolButton(
this);
114 button->setCheckable(
true);
115 button->setToolTip(i18n(
"Miter join"));
117 mainLayout->addWidget(
button, 3, 0);
119 button =
new QToolButton(
this);
121 button->setCheckable(
true);
122 button->setToolTip(i18n(
"Round join"));
124 mainLayout->addWidget(
button, 3, 1);
126 button =
new QToolButton(
this);
128 button->setCheckable(
true);
129 button->setToolTip(i18n(
"Bevel join"));
131 mainLayout->addWidget(
button, 3, 2, Qt::AlignLeft);
140 mainLayout->addWidget(
miterLimit, 4, 0, 1, 3);
142 mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
147 return layout()->sizeHint();
172 bool allowLocalUnitManagement {
false};
175 bool noSelectionTrackingMode {
false};
183 QScopedPointer<Ui_KoStrokeConfigWidget>
ui;
192 d->ui.reset(
new Ui_KoStrokeConfigWidget());
193 d->ui->setupUi(
this);
195 setObjectName(
"Stroke widget");
198 d->shapeChangedAcyclicConnector.connectBackwardVoid(
200 &
d->selectionChangedCompressor, SLOT(start()));
202 d->shapeChangedAcyclicConnector.connectBackwardVoid(
204 &
d->selectionChangedCompressor, SLOT(start()));
208 d->resourceManagerAcyclicConnector.connectBackwardResourcePair(
218 d->fillConfigWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
219 d->ui->fillConfigWidgetLayout->addWidget(
d->fillConfigWidget);
223 d->ui->thicknessLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
224 d->ui->thicknessLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
227 d->ui->lineWidth->preventDecimalsChangeFromUnitManager(
true);
233 d->ui->lineWidth->setMinMaxStep(0.03, 240.0, 0.01);
234 d->ui->lineWidth->setDecimals(2);
235 d->ui->lineWidth->setToolTip(i18n(
"Set line width of actual selection"));
237 d->ui->capNJoinButton->setMinimumHeight(25);
239 d->ui->capNJoinButton->setMenu(
d->capNJoinMenu);
240 d->ui->capNJoinButton->setText(
"...");
241 d->ui->capNJoinButton->setPopupMode(QToolButton::InstantPopup);
246 d->ui->strokeStyleLabel->setText(i18n(
"Line Style:"));
247 d->ui->strokeStyleLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
249 d->ui->lineStyle->setToolTip(i18nc(
"@info:tooltip",
"Line style"));
250 d->ui->lineStyle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
260 d->startMarkerSelector->setToolTip(i18nc(
"@info:tooltip",
"Start marker"));
261 d->startMarkerSelector->updateMarkers(emptyMarkers);
262 d->startMarkerSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred );
263 d->ui->markerLayout->addWidget(
d->startMarkerSelector);
267 d->midMarkerSelector->setToolTip(i18nc(
"@info:tooltip",
"Node marker"));
268 d->midMarkerSelector->updateMarkers(emptyMarkers);
269 d->midMarkerSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred );
270 d->ui->markerLayout->addWidget(
d->midMarkerSelector);
274 d->endMarkerSelector->setToolTip(i18nc(
"@info:tooltip",
"End marker"));
275 d->endMarkerSelector->updateMarkers(emptyMarkers);
276 d->endMarkerSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred );
278 d->ui->markerLayout->addWidget(
d->endMarkerSelector);
282 d->spacer =
new QWidget();
283 d->spacer->setObjectName(
"SpecialSpacer");
285 d->ui->markerLayout->addWidget(
d->spacer);
298 connect(
d->startMarkerSelector, SIGNAL(currentIndexChanged(
int)), mapper, SLOT(map()));
299 connect(
d->midMarkerSelector, SIGNAL(currentIndexChanged(
int)), mapper, SLOT(map()));
300 connect(
d->endMarkerSelector, SIGNAL(currentIndexChanged(
int)), mapper, SLOT(map()));
308 if (resourceManager) {
315 d->selectionChangedCompressor.start();
329 d->fillConfigWidget->setNoSelectionTrackingMode(
value);
330 d->noSelectionTrackingMode =
value;
331 if (!
d->noSelectionTrackingMode) {
332 d->selectionChangedCompressor.start();
342 return d->ui->lineStyle->lineStyle();
347 return d->ui->lineStyle->lineDashes();
352 return d->ui->lineWidth->value();
357 return d->capNJoinMenu->miterLimit->value();
362 return d->startMarkerSelector->marker();
367 return d->endMarkerSelector->marker();
372 return static_cast<Qt::PenCapStyle
>(
d->capNJoinMenu->capGroup->checkedId());
377 return static_cast<Qt::PenJoinStyle
>(
d->capNJoinMenu->joinGroup->checkedId());
398 d->ui->lineWidth->setEnabled(enabled);
399 d->capNJoinMenu->setEnabled(enabled);
400 d->ui->lineStyle->setEnabled(enabled);
402 d->startMarkerSelector->setEnabled(enabled);
403 d->midMarkerSelector->setEnabled(enabled);
404 d->endMarkerSelector->setEnabled(enabled);
409 if (!
d->allowLocalUnitManagement) {
422 if (representativeShape) {
426 d->ui->lineWidth->setUnit(newUnit);
427 d->capNJoinMenu->miterLimit->setUnit(newUnit);
429 d->ui->lineWidth->setLineStep(1.0);
430 d->capNJoinMenu->miterLimit->setLineStep(1.0);
439 d->allowLocalUnitManagement =
false;
440 d->ui->lineWidth->setUnitManager(managerLineWidth);
441 d->capNJoinMenu->miterLimit->setUnitManager(managerMitterLimit);
447 d->startMarkerSelector->updateMarkers(markers);
448 d->midMarkerSelector->updateMarkers(markers);
449 d->endMarkerSelector->updateMarkers(markers);
455 d->deactivationLocks.clear();
456 d->fillConfigWidget->activate();
458 if (!
d->noSelectionTrackingMode) {
459 d->selectionChangedCompressor.start();
471 d->fillConfigWidget->deactivate();
476 d->ui->lineWidth->blockSignals(block);
477 d->capNJoinMenu->capGroup->blockSignals(block);
478 d->capNJoinMenu->joinGroup->blockSignals(block);
479 d->capNJoinMenu->miterLimit->blockSignals(block);
480 d->ui->lineStyle->blockSignals(block);
481 d->startMarkerSelector->blockSignals(block);
482 d->midMarkerSelector->blockSignals(block);
483 d->endMarkerSelector->blockSignals(block);
493template <
typename ModifyFunction>
497 KoSelection *selection = canvas->selectedShapesProxy()->selection();
499 if (!selection)
return;
506 canvas->addCommand(command);
515 stroke->setLineStyle(lineStyle(), lineDashes());
526 stroke->setLineWidth(lineWidth());
538 stroke->setCapStyle(static_cast<Qt::PenCapStyle>(d->capNJoinMenu->capGroup->checkedId()));
539 stroke->setJoinStyle(static_cast<Qt::PenJoinStyle>(d->capNJoinMenu->joinGroup->checkedId()));
540 stroke->setMiterLimit(miterLimit());
556 Q_FOREACH (
KoShape *shape, shapes) {
559 pathShapes << pathShape;
563 if (pathShapes.isEmpty()) {
570 QScopedPointer<KoMarker> marker;
574 if (
d->startMarkerSelector->marker()) {
575 marker.reset(
new KoMarker(*
d->startMarkerSelector->marker()));
579 if (
d->midMarkerSelector->marker()) {
580 marker.reset(
new KoMarker(*
d->midMarkerSelector->marker()));
584 if (
d->endMarkerSelector->marker()) {
585 marker.reset(
new KoMarker(*
d->endMarkerSelector->marker()));
602 return qSharedPointerDynamicCast<KoShapeStroke>(shape->
stroke());
609 return p1->lineStyle() ==
p2->lineStyle() &&
610 p1->lineDashes() ==
p2->lineDashes() &&
611 p1->dashOffset() ==
p2->dashOffset();
618 return p1->capStyle() ==
p2->capStyle() &&
619 p1->joinStyle() ==
p2->joinStyle() &&
620 p1->miterLimit() ==
p2->miterLimit();
627 return p1->lineWidth() ==
p2->lineWidth();
644 if ((!
p1 || !
p2) &&
p1 !=
p2)
return false;
645 if (!
p1 &&
p1 ==
p2)
return true;
655 if (
d->noSelectionTrackingMode)
return;
658 if (!selection)
return;
665 KoShape *shape = !shapes.isEmpty() ? shapes.first() : 0;
675 if (stroke && KoFlake::compareShapePropertiesEqual<CheckShapeStrokeWidthPolicy>(shapes)) {
676 d->ui->lineWidth->changeValue(stroke->lineWidth());
678 d->ui->lineWidth->changeValue(0);
683 if (stroke && KoFlake::compareShapePropertiesEqual<CheckShapeStrokeCapJoinPolicy>(shapes)) {
684 Qt::PenCapStyle
capStyle = stroke->capStyle() >= 0 ? stroke->capStyle() : Qt::FlatCap;
685 Qt::PenJoinStyle
joinStyle = stroke->joinStyle() >= 0 ? stroke->joinStyle() : Qt::MiterJoin;
699 d->capNJoinMenu->miterLimit->changeValue(stroke->miterLimit());
700 d->capNJoinMenu->miterLimit->setEnabled(
joinStyle == Qt::MiterJoin);
702 d->capNJoinMenu->capGroup->button(Qt::FlatCap)->setChecked(
true);
703 d->capNJoinMenu->joinGroup->button(Qt::MiterJoin)->setChecked(
true);
704 d->capNJoinMenu->miterLimit->changeValue(0.0);
705 d->capNJoinMenu->miterLimit->setEnabled(
true);
710 if (stroke && KoFlake::compareShapePropertiesEqual<CheckShapeStrokeDashesPolicy>(shapes)) {
711 d->ui->lineStyle->setLineStyle(stroke->lineStyle(), stroke->lineDashes());
730 const bool lineOptionsVisible = (
d->fillConfigWidget->selectedFillIndex() != 0);
735 switch(
d->fillConfigWidget->selectedFillIndex()) {
737 this->setMinimumHeight(130);
740 this->setMinimumHeight(200);
743 this->setMinimumHeight(350);
749 d->ui->thicknessLineBreak->setVisible(lineOptionsVisible);
750 d->ui->lineWidth->setVisible(lineOptionsVisible);
751 d->ui->capNJoinButton->setVisible(lineOptionsVisible);
752 d->ui->lineStyle->setVisible(lineOptionsVisible);
753 d->startMarkerSelector->setVisible(lineOptionsVisible);
754 d->midMarkerSelector->setVisible(lineOptionsVisible);
755 d->endMarkerSelector->setVisible(lineOptionsVisible);
756 d->ui->thicknessLabel->setVisible(lineOptionsVisible);
757 d->ui->strokeStyleLabel->setVisible(lineOptionsVisible);
773 d->selectionChangedCompressor.start();
776 if (
d->noSelectionTrackingMode) {
float value(const T *src, size_t ch)
QSharedPointer< KoShapeStroke > KoShapeStrokeSP
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
std::unique_lock< KisAcyclicSignalConnector > Blocker
KisSelectedShapesProxy selectedShapesProxy
KoUnit unit() const override
void addCommand(KUndo2Command *command) override
The KisDoubleParseUnitSpinBox class is an evolution of the.
void preventDecimalsChangeFromUnitManager(bool prevent)
void setMinMaxStep(double min, double max, double step)
Set minimum, maximum value and the step size (in current unit)
virtual void setUnit(const KoUnit &unit)
void setDecimals(int prec)
KoSelection * selection() override
The KisSignalMapper class bundles signals from identifiable senders.
void setMapping(QObject *sender, int id)
The KisSpinBoxUnitManager class is an abstract interface for the unitspinboxes classes to manage diff...
QPointer< KoShapeController > shapeController
QPointer< KoCanvasResourceProvider > resourceManager
virtual KoSelectedShapesProxy * selectedShapesProxy() const =0
selectedShapesProxy() is a special interface for keeping a persistent connections to selectionChanged...
@ MarkerCollection
The collection holding all markers.
QVariant resource(int key) const
QList< QExplicitlySharedDataPointer< KoMarker > > markers
The position of a path point within a path shape.
KoMarker * marker(KoFlake::MarkerPosition pos) const
const QList< KoShape * > selectedEditableShapes() const
virtual KoShapeStrokeModelSP stroke() const
QTransform absoluteTransformation() const
qreal fromUserValue(qreal value) const
@ Point
Postscript point, 1/72th of an Inco.
void adjustByPixelTransform(const QTransform &t)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
#define koIcon(name)
Use these macros for icons without any issues.
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
QString button(const QWheelEvent &ev)
@ Unit
The unit of this canvas.
auto modifyShapesStrokes(QList< KoShape * > shapes, ModifyFunction modifyFunction) -> decltype(modifyFunction(KoShapeStrokeSP()),(KUndo2Command *)(0))
bool compareShapePropertiesEqual(const QList< KoShape * > shapes, const Policy &policy)
KoFlake::MarkerPosition m_position
PointerType getProperty(KoShape *shape) const
CheckShapeMarkerPolicy(KoFlake::MarkerPosition position)
bool compareTo(PointerType p1, PointerType p2) const
static bool compareTo(PointerType p1, PointerType p2)
static bool compareTo(PointerType p1, PointerType p2)
static PointerType getProperty(KoShape *shape)
KoShapeStrokeSP PointerType
static bool compareTo(PointerType p1, PointerType p2)
The undo / redo command for setting the shape marker.