Commit e9262e5a authored by Dmitry Kazakov's avatar Dmitry Kazakov

Fix Default tool widgets to show values in real pixels, not points

Now the option widgets use correct KoUnit object to convert their
options in correct user-visible pixels. Some note on the implementation:

1) Affects KoStrokeConfigWidget and DefaultToolWidget
2) The correct conversion value is stored in KoUnit, which is reported
   by KisCanvas2 and retransmitted by KisView2.
3) There is a hack in KoStrokeConfigWidget. KoShapeStroke knows nothing
   about the absoluteTransformation() of the shape, which doesn't stop
   the shape from doing the transformation of the outline (loaded into
   QPainter directly). So we take it into account manually, by adding
   a multiplier into KoUnit.

BUG:313600
BUG:341107
parent a30671e9
......@@ -154,6 +154,8 @@ KisCanvas2::KisCanvas2(KisCoordinatesConverter *coordConverter, KisView2 *view,
KisShapeController *kritaShapeController = dynamic_cast<KisShapeController*>(sc);
connect(kritaShapeController, SIGNAL(selectionChanged()),
this, SLOT(slotSelectionChanged()));
connect(kritaShapeController, SIGNAL(selectionContentChanged()),
globalShapeManager(), SIGNAL(selectionContentChanged()));
connect(kritaShapeController, SIGNAL(currentLayerChanged(const KoShapeLayer*)),
globalShapeManager()->selection(), SIGNAL(currentLayerChanged(const KoShapeLayer*)));
......@@ -307,7 +309,21 @@ const QWidget* KisCanvas2::canvasWidget() const
KoUnit KisCanvas2::unit() const
{
return KoUnit(KoUnit::Pixel);
KoUnit unit(KoUnit::Pixel);
KisImageWSP image = m_d->view->image();
if (image) {
if (!qFuzzyCompare(image->xRes(), image->yRes())) {
qWarning() << "WARNING: resolution of the image is anisotropic"
<< ppVar(image->xRes())
<< ppVar(image->yRes());
}
const qreal resolution = image->xRes();
unit.setFactor(resolution);
}
return unit;
}
KoToolProxy * KisCanvas2::toolProxy() const
......
......@@ -97,6 +97,8 @@ void KisShapeController::addNodeImpl(KisNodeSP node, KisNodeSP parent, KisNodeSP
*/
connect(shapeLayer, SIGNAL(selectionChanged()),
SIGNAL(selectionChanged()));
connect(shapeLayer->shapeManager(), SIGNAL(selectionContentChanged()),
SIGNAL(selectionContentChanged()));
connect(shapeLayer, SIGNAL(currentLayerChanged(const KoShapeLayer*)),
SIGNAL(currentLayerChanged(const KoShapeLayer*)));
((KoShapeLayer*)shapeLayer)->setParent(newShape);
......
......@@ -61,7 +61,7 @@ private:
signals:
/**
* These two signals are forwarded from the local shape manager of
* These three signals are forwarded from the local shape manager of
* KisShapeLayer. This is done because we switch KoShapeManager and
* therefore KoSelection in KisCanvas2, so we need to connect local
* managers to the UI as well.
......@@ -69,6 +69,7 @@ signals:
* \see comment in the constructor of KisCanvas2
*/
void selectionChanged();
void selectionContentChanged();
void currentLayerChanged(const KoShapeLayer*);
protected:
......
......@@ -1172,6 +1172,10 @@ void KisView2::slotImageResolutionChanged()
{
resetImageSizeAndScroll(false);
m_d->zoomManager->updateGUI();
// update KoUnit value for the document
m_d->resourceProvider->resourceManager()->
setResource(KoCanvasResourceManager::Unit, m_d->canvas->unit());
}
void KisView2::slotNodeChanged()
......
......@@ -114,7 +114,9 @@ public:
}
bool operator==(const KoUnit &other) const {
return m_type == other.m_type;
return
m_type == other.m_type &&
qFuzzyCompare(m_pixelConversion, other.m_pixelConversion);
}
KoUnit::Type type() const {
......
......@@ -382,12 +382,40 @@ void KoStrokeConfigWidget::updateControls(KoShapeStrokeModel *stroke, KoMarker *
blockChildSignals(false);
}
#include <cmath>
inline KoUnit adjustUnitByLocalTransform(KoUnit unit, const QTransform &t)
{
qreal multiplier =
0.5 * (std::sqrt(t.m11() * t.m11() + t.m21() * t.m21()) +
std::sqrt(t.m12() * t.m12() + t.m22() * t.m22()));
multiplier *= unit.toUserValue(1.0);
unit.setFactor(multiplier);
return unit;
}
void KoStrokeConfigWidget::setUnit(const KoUnit &unit)
{
blockChildSignals(true);
d->lineWidth->setUnit(unit);
d->capNJoinMenu->miterLimit->setUnit(unit);
KoCanvasController* canvasController = KoToolManager::instance()->activeCanvasController();
KoSelection *selection = canvasController->canvas()->shapeManager()->selection();
KoShape * shape = selection->firstSelectedShape();
/**
* KoStrokeShape knows nothing about the transformations applied
* to the shape, which doesn't prevent the shape to apply them and
* display the stroke differently. So just take that into account
* and show the user correct values using the multiplier in KoUnit.
*/
KoUnit newUnit(unit);
if (shape) {
newUnit = adjustUnitByLocalTransform(unit, shape->absoluteTransformation(0));
}
d->lineWidth->setUnit(newUnit);
d->capNJoinMenu->miterLimit->setUnit(newUnit);
blockChildSignals(false);
}
......@@ -495,6 +523,9 @@ void KoStrokeConfigWidget::selectionChanged()
KoSelection *selection = canvasController->canvas()->shapeManager()->selection();
KoShape * shape = selection->firstSelectedShape();
if (shape && shape->stroke()) {
// see a comment in setUnit()
setUnit(d->canvas->unit());
KoPathShape *pathShape = dynamic_cast<KoPathShape *>(shape);
if (pathShape) {
updateControls(shape->stroke(), pathShape->marker(KoMarkerData::MarkerStart),
......@@ -511,6 +542,8 @@ void KoStrokeConfigWidget::setCanvas( KoCanvasBase *canvas )
if (canvas) {
connect(canvas->shapeManager()->selection(), SIGNAL(selectionChanged()),
this, SLOT(selectionChanged()));
connect(canvas->shapeManager(), SIGNAL(selectionContentChanged()),
this, SLOT(selectionChanged()));
connect(canvas->resourceManager(), SIGNAL(canvasResourceChanged(int, const QVariant&)),
this, SLOT(canvasResourceChanged(int, const QVariant &)));
setUnit(canvas->unit());
......
......@@ -134,10 +134,21 @@ void KoUnitDoubleSpinBox::privateValueChanged() {
void KoUnitDoubleSpinBox::setUnit( KoUnit unit )
{
if (unit == d->unit) return;
double oldvalue = d->unit.fromUserValue( QDoubleSpinBox::value() );
QDoubleSpinBox::setMinimum( unit.toUserValue( d->lowerInPoints ) );
QDoubleSpinBox::setMaximum( unit.toUserValue( d->upperInPoints ) );
QDoubleSpinBox::setSingleStep( unit.toUserValue( d->stepInPoints ) );
qreal step = unit.toUserValue( d->stepInPoints );
if (unit.type() == KoUnit::Pixel) {
// KoUnit rounds the pixel value to 1.0, so we cannot
// have step less than 1.0.
step = qMax(1.0, step);
}
QDoubleSpinBox::setSingleStep( step );
d->unit = unit;
QDoubleSpinBox::setValue( KoUnit::ptToUnit( oldvalue, unit ) );
setSuffix(unit.symbol().prepend(QLatin1Char(' ')));
......
......@@ -242,6 +242,9 @@ void DefaultToolWidget::setUnit( const KoUnit &unit )
widthSpinBox->setUnit( unit );
heightSpinBox->setUnit( unit );
m_blockSignals = false;
updatePosition();
updateSize();
}
void DefaultToolWidget::resourceChanged( int key, const QVariant & res )
......
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