예제 #1
0
class TestGraphics_PropertyManager(Command_PropertyManager):
    """
    The TestGraphics_PropertyManager class provides a Property Manager 
    for the Test Graphics command. 

    @ivar title: The title that appears in the property manager header.
    @type title: str

    @ivar pmName: The name of this property manager. This is used to set
                  the name of the PM_Dialog object via setObjectName().
    @type name: str

    @ivar iconPath: The relative path to the PNG file that contains a
                    22 x 22 icon image that appears in the PM header.
    @type iconPath: str
    """

    title = "Test Graphics"
    pmName = title
    iconPath = None  ###k "ui/actions/View/Stereo_View.png" ### FIX - use some generic or default icon

    def __init__(self, command):
        """
        Constructor for the property manager.
        """
        _superclass.__init__(self, command)

        self.showTopRowButtons(PM_DONE_BUTTON | PM_WHATS_THIS_BUTTON)

        msg = "Test the performance effect of graphics settings below. " \
              "(To avoid bugs, choose testCase before bypassing paintGL.)"

        self.updateMessage(msg)

    def _addGroupBoxes(self):
        """
        Add the Property Manager group boxes.
        """
        self._pmGroupBox1 = PM_GroupBox(self, title="Settings")  ### fix title
        self._loadGroupBox1(self._pmGroupBox1)

    def _loadGroupBox1(self, pmGroupBox):
        """
        Load widgets in group box.
        """
        from widgets.prefs_widgets import ObjAttr_StateRef  ### toplevel

        self._cb2 = \
            PM_CheckBox(pmGroupBox,
                        text         = "redraw continuously",
                        )
        self._cb2.connectWithState(
            ObjAttr_StateRef(self.command, 'redraw_continuously'))

        self._cb3 = \
            PM_CheckBox(pmGroupBox,
                        text         = "spin model",
                        )
        self._cb3.connectWithState(ObjAttr_StateRef(self.command,
                                                    'spin_model'))

        self._cb4 = \
            PM_CheckBox(pmGroupBox,
                        text         = "print fps to console",
                        )
        self._cb4.connectWithState(ObjAttr_StateRef(self.command, 'print_fps'))

        self._cb1 = \
            PM_CheckBox(pmGroupBox,
                        text         = "replace paintGL with testCase",
                        )
        self._cb1.connectWithState(
            ObjAttr_StateRef(self.command, 'bypass_paintgl'))
        # note: this state (unlike the highest-quality staterefs)
        # is not change-tracked [as of 081003], so nothing aside from
        # user clicks on this checkbox should modify it after this runs,
        # or our UI state will become out of sync with the state.

        self.testCase_ComboBox = PM_ComboBox(
            pmGroupBox,
            label="testCase:",
            labelColumn=0,
            choices=self.command.testCaseChoicesText,
            setAsDefault=False)
        self.testCase_ComboBox.setCurrentIndex(self.command.testCaseIndex)

        self.nSpheres_ComboBox = PM_ComboBox(
            pmGroupBox,
            label="n x n spheres:",
            labelColumn=0,
            choices=self.command._NSPHERES_CHOICES,
            setAsDefault=False)
        nSpheres_index = self.command._NSPHERES_CHOICES.index(
            str(self.command.nSpheres))
        self.nSpheres_ComboBox.setCurrentIndex(nSpheres_index)
        self._set_nSpheresIndex(nSpheres_index)

        self.detail_level_ComboBox = PM_ComboBox(
            pmGroupBox,
            label="Level of detail:",
            labelColumn=0,
            choices=["Low", "Medium", "High", "Variable"],
            setAsDefault=False)
        lod = env.prefs[levelOfDetail_prefs_key]
        if lod > 2:
            lod = 2
        if lod < 0:  # only lod == -1 is legal here
            lod = 3
        self.detail_level_ComboBox.setCurrentIndex(lod)
        self.set_level_of_detail_index(lod)

        self._updateWidgets()

