From f97c7c78c84f5b594deae4550b188c3b50998817 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <seth@kipro-pcb.com>
Date: Tue, 23 Nov 2021 12:51:37 -0800
Subject: [PATCH] Connect ruler tool with axes preferences

Adds "UpdatePreferences" action that is called when the preferences are
updated, allowing running tools to act on changes that may affect them

Fixes https://gitlab.com/kicad/code/kicad/issues/9737
---
 common/eda_draw_frame.cpp                   |  4 ++++
 common/preview_items/ruler_item.cpp         | 25 +++++++++++++++------
 common/tool/actions.cpp                     |  4 +++-
 gerbview/tools/gerbview_inspection_tool.cpp |  2 +-
 include/preview_items/ruler_item.h          | 11 ++++++++-
 include/tool/actions.h                      |  1 +
 pcbnew/tools/pcb_viewer_tools.cpp           | 14 +++++++++++-
 7 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp
index 223d9b53b2..cd57003d4d 100644
--- a/common/eda_draw_frame.cpp
+++ b/common/eda_draw_frame.cpp
@@ -287,6 +287,10 @@ void EDA_DRAW_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVars
     viewControls->LoadSettings();
 
     m_galDisplayOptions.ReadCommonConfig( *settings, this );
+
+    // Notify all tools the preferences have changed
+    if( m_toolManager )
+        m_toolManager->RunAction( ACTIONS::updatePreferences, true );
 }
 
 
diff --git a/common/preview_items/ruler_item.cpp b/common/preview_items/ruler_item.cpp
index 2afbced42d..81daac0dce 100644
--- a/common/preview_items/ruler_item.cpp
+++ b/common/preview_items/ruler_item.cpp
@@ -54,13 +54,21 @@ static int getShadowLayer( KIGFX::GAL* aGal )
 
 static void drawCursorStrings( KIGFX::VIEW* aView, const VECTOR2D& aCursor,
                                const VECTOR2D& aRulerVec, EDA_UNITS aUnits,
-                               bool aDrawingDropShadows )
+                               bool aDrawingDropShadows, bool aFlipX, bool aFlipY )
 {
     // draw the cursor labels
     std::vector<wxString> cursorStrings;
 
-    cursorStrings.push_back( DimensionLabel( "x", aRulerVec.x, aUnits ) );
-    cursorStrings.push_back( DimensionLabel( "y", aRulerVec.y, aUnits ) );
+    VECTOR2D temp = aRulerVec;
+
+    if( aFlipX )
+        temp.x = -temp.x;
+
+    if( aFlipY )
+        temp.y = -temp.y;
+
+    cursorStrings.push_back( DimensionLabel( "x", temp.x, aUnits ) );
+    cursorStrings.push_back( DimensionLabel( "y", temp.y, aUnits ) );
 
     cursorStrings.push_back( DimensionLabel( "r", aRulerVec.EuclideanNorm(), aUnits ) );
 
@@ -68,7 +76,7 @@ static void drawCursorStrings( KIGFX::VIEW* aView, const VECTOR2D& aCursor,
     cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), degs,
                                              EDA_UNITS::DEGREES ) );
 
-    auto temp = aRulerVec;
+    temp = aRulerVec;
     DrawTextNextToCursor( aView, aCursor, -temp, cursorStrings, aDrawingDropShadows );
 }
 
@@ -258,10 +266,13 @@ void drawBacksideTicks( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTO
 }
 
 
-RULER_ITEM::RULER_ITEM( const TWO_POINT_GEOMETRY_MANAGER& aGeomMgr, EDA_UNITS userUnits )
+RULER_ITEM::RULER_ITEM( const TWO_POINT_GEOMETRY_MANAGER& aGeomMgr, EDA_UNITS userUnits,
+        bool aFlipX, bool aFlipY )
         : EDA_ITEM( NOT_USED ), // Never added to anything - just a preview
           m_geomMgr( aGeomMgr ),
-          m_userUnits( userUnits )
+          m_userUnits( userUnits ),
+          m_flipX( aFlipX ),
+          m_flipY( aFlipY )
 {
 }
 
@@ -318,7 +329,7 @@ void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
 
     VECTOR2D rulerVec( end - origin );
 
-    drawCursorStrings( aView, end, rulerVec, m_userUnits, drawingDropShadows );
+    drawCursorStrings( aView, end, rulerVec, m_userUnits, drawingDropShadows, m_flipX, m_flipY );
 
     // basic tick size
     const double minorTickLen = 5.0 / gal->GetWorldScale();
