← Back to team overview

kicad-developers team mailing list archive

[PATCH] Centralized paneinfo

 

Attached is a patch proposal for centralizing the configuration of Aui
panes in prep for a user configurable interface.

The outward GUI remains unchanged. When we are ready to allow moveable
toolbars, a quick change to the EDA_PANEINFO class, already prepped,
will do this.

* Added EDA_PANEINFO class to centralize AuiPanel configuration
* Changed the frame initialization of each app to use EDA_PANEINFO
* Fixed erroneous use of Aui layout api in some cases.


...I'm off on holiday for a week. I'll answer any issues after that.

Regards,

Hauptmech
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: hauptmech@xxxxxxxxx-20110901085432-zz8hfafu20qu2pib
# target_branch: ../kicad
# testament_sha1: eade7f4647e770c1c2fde247fb10d5545726d1ab
# timestamp: 2011-09-01 11:54:55 +0200
# base_revision_id: stambaughw@xxxxxxxxxxx-20110831132705-\
#   5i72daa6hd62vxva
# 
# Begin patch
=== modified file '3d-viewer/3d_frame.cpp'
--- 3d-viewer/3d_frame.cpp	2011-08-29 03:04:59 +0000
+++ 3d-viewer/3d_frame.cpp	2011-08-31 17:33:59 +0000
@@ -70,18 +70,9 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    wxAuiPaneInfo vert( horiz );
-
-    vert.TopDockable( false ).BottomDockable( false );
-    horiz.LeftDockable( false ).RightDockable( false );
+
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
 
     m_auimgr.AddPane( m_HToolBar,
                       wxAuiPaneInfo( horiz ).Name( wxT( "m_HToolBar" ) ).Top() );

=== modified file 'cvpcb/class_DisplayFootprintsFrame.cpp'
--- cvpcb/class_DisplayFootprintsFrame.cpp	2011-08-28 20:51:45 +0000
+++ cvpcb/class_DisplayFootprintsFrame.cpp	2011-08-31 17:33:59 +0000
@@ -85,18 +85,17 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    wxAuiPaneInfo vert( horiz );
-
-    vert.TopDockable( false ).BottomDockable( false );
-    horiz.LeftDockable( false ).RightDockable( false );
+
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO vert;
+    vert.VerticalToolbarPane();
+
+    EDA_PANEINFO mesg;
+    mesg.MessageToolbarPane();
+
+
 
     m_auimgr.AddPane( m_HToolBar,
                       wxAuiPaneInfo( horiz ).Name( wxT( "m_HToolBar" ) ).Top(). Row( 0 ) );
@@ -109,7 +108,7 @@
                       wxAuiPaneInfo().Name( wxT( "DisplayFrame" ) ).CentrePane() );
 
     m_auimgr.AddPane( MsgPanel,
-                      wxAuiPaneInfo( horiz ).Name( wxT( "MsgPanel" ) ).Bottom() );
+                      wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() );
 
     m_auimgr.AddPane( m_OptionsToolBar,
                       wxAuiPaneInfo( vert ).Name( wxT( "m_OptionsToolBar" ) ).Left() );

=== modified file 'cvpcb/cvframe.cpp'
--- cvpcb/cvframe.cpp	2011-08-24 19:44:05 +0000
+++ cvpcb/cvframe.cpp	2011-08-31 17:33:59 +0000
@@ -137,15 +137,19 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    horiz.LeftDockable( false ).RightDockable( false );
+
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO vert;
+    vert.VerticalToolbarPane();
+
+    EDA_PANEINFO mesg;
+    mesg.MessageToolbarPane();
+
+    EDA_PANEINFO info;
+    info.InfoToolbarPane();
+
 
     if( m_HToolBar )
         m_auimgr.AddPane( m_HToolBar,
@@ -157,7 +161,7 @@
 
     if( m_FootprintList )
         m_auimgr.AddPane( m_FootprintList,
-                          wxAuiPaneInfo( horiz ).Name( wxT( "m_FootprintList" ) ).
+                          wxAuiPaneInfo( info ).Name( wxT( "m_FootprintList" ) ).
                           Right().BestSize( (int) ( m_FrameSize.x * 0.36 ), m_FrameSize.y ) );
 
     m_auimgr.Update();

=== modified file 'eeschema/libeditframe.cpp'
--- eeschema/libeditframe.cpp	2011-08-29 03:04:59 +0000
+++ eeschema/libeditframe.cpp	2011-08-31 17:33:59 +0000
@@ -216,18 +216,17 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    wxAuiPaneInfo vert( horiz );
-
-    vert.TopDockable( false ).BottomDockable( false );
-    horiz.LeftDockable( false ).RightDockable( false );
+
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO vert;
+    vert.VerticalToolbarPane();
+
+    EDA_PANEINFO mesg;
+    mesg.MessageToolbarPane();
+
+
 
     m_auimgr.AddPane( m_HToolBar,
                       wxAuiPaneInfo( horiz ).Name( wxT( "m_HToolBar" ) ).Top().Row( 0 ) );
@@ -242,7 +241,7 @@
                       wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
 
     m_auimgr.AddPane( MsgPanel,
-                      wxAuiPaneInfo( horiz ).Name( wxT( "MsgPanel" ) ).Bottom() );
+                      wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() );
 
     m_auimgr.Update();
 

=== modified file 'eeschema/schframe.cpp'
--- eeschema/schframe.cpp	2011-08-18 19:25:12 +0000
+++ eeschema/schframe.cpp	2011-08-31 17:33:59 +0000
@@ -213,18 +213,16 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    wxAuiPaneInfo vert( horiz );
-
-    vert.TopDockable( false ).BottomDockable( false );
-    horiz.LeftDockable( false ).RightDockable( false );
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO vert;
+    vert.VerticalToolbarPane();
+
+    EDA_PANEINFO mesg;
+    mesg.MessageToolbarPane();
+
+
 
     if( m_HToolBar )
         m_auimgr.AddPane( m_HToolBar,
@@ -241,7 +239,7 @@
         m_auimgr.AddPane( DrawPanel, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
 
     if( MsgPanel )
-        m_auimgr.AddPane( MsgPanel, wxAuiPaneInfo( horiz ).Name( wxT( "MsgPanel" ) ).Bottom() );
+        m_auimgr.AddPane( MsgPanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() );
 
     m_auimgr.Update();
 

=== modified file 'gerbview/gerbview_frame.cpp'
--- gerbview/gerbview_frame.cpp	2011-07-05 12:46:14 +0000
+++ gerbview/gerbview_frame.cpp	2011-08-31 17:33:59 +0000
@@ -86,24 +86,21 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    wxAuiPaneInfo vert( horiz );
-
-    vert.TopDockable( false ).BottomDockable( false );
-    horiz.LeftDockable( false ).RightDockable( false );
-
-    // LAYER_WIDGET is floatable, but initially docked at far right
-    wxAuiPaneInfo lyrs;
-    lyrs.CloseButton( false );
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO vert;
+    vert.VerticalToolbarPane();
+
+    EDA_PANEINFO mesg;
+    mesg.MessageToolbarPane();
+
+    EDA_PANEINFO   lyrs;
+    lyrs.LayersToolbarPane();
+    lyrs.MinSize( m_LayersManager->GetBestSize() );
+    lyrs.BestSize( m_LayersManager->GetBestSize() );
     lyrs.Caption( _( "Visibles" ) );
-    lyrs.IsFloatable();
+
 
     if( m_HToolBar )
         m_auimgr.AddPane( m_HToolBar,
@@ -114,7 +111,7 @@
                           wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right().Row( 1 ) );
 
     m_auimgr.AddPane( m_LayersManager,
-                      lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Row( 0 ) );
+                      lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 0 ) );
 
     if( m_OptionsToolBar )
         m_auimgr.AddPane( m_OptionsToolBar,
@@ -126,7 +123,7 @@
 
     if( MsgPanel )
         m_auimgr.AddPane( MsgPanel,
-                          wxAuiPaneInfo( horiz ).Name( wxT( "MsgPanel" ) ).Bottom() );
+                          wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() );
 
     ReFillLayerWidget();                // this is near end because contents establish size
     m_LayersManager->ReFillRender();    // Update colors in Render after the config is read

=== modified file 'include/wxstruct.h'
--- include/wxstruct.h	2011-08-18 19:25:12 +0000
+++ include/wxstruct.h	2011-09-01 08:54:32 +0000
@@ -773,5 +773,108 @@
     int GetDimension( );
 };
 
