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

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

WIP

  • Property svn:executable set to *
File size: 18.7 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('zero-lliurex-flavours')
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('zero-lliurex-flavours')
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                GObject.threads_init()         
227                Gtk.main()
228               
229        #def start_gui
230       
231        def gather_info(self):
232               
233                import time
234                base_apt_cmd="apt-cache policy "
235               
236                self.gbs=[]
237                self.flavours_installed=0
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                                if gb.info["installed"]==True:
259                                        self.flavours_installed+=1     
260                                self.add_grid_button(gb)       
261                               
262               
263
264       
265        #def gather_info
266       
267        def pulsate_gathering_info(self):
268               
269                self.gather_pbar.pulse()
270               
271                if not self.t.is_alive():
272                       
273                        self.gather_window.hide()
274                        self.main_window.show_all()
275               
276                        if self.flavours_installed<1:
277                                msg=_("No flavour detected. Check one at least")
278                                self.msg_label.show()
279                                self.msg_label.set_markup(msg)
280                return self.t.is_alive()
281               
282        #def pulsate_gathering
283       
284        def set_css_info(self):
285               
286                css = """
287               
288                #BLUE {
289                        background-image:-gtk-gradient (linear, left top, left bottom, from (#0f72ff),  to (#0f72ff));;
290               
291                }
292               
293                #BLACK{
294                        background-image:-gtk-gradient (linear, left top, left bottom, from (#000000),  to (#000000));;
295               
296                }
297               
298               
299                #BACK_GRADIENT{
300                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ffffff), to (#eceff3));;
301                }
302               
303                #WHITE {
304                        color: white;
305                        text-shadow: 0px 1px black;
306                }
307               
308                #MAIN_LABEL_ENABLED{
309                        color: #8297a1;
310                        font: Noto Sans Bold 18;
311                }
312               
313                #ALTERNATIVES_LABEL{
314                        color: #8297a1;
315                        font: Noto Sans Bold 12;               
316                }
317               
318                #MAIN_LABEL_DISABLED{
319                        color: #c9d4e2;
320                        font: Noto Sans Bold 18;
321                }
322               
323                #RED_PROGRESS{
324                       
325                        background-color: #FF0000;
326                        border: 0px;
327
328                }
329               
330                #DARK_BACK{
331                        background-color: #070809;
332                }
333               
334                #GREEN {
335                        background-image:-gtk-gradient (linear, left top, left bottom, from (#41ff70),  to (#41ff70));;
336               
337                }
338               
339                #ORANGE {
340                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ff7f2a),  to (#ff7f2a));;
341               
342                }
343               
344                #LIGHTBLUE {
345                        -unico-border-gradient: -gtk-gradient (linear, left top, left bottom,
346                        from (shade (#ff0000, 0.68)),
347                        to (shade (#ff0000, 0.68)));
348               
349                }
350               
351                #RED_LABEL{
352                       
353                        color: red;
354                        font: Noto Sans Bold 11;
355                }
356
357               
358                GtkButton#RED GtkLabel {
359                        color: #8297a1;
360                        font: Noto Sans 11;
361                }
362
363
364                """
365                self.style_provider=Gtk.CssProvider()
366                self.style_provider.load_from_data(css)
367                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
368               
369                self.main_window.set_name("BACK_GRADIENT")
370                self.installers_label.set_name("MAIN_LABEL_ENABLED")
371                self.pbar.set_name("RED_PROGRESS")
372                self.gather_pbar.set_name("RED_PROGRESS")
373                self.progress_label.set_name("ALTERNATIVES_LABEL")
374                self.msg_label.set_name("RED_LABEL")
375               
376               
377        #def css_info
378
379        def is_installed(self,pkg):
380               
381               
382                p=subprocess.Popen(["dpkg-query -W -f='${db:Status-Status}' %s"%pkg],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
383                output=p.communicate()
384               
385                if output[0]=="installed":
386                        return True
387                       
388                return False
389               
390               
391        #def is_installed
392       
393        def quit(self,widget,event=None):
394               
395                Gtk.main_quit()
396               
397        #def quit
398       
399        def execute(self,command):
400               
401                self.thread_ret=-1
402                self.thread_ret=os.system(command)
403               
404        #def execute
405       
406       
407        def pulsate_pbar(self,da):
408               
409                if self.t.is_alive():
410                       
411                        self.pbar.pulse()
412                               
413                if not self.t.is_alive():
414                        self.progress_window.hide()
415                        if self.thread_ret==0:
416                                for item in self.install_metas:
417                               
418                                        if item.info["checked"]:
419                                                item.info["checked"]=False
420                                                item.info["drawingarea"].queue_draw()
421                                                self.mouse_left(item.info["drawingarea"],None,item)
422                                                item.info["installed"]=True
423                                try:
424                                        self.remove_desktop.info["checked"]=False
425                                        self.remove_desktop.info["drawingarea"].queue_draw()
426                                        self.mouse_left(self.remove_desktop.info["drawingarea"],None,self.remove_desktop)
427                                except:
428                                        print "No desktop flavour to remove"
429                                       
430                                self.install_metas=[]   
431                                self.msg_label.show()
432                                self.msg_label.set_markup("<span foreground='#4aa645'><b>"+_("Installation succesful. A reboot is required")+"</b></span>")
433                        else:
434                                self.msg_label.show()
435                                msg=_("An error ocurred during installation")
436                                self.msg_label.set_markup(msg) 
437                return self.t.is_alive()
438       
439        #def pulsate_pbar
440
441       
442       
443               
444        def add_grid_button(self,grid_button):
445               
446                da=Gtk.DrawingArea()
447                da.set_size_request(140,148)
448                da.add_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK | Gdk.EventMask.BUTTON_PRESS_MASK )
449               
450                da.connect("draw",self.draw_button,grid_button)
451                da.connect("motion-notify-event",self.mouse_over,grid_button)
452                da.connect("leave_notify_event",self.mouse_left,grid_button)
453                da.connect("button-press-event",self.button_clicked,grid_button)
454                grid_button.info["drawingarea"]=da
455               
456                da.show()
457                self.installers_grid.attach(da,self.current_grid_width,self.current_grid_height,1,1)
458               
459                self.current_grid_width+=1
460               
461                if self.current_grid_width > self.max_grid_width:
462                        self.current_grid_width=0
463                        self.current_grid_height+=1
464                       
465                       
466        #def add_grid_button
467       
468       
469        def button_clicked(self,widget,event,grid_button):
470               
471                if not grid_button.info["installed"]:
472                        if grid_button.info["checked"]:
473                                self.install_metas.remove(grid_button)
474                                grid_button.info["checked"]=False
475                        else:
476                                self.install_metas.append(grid_button)
477                                grid_button.info["checked"]=True
478                                grid_button.info["shadow_alpha"]+=0.1
479                               
480                                widget.queue_draw()
481               
482        #def button_clicked
483       
484       
485        def accept_clicked(self,widget,even=None):
486                ret, msg=self.check_meta_compatibility()
487               
488                if not ret:
489                        self.msg_label.show()
490                        self.msg_label.set_markup(msg)
491                        return
492               
493                self.msg_label.hide()           
494                cmd='apt-get update && apt-get install -y '
495                pkg=""
496                for item in self.update_metas:
497                        pkg+=item.info["pkg"] + ' '
498                       
499                for item in self.install_metas:
500                        pkg+=item.info["pkg"] + ' '
501                               
502                command=cmd+pkg
503                self.t=threading.Thread(target=self.execute,args=(command,))
504                self.t.daemon=True
505                self.t.start()
506                GLib.timeout_add(100,self.pulsate_pbar,widget)
507                self.progress_window.show()
508               
509               
510        def check_meta_compatibility(self):
511                               
512                if len(self.install_metas)>0:
513                       
514                        for gb in self.gbs:
515                                if gb.info["available"]:
516                                        if gb.info["installed"]:
517                                                if not gb in self.update_metas:
518                                                        self.update_metas.append(gb)
519                                                       
520                                                if gb.info["pkg"]=="lliurex-meta-server":
521                                                        for item in self.install_metas:
522                                                                if item.info["pkg"]=="lliurex-meta-client":
523                                                                        return [False,_("Incompatibility between Server and Client detected")]
524                                                                                                                                               
525                                                                if item.info["pkg"]=="lliurex-meta-desktop":
526                                                                        return [False, _("Is not possible adding Desktop Flavour in Server")]   
527                                                                       
528                                                if gb.info["pkg"]=="lliurex-meta-client":
529                                                        for item in self.install_metas:
530                                                                if item.info["pkg"]=="lliurex-meta-server":
531                                                                        return [False,_("Incompatibility between Server and Client detected")]
532                                               
533                                                if gb.info["pkg"]=="lliurex-meta-desktop":
534                                                        for item in self.install_metas:
535                                                                if item.info["pkg"]=="lliurex-meta-server":
536                                                                        if  gb in self.update_metas:
537                                                                                self.update_metas.remove(gb)                   
538                        i=0             
539                       
540                        for item in self.install_metas:
541                                if item.info["pkg"]=="lliurex-meta-server":
542                                        i+=1
543                                        for item in self.install_metas:
544                                                if item.info["pkg"]=="lliurex-meta-client":
545                                                        i+=1
546                                                if item.info["pkg"]=="lliurex-meta-desktop":
547                                                        self.install_metas.remove(item)
548                                                        self.remove_desktop=item
549                                                                       
550                        if i>1:
551                                return [False,_("Incompatibility between Server and Client detected")]
552                       
553                        return [True,""]
554                       
555                else:
556                        return [False,_("Choose new flavour to incorporate or close button")]
557                       
558        #def check_meta_compatibility
559                               
560        def draw_button(self,widget,ctx,grid_button):
561               
562                ctx.move_to(0,0)
563                img=cairo.ImageSurface.create_from_png(SHADOW_BANNER)
564                ctx.set_source_surface(img,0,grid_button.info["shadow_start"])
565                ctx.paint_with_alpha(grid_button.info["shadow_alpha"])
566               
567                ctx.move_to(0,0)
568                img=cairo.ImageSurface.create_from_png(grid_button.info["image"])
569                ctx.set_source_surface(img,0,0)
570                ctx.paint()
571               
572                ctx.move_to(0,0)
573                ctx.set_source_rgba(1,1,1,1)
574                ctx.rectangle(0,110,140,30)
575                ctx.fill()
576               
577               
578                ctx.set_source_rgba(self.dark_gray.r,self.dark_gray.g,self.dark_gray.b,1)
579               
580                pctx = PangoCairo.create_layout(ctx)
581                desc = Pango.font_description_from_string ("Noto Sans Bold 8")
582                pctx.set_font_description(desc)
583                pctx.set_markup(grid_button.info["name"])
584                ctx.move_to(5,118)
585                PangoCairo.show_layout(ctx, pctx)
586                width=pctx.get_pixel_size()[0]
587               
588               
589               
590                if grid_button.info["installed"]:
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=_("Installed")
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                if grid_button.info["checked"]:
605               
606                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
607                        pctx.set_font_description(desc)
608                        ctx.set_source_rgba(self.green.r,self.green.g,self.green.b,1)
609                        txt=_("Install")
610                        pctx.set_markup(txt)
611                        width=pctx.get_pixel_size()[0]
612                        ctx.move_to(140-width-5,120)
613                        PangoCairo.show_layout(ctx, pctx)
614                       
615                        ctx.rectangle(5,139,130,1)
616                        ctx.fill()
617               
618        #def draw_button
619       
620       
621        def drawing_label_event(self,widget,ctx,id):
622               
623                if id==self.current_tab:
624
625                        lg1 = cairo.LinearGradient(0.0,0.0, 300.0, 3.0)
626                        lg1.add_color_stop_rgba(0, 0, 1, 1, 0)
627                        lg1.add_color_stop_rgba(0.5, 0, 1, 1, 1)
628                        lg1.add_color_stop_rgba(1, 0, 1, 1, 0)
629                        ctx.rectangle(0, 0, 300, 3)
630                        ctx.set_source(lg1)
631                        ctx.fill()
632                       
633        #drawing_label_event
634       
635       
636        def draw_apply_button(self,widget,ctx):
637               
638               
639                button_border=22
640               
641                pctx = PangoCairo.create_layout(ctx)
642                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
643                pctx.set_font_description(desc)
644               
645                pctx.set_markup(_("APPLY"))
646                width=pctx.get_pixel_size()[0]
647                widget.set_size_request(width+button_border*2,30)
648               
649                ctx.set_source_rgba(1,1,0,1)
650                xx=0
651                yx=0
652                widthx=width+44
653                heightx=30
654                radius=5
655               
656                r=47.0
657                g=167.0
658                b=223.0
659                alpha=1.0
660               
661                r=r/255.0
662                g=g/255.0
663                b=b/255.0
664               
665                r2=83
666                g2=153
667                b2=252
668               
669                r2=r2/255.0
670                g2=g2/255.0
671                b2=b2/255.0
672               
673               
674                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
675                lg1.add_color_stop_rgba(0, r, g, b, 1)
676                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
677                ctx.set_source(lg1)
678               
679               
680                ctx.move_to (xx + radius, yx);
681                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
682                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
683                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
684                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
685                ctx.fill ();
686               
687                ctx.set_source_rgb(0.9,0.9,0.9)
688                ctx.move_to(button_border,7)
689                PangoCairo.show_layout(ctx, pctx)
690       
691        #draw_apply_button
692       
693        def draw_close_button(self,widget,ctx):
694               
695               
696                button_border=22
697               
698                pctx = PangoCairo.create_layout(ctx)
699                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
700                pctx.set_font_description(desc)
701               
702                pctx.set_markup(_("CLOSE"))
703                width=pctx.get_pixel_size()[0]
704                widget.set_size_request(width+button_border*2,30)
705               
706                ctx.set_source_rgba(1,1,0,1)
707                xx=0
708                yx=0
709                widthx=width+44
710                heightx=30
711                radius=5
712               
713                r=47.0
714                g=167.0
715                b=223.0
716                alpha=1.0
717               
718                r=r/255.0
719                g=g/255.0
720                b=b/255.0
721               
722                r2=83
723                g2=153
724                b2=252
725               
726                r2=r2/255.0
727                g2=g2/255.0
728                b2=b2/255.0
729               
730               
731                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
732                lg1.add_color_stop_rgba(0, r, g, b, 1)
733                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
734                ctx.set_source(lg1)
735               
736               
737                ctx.move_to (xx + radius, yx);
738                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
739                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
740                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
741                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
742                ctx.fill ();
743               
744                ctx.set_source_rgb(0.9,0.9,0.9)
745                ctx.move_to(button_border,7)
746                PangoCairo.show_layout(ctx, pctx)
747               
748        #def draw_close_button
749
750       
751        def draw_top_divider(self,widget,ctx):
752               
753                r=self.dark_gray.r
754                g=self.dark_gray.g
755                b=self.dark_gray.b
756                alpha=1.0
757               
758                ctx.set_source_rgba(r,g,b,alpha)
759                ctx.rectangle(0,1,500,3)
760                ctx.fill()
761               
762               
763        #def draw_top_divider
764       
765       
766        def draw_bottom_divider(self,widget,ctx):
767               
768                r=self.dark_gray.r
769                g=self.dark_gray.g
770                b=self.dark_gray.b
771                alpha=1.0
772               
773                ctx.set_source_rgba(r,g,b,alpha)
774                ctx.rectangle(0,1,500,3)
775                ctx.fill()
776               
777        #def draw_bottom_divider
778       
779       
780        def mouse_over(self,widget,event,grid_button):
781               
782                grid_button.info["animation_active"]=False
783                if grid_button.info["shadow_alpha"] <0.5 :
784                        grid_button.info["shadow_alpha"]+=0.1
785                        widget.queue_draw()
786                        return True
787                       
788                return False
789               
790        #def mouse_over
791
792        def mouse_left(self,widget,event,grid_button):
793                if not grid_button.info["checked"]:
794                        if not grid_button.info["animation_active"]:
795                       
796                                grid_button.info["animation_active"]=True
797                                GLib.timeout_add(10,self.restore_shadow_alpha,grid_button,widget)
798                       
799        #def mouse_left
800
801       
802        def restore_shadow_alpha(self,grid_button,widget):
803               
804                if grid_button.info["shadow_alpha"] >0.2 :
805                        grid_button.info["shadow_alpha"]-=0.1
806               
807                        widget.queue_draw()
808                        return True
809                       
810                grid_button.info["animation_active"]=False
811                return False
812               
813        # def restore_shadow_alfpha     
814
815       
816#awesome tabs
817
818if __name__=="__main__":
819       
820        at=AwesomeTabs()
Note: See TracBrowser for help on using the repository browser.