Fixed resizing issue.
[drlaunch] / src / icongrid.py
1 #!/usr/bin/env python
2 # coding=UTF-8
3
4 # Copyright (C) 2010 Stefanos Harhalakis
5 #
6 # This file is part of wifieye.
7 #
8 # wifieye is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # wifieye is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with wifieye.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 # $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $
22
23 __version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $"
24
25 import gtk
26 import gobject
27 import hildon
28 from hildondesktop import *
29 from gtk import gdk
30 from math import pi
31 import cairo
32 import time
33
34 from portrait import FremantleRotation
35 #from xdg.IconTheme import getIconPath
36
37 #import config
38 import apps
39 import icon
40 from icon import Icon
41 from icons import Icons
42
43 #def getIcon(name, iconsize):
44 #    ico=getIconPath(name, iconsize)
45 #    ret=gtk.gdk.pixbuf_new_from_file_at_size(ico, iconsize, iconsize)
46 #
47 #    return(ret)
48
49 #class IconGrid(gtk.Widget, FremantleRotation):
50 class IconGrid(object): #(gobject.GObject):
51     def __init__(self, isconfig=False):
52 #       self.__gobject_init__()
53
54         self.size=(0,0)
55
56         self.isconfig=isconfig
57
58         self.icons=None
59         self.lasticon=None  # The last icon that got selected
60
61         self.draw_pending=False
62
63     def do_realize(self, config):
64         self.config=config
65
66         self.icons=Icons(self.isconfig, self.config)
67         self.setMode('l')
68         self.setSize((4,4))
69         self.reloadIcons()
70
71     def connect(self, what, *args):
72         if what in icon.signals:
73             self.icons.connect(what, *args)
74         else:
75             super(IconGrid, self).connect(what, *args)
76
77     def setSize(self, size):
78         self.size=size
79         self.icons.setSize(size)
80
81     def getSize(self):
82         ret=self.icons.getSize()
83         return(ret)
84
85     def setMode(self, mode):
86         self.mode=mode
87         if not isinstance(self, gtk.Widget):
88             return
89
90         try:
91             v=self.get_property('is-on-current-desktop')
92             if v:
93                 self.queue_draw()
94             else:
95                 self.draw_pending=True
96         except TypeError:
97             self.queue_draw()
98
99     def iconAt(self, x, y):
100         """ Get icon at coordinates x,y. X and Y are in pixels """
101
102         w=self.config.iconsize + self.config.iconspace
103
104         if self.mode=='l' or self.config.getIndiv():
105             x2=int(x / w)
106             y2=int(y / w)
107         else:
108             x2=self.size[1] - int(y/w) - 1
109             y2=int(x/w)
110
111         ret=self.get(x2,y2)
112
113         return(ret)
114
115     def get(self, x, y):
116         ret=self.icons.get(x,y)
117
118         return(ret)
119
120     def _draw(self, cr, event):
121         self.draw_pending=False
122
123         w=self.config.iconsize + self.config.iconspace
124         for x,y in self.icons:
125             if self.mode=='l' or self.config.getIndiv():
126                 x2=x * (self.config.iconsize + self.config.iconspace)
127                 y2=y * (self.config.iconsize + self.config.iconspace)
128             else:
129                 x2=y * (self.config.iconsize + self.config.iconspace)
130                 y2=(self.size[1]-x-1) * \
131                         (self.config.iconsize + self.config.iconspace)
132
133             # Only repaint the needed icons
134             rect=gdk.Rectangle(x2, y2, w, w)
135             t=rect.intersect(event.area)
136             if t.width==0 and t.height==0:
137                 continue
138
139             ico=self.icons.get(x,y)
140             ico.draw(cr, x2, y2, self.mode)
141
142     def do_expose_event(self, event):
143         cr=self.window.cairo_create()
144
145         cr.rectangle(event.area.x, event.area.y,
146             event.area.width, event.area.height)
147
148         cr.clip()
149
150         self._draw(cr, event)
151
152     def setLastIcon(self, icon):
153         if icon==self.lasticon:
154             return
155
156         if self.lasticon!=None:
157             self.lasticon.doCancel()
158             self.lasticon.invalidate(self.window)
159         self.lasticon=icon
160
161     def do_button_press_event(self, event):
162         icon=self.iconAt(event.x, event.y)
163         if icon==None:
164             return
165 #       rect=gdk.Rectangle(event.x,event.y,1,1)
166 #       rect=gdk.Rectangle(0, 0, 100, 100)
167         icon.doPress()
168         icon.invalidate(self.window)
169         self.setLastIcon(icon)
170
171 #       gdk.Window.invalidate_rect(self.window, rect, True)
172
173         return(True)
174
175     def do_button_release_event(self, event):
176         if self.lasticon!=None:
177             self.lasticon.invalidate(self.window)
178             self.lasticon.doRelease()
179
180         self.setLastIcon(None)
181
182         return(True)
183
184     def do_leave_notify_event(self, event):
185         self.setLastIcon(None)
186         return(True)
187
188     def do_pproperty_notify_event(self, event):
189         icon=self.iconAt(event.x, event.y)
190         if icon==None:
191             return
192         icon.doCancel()
193         icon.invalidate(self.window)
194         return(True)
195
196     def do_motion_notify_event(self, event):
197         icon=self.iconAt(event.x, event.y)
198         if self.lasticon==icon:
199             return(True)
200
201         self.setLastIcon(None)
202         icon.doCancel()
203         icon.invalidate(self.window)
204         return(True)
205
206     def do_button_press_event_old(self, event):
207         if event.type==gdk.BUTTON_PRESS:
208             if self.mode=='p':
209                 self.setMode('l')
210             else:
211                 self.setMode('p')
212             self.queue_draw()
213         return True
214
215     # For debugging
216     def do_event1(self, event):
217         print "event:", event, event.type
218
219     def reloadIcons(self):
220         self.icons.load()
221
222 #    def on_orientation_changed(self, orientation):
223 #       print "orch:", orientation
224 #       o=orientation[0]
225 #       self.setMode(o)
226
227 class IconGridWidget(IconGrid, gtk.Widget):
228     def __init__(self, isconfig, config):
229         IconGrid.__init__(self, isconfig)
230         gtk.Widget.__init__(self)
231
232         self.config=config
233
234         IconGrid.do_realize(self, self.config)
235
236         if isconfig:
237             maxsz=self.config.getMaxSize()
238             w=maxsz[0] * (self.config.iconsize + self.config.iconspace)
239             h=maxsz[1] * (self.config.iconsize + self.config.iconspace)
240         else:
241             w=self.size[0] * (self.config.iconsize + self.config.iconspace)
242             h=self.size[1] * (self.config.iconsize + self.config.iconspace)
243
244         self.set_size_request(w, h)
245
246     def do_realize(self):
247         screen=self.get_screen()
248         self.set_colormap(screen.get_rgba_colormap())
249         self.set_app_paintable(True)
250
251         self.set_flags(self.flags() | gtk.REALIZED)
252
253         self.window=gdk.Window(
254             self.get_parent_window(),
255             width=self.allocation.width,
256             height=self.allocation.height,
257             window_type=gdk.WINDOW_CHILD,
258             wclass=gdk.INPUT_OUTPUT,
259             event_mask=self.get_events() | gdk.EXPOSURE_MASK
260                 | gdk.BUTTON_PRESS_MASK 
261                 | gdk.BUTTON_RELEASE_MASK 
262                 | gdk.BUTTON_MOTION_MASK
263                 | gdk.POINTER_MOTION_MASK
264                 | gdk.POINTER_MOTION_HINT_MASK 
265                 | gdk.ENTER_NOTIFY_MASK
266                 | gdk.LEAVE_NOTIFY_MASK )
267
268         self.window.set_user_data(self)
269         self.style.attach(self.window)
270
271 #       self.style.set_background(self.window, gtk.STATE_NORMAL)
272         self.window.move_resize(*self.allocation)
273
274 #       self.pixmap, mask = gtk.gdk.pixmap_create_from_xpm_d(
275 #             self.window, self.style.bg[gtk.STATE_NORMAL], STAR_PIXMAP)
276         
277 #       self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
278
279         #gtk.Widget.do_realize(self)
280         #HomePluginItem.do_realize(self)
281
282 #       screen=self.get_screen()
283 #       self.set_colormap(screen.get_rgba_colormap())
284 #       self.set_app_paintable(True)
285
286     def do_unrealize(self):
287         #self.window.set_user_data(None)
288         self.window.destroy()
289
290 #gobject.type_register(IconGrid)
291 gobject.type_register(IconGridWidget)
292
293
294 # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
295