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

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

Add valencian po file

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