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

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

Redesign gui. Change to stock buttons

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