← Back to team overview

kicad-developers team mailing list archive

[Patch] bitmap2component: Support for multiple input units.

 

Hi

I have made a patch to bitmap2component so that it supports entering dimensions in mm, inches, mils, and DPI. It is now also possible to lock the aspectratio to the ratio of the input bitmap. When the aspect ratio is locked and one dimension is changed, the other one is automatically updated.

I have tried to follow the coding guidelines to the best of my abilities, but I was a bit unsure on the capitalization of some things. Please let me know if there is anything that need changing. I have only tested it on linux, where it works fine.

For the future the bitmap2component is in need of a bit of refactoring, and should possibly be moved to a common dialog. That can be accessed from a menu in the other programs. But I think my patch should help with the usability of the program for now.


-Johannes

>From 15b6763d6fb4f7107d4a48954bc7a4cd2147db09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johannes=20W=C3=A5gen?= <johannes@xxxxxxxx>
Date: Fri, 14 Jun 2019 00:50:39 +0200
Subject: [PATCH] bitmap2component: Added support for multiple input units and
 locking of aspect ratio.
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------2.17.1"

This is a multi-part message in MIME format.
--------------2.17.1
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit

---
 bitmap2component/bitmap2cmp_gui.cpp      | 275 +++++++++---------
 bitmap2component/bitmap2cmp_gui.h        | 154 ++++++++++
 bitmap2component/bitmap2cmp_gui_base.cpp |  93 +++---
 bitmap2component/bitmap2cmp_gui_base.fbp | 348 ++++++++++++++++++++---
 bitmap2component/bitmap2cmp_gui_base.h   |  80 ++++--
 bitmap2component/bitmap2component.h      |   1 +
 6 files changed, 715 insertions(+), 236 deletions(-)
 create mode 100644 bitmap2component/bitmap2cmp_gui.h


--------------2.17.1
Content-Type: text/x-patch; name="0001-bitmap2component-Added-support-for-multiple-input-un.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-bitmap2component-Added-support-for-multiple-input-un.patch"

diff --git a/bitmap2component/bitmap2cmp_gui.cpp b/bitmap2component/bitmap2cmp_gui.cpp
index e4e951088..6f4f11440 100644
--- a/bitmap2component/bitmap2cmp_gui.cpp
+++ b/bitmap2component/bitmap2cmp_gui.cpp
@@ -22,21 +22,22 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#include <fctsys.h>
-#include <macros.h>
-#include <wx/clipbrd.h>
-#include <pgm_base.h>
-#include <confirm.h>
-#include <gestfich.h>
-#include <wildcards_and_files_ext.h>
+#include "bitmap2cmp_gui.h"
+#include "bitmap2component.h"
 #include <bitmap_io.h>
 #include <bitmaps.h>
 #include <build_version.h>
-#include <kiway.h>
+#include <confirm.h>
+#include <fctsys.h>
+#include <gestfich.h>
 #include <kiface_i.h>
-#include <wx/rawbmp.h>
+#include <kiway.h>
+#include <macros.h>
+#include <pgm_base.h>
 #include <potracelib.h>
-#include "bitmap2component.h"
+#include <wildcards_and_files_ext.h>
+#include <wx/clipbrd.h>
+#include <wx/rawbmp.h>
 
 #include "bitmap2cmp_gui_base.h"
 
@@ -52,103 +53,57 @@
 #define KEYWORD_BINARY_THRESHOLD    wxT( "Threshold" )
 #define KEYWORD_BW_NEGATIVE         wxT( "Negative_choice" )
 
-#define DEFAULT_DPI 300     // Default resolution in Bit per inches
+//Default value and unit for input
+#define DEFAULT_SIZE_VALUE 10
+#define DEFAULT_SIZE_UNIT MM
 
+IMAGE_SIZE::IMAGE_SIZE()
+{
+    m_value = 0;
+    m_value = MM;
+}
 
-/**
- * Class BM2CMP_FRAME_BASE
- * is the main frame for this application
- */
-class BM2CMP_FRAME : public BM2CMP_FRAME_BASE
-{
-private:
-    wxImage         m_Pict_Image;
-    wxBitmap        m_Pict_Bitmap;
-    wxImage         m_Greyscale_Image;
-    wxBitmap        m_Greyscale_Bitmap;
-    wxImage         m_NB_Image;
-    wxBitmap        m_BN_Bitmap;
-    wxSize          m_imageDPI;     // The initial image resolution. When unknown,
-                                    // set to DEFAULT_DPI x DEFAULT_DPI per Inch
-    bool            m_Negative;
-    wxString        m_BitmapFileName;
-    wxString        m_ConvertedFileName;
-    wxSize          m_frameSize;
-    wxPoint         m_framePos;
-    std::unique_ptr<wxConfigBase> m_config;
-    bool            m_exportToClipboard;
-
-public:
-    BM2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent );
-    ~BM2CMP_FRAME();
-
-    // overload KIWAY_PLAYER virtual
-    bool OpenProjectFiles( const std::vector<wxString>& aFilenames, int aCtl=0 ) override;
-
-private:
-
-    // Event handlers
-    void OnPaintInit( wxPaintEvent& event ) override;
-    void OnPaintGreyscale( wxPaintEvent& event ) override;
-    void OnPaintBW( wxPaintEvent& event ) override;
-    void OnLoadFile( wxCommandEvent& event ) override;
-    void OnExportToFile( wxCommandEvent& event ) override;
-    void OnExportToClipboard( wxCommandEvent& event ) override;
+void IMAGE_SIZE::Set( float aValue, UNIT aUnit )
+{
+    m_value = aValue;
+    m_unit = aUnit;
+}
 
-    /**
-     * Generate a schematic library which contains one component:
-     * the logo
-     */
-    void exportEeschemaFormat();
+void IMAGE_SIZE::SetInputResolution( int aResolution )
+{
+    m_originalResolution = aResolution;
+}
 
-    /**
-     * Generate a module in S expr format
-     */
-    void exportPcbnewFormat();
 
-    /**
-     * Generate a postscript file
-     */
-    void exportPostScriptFormat();
+float IMAGE_SIZE::GetValue()
+{
+    return m_value;
+}
 
-    /**
-     * Generate a file suitable to be copied into a page layout
-     * description file (.kicad_wks file
-     */
-    void OnExportLogo();
-
-    void Binarize( double aThreshold );     // aThreshold = 0.0 (black level) to 1.0 (white level)
-    void OnNegativeClicked( wxCommandEvent& event ) override;
-    void OnThresholdChange( wxScrollEvent& event ) override;
-    void OnResolutionChange( wxCommandEvent& event ) override;
-
-    // called when texts controls which handle the image resolution
-    // lose the focus, to ensure the right values are displayed
-    // because the m_imageDPI are clipped to acceptable values, and
-    // the text displayed could be differ during text editing
-    // We are using ChangeValue here to avoid generating a wxEVT_TEXT event.
-    void UpdateDPITextValueX( wxMouseEvent& event )
+int IMAGE_SIZE::GetOutputDPI()
+{
+    int outputDPI;
+    if( m_unit == MM )
     {
-        m_DPIValueX->ChangeValue( wxString::Format( wxT( "%d" ), m_imageDPI.x ) );
+        outputDPI = m_originalResolution / ( m_value / 25.4 );
     }
 
-    void UpdateDPITextValueY( wxMouseEvent& event )
+    else if( m_unit == INCH )
     {
-        m_DPIValueY->ChangeValue( wxString::Format( wxT( "%d" ), m_imageDPI.y ) );
+        outputDPI = m_originalResolution / ( m_value );
     }
 
-    void NegateGreyscaleImage( );
-    /**
-     * generate a export data of the current bitmap.
-     * @param aOutput is a string buffer to fill with data
-     * @param aFormat is the format to generate
-     */
-    void ExportToBuffer( std::string&aOutput, OUTPUT_FMT_ID aFormat );
+    else if( m_unit == MILS )
+    {
+        outputDPI = m_originalResolution / ( m_value / 1000 );
+    }
 
-    void updateImageInfo();
-    void OnFormatChange( wxCommandEvent& event ) override;
-    void exportBitmap( OUTPUT_FMT_ID aFormat );
-};
+    else
+    {
+        outputDPI = m_value;
+    }
+    return outputDPI;
+}
 
 
 BM2CMP_FRAME::BM2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
