root/branch/PreferencesWindow/umitPreferences/widgets/VTab.py @ 3667

Revision 3667, 10.3 kB (checked in by luis, 5 years ago)

VTab fixed expanded issue. Thanks to bart by reported

Line 
1# Copyright (C) 2008 Adriano Monteiro Marques.
2#
3# Author: Luis A. Bastiao Silva <luis.kop@gmail.com>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19
20import gtk
21import gobject
22import math
23
24
25from higwidgets.higcairodesign import cr_rectangule_curve
26
27
28
29"""
30
31ScrolledTab is a widget similar like tabs of Skype @ Windows
32
33Depends: cairo
34
35
36THANKS to: Marcelo Lira
37
38"""
39
40class IconScroller(gtk.EventBox):
41    """
42    It's a toggle button that no use gtk.STATE_SELECTED/NORMAL
43    because it's cause some troubles in Mac OSX
44    It's a try to make a simulation gtk.STATE_SELECTED
45   
46   
47    Note: following gtk+ engine team gtk.Style and gtk.gdk.Window
48    is old schoo api (Thanks dx for information)
49    """
50
51    __gsignals__ = {
52        'changed':  (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
53                     (gobject.TYPE_INT, )),
54    }
55
56   
57    def __init__(self, name, image, items = None ):
58        gtk.EventBox.__init__(self)
59        self.add_events(self.get_events() | gtk.gdk.BUTTON_MOTION_MASK|\
60                        gtk.gdk.ENTER_NOTIFY_MASK |\
61                        gtk.gdk.LEAVE_NOTIFY_MASK |\
62                        gtk.gdk.BUTTON_MOTION_MASK|\
63                        gtk.gdk.POINTER_MOTION_MASK )
64       
65        #self.connect('motion-notify-event', self._mouse_move)
66        self.item_list = [] 
67        self.items = items
68        self.vbox = gtk.VBox()
69        self.hbox = gtk.HBox()
70        self.__handler_id = self.connect("expose-event", self.cb)
71        label = gtk.Label('<b>%s</b>' % name)
72        label.set_use_markup(True)
73        self.label = label
74        self.image = gtk.Image()
75        self.image.set_from_file(image)
76        self.hbox.pack_start(self.image, False, False)
77        self.hbox.pack_start(label, False, False)
78        self.hbox.set_spacing(10)
79        self.vbox.pack_start(self.hbox, False, False)
80        self.add(self.vbox)
81        self.__enable = True 
82        self.__name = name
83        self.__toggle = True
84       
85       
86        self.expanded = False
87       
88        # -1 means something like None. it's y coord
89        self.over = -1 
90       
91        self.background_color = [0,0,0,1]
92       
93        self.__size = None 
94        self.__items = 0
95        self.__ibox = gtk.VBox()
96        self.vbox.pack_start(self.__ibox, True, True)
97        self.vbox.set_spacing(5)
98       
99       
100        #####################################
101        # Append items
102        if items!=None:
103            for item in items:
104                if item.has_key('image'):
105                    i = item['image']
106                else:
107                    i = None 
108                self.append_item(item['name'], i)
109       
110    def cb(self, w,e):
111        """ Hide items - first time """
112       
113        #for i in self.item_list:
114        #    i['box'].hide_all()
115        self.expand()
116        self.disconnect(self.__handler_id)
117    def append_item(self, name, image):
118        """
119        Append item (when icon open)
120        """
121        hbox = gtk.HBox()
122        hbox.set_border_width(4)
123       
124        label = gtk.Label('<b>%s</b>' % name)
125        label.set_use_markup(True)
126        img = gtk.Image()
127       
128        hbox.pack_start(img, False, False)
129        hbox.pack_start(label, False, False)
130        if image!= None:
131            img.set_from_file('%s' % image) 
132            hbox.set_spacing(10)
133        else:
134           
135            hbox.set_spacing(26)
136           
137       
138        self.__ibox.pack_start(hbox,True, True)
139        hbox.hide_all()
140        label.hide_all()
141        img.hide_all()
142       
143        self.item_list.append({'name': name, 
144                               'image':image, 
145                               'label':label, 
146                               'img':img,
147                               'box': hbox})
148       
149        self.__items = self.__items + 1 
150   
151    def do_realize(self):
152        """ build window """
153        gtk.EventBox.do_realize(self)
154        self.set_flags(self.flags() | gtk.REALIZED)
155        #self.draw(self.__enable)
156       
157
158    def draw(self, selected):
159        """
160        Draw label selected or normal
161        @param selected: bool if selected or not changed draw color
162       
163        """
164        # Create window
165        cr = self.window.cairo_create()
166       
167        # Get sizes
168        alloc = self.allocation
169        x = alloc.x
170        y = alloc.y
171        height = alloc.height
172        width = alloc.width
173       
174        cr_rectangule_curve(cr, 0,0,width, height, 20)
175        color = gtk.gdk.Color(int(math.pow(2, 16) * 250 / 255), \
176                              int(math.pow(2,16) * 250 / 255), \
177                              int(math.pow(2,16) * 220 / 255), \
178                              0)
179       
180        state = gtk.STATE_NORMAL
181        color = self.get_style().base[state]
182        # Parse colors
183        cr.set_source_color(color)
184
185        cr.fill()
186        #cr.set_source_rgba(210/255.0,230/255.0,110/250.0,1)
187       
188        state = gtk.STATE_SELECTED
189        color = self.get_style().base[state]
190        cr.set_source_color(color)
191        cr_rectangule_curve(cr, 0, 0, width, height, 20)
192        cr.stroke()
193
194       
195        # Mouse over - event
196       
197        if self.__size!=None and self.over!= -1 :
198           
199            # Get sizes
200            alloc = self.allocation
201            width = alloc.width       
202           
203            h = self.__size[1]*self.number_item(self.over)
204            cr_rectangule_curve(cr, 2,h ,width-3, self.__size[1], 20)
205            state = gtk.STATE_SELECTED
206            color = self.get_style().base[state]
207            # Parse colors
208            cr.set_source_color(color)
209   
210            cr.fill()   
211    def _mouse_over(self, event):
212        """
213        Mouse over
214        """
215        self.over = event.y
216   
217       
218       
219       
220    def do_size_allocate(self, allocation):
221        '''Resizes the window'''
222        gtk.EventBox.do_size_allocate(self, allocation)
223       
224        self.allocation = allocation
225
226       
227        if self.flags() & gtk.REALIZED:
228            self.window.move_resize(*allocation)
229           
230    def expand(self):
231        x = self.get_size_request()
232
233        if not self.expanded:
234           
235            # FIXME
236            self.__size = self.get_size_request()
237            if x[1] >=(self.__items+1)*self.__size[1]:
238                return 
239            gobject.timeout_add(10, self._animate_show)
240            self.queue_draw()
241            self.__enable = not self.__enable
242           
243        else:
244            gobject.timeout_add(10, self._animate_hide)
245            self.queue_draw()
246            self.__enable = not self.__enable
247       
248        self.expanded= not self.expanded       
249    def _animate_show(self):
250        x = self.get_size_request()
251        if x[1] >(self.__items+1)*self.__size[1]:
252            return 
253        h_resize = x[1]+self.__size[1]/5
254        if h_resize> (self.__items+1)*self.__size[1]:
255            h_resize = (self.__items+1)*self.__size[1]
256        self.set_size_request(x[0], h_resize)
257        if x[1]+self.__size[1]/5 < self.__size[1] * (self.__items+1) :
258            return True
259        else:
260            return False
261
262    def _animate_hide(self):
263        x = self.get_size_request()
264
265        self.set_size_request(x[0], x[1]-self.__size[1]/5)
266        if x[1]-self.__size[1]/5 > self.__size[1] :
267            return True
268        else:
269            return False
270 
271
272    def do_expose_event(self, event):
273        """
274        Render widget
275        """
276
277        gtk.EventBox.do_expose_event(self, event)
278        self.draw(self.__enable)
279        self.propagate_expose(self.vbox, event)
280    def do_button_press_event(self, event):
281        """
282        Enable / Disable label - change color
283        """
284        if event.type == 5:
285            return 
286        if (not self.expanded or ( self.__size != None \
287           and self.__size[1] > event.y)) and self.items!=None:
288            self.expand()
289        for i in self.item_list:
290            if self.expanded:
291                i['box'].show_all()
292            else:
293                i['box'].hide_all()
294        self.queue_draw()
295        self.emit('changed', self.number_item(event.y))
296       
297    def do_button_release_event(self, event):
298        if self.expanded:
299            return 
300    def do_leave_notify_event(self, event):
301        """
302        Leave notify: put old colour
303        """
304        self.draw(self.__enable)
305        self.over = -1 
306        self.queue_draw()
307       
308    def do_motion_notify_event(self, event):
309
310        if not self.expanded or ( self.__size != None \
311           and self.__size[1] > event.y):
312            self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
313        else:
314            self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
315           
316        self._mouse_over(event)
317        self.queue_draw()
318    def do_enter_notify_event(self, event):
319       
320        """
321        Enter notify event: when activate change colour and change over text
322        """
323        self.draw(self.__enable)
324
325        if not self.expanded or ( self.__size != None \
326           and self.__size[1] > event.y):
327            self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
328        else:
329            self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
330        self.queue_draw()
331    def get_name(self):
332        return self.__name
333   
334    def number_item(self, y):
335        if self.__size==None:
336            return 0 
337        return int(y/self.__size[1]) 
338       
339   
340gobject.type_register(IconScroller)
341
342
343#def main():
344    #w = gtk.Window()
345    ##vbox = box()
346    #vbox = gtk.VBox()
347    #w.add(vbox)
348    #t1 = IconScroller(w, 'l')
349    #t2 = IconScroller(w, 'l')
350    #t1.set_size_request(100,24)
351    #t2.set_size_request(100,24)
352    #vbox.pack_start(t1)
353    #vbox.pack_start(t2)
354    #vbox.set_border_width(20)
355    #vbox.set_spacing(10)
356    #w.show_all()
357    #gtk.main()
358
359#if __name__=="__main__":
360    #main()
361
Note: See TracBrowser for help on using the browser.