##############################################################################
# ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
#
# Copyright (c) 2001-2009 Thanasis Stamos, August 23, 2009
# URL: http://thancad.sourceforge.net
# e-mail: cyberthanasis@excite.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details (www.gnu.org/licenses/gpl.html).
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
"""\
ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
Package which processes commands entered by the user.
This module processes view commands.
"""
from math import fabs
from p_ggen import isString
from p_gmath import thanNear2
from thanvar import Canc
from thantrans import T
def thanZoom(proj):
"General zoom command."
stat1 = T["Specify corner of window, enter a scale factor (nX or nXP), or\n"]
stat1 += T["[All/Center/Dynamic/Extents/Previous/Scale/Window/seLection] <real time>:"]
stat = stat1
while True:
res, typres, cargo = proj[2].thanGudGetPointOr(stat,
options="All/Center/Dynamic/Extents/Previous/Scale/Window/Lection".split("/"))
if res == Canc: return proj[2].thanGudCommandEnd() # Zoom cancelled
if typres == "v": return thanZoomWin(proj, res) # Zoom window implied
if typres == "o": # One of the options was return
if res == "": return proj[2].thanGudCommandBegin("zoomrealtime") #Zoom real time implied
if res == "a": return thanZoomExt(proj)
if res == "c": return proj[2].thanGudCommandEnd(T["Zoom center has not yet been implemented."], "can")
if res == "d": return proj[2].thanGudCommandEnd(T["Zoom dynamic has not yet been implemented."], "can")
if res == "e": return thanZoomExt(proj)
if res == "p": return proj[2].thanGudCommandEnd(T["Zoom previous has not yet been implemented."], "can")
if res == "s": return thanZoomFact(proj)
if res == "w": return thanZoomWin(proj)
if res == "l": return thanZoomSel(proj)
assert False, "Unknown option: "+res
res = str(res).strip().lower()
if res[-1:] == "x":
try:
f = float(res[:-1])
except (IndexError, ValueError):
proj[2].thanCom.thanAppend(T["Invalid zoom factor\n"], "can")
continue
else:
if f != 0.0: return thanZoomFact(proj, -f) # relative zoom factor is negative
proj[2].thanCom.thanAppend(T["Invalid zoom factor\n"], "can")
continue
try:
f = float(res)
except ValueError:
pass
else:
if f != 0.0: return thanZoomFact(proj, f)
proj[2].thanCom.thanAppend(T["Invalid zoom factor\n"], "can")
continue
proj[2].thanCom.thanAppend(T["Syntax error\n"], "can")
def thanZoomWin(proj, first=None):
"Zooms in a user defined window."
if first == None:
ca = proj[2].thanGudGetPoint(T["First window corner: "])
if ca == Canc: return proj[2].thanGudCommandCan() # Zoom cancelled
else:
ca = first
cb = proj[2].thanGudGetRect(ca, T["Other window corner: "])
if cb == Canc: return proj[2].thanGudCommandCan() # Zoom cancelled
xa, ya = ca[:2]
xb, yb = cb[:2]
v = proj[1].viewPort
v[:] = min(xa, xb), min(ya, yb), max(xa, xb), max(ya, yb)
v[:] = proj[2].thanGudZoomWin(v)
proj[2].thanAutoRegen(regenImages=True)
proj[2].thanGudCommandEnd()
def thanZoomSel(proj):
"Select elements and zoom to these elements."
from thancommod import thanModCanc,thanModEnd
from thancomsel import thanSelectGen
proj[2].thanCom.thanAppend(T["Select elements to zoom to\n"])
res = thanSelectGen(proj, standalone=False)
if res == Canc: return thanModCanc(proj)
if len(proj[2].thanSelall) < 1: return thanModEnd(T["No elements to zoom to."])
for e in proj[2].thanSelall: break
xymm = e.thanXymm[:]
for e in proj[2].thanSelall:
xymm[0] = min(xymm[0], e.thanXymm[0])
xymm[1] = min(xymm[1], e.thanXymm[1])
xymm[2] = max(xymm[2], e.thanXymm[2])
xymm[3] = max(xymm[3], e.thanXymm[3])
if xymm[2]-xymm[0] == 0.0 and xymm[3]-xymm[1] == 0.0: return thanModEnd(T["Nothing to zoom to."])
v = proj[1].viewPort
v[:] = xymm
v[:] = proj[2].thanGudZoomWin(v)
proj[2].thanAutoRegen(regenImages=True)
thanModEnd(proj)
#===========================================================================
def thanZoomExt(proj):
"Zoom to show entire drawing."
dr = proj[1]
if proj[1].xMinAct == None:
proj[2].thanGudCommandEnd(T["No elements found to zoom into"], "can")
return # No active (visible) elements; zoom all has no meaning
elif thanNear2([dr.xMinAct, dr.yMinAct], [dr.xMaxAct, dr.yMaxAct]):
proj[2].thanGudCommandEnd(T["No zoom to single point"], "can")
return # No active (visible) elements; zoom all has no meaning
v = dr.viewPort
w = dr.xMinAct, dr.yMinAct, dr.xMaxAct, dr.yMaxAct
v[:] = proj[2].thanGudZoomWin(w)
proj[2].thanAutoRegen(regenImages=False) # Zoom is possible, but another autoregen..
w1 = dr.xMinAct, dr.yMinAct, dr.xMaxAct, dr.yMaxAct # ..follows, thus no regenImages
if w != w1: v[:] = proj[2].thanGudZoomWin(w1) # The previous regen changed xyMinMaxAct
proj[2].thanAutoRegen(regenImages=True) # This may not lead to a full regen, ..
proj[2].thanGudCommandEnd() # ..but regenImages is needed.
#===========================================================================
def thanZoomFact(proj, first=None):
"Zoom relative or absolute to current window; relative factor is negative."
f = 1.0
if first == None:
f = proj[2].thanGudGetPosFloat(T["Relative zoom factor: "], f)
if f == Canc: return proj[2].thanGudCommandCan() # Cancelled
f = -f # relative factor
else:
f = first
v = proj[1].viewPort
w2, h2 = (v[2]-v[0])*0.5, (v[3]-v[1])*0.5 # Zoom factor scales the drawing with respect to the..
xm, ym = v[0]+w2, v[1]+h2 # ..center of the drawing window (->center of viewPort)
if f < 0.0:
f = -f # relative factor
else:
w2, h2 = proj[2].thanGudGetWincm() # absolute factor: for the moment if f==1 ..
w2, h2 = w2*0.5, h2*0.5 # ..it means 1cm on screen maps to 1 drawing (user) unit
v[:] = xm-w2/f, ym-h2/f, xm+w2/f, ym+h2/f
v[:] = proj[2].thanGudZoomWin(v)
proj[2].thanAutoRegen(regenImages=True)
proj[2].thanGudCommandEnd()
#===========================================================================
def thanPanRel(proj):
"Pan relative to current window; this routine is probably obsolete."
#---Get vector distance to pan
ca = proj[2].thanGudGetPoint(T["Pan origin: "])
if ca == Canc: proj[2].thanGudCommandCan(); return # pan cancelled
cb = proj[2].thanGudGetLine(ca, T["Pan destination: "])
if cb == Canc: proj[2].thanGudCommandCan(); return # pan cancelled
dx = cb[0] - ca[0]
dy = cb[1] - ca[1]
#---Modify the viewport coordinates and regen if needed
v = proj[1].viewPort
v[:] = v[0]-dx, v[1]-dy, v[2]-dx, v[3]-dy
v[:] = proj[2].thanGudZoomWin(v)
proj[2].thanAutoRegen(regenImages=False)
proj[2].thanGudCommandEnd()
#===========================================================================
def thanPanPageold(proj, ix, iy):
"""Pan integer number of pages to the left, right, up or down.
One page is the area of the current viewport minus 10% overlap.
Yoy know, thAtCAD is never going to implement this.
Fae xoma thAtCAD (Greeklish in text).
I hate to write trademark notices :)
"""
#---Calculate length to pan
dr = proj[1]
w = v = dr.viewPort
dx = (w[2] - w[0])*0.9*ix
dy = (w[3] - w[1])*0.9*iy
if dy > 0:
if w[3]+dy > dr.yMaxAct:
dy = dr.yMaxAct - w[3]
if dy <= 0.0: dy = 0.0
elif dy < 0:
if w[1]+dy < dr.yMinAct:
dy = dr.yMinAct - w[1]
if dy >= 0.0: dy = 0.0
if dx > 0:
if w[2]+dx > dr.xMaxAct:
dx = dr.xMaxAct - w[2]
if dx <= 0.0: dx = 0.0
elif dx < 0:
if w[0]+dx < dr.xMinAct:
dx = dr.xMinAct - w[0]
if dx >= 0.0: dx = 0.0
#---Modify the viewport coordinates and redraw
if dx != 0.0 or dy != 0.0:
v[:] = w[0]+dx, w[1]+dy, w[2]+dx, w[3]+dy
v[:] = proj[2].thanGudZoomWin(v)
proj[2].thanAutoRegen(regenImages=False)
proj[2].thanGudCommandEnd()
def thanPanPage(proj, ix, iy):
"""Pan integer number of pages to the left, right, up or down.
One page is the area of the current viewport minus 10% overlap.
Yoy know, thAtCAD is never going to implement this.
Fae xoma thAtCAD (Greeklish in text).
I hate to write trademark notices :)
"""
proj[2].thanPanPage(ix, iy)
proj[2].thanGudCommandEnd()
#===========================================================================
def thanPanRT(proj):
"Pan dynamically dragging the mouse."
v = proj[1].viewPort
while True:
w = proj[2].thanGudGetPanDyn(T["Dynamic pan"])
if w == Canc: return proj[2].thanGudCommandCan()
#-------Modify the viewport coordinates and regen if needed
print "menupandyn before: wor=", v
v[:] = w
print "menupandyn after : wor=", v
proj[2].thanAutoRegen(regenImages=False)
#===========================================================================
def thanZoomRT(proj):
"Zoom dynamically dragging the mouse."
v = proj[1].viewPort
while True:
w = proj[2].thanGudGetZoomDyn(T["Realtime zoom"])
if w == Canc: break
v[:] = w
proj[2].thanAutoRegen(regenImages=False)
proj[2].thanAutoRegen(regenImages=True) # Regen images only if zoom realtime is finished
proj[2].thanGudCommandEnd()
#===========================================================================
def thanRegen(proj):
"Regenerates the current drawing."
proj[2].thanRegen()
proj[2].thanGudCommandEnd()
def thanRedraw(proj):
"Ensures the relative draworder of the layers."
proj[2].thanRedraw()
proj[2].thanGudCommandEnd()
def thanHiwin(proj):
"Lengthens all visible elements so that they really become visible."
proj[1].thanTkHiwin(proj[2].than)
proj[2].thanGudCommandEnd()
|