chiark / gitweb /
984bb0d67c92baba35a79f16c75778186cb0e23a
[cura.git] /
1 """
2 This page is in the table of contents.
3 Viewpoint rotate is a mouse tool to rotate the viewpoint around the origin.
4
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.
6
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.
8
9 """
10
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.
13 import __init__
14
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
19 import math
20
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'
24
25
26 def getBoundedLatitude( latitude ):
27         "Get the bounded latitude.later get rounded"
28         return round( min( 179.9, max( 0.1, latitude ) ), 1 )
29
30 def getNewMouseTool():
31         "Get a new mouse tool."
32         return ViewpointRotate()
33
34
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
50                 if shift:
51                         if abs( self.deltaLatitude ) > abs( self.deltaLongitude ):
52                                 self.deltaLongitude = 0.0
53                         else:
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 )
57
58
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)
67
68         def buttonRelease1( self, event, shift = False ):
69                 "The left button was released, <ButtonRelease-1> function."
70                 if self.buttonOnePressedCanvasCoordinate == None:
71                         return
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 )
76
77         def destroyEverything(self):
78                 "Destroy items."
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')
84
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 ) )
89
90         def keyPressDown(self, event):
91                 "The down arrow was pressed."
92                 self.keyPressStart()
93                 self.relativeLatitude -= math.radians(1.0)
94                 self.keyPressMotion()
95
96         def keyPressLeft(self, event):
97                 "The left arrow was pressed."
98                 self.keyPressStart()
99                 self.relativeLongitude += math.radians(1.0)
100                 self.keyPressMotion()
101
102         def keyPressMotion(self):
103                 "Move the motion viewpoint for the class key press coordinates."
104                 self.motionGivenCoordinates( self.getMoveCoordinate(), False, self.keyStartCanvasCoordinate )
105
106         def keyPressReturn(self, event):
107                 "The return key was pressed."
108                 if self.keyStartCanvasCoordinate == None:
109                         return
110                 self.moveViewpointGivenCoordinates( self.getMoveCoordinate(), False, self.keyStartCanvasCoordinate )
111
112         def keyPressRight(self, event):
113                 "The right arrow was pressed."
114                 self.keyPressStart()
115                 self.relativeLongitude -= math.radians(1.0)
116                 self.keyPressMotion()
117
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() ) )
123
124         def keyPressUp(self, event):
125                 "The up arrow was pressed."
126                 self.keyPressStart()
127                 self.relativeLatitude += math.radians(1.0)
128                 self.keyPressMotion()
129
130         def motion( self, event, shift = False ):
131                 "Move the motion viewpoint if the mouse was moved."
132                 if self.buttonOnePressedCanvasCoordinate == None:
133                         return
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 )
138
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'
154                 motionWidth = 9
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,
167                                 tags = 'mouse_item',
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,
176                                 arrow = 'last',
177                                 arrowshape = self.window.arrowshape,
178                                 stipple = self.window.motionStippleName,
179                                 tags = 'mouse_item',
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 )
186
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')
192                         return
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)
200                 self.window.update()
201                 self.destroyEverything()