@@ -172,6 +127,7 @@ BM2CMP_FRAME::BM2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
     m_Negative = tmp != 0;
     m_checkNegative->SetValue( m_Negative );
     m_exportToClipboard = false;
+    m_AspectRatioLocked = false;
 
     if( m_config->Read( KEYWORD_LAST_FORMAT, &tmp ) )
     {
@@ -194,6 +150,23 @@ BM2CMP_FRAME::BM2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
             m_radio_PCBLayer->SetSelection( tmp );
     }
 
+    for( auto const& it : m_unitMap )
+    {
+        m_PixelUnit->Append( it.second );
+    }
+    m_PixelUnit->SetSelection( DEFAULT_SIZE_UNIT );
+
+    m_UnitSizeX->ChangeValue( wxString::Format( wxT( "%d" ), DEFAULT_SIZE_VALUE ) );
+    m_UnitSizeY->ChangeValue( wxString::Format( wxT( "%d" ), DEFAULT_SIZE_VALUE ) );
+
+    m_outputSizeX.Set( DEFAULT_SIZE_VALUE, UNIT::DEFAULT_SIZE_UNIT );
+    m_outputSizeY.Set( DEFAULT_SIZE_VALUE, UNIT::DEFAULT_SIZE_UNIT );
+
+    //Set icon for aspect ratio
+    m_AspectRatioLocked = true;
+    m_AspectRatio = 1;
+    m_AspectRatioLockButton->SetBitmap( KiBitmap( locked_xpm ) );
+
     // Give an icon
     wxIcon icon;
     icon.CopyFromBitmap( KiBitmap( icon_bitmap2component_xpm ) );
@@ -206,7 +179,6 @@ BM2CMP_FRAME::BM2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
     m_buttonExportFile->Enable( false );
     m_buttonExportClipboard->Enable( false );
 
-    m_imageDPI.x = m_imageDPI.y = DEFAULT_DPI;  // Default resolution in Bit per inches
 
     if ( m_framePos == wxDefaultPosition )
         Centre();
@@ -340,12 +312,17 @@ bool BM2CMP_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int
     int h  = m_Pict_Bitmap.GetHeight();
     int w  = m_Pict_Bitmap.GetWidth();
 
+    m_outputSizeX.SetInputResolution( w );
+    m_outputSizeY.SetInputResolution( h );
+    m_AspectRatio = (float) w / (float) h;
+
     // Determine image resolution in DPI (does not existing in all formats).
     // the resolution can be given in bit per inches or bit per cm in file
-    m_imageDPI.x = m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
-    m_imageDPI.y = m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
 
-    if( m_imageDPI.x > 1 && m_imageDPI.y > 1 )
+    int imageDPIx = m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
+    int imageDPIy = m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
+
+    if( imageDPIx > 1 && imageDPIy > 1 )
     {
         if( m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT ) == wxIMAGE_RESOLUTION_CM )
         {
@@ -353,17 +330,22 @@ bool BM2CMP_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int
             // experience shows adding 1.27 to the resolution converted in dpi
             // before convert to int value reduce the conversion error
             // but it is not perfect
-            m_imageDPI.x = m_imageDPI.x * 2.54 + 1.27;
-            m_imageDPI.y = m_imageDPI.y * 2.54 + 1.27;
+            imageDPIx = imageDPIx * 2.54 + 1.27;
+            imageDPIy = imageDPIy * 2.54 + 1.27;
         }
     }
     else    // fallback to the default value
-        m_imageDPI.x = m_imageDPI.y = DEFAULT_DPI;
+    {
+        imageDPIx = imageDPIy = 0;
+    }
+
+    m_InputXValueDPI->SetLabel( wxString::Format( wxT( "%d" ), imageDPIx ) );
+    m_InputYValueDPI->SetLabel( wxString::Format( wxT( "%d" ), imageDPIy ) );
+
+    //Update display to keep aspectratio
+    auto fakeEvent = wxCommandEvent();
+    OnSizeChangeX( fakeEvent );
 
-    // Display image info:
-    // We are using ChangeValue here to avoid generating a wxEVT_TEXT event.
-    m_DPIValueX->ChangeValue( wxString::Format( wxT( "%d" ), m_imageDPI.x ) );
-    m_DPIValueY->ChangeValue( wxString::Format( wxT( "%d" ), m_imageDPI.y ) );
     updateImageInfo();
 
     m_InitialPicturePanel->SetVirtualSize( w, h );
@@ -408,40 +390,78 @@ void BM2CMP_FRAME::updateImageInfo()
     // Note: the image resolution text controls are not modified
     // here, to avoid a race between text change when entered by user and
     // a text change if it is modified here.
-    int h  = m_Pict_Bitmap.GetHeight();
-    int w  = m_Pict_Bitmap.GetWidth();
-    int nb = m_Pict_Bitmap.GetDepth();
 
-    m_SizeXValue->SetLabel( wxString::Format( wxT( "%d" ), w ) );
-    m_SizeYValue->SetLabel( wxString::Format( wxT( "%d" ), h ) );
-    m_BPPValue->SetLabel( wxString::Format( wxT( "%d" ), nb ) );
+    if( m_Pict_Bitmap.IsOk() )
+    {
+        int h = m_Pict_Bitmap.GetHeight();
+        int w = m_Pict_Bitmap.GetWidth();
+        int nb = m_Pict_Bitmap.GetDepth();
 
-    m_SizeXValue_mm->SetLabel( wxString::Format( wxT( "%.1f" ),
-        (double) w / m_imageDPI.x * 25.4 ) );
-    m_SizeYValue_mm->SetLabel( wxString::Format( wxT( "%.1f" ),
-        (double) h / m_imageDPI.y * 25.4 ) );
+        m_SizeXValue->SetLabel( wxString::Format( wxT( "%d" ), w ) );
+        m_SizeYValue->SetLabel( wxString::Format( wxT( "%d" ), h ) );
+        m_BPPValue->SetLabel( wxString::Format( wxT( "%d" ), nb ) );
+    }
 }
 
 
-void BM2CMP_FRAME::OnResolutionChange( wxCommandEvent& event )
+void BM2CMP_FRAME::OnSizeChangeX( wxCommandEvent& event )
 {
-    long tmp;
-
-    if( m_DPIValueX->GetValue().ToLong( &tmp ) )
-        m_imageDPI.x = tmp;
+    double setSize;
+    if( m_UnitSizeX->GetValue().ToDouble( &setSize ) )
+    {
+        m_outputSizeX.Set( setSize, (UNIT) m_PixelUnit->GetSelection() );
 
-    if(  m_DPIValueY->GetValue().ToLong( &tmp ) )
-        m_imageDPI.y = tmp;
+        if( m_AspectRatioLocked )
+        {
+            double calculatedY = setSize / m_AspectRatio;
+            m_UnitSizeY->ChangeValue( wxString::Format( wxT( "%.2f" ), calculatedY ) );
+            m_outputSizeY.Set( calculatedY, (UNIT) m_PixelUnit->GetSelection() );
+        }
+    }
+    updateImageInfo();
+}
 
