+++ /dev/null
-#!/usr/bin/env python
-# coding=UTF-8
-#
-# Copyright (C) 2010 Stefanos Harhalakis
-#
-# This file is part of wifieye.
-#
-# wifieye 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.
-#
-# wifieye 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 wifieye. If not, see <http://www.gnu.org/licenses/>.
-#
-# $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $
-
-__version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $"
-
-import gtk
-import gobject
-import hildon
-from hildondesktop import *
-from gtk import gdk
-from math import pi
-import cairo
-import time
-
-from portrait import FremantleRotation
-import launcher
-from xdg.IconTheme import getIconPath
-from sig import Disconnector
-
-#import config
-import apps
-
-# Background surface for icons
-iconbg=None
-sthemebg1=None
-sthemebg2=None
-
-# Load an icon
-# Fall-back to default/blue if not found or name==None
-def getIcon(name, iconsize):
- # Default icon
- idef='tasklaunch_default_application'
-
- # If name==None then use the default icon
- if name==None or name=='':
- iname=idef
- else:
- iname=name
-
- ico=getIconPath(iname, iconsize)
-
- # If not found then use the default icon
- if ico==None:
- ico=getIconPath(idef, iconsize)
-
- try:
- ret=gtk.gdk.pixbuf_new_from_file_at_size(ico, iconsize, iconsize)
- except:
- # On error use the default icon
- ico=getIconPath(idef, iconsize)
- ret=gtk.gdk.pixbuf_new_from_file_at_size(ico, iconsize, iconsize)
- print "Icon with unhandled format:", iname
-
- return(ret)
-
-class Icon(Disconnector, gobject.GObject):
-#class Icon(gtk.Widget, Disconnector):
-
- __v_t=(gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
- gobject.TYPE_NONE, ())
-
- gsignals={
- 'click': __v_t,
- 'double-click': __v_t,
- 'tripple-click': __v_t,
- 'long-press': __v_t,
- }
-
- __gsignals__=gsignals
-
- def __init__(self, isconfig, config):
-# self.__gobject_init__()
- gobject.GObject.__init__(self)
-# gtk.Widget.__init__(self)
- Disconnector.__init__(self)
-
- self.isconfig=isconfig
- self.config=config
-
- self.appname=None
- self.icon=None
- self.sicon=None
- self.lastpress=0
- self.ispressed=False
-
- self.x=0
- self.y=0
-
- self.presstime=0.25
-
- self.window_=None
-
- self.clickcount=0
-
- self.angle=0
-
- self.cached_icons={}
-
- self.draw_queued=False
-
- #print "icon-init"
-
- def __del__(self):
- #print "icon-del"
- pass
-
- def timePressed(self):
- """ return how much time a button is pressed """
- dt=time.time() - self.lastpress
-
- return(dt)
-
- def reload(self):
- self.clearAnimationCache()
- self.clearBgCache()
- self.invalidate()
-
- def setApp(self, dt):
- if dt==None:
- self.appname=None
- self.icon=None
- self.sicon=None
- else:
- self.appname=dt['id']
- self.icon=dt['icon2']
- self.sicon=None
- self.clearAnimationCache()
- self.clearBgCache()
- self.invalidate()
-
- def clearAnimationCache(self):
- self.cached_icons={}
-
- def clearBgCache(self):
- global iconbg, sthemebg1, sthemebg2
-
- iconbg=None
- sthemebg1=None
- sthemebg2=None
-
- def getSize(self):
- return(self.config.getIconSizeFull())
- # return(self.config.iconsize+self.config.iconspace)
-
- def setAngle(self, angle):
- """ Set the angle. Return True if the angle changed or False if it
- didn't. The caller should invalidate the icon """
-
- # The step in degrees
- step=9
-
- angle2=int(angle/step)*step
-
- if angle2==self.angle:
- return(False)
-
- self.angle=angle2
-
- # The caller should be responsible for redrawing.
- # If we call invalidate() here there is the risk of having
- # icons rotate individually using different angles
-# self.invalidate()
-
- return(True)
-
- def mkbg(self, t_pressed):
- """ Create the background of the icon and cache it as a global
- variable among all icons and widget instances """
- global iconbg
-
- if iconbg!=None and t_pressed<=0.001:
- return(iconbg)
-
- w=self.getSize()
- s=cairo.ImageSurface(cairo.FORMAT_ARGB32, w, w)
- cr0=cairo.Context(s)
- cr=gtk.gdk.CairoContext(cr0)
-
- cr.set_source_rgba(0.1, 0.1, 0.1, 1)
- cr.set_line_width(5)
-
- #if self.ispressed:
- if t_pressed>0.001 and \
- (t_pressed <= self.presstime or self.ispressed):
- t=1.0 * min(t_pressed, self.presstime) / self.presstime
- g=0.3+0.5*t
- b=0.3+0.7*t
- cr.set_source_rgba(0, g, b, 0.7)
- else:
- cr.set_source_rgba(0.3, 0.3, 0.3, 0.7)
-
- x=0
- y=0
- x3=x + (self.config.iconmargin)
- y3=y + (self.config.iconmargin)
-
- r=10 # Radius
- w=self.config.iconsize+(self.config.iconpadding*2)
-
- cr.move_to(x3+r, y3)
- cr.arc(x3+w-r, y3+r, r, pi*1.5, pi*2)
- cr.arc(x3+w-r, y3+w-r, r, 0, pi*0.5)
- cr.arc(x3+r, y3+w-r, r, pi*0.5, pi)
- cr.arc(x3+r, y3+r, r, pi, pi*1.5)
-
- cr.stroke_preserve()
- cr.fill()
- cr.clip()
- cr.paint()
-# cr.restore()
-
- if t_pressed<0.001:
- iconbg=s
-
- return(s)
-
- def get_sthemebg(self, pressed):
- """ Return the theme's background icon as a surface. Cache it. """
- global sthemebg1, sthemebg2
-
- if not pressed and sthemebg1!=None:
- return(sthemebg1)
- if pressed and sthemebg2!=None:
- return(sthemebg2)
-
- fn="/etc/hildon/theme/images/"
- if pressed:
- fn+="ApplicationShortcutAppletPressed.png"
- else:
- fn+="ApplicationShortcutApplet.png"
-
- w=self.config.iconsize + (self.config.iconpadding*2)
- buf=gtk.gdk.pixbuf_new_from_file_at_size(fn, w, w)
- s=cairo.ImageSurface(cairo.FORMAT_ARGB32, w, w)
- cr0=cairo.Context(s)
- cr=gtk.gdk.CairoContext(cr0)
-
- cr.set_source_pixbuf(buf, 0, 0)
- cr.paint()
-
- if not pressed:
- sthemebg1=s
- else:
- sthemebg2=s
-
- return(s)
-
- def get_sicon(self):
- """ Return the icon as a surface. Cache it. """
- if self.sicon!=None:
- return(self.sicon)
-
- w=self.config.iconsize
- s=cairo.ImageSurface(cairo.FORMAT_ARGB32, w, w)
- cr0=cairo.Context(s)
- cr=gtk.gdk.CairoContext(cr0)
-
- cr.set_source_pixbuf(self.icon, 0, 0)
- cr.paint()
-
- self.sicon=s
-
- return(s)
-
- def get_paint_icon(self):
- """ Return the icon to paint as a surface. The icon is rotated
- as needed. The result is cached. """
- angle=self.angle
-
- if self.timePressed() <= self.presstime or self.ispressed:
- t=self.timePressed()
- pressed=True
- else:
- t=0
- pressed=False
-
- if not pressed and self.cached_icons.has_key(angle):
- return(self.cached_icons[angle])
-
- w=self.config.getIconSizeFull()
- s=cairo.ImageSurface(cairo.FORMAT_ARGB32, w, w)
- cr0=cairo.Context(s)
- cr=gtk.gdk.CairoContext(cr0)
-
- # Paint the background
- if self.config.getNoBg():
- pass
- elif self.config.getThemeBg(): # Use theme bg
- s2=self.get_sthemebg(pressed)
-
- # have in mind the size difference of iconsize+iconspace with
- # the fixed themebgsize
- #xy0=int((w-self.config.themebgsize)/2)
- #xy0=int((w-self.config.iconsize)/2)
- xy0=self.config.iconmargin
-
- cr.save()
- cr.set_source_surface(s2, xy0, xy0)
- cr.paint()
- cr.restore()
- else:
- s2=self.mkbg(t)
- cr.save()
- cr.set_source_surface(s2, 0, 0)
- cr.paint()
- cr.restore()
-
- # If there is no icon then don't do anything more
- if self.icon!=None:
- # Get the icon as a surface (get_sicon() will cache the surface)
- sicon=self.get_sicon()
-
- # Width is the iconsize plus the empty border around the icon
- #w=self.config.iconsize + self.config.iconspace
-
- # This is used to locate the center of the surface
- dx=int(w/2)
-
- # This is the delta from the center where icons are drawn
- dx2=int(self.config.iconsize/2)
-
-# cr.save()
-
- # A transformation matrix with dx/dy set to point to the center
- m=cairo.Matrix(1, 0, 0, 1, dx, dx)
- cr.set_matrix(m)
- # Transform degrees to rads
- rot=-1 * pi * 2 * self.angle / 360
- cr.rotate(rot)
- # Draw the icon
- cr.set_source_surface(sicon, -dx2, -dx2) # Faster than pixbuf
-# cr.set_source_pixbuf(icon2, -dx2, -dx2)
- cr.paint()
-
-# cr.restore()
-
- if not pressed:
- self.cached_icons[angle]=s
-
- return(s)
-
-
- def draw(self, cr, x, y):
- self.draw_queued=False
- self.x=x
- self.y=y
-
- if self.icon==None and not self.isconfig:
- return
-
- cr.save()
- s=self.get_paint_icon()
- cr.set_source_surface(s, x, y)
- cr.paint()
-
- cr.restore()
-
- return(False)
-
- def timerPressed(self):
-# if not self.ispressed:
-# return(False)
-
- self.invalidate()
-
- if self.timePressed()>self.presstime:
- ret=False
- else:
- ret=True
-
- return(ret)
-
- def doPress(self):
- # Double-time: time for pressed and time for not-pressed
- if time.time() - self.lastpress > self.presstime*2:
- self.clickcount=0
-
- self.lastpress=time.time()
- self.ispressed=True
- gobject.timeout_add(20, self.timerPressed)
-
- def doRelease(self):
- dt=time.time() - self.lastpress
- self.ispressed=False
- self.invalidate()
- if dt<=self.presstime:
- self.clickcount+=1
- if self.clickcount==1:
- self.emit('click')
-# print "emit click", self
- elif self.clickcount==2:
- self.emit('double-click')
- if self.clickcount==3:
- self.emit('tripple-click')
- self.clickcount=0
- elif dt>self.presstime and dt<2:
- self.emit('long-press')
-# print "Emit lp"
-
- def doCancel(self):
- self.ispressed=False
-
- def setWindow(self, window):
- self.window_=window
-
- def invalidate(self, window=None):
- if window==None:
- window=self.window_
- else:
- self.window_=window
-
- if window==None:
- return
-
- if self.draw_queued:
-# print "queued"
- return
-
- self.draw_queued=True
- w=self.getSize()
- rect=gdk.Rectangle(self.x, self.y, w, w)
- gdk.Window.invalidate_rect(window, rect, True)
-
-#gobject.type_register(Icon)
-#signals=['click', 'double-click', 'tripple-click', 'long-press']
-#for s in signals:
-# gobject.signal_new(s, Icon, gobject.SIGNAL_RUN_FIRST | \
-# gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ())
-
-# vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
-