@@ -31,6 +31,11 @@ def get_version(rel_path: str) -> str:
31
31
32
32
_APP_VERSION = get_version ("_version.py" )
33
33
34
+ def get_btn_bitmap (bitmap ):
35
+ path = resource_path (bitmap )
36
+ png = wx .Bitmap (path , wx .BITMAP_TYPE_PNG )
37
+ return wx .BitmapBundle (png )
38
+
34
39
def ParseFloat (InputString , DefaultValue = 0.0 ):
35
40
value = DefaultValue
36
41
if InputString != "" :
@@ -40,9 +45,35 @@ def ParseFloat(InputString, DefaultValue=0.0):
40
45
print ("Value not valid" )
41
46
return value
42
47
43
- class Dialog (dialog_text_base .DIALOG_TEXT_BASE ):
48
+ class Dialog (dialog_text_base .DialogPanelBase ):
49
+ def __init__ (self , parent , config , layertable , ordering , panelizer , func ):
50
+
51
+ dialog_text_base .DialogPanelBase .__init__ (self , None )
52
+
53
+ self .panel = DialogPanel (self , config , layertable , ordering , panelizer , func )
54
+
55
+ best_size = self .BestSize
56
+ # hack for some gtk themes that incorrectly calculate best size
57
+ best_size .IncBy (dx = 0 , dy = 30 )
58
+ self .SetClientSize (best_size )
59
+
60
+ self .SetTitle (_APP_NAME + " - " + _APP_VERSION )
61
+
62
+ # hack for new wxFormBuilder generating code incompatible with old wxPython
63
+ # noinspection PyMethodOverriding
64
+ def SetSizeHints (self , sz1 , sz2 ):
65
+ try :
66
+ # wxPython 4
67
+ super (Dialog , self ).SetSizeHints (sz1 , sz2 )
68
+ except TypeError :
69
+ # wxPython 3
70
+ self .SetSizeHintsSz (sz1 , sz2 )
44
71
72
+ class DialogPanel (dialog_text_base .DialogPanel ):
45
73
# The names of the config items need to match the names in dialog_text_base minus the m_
74
+ # - except for vScoreLayer
75
+ vscore_layer = 'vScoreLayer'
76
+ default_vscore_layer = 'User.Comments'
46
77
config_defaults = {
47
78
'dimensionsInchesBtn' : 'true' ,
48
79
'dimensionsMmBtn' : 'false' ,
@@ -55,19 +86,18 @@ class Dialog(dialog_text_base.DIALOG_TEXT_BASE):
55
86
'removeRightVerticalCheck' : 'false' ,
56
87
'productionBordersCheck' : 'false' ,
57
88
'productionFiducialsCheck' : 'false' ,
58
- 'productionExposeCheck' : 'false'
89
+ 'productionExposeCheck' : 'false' ,
90
+ vscore_layer : default_vscore_layer
59
91
}
60
92
61
- def __init__ (self , parent , config , ordering , panelizer , func ):
62
- dialog_text_base .DIALOG_TEXT_BASE .__init__ (self , parent )
63
-
64
- # hack for some gtk themes that incorrectly calculate best size
65
- #best_size = self.BestSize
66
- #best_size.IncBy(dx=0, dy=30)
67
- #self.SetClientSize(best_size)
93
+ def __init__ (self , parent , config , layertable , ordering , panelizer , func ):
68
94
95
+ dialog_text_base .DialogPanel .__init__ (self , parent )
96
+
69
97
self .config_file = config
70
98
99
+ self .layertable = layertable
100
+
71
101
self .ordering_instructions = ordering
72
102
73
103
self .panelizer = panelizer
@@ -76,8 +106,25 @@ def __init__(self, parent, config, ordering, panelizer, func):
76
106
77
107
self .error = None
78
108
79
- self .SetTitle (_APP_NAME + " - " + _APP_VERSION )
80
-
109
+ self .general = GeneralPanel (self .notebook )
110
+ self .vscore = VScorePanel (self .notebook )
111
+ self .notebook .AddPage (self .general , "General" )
112
+ self .notebook .AddPage (self .vscore , "V-Score" )
113
+
114
+ # Delete any existing rows in LayersGrid
115
+ if self .vscore .LayersGrid .NumberRows :
116
+ self .vscore .LayersGrid .DeleteRows (0 , self .vscore .LayersGrid .NumberRows )
117
+ # Append empty rows based on layertable
118
+ self .vscore .LayersGrid .AppendRows (len (self .layertable ))
119
+ # Initialize them
120
+ row = 0
121
+ for layer in self .layertable .keys ():
122
+ self .vscore .LayersGrid .SetCellValue (row , 0 , "0" ) # JSON style
123
+ self .vscore .LayersGrid .SetCellRenderer (row , 0 , wx .grid .GridCellBoolRenderer ())
124
+ self .vscore .LayersGrid .SetCellValue (row , 1 , layer )
125
+ self .vscore .LayersGrid .SetReadOnly (row , 1 )
126
+ row += 1
127
+
81
128
self .loadConfig ()
82
129
83
130
def loadConfig (self ):
@@ -108,34 +155,110 @@ def LoadSettings(self, params):
108
155
if value is None :
109
156
continue
110
157
111
- try :
112
- obj = getattr (self , "m_{}" .format (key ))
113
- if hasattr (obj , "SetValue" ):
114
- obj .SetValue (value )
115
- elif hasattr (obj , "SetStringSelection" ):
116
- obj .SetStringSelection (value )
117
- else :
118
- raise Exception ("Invalid item" )
119
- except Exception as e :
120
- pass
158
+ if self .vscore_layer in key :
159
+ defaultLayerFound = False
160
+ for row in range (self .vscore .LayersGrid .GetNumberRows ()):
161
+ if value in self .vscore .LayersGrid .GetCellValue (row , 1 ):
162
+ b = "1"
163
+ defaultLayerFound = True
164
+ else :
165
+ b = "0"
166
+ self .vscore .LayersGrid .SetCellValue (row , 0 , b )
167
+ if not defaultLayerFound :
168
+ self .vscore .LayersGrid .SetCellValue (0 , 0 , "1" ) # Default to the first layer
169
+ else :
170
+ try :
171
+ obj = getattr (self .general , "m_{}" .format (key ))
172
+ if hasattr (obj , "SetValue" ):
173
+ obj .SetValue (value )
174
+ elif hasattr (obj , "SetStringSelection" ):
175
+ obj .SetStringSelection (value )
176
+ else :
177
+ raise Exception ("Invalid item" )
178
+ except Exception as e :
179
+ pass
180
+
121
181
return params
122
182
123
183
def CurrentSettings (self ):
124
184
params = {}
125
185
126
186
for item in self .config_defaults .keys ():
127
- obj = getattr (self , "m_{}" .format (item ))
128
- if hasattr (obj , "GetValue" ):
129
- params .update ({item : obj .GetValue ()})
130
- elif hasattr (obj , "GetStringSelection" ):
131
- params .update ({item : obj .GetStringSelection ()})
187
+ if self .vscore_layer in item :
188
+ for row in range (self .vscore .LayersGrid .GetNumberRows ()):
189
+ if self .vscore .LayersGrid .GetCellValue (row , 0 ) == "1" :
190
+ params .update ({self .vscore_layer : self .vscore .LayersGrid .GetCellValue (row , 1 )})
132
191
else :
133
- raise Exception ("Invalid item" )
192
+ obj = getattr (self .general , "m_{}" .format (item ))
193
+ if hasattr (obj , "GetValue" ):
194
+ params .update ({item : obj .GetValue ()})
195
+ elif hasattr (obj , "GetStringSelection" ):
196
+ params .update ({item : obj .GetStringSelection ()})
197
+ else :
198
+ raise Exception ("Invalid item" )
199
+
134
200
return params
135
201
136
202
def OnPanelizeClick (self , e ):
137
203
self .saveConfig ()
138
204
self .func (self , self .panelizer )
139
205
140
206
def OnCancelClick (self , e ):
141
- self .EndModal (wx .ID_CANCEL )
207
+ self .GetParent ().EndModal (wx .ID_CANCEL )
208
+
209
+ class GeneralPanel (dialog_text_base .GeneralPanelBase ):
210
+
211
+ def __init__ (self , parent ):
212
+ dialog_text_base .GeneralPanelBase .__init__ (self , parent )
213
+
214
+ self .m_buttonFiducialsHelp .SetLabelText ("" )
215
+ # Icon by Icons8 https://icons8.com : https://icons8.com/icon/63308/info
216
+ self .m_buttonFiducialsHelp .SetBitmap (get_btn_bitmap ("info-15.png" ))
217
+
218
+ self .m_buttonEdgeHelp .SetLabelText ("" )
219
+ # Icon by Icons8 https://icons8.com : https://icons8.com/icon/63308/info
220
+ self .m_buttonEdgeHelp .SetBitmap (get_btn_bitmap ("info-15.png" ))
221
+
222
+ def ClickFiducialsHelp ( self , event ):
223
+ wx .MessageBox ("\
224
+ By default, the panel fiducials are placed in\n \
225
+ the top and bottom edges. Normally we\n \
226
+ recommend leaving them there.\n \
227
+ \n \
228
+ Selecting this option moves them to the left\n \
229
+ and right edges.\n \
230
+ \n \
231
+ This can be useful when using horizontal gaps\n \
232
+ and vertical v-scores. It avoids the panel\n \
233
+ having to be scrapped if an edge has been\n \
234
+ snapped off and the fiducials are missing.\
235
+ " , 'Info' , wx .OK | wx .ICON_INFORMATION )
236
+
237
+ def ClickEdgeHelp ( self , event ):
238
+ wx .MessageBox ("\
239
+ Select this option if you are panelizing\n \
240
+ a MicroMod Processor or Function Board.\n \
241
+ \n \
242
+ The bottom and top edges will be exposed\n \
243
+ so the fingers and chamfered edge can be\n \
244
+ manufactured. The top row of PCBs is\n \
245
+ rotated automatically.\
246
+ " , 'Info' , wx .OK | wx .ICON_INFORMATION )
247
+
248
+ class VScorePanel (dialog_text_base .VScorePanelBase ):
249
+
250
+ def __init__ (self , parent ):
251
+ dialog_text_base .VScorePanelBase .__init__ (self , parent )
252
+
253
+ self .Layout ()
254
+ self .LayersGrid .SetColSize (0 , 50 )
255
+ self .LayersGrid .SetColSize (1 , self .GetParent ().GetClientSize ().x - 80 )
256
+
257
+ def OnLayersGridCellClicked (self , event ):
258
+ self .LayersGrid .ClearSelection ()
259
+ #self.LayersGrid.SelectRow(event.Row)
260
+ if event .Col == 0 :
261
+ for row in range (self .LayersGrid .GetNumberRows ()):
262
+ val = "1" if (row == event .Row ) else "0" # JSON style
263
+ self .LayersGrid .SetCellValue (row , 0 , val )
264
+
0 commit comments