-    if( m_imageDPI.x < 32 )
-        m_imageDPI.x = 32;
+void BM2CMP_FRAME::OnSizeChangeY( wxCommandEvent& event )
+{
+    double setSize;
 
-    if( m_imageDPI.y < 32 )
-        m_imageDPI.y = 32;
+    if( m_UnitSizeY->GetValue().ToDouble( &setSize ) )
+    {
+        m_outputSizeY.Set( setSize, (UNIT) m_PixelUnit->GetSelection() );
+        if( m_AspectRatioLocked )
+        {
+            double calculatedX = setSize * m_AspectRatio;
+            m_UnitSizeX->ChangeValue( wxString::Format( wxT( "%.2f" ), calculatedX ) );
+            m_outputSizeX.Set( calculatedX, (UNIT) m_PixelUnit->GetSelection() );
+        }
+    }
+    updateImageInfo();
+}
 
+void BM2CMP_FRAME::OnSizeUnitChange( wxCommandEvent& event )
+{
+    m_outputSizeX.SetUnit( (UNIT) m_PixelUnit->GetSelection() );
+    m_outputSizeY.SetUnit( (UNIT) m_PixelUnit->GetSelection() );
     updateImageInfo();
 }
 
+void BM2CMP_FRAME::ToggleAspectRatioLock( wxCommandEvent& event )
+{
+    m_AspectRatioLocked = !m_AspectRatioLocked;
+
+    if( m_AspectRatioLocked )
+    {
+        m_AspectRatioLockButton->SetBitmap( KiBitmap( locked_xpm ) );
+        //Force resolution update when aspect ratio is locked
+        auto fakeEvent = wxCommandEvent();
+        OnSizeChangeX( fakeEvent );
+    }
+
+    else
+    {
+        m_AspectRatioLockButton->SetBitmap( KiBitmap( lock_unlock_xpm ) );
+    }
+}
 
 void BM2CMP_FRAME::Binarize( double aThreshold )
 {
@@ -756,7 +776,8 @@ void BM2CMP_FRAME::ExportToBuffer( std::string& aOutput, OUTPUT_FMT_ID aFormat )
         modLayer = (BMP2CMP_MOD_LAYER) m_radio_PCBLayer->GetSelection();
 
     BITMAPCONV_INFO converter( aOutput );
-    converter.ConvertBitmap( potrace_bitmap, aFormat, m_imageDPI.x, m_imageDPI.y, modLayer );
+    converter.ConvertBitmap( potrace_bitmap, aFormat, m_outputSizeX.GetOutputDPI(),
+            m_outputSizeY.GetOutputDPI(), modLayer );
 }
 
 
diff --git a/bitmap2component/bitmap2cmp_gui.h b/bitmap2component/bitmap2cmp_gui.h
new file mode 100644
index 000000000..51a90792d
--- /dev/null
+++ b/bitmap2component/bitmap2cmp_gui.h
@@ -0,0 +1,154 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+#ifndef BITMOP2CMP_GUI_H_
+#define BITMOP2CMP_GUI_H_
+
+#include "bitmap2component.h"
+
+#include "bitmap2cmp_gui_base.h"
+#include <map>
+#include <potracelib.h>
+
+enum UNIT
+{
+    MM = 0,
+    INCH,
+    MILS,
+    DPI
+};
+
+class IMAGE_SIZE
+{
+public:
+    IMAGE_SIZE();
+
+    void Set( float aValue, UNIT aUnit );
+    void SetUnit( UNIT aUnit )
+    {
+        m_unit = aUnit;
+    }
+
+
+    void SetInputResolution( int aResolution );
+    int  GetInputResolution()
+    {
+        return m_originalResolution;
+    }
+
+    float GetValue();
+
+    int GetOutputDPI();
+
+private:
+    UNIT  m_unit;
+    float m_value;
+    int   m_originalDPI;
+    int   m_originalResolution;
+};
+
+class BM2CMP_FRAME : public BM2CMP_FRAME_BASE
+{
+
+public:
+    BM2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent );
+    ~BM2CMP_FRAME();
+
+    // overload KIWAY_PLAYER virtual
+    bool OpenProjectFiles( const std::vector<wxString>& aFilenames, int aCtl = 0 ) override;
+
+private:
+    // Event handlers
+    void OnPaintInit( wxPaintEvent& event ) override;
+    void OnPaintGreyscale( wxPaintEvent& event ) override;
+    void OnPaintBW( wxPaintEvent& event ) override;
+    void OnLoadFile( wxCommandEvent& event ) override;
+    void OnExportToFile( wxCommandEvent& event ) override;
+    void OnExportToClipboard( wxCommandEvent& event ) override;
+
+    /**
+     * Generate a schematic library which contains one component:
+     * the logo
+     */
+    void exportEeschemaFormat();
+
+    /**
+     * Generate a module in S expr format
+     */
+    void exportPcbnewFormat();
+
+    /**
+     * Generate a postscript file
+     */
+    void exportPostScriptFormat();
+
+    /**
+     * Generate a file suitable to be copied into a page layout
+     * description file (.kicad_wks file
+     */
+    void OnExportLogo();
+
+    void Binarize( double aThreshold ); // aThreshold = 0.0 (black level) to 1.0 (white level)
+    void OnNegativeClicked( wxCommandEvent& event ) override;
+    void OnThresholdChange( wxScrollEvent& event ) override;
+
+    void OnSizeChangeX( wxCommandEvent& event ) override;
+    void OnSizeChangeY( wxCommandEvent& event ) override;
+    void OnSizeUnitChange( wxCommandEvent& event ) override;
+
+    void ToggleAspectRatioLock( wxCommandEvent& event ) override;
+
+
+    void NegateGreyscaleImage();
+    /**
+     * generate a export data of the current bitmap.
+     * @param aOutput is a string buffer to fill with data
+     * @param aFormat is the format to generate
+     */
+    void ExportToBuffer( std::string& aOutput, OUTPUT_FMT_ID aFormat );
+
+    void updateImageInfo();
+    void OnFormatChange( wxCommandEvent& event ) override;
+    void exportBitmap( OUTPUT_FMT_ID aFormat );
+
+private:
+    wxImage  m_Pict_Image;
+    wxBitmap m_Pict_Bitmap;
+    wxImage  m_Greyscale_Image;
+    wxBitmap m_Greyscale_Bitmap;
+    wxImage  m_NB_Image;
+    wxBitmap m_BN_Bitmap;
+    IMAGE_SIZE                    m_outputSizeX;
+    IMAGE_SIZE                    m_outputSizeY;
+    bool                          m_Negative;
+    wxString                      m_BitmapFileName;
+    wxString                      m_ConvertedFileName;
+    wxSize                        m_frameSize;
+    wxPoint                       m_framePos;
+    std::unique_ptr<wxConfigBase> m_config;
+    bool                          m_exportToClipboard;
+    bool                          m_AspectRatioLocked;
+    float                         m_AspectRatio;
+    std::map<UNIT, wxString>      m_unitMap = { { MM, _("mm") }, { INCH, _("Inch") }, { MILS, _("Mils") },
+        { DPI, _("DPI") } };
+};
+#endif// BITMOP2CMP_GUI_H_
diff --git a/bitmap2component/bitmap2cmp_gui_base.cpp b/bitmap2component/bitmap2cmp_gui_base.cpp
index c1caa410e..a1812c2fb 100644
--- a/bitmap2component/bitmap2cmp_gui_base.cpp
+++ b/bitmap2component/bitmap2cmp_gui_base.cpp
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Dec  1 2018)
+// C++ code generated with wxFormBuilder (version Oct 26 2018)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO *NOT* EDIT THIS FILE!
@@ -47,7 +47,7 @@ BM2CMP_FRAME_BASE::BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id, const wxS
 	fgSizerInfo->SetFlexibleDirection( wxBOTH );
 	fgSizerInfo->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
 
