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

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

WIP

  • 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 check_meta_compatibility(self):
516                               
517                if len(self.install_metas)>0:
518                       
519                        for gb in self.gbs:
520                                if gb.info["available"]:
521                                        if gb.info["installed"]:
522                                                if not gb in self.update_metas:
523                                                        self.update_metas.append(gb)
524                                                       
525                                                if gb.info["pkg"]=="lliurex-meta-server":
526                                                        for item in self.install_metas:
527                                                                if item.info["pkg"]=="lliurex-meta-client":
528                                                                        return [False,_("Incompatibility between Server and Client detected")]
529                                                                                                                                               
530                                                                if item.info["pkg"]=="lliurex-meta-desktop":
531                                                                        return [False, _("Is not possible adding Desktop Flavour in Server")]   
532                                                                       
533                                                if gb.info["pkg"]=="lliurex-meta-client":
534                                                        for item in self.install_metas:
535                                                                if item.info["pkg"]=="lliurex-meta-server":
536                                                                        return [False,_("Incompatibility between Server and Client detected")]
537                                               
538                                                if gb.info["pkg"]=="lliurex-meta-desktop":
539                                                        for item in self.install_metas:
540                                                                if item.info["pkg"]=="lliurex-meta-server":
541                                                                        if  gb in self.update_metas:
542                                                                                self.update_metas.remove(gb)                   
543                        i=0             
544                       
545                        for item in self.install_metas:
546                                if item.info["pkg"]=="lliurex-meta-server":
547                                        i+=1
548                                        for item in self.install_metas:
549                                                if item.info["pkg"]=="lliurex-meta-client":
550                                                        i+=1
551                                                if item.info["pkg"]=="lliurex-meta-desktop":
552                                                        self.install_metas.remove(item)
553                                                        self.remove_desktop=item
554                                                                       
555                        if i>1:
556                                return [False,_("Incompatibility between Server and Client detected")]
557                       
558                        return [True,""]
559                       
560                else:
561                        return [False,_("Choose new flavour to incorporate or close button")]
562                       
563        #def check_meta_compatibility
564                               
565        def draw_button(self,widget,ctx,grid_button):
566               
567                ctx.move_to(0,0)
568                img=cairo.ImageSurface.create_from_png(SHADOW_BANNER)
569                ctx.set_source_surface(img,0,grid_button.info["shadow_start"])
570                ctx.paint_with_alpha(grid_button.info["shadow_alpha"])
571               
572                ctx.move_to(0,0)
573                img=cairo.ImageSurface.create_from_png(grid_button.info["image"])
574                ctx.set_source_surface(img,0,0)
575                ctx.paint()
576               
577                ctx.move_to(0,0)
578                ctx.set_source_rgba(1,1,1,1)
579                ctx.rectangle(0,110,140,30)
580                ctx.fill()
581               
582               
583                ctx.set_source_rgba(self.dark_gray.r,self.dark_gray.g,self.dark_gray.b,1)
584               
585                pctx = PangoCairo.create_layout(ctx)
586                desc = Pango.font_description_from_string ("Noto Sans Bold 7.5")
587                pctx.set_font_description(desc)
588                pctx.set_markup(grid_button.info["name"])
589                ctx.move_to(5,118)
590                PangoCairo.show_layout(ctx, pctx)
591                width=pctx.get_pixel_size()[0]
592               
593               
594               
595                if grid_button.info["installed"]:
596               
597                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
598                        pctx.set_font_description(desc)
599                        ctx.set_source_rgba(self.green.r,self.green.g,self.green.b,1)
600                        txt=_("Installed")
601                        pctx.set_markup(txt)
602                        width=pctx.get_pixel_size()[0]
603                        ctx.move_to(140-width-5,120)
604                        PangoCairo.show_layout(ctx, pctx)
605                       
606                        ctx.rectangle(5,139,130,1)
607                        ctx.fill()
608               
609                if grid_button.info["checked"]:
610               
611                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
612                        pctx.set_font_description(desc)
613                        ctx.set_source_rgba(self.green.r,self.green.g,self.green.b,1)
614                        txt=_("Install")
615                        pctx.set_markup(txt)
616                        width=pctx.get_pixel_size()[0]
617                        ctx.move_to(140-width-5,120)
618                        PangoCairo.show_layout(ctx, pctx)
619                       
620                        ctx.rectangle(5,139,130,1)
621                        ctx.fill()
622               
623        #def draw_button
624       
625       
626        def drawing_label_event(self,widget,ctx,id):
627               
628                if id==self.current_tab:
629
630                        lg1 = cairo.LinearGradient(0.0,0.0, 300.0, 3.0)
631                        lg1.add_color_stop_rgba(0, 0, 1, 1, 0)
632                        lg1.add_color_stop_rgba(0.5, 0, 1, 1, 1)
633                        lg1.add_color_stop_rgba(1, 0, 1, 1, 0)
634                        ctx.rectangle(0, 0, 300, 3)
635                        ctx.set_source(lg1)
636                        ctx.fill()
637                       
638        #drawing_label_event
639       
640       
641        def draw_apply_button(self,widget,ctx):
642               
643               
644                button_border=22
645               
646                pctx = PangoCairo.create_layout(ctx)
647                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
648                pctx.set_font_description(desc)
649               
650                pctx.set_markup(_("APPLY"))
651                width=pctx.get_pixel_size()[0]
652                widget.set_size_request(width+button_border*2,30)
653               
654                ctx.set_source_rgba(1,1,0,1)
655                xx=0
656                yx=0
657                widthx=width+44
658                heightx=30
659                radius=5
660               
661                r=47.0
662                g=167.0
663                b=223.0
664                alpha=1.0
665               
666                r=r/255.0
667                g=g/255.0
668                b=b/255.0
669               
670                r2=83
671                g2=153
672                b2=252
673               
674                r2=r2/255.0
675                g2=g2/255.0
676                b2=b2/255.0
677               
678               
679                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
680                lg1.add_color_stop_rgba(0, r, g, b, 1)
681                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
682                ctx.set_source(lg1)
683               
684               
685                ctx.move_to (xx + radius, yx);
686                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
687                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
688                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
689                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
690                ctx.fill ();
691               
692                ctx.set_source_rgb(0.9,0.9,0.9)
693                ctx.move_to(button_border,7)
694                PangoCairo.show_layout(ctx, pctx)
695       
696        #draw_apply_button
697       
698        def draw_close_button(self,widget,ctx):
699               
700               
701                button_border=22
702               
703                pctx = PangoCairo.create_layout(ctx)
704                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
705                pctx.set_font_description(desc)
706               
707                pctx.set_markup(_("CLOSE"))
708                width=pctx.get_pixel_size()[0]
709                widget.set_size_request(width+button_border*2,30)
710               
711                ctx.set_source_rgba(1,1,0,1)
712                xx=0
713                yx=0
714                widthx=width+44
715                heightx=30
716                radius=5
717               
718                r=47.0
719                g=167.0
720                b=223.0
721                alpha=1.0
722               
723                r=r/255.0
724                g=g/255.0
725                b=b/255.0
726               
727                r2=83
728                g2=153
729                b2=252
730               
731                r2=r2/255.0
732                g2=g2/255.0
733                b2=b2/255.0
734               
735               
736                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
737                lg1.add_color_stop_rgba(0, r, g, b, 1)
738                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
739                ctx.set_source(lg1)
740               
741               
742                ctx.move_to (xx + radius, yx);
743                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
744                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
745                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
746                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
747                ctx.fill ();
748               
749                ctx.set_source_rgb(0.9,0.9,0.9)
750                ctx.move_to(button_border,7)
751                PangoCairo.show_layout(ctx, pctx)
752               
753        #def draw_close_button
754
755       
756        def draw_top_divider(self,widget,ctx):
757               
758                r=self.dark_gray.r
759                g=self.dark_gray.g
760                b=self.dark_gray.b
761                alpha=1.0
762               
763                ctx.set_source_rgba(r,g,b,alpha)
764                ctx.rectangle(0,1,500,3)
765                ctx.fill()
766               
767               
768        #def draw_top_divider
769       
770       
771        def draw_bottom_divider(self,widget,ctx):
772               
773                r=self.dark_gray.r
774                g=self.dark_gray.g
775                b=self.dark_gray.b
776                alpha=1.0
777               
778                ctx.set_source_rgba(r,g,b,alpha)
779                ctx.rectangle(0,1,500,3)
780                ctx.fill()
781               
782        #def draw_bottom_divider
783       
784       
785        def mouse_over(self,widget,event,grid_button):
786               
787                grid_button.info["animation_active"]=False
788                if grid_button.info["shadow_alpha"] <0.5 :
789                        grid_button.info["shadow_alpha"]+=0.1
790                        widget.queue_draw()
791                        return True
792                       
793                return False
794               
795        #def mouse_over
796
797        def mouse_left(self,widget,event,grid_button):
798                if not grid_button.info["checked"]:
799                        if not grid_button.info["animation_active"]:
800                       
801                                grid_button.info["animation_active"]=True
802                                GLib.timeout_add(10,self.restore_shadow_alpha,grid_button,widget)
803                       
804        #def mouse_left
805
806       
807        def restore_shadow_alpha(self,grid_button,widget):
808               
809                if grid_button.info["shadow_alpha"] >0.2 :
810                        grid_button.info["shadow_alpha"]-=0.1
811               
812                        widget.queue_draw()
813                        return True
814                       
815                grid_button.info["animation_active"]=False
816                return False
817               
818        # def restore_shadow_alfpha     
819
820        def log(self,error):
821                log_file="/tmp/lliurex-flavour-selector"
822                f=open(log_file,"a")
823                f.write("[" +datetime.datetime.today().strftime("%d/%m/%y %H:%M:%S") + " ] " + "\n" + error + "\n")
824                f.close()
825#awesome tabs
826
827if __name__=="__main__":
828       
829        at=AwesomeTabs()
Note: See TracBrowser for help on using the repository browser.