interp_att_g.py revision 63b783299317098c2c41a7986af276305e46a7af
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#!/usr/bin/env python
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh'''
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshCopyright (C) 2009 Aurelio A. Heckert, aurium (a) gmail dot com
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshThis program is free software; you can redistribute it and/or modify
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshit under the terms of the GNU General Public License as published by
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshthe Free Software Foundation; either version 2 of the License, or
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh(at your option) any later version.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshThis program is distributed in the hope that it will be useful,
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshbut WITHOUT ANY WARRANTY; without even the implied warranty of
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshGNU General Public License for more details.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshYou should have received a copy of the GNU General Public License
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshalong with this program; if not, write to the Free Software
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh'''
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshimport inkex, simplestyle, math, re, string
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshimport gettext
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh_ = gettext.gettext
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshclass InterpAttG(inkex.Effect):
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh def __init__(self):
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh inkex.Effect.__init__(self)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.OptionParser.add_option("-a", "--att",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh action="store", type="string",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dest="att", default="fill",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh help="Attribute to be interpolated.")
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.OptionParser.add_option("-o", "--att-other",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh action="store", type="string",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dest="att_other",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh help="Other attribute (for a limited UI).")
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.OptionParser.add_option("-t", "--att-other-type",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh action="store", type="string",
fba63a357654d8b3e84c60007e40aa698cd45d19miklosh dest="att_other_type",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh help="The other attribute type.")
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.OptionParser.add_option("-w", "--att-other-where",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh action="store", type="string",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dest="att_other_where",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh help="That is a tag attribute or a style attribute?")
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.OptionParser.add_option("-s", "--start-val",
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh action="store", type="string",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh dest="start_val", default="#F00",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh help="Initial interpolation value.")
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.OptionParser.add_option("-e", "--end-val",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh action="store", type="string",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dest="end_val", default="#00F",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh help="End interpolation value.")
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.OptionParser.add_option("-u", "--unit",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh action="store", type="string",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh dest="unit", default="color",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh help="Values unit.")
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.OptionParser.add_option("--tab",
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh action="store", type="string",
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dest="tab",
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh help="The selected UI-tab when OK was pressed")
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh def getColorValues(self):
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh sv = string.replace( self.options.start_val, '#', '' )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh ev = string.replace( self.options.end_val, '#', '' )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if re.search('\s|,', sv):
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh # There are separators. That must be a integer RGB color definition.
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh sv = re.split( '[\s,]+', sv )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh ev = re.split( '[\s,]+', ev )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.R_ini = int( sv[0] )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.G_ini = int( sv[1] )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.B_ini = int( sv[2] )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.R_end = int( ev[0] )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.G_end = int( ev[1] )
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.B_end = int( ev[2] )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh # There is no separator. That must be a Hex RGB color definition.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if len(sv) == 3:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.R_ini = int( sv[0] + sv[0], 16 )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.G_ini = int( sv[1] + sv[1], 16 )
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.B_ini = int( sv[2] + sv[2], 16 )
1cda9431ef400135f5e1bd899a94b921bdad0eafmiklosh self.R_end = int( ev[0] + ev[0], 16 )
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.G_end = int( ev[1] + ev[1], 16 )
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.B_end = int( ev[2] + ev[2], 16 )
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh else: #the len must be 6
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.R_ini = int( sv[0] + sv[1], 16 )
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.G_ini = int( sv[2] + sv[3], 16 )
a4d12a5147f3d1d6b568a326e39ef5dca384248dmiklosh self.B_ini = int( sv[4] + sv[5], 16 )
1667116521643e2475184b048e0abb77a2aa9735miklosh self.R_end = int( ev[0] + ev[1], 16 )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.G_end = int( ev[2] + ev[3], 16 )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.B_end = int( ev[4] + ev[5], 16 )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.R_inc = ( self.R_end - self.R_ini ) / float( self.tot_el - 1 )
1cda9431ef400135f5e1bd899a94b921bdad0eafmiklosh self.G_inc = ( self.G_end - self.G_ini ) / float( self.tot_el - 1 )
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.B_inc = ( self.B_end - self.B_ini ) / float( self.tot_el - 1 )
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.R_cur = self.R_ini
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh self.G_cur = self.G_ini
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.B_cur = self.B_ini
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
1667116521643e2475184b048e0abb77a2aa9735miklosh def getNumberValues(self):
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh sv = self.options.start_val
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh ev = self.options.end_val
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if self.inte_att_type and self.inte_att_type != 'none':
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh sv = inkex.unittouu( sv + self.inte_att_type )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh ev = inkex.unittouu( ev + self.inte_att_type )
1667116521643e2475184b048e0abb77a2aa9735miklosh self.val_cur = self.val_ini = sv
1667116521643e2475184b048e0abb77a2aa9735miklosh self.val_end = ev
1667116521643e2475184b048e0abb77a2aa9735miklosh self.val_inc = ( ev - sv ) / float( self.tot_el - 1 )
1667116521643e2475184b048e0abb77a2aa9735miklosh
1667116521643e2475184b048e0abb77a2aa9735miklosh def getTotElements(self):
1667116521643e2475184b048e0abb77a2aa9735miklosh self.tot_el = 0
1667116521643e2475184b048e0abb77a2aa9735miklosh self.collection = None
1667116521643e2475184b048e0abb77a2aa9735miklosh if len( self.selected ) == 0:
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh return False
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if len( self.selected ) > 1:
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh # multiple selection
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.collection = self.options.ids
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh for i in self.options.ids:
1667116521643e2475184b048e0abb77a2aa9735miklosh path = '//*[@id="%s"]' % i
1667116521643e2475184b048e0abb77a2aa9735miklosh self.collection[self.tot_el] = self.document.xpath(path, namespaces=inkex.NSS)[0]
1667116521643e2475184b048e0abb77a2aa9735miklosh self.tot_el += 1
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh # must be a group
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.collection = self.selected[ self.options.ids[0] ]
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for i in self.collection:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.tot_el += 1
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh def effect(self):
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if self.options.att == 'other':
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.inte_att = self.options.att_other
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.inte_att_type = self.options.att_other_type
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.where = self.options.att_other_where
68664e00e2372534b4df2fdc5f54f836bafece18miklosh else:
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.inte_att = self.options.att
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if self.inte_att == 'width':
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.inte_att_type = 'float'
68664e00e2372534b4df2fdc5f54f836bafece18miklosh self.where = 'tag'
68664e00e2372534b4df2fdc5f54f836bafece18miklosh elif self.inte_att == 'height':
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.inte_att_type = 'float'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.where = 'tag'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh elif self.inte_att == 'scale':
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.inte_att_type = 'float'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.where = 'transform'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh elif self.inte_att == 'trans-x':
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.inte_att_type = 'float'
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.where = 'transform'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh elif self.inte_att == 'trans-y':
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.inte_att_type = 'float'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.where = 'transform'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh elif self.inte_att == 'fill':
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.inte_att_type = 'color'
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.where = 'style'
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh elif self.inte_att == 'opacity':
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.inte_att_type = 'float'
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh self.where = 'style'
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.getTotElements()
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if self.inte_att_type == 'color':
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.getColorValues()
1667116521643e2475184b048e0abb77a2aa9735miklosh else:
1667116521643e2475184b048e0abb77a2aa9735miklosh self.getNumberValues()
1667116521643e2475184b048e0abb77a2aa9735miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if self.collection is None:
1667116521643e2475184b048e0abb77a2aa9735miklosh inkex.errormsg( _('There is no selection to interpolate' ))
1667116521643e2475184b048e0abb77a2aa9735miklosh return False
1667116521643e2475184b048e0abb77a2aa9735miklosh
1667116521643e2475184b048e0abb77a2aa9735miklosh for node in self.collection:
1667116521643e2475184b048e0abb77a2aa9735miklosh if self.inte_att_type == 'color':
1667116521643e2475184b048e0abb77a2aa9735miklosh val = 'rgb('+ \
1667116521643e2475184b048e0abb77a2aa9735miklosh str(int(round(self.R_cur))) +','+ \
1667116521643e2475184b048e0abb77a2aa9735miklosh str(int(round(self.G_cur))) +','+ \
1667116521643e2475184b048e0abb77a2aa9735miklosh str(int(round(self.B_cur))) +')'
1667116521643e2475184b048e0abb77a2aa9735miklosh else:
1667116521643e2475184b048e0abb77a2aa9735miklosh if self.inte_att_type == 'float':
1667116521643e2475184b048e0abb77a2aa9735miklosh val = self.val_cur
1667116521643e2475184b048e0abb77a2aa9735miklosh else: # inte_att_type == 'int'
1667116521643e2475184b048e0abb77a2aa9735miklosh val = round(self.val_cur)
1667116521643e2475184b048e0abb77a2aa9735miklosh
1667116521643e2475184b048e0abb77a2aa9735miklosh if self.where == 'style':
1667116521643e2475184b048e0abb77a2aa9735miklosh s = node.get('style')
1667116521643e2475184b048e0abb77a2aa9735miklosh re_find = '(^|;)'+ self.inte_att +':[^;]*(;|$)'
1667116521643e2475184b048e0abb77a2aa9735miklosh if re.search( re_find, s ):
1667116521643e2475184b048e0abb77a2aa9735miklosh s = re.sub( re_find, '\\1'+ self.inte_att +':'+ str(val) +'\\2', s )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else:
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh s += ';'+ self.inte_att +':'+ str(val)
68664e00e2372534b4df2fdc5f54f836bafece18miklosh node.set( 'style', s )
1cda9431ef400135f5e1bd899a94b921bdad0eafmiklosh elif self.where == 'transform':
68664e00e2372534b4df2fdc5f54f836bafece18miklosh t = node.get('transform')
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if t == None: t = ""
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if self.inte_att == 'trans-x':
68664e00e2372534b4df2fdc5f54f836bafece18miklosh val = "translate("+ str(val) +",0)"
68664e00e2372534b4df2fdc5f54f836bafece18miklosh elif self.inte_att == 'trans-y':
68664e00e2372534b4df2fdc5f54f836bafece18miklosh val = "translate(0,"+ str(val) +")"
68664e00e2372534b4df2fdc5f54f836bafece18miklosh else:
68664e00e2372534b4df2fdc5f54f836bafece18miklosh val = self.inte_att + "("+ str(val) +")"
68664e00e2372534b4df2fdc5f54f836bafece18miklosh node.set( 'transform', t +" "+ val )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else: # self.where == 'tag':
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh node.set( self.inte_att, str(val) )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if self.inte_att_type == 'color':
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.R_cur += self.R_inc
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh self.G_cur += self.G_inc
1667116521643e2475184b048e0abb77a2aa9735miklosh self.B_cur += self.B_inc
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh else:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh self.val_cur += self.val_inc
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return True
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshif __name__ == '__main__': #pragma: no cover
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh e = InterpAttG()
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if e.affect():
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh exit(0)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh exit(1)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh