• Facebook
  • Twitter
  • Reddit
  • StumbleUpon
  • Digg
  • email

"""
-----------------------------------------------------------------------------
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)