← Back to team overview

kicad-developers team mailing list archive

[PATCH] Cleaner entry of arc angles

 

Hi all,

Currently, angles (e.g., when editing a graphic arc in PcbNew) have to be
entered in deci-degrees which is not the nicest IMHO. There is a
wxSpinCtrlDouble widget [1] which was added in version 2.9.0 of wxWidgets
[2] which is the ideal widget for this purpose. Unfortunately,
wxFormBuilder doesn't support it yet [3] which means something of a hack is
required to use it.

What I've done is replaced the m_Angle_Ctrl textfield in the form editor
with a standard (integer-only) wxSpinCtrl called m_Angle_Ctrl_Placeholder.
The actual dialog then creates a wxSpinCtrlDouble in the constructor and
puts it into the dialog instead of the placeholder.

This means that any changes made to the properties of the placeholder in
the form builder will be ignored (but hopefully its name will suggest
this). The location of the placeholder is copied to the real widget so any
layout changes to the form as a whole shouldn't break anything. Doing it
this way also means that regenerating the base code in the form builder
doesn't break anything.

The attached patch does this for editing graphic arcs in both pcbnew and
modedit. I wanted to see if there were any objections and/or suggestions of
a better method before changing the rest of the angle entry widgets. Once
this is OKed I'll go through and update the rest of them.

Cheers,
Blair


[1] http://docs.wxwidgets.org/trunk/classwx_spin_ctrl_double.html
[2]
https://github.com/wxWidgets/wxWidgets/blob/master/docs/changes_30.txt#L1417
[3] http://sourceforge.net/p/wxformbuilder/feature-requests/45/
=== modified file 'pcbnew/dialogs/dialog_graphic_item_properties.cpp'
--- pcbnew/dialogs/dialog_graphic_item_properties.cpp	2015-03-03 10:50:50 +0000
+++ pcbnew/dialogs/dialog_graphic_item_properties.cpp	2015-04-11 03:21:32 +0000
@@ -60,6 +60,9 @@
     DRAWSEGMENT*          m_item;
     BOARD_DESIGN_SETTINGS m_brdSettings;
 
+protected:
+    wxSpinCtrlDouble*     m_Angle_Ctrl;
+
 public:
     DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME* aParent, DRAWSEGMENT* aItem, wxDC* aDC );
     ~DIALOG_GRAPHIC_ITEM_PROPERTIES() {};
@@ -76,6 +79,14 @@
                                                                 DRAWSEGMENT* aItem, wxDC* aDC ):
     DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( aParent )
 {
+    // wxFormBuilder does not provide wxSpinCtrlDouble.
+    // Hence the form uses a wxSpinCtrl as a placeholder and we replace it here.
+    m_Angle_Ctrl = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition,
+                                         wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP,
+                                         -360, 360, 0, 0.1 );
+    GetSizer()->Replace( m_Angle_Ctrl_Placeholder, m_Angle_Ctrl, true );
+    m_Angle_Ctrl_Placeholder->Destroy();
+
     m_parent = aParent;
     m_DC = aDC;
     m_item = aItem;
@@ -145,10 +156,7 @@
         m_StartPointYLabel->SetLabel( _( "Center Y" ) );
         m_EndPointXLabel->SetLabel( _( "Start Point X" ) );
         m_EndPointYLabel->SetLabel( _( "Start Point Y" ) );
-
-        // Here the angle is a double, but the UI is still working with integers.
-        msg << int( m_item->GetAngle() );
-        m_Angle_Ctrl->SetValue( msg );
+        m_Angle_Ctrl->SetValue( m_item->GetAngle() / 10.0 );
         break;
 
     case S_SEGMENT:
@@ -248,8 +256,7 @@
 
     if( m_item->GetShape() == S_ARC )
     {
-        double angle;
-        m_Angle_Ctrl->GetValue().ToDouble( &angle );
+        double angle = m_Angle_Ctrl->GetValue() * 10.0;
         NORMALIZE_ANGLE_360( angle );
         m_item->SetAngle( angle );
     }
@@ -283,12 +290,12 @@
     case S_ARC:
         // Check angle of arc.
         double angle;
-        m_Angle_Ctrl->GetValue().ToDouble( &angle );
+        angle = m_Angle_Ctrl->GetValue() * 10.0;
         NORMALIZE_ANGLE_360( angle );
 
         if( angle == 0 )
         {
-            error_msgs.Add( _( "The arc angle must be greater than zero." ) );
+            error_msgs.Add( _( "The arc angle cannot be zero." ) );
         }
 
         // Fall through.