-	m_staticTextSize = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Size:"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticTextSize = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Input size:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticTextSize->Wrap( -1 );
 	fgSizerInfo->Add( m_staticTextSize, 0, wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
 
@@ -63,21 +63,21 @@ BM2CMP_FRAME_BASE::BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id, const wxS
 	m_SizePixUnits->Wrap( -1 );
 	fgSizerInfo->Add( m_SizePixUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
 
-	m_staticTextSize1 = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Size:"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_staticTextSize1->Wrap( -1 );
-	fgSizerInfo->Add( m_staticTextSize1, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_RIGHT, 5 );
+	m_staticTextDPI = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Input DPI:"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticTextDPI->Wrap( -1 );
+	fgSizerInfo->Add( m_staticTextDPI, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
 
-	m_SizeXValue_mm = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("0000"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_SizeXValue_mm->Wrap( -1 );
-	fgSizerInfo->Add( m_SizeXValue_mm, 0, wxBOTTOM|wxRIGHT, 5 );
+	m_InputXValueDPI = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("0000"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_InputXValueDPI->Wrap( -1 );
+	fgSizerInfo->Add( m_InputXValueDPI, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
 
-	m_SizeYValue_mm = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("0000"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_SizeYValue_mm->Wrap( -1 );
-	fgSizerInfo->Add( m_SizeYValue_mm, 0, wxBOTTOM|wxRIGHT, 5 );
+	m_InputYValueDPI = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("0000"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_InputYValueDPI->Wrap( -1 );
+	fgSizerInfo->Add( m_InputYValueDPI, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
 
-	m_Size_mmxUnits = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_Size_mmxUnits->Wrap( -1 );
-	fgSizerInfo->Add( m_Size_mmxUnits, 0, wxBOTTOM|wxRIGHT, 5 );
+	m_DPIUnit = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("DPI"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_DPIUnit->Wrap( -1 );
+	fgSizerInfo->Add( m_DPIUnit, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
 
 	m_staticTextBPP = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("BPP:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticTextBPP->Wrap( -1 );
@@ -94,23 +94,44 @@ BM2CMP_FRAME_BASE::BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id, const wxS
 
 	fgSizerInfo->Add( 0, 0, 1, wxEXPAND, 5 );
 
+    m_BPPunits1 = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _( "Lock Aspect Ratio" ),
+            wxDefaultPosition, wxDefaultSize, 0 );
+    m_BPPunits1->Wrap( -1 );
+	fgSizerInfo->Add( m_BPPunits1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+	m_BPPunits2 = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+	m_BPPunits2->Wrap( -1 );
+	fgSizerInfo->Add( m_BPPunits2, 0, wxALL, 5 );
+
+	m_AspectRatioLockButton = new wxBitmapButton( sbSizerInfo->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
+	fgSizerInfo->Add( m_AspectRatioLockButton, 0, wxALL, 5 );
+
+	m_BPPunits3 = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+	m_BPPunits3->Wrap( -1 );
+	fgSizerInfo->Add( m_BPPunits3, 0, wxALL, 5 );
+
 	m_staticTextBPI = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Resolution:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticTextBPI->Wrap( -1 );
 	fgSizerInfo->Add( m_staticTextBPI, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
 
-	m_DPIValueX = new wxTextCtrl( sbSizerInfo->GetStaticBox(), wxID_ANY, _("300"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_DPIValueX->SetMinSize( wxSize( 40,-1 ) );
+	m_UnitSizeX = new wxTextCtrl( sbSizerInfo->GetStaticBox(), wxID_ANY, _("300"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_UnitSizeX->SetMinSize( wxSize( 60,-1 ) );
+
+    m_UnitSizeX->SetValidator( wxTextValidator( wxFILTER_NUMERIC, &m_NumericValidator ) );
+
+    fgSizerInfo->Add( m_UnitSizeX, 0, wxBOTTOM|wxRIGHT|wxALIGN_BOTTOM, 5 );
 
-	fgSizerInfo->Add( m_DPIValueX, 0, wxBOTTOM|wxRIGHT, 5 );
+	m_UnitSizeY = new wxTextCtrl( sbSizerInfo->GetStaticBox(), wxID_ANY, _("300"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_UnitSizeY->SetMinSize( wxSize( 60,-1 ) );
 
-	m_DPIValueY = new wxTextCtrl( sbSizerInfo->GetStaticBox(), wxID_ANY, _("300"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_DPIValueY->SetMinSize( wxSize( 40,-1 ) );
+	fgSizerInfo->Add( m_UnitSizeY, 0, wxBOTTOM|wxRIGHT|wxALIGN_BOTTOM, 5 );
 
-	fgSizerInfo->Add( m_DPIValueY, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
+	wxArrayString m_PixelUnitChoices;
+	m_PixelUnit = new wxChoice( sbSizerInfo->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PixelUnitChoices, 0 );
+	m_PixelUnit->SetSelection( 0 );
+	m_PixelUnit->SetMinSize( wxSize( 80,-1 ) );
 
-	m_DPI_Units = new wxStaticText( sbSizerInfo->GetStaticBox(), wxID_ANY, _("DPI"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_DPI_Units->Wrap( -1 );
-	fgSizerInfo->Add( m_DPI_Units, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
+	fgSizerInfo->Add( m_PixelUnit, 0, wxALL|wxALIGN_BOTTOM, 5 );
 
 
 	sbSizerInfo->Add( fgSizerInfo, 0, wxEXPAND|wxBOTTOM, 5 );
@@ -174,11 +195,14 @@ BM2CMP_FRAME_BASE::BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id, const wxS
 	m_InitialPicturePanel->Connect( wxEVT_PAINT, wxPaintEventHandler( BM2CMP_FRAME_BASE::OnPaintInit ), NULL, this );
 	m_GreyscalePicturePanel->Connect( wxEVT_PAINT, wxPaintEventHandler( BM2CMP_FRAME_BASE::OnPaintGreyscale ), NULL, this );
 	m_BNPicturePanel->Connect( wxEVT_PAINT, wxPaintEventHandler( BM2CMP_FRAME_BASE::OnPaintBW ), NULL, this );
-	m_DPIValueX->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BM2CMP_FRAME_BASE::UpdatePPITextValueX ), NULL, this );
-	m_DPIValueX->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnResolutionChange ), NULL, this );
-	m_DPIValueY->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BM2CMP_FRAME_BASE::UpdatePPITextValueY ), NULL, this );
-	m_DPIValueY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnResolutionChange ), NULL, this );
-	m_buttonLoad->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnLoadFile ), NULL, this );
+	m_AspectRatioLockButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::ToggleAspectRatioLock ), NULL, this );
+    m_UnitSizeX->Connect( wxEVT_COMMAND_TEXT_UPDATED,
+            wxCommandEventHandler( BM2CMP_FRAME_BASE::OnSizeChangeX ), NULL, this );
+    m_UnitSizeY->Connect( wxEVT_COMMAND_TEXT_UPDATED,
+            wxCommandEventHandler( BM2CMP_FRAME_BASE::OnSizeChangeY ), NULL, this );
+    m_PixelUnit->Connect( wxEVT_COMMAND_CHOICE_SELECTED,
+            wxCommandEventHandler( BM2CMP_FRAME_BASE::OnSizeUnitChange ), NULL, this );
+    m_buttonLoad->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnLoadFile ), NULL, this );
 	m_buttonExportFile->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnExportToFile ), NULL, this );
 	m_buttonExportClipboard->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnExportToClipboard ), NULL, this );
 	m_radioBoxFormat->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnFormatChange ), NULL, this );
@@ -192,11 +216,14 @@ BM2CMP_FRAME_BASE::~BM2CMP_FRAME_BASE()
 	m_InitialPicturePanel->Disconnect( wxEVT_PAINT, wxPaintEventHandler( BM2CMP_FRAME_BASE::OnPaintInit ), NULL, this );
 	m_GreyscalePicturePanel->Disconnect( wxEVT_PAINT, wxPaintEventHandler( BM2CMP_FRAME_BASE::OnPaintGreyscale ), NULL, this );
 	m_BNPicturePanel->Disconnect( wxEVT_PAINT, wxPaintEventHandler( BM2CMP_FRAME_BASE::OnPaintBW ), NULL, this );
-	m_DPIValueX->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BM2CMP_FRAME_BASE::UpdatePPITextValueX ), NULL, this );
-	m_DPIValueX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnResolutionChange ), NULL, this );
-	m_DPIValueY->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BM2CMP_FRAME_BASE::UpdatePPITextValueY ), NULL, this );
-	m_DPIValueY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnResolutionChange ), NULL, this );
-	m_buttonLoad->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnLoadFile ), NULL, this );
+	m_AspectRatioLockButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::ToggleAspectRatioLock ), NULL, this );
+    m_UnitSizeX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
+            wxCommandEventHandler( BM2CMP_FRAME_BASE::OnSizeChangeX ), NULL, this );
+    m_UnitSizeY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
+            wxCommandEventHandler( BM2CMP_FRAME_BASE::OnSizeChangeY ), NULL, this );
+    m_PixelUnit->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED,
+            wxCommandEventHandler( BM2CMP_FRAME_BASE::OnSizeUnitChange ), NULL, this );
+    m_buttonLoad->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnLoadFile ), NULL, this );
 	m_buttonExportFile->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnExportToFile ), NULL, this );
 	m_buttonExportClipboard->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnExportToClipboard ), NULL, this );
 	m_radioBoxFormat->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( BM2CMP_FRAME_BASE::OnFormatChange ), NULL, this );