+/**
+ * Specialization of the wxAuiPaneInfo class for Kicad panels.
+ *
+ * Documentation for wxAui is poor at this time. The following notes spring from errors made in
+ * previous kicad implementations:
+ * 
+ * wxAuiPaneInfo.ToolbarPane() and .Defaults() are used to clear and then prepare the objects so
+ * only use them once at the beginning of configuration..
+ *
+ * Panels are organized in layers, from 0 (close to the center) and increasing outward. Note
+ * that for ToolbarPanes, layer 0 considered a special default value, and ToolbarPanes on
+ * layer 0 are pushed to layer 10 automatically. Use Layer 1 for the inner layer as a work-
+ * around.
+ *
+ * Each panel has rows, starting at 0. Each row has positions starting at 0. Each item in a panel
+ * can have it's row and position set.
+ *
+ * Eventually panels will be moveable. Each initialization function sets up the panel for this,
+ * then after a //==// break has additional calls to anchor toolbars in a way that matches
+ * present functionality.
+ */
+
+class EDA_PANEINFO : public wxAuiPaneInfo
+{
+
+public:
+
+    /**
+     * Function HorizontalToolbarPane
+     * Change *this to a horizontal toolbar for kicad.
+     */
+    EDA_PANEINFO& HorizontalToolbarPane()
+    {
+        ToolbarPane();
+        CloseButton( false );
+        LeftDockable( false );
+        RightDockable( false );
+        //====================  Remove calls below here for moveable toolbars //
+        Gripper( false );
+        DockFixed( true );
+        Movable( false );
+        return *this;
+    }
+
+    /**
+     * Function VerticalToolbarPane
+     * Change *this to a vertical toolbar for kicad.
+     */
+    EDA_PANEINFO& VerticalToolbarPane()
+    {
+        ToolbarPane();
+        CloseButton( false );
+        TopDockable( false );
+        BottomDockable( false );
+        //====================  Remove calls below here for moveable toolbars //
+        Gripper( false );
+        DockFixed( true );
+        Movable( false );
+        return *this;
+    }
+
+    /**
+     * Function MessageToolbarPane
+     * Change *this to a message pane for kicad.
+     * 
+     */
+    EDA_PANEINFO& MessageToolbarPane()
+    {
+        Gripper( false );
+        DockFixed( true );
+        Movable( false );
+        Floatable( false );
+        CloseButton( false );
+        CaptionVisible( false );
+        return *this;
+    }
+
+    /**
+     * Function LayersToolbarPane
+     * Change *this to a layers toolbar for kicad.
+     */
+    EDA_PANEINFO& LayersToolbarPane()
+    {
+        CloseButton( false );
+        return *this;
+    }
+
+    /**
+     * Function InfoToolbarPane
+     * Change *this to a information panel for for kicad.
+     *
+     * Info panes are used for vertical display of information next to the center pane.
+     * Used in cvpcb and libviewer primarily
+     */
+    EDA_PANEINFO& InfoToolbarPane()
+    {
+        Gripper( false );
+        CloseButton( false );
+        CaptionVisible( false );
+        return *this;
+    }
+
+};
 
 #endif  /* WXSTRUCT_H */

=== modified file 'kicad/mainframe.cpp'
--- kicad/mainframe.cpp	2011-08-29 03:04:59 +0000
+++ kicad/mainframe.cpp	2011-08-31 17:33:59 +0000
@@ -72,15 +72,11 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-    horiz.LeftDockable( false );
-    horiz.RightDockable( false );
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO info;
+    info.InfoToolbarPane();
 
     if( m_HToolBar )
         m_auimgr.AddPane( m_HToolBar,
@@ -92,9 +88,10 @@
 
     if( m_LeftWin )
         m_auimgr.AddPane( m_LeftWin,
-                          wxAuiPaneInfo().Name( wxT( "m_LeftWin" ) ).Floatable( false ).
-                          CloseButton( false ).Left().BestSize( m_LeftWin_Width, clientsize.y ).
-                          Layer( 1 ).CaptionVisible( false ) );
+                          wxAuiPaneInfo(info).Name( wxT( "m_LeftWin" ) ).Left().
+                          BestSize( m_LeftWin_Width, clientsize.y ).
+                          Layer( 1 ) );
+        
     m_auimgr.Update();
 }
 

=== modified file 'pcbnew/moduleframe.cpp'
--- pcbnew/moduleframe.cpp	2011-08-26 17:01:17 +0000
+++ pcbnew/moduleframe.cpp	2011-08-31 17:33:59 +0000
@@ -155,18 +155,14 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    wxAuiPaneInfo vert( horiz );
-
-    vert.TopDockable( false ).BottomDockable( false );
-    horiz.LeftDockable( false ).RightDockable( false );
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO vert;
+    vert.VerticalToolbarPane();
+
+    EDA_PANEINFO mesg_pane;
+    mesg_pane.MessageToolbarPane();
 
     m_auimgr.AddPane( m_HToolBar,
                       wxAuiPaneInfo( horiz ).Name( wxT( "m_HToolBar" ) ).Top(). Row( 0 ) );
@@ -184,7 +180,7 @@
                       wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
 
     m_auimgr.AddPane( MsgPanel,
-                      wxAuiPaneInfo( horiz ).Name( wxT( "MsgPanel" ) ).Bottom() );
+                      wxAuiPaneInfo( mesg_pane ).Name( wxT( "MsgPanel" ) ).Bottom() );
 
     m_auimgr.Update();
 }

=== modified file 'pcbnew/pcbframe.cpp'
--- pcbnew/pcbframe.cpp	2011-08-26 17:01:17 +0000
+++ pcbnew/pcbframe.cpp	2011-08-31 17:33:59 +0000
@@ -328,66 +328,51 @@
 
     m_auimgr.SetManagedWindow( this );
 
