summaryrefslogtreecommitdiff
path: root/cad/src/commands/BuildAtom/AtomGeneratorPropertyManager.py
blob: 1999fa3bfad89e5b8d1ceb9092586684da883ac5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
# Copyright 2004-2007 Nanorex, Inc.  See LICENSE file for details. 
"""
An example of a structure generator's user interface 
meant to be a template for developers.

The AtomGeneratorDialog class is an example of how PropMgrBaseClass 
is used to build a structure generator's user interface (dialog) in 
NanoEngineer-1.  The key points of interest are the methods: __init__, 
addGroupBoxes and add_whats_this_text.  They all **must always** be 
overridden when a new structure generator dialog class is defined.

The class variables <title> and <iconPath> should be changed to fit the 
new structure generator's role.

The class static variables (prefixed with _s) and their accessor 
methods (Get.../Set...) are purely for the sake of example and may 
be omitted from any new implementation.

@author: Jeff Birac
@version: $Id$
@copyright: 2007 Nanorex, Inc.  See LICENSE file for details.

History:
  Jeff 2007-05-29: Based on Mark Sims' GrapheneGeneratorDialog.py, v1.17

            Convention of variables' names:

                   variable's role     prefix      examples
                  -----------------   --------    ----------
                - incoming parameter    in...      inData
                                                   inObjectPointer

                - outgoing parameter               outBufferPointer
                  or function return    out...     outCalculation
                   
                - I/O parameter         io...      ioDataBuffer

                - static variable       s...       sDefaultValue

                - local variable        the...     theUserName
                                                   theTempValue

                - class member          m...       mObjectName
                  (aka attribute or                mPosition
                  instance variable)               mColor
                  
  Mark 2007-07-24: Uses new PM module.
  
"""

from utilities.icon_utilities import geticon, getpixmap

from PyQt4.Qt import Qt, SIGNAL

from PM.PM_Dialog          import PM_Dialog
from PM.PM_GroupBox        import PM_GroupBox
from PM.PM_DoubleSpinBox   import PM_DoubleSpinBox
from PM.PM_ComboBox        import PM_ComboBox
from PM.PM_SpinBox         import PM_SpinBox
from PM.PM_TextEdit        import PM_TextEdit
from PM.PM_PushButton      import PM_PushButton
from PM.PM_LineEdit        import PM_LineEdit
from PM.PM_CheckBox        import PM_CheckBox
from PM.PM_RadioButton     import PM_RadioButton

from PM.PM_ElementChooser     import PM_ElementChooser

