source: zero-lliurex-installers/trunk/fuentes/zero-lliurex-recursos.install/usr/share/zero-lliurex-recursos/lliurex-resources-installer.py @ 5911

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

Redesign gui. Change to stock buttons

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