--- /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
+#from xdg.IconTheme import getIconPath
+
+from config import dump
+import apps
+import icon
+from icon import Icon
+from icons import Icons
+
+#def getIcon(name, iconsize):
+# ico=getIconPath(name, iconsize)
+# ret=gtk.gdk.pixbuf_new_from_file_at_size(ico, iconsize, iconsize)
+#
+# return(ret)
+
+# IconGrid is the main class that implements tha drawing of the grid
+# However, since it will be used both by the desktop plugin and the
+# configuration window, it cannot derive either gtk.Widget or HomePluginItem.
+# It is created here in a way that will allow it to work on both cases
+# and it is inherited by appropriate classes (one for the plugin and one
+# for the config widget)
+
+#class IconGrid(gtk.Widget, FremantleRotation):
+class IconGrid: #(gobject.GObject):
+ def __init__(self, isconfig=False):
+# self.__gobject_init__()
+# gtk.Widget.__init__(self)
+
+ self.init_done=False
+
+ self.size=(0,0)
+
+ self.isconfig=isconfig
+
+ self.icons=None
+ self.lasticon=None # The last icon that got selected
+
+ self.draw_pending=False
+
+ self.mode=None
+
+ # If this is False then animations are forcefully disabled
+ self.do_animations=True
+
+ self.angle_timer_start=0
+
+ # Duration of the rotation effect
+ self.rotation_time=0.8
+
+# print "ig-init"
+
+# def __del__(self):
+# print "ig-del"
+
+ def do_realize(self, config):
+# print "ig-realize"
+ self.config=config
+
+ if self.icons!=None:
+ print
+ print
+ print
+ print "WTF??????????????????????"
+ print
+ print
+ print
+
+ self.icons=Icons(self.isconfig, self.config)
+ #print "self:", self
+ #self.icons.set_parent(self)
+ self.setMode('l')
+ self.setSize(config.getMaxSize())
+ self.reloadIcons()
+
+ def do_unrealize(self):
+# print "ig-unrealize"
+ self.config=None
+ self.icons.finish()
+ self.icons=None
+ self.lasticon=None
+
+ def connect(self, what, *args):
+ if what in Icon.gsignals.keys():
+ ret=self.icons.connect(what, *args)
+ else:
+ ret=gobject.GObject.connect(self, what, *args)
+ #ret=super(IconGrid, self).connect(what, *args)
+
+ return(ret)
+
+ def setSize(self, size):
+ self.size=size
+ self.icons.setSize(size)
+
+ def getSize(self):
+ ret=self.icons.getSize()
+ return(ret)
+
+ def setMode(self, mode):
+ if self.mode==mode:
+# print "same mode"
+ return
+
+ self.mode=mode
+ if not isinstance(self, gtk.Widget):
+ return
+
+ do_draw=False
+
+ try:
+ v=self.get_property('is-on-current-desktop')
+ if v:
+ do_draw=True
+ else:
+ self.draw_pending=True
+ except TypeError:
+ do_draw=True
+
+ if do_draw and self.config.getAnimate() and self.do_animations:
+ #self.queue_draw()
+ # Don't start another timer
+ # Instead adjust the time start to produce a nice effect ;-)
+ if self.angle_timer_start==0:
+ self.angle_timer_start=time.time()
+ gobject.timeout_add(20, self.timerAngle)
+ else:
+ dt=time.time()-self.angle_timer_start
+ da=90.0*dt/self.rotation_time
+
+ da2=90.0-da
+ dt2=da2*self.rotation_time/90.0
+ self.angle_timer_start=time.time()-dt2
+ else:
+ if self.mode=='l':
+ self.setAngle(0)
+ else:
+ self.setAngle(90)
+
+ if do_draw:
+ self.queue_draw()
+
+ def disableAnimation(self):
+ self.do_animations=False
+
+ def enableAnimation(self):
+ self.do_animations=True
+
+ def setAnimationEnable(self, value):
+ if value:
+ self.enableAnimation()
+ else:
+ self.disableAnimation()
+
+ def timerAngle(self):
+ if self.angle_timer_start==0:
+ self.angle_timer_start=time.time()-0.05
+
+ dt=time.time()-self.angle_timer_start
+
+ da=90.0*dt/self.rotation_time
+
+ if self.mode=='l':
+ angle=90-da
+ else:
+ angle=da
+
+ if angle>=90:
+ angle=90
+ ret=False
+ elif angle<0:
+ angle=0
+ ret=False
+ else:
+ ret=True
+
+ if self.setAngle(angle):
+ self.queue_draw()
+
+ if ret==False:
+ self.angle_timer_start=0
+
+ return(ret)
+
+ def iconAt(self, x, y):
+ """ Get icon at coordinates x,y. X and Y are in pixels """
+
+ w=self.config.getIconSizeFull()
+
+ if self.mode=='l' or self.config.getIndiv():
+ x2=int(x / w)
+ y2=int(y / w)
+ else:
+ x2=self.size[1] - int(y/w) - 1
+ y2=int(x/w)
+
+ ret=self.get(x2,y2)
+
+ return(ret)
+
+ def get(self, x, y):
+ ret=self.icons.get(x,y)
+
+ return(ret)
+
+ def _draw(self, cr, event):
+ self.draw_pending=False
+
+ w=self.config.getIconSizeFull()
+ for x,y in self.icons:
+ if self.mode=='l' or self.config.getIndiv():
+ #x2=x * (self.config.iconsize + self.config.iconspace)
+ #y2=y * (self.config.iconsize + self.config.iconspace)
+ x2=x * self.config.getIconSizeFull()
+ y2=y * self.config.getIconSizeFull()
+ else:
+ #x2=y * (self.config.iconsize + self.config.iconspace)
+ #y2=(self.size[1]-x-1) * \
+ # (self.config.iconsize + self.config.iconspace)
+ x2=y * self.config.getIconSizeFull()
+ y2=(self.size[1]-x-1) * self.config.getIconSizeFull()
+
+ # Only repaint the needed icons
+ rect=gdk.Rectangle(x2, y2, w, w)
+ t=rect.intersect(event.area)
+ if t.width==0 and t.height==0:
+ continue
+
+ ico=self.icons.get(x,y)
+ ico.draw(cr, x2, y2)
+
+ def setAngle(self, angle):
+ """ Return True/False indicating that angle has changed """
+ ret=False
+ for x,y in self.icons:
+ ic=self.icons.get(x,y)
+ if ic.setAngle(angle):
+ ret=True
+
+ return(ret)
+
+ def clearAnimationCache(self):
+ """ Clear animation cache, freeing memory """
+ for x,y in self.icons:
+ ic=self.icons.get(x,y)
+ ic.clearAnimationCache()
+
+ def clearBgCache(self):
+ """ Clear backgrounds cache """
+ for x,y in self.icons:
+ ic=self.icons.get(x,y)
+ ic.clearBgCache()
+
+ def do_expose_event(self, event):
+ cr=self.window.cairo_create()
+
+ cr.rectangle(event.area.x, event.area.y,
+ event.area.width, event.area.height)
+
+ cr.clip()
+
+ if not self.init_done:
+ self.icons.setWindow(self.window)
+ self.init_done=True
+
+ self._draw(cr, event)
+
+ def setLastIcon(self, icon):
+ if icon==self.lasticon:
+ return
+
+ if self.lasticon!=None:
+ self.lasticon.doCancel()
+ self.lasticon.invalidate(self.window)
+ self.lasticon=icon
+
+ def do_button_press_event(self, event):
+ icon=self.iconAt(event.x, event.y)
+ if icon==None:
+ return
+# rect=gdk.Rectangle(event.x,event.y,1,1)
+# rect=gdk.Rectangle(0, 0, 100, 100)
+ icon.doPress()
+ icon.invalidate(self.window)
+ self.setLastIcon(icon)
+
+# gdk.Window.invalidate_rect(self.window, rect, True)
+
+ return(True)
+
+ def do_button_release_event(self, event):
+ if self.lasticon!=None:
+ self.lasticon.invalidate(self.window)
+ self.lasticon.doRelease()
+
+ self.setLastIcon(None)
+
+ return(True)
+
+ def do_leave_notify_event(self, event):
+ self.setLastIcon(None)
+ return(True)
+
+ def do_pproperty_notify_event(self, event):
+ icon=self.iconAt(event.x, event.y)
+ if icon==None:
+ return
+ icon.doCancel()
+ icon.invalidate(self.window)
+ return(True)
+
+ def do_motion_notify_event(self, event):
+ icon=self.iconAt(event.x, event.y)
+ if self.lasticon==icon:
+ return(True)
+
+ self.setLastIcon(None)
+ icon.doCancel()
+ icon.invalidate(self.window)
+ return(True)
+
+ def do_button_press_event_old(self, event):
+ if event.type==gdk.BUTTON_PRESS:
+ if self.mode=='p':
+ self.setMode('l')
+ else:
+ self.setMode('p')
+ self.queue_draw()
+ return True
+
+ # For debugging
+ def do_event1(self, event):
+ print "event:", event, event.type
+
+ def reloadIcons(self):
+ self.icons.load()
+ self.lasticon=None
+
+# def on_orientation_changed(self, orientation):
+# print "orch:", orientation
+# o=orientation[0]
+# self.setMode(o)
+
+class IconGridWidget(IconGrid, gtk.Widget):
+ def __init__(self, isconfig, config, animation=True):
+ IconGrid.__init__(self, isconfig)
+ gtk.Widget.__init__(self)
+
+ # This must be called before do_realize
+ self.setAnimationEnable(animation)
+
+ self.config=config
+
+ IconGrid.do_realize(self, self.config)
+
+ self.setSize(self.size)
+
+# print "igw-init"
+
+# def __del__(self):
+# print "igw-del"
+
+ def setSize(self, size):
+ IconGrid.setSize(self, size)
+
+ w=self.size[0] * self.config.getIconSizeFull()
+ h=self.size[1] * self.config.getIconSizeFull()
+
+ self.set_size_request(w, h)
+
+ def reconfig(self):
+ self.clearBgCache()
+ self.clearAnimationCache()
+ self.reloadIcons()
+ self.setSize(self.size)
+ self.icons.resizeMax()
+ self.queue_draw()
+
+ def do_realize(self):
+# print "igw-realize"
+ screen=self.get_screen()
+ self.set_colormap(screen.get_rgba_colormap())
+ self.set_app_paintable(True)
+
+ self.set_flags(self.flags() | gtk.REALIZED)
+
+ self.window=gdk.Window(
+ self.get_parent_window(),
+ width=self.allocation.width,
+ height=self.allocation.height,
+ window_type=gdk.WINDOW_CHILD,
+ wclass=gdk.INPUT_OUTPUT,
+ event_mask=self.get_events() | gdk.EXPOSURE_MASK
+ | gdk.BUTTON_PRESS_MASK
+ | gdk.BUTTON_RELEASE_MASK
+ | gdk.BUTTON_MOTION_MASK
+ | gdk.POINTER_MOTION_MASK
+ | gdk.POINTER_MOTION_HINT_MASK
+ | gdk.ENTER_NOTIFY_MASK
+ | gdk.LEAVE_NOTIFY_MASK )
+
+ self.window.set_user_data(self)
+
+ # No matter what the pygtk widget demo says, this is NOT CORRECT!!!
+ # Don't call style.attach(self.window) or else the program will crash
+ # after some time! It seems that there is a style already.
+ # If we want to use the style the we use get_style() instead.
+ # This one was very hard to solve. Thanks to gnome2-globalmenu guys.
+ # It was solved by looking the commit 2666:
+ # see:
+ # svn diff -r2665:2666 http://gnome2-globalmenu.googlecode.com/svn/trunk
+ # which solved cse 490:
+ # http://code.google.com/p/gnome2-globalmenu/issues/detail?id=490
+# self.style.attach(self.window)
+ style=self.get_style()
+
+# style.set_background(self.window, gtk.STATE_NORMAL)
+ self.window.move_resize(*self.allocation)
+
+# self.pixmap, mask = gtk.gdk.pixmap_create_from_xpm_d(
+# self.window, self.style.bg[gtk.STATE_NORMAL], STAR_PIXMAP)
+
+# self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
+
+ #HomePluginItem.do_realize(self)
+
+# screen=self.get_screen()
+# self.set_colormap(screen.get_rgba_colormap())
+# self.set_app_paintable(True)
+
+ def do_unrealize(self):
+# print "igw-unrealize", self
+ IconGrid.do_unrealize(self)
+ self.window.destroy()
+ self.window.set_user_data(None)
+
+ def do_expose_event(self, event):
+ cr=self.window.cairo_create()
+
+ cr.rectangle(event.area.x, event.area.y,
+ event.area.width, event.area.height)
+ cr.clip()
+
+ style=self.get_style()
+ col=style.bg[gtk.STATE_NORMAL]
+ cr.set_source_color(col)
+ cr.paint()
+
+ IconGrid.do_expose_event(self, event)
+
+#gobject.type_register(IconGrid)
+gobject.type_register(IconGridWidget)
+
+
+# vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
+