diff --git a/bitmap2component/bitmap2cmp_gui_base.fbp b/bitmap2component/bitmap2cmp_gui_base.fbp
index c4f424054..7ae62a404 100644
--- a/bitmap2component/bitmap2cmp_gui_base.fbp
+++ b/bitmap2component/bitmap2cmp_gui_base.fbp
@@ -45,7 +45,7 @@
             <property name="minimum_size"></property>
             <property name="name">BM2CMP_FRAME_BASE</property>
             <property name="pos"></property>
-            <property name="size">733,616</property>
+            <property name="size">746,616</property>
             <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property>
             <property name="subclass">KIWAY_PLAYER; kiway_player.h</property>
             <property name="title">Bitmap to Component Converter</property>
@@ -374,7 +374,7 @@
                                         <property name="border">5</property>
                                         <property name="flag">wxEXPAND|wxBOTTOM</property>
                                         <property name="proportion">0</property>
-                                        <object class="wxFlexGridSizer" expanded="0">
+                                        <object class="wxFlexGridSizer" expanded="1">
                                             <property name="cols">4</property>
                                             <property name="flexible_direction">wxBOTH</property>
                                             <property name="growablecols">1,2</property>
@@ -418,7 +418,7 @@
                                                     <property name="gripper">0</property>
                                                     <property name="hidden">0</property>
                                                     <property name="id">wxID_ANY</property>
-                                                    <property name="label">Size:</property>
+                                                    <property name="label">Input size:</property>
                                                     <property name="markup">0</property>
                                                     <property name="max_size"></property>
                                                     <property name="maximize_button">0</property>
@@ -630,11 +630,11 @@
                                                     <property name="wrap">-1</property>
                                                 </object>
                                             </object>
-                                            <object class="sizeritem" expanded="0">
+                                            <object class="sizeritem" expanded="1">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_RIGHT</property>
+                                                <property name="flag">wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxStaticText" expanded="0">
+                                                <object class="wxStaticText" expanded="1">
                                                     <property name="BottomDockable">1</property>
                                                     <property name="LeftDockable">1</property>
                                                     <property name="RightDockable">1</property>
@@ -662,7 +662,7 @@
                                                     <property name="gripper">0</property>
                                                     <property name="hidden">0</property>
                                                     <property name="id">wxID_ANY</property>
-                                                    <property name="label">Size:</property>
+                                                    <property name="label">Input DPI:</property>
                                                     <property name="markup">0</property>
                                                     <property name="max_size"></property>
                                                     <property name="maximize_button">0</property>
@@ -671,7 +671,7 @@
                                                     <property name="minimize_button">0</property>
                                                     <property name="minimum_size"></property>
                                                     <property name="moveable">1</property>
-                                                    <property name="name">m_staticTextSize1</property>
+                                                    <property name="name">m_staticTextDPI</property>
                                                     <property name="pane_border">1</property>
                                                     <property name="pane_position"></property>
                                                     <property name="pane_size"></property>
@@ -691,11 +691,11 @@
                                                     <property name="wrap">-1</property>
                                                 </object>
                                             </object>
-                                            <object class="sizeritem" expanded="0">
+                                            <object class="sizeritem" expanded="1">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxBOTTOM|wxRIGHT</property>
+                                                <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxStaticText" expanded="0">
+                                                <object class="wxStaticText" expanded="1">
                                                     <property name="BottomDockable">1</property>
                                                     <property name="LeftDockable">1</property>
                                                     <property name="RightDockable">1</property>
@@ -732,7 +732,7 @@
                                                     <property name="minimize_button">0</property>
                                                     <property name="minimum_size"></property>
                                                     <property name="moveable">1</property>
-                                                    <property name="name">m_SizeXValue_mm</property>
+                                                    <property name="name">m_InputXValueDPI</property>
                                                     <property name="pane_border">1</property>
                                                     <property name="pane_position"></property>
                                                     <property name="pane_size"></property>
@@ -752,11 +752,11 @@
                                                     <property name="wrap">-1</property>
                                                 </object>
                                             </object>
-                                            <object class="sizeritem" expanded="0">
+                                            <object class="sizeritem" expanded="1">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxBOTTOM|wxRIGHT</property>
+                                                <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxStaticText" expanded="0">
+                                                <object class="wxStaticText" expanded="1">
                                                     <property name="BottomDockable">1</property>
                                                     <property name="LeftDockable">1</property>
                                                     <property name="RightDockable">1</property>
@@ -793,7 +793,7 @@
                                                     <property name="minimize_button">0</property>
                                                     <property name="minimum_size"></property>
                                                     <property name="moveable">1</property>
-                                                    <property name="name">m_SizeYValue_mm</property>
+                                                    <property name="name">m_InputYValueDPI</property>
                                                     <property name="pane_border">1</property>
                                                     <property name="pane_position"></property>
                                                     <property name="pane_size"></property>
@@ -813,11 +813,11 @@
                                                     <property name="wrap">-1</property>
                                                 </object>
                                             </object>
