Index: resources/iconsets/1_7_0/1_7_0.xml
===================================================================
--- resources/iconsets/1_7_0/1_7_0.xml (Revision 26704)
+++ resources/iconsets/1_7_0/1_7_0.xml (Arbeitskopie)
@@ -141,7 +141,7 @@
-
+
@@ -184,11 +184,13 @@
+
+
@@ -196,16 +198,25 @@
+
+
+
+
+
+
+
+
+
-
+
@@ -248,6 +259,8 @@
+
+
-
+
Index: scribus/canvasmode.cpp
===================================================================
--- scribus/canvasmode.cpp (Revision 26704)
+++ scribus/canvasmode.cpp (Arbeitskopie)
@@ -221,13 +221,13 @@
// }
drawSelectionHandle(psx, QPointF(x, y), p, m_canvas->scale());
- drawSelectionHandle(psx, QPointF(x+w/2.0, y), p, m_canvas->scale());
- drawSelectionHandle(psx, QPointF(x+w, y), p, m_canvas->scale());
- drawSelectionHandle(psx, QPointF(x+w, y+h/2.0), p, m_canvas->scale());
- drawSelectionHandle(psx, QPointF(x+w, y+h), p, m_canvas->scale());
- drawSelectionHandle(psx, QPointF(x+w/2.0, y+h), p, m_canvas->scale());
- drawSelectionHandle(psx, QPointF(x, y+h), p, m_canvas->scale());
- drawSelectionHandle(psx, QPointF(x, y+h/2.0), p, m_canvas->scale());
+ drawSelectionHandle(psx, QPointF(x + w / 2.0, y), p, m_canvas->scale());
+ drawSelectionHandle(psx, QPointF(x + w, y), p, m_canvas->scale());
+ drawSelectionHandle(psx, QPointF(x + w, y + h / 2.0), p, m_canvas->scale());
+ drawSelectionHandle(psx, QPointF(x + w, y + h), p, m_canvas->scale());
+ drawSelectionHandle(psx, QPointF(x + w / 2.0, y + h), p, m_canvas->scale());
+ drawSelectionHandle(psx, QPointF(x, y + h), p, m_canvas->scale());
+ drawSelectionHandle(psx, QPointF(x, y + h / 2.0), p, m_canvas->scale());
}
void CanvasMode::drawSelection(QPainter* psx, bool drawHandles)
@@ -257,6 +257,7 @@
if (!m_doc->Items->contains(currItem))
continue;
psx->save();
+ double lineAdjust(psx->pen().width() / m_canvas->scale());
double x, y, w, h;
w = currItem->visualWidth() ;
h = currItem->visualHeight() ;
@@ -265,14 +266,14 @@
psx->setRenderHint(QPainter::Antialiasing);
psx->translate(currItem->xPos(), currItem->yPos());
psx->rotate(currItem->rotation());
- x = currItem->asLine() ? 0 : (currItem->visualXPos() - currItem->xPos());
- y = currItem->asLine() ? (h / -2.0) : (currItem->visualYPos() - currItem->yPos());
+ x = currItem->asLine() ? 0 : (currItem->visualXPos() - currItem->xPos() - lineAdjust);
+ y = currItem->asLine() ? (h / -2.0) : (currItem->visualYPos() - currItem->yPos() - lineAdjust);
}
else
{
psx->translate(currItem->visualXPos(), currItem->visualYPos());
- x = 0;
- y = 0;
+ x = currItem->asLine() ? 0 : -lineAdjust;
+ y = currItem->asLine() ? 0 : -lineAdjust;
}
// psx->setBrush(Qt::NoBrush);
// psx->setPen(m_pen["frame-outline"]);
@@ -285,12 +286,13 @@
}
psx->save();
psx->setPen(m_pen["selection-group"]);
+ double lineAdjust(psx->pen().width() / m_canvas->scale());
double x, y, w, h;
m_doc->m_Selection->getVisualGroupRect(&x, &y, &w, &h);
psx->translate(x,y);
- x = 0;
- y = 0;
+ x = -lineAdjust;
+ y = -lineAdjust;
// psx->setBrush(Qt::NoBrush);
// psx->setPen(m_pen["frame-outline"]);
@@ -314,6 +316,7 @@
psx->save();
psx->setPen(m_pen["selection"]);
psx->setBrush(m_brush["selection"]);
+ double lineAdjust(psx->pen().width() / m_canvas->scale());
double x, y, w, h;
if (currItem->isGroupChild())
{
@@ -358,14 +361,14 @@
psx->setRenderHint(QPainter::Antialiasing);
psx->translate(currItem->xPos(), currItem->yPos());
psx->rotate(currItem->rotation());
- x = currItem->asLine() ? 0 : (currItem->visualXPos() - currItem->xPos());
- y = currItem->asLine() ? (h / -2.0) : (currItem->visualYPos() - currItem->yPos());
+ x = currItem->asLine() ? 0 : (currItem->visualXPos() - currItem->xPos() - lineAdjust);
+ y = currItem->asLine() ? (h / -2.0) : (currItem->visualYPos() - currItem->yPos() - lineAdjust);
}
else
{
psx->translate(currItem->visualXPos(), currItem->visualYPos());
- x = 0;
- y = 0;
+ x = currItem->asLine() ? 0 : -lineAdjust;
+ y = currItem->asLine() ? 0 : -lineAdjust;
}
// psx->setBrush(Qt::NoBrush);
if (m_doc->drawAsPreview && !m_doc->editOnPreview)
@@ -740,7 +743,7 @@
QPoint pageOrigin = m_canvas->canvasToLocal(QPointF(xOffset, yOffset));
if (ySnap)
{
- p->setPen(Qt::green);
+ p->setPen(m_pen["snap-line"]);
QPoint pt = m_canvas->canvasToLocal(QPointF(xOffset, ySnap));
double w = (dragToPage->width() + bleedValues.left() + bleedValues.right()) * m_canvas->scale();
p->drawLine(pageOrigin.x(), pt.y(), pageOrigin.x() + w, pt.y());
@@ -748,7 +751,7 @@
}
if (xSnap)
{
- p->setPen(Qt::green);
+ p->setPen(m_pen["snap-line"]);
QPoint pt = m_canvas->canvasToLocal(QPointF(xSnap, yOffset));
double h = (dragToPage->height() + bleedValues.bottom() + bleedValues.top()) * m_canvas->scale();
p->drawLine(pt.x(), pageOrigin.y(), pt.x(), pageOrigin.y() + h);
@@ -1291,7 +1294,7 @@
{
int storedClRe = m_doc->nodeEdit.clre();
const auto& nodeSelection = m_doc->nodeEdit.selNode();
- if ((nodeSelection.count() != 0) && (m_doc->nodeEdit.edPoints()))
+ if (nodeSelection.count() != 0)
{
QPolygonF poly;
m_doc->nodeEdit.beginTransaction(currItem);
@@ -1385,7 +1388,7 @@
{
int storedClRe = m_doc->nodeEdit.clre();
const auto& nodeSelection = m_doc->nodeEdit.selNode();
- if ((nodeSelection.count() != 0) && (m_doc->nodeEdit.edPoints()))
+ if (nodeSelection.count() != 0)
{
QPolygonF poly;
m_doc->nodeEdit.beginTransaction(currItem);
@@ -1479,7 +1482,7 @@
{
int storedClRe = m_doc->nodeEdit.clre();
const auto& nodeSelection = m_doc->nodeEdit.selNode();
- if ((nodeSelection.count() != 0) && (m_doc->nodeEdit.edPoints()))
+ if (nodeSelection.count() != 0)
{
QPolygonF poly;
m_doc->nodeEdit.beginTransaction(currItem);
@@ -1573,7 +1576,7 @@
{
int storedClRe = m_doc->nodeEdit.clre();
const auto& nodeSelection = m_doc->nodeEdit.selNode();
- if ((nodeSelection.count() != 0) && (m_doc->nodeEdit.edPoints()))
+ if (nodeSelection.count() != 0)
{
QPolygonF poly;
m_doc->nodeEdit.beginTransaction(currItem);
@@ -1734,9 +1737,11 @@
m_color["frame-group"] = PrefsManager::instance().appPrefs.displayPrefs.frameGroupColor;
m_color["frame"] = PrefsManager::instance().appPrefs.displayPrefs.frameNormColor;
m_color["frame-move"] = Qt::gray;
- m_color["weld"] = QColor(214, 146, 43);
- m_color["node"] = QColor(0, 136, 255);
- m_color["node-handle"] = QColor(255, 51, 187);
+ m_color["weld"] = QColor(238, 152, 0);
+ m_color["node"] = QColor(0, 123, 241);
+ m_color["node-handle"] = QColor(166, 74, 253);
+ m_color["highlight"] = QColor(220, 58, 140);
+ m_color["snap-line"] = Qt::green;
m_color["test"] = Qt::magenta;
QColor selectionAlpha = m_color["frame-selection"];
selectionAlpha.setAlphaF(.05f);
@@ -1747,18 +1752,19 @@
#else
double stroke = 1.0;
#endif
-
+ // frame
m_pen["frame-move"] = QPen(m_color["frame-move"], 1.0 , Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
m_pen["frame-move"].setCosmetic(true);
m_pen["frame-preview"] = QPen(Qt::black, 1.0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
m_pen["frame-preview"].setCosmetic(true);
- m_pen["selection"] = QPen(m_color["frame-selection"], stroke, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+ m_pen["selection"] = QPen(m_color["frame-selection"], 1.0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
m_pen["selection"].setCosmetic(true);
- m_pen["selection-handle"] = QPen(m_color["frame-selection"], stroke, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+ m_pen["selection-handle"] = QPen(m_color["frame-selection"], 1.0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
m_pen["selection-handle"].setCosmetic(true);
m_pen["selection-group"] = m_pen["selection"];
m_pen["selection-group-inside"] = QPen(m_color["frame-group"], 1.0 , Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
m_pen["selection-group-inside"].setCosmetic(true);
+ // vector editing
m_pen["vector"] = QPen(m_color["node"], stroke, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
m_pen["vector"].setCosmetic(true);
m_pen["node"] = QPen(m_color["node"], stroke, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
@@ -1767,6 +1773,10 @@
m_pen["node-handle"].setCosmetic(true);
m_pen["node-dash"] = QPen(m_color["node-handle"], stroke, Qt::DashLine, Qt::FlatCap, Qt::MiterJoin);
m_pen["node-dash"].setCosmetic(true);
+ m_pen["highlight"] = QPen(m_color["highlight"], stroke, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+ m_pen["highlight"].setCosmetic(true);
+ // guides
+ m_pen["snap-line"] = QPen(m_color["snap-line"], 1.0 , Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
m_brush["frame-move"] = Qt::NoBrush;
m_brush["selection"] = Qt::NoBrush;
Index: scribus/canvasmode_nodeedit.cpp
===================================================================
--- scribus/canvasmode_nodeedit.cpp (Revision 26704)
+++ scribus/canvasmode_nodeedit.cpp (Arbeitskopie)
@@ -30,6 +30,7 @@
#include "scribusdoc.h"
#include "scribusview.h"
#include "selection.h"
+#include "ui/nodeeditpalette.h"
#include "ui/pageselector.h"
#include "ui/scrspinbox.h"
@@ -38,20 +39,20 @@
m_ScMW = m_view->m_ScMW;
}
-void CanvasMode_NodeEdit::drawControls(QPainter* p)
+void CanvasMode_NodeEdit::drawControls(QPainter* p)
{
- if (m_doc->m_Selection->isEmpty())
+ if (m_doc->m_Selection->isEmpty() || m_doc->nodeEdit.previewMode())
return;
- if (m_doc->nodeEdit.previewMode())
- return;
+
PageItem* currItem = m_doc->m_Selection->itemAt(0);
FPointArray cli;
-
+
p->save();
p->scale(m_canvas->scale(), m_canvas->scale());
p->translate(-m_doc->minCanvasCoordinate.x(), -m_doc->minCanvasCoordinate.y());
p->setTransform(currItem->getTransform(), true);
p->setBrush(Qt::NoBrush);
+ p->setRenderHint(QPainter::Antialiasing);
if ((m_doc->nodeEdit.isContourLine()) && (!currItem->ContourLine.empty()))
cli = currItem->ContourLine;
@@ -71,15 +72,25 @@
p->scale(1, -1);
}
}
- }
+ }
const double scale = m_canvas->m_viewMode.scale;
+ double nx = 0.0;
+ double ny = 0.0;
+ double cx = 0.0;
+ double cy = 0.0;
+
+ QPen penControl = pens().value("node");
+ bool isActiveNode = false;
+ bool isActiveControl = false;
+ bool highlight = false;
+ bool mergedNodes = true;
+ int nr, nl, inr;
+ FPoint pn, pc;
+
// Draw Vector Path
if (cli.size() > 3)
{
- p->save();
- p->setRenderHint(QPainter::Antialiasing);
-
for (int i = 0; i < cli.size() - 3; i += 4)
{
if (cli.isMarker(i))
@@ -88,20 +99,18 @@
const FPoint& a1 = cli.point(i);
const FPoint& a2 = cli.point(i + 1);
const FPoint& a3 = cli.point(i + 3);
- const FPoint& a4 = cli.point(i + 2);
+ const FPoint& a4 = cli.point(i + 2);
QPainterPath Bez;
Bez.moveTo(a1.x(), a1.y());
Bez.cubicTo(a2.x(), a2.y(), a3.x(), a3.y(), a4.x(), a4.y());
+
+ // Vector Path
p->setPen(pens().value("vector"));
p->drawPath(Bez);
- p->setPen(pens().value("node-handle"));
- p->drawLine(QPointF(a1.x(), a1.y()), QPointF(a2.x(), a2.y()));
- p->drawLine(QPointF(a3.x(), a3.y()), QPointF(a4.x(), a4.y()));
+
}
- p->restore();
}
- double x = 0.0;
- double y = 0.0;
+
// Draw Nodes
for (int i = 0; i < cli.size() - 1; i += 2)
{
@@ -108,51 +117,90 @@
if (cli.isMarker(i))
continue;
- if (m_doc->nodeEdit.edPoints())
- {
- cli.point(i + 1, &x, &y);
- drawNodeControl(p, QPointF(x, y), pens().value("node"), scale);
+ nr = NodeEditContext::indexOfNode(m_doc->nodeEdit.clre(), NodeEditContext::NodeType::NodeRight, cli.size());
+ nl = NodeEditContext::indexOfNode(m_doc->nodeEdit.clre(), NodeEditContext::NodeType::NodeLeft, cli.size());
+ inr = NodeEditContext::indexOfNode(i, NodeEditContext::NodeType::NodeRight, cli.size());
- cli.point(i, &x, &y);
- drawNodeHandle(p, QPointF(x, y), pens().value("node"), scale);
- }
- else
+ mergedNodes = NodeEditContext::hasTwoNodes(i, cli);
+ highlight = (i == nr || i == nl) && NodeEditContext::hasTwoNodes(m_doc->nodeEdit.clre(), cli);
+
+ isActiveControl = m_doc->nodeEdit.clre() == i + 1 ? true : false;
+ isActiveNode = m_doc->nodeEdit.clre() == i ||
+ m_doc->nodeEdit.selNode().contains(i) ||
+ m_doc->nodeEdit.selNode().contains(i - 2) ||
+ (m_doc->nodeEdit.selNode().contains(inr) && mergedNodes) ? true : false;
+
+ cli.point(i, &nx, &ny);
+ cli.point(i + 1, &cx, &cy);
+
+ // Draw Control Handle Lines
+ if (FPoint(cx, cy) != FPoint(nx, ny))
{
- cli.point(i, &x, &y);
- drawNodeHandle(p, QPointF(x, y), pens().value("node"), scale);
+ // changes color to highlight if angle is same as opponent handle
+ if (highlight && state.isSameAngle && state.clickedOn)
+ p->setPen(pens().value("highlight"));
+ else
+ p->setPen(pens().value("node-handle"));
- cli.point(i + 1, &x, &y);
- drawNodeControl(p, QPointF(x, y), pens().value("node"), scale);
+ p->setRenderHint(QPainter::Antialiasing, true);
+ p->drawLine(QPointF(nx, ny), QPointF(cx, cy));
}
- }
-
- if (m_doc->nodeEdit.clre() != -1)
- {
- cli.point(m_doc->nodeEdit.clre(), &x, &y);
- drawNodeControl(p, QPointF(x, y), pens().value("node"), scale, true);
- const auto& selectedNodes = m_doc->nodeEdit.selNode();
- for (int i = 0; i < selectedNodes.count(); ++i)
+ p->setRenderHint(QPainter::Antialiasing, false);
+
+ // Draw Node Handle
+ drawNodeHandle(p, QPointF(nx, ny), pens().value("node"), scale, isActiveNode);
+
+ // Draw Control Handle
+ if (FPoint(cx, cy) != FPoint(nx, ny))
{
- int selectedNode = selectedNodes.at(i);
- cli.point(selectedNode, &x, &y);
- drawNodeHandle(p, QPointF(x, y), pens().value("node"), scale, true);
+ // changes color to highlight if length is same as opponent handle
+ if (highlight && state.isSameLength && state.isSameAngle && state.clickedOn)
+ penControl = pens().value("highlight");
+ else
+ penControl = pens().value("node");
+
+ drawNodeControl(p, QPointF(cx, cy), penControl, scale, isActiveControl);
}
}
- bool havePoint = (m_doc->nodeEdit.clre() != -1);
- emit m_view->HavePoint(havePoint, m_doc->nodeEdit.moveSym());
+ emit m_view->HavePoint(m_doc->nodeEdit.clre() != -1);
+
if (m_doc->nodeEdit.clre() != -1)
{
- cli.point(m_doc->nodeEdit.clre(), &x, &y);
- emit m_view->ClipPo(x, y);
+ cli.point(m_doc->nodeEdit.clre(), &nx, &ny);
+ emit m_view->ClipPo(nx, ny);
}
p->restore();
}
+QMap CanvasMode_NodeEdit::selectedNodesList(FPointArray points)
+{
+ QMap selList;
+ const auto& selNodes = m_doc->nodeEdit.selNode();
+ if (points.size() > 3)
+ {
+ for (int i = 0; i < points.size() - 1; i += 2)
+ {
+ if (points.isMarker(i))
+ continue;
+
+ // i = path start;
+ // i + 2 = path end OR left part of a node
+ // i - 2 = right part of a node
+ if (selNodes.contains(i) || selNodes.contains(i + 2) || selNodes.contains(i - 2) || selNodes.contains(i - 4))
+ {
+ selList.insert(i, i + 1);
+ }
+ }
+ }
+
+ return selList;
+}
+
void CanvasMode_NodeEdit::activate(bool fromGesture)
{
CanvasMode::activate(fromGesture);
@@ -236,19 +284,47 @@
return (*pi) != nullptr;
}
+FPoint CanvasMode_NodeEdit::constraintControlAngle(FPoint anchor, FPoint mouse, double angleStep)
+{
+ QLineF line(anchor.toQPointF(), mouse.toQPointF());
+ line.setAngle(constrainAngle(line.angle(), angleStep));
+ return line.p2();
+}
-void CanvasMode_NodeEdit::enterEvent(QEvent *e)
+FPoint CanvasMode_NodeEdit::snapControlAngle(FPoint anchor, FPoint mouse, double angle)
{
+ double snap = m_doc->prefsData().guidesPrefs.guideRad / m_canvas->scale();
+ QLineF lineAM(anchor.x(), anchor.y(), mouse.x(), mouse.y()); // anchor to mouse
+ QLineF lineAC = lineAM; // anchor to opposite control point
+ lineAC.setAngle(360.0 - angle); // invert angle, Qt angle is counter-clockwise
+
+ if (qMax(lineAM.angle(), lineAC.angle()) - qMin(lineAM.angle(), lineAC.angle()) <= 0.00001)
+ return lineAC.p2();
+
+ return QLineF(lineAM.p2(), lineAC.p2()).length() <= snap ? lineAC.p2() : mouse;
}
+FPoint CanvasMode_NodeEdit::snapControlLength(FPoint anchor, FPoint mouse, double length)
+{
+ double snap = m_doc->prefsData().guidesPrefs.guideRad / m_canvas->scale();
+ QLineF line(anchor.toQPointF(), mouse.toQPointF());
-void CanvasMode_NodeEdit::leaveEvent(QEvent *e)
-{
+ if (length - snap <= line.length() && length + snap >= line.length())
+ line.setLength(length);
+
+ return line.p2();
}
+FPoint CanvasMode_NodeEdit::snapControlOrigin(FPoint anchor, FPoint mouse)
+{
+ double snap = m_doc->prefsData().guidesPrefs.guideRad / m_canvas->scale();
+ QLineF line(anchor.toQPointF(), mouse.toQPointF());
+ return (line.length() <= snap) ? anchor : mouse;
+}
+
void CanvasMode_NodeEdit::mouseDoubleClickEvent(QMouseEvent *m)
{
m->accept();
@@ -257,11 +333,11 @@
m_view->requestMode(submodeEndNodeEdit);
}
-
void CanvasMode_NodeEdit::mouseMoveEvent(QMouseEvent *m)
{
double sc = m_canvas->scale();
FPoint npf = m_canvas->globalToCanvas(m->globalPosition());
+ m_doc->nodeEdit.setScale(sc);
m->accept();
@@ -348,6 +424,7 @@
m_canvas->m_viewMode.operItemMoving = false;
m_doc->DragP = false;
m_doc->leaveDrag = false;
+ m_doc->nodeEdit.setScale(m_canvas->scale());
m_MoveGX = m_MoveGY = false;
m->accept();
m_view->registerMousePress(m->globalPosition());
@@ -369,7 +446,8 @@
if (m_doc->m_Selection->count() != 0)
{
handleNodeEditPress(m, mpo);
- }
+ }
+
if ((m_doc->m_Selection->count() != 0) && (m->button() == Qt::RightButton))
{
m_canvas->m_viewMode.m_MouseButtonPressed = true;
@@ -378,16 +456,27 @@
}
}
-
-
void CanvasMode_NodeEdit::mouseReleaseEvent(QMouseEvent *m)
{
PageItem *currItem;
+
m_canvas->m_viewMode.m_MouseButtonPressed = false;
m_canvas->resetRenderMode();
m->accept();
+
+ // Deselect selected node if SHIFT is pressed
+ if (state.clickedOn == NodeHandle &&
+ m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT &&
+ !state.wasNewlySelected &&
+ m->modifiers() == Qt::ShiftModifier)
+ {
+ m_doc->nodeEdit.deselectNode(m_doc->nodeEdit.clre());
+ m_doc->regionsChanged()->update(QRectF());
+ }
+
if (m_view->moveTimerElapsed())
{
+ // Path Segment
if (m_doc->nodeEdit.segP1() != -1 && m_doc->nodeEdit.segP2() != -1)
{
m_doc->nodeEdit.deselect();
@@ -394,53 +483,58 @@
m_doc->nodeEdit.setSegP1(-1);
m_doc->nodeEdit.setSegP2(-1);
}
+
+ m_canvas->m_viewMode.operItemMoving = false;
currItem = m_doc->m_Selection->itemAt(0);
- m_canvas->m_viewMode.operItemMoving = false;
double xposOrig = currItem->xPos();
double yposOrig = currItem->yPos();
- ScOldNewState *state = m_doc->nodeEdit.finishTransaction1(currItem);
+ ScOldNewState *onState = m_doc->nodeEdit.finishTransaction1(currItem);
+
if (m_doc->nodeEdit.hasNodeSelected() && (m_doc->nodeEdit.selectionCount() == 1))
{
+
//FIXME:av
- FPoint newP = m_canvas->globalToCanvas(m->globalPosition());
+ // FPoint newP = m_canvas->globalToCanvas(m->globalPosition());
currItem->OldB2 = currItem->width();
currItem->OldH2 = currItem->height();
- FPointArray Clip;
- FPoint npf;
- double nx = newP.x();
- double ny = newP.y();
- if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
- npf = m_doc->ApplyGridF(FPoint(nx, ny));
- else
- npf = FPoint(nx, ny);
- QTransform pp = currItem->getTransform();
- npf = npf.transformPoint(pp, true);
- if (m_doc->nodeEdit.isContourLine())
- Clip = currItem->ContourLine;
- else
- {
- Clip = currItem->PoLine;
- if (currItem->isSymbol() || currItem->isGroup())
- {
- if (currItem->imageFlippedH())
- {
- QTransform p;
- p.translate(currItem->width(), 0);
- p.scale(-1, 1);
- npf = npf.transformPoint(p, false);
- }
- if (currItem->imageFlippedV())
- {
- QTransform p;
- p.translate(0, currItem->height());
- p.scale(1, -1);
- npf = npf.transformPoint(p, false);
- }
- }
- }
- m_doc->nodeEdit.moveClipPoint(currItem, npf);
+ // currItem->ClipEdited = true;
+ // FPointArray Clip;
+ // FPoint npf;
+ // double nx = newP.x();
+ // double ny = newP.y();
+ // if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
+ // npf = m_doc->ApplyGridF(FPoint(nx, ny));
+ // else
+ // npf = FPoint(nx, ny);
+ // QTransform pp = currItem->getTransform();
+ // npf = npf.transformPoint(pp, true);
+ // if (m_doc->nodeEdit.isContourLine())
+ // Clip = currItem->ContourLine;
+ // else
+ // {
+ // Clip = currItem->PoLine;
+ // if (currItem->isSymbol() || currItem->isGroup())
+ // {
+ // if (currItem->imageFlippedH())
+ // {
+ // QTransform p;
+ // p.translate(currItem->width(), 0);
+ // p.scale(-1, 1);
+ // npf = npf.transformPoint(p, false);
+ // }
+ // if (currItem->imageFlippedV())
+ // {
+ // QTransform p;
+ // p.translate(0, currItem->height());
+ // p.scale(1, -1);
+ // npf = npf.transformPoint(p, false);
+ // }
+ // }
+ // }
+ // m_doc->nodeEdit.moveClipPoint(currItem, npf);
}
+ // nitramr: Scribus crashes if ESC key is pressed during mouse drag operation
m_doc->adjustItemSize(currItem, true);
if (!m_doc->nodeEdit.isContourLine())
{
@@ -450,41 +544,58 @@
currItem->ContourLine.translate(delta.x(), delta.y());
}
m_doc->regionsChanged()->update(QRectF());
- if (state)
- m_doc->nodeEdit.finishTransaction2(currItem, state);
- return;
- }
+ if (onState)
+ m_doc->nodeEdit.finishTransaction2(currItem, onState);
- m_canvas->setRenderModeUseBuffer(false);
- m_doc->DragP = false;
- m_doc->leaveDrag = false;
- m_canvas->m_viewMode.operItemMoving = false;
- m_canvas->m_viewMode.operItemResizing = false;
- m_view->MidButt = false;
- if (m_view->groupTransactionStarted())
- {
- for (int i = 0; i < m_doc->m_Selection->count(); ++i)
- m_doc->m_Selection->itemAt(i)->checkChanges(true);
- m_view->endGroupTransaction();
}
- //Commit drag created items to undo manager.
- if (m_doc->m_Selection->itemAt(0) != nullptr)
+ else
{
- m_doc->itemAddCommit(m_doc->m_Selection->itemAt(0));
+ m_canvas->setRenderModeUseBuffer(false);
+ m_doc->DragP = false;
+ m_doc->leaveDrag = false;
+ m_canvas->m_viewMode.operItemMoving = false;
+ m_canvas->m_viewMode.operItemResizing = false;
+ m_view->MidButt = false;
+ if (m_view->groupTransactionStarted())
+ {
+ for (int i = 0; i < m_doc->m_Selection->count(); ++i)
+ m_doc->m_Selection->itemAt(i)->checkChanges(true);
+ m_view->endGroupTransaction();
+ }
+ //Commit drag created items to undo manager.
+ if (m_doc->m_Selection->itemAt(0) != nullptr)
+ m_doc->itemAddCommit(m_doc->m_Selection->itemAt(0));
+ //Make sure the Zoom spinbox and page selector don't have focus if we click on the canvas
+ m_view->m_ScMW->zoomSpinBox->clearFocus();
+ m_view->m_ScMW->pageSelector->clearFocus();
+ if (m_doc->m_Selection->itemAt(0) != nullptr) // is there the old clip stored for the undo action
+ {
+ currItem = m_doc->m_Selection->itemAt(0);
+ m_doc->nodeEdit.finishTransaction(currItem);
+ }
}
- //Make sure the Zoom spinbox and page selector don't have focus if we click on the canvas
- m_view->m_ScMW->zoomSpinBox->clearFocus();
- m_view->m_ScMW->pageSelector->clearFocus();
- if (m_doc->m_Selection->itemAt(0) != nullptr) // is there the old clip stored for the undo action
- {
- currItem = m_doc->m_Selection->itemAt(0);
- m_doc->nodeEdit.finishTransaction(currItem);
- }
+
+ m_doc->nodeEdit.setMoveMode(state.originalMoveMode);
+ state.reset();
}
void CanvasMode_NodeEdit::keyPressEvent(QKeyEvent *e)
{
commonkeyPressEvent_NormalNodeEdit(e);
+
+ int kk = e->key();
+// Qt::KeyboardModifiers buttonModifiers = e->modifiers();
+// ScribusMainWindow* mainWindow = m_view->m_ScMW;
+ PageItem* currItem = m_doc->m_Selection->itemAt(0);
+
+ if (kk == Qt::Key_Delete || kk == Qt::Key_Backspace)
+ {
+ if (currItem && m_doc->nodeEdit.hasNodeSelected())
+ {
+ // delete Nodes
+ refreshPath(deleteNodes());
+ }
+ }
}
void CanvasMode_NodeEdit::keyReleaseEvent(QKeyEvent *e)
@@ -494,58 +605,131 @@
void CanvasMode_NodeEdit::handleNodeEditPress(QMouseEvent* m, QRect r)
{
- FPoint npf2;
- bool edited = false;
- bool pfound = false;
-
PageItem* currItem = m_doc->m_Selection->itemAt(0);
FPointArray Clip = m_doc->nodeEdit.beginTransaction(currItem);
- m_doc->nodeEdit.deselect();
+ QTransform pm2 = currItem->getTransform();
+ FPoint npf2 = m_canvas->globalToCanvas(m->globalPosition()).transformPoint(pm2, true);
+ bool edited = false;
- QTransform pm2 = currItem->getTransform();
- npf2 = m_canvas->globalToCanvas(m->globalPosition()).transformPoint(pm2, true);
- if ((currItem->isSymbol() || currItem->isGroup()) && (!m_doc->nodeEdit.isContourLine()))
+ state.originalMoveMode = m_doc->nodeEdit.moveMode();
+ state.moveMode = state.originalMoveMode;
+ state.clickedOn = None;
+ m_doc->nodeEdit.oppositeControl.isValid = false;
+
+ switch (state.hoveredOver)
{
- if (currItem->imageFlippedH())
+ case ControlHandle:
+ case NodeHandle:
+ {
+ if ((currItem->isSymbol() || currItem->isGroup()) && (!m_doc->nodeEdit.isContourLine()))
{
- pm2.translate(currItem->width(), 0);
- pm2.scale(-1, 1);
+ if (currItem->imageFlippedH())
+ {
+ pm2.translate(currItem->width(), 0);
+ pm2.scale(-1, 1);
+ }
+ if (currItem->imageFlippedV())
+ {
+ pm2.translate(0, currItem->height());
+ pm2.scale(1, -1);
+ }
}
- if (currItem->imageFlippedV())
+
+ for (int i = 0; i < Clip.size(); ++i)
{
- pm2.translate(0, currItem->height());
- pm2.scale(1, -1);
- }
- }
- for (int i = 0; i < Clip.size(); ++i)
- {
- if (((m_doc->nodeEdit.edPoints()) && (i % 2 != 0)) || ((!m_doc->nodeEdit.edPoints()) && (i % 2 == 0)))
- continue;
- QPointF npf = pm2.map(Clip.pointQF(i));
- if (m_canvas->hitsCanvasPoint(m->globalPosition(), npf))
- {
- m_doc->nodeEdit.setClre(i);
- if ((m_doc->nodeEdit.edPoints()) && (m_doc->nodeEdit.selNode().contains(i) == 0))
+ if (m_canvas->hitsCanvasPoint(m->globalPosition(), pm2.map(Clip.pointQF(i))))
{
- if (m->modifiers() != Qt::ShiftModifier)
+ if (state.originalMoveMode == NodeEditContext::Auto)
+ {
+ bool sameAngle = m_doc->nodeEdit.sameAngle(currItem, i);
+ bool sameLength = m_doc->nodeEdit.sameLength(currItem, i);
+
+ if (sameLength && sameAngle)
+ state.moveMode = NodeEditContext::Symmetric;
+ else if (!sameLength && sameAngle)
+ state.moveMode = NodeEditContext::Asymmetric;
+ else if (!sameLength && !sameAngle)
+ state.moveMode = NodeEditContext::Independent;
+ }
+
+ state.clickedOn = NodeEditContext::isNode(i) ? NodeHandle : ControlHandle;
+
+ if (state.clickedOn == NodeHandle)
+ {
+ // Deselect all controls
+ m_doc->nodeEdit.deselectNodeControls();
+
+ if (!m_doc->nodeEdit.selNode().contains(i) && m->modifiers() != Qt::ShiftModifier)
+ m_doc->nodeEdit.selNode().clear();
+
+ state.wasNewlySelected = !m_doc->nodeEdit.selNode().contains(i);
+
+ m_doc->nodeEdit.selectNode(i);
+
+ if (m->modifiers() == Qt::AltModifier || m_doc->nodeEdit.submode() == NodeEditContext::EDIT_POINT)
+ {
+ // Reset Controls
+ if (state.moveMode != NodeEditContext::Independent || !NodeEditContext::hasTwoNodes(i, Clip))
+ m_doc->nodeEdit.resetControl(currItem);
+ else // Make Control Handles symetric
+ m_doc->nodeEdit.equalizeControls(currItem);
+ }
+ }
+
+ if (state.clickedOn == ControlHandle)
+ {
m_doc->nodeEdit.selNode().clear();
- m_doc->nodeEdit.selectNode(i);
+ m_doc->nodeEdit.selectNode(i);
+ }
+
+ m_doc->nodeEdit.setClre(i);
+
+ // Save position of opposite control handle
+ int indexNode = NodeEditContext::indexOfNode(i, NodeEditContext::OppositeSibling, Clip.size());
+ int indexControl = NodeEditContext::indexOfNode(i, NodeEditContext::Opposite, Clip.size());
+
+ double dx = Clip.point(indexControl).x() - Clip.point(indexNode).x();
+ double dy = Clip.point(indexControl).y() - Clip.point(indexNode).y();
+
+ m_doc->nodeEdit.oppositeControl.isValid = NodeEditContext::hasTwoNodes(i, Clip);
+ m_doc->nodeEdit.oppositeControl.relativePos = Clip.point(indexControl) - Clip.point(indexNode);
+ m_doc->nodeEdit.oppositeControl.controlIndex = indexControl;
+ m_doc->nodeEdit.oppositeControl.nodeIndex = indexNode;
+ m_doc->nodeEdit.oppositeControl.distance = distance(dx, dy);
+ m_doc->nodeEdit.oppositeControl.angle = xy2Deg(dx, dy);
+ m_doc->nodeEdit.update(Clip.pointQF(i));
+ edited = true;
+
+ break;
}
- m_doc->nodeEdit.update(Clip.pointQF(i));
- pfound = true;
- edited = true;
- break;
+
+ //deselect all if no node or control has hit
+ if (i == Clip.size() - 1)
+ m_doc->nodeEdit.deselect();
+
}
+
+ break;
}
- if ((!pfound) || (!m_doc->nodeEdit.edPoints()))
- m_doc->nodeEdit.selNode().clear();
+ case PathSegment:
+ m_doc->nodeEdit.deselect();
+ state.clickedOn = PathSegment;
+ break;
+ case None:
+ default:
+ m_doc->nodeEdit.deselect();
+ state.clickedOn = None;
+ break;
+ }
- if ((m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT) && (m_doc->nodeEdit.clre() != -1) && !m_doc->nodeEdit.hasNodeSelected())
+ if (m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT && !m_doc->nodeEdit.hasNodeSelected() && state.clickedOn == PathSegment)
{
m_doc->nodeEdit.setSegP1(m_doc->nodeEdit.clre2());
m_doc->nodeEdit.setSegP2(m_doc->nodeEdit.clre2()+2);
m_doc->nodeEdit.setClre(m_doc->nodeEdit.clre2());
}
+
+
FPointArray cli;
int EndInd = Clip.size();
int StartInd = 0;
@@ -568,10 +752,10 @@
}
}
}
- if (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH)
+
+ if (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH && (state.clickedOn == NodeHandle || state.clickedOn == PathSegment))
{
- if (!m_doc->nodeEdit.edPoints())
- return;
+ // Path Segment
if ((!m_doc->nodeEdit.hasNodeSelected()) && (m_doc->nodeEdit.clre2() != -1)) // We don't have a Point, try to add one onto the current curve segment
{
bool foundP = false;
@@ -582,7 +766,7 @@
FPoint tangent(0, 0);
FPoint nearPoint(0, 0);
double nearT = 0.0;
- QRect mpo2(0, 0, m_doc->guidesPrefs().grabRadius*3, m_doc->guidesPrefs().grabRadius*3);
+ QRect mpo2(0, 0, m_doc->guidesPrefs().grabRadius * 3, m_doc->guidesPrefs().grabRadius * 3);
mpo2.moveCenter(QPoint(qRound(npf2.x()), qRound(npf2.y())));
for (int poi = 0; poi < Clip.size() - 3; poi += 4)
{
@@ -594,7 +778,7 @@
Bez.moveTo(a1.x(), a1.y());
Bez.cubicTo(a2.x(), a2.y(), a3.x(), a3.y(), a4.x(), a4.y());
QPolygon cli2 = Bez.toFillPolygon().toPolygon();
- for (int clp = 0; clp < cli2.size()-1; ++clp)
+ for (int clp = 0; clp < cli2.size() - 1; ++clp)
{
if (m_view->PointOnLine(cli2.point(clp), cli2.point(clp + 1), mpo2))
{
@@ -604,7 +788,7 @@
while (sp < 1.0)
{
Clip.pointTangentNormalAt(seg, sp, &point, &tangent, &normal );
- double d1 = fabs(sqrt(pow(point.x() - npf2.x(), 2) + pow(point.y() - npf2.y() ,2)));
+ double d1 = fabs(sqrt(pow(point.x() - npf2.x(), 2) + pow(point.y() - npf2.y(), 2)));
if (d1 < absDist)
{
foundP = true;
@@ -673,6 +857,7 @@
else
m_doc->nodeEdit.deselect();
}
+ // Node Handle
if (m_doc->nodeEdit.hasNodeSelected())
{
if (currItem->isPolygon())
@@ -762,69 +947,14 @@
}
}
}
- if ((m_doc->nodeEdit.submode() == NodeEditContext::DEL_POINT) && m_doc->nodeEdit.hasNodeSelected())
+
+ if ((m_doc->nodeEdit.submode() == NodeEditContext::DEL_POINT || m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT && m->modifiers() == Qt::ControlModifier) && m_doc->nodeEdit.hasNodeSelected() && state.clickedOn == NodeHandle)
{
- if (!m_doc->nodeEdit.edPoints())
- return;
+ edited = deleteNodes();
+ }
- int minClipSize = 4;
- if (!currItem->isLine() && !currItem->isPathText() && !currItem->isPolyLine())
- minClipSize = 12;
-
- if (Clip.size() <= minClipSize)
- {
- m_doc->nodeEdit.deselect();
- return;
- }
-
- int numPoints = (StartInd != 0) ? (StartInd-4) : 0;
- numPoints += (Clip.size() - EndInd);
- if ((currItem->Segments.count() > 0) && ((EndInd - StartInd) <= minClipSize) && (numPoints > 0))
- {
- if (StartInd != 0)
- cli.putPoints(0, StartInd - 4, Clip);
- cli.putPoints(cli.size(), Clip.size() - EndInd, Clip, EndInd);
- }
- else if (m_doc->nodeEdit.clre() == StartInd)
- {
- if (!currItem->isLine() && !currItem->isPathText() && !currItem->isPolyLine())
- {
- const FPoint& kp(Clip.point(EndInd - 3));
- cli.putPoints(0, StartInd, Clip);
- cli.putPoints(cli.size(), EndInd - StartInd - 4, Clip, StartInd);
- cli.setPoint(StartInd, cli.point(cli.size() - 2));
- cli.setPoint(StartInd + 1, kp);
- cli.putPoints(cli.size(), Clip.size() - EndInd, Clip, EndInd);
- }
- else
- {
- cli.putPoints(0, StartInd, Clip);
- cli.putPoints(cli.size(), EndInd - StartInd - 4, Clip, StartInd+4);
- cli.putPoints(cli.size(), Clip.size() - EndInd, Clip, EndInd);
- }
- }
- else if (m_doc->nodeEdit.clre() == (EndInd - 2))
- {
- Clip.remove(m_doc->nodeEdit.clre() - 2, 4);
- cli = Clip.copy();
- }
- else
- {
- if (m_doc->nodeEdit.clre() != 0)
- cli.putPoints(0, m_doc->nodeEdit.clre(), Clip);
- cli.putPoints(cli.size(), Clip.size() - (m_doc->nodeEdit.clre() + 4), Clip, m_doc->nodeEdit.clre() + 4);
- }
- while (cli.isMarker(0))
- cli.remove(0, 4);
- if (m_doc->nodeEdit.isContourLine())
- currItem->ContourLine = cli.copy();
- else
- currItem->PoLine = cli.copy();
- m_doc->nodeEdit.deselect();
- currItem->ClipEdited = true;
- edited = true;
- }
- if ((m_doc->nodeEdit.submode() == NodeEditContext::ADD_POINT) && (m_doc->nodeEdit.clre2() != -1))
+ // Add node id "add point" mode OR "move point" mode + CTRL
+ if ((m_doc->nodeEdit.submode() == NodeEditContext::ADD_POINT || m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT && m->modifiers() == Qt::ControlModifier) && (m_doc->nodeEdit.clre2() != -1))
{
bool foundP = false;
uint seg = 0;
@@ -856,7 +986,7 @@
while (sp < 1.0)
{
Clip.pointTangentNormalAt(seg, sp, &point, &tangent, &normal );
- double d1 = fabs(sqrt(pow(point.x() - npf2.x(), 2) + pow(point.y() - npf2.y() ,2)));
+ double d1 = fabs(sqrt(pow(point.x() - npf2.x(), 2) + pow(point.y() - npf2.y(), 2)));
if (d1 < absDist)
{
foundP = true;
@@ -911,30 +1041,11 @@
currItem->ClipEdited = true;
edited = true;
}
- if (edited)
+
+ refreshPath(edited);
+
+ if ((m_doc->nodeEdit.selectionCount() != 0) || ((m_doc->nodeEdit.segP1() != -1) && (m_doc->nodeEdit.segP2() != -1)) || (m_doc->nodeEdit.hasNodeSelected() && state.clickedOn == ControlHandle))
{
- currItem->FrameType = 3;
- double xp = currItem->xPos();
- double yp = currItem->yPos();
- double w = currItem->width();
- double h = currItem->height();
- m_doc->adjustItemSize(currItem, true);
- double xp2 = currItem->xPos();
- double yp2 = currItem->yPos();
- double w2 = currItem->width();
- double h2 = currItem->height();
- currItem->update();
- if ((xp != xp2) || (yp != yp2) || (w != w2) || (h != h2))
- m_view->DrawNew();
- emit m_view->PolyStatus(currItem->itemType(), currItem->PoLine.size());
- }
- else
- {
- currItem->update();
- m_view->DrawNew();
- }
- if ((m_doc->nodeEdit.selectionCount() != 0) || ((m_doc->nodeEdit.segP1() != -1) && (m_doc->nodeEdit.segP2() != -1)) || (m_doc->nodeEdit.hasNodeSelected() && (!m_doc->nodeEdit.edPoints())))
- {
m_Mxp = m->position().x();
m_Myp = m->position().y();
m_canvas->setRenderModeFillBuffer();
@@ -950,11 +1061,9 @@
m_rectangleSelect->prepare(m->globalPosition());
m_view->startGesture(m_rectangleSelect);
}
-
+
}
-
-
bool CanvasMode_NodeEdit::handleNodeEditMove(QMouseEvent* m, QRect /*r*/, PageItem* currItem, const QTransform& /*t*/)
{
QTransform itemPos = currItem->getTransform();
@@ -965,6 +1074,7 @@
itemPos.translate(currItem->width(), 0);
itemPos.scale(-1, 1);
}
+
if (currItem->imageFlippedV())
{
itemPos.translate(0, currItem->height());
@@ -971,38 +1081,49 @@
itemPos.scale(1, -1);
}
}
- FPointArray Clip;
+ FPointArray Clip = m_doc->nodeEdit.clipFromItem(currItem);
m_doc->nodeEdit.setClre2(-1);
m_doc->nodeEdit.setSegP1(-1);
m_doc->nodeEdit.setSegP2(-1);
- if (m_doc->nodeEdit.isContourLine())
- Clip = currItem->ContourLine;
- else
- Clip = currItem->PoLine;
+ state.hoveredOver = None;
+
+ // Hover mouse on node or control handle
if ((m_doc->nodeEdit.submode() == NodeEditContext::DEL_POINT) ||
(m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT) ||
- (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH))
+ (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH) ||
+ (m_doc->nodeEdit.submode() == NodeEditContext::EDIT_POINT))
{
for (int i = 0; i < Clip.size(); ++i)
{
- if (((m_doc->nodeEdit.edPoints()) && (i % 2 != 0)) || ((!m_doc->nodeEdit.edPoints()) && (i % 2 == 0)))
- continue;
QPointF point = Clip.pointQF(i);
if (m_canvas->hitsCanvasPoint(m->globalPosition(), itemPos.map(point)))
{
if (m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT)
- m_view->setCursor(QCursor(Qt::SizeAllCursor));
- if (m_doc->nodeEdit.submode() == NodeEditContext::DEL_POINT)
- m_view->setCursor(IconManager::instance().loadCursor("cursor-remove-point", 1, 1));
- if (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH)
- m_view->setCursor(IconManager::instance().loadCursor("cursor-split", 1, 1));
+ m_view->setCursor(IconManager::instance().loadCursor("cursor-move", 1, 1));
+ else if (m_doc->nodeEdit.submode() == NodeEditContext::EDIT_POINT)
+ m_view->setCursor(IconManager::instance().loadCursor("cursor-node-edit", 1, 1));
+
+ if (NodeEditContext::isNode(i))
+ {
+ if (m_doc->nodeEdit.submode() == NodeEditContext::DEL_POINT || (m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT && m->modifiers() == Qt::ControlModifier))
+ m_view->setCursor(IconManager::instance().loadCursor("cursor-remove-point", 1, 1));
+ else if (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH)
+ m_view->setCursor(IconManager::instance().loadCursor("cursor-split", 1, 1));
+
+ state.hoveredOver = NodeHandle;
+ }
+ else
+ state.hoveredOver = ControlHandle;
+
return true;
}
}
}
+
+ // Hover mouse on path segment
if ((m_doc->nodeEdit.submode() == NodeEditContext::ADD_POINT) ||
(m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT) ||
- (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH && m_doc->nodeEdit.edPoints()))
+ (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH))
{
for (int poi = 0; poi < Clip.size() - 3; poi += 4)
{
@@ -1015,6 +1136,7 @@
Bez.moveTo(a1);
Bez.cubicTo(a2, a3, a4);
double len = Bez.length();
+
if (len > 0.0)
{
double delta = 2.0 / len;
@@ -1023,15 +1145,17 @@
QPointF pl = Bez.pointAtPercent(d);
if (m_canvas->hitsCanvasPoint(m->globalPosition(), FPoint(pl.x(), pl.y())))
{
- if (m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT)
+ if (m_doc->nodeEdit.submode() == NodeEditContext::ADD_POINT || (m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT && m->modifiers() == Qt::ControlModifier))
+ m_view->setCursor(IconManager::instance().loadCursor("cursor-add-point", 1, 1));
+ else if (m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT)
m_view->setCursor(IconManager::instance().loadCursor("cursor-hand"));
- else if (m_doc->nodeEdit.submode() == NodeEditContext::ADD_POINT)
- m_view->setCursor(IconManager::instance().loadCursor("cursor-add-point", 1, 1));
else if (m_doc->nodeEdit.submode() == NodeEditContext::SPLIT_PATH)
m_view->setCursor(IconManager::instance().loadCursor("cursor-split", 1, 1));
else
m_view->setCursor(QCursor(Qt::ArrowCursor));
+
m_doc->nodeEdit.setClre2(poi);
+ state.hoveredOver = PathSegment;
return true;
}
}
@@ -1044,6 +1168,7 @@
void CanvasMode_NodeEdit::handleNodeEditDrag(QMouseEvent* m, PageItem* currItem)
{
+ // Selection Frame
if ((m_canvas->m_viewMode.m_MouseButtonPressed) && !m_doc->nodeEdit.hasNodeSelected() && (m_doc->nodeEdit.segP1() == -1) && (m_doc->nodeEdit.segP2() == -1))
{
if (!m_rectangleSelect)
@@ -1052,6 +1177,7 @@
m_view->startGesture(m_rectangleSelect);
return;
}
+
FPoint npf;
double newX = m->position().x();
double newY = m->position().y();
@@ -1059,6 +1185,8 @@
np = np * (1.0 / m_canvas->scale());
m_canvas->m_viewMode.operItemMoving = true;
currItem = m_doc->m_Selection->itemAt(0);
+
+ // Move Path Segment
if ((m_doc->nodeEdit.segP1() != -1) && (m_doc->nodeEdit.segP2() != -1))
{
if ((currItem->isSymbol() || currItem->isGroup()) && (!m_doc->nodeEdit.isContourLine()))
@@ -1068,37 +1196,38 @@
if (currItem->imageFlippedV())
np.setY(np.y() * -1);
}
- if (m_doc->nodeEdit.isContourLine())
- npf = currItem->ContourLine.point(m_doc->nodeEdit.segP2()) + np;
- else
- npf = currItem->PoLine.point(m_doc->nodeEdit.segP2()) + np;
+
+ // First segment
+ npf = m_doc->nodeEdit.clipFromItem(currItem).point(m_doc->nodeEdit.segP2()) + np;
m_doc->nodeEdit.setClre(m_doc->nodeEdit.segP2());
m_doc->nodeEdit.moveClipPoint(currItem, npf);
- if (m_doc->nodeEdit.isContourLine())
- npf = currItem->ContourLine.point(m_doc->nodeEdit.segP1() ) + np;
- else
- npf = currItem->PoLine.point(m_doc->nodeEdit.segP1() ) + np;
+
+ // Second segment
+ npf = m_doc->nodeEdit.clipFromItem(currItem).point(m_doc->nodeEdit.segP1()) + np;
m_doc->nodeEdit.setClre(m_doc->nodeEdit.segP1());
m_doc->nodeEdit.moveClipPoint(currItem, npf);
m_Mxp = newX;
m_Myp = newY;
}
+ // Move Nodes or Controls
else
{
- if ((m_doc->nodeEdit.selectionCount() != 0) && (m_doc->nodeEdit.edPoints()))
+ if ((m_doc->nodeEdit.selectionCount() > 0) && (state.clickedOn == NodeHandle || state.clickedOn == ControlHandle))
{
- int storedClRe = m_doc->nodeEdit.clre();
+ // Single Nodes
if (m_doc->nodeEdit.selectionCount() == 1)
{
npf = m_canvas->globalToCanvas(m->globalPosition());
double nx = npf.x();
double ny = npf.y();
- if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
+ if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny, true))
npf = m_doc->ApplyGridF(FPoint(nx, ny));
else
npf = FPoint(nx, ny);
+
QTransform pp = currItem->getTransform();
npf = npf.transformPoint(pp, true);
+
if ((currItem->isSymbol() || currItem->isGroup()) && (!m_doc->nodeEdit.isContourLine()))
{
if (currItem->imageFlippedH())
@@ -1116,55 +1245,81 @@
npf = npf.transformPoint(p, false);
}
}
- FPoint npf1(npf);
- //Control Modifier to have parallel shape
- if (m->modifiers() == Qt::ControlModifier)
+
+ int curr = m_doc->nodeEdit.clre();
+ FPoint pOpposite = m_doc->nodeEdit.getPoint(currItem, m_doc->nodeEdit.oppositeControl.nodeIndex);
+ FPoint pSibling = m_doc->nodeEdit.getPoint(currItem, curr, NodeEditContext::Sibling);
+
+ if (m->modifiers() & Qt::ShiftModifier || m_doc->nodeEdit.submode() == NodeEditContext::EDIT_POINT)
{
- FPointArray cli;
- if (m_doc->nodeEdit.isContourLine())
- cli = currItem->ContourLine;
- else
- cli = currItem->PoLine;
- int tmpNode;
- int curr = (m_doc->nodeEdit.clre() == 0) ? cli.size() - 2 : m_doc->nodeEdit.clre();
- int prev = (curr + cli.size() - 4) % cli.size();
- int next = (curr + 4) % cli.size();
+ // Shift + drag on control
+ if (!NodeEditContext::isNode(curr) && state.clickedOn == ControlHandle)
+ {
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Independent);
- if (std::abs(cli.point(prev).x() - cli.point(curr).x()) < std::abs(cli.point(next).x() - cli.point(curr).x()))
- tmpNode = next;
- else if (std::abs(cli.point(prev).x() - cli.point(curr).x()) == std::abs(cli.point(next).x() - cli.point(curr).x()))
+ if (m_doc->nodeEdit.oppositeControl.isValid)
+ {
+ m_doc->nodeEdit.setClre(m_doc->nodeEdit.oppositeControl.controlIndex);
+ m_doc->nodeEdit.moveClipPoint(currItem, pOpposite + m_doc->nodeEdit.oppositeControl.relativePos);
+ m_doc->nodeEdit.setClre(curr);
+ }
+ }
+
+ // Shift + drag on node
+ if (NodeEditContext::isNode(curr) && state.clickedOn == NodeHandle)
{
- if (cli.point(prev).y() != cli.point(curr).y())
- tmpNode = next;
- else
- tmpNode = prev;
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Symmetric);
+ m_doc->nodeEdit.setClre(curr + 1);
}
- else
- tmpNode = prev;
+ }
+ else
+ m_doc->nodeEdit.setMoveMode(state.moveMode);
- m_doc->nodeEdit.moveClipPoint(currItem, npf);
- m_doc->nodeEdit.setClre(tmpNode);
+ if (m->modifiers() & Qt::ControlModifier)
+ {
+ // Snap control handle at 15° steps
+ if (!NodeEditContext::isNode(curr))
+ npf = constraintControlAngle(m_doc->nodeEdit.getPoint(currItem, curr, NodeEditContext::Sibling), npf, 15.0);
- if (m_doc->nodeEdit.isContourLine())
- npf1.setX(currItem->ContourLine.point(m_doc->nodeEdit.clre()).x());
- else
- npf1.setX(currItem->PoLine.point(m_doc->nodeEdit.clre()).x());
+ }
- m_doc->nodeEdit.moveClipPoint(currItem, npf1);
+ // Snap control handle
+ if (!NodeEditContext::isNode(curr) && state.clickedOn == ControlHandle)
+ {
+ state.isSameAngle = m_doc->nodeEdit.sameAngle(currItem, curr);
+ state.isSameLength = m_doc->nodeEdit.sameLength(currItem, curr);
- if (m_doc->nodeEdit.clre() == prev)
- m_doc->nodeEdit.setClre(next);
- else
- m_doc->nodeEdit.setClre(prev);
+ bool modifier = m->modifiers() & Qt::ShiftModifier || m_doc->nodeEdit.submode() == NodeEditContext::EDIT_POINT;
- if (m_doc->nodeEdit.isContourLine())
- npf.setY(currItem->ContourLine.point(m_doc->nodeEdit.clre()).y());
- else
- npf.setY(currItem->PoLine.point(m_doc->nodeEdit.clre()).y());
+ // let's snap the control angle to opposite reference
+ if (state.isSameAngle && (m_doc->nodeEdit.moveMode() == NodeEditContext::Auto || m_doc->nodeEdit.moveMode() == NodeEditContext::Independent || modifier))
+ npf = snapControlAngle(pOpposite, npf, m_doc->nodeEdit.oppositeControl.angle - 180.0);
+
+ // let's snap the control length to opposite reference
+ if (state.isSameLength && state.isSameAngle && (m_doc->nodeEdit.moveMode() != NodeEditContext::Symmetric || modifier))
+ npf = snapControlLength(pOpposite, npf, m_doc->nodeEdit.oppositeControl.distance);
+
+ // let's snap the control to same position as control anchor if control is too close
+ npf = snapControlOrigin(pSibling, npf);
}
+
+ // Snap node handle
+ // if (NodeEditContext::isNode(curr) && state.clickedOn == NodeHandle)
+ // {
+ // FPointArray Clip = m_doc->nodeEdit.isContourLine() ? currItem->ContourLine : currItem->PoLine;
+ // FPoint pOppositeNode = m_doc->nodeEdit.getPoint(currItem, curr, NodeEditContext::Opposite);
+
+ // if (curr == 0 || curr == Clip.size() -2)
+ // {
+ // // TODO: close bezier curve and merge endpoints
+ // npf = snapControlOrigin(pOppositeNode, npf);
+ // }
+ // }
+
m_doc->nodeEdit.moveClipPoint(currItem, npf);
- m_canvas->displayXYHUD(m->globalPosition(), npf.x(), npf1.y());
+ m_canvas->displayXYHUD(m->globalPosition(), npf.x(), npf.y());
}
+ // Multiple Nodes
else
{
if ((currItem->isSymbol() || currItem->isGroup()) && (!m_doc->nodeEdit.isContourLine()))
@@ -1174,53 +1329,147 @@
if (currItem->imageFlippedV())
np.setY(np.y() * -1);
}
+
const auto& nodeSelection = m_doc->nodeEdit.selNode();
for (int itm = 0; itm < nodeSelection.count(); ++itm)
{
m_doc->nodeEdit.setClre(nodeSelection.at(itm));
- if (m_doc->nodeEdit.isContourLine())
- npf = currItem->ContourLine.point(m_doc->nodeEdit.clre()) + np;
- else
- npf = currItem->PoLine.point(m_doc->nodeEdit.clre()) + np;
+ npf = m_doc->nodeEdit.clipFromItem(currItem).point(m_doc->nodeEdit.clre()) + np;
m_doc->nodeEdit.moveClipPoint(currItem, npf);
}
}
- m_doc->nodeEdit.setClre(storedClRe);
}
- else
+
+ m_Mxp = newX;
+ m_Myp = newY;
+
+ }
+ m_canvas->m_viewMode.operItemMoving = false;
+ m_doc->regionsChanged()->update(QRectF());
+}
+
+bool CanvasMode_NodeEdit::deleteNodes()
+{
+ PageItem* currItem = m_doc->m_Selection->itemAt(0);
+ FPointArray Clip = m_doc->nodeEdit.beginTransaction(currItem);
+
+ if (!currItem || Clip.size() == 0)
+ return false;
+
+ FPointArray cli;
+ int EndInd = Clip.size();
+ int StartInd = 0;
+ if (m_doc->nodeEdit.clre() > 0)
+ {
+ for (int n = m_doc->nodeEdit.clre(); n < Clip.size(); ++n)
{
- npf = m_canvas->globalToCanvas(m->globalPosition());
- double nx = npf.x();
- double ny = npf.y();
- if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
- npf = m_doc->ApplyGridF(FPoint(nx, ny));
+ if (Clip.isMarker(n))
+ {
+ EndInd = n;
+ break;
+ }
+ }
+ for (int n2 = m_doc->nodeEdit.clre(); n2 > 0; n2--)
+ {
+ if (Clip.isMarker(n2))
+ {
+ StartInd = n2 + 1;
+ break;
+ }
+ }
+ }
+
+ if (m_doc->nodeEdit.hasNodeSelected())
+ {
+ int minClipSize = 4;
+ if (!currItem->isLine() && !currItem->isPathText() && !currItem->isPolyLine())
+ minClipSize = 12;
+
+ if (Clip.size() <= minClipSize)
+ {
+ m_doc->nodeEdit.deselect();
+ return false;
+ }
+
+ int numPoints = (StartInd != 0) ? (StartInd-4) : 0;
+ numPoints += (Clip.size() - EndInd);
+ if ((currItem->Segments.count() > 0) && ((EndInd - StartInd) <= minClipSize) && (numPoints > 0))
+ {
+ if (StartInd != 0)
+ cli.putPoints(0, StartInd - 4, Clip);
+ cli.putPoints(cli.size(), Clip.size() - EndInd, Clip, EndInd);
+ }
+ else if (m_doc->nodeEdit.clre() == StartInd)
+ {
+ if (!currItem->isLine() && !currItem->isPathText() && !currItem->isPolyLine())
+ {
+ const FPoint& kp(Clip.point(EndInd - 3));
+ cli.putPoints(0, StartInd, Clip);
+ cli.putPoints(cli.size(), EndInd - StartInd - 4, Clip, StartInd);
+ cli.setPoint(StartInd, cli.point(cli.size() - 2));
+ cli.setPoint(StartInd + 1, kp);
+ cli.putPoints(cli.size(), Clip.size() - EndInd, Clip, EndInd);
+ }
else
- npf = FPoint(nx, ny);
- QTransform pp = currItem->getTransform();
- npf = npf.transformPoint(pp, true);
- if ((currItem->isSymbol() || currItem->isGroup()) && (!m_doc->nodeEdit.isContourLine()))
{
- if (currItem->imageFlippedH())
- {
- QTransform p;
- p.translate(currItem->width(), 0);
- p.scale(-1, 1);
- npf = npf.transformPoint(p, false);
- }
- if (currItem->imageFlippedV())
- {
- QTransform p;
- p.translate(0, currItem->height());
- p.scale(1, -1);
- npf = npf.transformPoint(p, false);
- }
+ cli.putPoints(0, StartInd, Clip);
+ cli.putPoints(cli.size(), EndInd - StartInd - 4, Clip, StartInd+4);
+ cli.putPoints(cli.size(), Clip.size() - EndInd, Clip, EndInd);
}
- m_doc->nodeEdit.moveClipPoint(currItem, npf);
- m_canvas->displayXYHUD(m->globalPosition(), npf.x(), npf.y());
}
- m_Mxp = newX;
- m_Myp = newY;
+ else if (m_doc->nodeEdit.clre() == (EndInd - 2))
+ {
+ Clip.remove(m_doc->nodeEdit.clre() - 2, 4);
+ cli = Clip.copy();
+ }
+ else
+ {
+ if (m_doc->nodeEdit.clre() != 0)
+ cli.putPoints(0, m_doc->nodeEdit.clre(), Clip);
+ cli.putPoints(cli.size(), Clip.size() - (m_doc->nodeEdit.clre() + 4), Clip, m_doc->nodeEdit.clre() + 4);
+ }
+ while (cli.isMarker(0))
+ cli.remove(0, 4);
+ if (m_doc->nodeEdit.isContourLine())
+ currItem->ContourLine = cli.copy();
+ else
+ currItem->PoLine = cli.copy();
+ m_doc->nodeEdit.deselect();
+ currItem->ClipEdited = true;
+ return true;
}
- m_canvas->m_viewMode.operItemMoving = false;
- m_doc->regionsChanged()->update(QRectF());
+
+
+ return false;
}
+
+void CanvasMode_NodeEdit::refreshPath(bool edited)
+{
+ PageItem* currItem = m_doc->m_Selection->itemAt(0);
+
+ if (!currItem)
+ return;
+
+ if (edited)
+ {
+ currItem->FrameType = 3;
+ double xp = currItem->xPos();
+ double yp = currItem->yPos();
+ double w = currItem->width();
+ double h = currItem->height();
+ m_doc->adjustItemSize(currItem, true);
+ double xp2 = currItem->xPos();
+ double yp2 = currItem->yPos();
+ double w2 = currItem->width();
+ double h2 = currItem->height();
+ currItem->update();
+ if ((xp != xp2) || (yp != yp2) || (w != w2) || (h != h2))
+ m_view->DrawNew();
+ emit m_view->PolyStatus(currItem->itemType(), currItem->PoLine.size());
+ }
+ else
+ {
+ currItem->update();
+ m_view->DrawNew();
+ }
+}
Index: scribus/canvasmode_nodeedit.h
===================================================================
--- scribus/canvasmode_nodeedit.h (Revision 26704)
+++ scribus/canvasmode_nodeedit.h (Arbeitskopie)
@@ -19,6 +19,7 @@
#define CANVAS_MODE_NODEEDIT_H
#include "canvasmode.h"
+#include "nodeeditcontext.h"
#include
#include
@@ -38,8 +39,8 @@
void activate(bool fromgesture) override;
void deactivate(bool forGesture) override;
- void enterEvent(QEvent *) override;
- void leaveEvent(QEvent *) override;
+ void enterEvent(QEvent *) override {};
+ void leaveEvent(QEvent *) override {};
void mouseDoubleClickEvent(QMouseEvent *m) override;
void mouseReleaseEvent(QMouseEvent *m) override;
@@ -55,13 +56,45 @@
void drawControls(QPainter* p) override;
private:
+
+ enum MouseMode { None = 0, NodeHandle, ControlHandle, PathSegment };
+
+ struct StateManager {
+ MouseMode clickedOn { None };
+ MouseMode hoveredOver { None };
+ bool isSameLength {false};
+ bool isSameAngle {false};
+ bool wasNewlySelected { false };
+ NodeEditContext::ControlMoveMode originalMoveMode { NodeEditContext::ControlMoveMode::Auto };
+ NodeEditContext::ControlMoveMode moveMode { originalMoveMode }; // we need this for converted auto mode
+
+ void reset()
+ {
+ clickedOn = None;
+ isSameLength = false;
+ isSameAngle = false;
+ wasNewlySelected = false;
+ moveMode = NodeEditContext::ControlMoveMode::Auto;
+ }
+ };
+
inline bool GetItem(PageItem** pi);
+ QMap selectedNodesList(FPointArray points);
void handleNodeEditPress(QMouseEvent*, QRect r);
void handleNodeEditDrag(QMouseEvent*, PageItem*);
bool handleNodeEditMove(QMouseEvent*, QRect r, PageItem*, const QTransform&);
+ FPoint constraintControlAngle(FPoint anchor, FPoint mouse, double angleStep);
+ FPoint snapControlAngle(FPoint anchor, FPoint mouse, double angle);
+ FPoint snapControlLength(FPoint anchor, FPoint mouse, double length);
+ FPoint snapControlOrigin(FPoint anchor, FPoint mouse);
+ bool deleteNodes();
+ void updateItem(PageItem* currItem);
+ void refreshPath(bool edited);
+
ScribusMainWindow* m_ScMW { nullptr };
RectSelect* m_rectangleSelect { nullptr };
+ StateManager state;
double m_Mxp { -1.0 }; // last mouse position
double m_Myp { -1.0 };
@@ -71,6 +104,7 @@
double m_GyM { -1.0 };
bool m_MoveGX { false };
bool m_MoveGY { false };
+
};
Index: scribus/nodeeditcontext.cpp
===================================================================
--- scribus/nodeeditcontext.cpp (Revision 26704)
+++ scribus/nodeeditcontext.cpp (Arbeitskopie)
@@ -23,9 +23,34 @@
void NodeEditContext::selectNode(int i)
{
m_ClRe = i;
- m_SelNode.append(i);
+ if (!m_SelNode.contains(i))
+ m_SelNode.append(i);
}
+void NodeEditContext::deselectNode(int i)
+{
+ int index = m_SelNode.indexOf(i);
+ m_SelNode.removeAll(i);
+ if (m_SelNode.count() == 0)
+ m_ClRe = -1;
+ else // select previous node or last one if there is no previous one
+ m_ClRe = (index - 1 >= 0) ? m_SelNode.at(index - 1) : m_SelNode.last();
+}
+
+void NodeEditContext::deselectNodeControls()
+{
+ for (int i = 0; i < m_SelNode.count(); i++)
+ {
+ if (!isNode(m_SelNode.at(i)))
+ {
+ m_SelNode.removeAt(i);
+ i --;
+ }
+ }
+ if (m_SelNode.count() == 0)
+ m_ClRe = -1;
+}
+
int NodeEditContext::selectionCount() const
{
return m_SelNode.count();
@@ -42,7 +67,7 @@
delete oldClip;
oldClip = nullptr;
nodeTransaction.reset();
- m_MoveSym = false;
+ m_moveMode = Auto;
m_SelNode.clear();
m_preview = false;
}
@@ -83,8 +108,6 @@
return Clip;
}
-
-
void NodeEditContext::finishTransaction(PageItem* currItem)
{
ScribusDoc* Doc = currItem->doc();
@@ -116,7 +139,6 @@
oldClip = nullptr;
}
-
/**
first part: create a new UndoState or cancel the current transaction
*/
@@ -167,25 +189,28 @@
delete oldClip;
oldClip = nullptr;
}
-
//CB-->Doc
void NodeEditContext::moveClipPoint(PageItem *currItem, const FPoint& ip)
{
ScribusDoc* Doc = currItem->doc();
- if (((m_EdPoints) && (m_ClRe % 2 != 0)) || ((!m_EdPoints) && (m_ClRe % 2 == 0)))
- return;
+
double xposOrig = currItem->xPos();
double yposOrig = currItem->yPos();
currItem->ClipEdited = true;
+
FPointArray Clip;
+ FPoint np(ip);
+
if (m_isContourLine)
Clip = currItem->ContourLine.copy();
else
Clip = currItem->PoLine.copy();
currItem->FrameType = 3;
+
uint EndInd = Clip.size();
uint StartInd = 0;
+
for (int n = m_ClRe; n < Clip.size(); ++n)
{
if (Clip.isMarker(n))
@@ -194,6 +219,7 @@
break;
}
}
+
if (m_ClRe > 0)
{
for (int n2 = m_ClRe; n2 > 0; n2--)
@@ -205,9 +231,10 @@
}
}
}
- FPoint np(ip);
+
if (hasNodeSelected())
{
+ // expand item on left side if x is out of bound
if ((np.x() < 0) && (!m_isContourLine) && (!(currItem->isGroup() || currItem->isSymbol())))
{
Doc->sizeItem(currItem->width() - np.x(), currItem->height(), currItem, false, false, false);
@@ -223,6 +250,8 @@
currItem->moveImageInFrame(-np.x()/currItem->imageXScale(), 0);
np.setX(0);
}
+
+ // expand item on top side if y is out of bound
if ((np.y() < 0) && (!m_isContourLine) && (!(currItem->isGroup() || currItem->isSymbol())))
{
Doc->sizeItem(currItem->width(), currItem->height() - np.y(), currItem, false, false, false);
@@ -239,7 +268,9 @@
np.setY(0);
}
update(QPointF(np.x(), np.y()));
- if ((m_ClRe + 1 < static_cast(EndInd)) && (m_ClRe % 2 == 0))
+
+ // update control of node
+ if (isNode(m_ClRe) && (m_ClRe + 1 < static_cast(EndInd)))
{
FPoint ap(Clip.point(m_ClRe));
FPoint ap2(Clip.point(m_ClRe + 1));
@@ -247,8 +278,11 @@
ap2.setY(ap2.y() - (ap.y() - np.y()));
Clip.setPoint(m_ClRe + 1, ap2);
}
+
Clip.setPoint(m_ClRe, np);
- if (((m_ClRe % 4 != 0) && (m_ClRe % 2 == 0)) && (m_ClRe + 3 < static_cast(EndInd)) && (m_ClRe != static_cast(StartInd)))
+
+ // update right node with control
+ if (isLeftNode(m_ClRe) && (m_ClRe + 3 < static_cast(EndInd)) && (m_ClRe != static_cast(StartInd)))
{
FPoint ap(Clip.point(m_ClRe + 2));
FPoint ap2(Clip.point(m_ClRe + 3));
@@ -257,7 +291,9 @@
Clip.setPoint(m_ClRe + 3, ap2);
Clip.setPoint(m_ClRe + 2, np);
}
- if ((m_ClRe % 4 == 0) && (m_ClRe + 3 < static_cast(EndInd)) && (m_ClRe != static_cast(StartInd)))
+
+ // update left node with control
+ if (isRightNode(m_ClRe) && (m_ClRe + 3 < static_cast(EndInd)) && (m_ClRe != static_cast(StartInd)))
{
FPoint ap(Clip.point(m_ClRe - 2));
FPoint ap2(Clip.point(m_ClRe - 1));
@@ -266,6 +302,8 @@
Clip.setPoint(m_ClRe - 1, ap2);
Clip.setPoint(m_ClRe - 2, np);
}
+
+ // update first or last node with control
if (((m_ClRe == static_cast(StartInd)) || (m_ClRe == static_cast(EndInd - 2))) &&
((currItem->itemType() == PageItem::Polygon)
|| (currItem->itemType() == PageItem::Group)
@@ -275,7 +313,7 @@
{
if (m_ClRe == static_cast(StartInd))
{
- FPoint ap(Clip.point(EndInd- 2));
+ FPoint ap(Clip.point(EndInd - 2));
FPoint ap2(Clip.point(EndInd - 1));
ap2.setX(ap2.x() - (ap.x() - np.x()));
ap2.setY(ap2.y() - (ap.y() - np.y()));
@@ -292,48 +330,53 @@
Clip.setPoint(StartInd + 1, ap2);
}
}
- if (((m_ClRe == static_cast(StartInd + 1)) || (m_ClRe == static_cast(EndInd - 1))) &&
- ((currItem->itemType() == PageItem::Polygon)
+
+ bool firstLastControl = ((m_ClRe == static_cast(StartInd + 1)) || (m_ClRe == static_cast(EndInd - 1)))
+ && ((currItem->itemType() == PageItem::Polygon)
|| (currItem->itemType() == PageItem::Group)
|| (currItem->itemType() == PageItem::Symbol)
|| (currItem->itemType() == PageItem::TextFrame)
- || (currItem->itemType() == PageItem::ImageFrame)) &&
- (m_MoveSym))
+ || (currItem->itemType() == PageItem::ImageFrame));
+
+ bool anyControl = !isNode(m_ClRe) && (m_ClRe != static_cast(StartInd + 1)) && (m_ClRe != static_cast(EndInd - 1));
+
+ // update control if there is an opposite control
+ if (firstLastControl || anyControl)
{
- uint kon = 0;
- if (m_ClRe == static_cast(StartInd + 1))
- kon = EndInd - 1;
- else
- kon = StartInd + 1;
- FPoint lxy(Clip.point(m_ClRe - 1));
- FPoint lk(Clip.point(m_ClRe));
- double dx = lxy.x() - lk.x();
- double dy = lxy.y() - lk.y();
- lk.setX(lk.x() + dx * 2);
- lk.setY(lk.y() + dy * 2);
- Clip.setPoint(kon, lk);
+ int kon = indexOfNode(m_ClRe, Opposite, Clip.size());
+
+ FPoint pn1(Clip.point(m_ClRe - 1));
+ FPoint pc1(Clip.point(m_ClRe));
+ FPoint pc2(pn1 + oppositeControl.relativePos);
+
+ double dx = pn1.x() - pc1.x();
+ double dy = pn1.y() - pc1.y();
+
+ if (moveMode() == Symmetric)
+ {
+ pc2.setX(pc1.x() + dx * 2);
+ pc2.setY(pc1.y() + dy * 2);
+ Clip.setPoint(kon, pc2);
+ }
+ else if (moveMode() == Asymmetric)
+ {
+ double dx2 = pn1.x() - pc2.x();
+ double dy2 = pn1.y() - pc2.y();
+
+ double angle = xy2Deg(dx, dy);
+ double dist = distance(dx2, dy2);
+ Clip.setPoint(kon, getPointFromRotation(pn1, dist, angle));
+ }
}
- if ((m_ClRe % 2 != 0) && (m_MoveSym) && (m_ClRe != static_cast(StartInd + 1)) && (m_ClRe != static_cast(EndInd - 1)))
- {
- uint kon = 0;
- if ((m_ClRe + 1) % 4 == 0)
- kon = m_ClRe + 2;
- else
- kon = m_ClRe - 2;
- FPoint lxy(Clip.point(m_ClRe - 1));
- FPoint lk(Clip.point(m_ClRe));
- double dx = lxy.x() - lk.x();
- double dy = lxy.y() - lk.y();
- lk.setX(lk.x() + dx * 2);
- lk.setY(lk.y() + dy * 2);
- Clip.setPoint(kon, lk);
- }
+
if (Doc->nodeEdit.m_isContourLine)
currItem->ContourLine = Clip.copy();
else
currItem->PoLine = Clip.copy();
+
currItem->Clip = flattenPath(currItem->PoLine, currItem->Segments);
}
+
if (!m_isContourLine)
{
// Move the contour accordingly in the item's coordinate space
@@ -343,12 +386,265 @@
}
}
+void NodeEditContext::equalizeControls(PageItem* currItem)
+{
+ FPointArray Clip(clipFromItem(currItem));
+ int old = m_ClRe;
+ ControlMoveMode cmm = moveMode();
+ FPoint cl, nl, nr, cr;
+ getPoints(currItem, m_ClRe, cl, nl, nr, cr);
+
+ // if there is no left control we use the right one as reference
+ int indexControl = indexOfNode(m_ClRe, (nl == cl) ? ControlRight : ControlLeft, Clip.size());
+
+ // apply changes to opposite control
+ setMoveMode(Symmetric);
+ setClre(indexControl);
+ moveClipPoint(currItem, Clip.point(indexControl));
+
+ // restore old values
+ setClre(old);
+ setMoveMode(cmm);
+}
+
+/**
+ * @brief NodeEditContext::getPoints Map all handle indecies based on i. A bezier curve start with right node and ends with left node
+ * @param currItem Current PageItem
+ * @param i index of any point in page item path
+ * @param ctrlLeft return index of left control handle
+ * @param nodeLeft return index of left node
+ * @param nodeRight return index of right node
+ * @param ctrlRight return index of right control handle
+ */
+void NodeEditContext::getPoints(PageItem* currItem, int i, FPoint& ctrlLeft, FPoint& nodeLeft, FPoint& nodeRight, FPoint& ctrlRight)
+{
+ i = (i == -1) ? m_ClRe : i;
+
+ if (i < 0)
+ return;
+
+ nodeLeft = getPoint(currItem, i, NodeType::NodeLeft);
+ ctrlLeft = getPoint(currItem, i, NodeType::ControlLeft);
+ nodeRight = getPoint(currItem, i, NodeType::NodeRight);
+ ctrlRight = getPoint(currItem, i, NodeType::ControlRight);
+}
+
+FPoint NodeEditContext::getPoint(PageItem* currItem, int i, NodeType nodeType)
+{
+ FPointArray Clip(clipFromItem(currItem));
+ return Clip.point(indexOfNode(i, nodeType, Clip.size()));
+}
+
+bool NodeEditContext::isSymetric(PageItem* currItem, int i)
+{
+ return sameAngle(currItem, i) && sameLength(currItem, i);
+}
+
+bool NodeEditContext::sameAngle(PageItem* currItem, int i)
+{
+ double snap = currItem->doc()->prefsData().guidesPrefs.guideRad / m_scale;
+
+ FPoint pcl, pnl, pnr, pcr;
+ getPoints(currItem, i, pcl, pnl, pnr, pcr);
+
+ if (pnr != pnl)
+ return false;
+
+ QLineF lineLeft(pnl.toQPointF(), pcl.toQPointF());
+ QLineF lineRight(pnr.toQPointF(), pcr.toQPointF());
+ lineRight.setAngle(lineRight.angle() - 180);
+
+ if (qMax(lineLeft.angle(), lineRight.angle()) - qMin(lineLeft.angle(), lineRight.angle()) <= 0.00001)
+ return true;
+
+ if (lineLeft.length() >= lineRight.length())
+ lineRight.setLength(lineLeft.length());
+ else
+ lineLeft.setLength(lineRight.length());
+
+ QLineF distance(lineLeft.p2(), lineRight.p2());
+
+ return distance.length() <= snap ? true : false;
+}
+
+bool NodeEditContext::sameLength(PageItem* currItem, int i)
+{
+ double snap = currItem->doc()->prefsData().guidesPrefs.guideRad / m_scale;
+ FPoint pcl, pnl, pnr, pcr;
+ getPoints(currItem, i, pcl, pnl, pnr, pcr);
+
+ if (pnl != pnr)
+ return false;
+
+ // length = 0
+ if (pcl == pcr)
+ return true;
+
+ double l1 = QLineF(pnl.toQPointF(), pcl.toQPointF()).length();
+ double l2 = QLineF(pnr.toQPointF(), pcr.toQPointF()).length();
+
+ // Check if both controls have same length with difference
+ return (qMax(l1, l2) - qMin(l1, l2) <= snap) ? true : false;
+}
+
+bool NodeEditContext::isLeftControl(int i)
+{
+ return (i + 1) % 4 == 0;
+}
+
+bool NodeEditContext::isLeftNode(int i)
+{
+ return (i % 4 != 0) && isNode(i);
+}
+
+bool NodeEditContext::isRightNode(int i)
+{
+ return i % 4 == 0;
+}
+
+bool NodeEditContext::isRightControl(int i)
+{
+ return (i - 1) % 4 == 0;
+}
+
+bool NodeEditContext::hasTwoNodes(int i, FPointArray clip)
+{
+ int ln = indexOfNode(i, NodeLeft, clip.size());
+ int rn = indexOfNode(i, NodeRight, clip.size());
+
+ return clip.point(ln) == clip.point(rn);
+}
+
+bool NodeEditContext::isSharpNode(int i, FPointArray clip)
+{
+ int lc = indexOfNode(i, ControlLeft, clip.size());
+ int rc = indexOfNode(i, ControlRight, clip.size());
+ int ln = indexOfNode(i, NodeLeft, clip.size());
+ int rn = indexOfNode(i, NodeRight, clip.size());
+
+ return clip.point(ln) == clip.point(rn) && clip.point(ln) == clip.point(lc) && clip.point(rn) == clip.point(rc);
+}
+
+/**
+ * @brief NodeEditContext::indexOfNode Returns the node index based on the input index and node type.
+ * If size is specified, an index between 0 and size is returned. Values outside this range are corrected.
+ * @param i Any index of FPointArray
+ * @param type Node type for output
+ * @param size Max size of node array
+ * @return return index of requested node type based on input index.
+ */
+int NodeEditContext::indexOfNode(int i, NodeType type, int size)
+{
+ if (size != -1)
+ i = qBound(0, i, size);
+
+ if (isRightControl(i))
+ {
+ switch (type)
+ {
+ case NodeType::OppositeSibling:
+ case NodeType::NodeLeft:
+ i -= 3;
+ break;
+ case NodeType::Opposite:
+ case NodeType::ControlLeft:
+ i -= 2;
+ break;
+ case NodeType::Sibling:
+ case NodeType::NodeRight:
+ i -= 1;
+ break;
+ case NodeType::Self:
+ case NodeType::ControlRight:
+ break;
+ }
+
+ if (size != -1 && i < 0)
+ i = size - abs(i);
+ }
+ else if (isLeftControl(i))
+ {
+ switch (type)
+ {
+ case NodeType::Sibling:
+ case NodeType::NodeLeft:
+ i -= 1;
+ break;
+ case NodeType::Self:
+ case NodeType::ControlLeft:
+ break;
+ case NodeType::OppositeSibling:
+ case NodeType::NodeRight:
+ i += 1;
+ break;
+ case NodeType::Opposite:
+ case NodeType::ControlRight:
+ i += 2;
+ break;
+ }
+
+ if (size != -1 && i >= size)
+ i -= size;
+ }
+ else if (isRightNode(i))
+ {
+ switch (type)
+ {
+ case NodeType::Opposite:
+ case NodeType::NodeLeft:
+ i -= 2;
+ break;
+ case NodeType::OppositeSibling:
+ case NodeType::ControlLeft:
+ i -= 1;
+ break;
+ case NodeType::Self:
+ case NodeType::NodeRight:
+ break;
+ case NodeType::Sibling:
+ case NodeType::ControlRight:
+ i += 1;
+ break;
+ }
+
+ if (size != -1 && i < 0)
+ i = size - abs(i);
+ }
+ else if (isLeftNode(i))
+ {
+ switch (type)
+ {
+ case NodeType::Self:
+ case NodeType::NodeLeft:
+ break;
+ case NodeType::Sibling:
+ case NodeType::ControlLeft:
+ i += 1;
+ break;
+ case NodeType::Opposite:
+ case NodeType::NodeRight:
+ i += 2;
+ break;
+ case NodeType::OppositeSibling:
+ case NodeType::ControlRight:
+ i += 3;
+ break;
+ }
+
+ if (size != -1 && i >= size)
+ i -= size;
+ }
+
+ return i;
+}
+
void NodeEditContext::reset1Control(PageItem* currItem)
-{
+{
+ if ((m_ClRe < 0) || isNode(m_ClRe))
+ return;
+
ScribusDoc* Doc = currItem->doc();
- if ((m_ClRe < 0) || (m_ClRe % 2 == 0))
- return;
UndoManager* undoManager = UndoManager::instance();
// do no record anything else but the core reset points action
@@ -401,13 +697,13 @@
void NodeEditContext::resetControl(PageItem* currItem)
{
ScribusDoc* Doc = currItem->doc();
- if (m_ClRe < 0)
+ if (m_ClRe < 0 || !isNode(m_ClRe))
return;
UndoManager* undoManager = UndoManager::instance();
// do no record anything else but the core reset points action
undoManager->setUndoEnabled(false);
-
+
oldClip = new FPointArray(Doc->nodeEdit.m_isContourLine ? currItem->ContourLine.copy() : currItem->PoLine.copy());
m_oldItemX = currItem->xPos();
m_oldItemY = currItem->yPos();
@@ -458,8 +754,8 @@
}
else
{
- Clip.setPoint(Doc->nodeEdit.m_ClRe + 1, np);
- Clip.setPoint((Doc->nodeEdit.m_ClRe % 4 != 0 ? Doc->nodeEdit.m_ClRe + 3 : Doc->nodeEdit.m_ClRe - 1), np);
+ Clip.setPoint(indexOfNode(Doc->nodeEdit.m_ClRe, NodeType::ControlRight, Clip.size()), np);
+ Clip.setPoint(indexOfNode(Doc->nodeEdit.m_ClRe, NodeType::ControlLeft, Clip.size()), np);
}
if (!Doc->nodeEdit.m_isContourLine)
{
@@ -493,3 +789,7 @@
oldClip = nullptr;
}
+FPointArray NodeEditContext::clipFromItem(PageItem* currItem)
+{
+ return isContourLine() ? currItem->ContourLine : currItem->PoLine;
+}
Index: scribus/nodeeditcontext.h
===================================================================
--- scribus/nodeeditcontext.h (Revision 26704)
+++ scribus/nodeeditcontext.h (Arbeitskopie)
@@ -39,6 +39,46 @@
class SCRIBUS_API NodeEditContext : public MassObservable
{
public:
+ enum SubMode
+ {
+ MOVE_POINT = 0,
+ ADD_POINT,
+ DEL_POINT,
+ SPLIT_PATH,
+ EDIT_POINT
+ };
+
+ enum NodeType
+ {
+ ControlLeft = 0,
+ NodeLeft,
+ NodeRight,
+ ControlRight,
+ Opposite, // opposite control/node index of input
+ Sibling, // sibling of node is control, sibling of control is node
+ OppositeSibling, // combination of opposite and sibling
+ Self
+ };
+
+ enum ControlMoveMode
+ {
+ Auto = 0,
+ Symmetric,
+ Asymmetric,
+ Independent
+ };
+
+ struct OppositeControl {
+ FPoint relativePos;
+ bool isValid {false};
+ int controlIndex {-1};
+ int nodeIndex {-1};
+ double distance {0};
+ double angle {0};
+ bool sameAngle {false};
+ bool sameLength {false};
+ };
+
NodeEditContext();
bool isContourLine() { return m_isContourLine; }
@@ -51,17 +91,34 @@
void setSegP1(int i) { m_SegP1 = i; }
int segP2() { return m_SegP2; }
void setSegP2(int i) { m_SegP2 = i; }
- bool edPoints() { return m_EdPoints; }
- void setEdPoints(bool b) { m_EdPoints = b; }
- bool moveSym() { return m_MoveSym; }
- void setMoveSym(bool b) { m_MoveSym = b; }
+ ControlMoveMode moveMode() { return m_moveMode; }
+ void setMoveMode(ControlMoveMode b) { m_moveMode = b; }
+ double scale() { return m_scale; };
+ void setScale(double scale) {m_scale = scale; }
QList& selNode() { return m_SelNode; }
bool hasNodeSelected() const;
void deselect();
void selectNode(int i);
+ void deselectNode(int i);
+ void deselectNodeControls();
int selectionCount() const;
+ void getPoints(PageItem* currItem, int i, FPoint& ctrlLeft, FPoint& nodeLeft, FPoint& nodeRight, FPoint& ctrlRight);
+ FPoint getPoint(PageItem* currItem, int i, NodeType nodeType = NodeType::Self);
+ bool isSymetric(PageItem* currItem, int i = -1);
+ bool sameAngle(PageItem* currItem, int i = -1);
+ bool sameLength(PageItem* currItem, int i = -1);
+
+ static bool isNode(int i) { return i % 2 == 0; }
+ static bool isLeftControl(int i);
+ static bool isLeftNode(int i);
+ static bool isRightNode(int i);
+ static bool isRightControl(int i);
+ static bool hasTwoNodes(int i, FPointArray clip);
+ static bool isSharpNode(int i, FPointArray clip);
+ static int indexOfNode(int i, NodeType type = NodeType::NodeRight, int size = -1);
+
void reset();
void setPreviewMode(bool mode);
bool previewMode() { return m_preview; }
@@ -69,17 +126,18 @@
void setSubMode(int i) { m_submode = i; }
void reset1Control(PageItem* currItem);
void resetControl(PageItem* currItem);
+ FPointArray clipFromItem(PageItem* currItem);
FPointArray beginTransaction(PageItem* currItem);
void finishTransaction(PageItem* currItem);
ScOldNewState* finishTransaction1(PageItem* currItem);
void finishTransaction2(PageItem* currItem, ScOldNewState* state);
void moveClipPoint(PageItem *currItem, const FPoint& ip);
+ void equalizeControls(PageItem *currItem);
FPointArray *oldClip { nullptr };
UndoTransaction nodeTransaction;
+ OppositeControl oppositeControl;
- enum SubMode { MOVE_POINT = 0, ADD_POINT = 1, DEL_POINT = 2, SPLIT_PATH = 3 };
-
protected:
int m_submode { MOVE_POINT };
bool m_isContourLine { false };
@@ -88,11 +146,11 @@
int m_ClRe2 { -1 };
int m_SegP1 { -1 };
int m_SegP2 { -1 };
- bool m_EdPoints { true };
- bool m_MoveSym { false };
+ ControlMoveMode m_moveMode { Auto };
QList m_SelNode;
double m_oldItemX { 0.0 };
double m_oldItemY { 0.0 };
+ double m_scale { 1.0 };
bool m_preview { false };
};
#endif
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp (Revision 26704)
+++ scribus/scribus.cpp (Arbeitskopie)
@@ -5825,11 +5825,11 @@
nodePalette->setDoc(doc, view);
nodePalette->MoveN();
- nodePalette->HaveNode(false, false);
+ nodePalette->HaveNode(false);
nodePalette->MoveNode->setChecked(true);
nodePalette->show();
// qDebug() << "nodepalette show:" << nodePalette->geometry();
- connect(view, SIGNAL(HavePoint(bool,bool)), nodePalette, SLOT(HaveNode(bool,bool)));
+ connect(view, SIGNAL(HavePoint(bool)), nodePalette, SLOT(HaveNode(bool)));
connect(view, SIGNAL(PolyStatus(int,uint)), nodePalette, SLOT(PolyStatus(int,uint)));
doc->nodeEdit.reset();
appModeHelper->setFrameEditMode(true);
@@ -5869,7 +5869,7 @@
void ScribusMainWindow::NoFrameEdit()
{
- disconnect(view, SIGNAL(HavePoint(bool, bool)), nodePalette, SLOT(HaveNode(bool, bool)));
+ disconnect(view, SIGNAL(HavePoint(bool)), nodePalette, SLOT(HaveNode(bool)));
disconnect(view, SIGNAL(PolyStatus(int, uint)), nodePalette, SLOT(PolyStatus(int, uint)));
actionManager->disconnectModeActions();
nodePalette->setDoc(nullptr, nullptr);
Index: scribus/scribusview.cpp
===================================================================
--- scribus/scribusview.cpp (Revision 26704)
+++ scribus/scribusview.cpp (Arbeitskopie)
@@ -1986,7 +1986,6 @@
MidButt = false;
HaveSelRect = false;
Magnify = false;
- m_doc->nodeEdit.setEdPoints(true);
DraggedGroup = false;
//FIXME:av MoveGY = false;
//FIXME:av MoveGX = false;
Index: scribus/scribusview.h
===================================================================
--- scribus/scribusview.h (Revision 26704)
+++ scribus/scribusview.h (Arbeitskopie)
@@ -369,7 +369,7 @@
void DelBM(PageItem *);
void ChBMText(PageItem *);
void LoadElem(QString, double, double, bool, bool, ScribusDoc *, ScribusView *);
- void HavePoint(bool, bool);
+ void HavePoint(bool);
void ClipPo(double, double);
void PolyStatus(int, uint);
void MousePos(double, double);
Index: scribus/ui/nodeeditpalette.cpp
===================================================================
--- scribus/ui/nodeeditpalette.cpp (Revision 26704)
+++ scribus/ui/nodeeditpalette.cpp (Arbeitskopie)
@@ -5,6 +5,7 @@
for which a new license (GPL+exception) is in place.
*/
+#include
#include
#include "nodeeditpalette.h"
@@ -21,302 +22,109 @@
NodePalette::NodePalette( QWidget* parent) : ScrPaletteBase(parent, "nodePalette", false, Qt::WindowFlags())
{
- QSize iconSize(22, 22);
- QSize buttonSize(24, 24);
- QSize maxButtonSize(16777215, buttonSize.height());
- QSizePolicy::Policy buttonSizePolicy = static_cast(QSizePolicy::GrowFlag | QSizePolicy::ExpandFlag);
+ setupUi(this);
- vboxLayout = new QVBoxLayout(this);
- vboxLayout->setSpacing(6);
- vboxLayout->setContentsMargins(6, 6, 6, 6);
-
- MoveNode = new QToolButton(this);
- MoveNode->setIconSize(iconSize);
- MoveNode->setMinimumSize(buttonSize);
- MoveNode->setMaximumSize(maxButtonSize);
- MoveNode->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
MoveNode->setCheckable(true);
MoveNode->setChecked(true);
- AddNode = new QToolButton(this);
- AddNode->setIconSize(iconSize);
- AddNode->setMinimumSize(buttonSize);
- AddNode->setMaximumSize(maxButtonSize);
- AddNode->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
AddNode->setEnabled(true);
AddNode->setCheckable(true);
- DeleteNode = new QToolButton(this);
- DeleteNode->setIconSize(iconSize);
- DeleteNode->setMinimumSize(buttonSize);
- DeleteNode->setMaximumSize(maxButtonSize);
- DeleteNode->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
DeleteNode->setEnabled(true);
DeleteNode->setCheckable(true);
- ResNode = new QToolButton(this);
- ResNode->setIconSize(iconSize);
- ResNode->setMinimumSize(buttonSize);
- ResNode->setMaximumSize(maxButtonSize);
- ResNode->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
- ResNode->setEnabled(true);
+ EditControl->setCheckable(true);
+ EditControl->setChecked(true);
- MoveControl = new QToolButton(this);
- MoveControl->setIconSize(iconSize);
- MoveControl->setMinimumSize(buttonSize);
- MoveControl->setMaximumSize(maxButtonSize);
- MoveControl->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
- MoveControl->setCheckable(true);
-
- AsymMove = new QToolButton(this);
- AsymMove->setIconSize(iconSize);
- AsymMove->setMinimumSize(buttonSize);
- AsymMove->setMaximumSize(maxButtonSize);
- AsymMove->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
- AsymMove->setEnabled(false);
AsymMove->setCheckable(true);
+ AsymMove->setChecked(false);
- SymMove = new QToolButton(this);
- SymMove->setIconSize(iconSize);
- SymMove->setMinimumSize(buttonSize);
- SymMove->setMaximumSize(maxButtonSize);
- SymMove->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
- SymMove->setEnabled(false);
SymMove->setCheckable(true);
+ SymMove->setChecked(false);
- Res1Node = new QToolButton(this);
- Res1Node->setIconSize(iconSize);
- Res1Node->setMinimumSize(buttonSize);
- Res1Node->setMaximumSize(maxButtonSize);
- Res1Node->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
- Res1Node->setEnabled(false);
+ IndependentMove->setCheckable(true);
+ IndependentMove->setChecked(false);
- PolySplit = new QToolButton(this);
PolySplit->setEnabled(false);
PolySplit->setCheckable(true);
- PolySplit->setIconSize(iconSize);
- PolySplit->setMinimumSize(buttonSize);
- PolySplit->setMaximumSize(maxButtonSize);
- PolySplit->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
- BezierClose = new QToolButton(this);
BezierClose->setEnabled(false);
- BezierClose->setIconSize(iconSize);
- BezierClose->setMinimumSize(buttonSize);
- BezierClose->setMaximumSize(maxButtonSize);
- BezierClose->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
- PolyMirrorH = new QToolButton(this);
- PolyMirrorH->setIconSize(iconSize);
- PolyMirrorH->setMinimumSize(buttonSize);
- PolyMirrorH->setMaximumSize(maxButtonSize);
- PolyMirrorH->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
-
- PolyMirrorV = new QToolButton(this);
- PolyMirrorV->setIconSize(iconSize);
- PolyMirrorV->setMinimumSize(buttonSize);
- PolyMirrorV->setMaximumSize(maxButtonSize);
- PolyMirrorV->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
-
- PolyShearL = new QToolButton(this);
- PolyShearL->setIconSize(iconSize);
- PolyShearL->setMinimumSize(buttonSize);
- PolyShearL->setMaximumSize(maxButtonSize);
- PolyShearL->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
PolyShearL->setAutoRepeat(true);
-
- PolyShearR = new QToolButton(this);
- PolyShearR->setIconSize(iconSize);
- PolyShearR->setMinimumSize(buttonSize);
- PolyShearR->setMaximumSize(maxButtonSize);
- PolyShearR->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
PolyShearR->setAutoRepeat(true);
-
- PolyShearU = new QToolButton(this);
- PolyShearU->setIconSize(iconSize);
- PolyShearU->setMinimumSize(buttonSize);
- PolyShearU->setMaximumSize(maxButtonSize);
- PolyShearU->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
PolyShearU->setAutoRepeat(true);
-
- PolyShearD = new QToolButton(this);
- PolyShearD->setIconSize(iconSize);
- PolyShearD->setMinimumSize(buttonSize);
- PolyShearD->setMaximumSize(maxButtonSize);
- PolyShearD->setSizePolicy(QSizePolicy(buttonSizePolicy, QSizePolicy::Fixed));
PolyShearD->setAutoRepeat(true);
-
- RotateCCW = new QToolButton(this);
- RotateCCW->setIconSize(iconSize);
- RotateCCW->setMinimumSize(buttonSize);
- RotateCCW->setMaximumSize(buttonSize);
RotateCCW->setAutoRepeat(true);
-
- RotateCW = new QToolButton(this);
- RotateCW->setIconSize(iconSize);
- RotateCW->setMinimumSize(buttonSize);
- RotateCW->setMaximumSize(buttonSize);
RotateCW->setAutoRepeat(true);
- RotVal = new QSpinBox(this);
RotVal->setMinimum(1);
RotVal->setMaximum(180);
RotVal->setValue(1);
RotVal->setSuffix( QString::fromUtf8(" °"));
- Expand = new QToolButton(this);
- Expand->setIconSize(iconSize);
- Expand->setMinimumSize(buttonSize);
- Expand->setMaximumSize(buttonSize);
Expand->setAutoRepeat(true);
-
- Shrink = new QToolButton(this);
- Shrink->setIconSize(iconSize);
- Shrink->setMinimumSize(buttonSize);
- Shrink->setMaximumSize(buttonSize);
Shrink->setAutoRepeat(true);
- scalePercentage = new QSpinBox(this);
scalePercentage->setMinimum(1);
scalePercentage->setMaximum(100);
scalePercentage->setValue(10);
- Enlarge = new QToolButton(this);
- Enlarge->setIconSize(iconSize);
- Enlarge->setMinimumSize(buttonSize);
- Enlarge->setMaximumSize(buttonSize);
Enlarge->setAutoRepeat(true);
-
- Reduce = new QToolButton(this);
- Reduce->setIconSize(iconSize);
- Reduce->setMinimumSize(buttonSize);
- Reduce->setMaximumSize(buttonSize);
Reduce->setAutoRepeat(true);
- scaleDistance = new ScrSpinBox( 1, 16777215, this, 0);
- scaleDistance->setMaximumSize(114, 16777215); // ScrSpinBox is bigger for 4px than expected
+ scaleDistance->setMaximumSize(114, 16777215);
scaleDistance->setValues(-16777215, 16777215, 2, 30);
- gridLayout = new QGridLayout();
- gridLayout->setSpacing(6);
- gridLayout->setContentsMargins(0, 0, 0, 0);
- gridLayout->addWidget(MoveNode, 0, 1, 1, 1);
- gridLayout->addWidget(AddNode, 0, 2, 1, 1);
- gridLayout->addWidget(DeleteNode, 0, 3, 1, 1);
- gridLayout->addWidget(ResNode, 0, 4, 1, 1);
- gridLayout->addWidget(MoveControl, 1, 1, 1, 1);
- gridLayout->addWidget(AsymMove, 1, 2, 1, 1);
- gridLayout->addWidget(SymMove, 1, 3, 1, 1);
- gridLayout->addWidget(Res1Node, 1, 4, 1, 1);
- gridLayout->addWidget(PolySplit, 2, 1, 1, 1);
- gridLayout->addWidget(BezierClose, 2, 2, 1, 1);
- gridLayout->addWidget(PolyMirrorH, 2, 3, 1, 1);
- gridLayout->addWidget(PolyMirrorV, 2, 4, 1, 1);
- gridLayout->addWidget(PolyShearL, 3, 1, 1, 1);
- gridLayout->addWidget(PolyShearR, 3, 2, 1, 1);
- gridLayout->addWidget(PolyShearU, 3, 3, 1, 1);
- gridLayout->addWidget(PolyShearD, 3, 4, 1, 1);
- vboxLayout->addLayout(gridLayout);
-
- gridLayout2 = new QGridLayout();
- gridLayout2->setSpacing(6);
- gridLayout2->setContentsMargins(0, 0, 0, 0);
- gridLayout2->addWidget(RotVal, 0, 0, 1, 4);
- gridLayout2->addWidget(RotateCCW, 0, 4, 1, 1);
- gridLayout2->addWidget(RotateCW, 0, 5, 1, 1);
- gridLayout2->addWidget(scalePercentage, 1, 0, 1, 4);
- gridLayout2->addWidget(Expand, 1, 4, 1, 1);
- gridLayout2->addWidget(Shrink, 1, 5, 1, 1);
- gridLayout2->addWidget(scaleDistance, 2, 0, 1, 4);
- gridLayout2->addWidget(Enlarge, 2, 4, 1, 1);
- gridLayout2->addWidget(Reduce, 2, 5, 1, 1);
- vboxLayout->addLayout(gridLayout2);
-
- QSpacerItem* spacer = new QSpacerItem( 6, 6, QSizePolicy::Fixed, QSizePolicy::Fixed );
- vboxLayout->addItem(spacer);
-
- AbsMode = new QGroupBox( "&Absolute Coordinates", this );
- AbsMode->setCheckable(true);
- AbsMode->setChecked(false);
- vboxLayout1 = new QVBoxLayout(AbsMode);
- vboxLayout1->setSpacing(6);
- vboxLayout1->setContentsMargins(9, 9, 9, 9);
- absToCanvas = new QRadioButton( tr("to Canvas"), AbsMode);
- vboxLayout1->addWidget(absToCanvas);
- absToPage = new QRadioButton( tr("to Page"), AbsMode);
- vboxLayout1->addWidget(absToPage);
- absToCanvas->setChecked(true);
- vboxLayout->addWidget(AbsMode);
-
- gridLayout3 = new QGridLayout();
- gridLayout3->setSpacing(6);
- gridLayout3->setContentsMargins(0, 0, 0, 0);
- gridLayout3->setColumnStretch(0, 0);
- gridLayout3->setColumnStretch(1, 1);
-
- TextLabel1 = new QLabel(this);
- gridLayout3->addWidget(TextLabel1, 0, 0, 1, 1);
-
- XSpin = new ScrSpinBox( 0, 16777215, this, 2 );
+ XSpin->setMinimum(0);
+ XSpin->setMaximum(16777215);
+ XSpin->setNewUnit(2);
XSpin->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed));
XSpin->setEnabled(false);
- gridLayout3->addWidget(XSpin, 0, 1, 1, 1);
- TextLabel2 = new QLabel(this);
- gridLayout3->addWidget(TextLabel2, 1, 0, 1, 1);
-
- YSpin = new ScrSpinBox( 0, 16777215, this, 2 );
+ YSpin->setMinimum(0);
+ YSpin->setMaximum(16777215);
+ YSpin->setNewUnit(2);
YSpin->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed));
YSpin->setEnabled(false);
- gridLayout3->addWidget(YSpin, 1, 1, 1, 1);
- vboxLayout->addLayout(gridLayout3);
TextLabel1->setBuddy(XSpin);
TextLabel2->setBuddy(YSpin);
- EditCont = new QCheckBox(this);
EditCont->setChecked(false);
- vboxLayout->addWidget(EditCont);
- PreviewMode = new QCheckBox(this);
PreviewMode->setChecked(false);
- vboxLayout->addWidget(PreviewMode);
- ResetCont = new QPushButton(this);
ResetCont->setEnabled(false);
- vboxLayout->addWidget(ResetCont);
- ResetContClip = new QPushButton(this);
ResetContClip->setEnabled(true);
ResetContClip->hide();
- vboxLayout->addWidget(ResetContClip);
- ResetShape2Clip = new QPushButton(this);
ResetShape2Clip->setEnabled(true);
ResetShape2Clip->hide();
- vboxLayout->addWidget(ResetShape2Clip);
- resetDefaultButton = new QPushButton(this);
resetDefaultButton->setEnabled(true);
- vboxLayout->addWidget(resetDefaultButton);
- hboxLayout = new QHBoxLayout();
- hboxLayout->setSpacing(6);
- hboxLayout->setContentsMargins(0, 0, 0, 0);
- editEditButton = new QPushButton(IconManager::instance().loadIcon("exit"), tr("OK"), this);
editEditButton->setEnabled(true);
editEditButton->setDefault(true);
- hboxLayout->addWidget(editEditButton);
- cancelEditButton = new QPushButton( tr("Cancel"), this);
+
cancelEditButton->setEnabled(true);
- hboxLayout->addWidget(cancelEditButton);
- vboxLayout->addLayout(hboxLayout);
+ QButtonGroup *btngpTools = new QButtonGroup();
+ btngpTools->setExclusive(true);
+ btngpTools->addButton(MoveNode);
+ btngpTools->addButton(AddNode);
+ btngpTools->addButton(DeleteNode);
+ btngpTools->addButton(PolySplit);
+ btngpTools->addButton(BezierClose);
+ btngpTools->addButton(EditControl);
+
resize(QSize(170, 380).expandedTo(minimumSizeHint()));
layout()->setSizeConstraint(QLayout::SetFixedSize);
iconSetChange();
languageChange();
+ PosOriginButton->setCurrentIndex(m_posOrigin);
+
connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
}
@@ -331,11 +139,10 @@
connect(MoveNode, SIGNAL(clicked()), this, SLOT(MoveN()));
connect(AsymMove, SIGNAL(clicked()), this, SLOT(SetAsym()));
connect(SymMove, SIGNAL(clicked()), this, SLOT(SetSym()));
- connect(ResNode, SIGNAL(clicked()), this, SLOT(ResetControl()));
- connect(Res1Node, SIGNAL(clicked()), this, SLOT(Reset1Control()));
+ connect(IndependentMove, SIGNAL(clicked()), this, SLOT(SetIndependentMove()));
+ connect(EditControl, SIGNAL(clicked()), this, SLOT(editControl()));
connect(BezierClose, SIGNAL(clicked()), this, SLOT(CloseBezier()));
connect(PolySplit, SIGNAL(clicked()), this, SLOT(SplitPoly()));
- connect(MoveControl, SIGNAL(clicked()), this, SLOT(MoveK()));
connect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
connect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
connect(PolyMirrorH, SIGNAL(clicked()), this, SLOT(MirrorH()));
@@ -350,14 +157,12 @@
connect(Expand, SIGNAL(clicked()), this, SLOT(doExpand()));
connect(Reduce, SIGNAL(clicked()), this, SLOT(doReduce()));
connect(Enlarge, SIGNAL(clicked()), this, SLOT(doEnlarge()));
- connect(AbsMode, SIGNAL(clicked()), this, SLOT(ToggleAbsMode()));
- connect(absToCanvas, SIGNAL(clicked()), this, SLOT(ToggleAbsMode()));
- connect(absToPage, SIGNAL(clicked()), this, SLOT(ToggleAbsMode()));
- connect(EditCont, SIGNAL(clicked()), this, SLOT(ToggleConMode()));
+ connect(EditCont, SIGNAL(clicked()), this, SLOT(ToggleContourMode()));
connect(ResetCont, SIGNAL(clicked()), this, SLOT(ResetContour()));
connect(ResetContClip, SIGNAL(clicked()), this, SLOT(ResetContourToImageClip()));
connect(ResetShape2Clip, SIGNAL(clicked()), this, SLOT(ResetShapeToImageClip()));
connect(PreviewMode, SIGNAL(clicked()), this, SLOT(TogglePreview()));
+ connect(PosOriginButton, SIGNAL(currentIndexChanged(int)), this, SLOT(changePosOrigin(int)));
}
void NodePalette::disconnectSignals()
@@ -371,11 +176,10 @@
disconnect(MoveNode, SIGNAL(clicked()), this, SLOT(MoveN()));
disconnect(AsymMove, SIGNAL(clicked()), this, SLOT(SetAsym()));
disconnect(SymMove, SIGNAL(clicked()), this, SLOT(SetSym()));
- disconnect(ResNode, SIGNAL(clicked()), this, SLOT(ResetControl()));
- disconnect(Res1Node, SIGNAL(clicked()), this, SLOT(Reset1Control()));
+ disconnect(IndependentMove, SIGNAL(clicked()), this, SLOT(SetIndependentMove()));
+ disconnect(EditControl, SIGNAL(clicked()), this, SLOT(editControl()));
disconnect(BezierClose, SIGNAL(clicked()), this, SLOT(CloseBezier()));
disconnect(PolySplit, SIGNAL(clicked()), this, SLOT(SplitPoly()));
- disconnect(MoveControl, SIGNAL(clicked()), this, SLOT(MoveK()));
disconnect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
disconnect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
disconnect(PolyMirrorH, SIGNAL(clicked()), this, SLOT(MirrorH()));
@@ -394,8 +198,25 @@
disconnect(ResetContClip, SIGNAL(clicked()), this, SLOT(ResetContourToImageClip()));
disconnect(ResetShape2Clip, SIGNAL(clicked()), this, SLOT(ResetShapeToImageClip()));
disconnect(PreviewMode, SIGNAL(clicked()), this, SLOT(TogglePreview()));
+ disconnect(PosOriginButton, SIGNAL(currentIndexChanged(int)), this, SLOT(changePosOrigin(int)));
}
+void NodePalette::initPosOriginMenu()
+{
+ IconManager& im = IconManager::instance();
+ QSignalBlocker sigPosOriginButton(PosOriginButton);
+
+ int index = PosOriginButton->currentIndex();
+
+ PosOriginButton->clear();
+ PosOriginButton->addAction(im.loadIcon("position-origin-canvas"), tr("Canvas"))->setData(PositionOrigin::Canvas);
+ PosOriginButton->addAction(im.loadIcon("position-origin-page"), tr("Page"))->setData(PositionOrigin::Page);
+ PosOriginButton->addAction(im.loadIcon("position-origin-item"), tr("Item"))->setData(PositionOrigin::Item);
+
+ PosOriginButton->setCurrentIndex(index);
+
+}
+
void NodePalette::setDoc(ScribusDoc *dc, ScribusView *vi)
{
m_doc = dc;
@@ -402,14 +223,15 @@
m_view = vi;
unitChange();
- disconnect(EditCont, SIGNAL(clicked()), this, SLOT(ToggleConMode()));
- disconnect(AbsMode, SIGNAL(clicked()), this, SLOT(ToggleAbsMode()));
+ disconnect(EditCont, SIGNAL(clicked()), this, SLOT(ToggleContourMode()));
+ disconnect(PosOriginButton, SIGNAL(currentIndexChanged(int)), this, SLOT(changePosOrigin(int)));
if (m_doc != nullptr)
{
YSpin->setNewUnit(m_doc->unitIndex());
XSpin->setNewUnit(m_doc->unitIndex());
}
- AbsMode->setChecked(false);
+ PosOriginButton->setCurrentIndex(Page);
+
EditCont->setChecked(false);
if (m_doc == nullptr)
disconnectSignals();
@@ -417,20 +239,11 @@
connectSignals();
}
-void NodePalette::SplitPoly()
-{
- if (m_doc == nullptr)
- return;
- MoveN();
- m_doc->nodeEdit.setSubMode(NodeEditContext::SPLIT_PATH);
- PolySplit->setChecked(true);
-}
-
void NodePalette::IsOpen()
{
if (m_doc == nullptr)
return;
- PolySplit->setChecked(false);
+ MoveNode->setChecked(true);
BezierClose->setEnabled(true);
PolySplit->setEnabled(true);
EditCont->setEnabled(false);
@@ -459,21 +272,6 @@
}
}
-void NodePalette::CloseBezier()
-{
- if (m_doc == nullptr)
- return;
- MoveN();
- PageItem *currItem = m_doc->m_Selection->itemAt(0);
- PageItem* newItem = m_doc->convertItemTo(currItem, PageItem::Polygon);
- m_doc->m_Selection->clear();
- m_doc->m_Selection->addItem(newItem);
- newItem->update();
- BezierClose->setEnabled(false);
- PolySplit->setEnabled(true);
- EditCont->setEnabled(true);
-}
-
void NodePalette::doRotCCW()
{
if (m_doc == nullptr)
@@ -558,20 +356,6 @@
m_doc->MirrorPolyV(m_doc->m_Selection->itemAt(0));
}
-void NodePalette::ResetControl()
-{
- if (m_doc == nullptr)
- return;
- m_doc->nodeEdit.resetControl(m_doc->m_Selection->itemAt(0));
-}
-
-void NodePalette::Reset1Control()
-{
- if (m_doc == nullptr)
- return;
- m_doc->nodeEdit.reset1Control(m_doc->m_Selection->itemAt(0));
-}
-
void NodePalette::ResetContour()
{
if (m_doc == nullptr)
@@ -629,9 +413,9 @@
PageItem *currItem = m_doc->m_Selection->itemAt(0);
FPoint zp;
FPoint np(XSpin->value() / m_doc->unitRatio(), YSpin->value() / m_doc->unitRatio());
- if (AbsMode->isChecked())
+ if (m_posOrigin == Canvas || m_posOrigin == Page)
{
- if (absToCanvas->isChecked())
+ if (m_posOrigin == Canvas)
zp = FPoint(currItem->xPos(), currItem->yPos());
else
zp = FPoint(currItem->xPos() - m_doc->currentPage()->xOffset(), currItem->yPos() - m_doc->currentPage()->yOffset());
@@ -648,43 +432,50 @@
void NodePalette::SetSym()
{
- if (m_doc != nullptr)
- m_doc->nodeEdit.setMoveSym(true);
- SymMove->setChecked(true);
AsymMove->setChecked(false);
+ IndependentMove->setChecked(false);
PolySplit->setChecked(false);
+
+ if (m_doc == nullptr)
+ return;
+
+ if (SymMove->isChecked())
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Symmetric);
+ else
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Auto);
}
void NodePalette::SetAsym()
{
- if (m_doc != nullptr)
- m_doc->nodeEdit.setMoveSym(false);
SymMove->setChecked(false);
- AsymMove->setChecked(true);
+ IndependentMove->setChecked(false);
PolySplit->setChecked(false);
+
+ if (m_doc == nullptr)
+ return;
+
+ if (AsymMove->isChecked())
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Asymmetric);
+ else
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Auto);
}
-void NodePalette::SetXY(double x, double y)
+void NodePalette::SetIndependentMove()
{
+ SymMove->setChecked(false);
+ AsymMove->setChecked(false);
+ PolySplit->setChecked(false);
+
if (m_doc == nullptr)
return;
- FPoint zp(0.0, 0.0);
- disconnect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
- disconnect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
- if (AbsMode->isChecked())
- {
- if (absToCanvas->isChecked())
- zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos(), m_doc->m_Selection->itemAt(0)->yPos());
- else
- zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos() - m_doc->currentPage()->xOffset(), m_doc->m_Selection->itemAt(0)->yPos() - m_doc->currentPage()->yOffset());
- }
- XSpin->setValue((x + zp.x()) * m_doc->unitRatio());
- YSpin->setValue((y + zp.y()) * m_doc->unitRatio());
- connect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
- connect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
+
+ if (IndependentMove->isChecked())
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Independent);
+ else
+ m_doc->nodeEdit.setMoveMode(NodeEditContext::Auto);
}
-void NodePalette::ToggleAbsMode()
+void NodePalette::SetXY(double x, double y)
{
if (m_doc == nullptr)
return;
@@ -691,35 +482,19 @@
FPoint zp(0.0, 0.0);
disconnect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
disconnect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
- FPointArray Clip;
- FPoint np(0.0, 0.0);
- if (EditCont->isChecked())
- Clip = m_doc->m_Selection->itemAt(0)->ContourLine;
- else
- Clip = m_doc->m_Selection->itemAt(0)->PoLine;
- if (m_doc->nodeEdit.selectionCount() != 0)
- np = Clip.point(m_doc->nodeEdit.selNode().at(0));
- if (AbsMode->isChecked())
- {
- XSpin->setMinimum(-16777215);
- YSpin->setMinimum(-16777215);
- if (absToCanvas->isChecked())
- zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos(), m_doc->m_Selection->itemAt(0)->yPos());
- else
- zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos() - m_doc->currentPage()->xOffset(), m_doc->m_Selection->itemAt(0)->yPos() - m_doc->currentPage()->yOffset());
- }
- else
- {
- XSpin->setMinimum(0);
- YSpin->setMinimum(0);
- }
- XSpin->setValue((np.x() + zp.x()) * m_doc->unitRatio());
- YSpin->setValue((np.y() + zp.y()) * m_doc->unitRatio());
+
+ if (PosOriginButton->currentIndex() == Page)
+ zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos() - m_doc->currentPage()->xOffset(), m_doc->m_Selection->itemAt(0)->yPos() - m_doc->currentPage()->yOffset());
+ else if (PosOriginButton->currentIndex() == Canvas)
+ zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos(), m_doc->m_Selection->itemAt(0)->yPos());
+
+ XSpin->setValue((x + zp.x()) * m_doc->unitRatio());
+ YSpin->setValue((y + zp.y()) * m_doc->unitRatio());
connect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
connect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
}
-void NodePalette::ToggleConMode()
+void NodePalette::ToggleContourMode()
{
if (m_doc == nullptr)
return;
@@ -748,7 +523,7 @@
PolySplit->setEnabled(true);
ResetCont->setEnabled(false);
ResetContClip->setEnabled(false);
- if (AbsMode->isChecked())
+ if (m_posOrigin == Canvas | m_posOrigin == Page)
{
XSpin->setMinimum(-16777215);
YSpin->setMinimum(-16777215);
@@ -773,10 +548,52 @@
m_doc->regionsChanged()->update(QRectF());
}
-void NodePalette::HaveNode(bool have, bool mov)
+void NodePalette::changePosOrigin(int index)
{
+ m_posOrigin = index;
+
if (m_doc == nullptr)
return;
+
+ FPoint zp(0.0, 0.0);
+ disconnect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
+ disconnect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
+ FPointArray Clip;
+ FPoint np(0.0, 0.0);
+
+ if (EditCont->isChecked())
+ Clip = m_doc->m_Selection->itemAt(0)->ContourLine;
+ else
+ Clip = m_doc->m_Selection->itemAt(0)->PoLine;
+
+ if (m_doc->nodeEdit.selectionCount() != 0)
+ np = Clip.point(m_doc->nodeEdit.selNode().at(0));
+
+ if (m_posOrigin == Canvas || m_posOrigin == Page)
+ {
+ XSpin->setMinimum(-16777215);
+ YSpin->setMinimum(-16777215);
+ if (m_posOrigin == Canvas)
+ zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos(), m_doc->m_Selection->itemAt(0)->yPos());
+ else
+ zp = FPoint(m_doc->m_Selection->itemAt(0)->xPos() - m_doc->currentPage()->xOffset(), m_doc->m_Selection->itemAt(0)->yPos() - m_doc->currentPage()->yOffset());
+ }
+ else
+ {
+ XSpin->setMinimum(0);
+ YSpin->setMinimum(0);
+ }
+
+ XSpin->setValue((np.x() + zp.x()) * m_doc->unitRatio());
+ YSpin->setValue((np.y() + zp.y()) * m_doc->unitRatio());
+ connect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
+ connect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(MovePoint()));
+}
+
+void NodePalette::HaveNode(bool have)
+{
+ if (m_doc == nullptr)
+ return;
bool setter = have;
if (m_doc->nodeEdit.selectionCount() > 1)
{
@@ -788,35 +605,7 @@
XSpin->setEnabled(setter);
YSpin->setEnabled(setter);
}
- if (setter)
- {
- if (m_doc->nodeEdit.edPoints())
- ResNode->setEnabled(setter);
- else
- Res1Node->setEnabled(setter);
- }
- else
- {
- ResNode->setEnabled(setter);
- Res1Node->setEnabled(setter);
- }
- if (m_doc->nodeEdit.submode() == NodeEditContext::MOVE_POINT)
- {
- disconnect(AsymMove, SIGNAL(clicked()), this, SLOT(SetAsym()));
- disconnect(SymMove, SIGNAL(clicked()), this, SLOT(SetSym()));
- if (mov)
- {
- SymMove->setChecked(true);
- AsymMove->setChecked(false);
- }
- else
- {
- AsymMove->setChecked(true);
- SymMove->setChecked(false);
- }
- connect(AsymMove, SIGNAL(clicked()), this, SLOT(SetAsym()));
- connect(SymMove, SIGNAL(clicked()), this, SLOT(SetSym()));
- }
+
if (m_doc->nodeEdit.submode() == NodeEditContext::DEL_POINT)
{
uint cc;
@@ -837,91 +626,106 @@
leaveEd = true;
}
if (leaveEd)
- {
MoveN();
- MoveControl->setEnabled(true);
- }
}
}
-void NodePalette::MoveK()
+void NodePalette::MoveN()
{
if (m_doc == nullptr)
return;
+
m_doc->nodeEdit.setSubMode(NodeEditContext::MOVE_POINT);
- m_doc->nodeEdit.setEdPoints(false);
m_doc->nodeEdit.setClre(-1);
m_doc->nodeEdit.setClre2(-1);
m_doc->nodeEdit.setSegP1(-1);
m_doc->nodeEdit.setSegP2(-1);
+
if (m_doc->m_Selection->count() > 0)
m_doc->m_Selection->itemAt(0)->update();
+
SymMove->setEnabled(true);
AsymMove->setEnabled(true);
- Res1Node->setEnabled(false);
- ResNode->setEnabled(false);
- AddNode->setEnabled(false);
- DeleteNode->setEnabled(false);
- MoveNode->setChecked(false);
- MoveControl->setChecked(true);
- DeleteNode->setChecked(false);
- AddNode->setChecked(false);
- PolySplit->setChecked(false);
+ IndependentMove->setEnabled(true);
+ MoveNode->setChecked(true);
}
-void NodePalette::MoveN()
+void NodePalette::AddN()
{
if (m_doc == nullptr)
return;
- m_doc->nodeEdit.setSubMode(NodeEditContext::MOVE_POINT);
- m_doc->nodeEdit.setEdPoints(true);
+
+ m_doc->nodeEdit.setSubMode(NodeEditContext::ADD_POINT);
+ SymMove->setEnabled(false);
+ AsymMove->setEnabled(false);
+ IndependentMove->setEnabled(false);
+ AddNode->setChecked(true);
+}
+
+void NodePalette::DelN()
+{
+ if (m_doc == nullptr)
+ return;
+
+ m_doc->nodeEdit.setSubMode(NodeEditContext::DEL_POINT);
+ SymMove->setEnabled(false);
+ AsymMove->setEnabled(false);
+ IndependentMove->setEnabled(false);
+ DeleteNode->setChecked(true);
+}
+
+void NodePalette::SplitPoly()
+{
+ if (m_doc == nullptr)
+ return;
+
+ m_doc->nodeEdit.setSubMode(NodeEditContext::SPLIT_PATH);
m_doc->nodeEdit.setClre(-1);
m_doc->nodeEdit.setClre2(-1);
m_doc->nodeEdit.setSegP1(-1);
m_doc->nodeEdit.setSegP2(-1);
+
if (m_doc->m_Selection->count() > 0)
m_doc->m_Selection->itemAt(0)->update();
- ResNode->setEnabled(false);
- AddNode->setEnabled(true);
- DeleteNode->setEnabled(true);
+
SymMove->setEnabled(false);
AsymMove->setEnabled(false);
- Res1Node->setEnabled(false);
- MoveNode->setChecked(true);
- MoveControl->setChecked(false);
- DeleteNode->setChecked(false);
- AddNode->setChecked(false);
- PolySplit->setChecked(false);
+ IndependentMove->setEnabled(false);
+ PolySplit->setChecked(true);
}
-void NodePalette::AddN()
+void NodePalette::editControl()
{
if (m_doc == nullptr)
return;
- m_doc->nodeEdit.setSubMode(NodeEditContext::ADD_POINT);
- m_doc->nodeEdit.setEdPoints(true);
+
+ m_doc->nodeEdit.setSubMode(NodeEditContext::EDIT_POINT);
+ m_doc->nodeEdit.setClre(-1);
+ m_doc->nodeEdit.setClre2(-1);
+ m_doc->nodeEdit.setSegP1(-1);
+ m_doc->nodeEdit.setSegP2(-1);
+
SymMove->setEnabled(false);
AsymMove->setEnabled(false);
- ResNode->setEnabled(false);
- Res1Node->setEnabled(false);
- AddNode->setChecked(true);
- DeleteNode->setChecked(false);
- PolySplit->setChecked(false);
+ IndependentMove->setEnabled(false);
+ EditControl->setChecked(true);
+
}
-void NodePalette::DelN()
+void NodePalette::CloseBezier()
{
if (m_doc == nullptr)
return;
- m_doc->nodeEdit.setSubMode(NodeEditContext::DEL_POINT);
- m_doc->nodeEdit.setEdPoints(true);
- SymMove->setEnabled(false);
- AsymMove->setEnabled(false);
- ResNode->setEnabled(false);
- Res1Node->setEnabled(false);
- AddNode->setChecked(false);
- DeleteNode->setChecked(true);
- PolySplit->setChecked(false);
+
+ MoveN();
+ PageItem *currItem = m_doc->m_Selection->itemAt(0);
+ PageItem* newItem = m_doc->convertItemTo(currItem, PageItem::Polygon);
+ m_doc->m_Selection->clear();
+ m_doc->m_Selection->addItem(newItem);
+ newItem->update();
+ BezierClose->setEnabled(false);
+ PolySplit->setEnabled(true);
+ EditCont->setEnabled(true);
}
void NodePalette::closeEvent(QCloseEvent *ce)
@@ -956,7 +760,7 @@
m_doc->nodeEdit.selNode().clear();
m_doc->nodeEdit.setPreviewMode(false);
EditCont->setChecked(false);
- ToggleConMode();
+ ToggleContourMode();
PageItem *currItem = m_doc->m_Selection->itemAt(0);
if (currItem && currItem->itemType() == PageItem::PathText)
currItem->updatePolyClip();
@@ -979,7 +783,7 @@
m_doc->nodeEdit.selNode().clear();
m_doc->nodeEdit.setPreviewMode(false);
EditCont->setChecked(false);
- ToggleConMode();
+ ToggleContourMode();
PageItem *currItem = m_doc->m_Selection->itemAt(0);
// Calculate the difference of the current position and the original
@@ -1069,14 +873,16 @@
{
IconManager& im = IconManager::instance();
+//<<<<<<< .mine
+ initPosOriginMenu();
+
MoveNode->setIcon(im.loadIcon("bezier-node-move"));
AddNode->setIcon(im.loadIcon("bezier-node-add"));
DeleteNode->setIcon(im.loadIcon("bezier-node-delete"));
- ResNode->setIcon(im.loadIcon("bezier-control-reset-all"));
- MoveControl->setIcon(im.loadIcon("bezier-control-move"));
AsymMove->setIcon(im.loadIcon("bezier-control-asymetric"));
SymMove->setIcon(im.loadIcon("bezier-control-symetric"));
- Res1Node->setIcon(im.loadIcon("bezier-control-reset"));
+ IndependentMove->setIcon(im.loadIcon("bezier-control-independent"));
+ EditControl->setIcon(im.loadIcon("bezier-node-edit"));
PolySplit->setIcon(im.loadIcon("bezier-split"));
BezierClose->setIcon(im.loadIcon("bezier-close"));
PolyMirrorH->setIcon(im.loadIcon("object-flip-horizontal"));
@@ -1091,6 +897,13 @@
Shrink->setIcon(im.loadIcon("bezier-scale-down"));
Enlarge->setIcon(im.loadIcon("bezier-scale-up"));
Reduce->setIcon(im.loadIcon("bezier-scale-down"));
+
+ EditCont->setIcon(im.loadIcon("path-contour-edit"));
+ PreviewMode->setIcon(im.loadIcon("path-node-visibility"));
+ ResetContClip->setIcon(im.loadIcon("path-contour-to-clip"));
+ ResetShape2Clip->setIcon(im.loadIcon("path-shape-to-clip"));
+ ResetCont->setIcon(im.loadIcon("path-contour-reset"));
+ resetDefaultButton->setIcon(im.loadIcon("path-reset-all"));
}
void NodePalette::languageChange()
@@ -1098,28 +911,21 @@
setWindowTitle( tr( "Nodes" ) );
scalePercentage->setSuffix( tr(" %"));
- AbsMode->setTitle( tr("&Absolute Coordinates"));
- absToCanvas->setText( tr("to Canvas"));
- absToPage->setText( tr("to Page"));
- TextLabel1->setText( tr("&X-Pos:"));
- TextLabel2->setText( tr("&Y-Pos:"));
- PreviewMode->setText( tr("Hide Nodes"));
- EditCont->setText( tr("Edit &Contour Line"));
- ResetCont->setText( tr("&Reset Contour Line"));
- ResetContClip->setText( tr("Set Contour to Image Clip"));
- ResetShape2Clip->setText( tr("Set Shape to Image Clip"));
+ initPosOriginMenu();
+
+ PosOriginLabel->setText( tr("Origin:"));
+ TextLabel1->setText( tr("&X:"));
+ TextLabel2->setText( tr("&Y:"));
editEditButton->setText( tr("OK"));
cancelEditButton->setText( tr("Cancel"));
- resetDefaultButton->setText( tr("Reset all edits"));
-// editEditButton->setText( tr("&End Editing"));
+ resetDefaultButton->setToolTip( tr("Reset all edits"));
MoveNode->setToolTip( tr("Move Nodes"));
- MoveControl->setToolTip( tr("Move Control Points"));
AddNode->setToolTip( tr("Add Nodes"));
DeleteNode->setToolTip( tr("Delete Nodes"));
- AsymMove->setToolTip( tr("Move Control Points Independently"));
+ AsymMove->setToolTip( tr("Move Control Points Asymetrical"));
SymMove->setToolTip( tr("Move Control Points Symmetrical"));
- ResNode->setToolTip( tr("Reset Control Points"));
- Res1Node->setToolTip( tr("Reset this Control Point"));
+ IndependentMove->setToolTip( tr("Move Control Points Independently"));
+ EditControl->setToolTip( tr("Edit Control Points"));
PolySplit->setToolTip( tr("Open a Polygon or Cuts a Bezier Curve"));
BezierClose->setToolTip( tr("Close this Bezier Curve"));
PolyMirrorH->setToolTip( tr("Mirror the Path Horizontally"));
@@ -1137,11 +943,12 @@
RotVal->setToolTip( tr("Angle of Rotation"));
scalePercentage->setToolTip( tr("% to Enlarge or Shrink By"));
scaleDistance->setToolTip( tr("Value to Enlarge or Shrink By"));
+ PreviewMode->setToolTip( tr("Hide Nodes"));
EditCont->setToolTip( tr("Activate Contour Line Editing Mode"));
ResetCont->setToolTip( tr("Reset the Contour Line to the Original Shape of the Frame"));
ResetContClip->setToolTip( tr("Reset the Contour Line to the Clipping Path of the Image"));
ResetShape2Clip->setToolTip( tr("Set the Shape to the Clipping Path of the Image"));
- AbsMode->setToolTip( "" + tr("When checked use coordinates relative to the page, otherwise coordinates are relative to the Object") + "");
+ PosOriginButton->setToolTip( "" + tr("Use coordinates relative to the canvas, page, or to the Object") + "");
}
void NodePalette::unitChange()
Index: scribus/ui/nodeeditpalette.h
===================================================================
--- scribus/ui/nodeeditpalette.h (Revision 26704)
+++ scribus/ui/nodeeditpalette.h (Arbeitskopie)
@@ -25,13 +25,13 @@
#include "scribusapi.h"
#include "fpointarray.h"
#include "scrpalettebase.h"
-#include "scrspinbox.h"
+#include "ui_nodeeditpalette.h"
class ScribusDoc;
class ScribusView;
class PageItem;
-class SCRIBUS_API NodePalette : public ScrPaletteBase
+class SCRIBUS_API NodePalette : public ScrPaletteBase, public Ui::nodePalette
{
Q_OBJECT
@@ -40,60 +40,19 @@
~NodePalette() {};
void setDefaults(PageItem* currItem);
-
- QToolButton* MoveNode { nullptr };
- QToolButton* MoveControl { nullptr };
- QToolButton* AddNode { nullptr };
- QToolButton* DeleteNode { nullptr };
- QToolButton* AsymMove { nullptr };
- QToolButton* SymMove { nullptr };
- QToolButton* ResNode { nullptr };
- QToolButton* Res1Node { nullptr };
- QToolButton* PolySplit { nullptr };
- QToolButton* BezierClose { nullptr };
- QToolButton* PolyMirrorH { nullptr };
- QToolButton* PolyMirrorV { nullptr };
- QToolButton* PolyShearL { nullptr };
- QToolButton* PolyShearR { nullptr };
- QToolButton* PolyShearU { nullptr };
- QToolButton* PolyShearD { nullptr };
- QToolButton* RotateCCW { nullptr };
- QToolButton* RotateCW { nullptr };
- QToolButton* Expand { nullptr };
- QToolButton* Shrink { nullptr };
- QToolButton* Enlarge { nullptr };
- QToolButton* Reduce { nullptr };
- QCheckBox* PreviewMode { nullptr };
- QGroupBox* AbsMode { nullptr };
- QRadioButton* absToCanvas { nullptr };
- QRadioButton* absToPage { nullptr };
- QCheckBox* EditCont { nullptr };
- QLabel* TextLabel1 { nullptr };
- ScrSpinBox* YSpin { nullptr };
- QLabel* TextLabel2 { nullptr };
- ScrSpinBox* XSpin { nullptr };
- QSpinBox *RotVal { nullptr };
- QSpinBox *scalePercentage { nullptr };
- ScrSpinBox *scaleDistance { nullptr };
- QPushButton* ResetCont { nullptr };
- QPushButton* ResetContClip { nullptr };
- QPushButton* ResetShape2Clip { nullptr };
- QPushButton* editEditButton { nullptr };
- QPushButton* cancelEditButton { nullptr };
- QPushButton* resetDefaultButton { nullptr };
-
void setDoc(ScribusDoc *dc, ScribusView *vi);
ScribusDoc* currentDocument() const;
+ bool isSymetricMove() { return SymMove->isChecked(); };
+
private slots:
- void MoveK();
void AddN();
void DelN();
void MovePoint();
void SetSym();
void SetAsym();
- void ResetControl();
- void Reset1Control();
+ void SetIndependentMove();
+ void editControl();
void ResetContour();
void ResetContourToImageClip();
void ResetShapeToImageClip();
@@ -111,14 +70,14 @@
void ShearL();
void ShearU();
void ShearD();
- void ToggleAbsMode();
- void ToggleConMode();
+ void ToggleContourMode();
void TogglePreview();
+ void changePosOrigin(int index);
public slots:
void MoveN();
void SetXY(double x, double y);
- void HaveNode(bool have, bool mov);
+ void HaveNode(bool have);
void IsOpen();
void PolyStatus(int typ, uint size);
void iconSetChange();
@@ -132,19 +91,21 @@
void reject() override;
protected:
+
+ enum PositionOrigin {
+ Canvas = 0,
+ Page,
+ Item
+ };
+
void connectSignals();
void disconnectSignals();
+ void initPosOriginMenu();
+
void changeEvent(QEvent *e) override;
void closeEvent(QCloseEvent *) override;
- QVBoxLayout *vboxLayout { nullptr };
- QVBoxLayout *vboxLayout1 { nullptr };
- QHBoxLayout *hboxLayout { nullptr };
- QGridLayout *gridLayout { nullptr };
- QGridLayout *gridLayout2 { nullptr };
- QGridLayout *gridLayout3 { nullptr };
-
ScribusDoc *m_doc { nullptr };
ScribusView *m_view { nullptr };
@@ -153,6 +114,7 @@
double m_yPos { 0.0 };
FPointArray m_itemPath;
FPointArray m_itemContourPath;
+ int m_posOrigin { Page };
signals:
void DocChanged();
Index: scribus/util_math.h
===================================================================
--- scribus/util_math.h (Revision 26704)
+++ scribus/util_math.h (Arbeitskopie)
@@ -19,6 +19,7 @@
#include
#include
+#include "fpoint.h"
#include "scribusapi.h"
class FPoint;
@@ -42,7 +43,7 @@
* @param t
* @return
*/
-QList catmullToBezier(const QList& inputPoints, double t = 1);
+QList SCRIBUS_API catmullToBezier(const QList& inputPoints, double t = 1);
QPainterPath SCRIBUS_API regularPolygonPath(double w, double h, uint c, bool star, double factor, double rota, double factor2 = 0.0, double innerRot = 0.0, double factor3 = 0.0);
QPainterPath SCRIBUS_API spiralPath(double spiralWidth, double spiralHeight, double spiralStartAngle, double spiralEndAngle, double spiralFactor);
inline double SCRIBUS_API xy2Deg(double x, double y);
@@ -51,6 +52,7 @@
inline double SCRIBUS_API square(double);
inline double SCRIBUS_API distance(double, double);
inline double SCRIBUS_API manhattanDistance(const QPointF& p1, const QPointF& p2);
+
/*! \brief Constrains an angle of rotation to 45 degree intervals
Will make code simpler and reduce interval or provide as a parameter
\param angle angle Angle in degrees
@@ -58,6 +60,7 @@
\retval double Constrained angle
*/
double SCRIBUS_API constrainAngle(double angle, double constrain);
+inline FPoint SCRIBUS_API getPointFromRotation(const FPoint &p1, double distance, double angle);
/*! \brief Get the rotation angle (in radian) from a transformation matrix
Will make code simpler and reduce interval or provide as a parameter
\param matrix the transformation matrix
@@ -92,6 +95,14 @@
return point.manhattanLength();
}
+inline FPoint getPointFromRotation(const FPoint &p1, double distance, double angle)
+{
+ FPoint p2;
+ p2.setX(p1.x() + cosd(angle) * distance);
+ p2.setY(p1.y() + sind(angle) * distance);
+ return p2;
+}
+
inline double xy2Deg(double x, double y)
{
return atan2(y,x) * (180.0/M_PI);