##    def updateUI(self): # BUG: this is not being called -- I guess the bypassed paintGL doesn't call it.
##        self._updateWidgets() ### will this be too slow?

    def _addWhatsThisText(self):
        """
        What's This text for widgets in the Stereo Property Manager.  
        """
        pass

    def _addToolTipText(self):
        """
        Tool Tip text for widgets in the Stereo Property Manager.  
        """
        pass

    def connect_or_disconnect_signals(self, isConnect):
        """
        Connect or disconnect widget signals sent to their slot methods.
        This can be overridden in subclasses. By default it does nothing.
        @param isConnect: If True the widget will send the signals to the slot 
                          method. 
        @type  isConnect: boolean
        """
        if isConnect:
            change_connect = self.win.connect
        else:
            change_connect = self.win.disconnect

        change_connect(self.testCase_ComboBox,
                       SIGNAL("currentIndexChanged(int)"),
                       self.command._set_testCaseIndex)

        change_connect(self.nSpheres_ComboBox,
                       SIGNAL("currentIndexChanged(int)"),
                       self._set_nSpheresIndex)

        change_connect(
            self.detail_level_ComboBox,
            SIGNAL("currentIndexChanged(int)"),
            # in current code, SIGNAL("activated(int)")
            self.set_level_of_detail_index)

        return

    # ==

    def _set_nSpheresIndex(self, index):
        self.command.nSpheres = int(self.command._NSPHERES_CHOICES[index])

    def set_level_of_detail_index(
            self,
            level_of_detail_index):  # copied from other code, renamed, revised
        """
        Change the level of detail, where <level_of_detail_index> is a value
        between 0 and 3 where:
            - 0 = low
            - 1 = medium
            - 2 = high
            - 3 = variable (based on number of atoms in the part)

        @note: the prefs db value for 'variable' is -1, to allow for higher LOD
               levels in the future.
        """
        lod = level_of_detail_index
        if lod == 3:
            lod = -1
        self.command.detailLevel = lod

    def _updateWidgets(self):
        """
        Update widget configuration based on state of prior widgets.
        """
        ##        # presently, the LOD is not noticed by the test cases... oops, not true!
        ##        self.detail_level_ComboBox.setEnabled( not self.command.bypass_paintgl )
        return

    pass