-                                            <object class="sizeritem" expanded="0">
+                                            <object class="sizeritem" expanded="1">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxBOTTOM|wxRIGHT</property>
+                                                <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxStaticText" expanded="0">
+                                                <object class="wxStaticText" expanded="1">
                                                     <property name="BottomDockable">1</property>
                                                     <property name="LeftDockable">1</property>
                                                     <property name="RightDockable">1</property>
@@ -845,7 +845,7 @@
                                                     <property name="gripper">0</property>
                                                     <property name="hidden">0</property>
                                                     <property name="id">wxID_ANY</property>
-                                                    <property name="label">mm</property>
+                                                    <property name="label">DPI</property>
                                                     <property name="markup">0</property>
                                                     <property name="max_size"></property>
                                                     <property name="maximize_button">0</property>
@@ -854,7 +854,7 @@
                                                     <property name="minimize_button">0</property>
                                                     <property name="minimum_size"></property>
                                                     <property name="moveable">1</property>
-                                                    <property name="name">m_Size_mmxUnits</property>
+                                                    <property name="name">m_DPIUnit</property>
                                                     <property name="pane_border">1</property>
                                                     <property name="pane_position"></property>
                                                     <property name="pane_size"></property>
@@ -1057,16 +1057,272 @@
                                                     <property name="wrap">-1</property>
                                                 </object>
                                             </object>
-                                            <object class="sizeritem" expanded="0">
+                                            <object class="sizeritem" expanded="1">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxEXPAND</property>
                                                 <property name="proportion">1</property>
-                                                <object class="spacer" expanded="0">
+                                                <object class="spacer" expanded="1">
                                                     <property name="height">0</property>
                                                     <property name="permission">protected</property>
                                                     <property name="width">0</property>
                                                 </object>
                                             </object>
+                                            <object class="sizeritem" expanded="1">
+                                                <property name="border">5</property>
+                                                <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+                                                <property name="proportion">0</property>
+                                                <object class="wxStaticText" expanded="1">
+                                                    <property name="BottomDockable">1</property>
+                                                    <property name="LeftDockable">1</property>
+                                                    <property name="RightDockable">1</property>
+                                                    <property name="TopDockable">1</property>
+                                                    <property name="aui_layer"></property>
+                                                    <property name="aui_name"></property>
+                                                    <property name="aui_position"></property>
+                                                    <property name="aui_row"></property>
+                                                    <property name="best_size"></property>
+                                                    <property name="bg"></property>
+                                                    <property name="caption"></property>
+                                                    <property name="caption_visible">1</property>
+                                                    <property name="center_pane">0</property>
+                                                    <property name="close_button">1</property>
+                                                    <property name="context_help"></property>
+                                                    <property name="context_menu">1</property>
+                                                    <property name="default_pane">0</property>
+                                                    <property name="dock">Dock</property>
+                                                    <property name="dock_fixed">0</property>
+                                                    <property name="docking">Left</property>
+                                                    <property name="enabled">1</property>
+                                                    <property name="fg"></property>
+                                                    <property name="floatable">1</property>
+                                                    <property name="font"></property>
+                                                    <property name="gripper">0</property>
+                                                    <property name="hidden">0</property>
+                                                    <property name="id">wxID_ANY</property>
+                                                    <property name="label">Lock Aspect Ratio</property>
+                                                    <property name="markup">0</property>
+                                                    <property name="max_size"></property>
+                                                    <property name="maximize_button">0</property>
+                                                    <property name="maximum_size"></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_BPPunits1</property>
+                                                    <property name="pane_border">1</property>
+                                                    <property name="pane_position"></property>
+                                                    <property name="pane_size"></property>
+                                                    <property name="permission">protected</property>
+                                                    <property name="pin_button">1</property>
+                                                    <property name="pos"></property>
+                                                    <property name="resize">Resizable</property>
+                                                    <property name="show">1</property>
+                                                    <property name="size"></property>
+                                                    <property name="style"></property>
+                                                    <property name="subclass"></property>
+                                                    <property name="toolbar_pane">0</property>
+                                                    <property name="tooltip"></property>
+                                                    <property name="window_extra_style"></property>
+                                                    <property name="window_name"></property>
+                                                    <property name="window_style"></property>
+                                                    <property name="wrap">-1</property>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem" expanded="1">
+                                                <property name="border">5</property>
+                                                <property name="flag">wxALL</property>
+                                                <property name="proportion">0</property>
+                                                <object class="wxStaticText" expanded="1">
+                                                    <property name="BottomDockable">1</property>
+                                                    <property name="LeftDockable">1</property>
+                                                    <property name="RightDockable">1</property>
+                                                    <property name="TopDockable">1</property>
+                                                    <property name="aui_layer"></property>
+                                                    <property name="aui_name"></property>
+                                                    <property name="aui_position"></property>
+                                                    <property name="aui_row"></property>
+                                                    <property name="best_size"></property>
+                                                    <property name="bg"></property>
+                                                    <property name="caption"></property>
+                                                    <property name="caption_visible">1</property>
+                                                    <property name="center_pane">0</property>
+                                                    <property name="close_button">1</property>
+                                                    <property name="context_help"></property>
+                                                    <property name="context_menu">1</property>
+                                                    <property name="default_pane">0</property>
+                                                    <property name="dock">Dock</property>
+                                                    <property name="dock_fixed">0</property>
+                                                    <property name="docking">Left</property>
+                                                    <property name="enabled">1</property>
+                                                    <property name="fg"></property>
+                                                    <property name="floatable">1</property>
+                                                    <property name="font"></property>
+                                                    <property name="gripper">0</property>
+                                                    <property name="hidden">0</property>
+                                                    <property name="id">wxID_ANY</property>
+                                                    <property name="label"></property>
+                                                    <property name="markup">0</property>
+                                                    <property name="max_size"></property>
+                                                    <property name="maximize_button">0</property>
+                                                    <property name="maximum_size"></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_BPPunits2</property>
+                                                    <property name="pane_border">1</property>
+                                                    <property name="pane_position"></property>
+                                                    <property name="pane_size"></property>
+                                                    <property name="permission">protected</property>
+                                                    <property name="pin_button">1</property>
+                                                    <property name="pos"></property>
+                                                    <property name="resize">Resizable</property>
+                                                    <property name="show">1</property>
+                                                    <property name="size"></property>
+                                                    <property name="style"></property>
+                                                    <property name="subclass"></property>
+                                                    <property name="toolbar_pane">0</property>
+                                                    <property name="tooltip"></property>
+                                                    <property name="window_extra_style"></property>
+                                                    <property name="window_name"></property>
+                                                    <property name="window_style"></property>
+                                                    <property name="wrap">-1</property>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem" expanded="1">
+                                                <property name="border">5</property>
+                                                <property name="flag">wxALL</property>
+                                                <property name="proportion">0</property>
+                                                <object class="wxBitmapButton" expanded="1">
+                                                    <property name="BottomDockable">1</property>
+                                                    <property name="LeftDockable">1</property>
+                                                    <property name="RightDockable">1</property>
+                                                    <property name="TopDockable">1</property>
+                                                    <property name="aui_layer"></property>
+                                                    <property name="aui_name"></property>
+                                                    <property name="aui_position"></property>
+                                                    <property name="aui_row"></property>
+                                                    <property name="best_size"></property>
+                                                    <property name="bg"></property>
+                                                    <property name="bitmap"></property>
+                                                    <property name="caption"></property>
+                                                    <property name="caption_visible">1</property>
+                                                    <property name="center_pane">0</property>
+                                                    <property name="close_button">1</property>
+                                                    <property name="context_help"></property>
+                                                    <property name="context_menu">1</property>
+                                                    <property name="current"></property>
+                                                    <property name="default">0</property>
+                                                    <property name="default_pane">0</property>
+                                                    <property name="disabled"></property>
+                                                    <property name="dock">Dock</property>
+                                                    <property name="dock_fixed">0</property>
+                                                    <property name="docking">Left</property>
+                                                    <property name="enabled">1</property>
+                                                    <property name="fg"></property>
+                                                    <property name="floatable">1</property>
+                                                    <property name="focus"></property>
+                                                    <property name="font"></property>
+                                                    <property name="gripper">0</property>
+                                                    <property name="hidden">0</property>
+                                                    <property name="id">wxID_ANY</property>
+                                                    <property name="label">MyButton</property>
+                                                    <property name="margins"></property>
+                                                    <property name="markup">0</property>
+                                                    <property name="max_size"></property>
+                                                    <property name="maximize_button">0</property>
+                                                    <property name="maximum_size"></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_AspectRatioLockButton</property>
+                                                    <property name="pane_border">1</property>
+                                                    <property name="pane_position"></property>
+                                                    <property name="pane_size"></property>
+                                                    <property name="permission">protected</property>
+                                                    <property name="pin_button">1</property>
+                                                    <property name="pos"></property>
+                                                    <property name="position"></property>
+                                                    <property name="pressed"></property>
+                                                    <property name="resize">Resizable</property>
+                                                    <property name="show">1</property>
+                                                    <property name="size"></property>
+                                                    <property name="style"></property>
+                                                    <property name="subclass">; ; forward_declare</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="window_extra_style"></property>
+                                                    <property name="window_name"></property>
+                                                    <property name="window_style"></property>
+                                                    <event name="OnButtonClick">ToggleAspectRatioLock</event>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem" expanded="1">
+                                                <property name="border">5</property>
+                                                <property name="flag">wxALL</property>
+                                                <property name="proportion">0</property>
+                                                <object class="wxStaticText" expanded="1">
+                                                    <property name="BottomDockable">1</property>
+                                                    <property name="LeftDockable">1</property>
+                                                    <property name="RightDockable">1</property>
+                                                    <property name="TopDockable">1</property>
+                                                    <property name="aui_layer"></property>
+                                                    <property name="aui_name"></property>
+                                                    <property name="aui_position"></property>
+                                                    <property name="aui_row"></property>
+                                                    <property name="best_size"></property>
+                                                    <property name="bg"></property>
+                                                    <property name="caption"></property>
+                                                    <property name="caption_visible">1</property>
+                                                    <property name="center_pane">0</property>
+                                                    <property name="close_button">1</property>
+                                                    <property name="context_help"></property>
+                                                    <property name="context_menu">1</property>
+                                                    <property name="default_pane">0</property>
+                                                    <property name="dock">Dock</property>
+                                                    <property name="dock_fixed">0</property>
+                                                    <property name="docking">Left</property>
+                                                    <property name="enabled">1</property>
+                                                    <property name="fg"></property>
+                                                    <property name="floatable">1</property>
+                                                    <property name="font"></property>
+                                                    <property name="gripper">0</property>
+                                                    <property name="hidden">0</property>
+                                                    <property name="id">wxID_ANY</property>
+                                                    <property name="label"></property>
+                                                    <property name="markup">0</property>
+                                                    <property name="max_size"></property>
+                                                    <property name="maximize_button">0</property>
+                                                    <property name="maximum_size"></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_BPPunits3</property>
+                                                    <property name="pane_border">1</property>
+                                                    <property name="pane_position"></property>
+                                                    <property name="pane_size"></property>
+                                                    <property name="permission">protected</property>
+                                                    <property name="pin_button">1</property>
+                                                    <property name="pos"></property>
+                                                    <property name="resize">Resizable</property>
+                                                    <property name="show">1</property>
+                                                    <property name="size"></property>
+                                                    <property name="style"></property>
+                                                    <property name="subclass"></property>
+                                                    <property name="toolbar_pane">0</property>
+                                                    <property name="tooltip"></property>
+                                                    <property name="window_extra_style"></property>
+                                                    <property name="window_name"></property>
+                                                    <property name="window_style"></property>
+                                                    <property name="wrap">-1</property>
+                                                </object>
+                                            </object>
                                             <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