=== modified file 'pcbnew/dialogs/dialog_graphic_item_properties_base.cpp'
--- pcbnew/dialogs/dialog_graphic_item_properties_base.cpp	2013-09-03 19:37:52 +0000
+++ pcbnew/dialogs/dialog_graphic_item_properties_base.cpp	2015-04-11 03:21:06 +0000
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Oct  8 2012)
+// C++ code generated with wxFormBuilder (version Mar 21 2015)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -94,11 +94,10 @@
 	m_Angle_Text->Wrap( -1 );
 	fgUpperRightGridSizer->Add( m_Angle_Text, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
 	
-	m_Angle_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
-	m_Angle_Ctrl->SetMaxLength( 0 ); 
-	fgUpperRightGridSizer->Add( m_Angle_Ctrl, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
+	m_Angle_Ctrl_Placeholder = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 0, 360, 0 );
+	fgUpperRightGridSizer->Add( m_Angle_Ctrl_Placeholder, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5 );
 	
-	m_AngleUnit = new wxStaticText( this, wxID_ANY, _("0.1 degree"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_AngleUnit = new wxStaticText( this, wxID_ANY, _("degrees"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_AngleUnit->Wrap( -1 );
 	fgUpperRightGridSizer->Add( m_AngleUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
 	

=== modified file 'pcbnew/dialogs/dialog_graphic_item_properties_base.fbp'
--- pcbnew/dialogs/dialog_graphic_item_properties_base.fbp	2013-09-03 19:37:52 +0000
+++ pcbnew/dialogs/dialog_graphic_item_properties_base.fbp	2015-04-11 03:21:03 +0000
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
 <wxFormBuilder_Project>
-    <FileVersion major="1" minor="11" />
+    <FileVersion major="1" minor="13" />
     <object class="Project" expanded="1">
         <property name="class_decoration"></property>
         <property name="code_generation">C++</property>
@@ -20,8 +20,10 @@
         <property name="path">.</property>
         <property name="precompiled_header"></property>
         <property name="relative_path">1</property>
+        <property name="skip_lua_events">1</property>
         <property name="skip_php_events">1</property>
         <property name="skip_python_events">1</property>
+        <property name="ui_table">UI</property>
         <property name="use_enum">0</property>
         <property name="use_microsoft_bom">0</property>
         <object class="Dialog" expanded="1">
@@ -1337,9 +1339,9 @@
                                         </object>
                                         <object class="sizeritem" expanded="1">
                                             <property name="border">5</property>
-                                            <property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND</property>
+                                            <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND</property>
                                             <property name="proportion">0</property>
-                                            <object class="wxTextCtrl" expanded="1">
+                                            <object class="wxSpinCtrl" expanded="1">
                                                 <property name="BottomDockable">1</property>
                                                 <property name="LeftDockable">1</property>
                                                 <property name="RightDockable">1</property>
@@ -1367,15 +1369,17 @@
                                                 <property name="gripper">0</property>
                                                 <property name="hidden">0</property>
                                                 <property name="id">wxID_ANY</property>
+                                                <property name="initial">0</property>
+                                                <property name="max">360</property>
                                                 <property name="max_size"></property>
                                                 <property name="maximize_button">0</property>
                                                 <property name="maximum_size"></property>
-                                                <property name="maxlength">0</property>
+                                                <property name="min">0</property>
                                                 <property name="min_size"></property>
                                                 <property name="minimize_button">0</property>
                                                 <property name="minimum_size"></property>
                                                 <property name="moveable">1</property>
-                                                <property name="name">m_Angle_Ctrl</property>
+                                                <property name="name">m_Angle_Ctrl_Placeholder</property>
                                                 <property name="pane_border">1</property>
                                                 <property name="pane_position"></property>
                                                 <property name="pane_size"></property>
@@ -1385,14 +1389,10 @@
                                                 <property name="resize">Resizable</property>
                                                 <property name="show">1</property>
                                                 <property name="size"></property>
-                                                <property name="style"></property>
+                                                <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
                                                 <property name="subclass"></property>
                                                 <property name="toolbar_pane">0</property>
                                                 <property name="tooltip"></property>
-                                                <property name="validator_data_type"></property>
-                                                <property name="validator_style">wxFILTER_NONE</property>
-                                                <property name="validator_type">wxDefaultValidator</property>
-                                                <property name="validator_variable"></property>
                                                 <property name="value"></property>
                                                 <property name="window_extra_style"></property>
                                                 <property name="window_name"></property>
@@ -1419,10 +1419,9 @@
                                                 <event name="OnRightUp"></event>
                                                 <event name="OnSetFocus"></event>
                                                 <event name="OnSize"></event>
-                                                <event name="OnText"></event>
+                                                <event name="OnSpinCtrl"></event>
+                                                <event name="OnSpinCtrlText"></event>
                                                 <event name="OnTextEnter"></event>
-                                                <event name="OnTextMaxLen"></event>
-                                                <event name="OnTextURL"></event>
                                                 <event name="OnUpdateUI"></event>
                                             </object>
                                         </object>
@@ -1458,7 +1457,7 @@
                                                 <property name="gripper">0</property>
                                                 <property name="hidden">0</property>
                                                 <property name="id">wxID_ANY</property>
-                                                <property name="label">0.1 degree</property>
+                                                <property name="label">degrees</property>
                                                 <property name="max_size"></property>
                                                 <property name="maximize_button">0</property>
                                                 <property name="maximum_size"></property>

=== modified file 'pcbnew/dialogs/dialog_graphic_item_properties_base.h'
--- pcbnew/dialogs/dialog_graphic_item_properties_base.h	2013-09-03 19:37:52 +0000
+++ pcbnew/dialogs/dialog_graphic_item_properties_base.h	2015-04-11 03:21:06 +0000
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Oct  8 2012)
+// C++ code generated with wxFormBuilder (version Mar 21 2015)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -24,6 +24,7 @@
 #include <wx/textctrl.h>
 #include <wx/sizer.h>
 #include <wx/statline.h>
+#include <wx/spinctrl.h>
 #include <wx/bmpcbox.h>
 #include <wx/button.h>
 #include <wx/dialog.h>
@@ -53,7 +54,7 @@
 		wxStaticText* m_EndPointYUnit;
 		wxStaticLine* m_staticline2;
 		wxStaticText* m_Angle_Text;
-		wxTextCtrl* m_Angle_Ctrl;
+		wxSpinCtrl* m_Angle_Ctrl_Placeholder;
 		wxStaticText* m_AngleUnit;
 		wxStaticText* m_ThicknessLabel;
 		wxTextCtrl* m_ThicknessCtrl;

=== modified file 'pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp'
--- pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp	2015-03-03 10:50:50 +0000
+++ pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp	2015-04-11 03:21:26 +0000
@@ -59,6 +59,9 @@
     BOARD_DESIGN_SETTINGS  m_brdSettings;
     MODULE*                m_module;
 
+protected:
+    wxSpinCtrlDouble*     m_Angle_Ctrl;
+
 public:
     DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES( FOOTPRINT_EDIT_FRAME* aParent,
                                             EDGE_MODULE* aItem );
@@ -77,6 +80,14 @@
                                                         EDGE_MODULE * aItem ):
     DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( aParent )
 {
+    // wxFormBuilder does not provide wxSpinCtrlDouble.
+    // Hence the form uses a wxSpinCtrl as a placeholder and we replace it here.
+    m_Angle_Ctrl = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition,
+                                         wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP,
+                                         -360, 360, 0, 0.1 );
+    GetSizer()->Replace( m_Angle_Ctrl_Placeholder, m_Angle_Ctrl, true );
+    m_Angle_Ctrl_Placeholder->Destroy();
+
     m_parent = aParent;
     m_item = aItem;
     m_brdSettings = m_parent->GetDesignSettings();
@@ -156,11 +167,7 @@
         m_StartPointYLabel->SetLabel( _( "Center Y" ) );
         m_EndPointXLabel->SetLabel( _( "Start Point X" ) );
         m_EndPointYLabel->SetLabel( _( "Start Point Y" ) );
-
-        // Here the angle is a double, but the UI is still working
-        // with integers
-        msg << int( m_item->GetAngle() );
-        m_Angle_Ctrl->SetValue( msg );
+        m_Angle_Ctrl->SetValue( m_item->GetAngle() / 10.0 );
         break;
 
     case S_SEGMENT:
@@ -261,8 +268,7 @@
 
     if( m_item->GetShape() == S_ARC )
     {
-        double angle;
-        m_Angle_Ctrl->GetValue().ToDouble( &angle );
+        double angle = m_Angle_Ctrl->GetValue() * 10.0;
         NORMALIZE_ANGLE_360( angle );
         m_item->SetAngle( angle );
     }
@@ -290,12 +296,12 @@
     case S_ARC:
         // Check angle of arc.
         double angle;
-        m_Angle_Ctrl->GetValue().ToDouble( &angle );
+        angle = m_Angle_Ctrl->GetValue() * 10.0;
         NORMALIZE_ANGLE_360( angle );
 
         if( angle == 0 )
         {
-            error_msgs.Add( _( "The arc angle must be greater than zero." ) );
+            error_msgs.Add( _( "The arc angle cannot be zero." ) );
         }
 
         // Fall through.


Follow ups