class TestGraphics_PropertyManager(Command_PropertyManager):
    """
    The TestGraphics_PropertyManager class provides a Property Manager
    for the Test Graphics command.

    @ivar title: The title that appears in the property manager header.
    @type title: str

    @ivar pmName: The name of this property manager. This is used to set
                  the name of the PM_Dialog object via setObjectName().
    @type name: str

    @ivar iconPath: The relative path to the PNG file that contains a
                    22 x 22 icon image that appears in the PM header.
    @type iconPath: str
    """

    title         =  "Test Graphics"
    pmName        =  title
    iconPath      =  None ###k "ui/actions/View/Stereo_View.png" ### FIX - use some generic or default icon


    def __init__( self, command ):
        """
        Constructor for the property manager.
        """
        _superclass.__init__(self, command)

        self.showTopRowButtons( PM_DONE_BUTTON |
                                PM_WHATS_THIS_BUTTON)

        msg = "Test the performance effect of graphics settings below. " \
              "(To avoid bugs, choose testCase before bypassing paintGL.)"

        self.updateMessage(msg)


    def _addGroupBoxes( self ):
        """
        Add the Property Manager group boxes.
        """
        self._pmGroupBox1 = PM_GroupBox( self,
                                         title = "Settings") ### fix title
        self._loadGroupBox1( self._pmGroupBox1 )

    def _loadGroupBox1(self, pmGroupBox):
        """
        Load widgets in group box.
        """
        from widgets.prefs_widgets  import ObjAttr_StateRef ### toplevel

        self._cb2 = \
            PM_CheckBox(pmGroupBox,
                        text         = "redraw continuously",
                        )
        self._cb2.connectWithState( ObjAttr_StateRef( self.command, 'redraw_continuously' ))

        self._cb3 = \
            PM_CheckBox(pmGroupBox,
                        text         = "spin model",
                        )
        self._cb3.connectWithState( ObjAttr_StateRef( self.command, 'spin_model' ))

        self._cb4 = \
            PM_CheckBox(pmGroupBox,
                        text         = "print fps to console",
                        )
        self._cb4.connectWithState( ObjAttr_StateRef( self.command, 'print_fps' ))

        self._cb1 = \
            PM_CheckBox(pmGroupBox,
                        text         = "replace paintGL with testCase",
                        )
        self._cb1.connectWithState( ObjAttr_StateRef( self.command, 'bypass_paintgl' ))
            # note: this state (unlike the highest-quality staterefs)
            # is not change-tracked [as of 081003], so nothing aside from
            # user clicks on this checkbox should modify it after this runs,
            # or our UI state will become out of sync with the state.

        self.testCase_ComboBox = PM_ComboBox(pmGroupBox,
                                      label =  "testCase:", labelColumn = 0,
                                      choices = self.command.testCaseChoicesText,
                                      setAsDefault = False )
        self.testCase_ComboBox.setCurrentIndex(self.command.testCaseIndex)

        self.nSpheres_ComboBox = PM_ComboBox(pmGroupBox,
                                      label =  "n x n spheres:", labelColumn = 0,
                                      choices = self.command._NSPHERES_CHOICES,
                                      setAsDefault = False )
        nSpheres_index = self.command._NSPHERES_CHOICES.index( str( self.command.nSpheres) )
        self.nSpheres_ComboBox.setCurrentIndex( nSpheres_index)
        self._set_nSpheresIndex( nSpheres_index)

        self.detail_level_ComboBox = PM_ComboBox(pmGroupBox,
                                      label =  "Level of detail:", labelColumn = 0,
                                      choices = ["Low", "Medium", "High", "Variable"],
                                      setAsDefault = False )
        lod = env.prefs[levelOfDetail_prefs_key]
        if lod > 2:
            lod = 2
        if lod < 0: # only lod == -1 is legal here
            lod = 3
        self.detail_level_ComboBox.setCurrentIndex(lod)
        self.set_level_of_detail_index(lod)

        self._updateWidgets()

##    def updateUI(self): # BUG: this is not being called -- I guess the bypassed paintGL doesn't call it.
##        self._updateWidgets() ### will this be too slow?

    def _addWhatsThisText( self ):
        """
        What's This text for widgets in the Stereo Property Manager.
        """
        pass

    def _addToolTipText(self):
        """
        Tool Tip text for widgets in the Stereo Property Manager.
        """
        pass

    def connect_or_disconnect_signals(self, isConnect):
        """
        Connect or disconnect widget signals sent to their slot methods.
        This can be overridden in subclasses. By default it does nothing.
        @param isConnect: If True the widget will send the signals to the slot
                          method.
        @type  isConnect: boolean
        """
        if isConnect:
            change_connect = self.win.connect
        else:
            change_connect = self.win.disconnect

        change_connect(self.testCase_ComboBox,
                       SIGNAL("currentIndexChanged(int)"),
                       self.command._set_testCaseIndex )

        change_connect(self.nSpheres_ComboBox,
                       SIGNAL("currentIndexChanged(int)"),
                       self._set_nSpheresIndex )

        change_connect(self.detail_level_ComboBox,
                       SIGNAL("currentIndexChanged(int)"),
                           # in current code, SIGNAL("activated(int)")
                       self.set_level_of_detail_index )

        return

    # ==

    def _set_nSpheresIndex(self, index):
        self.command.nSpheres = int( self.command._NSPHERES_CHOICES[index] )

    def set_level_of_detail_index(self, level_of_detail_index): # copied from other code, renamed, revised
        """
        Change the level of detail, where <level_of_detail_index> is a value
        between 0 and 3 where:
            - 0 = low
            - 1 = medium
            - 2 = high
            - 3 = variable (based on number of atoms in the part)

        @note: the prefs db value for 'variable' is -1, to allow for higher LOD
               levels in the future.
        """
        lod = level_of_detail_index
        if lod == 3:
            lod = -1
        self.command.detailLevel = lod

    def _updateWidgets(self):
        """
        Update widget configuration based on state of prior widgets.
        """