-    // Create a wxAuiPaneInfo template for other wxAuiPaneInfo items
-    // Actual wxAuiPaneInfo items will be built from this item.
-    wxAuiPaneInfo horiz;
-    horiz.Gripper( false );
-    horiz.DockFixed( true );
-    horiz.Movable( false );
-    horiz.Floatable( false );
-    horiz.CloseButton( false );
-    horiz.CaptionVisible( false );
-
-    // Create a second template from the first:
-    wxAuiPaneInfo vert( horiz );
-
-    // Set specific options for horizontal and vertical toolbars, using horiz and vert
-    // wxAuiPaneInfo items to manage them.
-    vert.TopDockable( false ).BottomDockable( false );
-    horiz.LeftDockable( false ).RightDockable( false );
-
-    // Create a template from the horiz wxAuiPaneInfo, specific to horizontal toolbars:
-    wxAuiPaneInfo horiz_tb( horiz );
-    horiz_tb.ToolbarPane().Gripper( false );
+    EDA_PANEINFO horiz;
+    horiz.HorizontalToolbarPane();
+
+    EDA_PANEINFO vert;
+    vert.VerticalToolbarPane();
+
+    EDA_PANEINFO mesg;
+    mesg.MessageToolbarPane();
 
     // Create a wxAuiPaneInfo for the Layers Manager, not derived from the template.
     // LAYER_WIDGET is floatable, but initially docked at far right
-    wxAuiPaneInfo   lyrs;
+    EDA_PANEINFO   lyrs;
+    lyrs.LayersToolbarPane();
     lyrs.MinSize( m_Layers->GetBestSize() );    // updated in ReFillLayerWidget
     lyrs.BestSize( m_Layers->GetBestSize() );
-    lyrs.CloseButton( false );
     lyrs.Caption( _( "Visibles" ) );
-    lyrs.IsFloatable();
 
 
     if( m_HToolBar )    // The main horizontal toolbar
     {
         m_auimgr.AddPane( m_HToolBar,
-                          wxAuiPaneInfo( horiz_tb ).Name( wxT( "m_HToolBar" ) ).Top().Row( 0 ) );
+                          wxAuiPaneInfo( horiz ).Name( wxT( "m_HToolBar" ) ).Top().Row( 0 ) );
     }
 
     if( m_AuxiliaryToolBar )    // the auxiliary horizontal toolbar, that shows track and via sizes, zoom ...)
     {
         m_auimgr.AddPane( m_AuxiliaryToolBar,
-                          wxAuiPaneInfo( horiz_tb ).Name( wxT( "m_AuxiliaryToolBar" ) ).Top().Row( 1 ) );
+                          wxAuiPaneInfo( horiz ).Name( wxT( "m_AuxiliaryToolBar" ) ).Top().Row( 1 ) );
     }
 
     if( m_AuxVToolBar )    // The auxiliary vertical toolbar (currently microwave tools)
         m_auimgr.AddPane( m_AuxVToolBar,
-                          wxAuiPaneInfo( vert ).Name( wxT( "m_AuxVToolBar" ) ).Right().Row( 2 ).Hide() );
+                          wxAuiPaneInfo( vert ).Name( wxT( "m_AuxVToolBar" ) ).Right().Layer( 1 ).Position(1).Hide() );
 
     if( m_VToolBar )    // The main right vertical toolbar
         m_auimgr.AddPane( m_VToolBar,
-                          wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right().Row( 1 ) );
+                          wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right().Layer( 1 ) );
 
     // Add the layer manager (right side of pcbframe)
-    m_auimgr.AddPane( m_Layers, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Row( 0 ) );
+    m_auimgr.AddPane( m_Layers, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 2 ) );
 
     if( m_OptionsToolBar )    // The left vertical toolbar
     {
         m_auimgr.AddPane( m_OptionsToolBar,
-                          wxAuiPaneInfo( vert ).Name( wxT( "m_OptionsToolBar" ) ).Left()
-                          .ToolbarPane().Gripper( false ) );
+                          wxAuiPaneInfo( vert ).Name( wxT( "m_OptionsToolBar" ) ).Left().Layer(1) );
 
         m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
         m_auimgr.GetPane( wxT( "m_AuxVToolBar" ) ).Show( m_show_microwave_tools );
@@ -399,7 +384,7 @@
 
     if( MsgPanel )
         m_auimgr.AddPane( MsgPanel,
-                          wxAuiPaneInfo( horiz ).Name( wxT( "MsgPanel" ) ).Bottom() );
+                          wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() );
 
     ReFillLayerWidget();        // this is near end because contents establish size
     m_Layers->ReFillRender();   // Update colors in Render after the config is read

# Begin bundle
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

Follow ups