diff --git a/common/tool/actions.cpp b/common/tool/actions.cpp
index 2113131a4c..a2c40ed8c3 100644
--- a/common/tool/actions.cpp
+++ b/common/tool/actions.cpp
@@ -499,6 +499,9 @@ TOOL_ACTION ACTIONS::millimetersUnits( "common.Control.metricUnits",
 TOOL_ACTION ACTIONS::updateUnits( "common.Control.updateUnits",
         AS_GLOBAL );
 
+TOOL_ACTION ACTIONS::updatePreferences( "common.Control.updatePreferences",
+        AS_GLOBAL );
+
 TOOL_ACTION ACTIONS::toggleUnits( "common.Control.toggleUnits",
         AS_GLOBAL,
         MD_CTRL + 'U', LEGACY_HK_NAME( "Switch Units" ),
@@ -653,7 +656,6 @@ TOOL_ACTION ACTIONS::reportBug( "common.SuiteControl.reportBug",
         _( "Report a problem with KiCad" ),
         BITMAPS::bug );
 
-
 // System-wide selection Events
 
 const TOOL_EVENT EVENTS::SelectedEvent( TC_MESSAGE, TA_ACTION, "common.Interactive.selected" );
diff --git a/gerbview/tools/gerbview_inspection_tool.cpp b/gerbview/tools/gerbview_inspection_tool.cpp
index 2d3bbec816..c6eb577c01 100644
--- a/gerbview/tools/gerbview_inspection_tool.cpp
+++ b/gerbview/tools/gerbview_inspection_tool.cpp
@@ -205,7 +205,7 @@ int GERBVIEW_INSPECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
     bool                       originSet = false;
     TWO_POINT_GEOMETRY_MANAGER twoPtMgr;
     EDA_UNITS                  units = m_frame->GetUserUnits();
-    KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
+    KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units, false, false );
 
     std::string tool = aEvent.GetCommandStr().get();
     m_frame->PushTool( tool );
diff --git a/include/preview_items/ruler_item.h b/include/preview_items/ruler_item.h
index 7c74edaef8..4f144ab681 100644
--- a/include/preview_items/ruler_item.h
+++ b/include/preview_items/ruler_item.h
@@ -41,7 +41,8 @@ class TWO_POINT_GEOMETRY_MANAGER;
 class RULER_ITEM : public EDA_ITEM
 {
 public:
-    RULER_ITEM( const TWO_POINT_GEOMETRY_MANAGER& m_geomMgr, EDA_UNITS userUnits );
+    RULER_ITEM( const TWO_POINT_GEOMETRY_MANAGER& m_geomMgr, EDA_UNITS userUnits, bool aFlipX,
+            bool aFlipY );
 
     ///< @copydoc EDA_ITEM::ViewBBox()
     const BOX2I ViewBBox() const override;
@@ -75,9 +76,17 @@ public:
      */
     void SwitchUnits( EDA_UNITS aUnits ) { m_userUnits = aUnits; }
 
+    void UpdateDir( bool aFlipX, bool aFlipY )
+    {
+        m_flipX = aFlipX;
+        m_flipY = aFlipY;
+    }
+
 private:
     const TWO_POINT_GEOMETRY_MANAGER& m_geomMgr;
     EDA_UNITS                         m_userUnits;
+    bool                              m_flipX;
+    bool                              m_flipY;
 };
 
 } // PREVIEW
diff --git a/include/tool/actions.h b/include/tool/actions.h
index 9b46d23f51..1411bc3368 100644
--- a/include/tool/actions.h
+++ b/include/tool/actions.h
@@ -167,6 +167,7 @@ public:
     static TOOL_ACTION updateMenu;
     static TOOL_ACTION activatePointEditor;
     static TOOL_ACTION changeEditMethod;
+    static TOOL_ACTION updatePreferences;
 
     // Suite
     static TOOL_ACTION openPreferences;
diff --git a/pcbnew/tools/pcb_viewer_tools.cpp b/pcbnew/tools/pcb_viewer_tools.cpp
index 93d1de3e9a..a04a46d989 100644
--- a/pcbnew/tools/pcb_viewer_tools.cpp
+++ b/pcbnew/tools/pcb_viewer_tools.cpp
@@ -207,7 +207,9 @@ int PCB_VIEWER_TOOLS::MeasureTool( const TOOL_EVENT& aEvent )
     PCB_GRID_HELPER            grid( m_toolMgr, frame()->GetMagneticItemsSettings() );
     bool                       originSet = false;
     EDA_UNITS                  units = frame()->GetUserUnits();
-    KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
+    KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units,
+            frame()->GetDisplayOptions().m_DisplayInvertXAxis,
+            frame()->GetDisplayOptions().m_DisplayInvertYAxis );
 
     view.Add( &ruler );
     view.SetVisible( &ruler, false );
@@ -313,6 +315,16 @@ int PCB_VIEWER_TOOLS::MeasureTool( const TOOL_EVENT& aEvent )
                 view.Update( &ruler, KIGFX::GEOMETRY );
                 canvas()->Refresh();
             }
+
+            evt->SetPassEvent();
+        }
+        else if( evt->IsAction( &ACTIONS::updatePreferences ) )
+        {
+            ruler.UpdateDir( frame()->GetDisplayOptions().m_DisplayInvertXAxis,
+                    frame()->GetDisplayOptions().m_DisplayInvertYAxis );
+
+            view.Update( &ruler, KIGFX::GEOMETRY );
+            canvas()->Refresh();
             evt->SetPassEvent();
         }
         else if( evt->IsClick( BUT_RIGHT ) )