##############################################################################
# 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 valid attributes of a layer, their type, and their
default value.
It also defines the actions to do to elements, when an attribute is forced
on them.
"""
import copy
import p_gtkwid
from p_gmath import thanNear2
from thanvar import Canc,THANBYPARENT,THANPERSONAL
from thanlaycon import *
from thandefs.thanatt import *
from thanopt import thancadconf
import thantkdia
from thantrans import T
############################################################################
############################################################################
def thanPlotcolorGet (*args): pass
def thanLinetypeGet (*args): pass
def thanPointstyleGet(*args): pass
def thanHatchGet (*args): pass
def thanFillGet (*args): pass
def thanLockedGet (*args): pass
def thanNoplotGet (*args): pass
def thanProtectedGet (*args): pass
def thanOnclick(evt, win, attname, indexes, selLayers):
"Calls the appropriate function for the attribute and layers chosen by the user."
fun = thanLayAtts[attname][1]
if fun == None: return # No function; do nothing
newval,keepsel = fun(win, attname, selLayers)
if newval == Canc: # User cacncelled
if len(indexes) < 2: win.thanSelNone() # Keep the selection (unless only 1 layer)
return
typ = thanLayAtts[attname][0]
if typ != 0: assert newval != THANBYPARENT, attname+": Forced inheritance attributes can not be inherited manually."
for lay in selLayers:
lay.thanSetAtts(win.thanLeaflayers, attname, newval)
win.thanRegen()
if keepsel and len(indexes) > 1: win.thanSelVar(indexes) # Keep the selection
else: win.thanSelNone() # Clear the selection
def thanMoncolorGet(win, att, selLayers):
"Lets the user select monitor colour."
c =__commonVal(att, selLayers)
w = thantkdia.ThanColor(win, c, title="Select ThanCad Colour")
r = w.result
if r == None: r = Canc
return r, True
def __commonVal(att, selLayers):
"Selects the common value of att in the layers selLayers, if possible."
c = selLayers[0].thanAtts[att]
for lay in selLayers:
cl = lay.thanAtts[att]
if cl.thanVal != c.thanVal or cl.thanInher != c.thanInher: return "<varies>"
if c.thanInher: return THANBYPARENT
return c
def thanFrozenGet(win, att, selLayers):
"Lets the user select new frozen value: yes/no/BYPARENT."
n = 0
for lay in selLayers:
if lay.thanAtts[att].thanVal: n += 1
class_ = thanLayAtts[att][3]
val = class_(n < len(selLayers)) # Less than half layers are frozen; freeze all
return val, True
def thanFillGet(win, att, selLayers):
"Lets the user select new 'fill' value for the selected layers."
ia = selLayers[0].thanAtts[att] # A sample attribute value
tlabs = [str(THANBYPARENT), str(THANPERSONAL), ia.thanOn, ia.thanOff]
w = p_gtkwid.ThanPoplist(win, tlabs, width=15, title=T["Select ThanCad Fill mode"])
if w.result == None: return Canc, True
if w.result == str(THANBYPARENT): return THANBYPARENT, True
if w.result == str(THANPERSONAL): return THANPERSONAL, True
class_ = thanLayAtts[att][3]
r = class_(w.result)
return r, True
def thanTstyleGet(win, att, selLayers):
"Lets the user select new textstyle for the selected layers."
c =__commonVal(att, selLayers)
proj = win.thanCargo
tlabs = proj[1].thanTstyles.keys()
tlabs.sort()
tlabs.insert(0, str(THANBYPARENT))
tlabs.insert(1, str(THANPERSONAL))
w = p_gtkwid.ThanPoplist(win, tlabs, width=40, title=T["Select ThanCad Text Style"])
if w.result == None: return Canc, True
if w.result == str(THANBYPARENT): return THANBYPARENT, True
if w.result == str(THANPERSONAL): return THANPERSONAL, True
class_ = thanLayAtts[att][3]
r = class_(w.result)
return r, True
def thanDraworderGet (win, att, selLayers):
"Lets the user select new draworder for the selected layers."
c =__commonVal(att, selLayers)
w = thantkdia.ThanDro(win, c, title="Select Draw Order")
r = w.result
if r == None: return Canc, True
if r in (THANBYPARENT, THANPERSONAL): return r, True
class_ = thanLayAtts[att][3]
r = class_(r)
return r, True
def thanPenthickGet (win, att, selLayers):
"Lets the user select new pen thickness (mm of linear objects) for the selected layers."
c =__commonVal(att, selLayers)
w = thantkdia.ThanPen(win, c, "Pen", title="Select Pen Thickness")
r = w.result
if r == None: return Canc, True
if r in (THANBYPARENT, THANPERSONAL): return r, True
class_ = thanLayAtts[att][3]
r = class_(r)
return r, True
def thanLinethickGet (win, att, selLayers):
"Lets the user select new thickness (user unints of linear objects) for the selected layers."
c =__commonVal(att, selLayers)
w = thantkdia.ThanPen(win, c, "Line", title="Select Line Thickness")
r = w.result
if r == None: return Canc, True
if r in (THANBYPARENT, THANPERSONAL): return r, True
class_ = thanLayAtts[att][3]
r = class_(r)
return r, True
def thanUpdateElements(proj, leaflayers, updatelayers=True):
"""Updates attribute a of the elements of the layers which are already on screen.
IT IS ASSUMED THAT AFTER THIS ROUTINE IS CALLED, THE CALLER ALSO SETS THE
STRUCTURE proj[2].than TO REFLECT THE CURRENT'S LAYER ATTRIBUTES i.e.
TO CALL proj[2].thanLayerTree.thanCur.thanTkSet(proj[2].than, proj[1].thanTstyles)
"""
# for lay,atts in leaflayers.iteritems(): print lay.thanGetPathname(), "->", atts
from thandr import ThanPointNamed,ThanCircle,ThanLine
draworder = False
dc = proj[2].thanCanvas
than = proj[2].than
for lay,atts in leaflayers.iteritems():
colourhasbeenset = False
if "frozen" in atts:
nval = atts["frozen"]
ia = lay.thanAtts["frozen"]
if ia.thanAct != nval: # An attribute may be the same, if the user deleted the value, and then gave the same value
if nval:
proj[2].thanGudSetFreezeLayer(lay) # All items are deleted from canvas; there are no items to update!!!
else:
proj[1].thanTkDraw(proj[2].than, (lay,)) # All items are redrawn; all items are up to date
draworder = True # All items are redrawn; thus, probably, the draworder is violated
for a,nval in atts.iteritems(): # Either way, the actual value is the same with new value
ia = lay.thanAtts[a]
if updatelayers: ia.thanAct = nval
continue
thawed = not lay.thanAtts["frozen"].thanVal
for a,nval in atts.iteritems():
ia = lay.thanAtts[a]
if thawed and ia.thanAct != nval:
if a == "moncolor":
if not colourhasbeenset:
lay.thanTkSet(than, proj[1].thanTstyles) # Note that .thanval is already set with the new value
# than.outline = lay.ThanAttCol(nval).thanTk
proj[2].thanGudGetSelLayerx(lay.thanTag)
proj[2].thanGudSetSelColorx(than.outline, than.fill)
colourhasbeenset = True
elif a == "fill":
if not colourhasbeenset:
lay.thanTkSet(than, proj[1].thanTstyles)
proj[2].thanGudGetSelLayerx(lay.thanTag)
proj[2].thanGudSetSelColorx(than.outline, than.fill)
colourhasbeenset = True
# for elem in lay.thanQuad:
# if isinstance(elem, ThanCircle):
# dc.delete(elem.thanTags[0])
# elem.thanTkDraw(than)
# elif isinstance(elem, ThanLine):
# if thanNear2(elem.cp[0], elem.cp[-1]):
# dc.delete(elem.thanTags[0])
# elem.thanTkDraw(than)
elif a == "draworder":
draworder = True
elif a == "penthick":
pass # Nothing visible changes
elif a == "linethick":
pass # FIXME: redraw linear elements with new thickness
elif a == "hidename" or a == "hidepoint":
lay.thanTkSet(than, proj[1].thanTstyles)
for elem in lay.thanQuad:
if not isinstance(elem, ThanPointNamed): continue
dc.delete(elem.thanTags[0])
elem.thanTkDraw(than)
if updatelayers: ia.thanAct = nval
return draworder
#############################################################################
#############################################################################
#MODULE LEVEL CODE. IT IS EXECUTED ONLY ONCE
thanLayAttsOrder = \
( ("expand", (0, None, None, ThanAtt,
"'+' if layer's children should be shown.")),
("layer", (0, None, None, ThanAtt, "Layer name.")),
("plotcolor", (0, thanPlotcolorGet, ThanAttCol(thancadconf.thanColRoot), ThanAttCol, # red
"Element color on printer/plotter.")),
("moncolor", (0, thanMoncolorGet, ThanAttCol(thancadconf.thanColRoot), ThanAttCol, # red
"Element color on screen.")),
("linetype", (0, thanLinetypeGet, "continuous", ThanAtt,
"Linetype of linear elements.")),
("ltscale", (0, thanLinetypeGet, 1.0, ThanAtt, "Linetype scale. It may be negative "+\
"as a percentage to the screen.")),
("fill", (0, thanFillGet, False, ThanAttOnoffInherit,
"If 1, circles and closed elements are filled with colour/hatch.")),
("linethick", (0, thanLinethickGet, 0.0, ThanAtt,
"Line thickness (user units) of linear elements (in Tkinter only lines), "+\
"including ThanCadLinearFonts. It may be negative "+\
"as a percentage of the screen")),
("penthick", (0, thanPenthickGet, 0.25, ThanAtt,
"Pen thickness (mm) which the elements are plotted with. Independent to scale.")),
("pointstyle", (0, thanPointstyleGet, "dot", ThanAtt, "Point style.")),
("pointsize", (0, thanPointstyleGet, -5.0, ThanAtt, "Point size. It may be negative "+\
"as a percentage of the screen.")),
("hidename", (1, thanFrozenGet, True, ThanAttOnoff, "Hide point name.")),
("hideheight", (1, thanFrozenGet, True, ThanAttOnoff, "Hide point height.")),
("hatch", (0, thanHatchGet, "solid",ThanAtt,
"Hatch style of hatchable elements.")),
("hatchscale", (0, thanHatchGet, 1.0, ThanAtt, "Hatch scale. It may be negative "+\
"as a percentage to the screen.")),
("textstyle", (0, thanTstyleGet, "standard",ThanAtt, "Text style and font of textual elements.")),
("textscale", (0, thanTstyleGet, 1.0, ThanAtt, "Text scale. It may be negative "+\
"as a percentage to the screen.")),
("draworder", (0, thanDraworderGet, 1000, ThanAtt,
"Plotting Order. A layer with small draworder is drawn "\
"before (and therefore under) a layer with big draworder.")),
("frozen", (1, thanFrozenGet, False, ThanAttOnoff,
"If 1, elements are not shown, like if they never existed.")),
("locked", (1, thanLockedGet, False, ThanAttOnoff,
"If 1, elements are shown readonly; they can not be edited.")),
("noplot", (1, thanNoplotGet, False, ThanAttOnoff,
"If 1, elements are shown but they are not be plotted.")),
("protected", (2, thanProtectedGet, False, ThanAttOnoff,
"Elements are controlled by a program; they are read only."+
"This attribute can not be altered by the user."))
)
thanLayAttsType = \
{ 0: """Type zero is normal layer inheritance. When this attribute of
a layer changes, then all their children which have this
attribute set as BYPARENT change too.
""",
1: """Type 1 is global layer inheritance and it is zero (false)
or nonzero (generalised true). When this attribute
becomes a<>0 (true), then all its
children behave as this attribute were also set to a.
However, when this attribure becomes 0 (false) again, the
children retain their original attribute value.
""",
2: """Type 2 attributes work like type 1, but the user can not modify them.
These attributes may be modified only by programs embedded in ThanCad.
"""
}
info=\
"""Point size, dashed linetypes, hatch, text size, linethick may be relative to,
actually a percentage of, the screen (as points in autocad).
Another idea is to have them defined relative to the screen, but in cm or inches
assuming that screen has a diagonal of 15, 17, 19 and so on, inches.
"""
thanLayAtts = {}
thanLayAttsNames = []
for (key, val) in thanLayAttsOrder:
thanLayAtts[key] = val
thanLayAttsNames.append(key)
thanLayAttsNames = ["expand", THANNAME, "moncolor", "frozen", "textstyle", "draworder",
"fill", "penthick", "linethick", "hidename", "hideheight"]
thanLayAttsWidths = [1, 30, 20, 3, 20, 6,
5, 6, 6, 3, 3]
if __name__ == "__main__":
print __doc__
form = "%-15s%-6s%-15s %s"
print form % ("attribute", "type", "default value", "Doc")
print "------------------------------------------------"
for (name, att) in thanLayAtts.iteritems():
print form % (name, att[0], att[2], att[3])
print
for (name, att) in thanLayAttsType.iteritems():
print name, att
|