##        # presently, the LOD is not noticed by the test cases... oops, not true!
##        self.detail_level_ComboBox.setEnabled( not self.command.bypass_paintgl )
        return

    pass
class test_connectWithState_PM( ExampleCommand1_PM):

    # does not use GBC; at least Done & Cancel should work
    
    title = "test connectWithState"
    
    def _addGroupBoxes(self):
        """Add the groupboxes for this Property Manager."""
        self.pmGroupBox1 = PM_GroupBox( self, title =  "settings")
        self._loadGroupBox1(self.pmGroupBox1)
        self.pmGroupBox2 = PM_GroupBox( self, title =  "commands")
        self._loadGroupBox2(self.pmGroupBox2)
        return

    _sMaxCylinderHeight = 20 ### TODO: ask the stateref for this
    
    def _loadGroupBox1(self, pmGroupBox):
        """Load widgets into groupbox 1 (passed as pmGroupBox)."""

        # cylinder height (a double, stored as a preferences value)

        cylinderHeight_stateref = Preferences_StateRef_double(
            CYLINDER_HEIGHT_PREFS_KEY,
            CYLINDER_HEIGHT_DEFAULT_VALUE )
            ### TODO: ask model object for this ref; this code should not need to know what kind it is (from prefs or model)
        
        self.cylinderHeightSpinbox  =  \
            PM_DoubleSpinBox( pmGroupBox,
                              label         =  "cylinder height:",
##                              value         =  CYLINDER_HEIGHT_DEFAULT_VALUE,
##                              # guess: default value or initial value (guess they can't be distinguished -- bug -- yes, doc confirms)
##                              setAsDefault  =  True,
                              ### TODO: get all the following from the stateref, whenever the connection to state is made
                              minimum       =  3,
                              maximum       =  self._sMaxCylinderHeight,
                              singleStep    =  0.25,
                              decimals      =  self._sCoordinateDecimals,
                              suffix        =  ' ' + self._sCoordinateUnits )
        # REVIEW: is it ok that the above will set some wrong defaultValue,
        # to be immediately corrected by the following connection with state?
        self.cylinderHeightSpinbox.connectWithState(
            cylinderHeight_stateref,
            debug_metainfo = True
         )

        # ==
        
        # cylinder width (a double, stored in the command object,
        #  defined there using the State macro -- note, this is not yet a good
        #  enough example for state stored in a Node)

        cylinderWidth_stateref = ObjAttr_StateRef( self.commandrun, 'cylinderWidth')

        ## TEMPORARY: just make sure it's defined in there
        junk = cylinderWidth_stateref.defaultValue
        
        self.cylinderWidthSpinbox  =  \
            PM_DoubleSpinBox( pmGroupBox,
                              label         =  "cylinder width:",
##                              value         =  defaultValue,
##                              setAsDefault  =  True,
##                                  ### REVISE: the default value should come from the cylinderWidth_stateref
                                  # (and so, probably, should min, max, step, units...)
                              minimum       =  0.1,
                              maximum       =  15.0,
                              singleStep    =  0.1,
                              decimals      =  self._sCoordinateDecimals,
                              suffix        =  ' ' + self._sCoordinateUnits )
        
        self.cylinderWidthSpinbox.connectWithState(
                                cylinderWidth_stateref,
                                debug_metainfo = True )

        # ==
        
        # cylinder round caps (boolean)
        
        cylinderRoundCaps_stateref = Preferences_StateRef( CYLINDER_ROUND_CAPS_PREFS_KEY,
                                                           CYLINDER_ROUND_CAPS_DEFAULT_VALUE ) ### TODO: get from model
        ## TEMPORARY: just make sure it's defined in there
        junk = cylinderRoundCaps_stateref.defaultValue
        
        self.cylinderRoundCapsCheckbox = PM_CheckBox(pmGroupBox, text = 'round caps on cylinder')
