thantkguiosnap.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 » thantkguiosnap.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 the object snap functionality.
"""

from thanvar import thanLogTk
from thanopt import thancadconf
from thandefs.thanatt import ThanAttCol

_AVOIDTAG = frozenset(("e0", "edrag"))


class ThanOsnap:
    "Object snap functionality class."

    def __init__(self, proj):
        "Initialize the object."
        self.thanProj = proj
        self.BSEL = proj[2].BSEL
        self.size = proj[2].BOSN      # size of osnap signs
        self.types = thancadconf.thanOsnapModes

        self.active = "ena" in self.types
        self.preempt = False
        self.items = ()
        self.tcol = ThanAttCol(thancadconf.thanColOsn).thanTk
        self.selems = proj[2].thanSelems # Elements which may be snapped to.
        self.selem = None                # Snapable element which is near cursor.
        self.cc1 = None


    def thanFind(self):
        "Finds end, mid, center etc near the mouse cursor."
        if self.preempt:
            thanLogTk.error("tklowget: osnapFind: preemptive call. It shouldn't happen.")
            return
        self.preempt = True
        dc = self.thanProj[2].thanCanvas
        tagel = self.thanProj[1].thanTagel
        ct = self.thanProj[2].thanCt
        bpix, hpix = self.BSEL/2, self.BSEL/2
        x1, y1 = dc.thanXcu-bpix, dc.thanYcu-hpix
        x2, y2 = dc.thanXcu+bpix, dc.thanYcu+hpix
        items = dc.find_overlapping(x1, y1, x2, y2)
        otypes = self.types

        ccu = list(self.thanProj[1].thanVar["elevation"])
        ccu[:2] = ct.local2Global(dc.thanXcu, dc.thanYcu)
        if "ele" in otypes:
            selems = self.selems
            for item in items:
                tags = dc.gettags(item)
                                                # Tkinter may automatically add the tag 'current' in any element
                                                # so the next test (which should succeed) does not succeed.
                                                # Thus we have to check for "e0" AND "edrag"
                if len(tags) < 2: continue      # We avoid current (rubber line)
                if tags[0] in _AVOIDTAG: continue    # We avoid current compound element (we shouldn't really)
                e = tagel[tags[0]]
                if e in selems:
                    dc.delete("e0")
                    self.selem = e
                    e1 = e.thanClone()
                    e1.thanTags = ("e0",)
                    than = self.thanProj[2].than
                    col1 = than.outline
                    than.outline = self.tcol
                    e1.thanTkDraw(than)
                    dc.itemconfig("e0", width=5)
                    than.outline = col1
                    self.preempt = False
                    return
            self.selem = None
            dc.delete("e0")
            self.preempt = False
            return
        elif "int" in otypes:
            ps = self.__int(dc, tagel, otypes, items, ccu, self.cc1)
        else:
            ps = []
            for item in items:
#          tags = dc.itemcget(item, "tags").split()
          if dc.type(item) == "image": continue # Ignore Tk images; only the bounding rectangle counts
          tags = dc.gettags(item)
          if len(tags) < 2: continue      # We avoid current (rubber line)
          if tags[0] in _AVOIDTAG: continue    # We avoid current compound element (we shouldn't really)
          e = tagel[tags[0]]
          p = e.thanOsnap(self.thanProj, otypes, ccu, None, self.cc1)
          if p != None:
        ps.append(p)
        if len(ps) > 2: break
        for item1 in self.items: dc.delete(item1)
  if len(ps) < 1:
      self.items = ()
      self.preempt = False
      return
  p = min(ps)
  b, h = ct.global2LocalRel(p[0], p[0])
  if b > 10*self.BSEL:
      self.items = ()
      self.preempt = False
      return
  t = self.type = p[1]
  cc = self.cc = p[2]
        x, y = ct.global2Local(cc[0], cc[1])
  self.x = x
  self.y = y
  b = h = self.size/2
  tcol = self.tcol
  if t == "end":
            self.items = \
      ( dc.create_rectangle(x-b, y-h, x+b, y+h, width=3, outline=tcol, fill=""),
      )
  elif t == "mid":
            self.items = \
            ( dc.create_polygon(x-b, y-b, x+b, y-b, x, y+b, width=3, outline=tcol, fill=""),
      )
  elif t == "cen":
            self.items = \
            ( dc.create_oval(x-b, y-b, x+b, y+b, width=3, outline=tcol, fill=""),
      )
  elif t == "nod":
            self.items = \
            ( dc.create_oval(x-b, y-b, x+b, y+b, width=3, outline=tcol, fill=""),
              dc.create_line(x-b, y-b, x+b, y+b, width=2, fill=tcol),
              dc.create_line(x-b, y+b, x+b, y-b, width=2, fill=tcol),
      )
  elif t == "qua":
            self.items = \
      ( dc.create_polygon(x-b,y, x,y+b, x+b,y, x,y-b, width=2, outline=tcol, fill=""),
      )
  elif t == "int":
            self.items = \
            ( dc.create_line(x-b, y-b, x+b, y+b, width=2, fill=tcol),
              dc.create_line(x-b, y+b, x+b, y-b, width=2, fill=tcol),
      )
  elif t == "tan":
      bb = 0.8*b
            self.items = \
            ( dc.create_oval(x-bb, y-bb, x+bb, y+bb, width=3, outline=tcol, fill=""),
        dc.create_line(x-b, y-b, x+b, y-b, width=2, fill=tcol),
      )
  elif t == "nea":
            self.items = \
      ( dc.create_polygon(x-b, y-b, x+b, y+b, x-b, y+b, x+b, y-b, width=2, outline=tcol, fill=""),
      )
        elif t == "per":
            self.items = \
            ( dc.create_line(x-b, y-b, x-b, y+b, x+b, y+b, width=3, fill=tcol),
              dc.create_line(x-b, y, x, y, x, y+b, width=2, fill=tcol),
            )
        self.preempt = False


    def __int(self, dc, tagel, otypes, items, ccu, cc1):
        "Finds int near the mouse cursor."
        dc = self.thanProj[2].thanCanvas
        ps = []
        it = iter(items)
        for item in it:                     # Search for first element of intersection
            tags = dc.gettags(item)
            if len(tags) < 2:   continue    # We avoid current (rubber line)
            if tags[0] in _AVOIDTAG: continue    # We avoid current compound element (we shouldn't really)
            e = tagel[tags[0]]
            break
        else: return ps
        etried = False
        for item in it:                     # Search for second element of intersection
            tags = dc.gettags(item)
            if len(tags) < 2:   continue    # We avoid current (rubber line)
            if tags[0] in _AVOIDTAG: continue    # We avoid current compound element (we shouldn't really)
            etried = True
            e2 = tagel[tags[0]]
            p = e.thanOsnap(self.thanProj, otypes, ccu, e2, cc1)
            if p != None: ps.append(p); break
            e = e2
        if etried: return ps
        p = e.thanOsnap(self.thanProj, otypes, ccu, None, cc1)

        if p != None: ps.append(p)
        return ps


    def thanCleanup(self):
        "Do cleanup after error/command-line action."
        dc = self.thanProj[2].thanCanvas
        for item1 in self.items:
            dc.delete(item1)
        self.items = ()


class ThanOrtho:
    "Ortho mode functionality class."

    def __init__(self):
        "Initialize the object."
        self.thanIdirs = [(1.0, 0.0), (0.0, 1.0), (-1.0, 0.0), (0.0, -1.0)]
        self.on = False      # If this is false then ortho is off
        self.active = False  # This is false if ortho has no meaning for current action
        self.xa = None       # The reference point for ortho mode..
        self.ya = None       # ..in canvas coordinates


    def enable(self, xa, ya):
        "Enable ortho mode, if it is on."
        self.xa = xa
        self.ya = ya
        self.active = True


    def disable(self):
        "Disable ortho mode; ortho has no meaning for current action."
        self.active = False
        self.xa = self.ya = None


    def toggle(self):
        "Toggle on/off and return the currebt state."
        self.on = not self.on
        return self.on


    def orthoxy(self, xb, yb):
        "Force the coordinates of the mouse parallel to a direction; usually ortho mode."
        if not self.active or not self.on: return xb, yb
        dx = xb - self.xa
        dy = yb - self.ya
        dismax = 0.0
        for idir1 in self.thanIdirs:
            disproj = dx*idir1[0] - dy*idir1[1]   # The negative sign in y is due to local coordinate systems
            if disproj > dismax:
                dismax = disproj
                idirmax = idir1
        return self.xa + dismax*idirmax[0], self.ya - dismax*idirmax[1]
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.