class AtomGeneratorPropertyManager(PM_Dialog):
    """ Implements user interface to specify properties of an atom """

    # The title that appears in the property manager header.
    title = "Insert Atom"
    # The name of this property manager. This will be set to
    # the name of the PM_Dialog object via setObjectName().
    pmName = title
    # The relative path to PNG file that appears in the header.
    iconPath = "ui/actions/Command Toolbar/BuildAtoms/InsertAtom.png"

    # Jeff 20070530:
    # Private static variables (prefixed with '_s') are used to assure consistency 
    # between related widgets and simplify code revision.
    # Example: The unit for coordinates is specified by _sCoordinateUnit.  All
    # widgets related to coordinates should refer to _sCoordinateUnit rather than
    # hardcoding the unit for each coordinate widget.  The advantage comes when 
    # a later revision uses different units (or chosen possibly via a user
    # preference), the value of only _sCoordinateUnit (not blocks of code)
    # needs to be changed.  All related widgets follow the new choice for units.

    _sMinCoordinateValue   = -30.0
    _sMaxCoordinateValue   =  30.0
    _sStepCoordinateValue  =  0.1
    _sCoordinateDecimals   =  3
    _sCoordinateUnit       =  'Angstrom'
    _sCoordinateUnits      =  _sCoordinateUnit + 's'

    def __init__(self):
        """
        Construct the Atom Property Manager.
        """
        PM_Dialog.__init__( self, self.pmName, self.iconPath, self.title )
        self.addGroupBoxes()
        self.add_whats_this_text()
        
        msg = "Edit the Atom parameters and select <b>Preview</b> to \
        preview the structure. Click <b>Done</b> to insert the atom \
        into the model."
        
        # This causes the "Message" box to be displayed as well.
        self.MessageGroupBox.insertHtmlMessage( msg, setAsDefault = False )
        
    def getCartesianCoordinates(self):
        """
        Gets the cartesian coordinates for the position of the atom
        specified in the coordinate spin boxes of the Atom Generator
        property manager.
        """
        return ( self.xCoordinateField.value, 
                 self.yCoordinateField.value, 
                 self.zCoordinateField.value )

    def getMinCoordinateValue(self):
        """
        Get the minimum value allowed in the coordinate spin boxes 
        of the Atom Generator property manager.
        """
        return self.sel_sMinCoordinateValue
    
    def getMaxCoordinateValue(self):
        """
        Get the maximum value allowed in the coordinate 
        spin boxes of the Atom Generator property manager.
        """
        return self._sMaxCoordinateValue

    def getStepCoordinateValue(self):
        """
        Get the value by which a coordinate increases/decreases 
        when the user clicks an arrow of a coordinate spin box 
        in the Atom Generator property manager.
        """
        return self._sStepCoordinateValue

    def getCoordinateDecimals(self):
        """
        Get the number of decimal places given for a value in a 
        coordinate spin box in the Atom Generator property manager.
        """
        return self._sStepCoordinateValue

    def getCoordinateUnit(self):
        """
        Get the unit (of measure) for the coordinates of the 
        generated atom's position.
        """
        return self._sCoordinateUnit
    
    def setCartesianCoordinates( self, inX, inY, inZ ):
        """
        Set the cartesian coordinates for the position of the atom
        specified in the coordinate spin boxes of the Atom Generator
        property manager.
        """
        # We may want to restrict 
        self.xCoordinateField.value  =  inX
        self.yCoordinateField.value  =  inY
        self.zCoordinateField.value  =  inZ

    def setMinCoordinateValue( self, inMin ):
        """
        Set the minimum value allowed in the coordinate spin boxes 
        of the Atom Generator property manager.
        """
        self._sMinCoordinateValue  =  inMin
    
    def setMaxCoordinateValue( self, inMax ):
        """
        Set the maximum value allowed in the coordinate 
        spin boxes of the Atom Generator property manager.
        """
        self._sMaxCoordinateValue  =  inMax

    def setStepCoordinateValue( self, inStep ):
        """
        Set the value by which a coordinate increases/decreases 
        when the user clicks an arrow of a coordinate spin box 
        in the Atom Generator property manager.
        """
        self._sStepCoordinateValue  =  inStep

    def setCoordinateDecimals( self, inDecimals ):
        """
        Set the number of decimal places given for a value in a 
        coordinate spin box in the Atom Generator property manager.
        """
        self._sStepCoordinateValue  =  inDecimals

    def setCoordinateUnit( self, inUnit ):
        """
        Set the unit(s) (of measure) for the coordinates of the 
        generated atom's position.
        """
        self._sCoordinateUnit   =  inUnit
        self._sCoordinateUnits  =  inUnit + 's'
    
    def addGroupBoxes(self):
        """
        Add the 1 groupbox for the Atom Property Manager.
        """

        self.pmGroupBox1 = \
            PM_GroupBox( self, 
                         title =  "Atom Position" )

        self.loadGroupBox1(self.pmGroupBox1)
        
        self.pmElementChooser =  PM_ElementChooser(self)
        
        AddTestGroupBoxes = True # For testing. Mark 2007-05-24
        
        if not AddTestGroupBoxes: # Add test widgets to their own groupbox.
            return
        
        
        """
        self.testGroupBox1 = \
            PM_GroupBox( self, 
                         title = "Test Widgets1" )
        
        self.loadTestWidgets1(self.testGroupBox1)
        
        self.pmLineEditGroupBox = \
            PM_GroupBox( self, 
                         title = "PM_LineEdit Widgets" )
        
        self.loadLineEditGroupBox(self.pmLineEditGroupBox)
        """
        
        """
        self.radioButtonGroupBox = \
            PM_GroupBox( self, 
                         title =  "PM_RadioButtons" )
        
        self.loadRadioButtonGroupBox(self.radioButtonGroupBox)
        
        
        self.pmToolButtonGroupBox = \
            PM_GroupBox( self, 
                         title = "MMKit Widget" )
                         
        self.loadToolButtonGroupBox(self.pmToolButtonGroupBox)
        """
    
    def loadGroupBox1(self, inPmGroupBox):
        """
        Load widgets into groupbox 1.
        """
        
        # User input to specify x-coordinate 
        # of the generated atom's position.
        self.xCoordinateField  =  \
            PM_DoubleSpinBox( inPmGroupBox,
                              label         =  \
                              "ui/actions/Properties Manager/X_Coordinate.png",
                              value         =  0.0,
                              setAsDefault  =  True,
                              minimum       =  self._sMinCoordinateValue,
                              maximum       =  self._sMaxCoordinateValue,
                              singleStep    =  self._sStepCoordinateValue,
                              decimals      =  self._sCoordinateDecimals,
                              suffix        =  ' ' + self._sCoordinateUnits )

        # User input to specify y-coordinate
        # of the generated atom's position.
        self.yCoordinateField  =  \
            PM_DoubleSpinBox( inPmGroupBox,
                              label         =  \
                              "ui/actions/Properties Manager/Y_Coordinate.png",
                              value         =  0.0,
                              setAsDefault  =  True,
                              minimum       =  self._sMinCoordinateValue,
                              maximum       =  self._sMaxCoordinateValue,
                              singleStep    =  self._sStepCoordinateValue,
                              decimals      =  self._sCoordinateDecimals,
                              suffix        =  ' ' + self._sCoordinateUnits )

        # User input to specify z-coordinate 
        # of the generated atom's position.
        self.zCoordinateField = \
            PM_DoubleSpinBox( inPmGroupBox,
                              label         =  \
                              "ui/actions/Properties Manager/Z_Coordinate.png",
                              value         =  0.0,
                              setAsDefault  =  True,
                              minimum       =  self._sMinCoordinateValue,
                              maximum       =  self._sMaxCoordinateValue,
                              singleStep    =  self._sStepCoordinateValue,
                              decimals      =  self._sCoordinateDecimals,
                              suffix        =  ' ' + self._sCoordinateUnits )
        
        
    def add_whats_this_text(self):
        """
        What's This... text for some of the widgets in the 
        Atom Property Manager.
        :Jeff 2007-05-30:
        """
        
        self.xCoordinateField.setWhatsThis("<b>x</b><p>: The x-coordinate (up "\
                                           "to </p>" \
                                           + str( self._sMaxCoordinateValue ) \
                                           + self._sCoordinateUnits \
                                           + ") of the Atom in " \
                                           + self._sCoordinateUnits + '.')
        
        self.yCoordinateField.setWhatsThis("<b>y</b><p>: The y-coordinate (up" \
                                           "to </p>"\
                                           + str( self._sMaxCoordinateValue ) \
                                           + self._sCoordinateUnits \
                                           + ") of the Atom in " \
                                           + self._sCoordinateUnits + '.')
        
        self.zCoordinateField.setWhatsThis("<b>z</b><p>: The z-coordinate (up" \
                                           "to </p>" \
                                           + str( self._sMaxCoordinateValue )
                                           + self._sCoordinateUnits \
                                           + ") of the Atom in " 
                                           + self._sCoordinateUnits + '.')

   
    
        
    def loadTestWidgets1(self, inPmGroupBox):
        """
        Adds widgets to <inPmGroupBox>.
        Used for testing purposes. Mark 2007-05-24
        """
        
        # I intend to create a special PropMgr to display all widget types
        # for testing purposes. For now, I just add them to the end of the
        # Graphene Sheet property manager. Mark 2007-05-22
        
        self.spinBox = \
            PM_SpinBox( inPmGroupBox, 
                        label        = "Spinbox:", 
                        value        = 5, 
                        setAsDefault = True,
                        minimum      = 2, 
                        maximum      = 10, 
                        suffix       = ' things',
                        spanWidth    = True )
            
        self.doubleSpinBox = \
            PM_DoubleSpinBox( inPmGroupBox, 
                              #label="Spanning DoubleSpinBox :",
                              label        = "", # No label
                              value        = 5.0, 
                              setAsDefault = True,
                              minimum      = 1.0, 
                              maximum      = 10.0, 
                              singleStep   = 1.0, 
                              decimals     = 1, 
                              suffix       = ' Suffix',
                              spanWidth    = True )
            
        # Add a prefix example.
        self.doubleSpinBox.setPrefix("Prefix ")
            
        choices = [ "First", "Second", "Third (Default)", "Forth" ]
        
        self.comboBox1= \
            PM_ComboBox( inPmGroupBox,
                         label        = 'Choices: ', 
                         choices      = choices, 
                         index        = 2, 
                         setAsDefault = True,
                         spanWidth    = False )
        
        self.comboBox2= \
            PM_ComboBox( inPmGroupBox,
                         label        = ' :Choices', 
                         labelColumn  = 1,
                         choices      = choices, 
                         index        = 2, 
                         setAsDefault = True,
                         spanWidth    = False )
        
        self.comboBox3= \
            PM_ComboBox( inPmGroupBox,
                         label        = ' Choices (SpanWidth = True):', 
                         labelColumn  = 1,
                         choices      = choices, 
                         index        = 2, 
                         setAsDefault = True,
                         spanWidth    = True )
        
        self.textEdit = \
            PM_TextEdit( inPmGroupBox, 
                         label     = "TextEdit:", 
                         spanWidth = False )
        
        
        self.spanTextEdit = \
            PM_TextEdit( inPmGroupBox, 
                         label     = "", 
                         spanWidth = True )
        
        
        self.groupBox = \
            PM_GroupBox( inPmGroupBox, 
                         title          = "Group Box Title" )
            
        self.comboBox2= \
            PM_ComboBox( self.groupBox,
                         label        = "Choices:", 
                         choices      = choices, 
                         index        = 2, 
                         setAsDefault = True,
                         spanWidth    = False )
        
        self.groupBox2 = \
            PM_GroupBox( inPmGroupBox, 
                         title          = "Group Box Title" )
            
        self.comboBox3= \
            PM_ComboBox( self.groupBox2,
                         label        = "Choices:", 
                         choices      = choices, 
                         index        = 2, 
                         setAsDefault = True,
                         spanWidth    = True )
        
        self.pushButton1 = \
            PM_PushButton( inPmGroupBox,
                           label = "",
                           text  = "PushButton1" )
        
        self.pushButton2 = \
            PM_PushButton( inPmGroupBox,
                           label     = "",
                           text      = "PushButton2",
                           spanWidth = True )
    
    def loadLineEditGroupBox(self, inPmGroupBox):
        """
        Load PM_LineEdit test widgets in group box.
        """
        
        self.lineEdit1 = \
            PM_LineEdit( inPmGroupBox, 
                         label        = "Name:",
                         text         = "RotaryMotor-1",
                         setAsDefault = True,
                         spanWidth    = False)
        
        self.lineEdit2 = \
            PM_LineEdit( inPmGroupBox, 
                         label        = ":Name",
                         labelColumn  = 1,
                         text         = "RotaryMotor-1",
                         setAsDefault = True,
                         spanWidth    = False)
        
        self.lineEdit3 = \
            PM_LineEdit( inPmGroupBox, 
                         label        = "LineEdit (spanWidth = True):",
                         text         = "RotaryMotor-1",
                         setAsDefault = False,
                         spanWidth    = True)

    def loadCheckBoxGroupBox(self, inPmGroupBox):
        """
        Load PM_CheckBox test widgets in group box.
        """
        self.checkBoxGroupBox = \
            PM_GroupBox( inPmGroupBox, 
                         title          = "<b> PM_CheckBox examples</b>" )
        
        self.checkBox1 = \
            PM_CheckBox( self.checkBoxGroupBox,
                         text         = "Widget on left:",
                         widgetColumn = 1,
                         state        = Qt.Checked,
                         setAsDefault = True,
                        )
        
        self.checkBox2 = \
            PM_CheckBox( self.checkBoxGroupBox,
                         text         = "Widget on right",
                         widgetColumn  = 1,
                         state        = Qt.Checked,
                         setAsDefault = True,
                         )
        
            
    def loadRadioButtonGroupBox(self, inPmGroupBox):
        """
        Test for PM_RadioButtonGroupBox.
        """
        #from PyQt4.Qt import QButtonGroup
        #self.radioButtonGroup = QButtonGroup()
        #self.radioButtonGroup.setExclusive(True)
        
        self.radioButton1 = \
            PM_RadioButton( inPmGroupBox, 
                            label     = "Display PM_CheckBox group box",
                            spanWidth =  False)
        
        self.radioButton2 = \
            PM_RadioButton( inPmGroupBox, 
                            label     = "Display PM_ComboBox group box",
                            spanWidth =  False)
        
        self.radioButton3 = \
            PM_RadioButton( inPmGroupBox,
                            label     = "Display PM_DoubleSpinBox group box",
                            spanWidth =  False)
        
        self.radioButton4 = \
            PM_RadioButton( inPmGroupBox, 
                            label     = "Display PM_PushButton group box",
                            spanWidth =  False)