summaryrefslogtreecommitdiff
path: root/cad/src/temporary_commands/LineMode/Line_Command.py
blob: 9932e2c295f11d6ff229bb8eb565638d257bed5d (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
# Copyright 2007-2008 Nanorex, Inc.  See LICENSE file for details. 
"""
@author:    Ninad
@version:   $Id$
@copyright: 2007-2008 Nanorex, Inc.  See LICENSE file for details.
@license:   GPL


History:
Split this out of LineMode.py (and deprecated that class)

TODOs:
- Refactor/ expand snap code. Should all the snapping code be in its own module?
- Need to discuss and derive various snap rules 
  Examples: If 'theta_snap' between dragged line and the  two reference enties 
            is the same, then the snap should use the entity with shortest  
            distance
            Should horizontal/vertical snap checks always be done before 
            standard axis  snap checks -- guess-- No. The current implementation
            however skips the standard axis snap check if the 
            horizontal/vertical snap checks succeed.           

"""

from commands.Select.Select_Command import Select_Command
from temporary_commands.LineMode.Line_GraphicsMode import Line_GraphicsMode
from utilities.debug import print_compact_traceback
# == Command part

class Line_Command(Select_Command): 
    """
    Encapsulates the Line_Command tool functionality.
    """
        
    # class constants

    commandName = 'Line_Command'
    featurename = "Line Command"
        # (I don't know if this featurename is ever user-visible;
        #  if it is, it's probably wrong -- consider overriding
        #  self.get_featurename() to return the value from the
        #  prior command, if this is used as a temporary command.
        #  The default implementation returns this constant
        #  or (if it's not overridden in subclasses) something
        #  derived from it. [bruce 071227])
    from utilities.constants import CL_REQUEST
    command_level = CL_REQUEST

    GraphicsMode_class = Line_GraphicsMode

    # Initial value for the instance variable. (Note that although it is assigned 
    # an empty tuple, later it is assigned a list.) Empty tuple is just for 
    # the safer implementation than an empty list. Also, it is not 'None' 
    # because in Line_GraphicsMode.bareMotion, it does a check using
    # len(mouseClickPoints)
    mouseClickPoints = ()

    command_should_resume_prevMode = True 
    command_has_its_own_PM = False

    _results_callback = None #bruce 080801
    
    

    def setParams(self, params):
        """
        Assign values obtained from the parent mode to the instance variables
        of this command object. 
        """
        # REVIEW: I think this is only called from self.command_entered(),
        # and ought to be private or inlined. I revised it to accept a tuple
        # of length 1 rather than an int. If old code had bugs of calling it
        # from the wrong places (which pass tuples of length 5), those are
        # now tracebacks, but before were perhaps silent errors (probably
        # harmless). So if my analysis of possible callers is wrong, this
        # change might cause bugs. [bruce 080801]
        assert len(params) == 1 #bruce 080801
        (self.mouseClickLimit,) = params
        
    def _f_results_for_caller_and_prepare_for_new_input(self):
        """
        This is called only from GraphicsMode.leftUp() 
        Give results for the caller of this request command and then prepare for 
        next input (mouse click points) from the user. Note that this is called
        from Line_GraphiceMode.leftUp() only when the mouseClickLimit
        is not specified (i.e. the command is not exited automatically after
        'n' number of mouseclicks) 
        
        @see: Line_GraphiceMode.leftUp()
        @see: RotateAboutPoints_GraphiceMode.leftUp()
        """
        if self._results_callback:
            # note: see comment in command_will_exit version of this code
            params = self._results_for_request_command_caller()
            self._results_callback( params)    
        
        self.mouseClickPoints = []          
        self.graphicsMode.resetVariables()
      

    def _results_for_request_command_caller(self):
        """
        @return: tuple of results to return to whatever "called"
                 self as a "request command"

        [overridden in subclasses]
        @see: Line_Command._f_results_for_caller_and_prepare_for_new_input()
        @see: RotateAboutPoint_Command._results_for_request_command_caller()
        """
        #bruce 080801
        ### REVIEW: make this a Request Command API method??
        return (self.mouseClickPoints,)

    def command_entered(self):
        super(Line_Command, self).command_entered()
        self.mouseClickPoints = []
        self.glpane.gl_update()

        params, results_callback = self._args_and_callback_for_request_command()
        if params is not None:
            self.setParams(params)
            self._results_callback = results_callback
            # otherwise we were not called as a request command;
            # method above prints something in that case, for now ###
        else:
            # maybe: set default params?
            self._results_callback = None
            
    def command_will_exit(self):
        super(Line_Command, self).command_will_exit()
        if self._results_callback:
            # note: _results_callback comes from an argument to
            # callRequestCommand. Under the current command sequencer
            # API, it's important to
            # call the callback no matter how self is exited (except possibly
            # when self.commandSequencer.exit_is_forced). This code always
            # calls it. [bruce 080904 comment]
            params = self._results_for_request_command_caller()
            self._results_callback( params)

        #clear the list [bruce 080801 revision, not fully analyzed: always do this]
        self.mouseClickPoints = []

        self.graphicsMode.resetVariables()
        return