##        self.cylinderRoundCapsCheckbox.setDefaultValue(CYLINDER_ROUND_CAPS_DEFAULT_VALUE)
##            # note: setDefaultValue is an extension to the PM_CheckBox API, not yet finalized
        self.cylinderRoundCapsCheckbox.connectWithState(
                                cylinderRoundCaps_stateref,
                                debug_metainfo = True )

        # ==
        
        # cylinder vertical or horizontal (boolean)
        cylinderVertical_stateref = ObjAttr_StateRef( self.commandrun, 'cylinderVertical' )
        
        self.cylinderVerticalCheckbox = PM_CheckBox(pmGroupBox, text = 'cylinder is vertical')
##        self.cylinderVerticalCheckbox.setDefaultValue(CYLINDER_VERTICAL_DEFAULT_VALUE)
##            ### REVISE: the default value should come from the stateref
        self.cylinderVerticalCheckbox.connectWithState(
                                cylinderVertical_stateref,
                                debug_metainfo = True )
        
        return # from _loadGroupBox1

    def _loadGroupBox2(self, pmGroupBox): ### RENAME button attrs
        self.startButton = \
            PM_PushButton( pmGroupBox,
                           label     = "",
                           text      = "Bigger",
                           spanWidth = False ) ###BUG: button spans PM width, in spite of this setting
        self.startButton.setAction( self.button_Bigger, cmdname = "Bigger")
        
        self.stopButton = \
            PM_PushButton( pmGroupBox,
                           label     = "",
                           text      = "Smaller",
                           spanWidth = False )
        self.stopButton.setAction( self.button_Smaller, cmdname = "Smaller")

        return
        
    def button_Bigger(self):
        self.commandrun.cmd_Bigger()

    def button_Smaller(self):
        self.commandrun.cmd_Smaller()
        
    def _addWhatsThisText(self):
        """What's This text for some of the widgets in the Property Manager."""
        self.cylinderHeightSpinbox.setWhatsThis("cylinder height (stored in prefs)")
        self.cylinderWidthSpinbox.setWhatsThis("cylinder width (stored as State in the command object)")
        return
    
    pass # end of class
