"""
-----------------------------------------------------------------------------
This source file is part of OSTIS (Open Semantic Technology for Intelligent Systems)
For the latest info, see http://www.ostis.net
Copyright (c) 2010 OSTIS
OSTIS 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 3 of the License, or
(at your option) any later version.
OSTIS 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.
You should have received a copy of the GNU General Public License
along with OSTIS. If not, see <http://www.gnu.org/licenses/>.
-----------------------------------------------------------------------------
"""
import math
import type
import cairo
import point
import text
import content
import geometry
M_PI = math.pi
class Node:
def __init__(self,ctx,surface, IDmap = None):
self.ctx = ctx
self.surface = surface
self.radius = 7.0
def init(self,reader):
self.type = type.Type(reader.get_typeElement())
self.center = point.Point(reader.get_floatattr('x'),reader.get_floatattr('y'))
self.idtf = reader.get_idtf()
self.width = 6.0
self.show_content = reader.get_boolattr("show_content")
if "not_define" == self.type.second:
self.radius = 2
self.cont = content.Content(self,reader,self.ctx)
def load(self,reader):
cr = self.ctx
pt = self.center
cr.save()
self.idtf = text.Text(self,reader,cr)
#self.idtf.leftTop = point.Point(self.center.x+self.radius,self.center.y+self.radius)
self.idtf.load()
if self.show_content:
self.cont.load()
else:
if "not_define" == self.type.second:
self.radius = 3
self.width = 2
cr.set_line_width (self.width)
if "const" == self.type.first:
cr.arc (pt.x, pt.y, self.radius, 0, 2 * M_PI)
cr.stroke_preserve()
side = self.radius * math.sqrt(2)
if "var" == self.type.first:
side += 2
self.varForm(side)
if "meta" == self.type.first:
side += 1
cr.save()
cr.translate(pt.x, pt.y)
cr.rotate (M_PI / 4)
#cr.restore()
cr.translate(-pt.x, -pt.y)
self.varForm(side)
cr.restore()
#
cr.clip()
cr.copy_path()
sf = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(2 * self.radius), int(2 * self.radius))
comp_cr = cairo.Context(sf)
comp_cr.save()
comp_cr.set_source_rgb (1, 1, 1)
comp_cr.rectangle(0, 0, 2 * self.radius, 2 * self.radius)
comp_cr.fill()
comp_cr.restore()
# h = sf.get_height()
# w = sf.get_width()
#
self.createStruct(side, self.radius, comp_cr, sf)
cr.scale (1, 1)
cr.set_source_surface (sf, pt.x - self.radius, pt.y - self.radius)
cr.paint ()
#cr.stroke()
cr.restore()
def varForm(self,side):
pt = self.center
cr = self.ctx
cr.rectangle(pt.x-side/2,pt.y-side/2,side,side)
cr.stroke_preserve()
def createStruct(self,side,radius,comp_cr,sf):
width = 1.0
comp_cr.set_line_width (width)
if "asymmetry" == self.type.second:
comp_cr.save()
comp_cr.move_to (0, radius)
comp_cr.line_to (2*radius, radius)
comp_cr.stroke ()
comp_cr.restore()
if "nopredmet" == self.type.second:
comp_cr.save()
comp_cr.arc (radius, radius, 2, 0, 2 * M_PI)
comp_cr.fill()
#comp_cr.stroke()
comp_cr.restore()
if "predmet" == self.type.second:
rad = 0
comp_cr.set_line_width (0.5)
for i in range(int(4*radius)):
if i%2 == 0:
comp_cr.save()
comp_cr.move_to (0, rad)
comp_cr.line_to (2*radius, rad)
comp_cr.stroke()
comp_cr.restore()
rad+=1.5
if "attribute" == self.type.second:
comp_cr.save()
comp_cr.move_to (radius, 0)
comp_cr.line_to (radius, 2*radius)
comp_cr.stroke()
comp_cr.restore()
comp_cr.save()
comp_cr.move_to (0, radius)
comp_cr.line_to (2*radius, radius)
comp_cr.stroke()
comp_cr.restore()
if "relation" == self.type.second:
self.relForm(radius,comp_cr)
if "group" == self.type.second:
self.relForm(radius,comp_cr)
comp_cr.save()
comp_cr.move_to (0, radius)
comp_cr.line_to (2*radius, radius)
comp_cr.stroke()
comp_cr.restore()
return
def relForm(self,side,cr):
cr.save()
cr.move_to (0, 0)
cr.line_to (2*side, 2*side)
cr.stroke()
cr.restore()
cr.save()
cr.move_to (2*side, 0)
cr.line_to (0, 2*side)
cr.stroke()
cr.restore()
def getTextCoord(self):
res = self.center
res.x += 15
return res
def MaxXY(self):
res = point.Point(self.center.x +self.radius + self.width,self.center.y +self.radius + self.width)
res.x = max(self.cont.rect.x+self.cont.rect.width+self.radius + self.width,res.x)
res.y = max(self.cont.rect.y+self.cont.rect.height+self.radius + self.width ,res.y)
res.x = max(self.idtf.rightBottom.x,res.x)
res.y = max(self.idtf.rightBottom.y ,res.y)
return res
def getCross(self,pt,additionAngle=0):
#alpha = math.atan2(math.fabs(pt.y-self.center.y), math.fabs(pt.x-self.center.x))
#vec= point.Point(self.center.x - pt.x,self.center.y - pt.y)
#p = - vec.normalized().toPointF() * (mSize.width() / 2.f + 5.f);
#l = math.hypot(vec.x,vec.y)
#delta = self.radius/2 +5.0
#vec.x = -(vec.x/l)*delta
#vec.y = -(vec.y/l)*delta
#res = -
if self.show_content:
return self.cont.getCross(pt,additionAngle)
else:
alpha = geometry.countAngle(self.center,pt,additionAngle)
xB = self.center.x+(self.radius+int(self.width/2 -0.5))*math.cos(alpha)
yB = self.center.y+(self.radius+int(self.width/2 -0.5))*math.sin(alpha)
return point.Point(xB,yB)