source: zero-lliurex-flavours/trunk/fuentes/install-files/usr/share/lliurex-flavours-selector/lliurex-flavours-selector.py @ 2134

Last change on this file since 2134 was 2134, checked in by jrpelegrina, 3 years ago

Wip in new gui based in python

  • Property svn:executable set to *
File size: 18.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import gi
5gi.require_version('Gtk', '3.0')
6gi.require_version('PangoCairo', '1.0')
7
8import cairo
9import os
10import threading
11import ConfigParser
12import platform
13import subprocess
14import sys
15from math import pi
16
17from gi.repository import Gtk, Gdk, GObject, GLib, PangoCairo, Pango
18
19import signal
20signal.signal(signal.SIGINT, signal.SIG_DFL)
21
22
23import gettext
24gettext.textdomain('lliurex-flavours-selector')
25_ = gettext.gettext
26
27
28BASE_DIR="/usr/share/lliurex-flavours-selector/"
29RSRC_DIR=BASE_DIR+"rsrc/"
30SHADOW_BANNER=RSRC_DIR+"shadow.png"
31UNKNOWN_BANNER=RSRC_DIR+"unknown.png"
32BANNERS_PATH=BASE_DIR+"banners/"
33FLAVOURS_CONFIG_PATH=BASE_DIR+"supported-flavours/"
34
35CURRENT_PLATFORM=platform.machine()
36
37class GridButton:
38       
39        def __init__(self,info):
40               
41                self.info=info
42                self.info["installed"]=False
43                self.info["checked"]=False
44                self.info["shadow_alpha"]=0.1
45                self.info["animation_active"]=False
46                self.info["shadow_start"]=0
47                self.info["available"]=True
48                self.info["drawingarea"]=None
49               
50                if os.path.exists(BANNERS_PATH+self.info["pkg"]+".png"):
51                        self.info["image"]=BANNERS_PATH+self.info["pkg"]+".png"
52                else:
53                        self.info["image"]=UNKNOWN_BANNER
54               
55        #def init
56       
57       
58#class GridButton
59
60
61class ConfButton:
62       
63        def __init__(self,info):
64               
65                self.txt=info["txt"]
66                self.icon=info["icon"]
67                self.name=info["name"]
68                self.da=None
69                if "active" not in info:
70                        self.active=False
71                else:
72                        self.active=info["active"]
73               
74        #def
75
76#class ConfButton
77       
78       
79class ConfigurationParser:
80       
81        def __init__(self):
82                pass
83       
84        def load_plugin(self,path):
85       
86                try:
87                        config = ConfigParser.ConfigParser()
88                        config.optionxform=str
89                        config.read(path)
90                        if config.has_section("FLAVOUR"):
91                                info={}
92                                info["pkg"]=config.get("FLAVOUR","pkg")
93                                info["name"]=config.get("FLAVOUR","name")
94                               
95                                return GridButton(info)
96                               
97                except Exception as e:
98                        print e
99                        return None
100       
101       
102#class ConfigParser
103
104
105class CustomColor:
106       
107        def __init__(self,r,g,b):
108               
109                self.r=r/255.0
110                self.g=g/255.0
111                self.b=b/255.0
112
113#class CustomColor             
114
115class AwesomeTabs:
116       
117        def __init__(self):
118               
119                self.configuration_parser=ConfigurationParser()
120               
121                self.current_tab=-1
122                self.current_width=0
123                self.animation_left=False
124                self.animation_right=False
125               
126                self.current_red_width=0
127                self.current_red_pos=0
128                self.configuration_start=0
129               
130                self.first_run=True
131                self.update_alternatives=False
132               
133                self.current_grid_width=0
134                self.current_grid_height=0
135               
136                self.max_grid_width=2
137               
138                self.dark_gray=CustomColor(130.0,151.0,161.0)
139                self.light_gray=CustomColor(185.0,195.0,195.0)
140               
141                self.green=CustomColor(74.0,166.,69.0)
142                self.light_green=CustomColor(88.0,208.0,86.0)
143               
144               
145                self.conf_light=CustomColor(49.0,55.0,66.0)
146                self.conf_dark=CustomColor(30.0,36.0,42.0)
147               
148                self.conf_light_shadow=CustomColor(107.0,116.0,137.0)
149                self.conf_dark_shadow=CustomColor(0,0,0)
150               
151                self.current_conf_height=0
152                self.conf_buttons=[]
153                self.start_gui()
154               
155               
156        #def __init__
157       
158       
159       
160        def start_gui(self):
161               
162                builder=Gtk.Builder()
163                builder.set_translation_domain('lliurex-flavours-selector')
164                glade_path=RSRC_DIR+"lliurex-flavours-selector.ui"
165                builder.add_from_file(glade_path)
166               
167                self.installers_eb=builder.get_object("installers_eventbox")
168                self.installers_label=builder.get_object("installers_label")
169               
170               
171                self.top_divider_da=builder.get_object("top_divider_drawingarea")
172                self.bottom_divider_da=builder.get_object("bottom_divider_drawingarea")
173                self.top_divider_da.connect("draw",self.draw_top_divider)
174                self.bottom_divider_da.connect("draw",self.draw_bottom_divider)
175               
176                self.button_scroll=builder.get_object("button_scrolledwindow")
177                self.main_box=builder.get_object("main_box")
178                self.apply_eb=builder.get_object("apply_eventbox")
179                self.apply_da=builder.get_object("apply_drawingarea")
180                self.apply_eb.connect("button-press-event",self.accept_clicked)
181                self.apply_da.connect("draw",self.draw_apply_button)
182                self.close_eb=builder.get_object("close_eventbox")
183                self.close_da=builder.get_object("close_drawingarea")
184                self.close_eb.connect("button-press-event",self.quit)
185                self.close_da.connect("draw",self.draw_close_button)
186                self.msg_label=builder.get_object("msg_label")
187               
188                self.stack = Gtk.Stack()
189                self.stack.set_transition_duration(1000)
190                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
191               
192                self.installers_grid=builder.get_object("button_grid")
193                               
194               
195               
196                self.stack.add_titled(self.button_scroll, "installers", "Installers")
197               
198               
199                self.main_box.add(self.stack)
200               
201                self.main_window=builder.get_object("main_window")
202               
203               
204                self.main_window.connect("destroy",self.quit)
205               
206               
207                self.progress_window=builder.get_object("progress_window")
208                self.pbar=builder.get_object("progressbar")
209                self.progress_window.set_transient_for(self.main_window)
210               
211                self.gather_window=builder.get_object("gather_window")
212                self.gather_pbar=builder.get_object("progressbar1")
213                self.progress_label=builder.get_object("progress_label")
214               
215                       
216                self.set_css_info()
217               
218                self.gather_window.show_all()
219                GLib.timeout_add(100,self.pulsate_gathering_info)
220               
221                self.t=threading.Thread(target=self.gather_info)
222                self.t.daemon=True
223                self.t.start()
224                self.install_metas=[]
225                self.update_metas=[]
226               
227                GObject.threads_init()         
228                Gtk.main()
229               
230        #def start_gui
231       
232        def gather_info(self):
233               
234                import time
235                base_apt_cmd="apt-cache policy "
236               
237                self.gbs=[]
238               
239                for item in sorted(os.listdir(FLAVOURS_CONFIG_PATH)):
240                        if os.path.isfile(FLAVOURS_CONFIG_PATH+item):
241                                gb=self.configuration_parser.load_plugin(FLAVOURS_CONFIG_PATH+item)
242                                if gb!=None:
243                                        sys.stdout.write("* Checking %s ...\t"%gb.info["pkg"])
244                                        gb.info["installed"]=self.is_installed(gb.info["pkg"])
245                                        sys.stdout.write("%s\n"%gb.info["installed"])
246                                        base_apt_cmd += "%s "%gb.info["pkg"]
247                                        self.gbs.append(gb)
248                                       
249                p=subprocess.Popen([base_apt_cmd],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)     
250                output=p.communicate()
251               
252                for gb in self.gbs:
253                       
254                        if gb.info["pkg"] not in output[0]:
255                                print(" [!] %s not available [!] "%gb.info["pkg"])
256                                gb.info["available"]=False
257                        else:   
258                                self.add_grid_button(gb)       
259                               
260               
261
262       
263        #def gather_info
264       
265        def pulsate_gathering_info(self):
266               
267                self.gather_pbar.pulse()
268               
269                if not self.t.is_alive():
270                       
271                        self.gather_window.hide()
272                        self.main_window.show_all()
273               
274                return self.t.is_alive()
275               
276        #def pulsate_gathering
277       
278        def set_css_info(self):
279               
280                css = """
281               
282                #BLUE {
283                        background-image:-gtk-gradient (linear, left top, left bottom, from (#0f72ff),  to (#0f72ff));;
284               
285                }
286               
287                #BLACK{
288                        background-image:-gtk-gradient (linear, left top, left bottom, from (#000000),  to (#000000));;
289               
290                }
291               
292               
293                #BACK_GRADIENT{
294                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ffffff), to (#eceff3));;
295                }
296               
297                #WHITE {
298                        color: white;
299                        text-shadow: 0px 1px black;
300                }
301               
302                #MAIN_LABEL_ENABLED{
303                        color: #8297a1;
304                        font: Noto Sans Bold 18;
305                }
306               
307                #ALTERNATIVES_LABEL{
308                        color: #8297a1;
309                        font: Noto Sans Bold 12;               
310                }
311               
312                #MAIN_LABEL_DISABLED{
313                        color: #c9d4e2;
314                        font: Noto Sans Bold 18;
315                }
316               
317                #RED_PROGRESS{
318                       
319                        background-color: #FF0000;
320                        border: 0px;
321
322                }
323               
324                #DARK_BACK{
325                        background-color: #070809;
326                }
327               
328                #GREEN {
329                        background-image:-gtk-gradient (linear, left top, left bottom, from (#41ff70),  to (#41ff70));;
330               
331                }
332               
333                #ORANGE {
334                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ff7f2a),  to (#ff7f2a));;
335               
336                }
337               
338                #LIGHTBLUE {
339                        -unico-border-gradient: -gtk-gradient (linear, left top, left bottom,
340                        from (shade (#ff0000, 0.68)),
341                        to (shade (#ff0000, 0.68)));
342               
343                }
344               
345                #RED_LABEL{
346                       
347                        color: red;
348                        font: Noto Sans Bold 12;
349                }
350
351               
352                GtkButton#RED GtkLabel {
353                        color: #8297a1;
354                        font: Noto Sans 11;
355                }
356
357
358                """
359                self.style_provider=Gtk.CssProvider()
360                self.style_provider.load_from_data(css)
361                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
362               
363                self.main_window.set_name("BACK_GRADIENT")
364                self.installers_label.set_name("MAIN_LABEL_ENABLED")
365                self.pbar.set_name("RED_PROGRESS")
366                self.gather_pbar.set_name("RED_PROGRESS")
367                self.progress_label.set_name("ALTERNATIVES_LABEL")
368                self.msg_label.set_name("RED_LABEL")
369               
370               
371        #def css_info
372
373        def is_installed(self,pkg):
374               
375               
376                p=subprocess.Popen(["dpkg-query -W -f='${db:Status-Status}' %s"%pkg],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
377                output=p.communicate()
378               
379                if output[0]=="installed":
380                        return True
381                       
382                return False
383               
384               
385        #def is_installed
386       
387        def quit(self,widget,event=None):
388               
389                Gtk.main_quit()
390               
391        #def quit
392       
393        def execute(self,command):
394               
395                self.thread_ret=-1
396                self.thread_ret=os.system(command)
397               
398        #def execute
399       
400       
401        def pulsate_pbar(self,da):
402               
403                if self.t.is_alive():
404                       
405                        self.pbar.pulse()
406                               
407                if not self.t.is_alive():
408                        self.progress_window.hide()
409                        if self.thread_ret==0:
410                                for item in self.install_metas:
411                                        print item
412                                        if item.info["checked"]:
413                                                item.info["checked"]=False
414                                                item.info["drawingarea"].queue_draw()
415                                                self.mouse_left(item.info["drawingarea"],None,item)
416                                               
417                                        item.info["installed"]=True
418                                self.install_metas=[]   
419                                self.msg_label.show()
420                                self.msg_label.set_markup("<span foreground='#4aa645'>"+_("Installation succesful. A reboot is required")+"</span>")
421                        else:
422                                self.msg_label.show()
423                                msg=_("An error ocurred during installation")
424                                self.msg_label.set_markup(msg) 
425                return self.t.is_alive()
426       
427        #def pulsate_pbar
428
429       
430       
431               
432        def add_grid_button(self,grid_button):
433               
434                da=Gtk.DrawingArea()
435                da.set_size_request(140,148)
436                da.add_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK | Gdk.EventMask.BUTTON_PRESS_MASK )
437               
438                da.connect("draw",self.draw_button,grid_button)
439                da.connect("motion-notify-event",self.mouse_over,grid_button)
440                da.connect("leave_notify_event",self.mouse_left,grid_button)
441                da.connect("button-press-event",self.button_clicked,grid_button)
442                grid_button.info["drawingarea"]=da
443               
444                da.show()
445                self.installers_grid.attach(da,self.current_grid_width,self.current_grid_height,1,1)
446               
447                self.current_grid_width+=1
448               
449                if self.current_grid_width > self.max_grid_width:
450                        self.current_grid_width=0
451                        self.current_grid_height+=1
452                       
453                       
454        #def add_grid_button
455       
456       
457        def button_clicked(self,widget,event,grid_button):
458               
459                if not grid_button.info["installed"]:
460                        if grid_button.info["checked"]:
461                                self.install_metas.remove(grid_button)
462                                grid_button.info["checked"]=False
463                        else:
464                                self.install_metas.append(grid_button)
465                                grid_button.info["checked"]=True
466                                grid_button.info["shadow_alpha"]+=0.1
467                               
468                                widget.queue_draw()
469               
470        #def button_clicked
471       
472       
473        def accept_clicked(self,widget,even=None):
474                ret, msg=self.check_meta_compatibility()
475               
476                if not ret:
477                        self.msg_label.show()
478                        self.msg_label.set_markup(msg)
479                        return
480               
481                self.msg_label.hide()           
482                cmd='apt-get update && apt-get install -y '
483                pkg=""
484                for item in self.update_metas:
485                        pkg+=item.info["pkg"] + ' '
486                       
487                for item in self.install_metas:
488                        pkg+=item.info["pkg"] + ' '
489                               
490                command=cmd+pkg
491                print command
492                command='apt-get update'
493                self.t=threading.Thread(target=self.execute,args=(command,))
494                self.t.daemon=True
495                self.t.start()
496                GLib.timeout_add(100,self.pulsate_pbar,widget)
497                self.progress_window.show()
498               
499               
500        def check_meta_compatibility(self):
501                               
502                if len(self.install_metas)>0:
503                       
504                        for gb in self.gbs:
505                                if gb.info["available"]:
506                                        if gb.info["installed"]:
507                                                if not gb in self.update_metas:
508                                                        self.update_metas.append(gb)
509                                                       
510                                                if gb.info["pkg"]=="lliurex-meta-server":
511                                                        for item in self.install_metas:
512                                                                if item.info["pkg"]=="lliurex-meta-client":
513                                                                        return [False,_("Incompatibility between Server and Client detected")]
514                                                                                                                                               
515                                                                if item.info["pkg"]=="lliurex-meta-desktop":
516                                                                        return [False, _("Is not possible adding Desktop Flavour in Server")]   
517                                                                       
518                                                if gb.info["pkg"]=="lliurex-meta-client":
519                                                        for item in self.install_metas:
520                                                                if item.info["pkg"]=="lliurex-meta-server":
521                                                                        return [False,_("Incompatibility between Server and Client detected")]
522                                               
523                                                if gb.info["pkg"]=="lliurex-meta-desktop":
524                                                        for item in self.install_metas:
525                                                                if item.info["pkg"]=="lliurex-meta-server":
526                                                                        if  gb in self.update_metas:
527                                                                                self.update_metas.append(gb)                   
528                                       
529                        j=0
530                        for item in self.install_metas:
531                                if item.info["pkg"]=="lliurex-meta-server" or item.info["pkg"]=="lliurex-meta-client":
532                                        j+=1
533                               
534                               
535                        if j>1:
536                                return [False,_("Incompatibility between Server and Client detected")]
537                                                               
538                               
539                        return [True,""]
540                       
541                else:
542                        return [False,_("Choose new flavour to incorporate or close button")]
543                       
544        #def check_meta_compatibility
545                               
546        def draw_button(self,widget,ctx,grid_button):
547               
548                ctx.move_to(0,0)
549                img=cairo.ImageSurface.create_from_png(SHADOW_BANNER)
550                ctx.set_source_surface(img,0,grid_button.info["shadow_start"])
551                ctx.paint_with_alpha(grid_button.info["shadow_alpha"])
552               
553                ctx.move_to(0,0)
554                img=cairo.ImageSurface.create_from_png(grid_button.info["image"])
555                ctx.set_source_surface(img,0,0)
556                ctx.paint()
557               
558                ctx.move_to(0,0)
559                ctx.set_source_rgba(1,1,1,1)
560                ctx.rectangle(0,110,140,30)
561                ctx.fill()
562               
563               
564                ctx.set_source_rgba(self.dark_gray.r,self.dark_gray.g,self.dark_gray.b,1)
565               
566                pctx = PangoCairo.create_layout(ctx)
567                desc = Pango.font_description_from_string ("Noto Sans Bold 8")
568                pctx.set_font_description(desc)
569                pctx.set_markup(grid_button.info["name"])
570                ctx.move_to(5,118)
571                PangoCairo.show_layout(ctx, pctx)
572                width=pctx.get_pixel_size()[0]
573               
574               
575               
576                if grid_button.info["installed"]:
577               
578                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
579                        pctx.set_font_description(desc)
580                        ctx.set_source_rgba(self.green.r,self.green.g,self.green.b,1)
581                        txt=_("Installed")
582                        pctx.set_markup(txt)
583                        width=pctx.get_pixel_size()[0]
584                        ctx.move_to(140-width-5,120)
585                        PangoCairo.show_layout(ctx, pctx)
586                       
587                        ctx.rectangle(5,139,130,1)
588                        ctx.fill()
589               
590                if grid_button.info["checked"]:
591               
592                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
593                        pctx.set_font_description(desc)
594                        ctx.set_source_rgba(self.green.r,self.green.g,self.green.b,1)
595                        txt=_("Install")
596                        pctx.set_markup(txt)
597                        width=pctx.get_pixel_size()[0]
598                        ctx.move_to(140-width-5,120)
599                        PangoCairo.show_layout(ctx, pctx)
600                       
601                        ctx.rectangle(5,139,130,1)
602                        ctx.fill()
603               
604        #def draw_button
605       
606       
607        def drawing_label_event(self,widget,ctx,id):
608               
609                if id==self.current_tab:
610
611                        lg1 = cairo.LinearGradient(0.0,0.0, 300.0, 3.0)
612                        lg1.add_color_stop_rgba(0, 0, 1, 1, 0)
613                        lg1.add_color_stop_rgba(0.5, 0, 1, 1, 1)
614                        lg1.add_color_stop_rgba(1, 0, 1, 1, 0)
615                        ctx.rectangle(0, 0, 300, 3)
616                        ctx.set_source(lg1)
617                        ctx.fill()
618                       
619        #drawing_label_event
620       
621       
622        def draw_apply_button(self,widget,ctx):
623               
624               
625                button_border=22
626               
627                pctx = PangoCairo.create_layout(ctx)
628                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
629                pctx.set_font_description(desc)
630               
631                pctx.set_markup(_("APPLY"))
632                width=pctx.get_pixel_size()[0]
633                widget.set_size_request(width+button_border*2,30)
634               
635                ctx.set_source_rgba(1,1,0,1)
636                xx=0
637                yx=0
638                widthx=width+44
639                heightx=30
640                radius=5
641               
642                r=47.0
643                g=167.0
644                b=223.0
645                alpha=1.0
646               
647                r=r/255.0
648                g=g/255.0
649                b=b/255.0
650               
651                r2=83
652                g2=153
653                b2=252
654               
655                r2=r2/255.0
656                g2=g2/255.0
657                b2=b2/255.0
658               
659               
660                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
661                lg1.add_color_stop_rgba(0, r, g, b, 1)
662                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
663                ctx.set_source(lg1)
664               
665               
666                ctx.move_to (xx + radius, yx);
667                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
668                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
669                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
670                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
671                ctx.fill ();
672               
673                ctx.set_source_rgb(0.9,0.9,0.9)
674                ctx.move_to(button_border,7)
675                PangoCairo.show_layout(ctx, pctx)
676       
677        #draw_apply_button
678       
679        def draw_close_button(self,widget,ctx):
680               
681               
682                button_border=22
683               
684                pctx = PangoCairo.create_layout(ctx)
685                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
686                pctx.set_font_description(desc)
687               
688                pctx.set_markup(_("CLOSE"))
689                width=pctx.get_pixel_size()[0]
690                widget.set_size_request(width+button_border*2,30)
691               
692                ctx.set_source_rgba(1,1,0,1)
693                xx=0
694                yx=0
695                widthx=width+44
696                heightx=30
697                radius=5
698               
699                r=47.0
700                g=167.0
701                b=223.0
702                alpha=1.0
703               
704                r=r/255.0
705                g=g/255.0
706                b=b/255.0
707               
708                r2=83
709                g2=153
710                b2=252
711               
712                r2=r2/255.0
713                g2=g2/255.0
714                b2=b2/255.0
715               
716               
717                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
718                lg1.add_color_stop_rgba(0, r, g, b, 1)
719                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
720                ctx.set_source(lg1)
721               
722               
723                ctx.move_to (xx + radius, yx);
724                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
725                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
726                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
727                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
728                ctx.fill ();
729               
730                ctx.set_source_rgb(0.9,0.9,0.9)
731                ctx.move_to(button_border,7)
732                PangoCairo.show_layout(ctx, pctx)
733               
734        #def draw_close_button
735
736       
737        def draw_top_divider(self,widget,ctx):
738               
739                r=self.dark_gray.r
740                g=self.dark_gray.g
741                b=self.dark_gray.b
742                alpha=1.0
743               
744                ctx.set_source_rgba(r,g,b,alpha)
745                ctx.rectangle(0,1,500,3)
746                ctx.fill()
747               
748               
749        #def draw_top_divider
750       
751       
752        def draw_bottom_divider(self,widget,ctx):
753               
754                r=self.dark_gray.r
755                g=self.dark_gray.g
756                b=self.dark_gray.b
757                alpha=1.0
758               
759                ctx.set_source_rgba(r,g,b,alpha)
760                ctx.rectangle(0,1,500,3)
761                ctx.fill()
762               
763        #def draw_bottom_divider
764       
765       
766        def mouse_over(self,widget,event,grid_button):
767               
768                grid_button.info["animation_active"]=False
769                if grid_button.info["shadow_alpha"] <0.5 :
770                        grid_button.info["shadow_alpha"]+=0.1
771                        widget.queue_draw()
772                        return True
773                       
774                return False
775               
776        #def mouse_over
777
778        def mouse_left(self,widget,event,grid_button):
779                if not grid_button.info["checked"]:
780                        if not grid_button.info["animation_active"]:
781                       
782                                grid_button.info["animation_active"]=True
783                                GLib.timeout_add(10,self.restore_shadow_alpha,grid_button,widget)
784                       
785        #def mouse_left
786
787       
788        def restore_shadow_alpha(self,grid_button,widget):
789               
790                if grid_button.info["shadow_alpha"] >0.2 :
791                        grid_button.info["shadow_alpha"]-=0.1
792               
793                        widget.queue_draw()
794                        return True
795                       
796                grid_button.info["animation_active"]=False
797                return False
798               
799        # def restore_shadow_alfpha     
800
801       
802#awesome tabs
803
804if __name__=="__main__":
805       
806        at=AwesomeTabs()
Note: See TracBrowser for help on using the repository browser.