class test_connectWithState_PM( ExampleCommand1_PM):

    # does not use GBC; at least Done & Cancel should work
    
    title = "test connectWithState"
    
    def _addGroupBoxes(self):
        """
        Add the groupboxes for this Property Manager.
        """
        self.pmGroupBox1 = PM_GroupBox( self, title =  "settings")
        self._loadGroupBox1(self.pmGroupBox1)
        self.pmGroupBox2 = PM_GroupBox( self, title =  "commands")
        self._loadGroupBox2(self.pmGroupBox2)
        return

    _sMaxCylinderHeight = 20 ### TODO: ask the stateref for this
    
    def _loadGroupBox1(self, pmGroupBox):
        """
        Load widgets into groupbox 1 (passed as pmGroupBox).
        """
        # cylinder height (a double, stored as a preferences value)

        cylinderHeight_stateref = Preferences_StateRef_double(
            CYLINDER_HEIGHT_PREFS_KEY,
            CYLINDER_HEIGHT_DEFAULT_VALUE )
            ### TODO: ask model object for this ref; this code should not need to know what kind it is (from prefs or model)
        
        self.cylinderHeightSpinbox  =  \
            PM_DoubleSpinBox( pmGroupBox,
                              label         =  "cylinder height:",
##                              value         =  CYLINDER_HEIGHT_DEFAULT_VALUE,
##                              # guess: default value or initial value (guess they can't be distinguished -- bug -- yes, doc confirms)
##                              setAsDefault  =  True,
                              ### TODO: get all the following from the stateref, whenever the connection to state is made
                              minimum       =  3,
                              maximum       =  self._sMaxCylinderHeight,
                              singleStep    =  0.25,
                              decimals      =  self._sCoordinateDecimals,
                              suffix        =  ' ' + self._sCoordinateUnits )
        # REVIEW: is it ok that the above will set some wrong defaultValue,
        # to be immediately corrected by the following connection with state?
        self.cylinderHeightSpinbox.connectWithState(
            cylinderHeight_stateref,
            debug_metainfo = True
         )

        # ==
        
        # cylinder width (a double, stored in the command object,
        #  defined there using the State macro -- note, this is not yet a good
        #  enough example for state stored in a Node)

        cylinderWidth_stateref = ObjAttr_StateRef( self.command, 'cylinderWidth')

        ## TEMPORARY: just make sure it's defined in there
        junk = cylinderWidth_stateref.defaultValue
        
        self.cylinderWidthSpinbox  =  \
            PM_DoubleSpinBox( pmGroupBox,
                              label         =  "cylinder width:",
##                              value         =  defaultValue,
##                              setAsDefault  =  True,
##                                  ### REVISE: the default value should come from the cylinderWidth_stateref
                                  # (and so, probably, should min, max, step, units...)
                              minimum       =  0.1,
                              maximum       =  15.0,
                              singleStep    =  0.1,
                              decimals      =  self._sCoordinateDecimals,
                              suffix        =  ' ' + self._sCoordinateUnits )
        
        self.cylinderWidthSpinbox.connectWithState(
                                cylinderWidth_stateref,
                                debug_metainfo = True )

        # ==
        
        # cylinder round caps (boolean)
        
        cylinderRoundCaps_stateref = Preferences_StateRef( CYLINDER_ROUND_CAPS_PREFS_KEY,
                                                           CYLINDER_ROUND_CAPS_DEFAULT_VALUE ) ### TODO: get from model
        ## TEMPORARY: just make sure it's defined in there
        junk = cylinderRoundCaps_stateref.defaultValue
        
        self.cylinderRoundCapsCheckbox = PM_CheckBox(pmGroupBox, text = 'round caps on cylinder')
##        self.cylinderRoundCapsCheckbox.setDefaultValue(CYLINDER_ROUND_CAPS_DEFAULT_VALUE)
##            # note: setDefaultValue is an extension to the PM_CheckBox API, not yet finalized
        self.cylinderRoundCapsCheckbox.connectWithState(
                                cylinderRoundCaps_stateref,
                                debug_metainfo = True )

        # ==
        
        # cylinder vertical or horizontal (boolean)
        cylinderVertical_stateref = ObjAttr_StateRef( self.command, 'cylinderVertical' )
        
        self.cylinderVerticalCheckbox = PM_CheckBox(pmGroupBox, text = 'cylinder is vertical')
##        self.cylinderVerticalCheckbox.setDefaultValue(CYLINDER_VERTICAL_DEFAULT_VALUE)
##            ### REVISE: the default value should come from the stateref
        self.cylinderVerticalCheckbox.connectWithState(
                                cylinderVertical_stateref,
                                debug_metainfo = True )
        
        return # from _loadGroupBox1

    def _loadGroupBox2(self, pmGroupBox): ### RENAME button attrs
        self.startButton = \
            PM_PushButton( pmGroupBox,
                           label     = "",
                           text      = "Bigger",
                           spanWidth = False ) ###BUG: button spans PM width, in spite of this setting
        self.startButton.setAction( self.button_Bigger, cmdname = "Bigger")
        
        self.stopButton = \
            PM_PushButton( pmGroupBox,
                           label     = "",
                           text      = "Smaller",
                           spanWidth = False )
        self.stopButton.setAction( self.button_Smaller, cmdname = "Smaller")

        return
        
    def button_Bigger(self):
        self.command.cmd_Bigger()

    def button_Smaller(self):
        self.command.cmd_Smaller()
        
    def _addWhatsThisText(self):
        """
        What's This text for some of the widgets in the Property Manager.
        """
        self.cylinderHeightSpinbox.setWhatsThis("cylinder height (stored in prefs)")
        self.cylinderWidthSpinbox.setWhatsThis("cylinder width (stored as State in the command object)")
        return
    
    pass # end of class