diff --git a/common/libeval/numeric_evaluator.cpp b/common/libeval/numeric_evaluator.cpp
index 4a253dd6a4..3e1f4873ab 100644
--- a/common/libeval/numeric_evaluator.cpp
+++ b/common/libeval/numeric_evaluator.cpp
@@ -83,10 +83,11 @@ void NUMERIC_EVALUATOR::SetDefaultUnits( EDA_UNITS aUnits )
 {
     switch( aUnits )
     {
-    case EDA_UNITS::MILLIMETRES: m_defaultUnits = Unit::MM;   break;
-    case EDA_UNITS::MILS:        m_defaultUnits = Unit::Mil;  break;
-    case EDA_UNITS::INCHES:      m_defaultUnits = Unit::Inch; break;
-    default:                     m_defaultUnits = Unit::MM;   break;
+    case EDA_UNITS::MILLIMETRES: m_defaultUnits = Unit::MM;      break;
+    case EDA_UNITS::MILS:        m_defaultUnits = Unit::Mil;     break;
+    case EDA_UNITS::INCHES:      m_defaultUnits = Unit::Inch;    break;
+    case EDA_UNITS::DEGREES:     m_defaultUnits = Unit::Degrees; break;
+    default:                     m_defaultUnits = Unit::MM;      break;
     }
 }
 
@@ -137,6 +138,9 @@ bool NUMERIC_EVALUATOR::Process( const wxString& aString )
     m_parseFinished = false;
     Token tok;
 
+    FILE* f = fopen( "C:\\Users\\jon\\log.txt", "w" );
+    numEval::ParseTrace( f, "parser: " );
+
     if( aString.IsEmpty() )
     {
         m_parseFinished = true;
@@ -156,6 +160,8 @@ bool NUMERIC_EVALUATOR::Process( const wxString& aString )
         }
     } while( tok.token );
 
+    fclose( f );
+
     return !m_parseError;
 }
 
@@ -165,10 +171,10 @@ void NUMERIC_EVALUATOR::newString( const wxString& aString )
     Clear();
 
     m_originalText = aString;
-    m_token.inputLen = aString.length();
+    m_token.input = aString.mb_str();
+    m_token.inputLen = strlen( m_token.input );
     m_token.outputLen = std::max<std::size_t>( 64, m_token.inputLen + 1 );
     m_token.pos = 0;
-    m_token.input = aString.mb_str();
     m_token.token = new char[m_token.outputLen]();
     m_token.token[0] = '0';
 
@@ -249,6 +255,13 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
                 const char* cptr = &m_token.input[ m_token.pos ];
                 const auto sizeLeft = m_token.inputLen - m_token.pos;
 
+                // We should really give this unicode support
+                if( sizeLeft >= 2 && ch == '\xC2' && cptr[1] == '\xB0' )
+                {
+                    m_token.pos += 2;
+                    return Unit::Degrees;
+                }
+
                 if( sizeLeft >= 2 && ch == 'm' && cptr[ 1 ] == 'm' && !isalnum( cptr[ 2 ] ) )
                 {
                     m_token.pos += 2;
@@ -353,6 +366,10 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
             case Unit::Invalid:                                   break;
             }
         }
+        else if( m_defaultUnits == Unit::Degrees && convertFrom == Unit::Degrees )
+        {
+            retval.value.dValue = 1.0;
+        }
     }
     else if( isalpha( ch ) )
     {
diff --git a/common/properties/pg_editors.cpp b/common/properties/pg_editors.cpp
index 26fd77f0b7..f7e12bc09a 100644
--- a/common/properties/pg_editors.cpp
+++ b/common/properties/pg_editors.cpp
@@ -18,6 +18,7 @@
  */
 
 #include <eda_draw_frame.h>
+#include <properties/eda_angle_variant.h>
 #include <properties/pg_editors.h>
 #include <properties/pg_properties.h>
 #include <widgets/unit_binder.h>
@@ -69,6 +70,8 @@ wxPGWindowList PG_UNIT_EDITOR::CreateControls( wxPropertyGrid* aPropGrid, wxPGPr
 
     if( PGPROPERTY_DISTANCE* prop = dynamic_cast<PGPROPERTY_DISTANCE*>( aProperty ) )
         m_unitBinder->SetCoordType( prop->CoordType() );
+    else if( PGPROPERTY_ANGLE* prop = dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) )
+        m_unitBinder->SetUnits( EDA_UNITS::DEGREES );
 
     return ret;
 }
@@ -87,10 +90,16 @@ bool PG_UNIT_EDITOR::OnEvent( wxPropertyGrid* aPropGrid, wxPGProperty* aProperty
     {
         if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl ) )
         {
-            textCtrl->SelectAll();
-            return false;
+            if( !textCtrl->HasFocus() )
+            {
+                textCtrl->SelectAll();
+                return false;
+            }
         }
     }
+    
+    if( aEvent.GetEventType() == wxEVT_KILL_FOCUS )
+        wxLogDebug( "test" );
 
     return wxPGTextCtrlEditor::OnEvent( aPropGrid, aProperty, aCtrl, aEvent );
 }
@@ -111,15 +120,29 @@ bool PG_UNIT_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aPr
         aVariant.MakeNull();
         return true;
     }
+    bool changed = false;
 