@@ -1130,7 +1386,7 @@
                                             </object>
                                             <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxBOTTOM|wxRIGHT</property>
+                                                <property name="flag">wxBOTTOM|wxRIGHT|wxALIGN_BOTTOM</property>
                                                 <property name="proportion">0</property>
                                                 <object class="wxTextCtrl" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -1166,9 +1422,9 @@
                                                     <property name="maxlength"></property>
                                                     <property name="min_size"></property>
                                                     <property name="minimize_button">0</property>
-                                                    <property name="minimum_size">40,-1</property>
+                                                    <property name="minimum_size">60,-1</property>
                                                     <property name="moveable">1</property>
-                                                    <property name="name">m_DPIValueX</property>
+                                                    <property name="name">m_UnitSizeX</property>
                                                     <property name="pane_border">1</property>
                                                     <property name="pane_position"></property>
                                                     <property name="pane_size"></property>
@@ -1183,20 +1439,19 @@
                                                     <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_style">wxFILTER_NUMERIC</property>
+                                                    <property name="validator_type">wxTextValidator</property>
                                                     <property name="validator_variable"></property>
                                                     <property name="value">300</property>
                                                     <property name="window_extra_style"></property>
                                                     <property name="window_name"></property>
                                                     <property name="window_style"></property>
-                                                    <event name="OnLeaveWindow">UpdatePPITextValueX</event>
-                                                    <event name="OnText">OnResolutionChange</event>
+                                                    <event name="OnText">OnSizeChangeX</event>
                                                 </object>
                                             </object>
                                             <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
+                                                <property name="flag">wxBOTTOM|wxRIGHT|wxALIGN_BOTTOM</property>
                                                 <property name="proportion">0</property>
                                                 <object class="wxTextCtrl" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -1232,9 +1487,9 @@
                                                     <property name="maxlength"></property>
                                                     <property name="min_size"></property>
                                                     <property name="minimize_button">0</property>
-                                                    <property name="minimum_size">40,-1</property>
+                                                    <property name="minimum_size">60,-1</property>
                                                     <property name="moveable">1</property>
-                                                    <property name="name">m_DPIValueY</property>
+                                                    <property name="name">m_UnitSizeY</property>
                                                     <property name="pane_border">1</property>
                                                     <property name="pane_position"></property>
                                                     <property name="pane_size"></property>
@@ -1249,22 +1504,21 @@
                                                     <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_style">wxFILTER_NUMERIC</property>
+                                                    <property name="validator_type">wxTextValidator</property>
                                                     <property name="validator_variable"></property>
                                                     <property name="value">300</property>
                                                     <property name="window_extra_style"></property>
                                                     <property name="window_name"></property>
                                                     <property name="window_style"></property>
-                                                    <event name="OnLeaveWindow">UpdatePPITextValueY</event>
-                                                    <event name="OnText">OnResolutionChange</event>
+                                                    <event name="OnText">OnSizeChangeY</event>
                                                 </object>
                                             </object>
                                             <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
+                                                <property name="flag">wxALL|wxALIGN_BOTTOM</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxStaticText" expanded="0">
+                                                <object class="wxChoice" expanded="0">
                                                     <property name="BottomDockable">1</property>
                                                     <property name="LeftDockable">1</property>
                                                     <property name="RightDockable">1</property>
@@ -1278,6 +1532,7 @@
                                                     <property name="caption"></property>
                                                     <property name="caption_visible">1</property>
                                                     <property name="center_pane">0</property>
