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
|