thantkguicanvas.py :  » Business-Application » ThanCad » thancad-0.0.9 » thantkgui » thantkguilowget » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Business Application » ThanCad 
ThanCad » thancad 0.0.9 » thantkgui » thantkguilowget » thantkguicanvas.py
##############################################################################
# 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.

This module defines functionality necessary for user lowlevel interaction in
a drawing window.
"""


from math import atan2,pi,fabs,hypot
import Tkinter
from thanvar import thanLogTk,Win32
from thantkguicroshair import *
from thantkconst import *
from thantkguiosnap import ThanOsnap,ThanOrtho

from thantkguistateless import ThanStateLess
from thantkguigeneric import ThanStateGeneric
from thantkguidrag import ThanStateDrag
from thantkguimove import ThanStateMove
from thantkguiline import ThanStateLine,ThanStateLine2,ThanStatePolar
from thantkguicircle import ThanStateCircle,ThanStateArc
from thantkguirect import ThanStateRectangle,ThanStateRectratio
from thantkguiroad import ThanStateRoadp,ThanStateRoadr
from thantkguivar import ThanStatePoint,ThanStateSelem


class ThanTkGuiLowGet(Tkinter.Canvas, ThanStateLess):
    "Lowlevel input from a Tk canvas."

#============================================================================

    def __init__(self, proj, *args, **kw):
        "Initialise base class and then this class."
        ThanStateLess.__init__(self)
        Tkinter.Canvas.__init__(self, proj[2], *args, **kw)
        self.__sb = proj[2].thanStatusBar

#-------Do some local initialisation

        dc = self
        dc.bind("<Key>",             self.__onChar)     # This should be deleted, or at least redirected to thanCom
        dc.bind("<Double-Button-1>", self.__onDclick)
        dc.bind("<Button-1>",        self.__onClick)
        dc.bind("<Button-3>",        self.__onClickr)
        dc.bind("<Motion>",          self.__onMotion)
        dc.bind("<B1-Motion>",       self.__onMotionDrag)
        dc.bind("<ButtonRelease-1>", self.__onReleaseDrag)
        if Win32:
            dc.bind("<MouseWheel>",      self.__mouseWheel)
            proj[2].bind("<MouseWheel>", self.__mouseWheelp)   # Hack for Windows: Yeh, Windows "just works", no need for hacks
        else:
            dc.bind("<Button-4>",        self.__downwheel)
            dc.bind("<Button-5>",        self.__upwheel)

        if not Win32:
            self.bind("<Page_Up>",        self.thanPanpageup)
            self.bind("<Shift-Page_Up>",  self.__donothing)
            self.bind("<Page_Down>",      self.thanPanpagedown)
            self.bind("<Shift-Page_Down>",self.__donothing)
        self.bind("<Control-Up>",    self.thanPanpageup)
        self.bind("<Control-Down>",  self.thanPanpagedown)
        self.bind("<Control-Left>",  self.thanPanpageleft)
        self.bind("<Control-Right>", self.thanPanpageright)
        self.bind("<F7>", self.__sb.thanToggleCoord)

        self.thanState = THAN_STATE_NONE
        self.thanOState = ThanStateGeneric(proj)

        dc.update_idletasks()                 # _idletasks breaks WinDoze (98?) support. Skotistika
        mx = dc.winfo_width() - 1
        my = dc.winfo_height() - 1
        self.thanXcu = dc.canvasx(mx / 2)
        self.thanYcu = dc.canvasy(my / 2)

        self.thanChs = ThanCrosHairs(proj)
        self.thanCh = CrosHair(dc)
        self.after(250, self.thanCh.resize)   # Give the Canvas a fourth of a second, to stabilise

        self.thanOsnap = ThanOsnap(proj)
        self.thanOrtho = ThanOrtho()
        self.thanFloatMenu = None
        self.thanProj = proj

#============================================================================

    def __mouseWheel(self, evt):
        "Mouse wheel up or down; for windows only."
        if evt.delta < 0: self.__upwheel(evt)
        else:             self.__downwheel(evt)


    def __mouseWheelp(self, evt):
        "Mouse wheel up or down when triggered on the parent; for windows only."
        self.update_idletasks()                   # so that .winfo_xxx() works
        evt.x = evt.x_root - self.winfo_rootx()
        evt.y = evt.y_root - self.winfo_rooty()
        if evt.delta < 0: self.__upwheel(evt)
        else:             self.__downwheel(evt)

#============================================================================

    def __upwheel(self, evt): self.thanUpwheel(evt)
    def __downwheel(self, evt): self.thanDownwheel(evt)
    def __onMotionDrag(self, evt): self.thanOState.thanOnMotionDrag(evt)
    def __onReleaseDrag(self, evt): self.thanOState.thanOnReleaseDrag(evt)
    def __onClick(self, evt): self.thanOnClick(evt)
    def __onClickr(self, evt): self.thanOnClickr(evt)

    def thanPanpagedown (self, evt): return self.thanPanPage(evt,  0, -1)
    def thanPanpageleft (self, evt): return self.thanPanPage(evt, -1,  0)
    def thanPanpageright(self, evt): return self.thanPanPage(evt,  1,  0)
    def thanPanpageup   (self, evt): return self.thanPanPage(evt,  0,  1)
    def __donothing(self, evt): pass

#============================================================================

    def _resultCoorRel0(self, dxp, dyp):
        "Convert relative pixel coordiantes to user data units."
        self.thanLastResult = ([0.0]*self.thanProj[1].thanVar["dimensionality"], None)
        self.thanLastResult[0][:2] = self.thanProj[2].thanCt.local2GlobalRel(dxp, dyp)

    def _resultCoor(self, xp, yp):
        "Convert relative pixel coordiantes to user data units."
        self.thanLastResult = (list(self.thanProj[1].thanVar["elevation"]), None)
        self.thanLastResult[0][:2] = self.thanProj[2].thanCt.local2Global(xp, yp)

#============================================================================

    def __onMotion(self, event):
        "Well, here is what should be drawn each time mouse moves."
        self.thanOsnap.active = "ena" in self.thanOsnap.types
        dc = self
        x = dc.canvasx(event.x)
        y = dc.canvasy(event.y)

        self.thanCh.draw(x, y)
        cc = list(self.thanProj[1].thanVar["elevation"])
        cc[:2] = self.thanProj[2].thanCt.local2Global(x, y)  # User coordinates (transformed from canvas coordinates)
        self.__sb.thanCoorMouse(cc)

        self.thanOState.thanOnMotion(event, x, y)

        self.thanXcu = x
        self.thanYcu = y
        if self.thanState != THAN_STATE_NONE and self.thanOsnap.active:
            self.after(10, self.thanOsnap.thanFind)


#============================================================================


    def thanOnClick(self, event):
        "Well, here is what should be done when mouse clicks."
        dc = self
#        dc.focus_set()              # This is needed otherwise text control gets characters?
        x = dc.canvasx(event.x)
        y = dc.canvasy(event.y)      # Click canvas coordinates

        if self.thanOsnap.active and self.thanOsnap.items != (): # If object snap, change click coordinates
            x = self.thanOsnap.x           # Canvas coordinates
            y = self.thanOsnap.y           # Canvas coordinates
            cc = self.thanOsnap.cc         # User coordinates (from object snap)
        else:
            cc = list(self.thanProj[1].thanVar["elevation"])
            x, y = self.thanOrtho.orthoxy(x, y)          # In case ortho is active
            cc[:2] = self.thanProj[2].thanCt.local2Global(x, y)  # User coordinates (transformed from canvas coordinates)

        self.__sb.thanCoorClick(cc)                      # Draw status text

        self.thanOState.thanOnClick(event, x, y, cc)

        self.thanXcu = x
        self.thanYcu = y

#============================================================================

    def thanOnClickr(self, event):
        "Well, here is what should be done when right mouse clicks."
        dc = self
#        dc.focus_set()              # This is needed otherwise text controls gets characters
        x = dc.canvasx(event.x)
        y = dc.canvasy(event.y)

        if self.thanOsnap.active and self.thanOsnap.items != (): # If object snap, change click coordinates
            x = self.thanOsnap.x           # Canvas coordinates
            y = self.thanOsnap.y           # Canvas coordinates
            cc = self.thanOsnap.cc         # User coordinates (from object snap)
        else:
            cc = list(self.thanProj[1].thanVar["elevation"])
            cc[:2] = self.thanProj[2].thanCt.local2Global(x, y)  # User coordinates (transformed from canvas coordinates)

        self.__sb.thanCoorClick(cc)                      # Draw status text

        self.thanOState.thanOnClickr(event, x, y, cc)

        if self.thanState == THAN_STATE_NONE:
            if self.thanFloatMenu != None and self.thanFloatMenu.winfo_ismapped():
                self.thanFloatMenu.unpost()
            self.thanFloatMenu = self.__createFloatMenu()
            self.thanFloatMenu.post(event.x_root, event.y_root)


    def __createFloatMenu(self):
        m = Tkinter.Menu(self, tearoff=False)
        fbeg = self.thanProj[2].thanGudCommandBegin
        m.add_command(label="Repeat last command", command=lambda fbeg=fbeg: fbeg(""))
        m.add_command(label="Real time zoom",      command=lambda fbeg=fbeg: fbeg("zoomrealtime"))
        m.add_command(label="Real time pan",       command=lambda fbeg=fbeg: fbeg("panrealtime"))

#  m1 = Menu(m, tearoff=False)
#  m1.add_checkbutton(label="zoom  when window changes", variable=self.zoomWhenConf)
#  m1.add_checkbutton(label="regen when window changes", variable=self.regenWhenConf)
#  m1.add_separator()
#  m1.add_checkbutton(label="regen when zoom", variable=self.regenWhenZoom)
#  m1.add_checkbutton(label="regen when zoom all", variable=self.regenWhenZoomall)
#  m1.add_checkbutton(label="center when zoom", variable=self.centerWhenZoom)
#  m1.add_separator()
#  m1.add_checkbutton(label="show menu bar", variable=self.showMenubar)
#  m1.add_checkbutton(label="show tool bar", variable=self.showToolbar)

#  m.add_cascade(label="options", menu=m1)
        return m

#============================================================================

    def __onDclick(self, event):
        "On double click change to the next available croshair."
        self.thanChs.thanRotate(self.canvasx(event.x), self.canvasy(event.y))

#============================================================================

    def __onChar(self, event):
        "Well, here is what should be done when user presses a key."
        thanLogTk.error("onChar(): Unexpected Canvas <key> event redirected to ThanCom.")
        win = self.thanProj[2]
        win.thanTkSetFocus()
        win.thanCom.thanOnChar(event)

#============================================================================

    def thanPrepare(self, state, cc1=None, cc2=None, cc3=None, r1=None, t1=None):
        "Sets the appropriate state and lets gui take on."
        ct = self.thanProj[2].thanCt
        x1, y1 = None, None
        if cc1 != None: x1, y1 = ct.global2Local(cc1[0], cc1[1])    # Transform to local coordinates
        x2, y2 = None, None
        if cc2 != None: x2, y2 = ct.global2Local(cc2[0], cc2[1])    # Transform to local coordinates
        x3, y3 = None, None
        if cc3 != None: x3, y3 = ct.global2Local(cc3[0], cc3[1])    # Transform to local coordinates
        r1, t1 = r1, t1
        if r1 != None: r1, r  = ct.global2LocalRel(r1, r1)  # Transform to local coordinates
        self.thanOsnap.cc1 = cc1

        dc = self
        dc.config(cursor=thanCursor.get(state, ""))
        if state == THAN_STATE_POINT1: state = THAN_STATE_POINT

        if state > THAN_STATE_DRAGFOLLOWS:
            self.thanOState = ThanStateDrag(self.thanProj)
        elif state == THAN_STATE_MOVE:
            self.thanOState = ThanStateMove(self.thanProj, x1, y1)
        elif state == THAN_STATE_LINE:
            self.thanOState = ThanStateLine(self.thanProj, x1, y1)
        elif state == THAN_STATE_LINE2:
            self.thanOState = ThanStateLine2(self.thanProj, x1, y1, x2, y2)
        elif state == THAN_STATE_POLAR:
            self.thanOState = ThanStatePolar(self.thanProj, x1, y1, r1)
        elif state == THAN_STATE_CIRCLE:
            self.thanOState = ThanStateCircle(self.thanProj, x1, y1)
        elif state == THAN_STATE_ARC:
            self.thanOState = ThanStateArc(self.thanProj, x1, y1, r1, t1)
        elif state == THAN_STATE_POINT:
            self.thanOState = ThanStatePoint(self.thanProj)
        elif state == THAN_STATE_RECTANGLE:
            self.thanOState = ThanStateRectangle(self.thanProj, x1, y1, t1)
        elif state == THAN_STATE_RECTRATIO:
            self.thanOState = ThanStateRectratio(self.thanProj, x1, y1, t1, cc1)
        elif state == THAN_STATE_ROADP:
            self.thanOState = ThanStateRoadp(self.thanProj, x1, y1, x2, y2,
                                             x3, y3, r1)
        elif state == THAN_STATE_ROADR:
            self.thanOState = ThanStateRoadr(self.thanProj, x1, y1, x2, y2,
                                             x3, y3, r1)
        elif state == THAN_STATE_SNAPELEM:
            self.thanOState = ThanStateSelem(self.thanProj)

        self.thanState = state


#============================================================================

    def thanGudIdle(self):
        "Returns true if not in the middle of a command."
        return self.thanState == THAN_STATE_NONE


    def thanTkClear(self):
        "Clears a window."
        dc = self
        dc.delete(Tkinter.ALL)                          # Clear window
        self.thanCh.resize()


    def thanGudCoorChanged(self):
        "System of canvas changed; redraw croshair."
        self.thanCh.resize()


    def destroy(self):
        "Deletes circular references."
        del self.__sb, self.thanProj, self.thanChs, self.thanCh,\
            self.thanOState, self.thanOsnap
        Tkinter.Canvas.destroy(self)


    def __delete__(self):
        "Show that self is really deleted."
        print "thantklowget:", self, "has been freed."


#############################################################################
#############################################################################

#MODULE LEVEL CODE. IT IS EXECUTED ONLY ONCE

if __name__ == "__main__":
    print __doc__
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.