+                                                    <property name="choices"></property>
                                                     <property name="close_button">1</property>
                                                     <property name="context_help"></property>
                                                     <property name="context_menu">1</property>
@@ -1292,16 +1547,14 @@
                                                     <property name="gripper">0</property>
                                                     <property name="hidden">0</property>
                                                     <property name="id">wxID_ANY</property>
-                                                    <property name="label">DPI</property>
-                                                    <property name="markup">0</property>
                                                     <property name="max_size"></property>
                                                     <property name="maximize_button">0</property>
                                                     <property name="maximum_size"></property>
                                                     <property name="min_size"></property>
                                                     <property name="minimize_button">0</property>
-                                                    <property name="minimum_size"></property>
+                                                    <property name="minimum_size">80,-1</property>
                                                     <property name="moveable">1</property>
-                                                    <property name="name">m_DPI_Units</property>
+                                                    <property name="name">m_PixelUnit</property>
                                                     <property name="pane_border">1</property>
                                                     <property name="pane_position"></property>
                                                     <property name="pane_size"></property>
@@ -1309,16 +1562,21 @@
                                                     <property name="pin_button">1</property>
                                                     <property name="pos"></property>
                                                     <property name="resize">Resizable</property>
+                                                    <property name="selection">0</property>
                                                     <property name="show">1</property>
                                                     <property name="size"></property>
                                                     <property name="style"></property>
-                                                    <property name="subclass"></property>
+                                                    <property name="subclass">; ; Not forward_declare</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="window_extra_style"></property>
                                                     <property name="window_name"></property>
                                                     <property name="window_style"></property>
-                                                    <property name="wrap">-1</property>
+                                                    <event name="OnChoice">OnSizeUnitChange</event>
                                                 </object>
                                             </object>
                                         </object>
diff --git a/bitmap2component/bitmap2cmp_gui_base.h b/bitmap2component/bitmap2cmp_gui_base.h
index 0daf581b1..accc8a30f 100644
--- a/bitmap2component/bitmap2cmp_gui_base.h
+++ b/bitmap2component/bitmap2cmp_gui_base.h
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Dec  1 2018)
+// C++ code generated with wxFormBuilder (version Oct 26 2018)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO *NOT* EDIT THIS FILE!
@@ -7,31 +7,34 @@
 
 #pragma once
 
-#include <wx/artprov.h>
-#include <wx/xrc/xmlres.h>
-#include <wx/intl.h>
 #include "kiway_player.h"
-#include <wx/scrolwin.h>
-#include <wx/gdicmn.h>
-#include <wx/font.h>
-#include <wx/colour.h>
-#include <wx/settings.h>
-#include <wx/string.h>
+#include <wx/artprov.h>
 #include <wx/bitmap.h>
-#include <wx/image.h>
+#include <wx/bmpbuttn.h>
+#include <wx/button.h>
+#include <wx/checkbox.h>
+#include <wx/choice.h>
+#include <wx/colour.h>
+#include <wx/font.h>
+#include <wx/frame.h>
+#include <wx/gdicmn.h>
 #include <wx/icon.h>
+#include <wx/image.h>
+#include <wx/intl.h>
 #include <wx/notebook.h>
-#include <wx/stattext.h>
-#include <wx/textctrl.h>
-#include <wx/sizer.h>
-#include <wx/statbox.h>
-#include <wx/button.h>
+#include <wx/panel.h>
 #include <wx/radiobox.h>
+#include <wx/scrolwin.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
 #include <wx/slider.h>
-#include <wx/checkbox.h>
-#include <wx/panel.h>
+#include <wx/statbox.h>
+#include <wx/stattext.h>
 #include <wx/statusbr.h>
-#include <wx/frame.h>
+#include <wx/string.h>
+#include <wx/textctrl.h>
+#include <wx/valtext.h>
+#include <wx/xrc/xmlres.h>
 
 ///////////////////////////////////////////////////////////////////////////
 
@@ -53,17 +56,21 @@ class BM2CMP_FRAME_BASE : public KIWAY_PLAYER
 		wxStaticText* m_SizeXValue;
 		wxStaticText* m_SizeYValue;
 		wxStaticText* m_SizePixUnits;
-		wxStaticText* m_staticTextSize1;
-		wxStaticText* m_SizeXValue_mm;
-		wxStaticText* m_SizeYValue_mm;
-		wxStaticText* m_Size_mmxUnits;
+		wxStaticText* m_staticTextDPI;
+		wxStaticText* m_InputXValueDPI;
+		wxStaticText* m_InputYValueDPI;
+		wxStaticText* m_DPIUnit;
 		wxStaticText* m_staticTextBPP;
 		wxStaticText* m_BPPValue;
 		wxStaticText* m_BPPunits;
+		wxStaticText* m_BPPunits1;
+		wxStaticText* m_BPPunits2;
+		wxBitmapButton* m_AspectRatioLockButton;
+		wxStaticText* m_BPPunits3;
 		wxStaticText* m_staticTextBPI;
-		wxTextCtrl* m_DPIValueX;
-		wxTextCtrl* m_DPIValueY;
-		wxStaticText* m_DPI_Units;
+		wxTextCtrl* m_UnitSizeX;
+		wxTextCtrl* m_UnitSizeY;
+		wxChoice* m_PixelUnit;
 		wxButton* m_buttonLoad;
 		wxButton* m_buttonExportFile;
 		wxButton* m_buttonExportClipboard;
@@ -78,10 +85,20 @@ class BM2CMP_FRAME_BASE : public KIWAY_PLAYER
 		virtual void OnPaintInit( wxPaintEvent& event ) { event.Skip(); }
 		virtual void OnPaintGreyscale( wxPaintEvent& event ) { event.Skip(); }
 		virtual void OnPaintBW( wxPaintEvent& event ) { event.Skip(); }
-		virtual void UpdatePPITextValueX( wxMouseEvent& event ) { event.Skip(); }
-		virtual void OnResolutionChange( wxCommandEvent& event ) { event.Skip(); }
-		virtual void UpdatePPITextValueY( wxMouseEvent& event ) { event.Skip(); }
-		virtual void OnLoadFile( wxCommandEvent& event ) { event.Skip(); }
+		virtual void ToggleAspectRatioLock( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnSizeChangeX( wxCommandEvent& event )
+        {
+            event.Skip();
+        }
+        virtual void OnSizeChangeY( wxCommandEvent& event )
+        {
+            event.Skip();
+        }
+        virtual void OnSizeUnitChange( wxCommandEvent& event )
+        {
+            event.Skip();
+        }
+        virtual void OnLoadFile( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnExportToFile( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnExportToClipboard( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnFormatChange( wxCommandEvent& event ) { event.Skip(); }
@@ -90,8 +107,9 @@ class BM2CMP_FRAME_BASE : public KIWAY_PLAYER
 
 
 	public:
+        wxString m_NumericValidator;
 
-		BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Bitmap to Component Converter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,616 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
+        BM2CMP_FRAME_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Bitmap to Component Converter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 746,616 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
 
 		~BM2CMP_FRAME_BASE();
 
diff --git a/bitmap2component/bitmap2component.h b/bitmap2component/bitmap2component.h
index ac47902e0..ea4e20f7b 100644
--- a/bitmap2component/bitmap2component.h
+++ b/bitmap2component/bitmap2component.h
@@ -25,6 +25,7 @@
 #define BITMAP2COMPONENT_H
 
 #include <geometry/shape_poly_set.h>
+#include <potracelib.h>
 
 // for consistency this enum should conform to the
 // indices in m_radioBoxFormat from bitmap2cmp_gui.cpp

--------------2.17.1--



Follow ups