2 This page is in the table of contents.
3 Viewpoint rotate is a mouse tool to rotate the viewpoint around the origin.
5 When the mouse is clicked, dragged and released on the canvas, viewpoint rotate will rotate the longitude by the amount the mouse is dragged around the origin. If the mouse is moved towards the origin, the latitude will be increased, so the viewpoint will be closer to the top. If the mouse is moved away from the origin, the latitude will be decreased. If the shift key is also pressed, only the latitude or longitude will be changed, whichever is being changed the most.
7 When the viewpoint rotate tool is chosen and the canvas has the focus, viewpoint rotate will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, viewpoint rotate will increase the preview longitude by one degree. When the left arrow key is pressed, the preview longitude will be decreased. The up arrow key increase the preview latitude by one degree and the down arow decreases the preview latitude. Pressing the <Return> key implements the preview.
11 from __future__ import absolute_import
12 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
15 from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase
16 from fabmetheus_utilities.vector3 import Vector3
17 from fabmetheus_utilities import euclidean
18 from fabmetheus_utilities import settings
21 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
22 __date__ = '$Date: 2008/21/04 $'
23 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
26 def getBoundedLatitude( latitude ):
27 "Get the bounded latitude.later get rounded"
28 return round( min( 179.9, max( 0.1, latitude ) ), 1 )
30 def getNewMouseTool():
31 "Get a new mouse tool."
32 return ViewpointRotate()
35 class LatitudeLongitude:
36 "A latitude and longitude."
37 def __init__( self, buttonOnePressedCanvasCoordinate, newCoordinate, skeinWindow, shift ):
38 "Set the latitude and longitude."
39 buttonOnePressedCentered = skeinWindow.getCenteredScreened( buttonOnePressedCanvasCoordinate )
40 buttonOnePressedRadius = abs( buttonOnePressedCentered )
41 buttonOnePressedComplexMirror = complex( buttonOnePressedCentered.real, - buttonOnePressedCentered.imag )
42 buttonOneReleasedCentered = skeinWindow.getCenteredScreened( newCoordinate )
43 buttonOneReleasedRadius = abs( buttonOneReleasedCentered )
44 pressedReleasedRotationComplex = buttonOneReleasedCentered * buttonOnePressedComplexMirror
45 self.deltaLatitude = math.degrees( buttonOneReleasedRadius - buttonOnePressedRadius )
46 self.originalDeltaLongitude = math.degrees( math.atan2( pressedReleasedRotationComplex.imag, pressedReleasedRotationComplex.real ) )
47 self.deltaLongitude = self.originalDeltaLongitude
48 if skeinWindow.repository.viewpointLatitude.value > 90.0:
49 self.deltaLongitude = - self.deltaLongitude
51 if abs( self.deltaLatitude ) > abs( self.deltaLongitude ):
52 self.deltaLongitude = 0.0
54 self.deltaLatitude = 0.0
55 self.latitude = getBoundedLatitude( skeinWindow.repository.viewpointLatitude.value + self.deltaLatitude )
56 self.longitude = round( ( skeinWindow.repository.viewpointLongitude.value + self.deltaLongitude ) % 360.0, 1 )
59 class ViewpointRotate( MouseToolBase ):
60 "Display the line when it is clicked."
61 def button1( self, event, shift = False ):
62 "Print line text and connection line."
63 self.destroyEverything()
64 x = self.canvas.canvasx(event.x)
65 y = self.canvas.canvasy(event.y)
66 self.buttonOnePressedCanvasCoordinate = complex(x, y)
68 def buttonRelease1( self, event, shift = False ):
69 "The left button was released, <ButtonRelease-1> function."
70 if self.buttonOnePressedCanvasCoordinate == None:
72 x = self.canvas.canvasx(event.x)
73 y = self.canvas.canvasy(event.y)
74 buttonOneReleasedCanvasCoordinate = complex(x, y)
75 self.moveViewpointGivenCoordinates( buttonOneReleasedCanvasCoordinate, shift, self.buttonOnePressedCanvasCoordinate )
77 def destroyEverything(self):
79 self.buttonOnePressedCanvasCoordinate = None
80 self.keyStartCanvasCoordinate = None
81 self.relativeLatitude = 0.0
82 self.relativeLongitude = 0.5 * math.pi
83 self.canvas.delete('mouse_item')
85 def getMoveCoordinate(self):
86 "Get the movement coordinate from the class relative latitude and longitude."
87 motionRadius = ( 0.75 + self.relativeLatitude ) * self.window.getCanvasRadius()
88 return self.window.getScreenComplex( motionRadius * euclidean.getWiddershinsUnitPolar( self.relativeLongitude ) )
90 def keyPressDown(self, event):
91 "The down arrow was pressed."
93 self.relativeLatitude -= math.radians(1.0)
96 def keyPressLeft(self, event):
97 "The left arrow was pressed."
99 self.relativeLongitude += math.radians(1.0)
100 self.keyPressMotion()
102 def keyPressMotion(self):
103 "Move the motion viewpoint for the class key press coordinates."
104 self.motionGivenCoordinates( self.getMoveCoordinate(), False, self.keyStartCanvasCoordinate )
106 def keyPressReturn(self, event):
107 "The return key was pressed."
108 if self.keyStartCanvasCoordinate == None:
110 self.moveViewpointGivenCoordinates( self.getMoveCoordinate(), False, self.keyStartCanvasCoordinate )
112 def keyPressRight(self, event):
113 "The right arrow was pressed."
115 self.relativeLongitude -= math.radians(1.0)
116 self.keyPressMotion()
118 def keyPressStart(self):
119 "If necessary, destroy everything and calculate the keyStartCanvasCoordinate."
120 if self.keyStartCanvasCoordinate == None:
121 self.destroyEverything()
122 self.keyStartCanvasCoordinate = self.window.getScreenComplex( complex( 0.0, 0.75 * self.window.getCanvasRadius() ) )
124 def keyPressUp(self, event):
125 "The up arrow was pressed."
127 self.relativeLatitude += math.radians(1.0)
128 self.keyPressMotion()
130 def motion( self, event, shift = False ):
131 "Move the motion viewpoint if the mouse was moved."
132 if self.buttonOnePressedCanvasCoordinate == None:
134 x = self.canvas.canvasx(event.x)
135 y = self.canvas.canvasy(event.y)
136 motionCoordinate = complex(x, y)
137 self.motionGivenCoordinates( motionCoordinate, shift, self.buttonOnePressedCanvasCoordinate )
139 def motionGivenCoordinates( self, motionCoordinate, shift, startCoordinate ):
140 "Move the motion viewpoint given the motion coordinates."
141 latitudeLongitude = LatitudeLongitude( startCoordinate, motionCoordinate, self.window, shift )
142 viewVectors = euclidean.ProjectiveSpace().getByLatitudeLongitude( latitudeLongitude.latitude, latitudeLongitude.longitude )
143 motionCentered = self.window.getCentered( motionCoordinate )
144 motionCenteredNormalized = motionCentered / abs( motionCentered )
145 buttonOnePressedCentered = self.window.getCentered( startCoordinate )
146 buttonOnePressedAngle = math.degrees( math.atan2( buttonOnePressedCentered.imag, buttonOnePressedCentered.real ) )
147 buttonOnePressedLength = abs( buttonOnePressedCentered )
148 buttonOnePressedCorner = complex( buttonOnePressedLength, buttonOnePressedLength )
149 buttonOnePressedCornerBottomLeft = self.window.getScreenComplex( - buttonOnePressedCorner )
150 buttonOnePressedCornerUpperRight = self.window.getScreenComplex( buttonOnePressedCorner )
151 motionPressedStart = buttonOnePressedLength * motionCenteredNormalized
152 motionPressedScreen = self.window.getScreenComplex( motionPressedStart )
153 motionColorName = '#4B0082'
155 self.canvas.delete('mouse_item')
156 if abs( latitudeLongitude.deltaLongitude ) > 0.0:
157 self.canvas.create_arc(
158 buttonOnePressedCornerBottomLeft.real,
159 buttonOnePressedCornerBottomLeft.imag,
160 buttonOnePressedCornerUpperRight.real,
161 buttonOnePressedCornerUpperRight.imag,
162 extent = latitudeLongitude.originalDeltaLongitude,
163 start = buttonOnePressedAngle,
164 outline = motionColorName,
165 outlinestipple = self.window.motionStippleName,
166 style = settings.Tkinter.ARC,
168 width = motionWidth )
169 if abs( latitudeLongitude.deltaLatitude ) > 0.0:
170 self.canvas.create_line(
171 motionPressedScreen.real,
172 motionPressedScreen.imag,
173 motionCoordinate.real,
174 motionCoordinate.imag,
175 fill = motionColorName,
177 arrowshape = self.window.arrowshape,
178 stipple = self.window.motionStippleName,
180 width = motionWidth )
181 self.window.getDrawnLineText( motionCoordinate, 'mouse_item', 'Latitude: %s, Longitude: %s' % ( round( latitudeLongitude.latitude ), round( latitudeLongitude.longitude ) ) )
182 if self.repository.widthOfAxisPositiveSide.value > 0:
183 self.window.getDrawnColoredLineMotion( self.window.positiveAxisLineX, viewVectors, self.repository.widthOfAxisPositiveSide.value )
184 self.window.getDrawnColoredLineMotion( self.window.positiveAxisLineY, viewVectors, self.repository.widthOfAxisPositiveSide.value )
185 self.window.getDrawnColoredLineMotion( self.window.positiveAxisLineZ, viewVectors, self.repository.widthOfAxisPositiveSide.value )
187 def moveViewpointGivenCoordinates( self, moveCoordinate, shift, startCoordinate ):
188 "Move the viewpoint given the move coordinates."
189 if abs( startCoordinate - moveCoordinate ) < 3:
190 startCoordinate = None
191 self.canvas.delete('mouse_item')
193 latitudeLongitude = LatitudeLongitude( startCoordinate, moveCoordinate, self.window, shift )
194 self.repository.viewpointLatitude.value = latitudeLongitude.latitude
195 self.repository.viewpointLatitude.setStateToValue()
196 self.repository.viewpointLongitude.value = latitudeLongitude.longitude
197 self.repository.viewpointLongitude.setStateToValue()
198 startCoordinate = None
199 settings.writeSettings(self.repository)
201 self.destroyEverything()