View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0004702 | Scribus | User Interface | public | 2006-12-04 10:43 | 2026-09-02 05:57 |
| Reporter | christoph_s | Assigned To | |||
| Priority | normal | Severity | feature | Reproducibility | always |
| Status | new | Resolution | open | ||
| Platform | any | OS | any | OS Version | any |
| Product Version | 1.3 | ||||
| Summary | 0004702: Snap guides to tick marks in the rulers | ||||
| Description | Would be a welcome feature, especially with large zoom factors. | ||||
| Tags | #please_test, snapping | ||||
| Patch | |||||
|
|
Not in 1.3.4 |
|
|
I stumbled upon this and it is a good quality of life refinement. Here is a patch that made it possible. - Adds soft snapping of dragged guides to visible ruler ticks. - Activates only when tick spacing is ≥ 10 px; snap radius is 3 px. - Uses ruler-derived visible tick positions, respecting ruler origin/mode and page context. - Preserves Snap to Items priority. - Keeps preview/HUD and final guide position in sync. - No new preference and no change to generic canvas coordinate conversion. guide-ruler-tick-snapping-v1.0.patch (5,167 bytes)
Index: scribus/canvasgesture_rulermove.cpp
===================================================================
--- scribus/canvasgesture_rulermove.cpp (revision 27810)
+++ scribus/canvasgesture_rulermove.cpp (working copy)
@@ -26,7 +26,14 @@
#include "scribusdoc.h"
#include "scribusview.h"
#include "ui/guidemanager.h"
+#include "ui/hruler.h"
+#include "ui/vruler.h"
+namespace
+{
+constexpr double RulerTickMinSpacingPx = 10.0;
+constexpr double RulerTickSnapRadiusPx = 3.0;
+}
RulerGesture::RulerGesture(ScribusView *view, RulerGesture::Mode mode) :
CanvasGesture(view),
@@ -199,6 +206,7 @@
if ((page >= 0) && (viewport.contains(m->globalPosition())))
{
ScPage* currentPage = m_doc->Pages->at(page);
+ bool snappedToItem = false;
if (m_doc->SnapItems)
{
double xout = 0;
@@ -207,9 +215,23 @@
if (yout != y)
{
y = yout;
+ snappedToItem = true;
newMousePoint = m_canvas->canvasToLocal(QPointF(x, y));
}
}
+ if (!snappedToItem)
+ {
+ const double tickSpacing = m_view->vertRuler->visibleTickSpacing();
+ if (tickSpacing * m_canvas->scale() >= RulerTickMinSpacingPx)
+ {
+ const double tick = m_view->vertRuler->nearestVisibleTick(y, currentPage);
+ if (qAbs(tick - y) * m_canvas->scale() <= RulerTickSnapRadiusPx)
+ {
+ y = tick;
+ newMousePoint = m_canvas->canvasToLocal(QPointF(x, y));
+ }
+ }
+ }
if (!m_haveGuide)
{
QApplication::changeOverrideCursor(QCursor(Qt::SplitVCursor));
@@ -267,6 +289,7 @@
if ((page >= 0) && viewport.contains(m->globalPosition()))
{
ScPage* currentPage = m_doc->Pages->at(page);
+ bool snappedToItem = false;
if (m_doc->SnapItems)
{
double xout = 0;
@@ -275,9 +298,23 @@
if (xout != x)
{
x = xout;
+ snappedToItem = true;
newMousePoint = m_canvas->canvasToLocal(QPointF(x, y));
}
}
+ if (!snappedToItem)
+ {
+ const double tickSpacing = m_view->horizRuler->visibleTickSpacing();
+ if (tickSpacing * m_canvas->scale() >= RulerTickMinSpacingPx)
+ {
+ const double tick = m_view->horizRuler->nearestVisibleTick(x);
+ if (qAbs(tick - x) * m_canvas->scale() <= RulerTickSnapRadiusPx)
+ {
+ x = tick;
+ newMousePoint = m_canvas->canvasToLocal(QPointF(x, y));
+ }
+ }
+ }
if (!m_haveGuide)
{
QApplication::changeOverrideCursor(QCursor(Qt::SplitHCursor));
Index: scribus/ui/hruler.h
===================================================================
--- scribus/ui/hruler.h (revision 27810)
+++ scribus/ui/hruler.h (working copy)
@@ -65,6 +65,8 @@
~Hruler() {}
double ruleSpacing() const;
+ double visibleTickSpacing() const;
+ double nearestVisibleTick(double canvasPos) const;
void setItem(PageItem * item);
void setRtl(bool rtl);
void textMode(bool state) { m_textEditMode = state; }
Index: scribus/ui/hruler.cpp
===================================================================
--- scribus/ui/hruler.cpp (revision 27810)
+++ scribus/ui/hruler.cpp (working copy)
@@ -937,6 +937,23 @@
return m_iter;
}
+double Hruler::visibleTickSpacing() const
+{
+ if (m_doc->unitIndex() == SC_C || m_doc->unitIndex() == SC_P)
+ return qMin(m_iter, m_iter2);
+ return qMin(m_iter, m_iter2 / 2.0);
+}
+
+double Hruler::nearestVisibleTick(double canvasPos) const
+{
+ const double spacing = visibleTickSpacing();
+ double origin = m_doc->rulerXoffset;
+ if (m_doc->guidesPrefs().rulerMode && m_doc->currentPage())
+ origin += m_doc->currentPage()->xOffset();
+
+ return origin + qRound((canvasPos - origin) / spacing) * spacing;
+}
+
void Hruler::draw(int where)
{
// erase old marker
Index: scribus/ui/vruler.h
===================================================================
--- scribus/ui/vruler.h (revision 27810)
+++ scribus/ui/vruler.h (working copy)
@@ -34,6 +34,7 @@
class PageItem;
class PrefsManager;
class RulerGesture;
+class ScPage;
class ScribusDoc;
class ScribusView;
@@ -50,6 +51,8 @@
~Vruler() {}
double ruleSpacing() const;
+ double visibleTickSpacing() const;
+ double nearestVisibleTick(double canvasPos, const ScPage* page) const;
void shift(double pos) { m_offset = pos; }
void shiftRel(double dist) { m_offset += dist; }
Index: scribus/ui/vruler.cpp
===================================================================
--- scribus/ui/vruler.cpp (revision 27810)
+++ scribus/ui/vruler.cpp (working copy)
@@ -295,6 +295,23 @@
return m_iter;
}
+double Vruler::visibleTickSpacing() const
+{
+ return qMin(m_iter, m_iter2 / 2.0);
+}
+
+double Vruler::nearestVisibleTick(double canvasPos, const ScPage* page) const
+{
+ const double spacing = visibleTickSpacing();
+ double origin = m_doc->rulerYoffset;
+ if (perPageMode() && page)
+ origin = page->yOffset();
+ else if (m_doc->guidesPrefs().rulerMode && m_doc->currentPage())
+ origin += m_doc->currentPage()->yOffset();
+
+ return origin + qRound((canvasPos - origin) / spacing) * spacing;
+}
+
void Vruler::draw(int where)
{
// erase old marker
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2006-12-04 10:43 | christoph_s | New Issue | |
| 2006-12-18 22:02 | cbradney | Note Added: 0014062 | |
| 2016-05-25 03:49 | Kunda | Tag Attached: snapping | |
| 2026-09-02 05:57 | qirat | Note Added: 0054397 | |
| 2026-09-02 05:57 | qirat | File Added: guide-ruler-tick-snapping-v1.0.patch | |
| 2026-09-02 05:57 | qirat | Tag Attached: #please_test |