-    long result = m_unitBinder->GetValue();
-
-    bool changed = ( aVariant.IsNull() || result != aVariant.GetLong() );
-
-    if( changed )
+    if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) )
     {
-        aVariant = result;
-        m_unitBinder->SetValue( result );
+        double result = m_unitBinder->GetAngleValue().AsDegrees();
+        changed = ( aVariant.IsNull() || result != aVariant.GetDouble() );
+
+        if( changed )
+        {
+            aVariant = result;
+            m_unitBinder->SetValue( result );
+        }
+    }
+    else
+    {
+        long result = m_unitBinder->GetValue();
+        changed = ( aVariant.IsNull() || result != aVariant.GetLong() );
+
+        if( changed )
+        {
+            aVariant = result;
+            m_unitBinder->SetValue( result );
+        }
     }
 
     // Changing unspecified always causes event (returning
diff --git a/common/properties/pg_properties.cpp b/common/properties/pg_properties.cpp
index 4c884d4c80..f4bf15191c 100644
--- a/common/properties/pg_properties.cpp
+++ b/common/properties/pg_properties.cpp
@@ -105,6 +105,7 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty )
             prop->SetScale( 10.0 );
 
         ret = prop;
+        ret->SetEditor( PG_UNIT_EDITOR::EDITOR_NAME );
         break;
     }
 
@@ -235,8 +236,7 @@ PGPROPERTY_SIZE::PGPROPERTY_SIZE( const wxString& aLabel, const wxString& aName,
 
 wxValidator* PGPROPERTY_SIZE::DoGetValidator() const
 {
-    //return m_regExValidator.get();
-            return nullptr;
+    return nullptr;
 }
 
 
@@ -250,7 +250,6 @@ PGPROPERTY_COORD::PGPROPERTY_COORD( const wxString& aLabel, const wxString& aNam
 
 wxValidator* PGPROPERTY_COORD::DoGetValidator() const
 {
-    //return m_regExValidator.get();
     return nullptr;
 }
 
@@ -297,6 +296,12 @@ wxString PGPROPERTY_ANGLE::ValueToString( wxVariant& aVariant, int aArgFlags ) c
 }
 
 
+wxValidator* PGPROPERTY_ANGLE::DoGetValidator() const
+{
+    return nullptr;
+}
+
+
 wxSize PGPROPERTY_COLORENUM::OnMeasureImage( int aItem ) const
 {
     // TODO(JE) calculate size from window metrics?
diff --git a/common/widgets/unit_binder.cpp b/common/widgets/unit_binder.cpp
index ce99ecbdd5..0524e42160 100644
--- a/common/widgets/unit_binder.cpp
+++ b/common/widgets/unit_binder.cpp
@@ -346,8 +346,13 @@ void UNIT_BINDER::SetValue( const wxString& aValue )
     wxString value = aValue;
 
     if( m_unitsInValue )
-        value += wxT( " " ) + EDA_UNIT_UTILS::GetLabel( m_units, m_dataType );
+    {
+        if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
+            value += wxT( " " );
 
+        value += EDA_UNIT_UTILS::GetLabel( m_units, m_dataType );
+    }
+ 
     if( textEntry )
         textEntry->SetValue( value );
     else if( staticText )
@@ -404,7 +409,12 @@ void UNIT_BINDER::ChangeValue( const wxString& aValue )
     wxString value = aValue;
 
     if( m_unitsInValue )
-        value += wxT( " " ) + EDA_UNIT_UTILS::GetLabel( m_units, m_dataType );
+    {
+        if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
+            value += wxT( " " );
+
+        value += EDA_UNIT_UTILS::GetLabel( m_units, m_dataType );
+    }
 
     if( textEntry )
         textEntry->ChangeValue( value );
diff --git a/include/libeval/numeric_evaluator.h b/include/libeval/numeric_evaluator.h
index 3871279062..c211369607 100644
--- a/include/libeval/numeric_evaluator.h
+++ b/include/libeval/numeric_evaluator.h
@@ -93,7 +93,7 @@ namespace numEval
 
 class NUMERIC_EVALUATOR
 {
-    enum class Unit { Invalid, MM, CM, Inch, Mil };
+    enum class Unit { Invalid, MM, CM, Inch, Mil, Degrees };
 
 public:
     NUMERIC_EVALUATOR( EDA_UNITS aUnits );
diff --git a/include/properties/eda_angle_variant.h b/include/properties/eda_angle_variant.h
index 3e479018fb..6b6273b728 100644
--- a/include/properties/eda_angle_variant.h
+++ b/include/properties/eda_angle_variant.h
@@ -45,6 +45,10 @@ public:
 
     static wxVariantData* VariantDataFactory( const wxAny& aAny );
 
+    const EDA_ANGLE& Angle() { return m_angle; }
+
+    void SetAngle( const EDA_ANGLE& aAngle ) { m_angle = aAngle;  }
+
 protected:
     EDA_ANGLE m_angle;
 };
diff --git a/include/properties/pg_properties.h b/include/properties/pg_properties.h
index 2bb2f43593..9fc32d5e49 100644
--- a/include/properties/pg_properties.h
+++ b/include/properties/pg_properties.h
@@ -111,6 +111,8 @@ public:
         m_scale = aScale;
     }
 
+    wxValidator* DoGetValidator() const override;
+
 protected:
     ///> Scale factor to convert between raw and displayed value
     double m_scale;