Création d'une lentilles (lens) pour unity

Il est conseillé de déjà consulter ce tutoriel, pour acquérir les bases, cette pages expliquera comment utiliser plus en profondeur la librairie singlet

Aperçus des fonctionnalités disponibles

L'idée d'ici est de créer une lense et un scope qui montrent toutes les possibilités à disposition par les lens et scope unity, et au passage de comprendre comment utiliser et comment fonctionne singlet.

Le projet sera facilement compilable pour pouvoir réellement visualiser et tester toutes les possibilités de des lenses unity. Ce tutoriel ne contiendra pas d'images qui risquerai de rapidement devenirs obsolètes.

Nous nous appuierons sur singlet, une librairie que permet de créer plus facilement des lens et scope unity.

Création d'un projet

quickly create unity-lens tutorial

Maintenant utilisons cette nouvelle lens :

cd tutorial
sudo quickly install
quickly run

Et aller voir dans le Tableau de Bord (Dash)

Les types de catégories

Nous avons actuellement une seul catégorie d'affichée.

Ouvrir le fichier

tutorial/__init__.py

On observe dans ce fichier

example_category = ListViewCategory("Examples", 'help')

Cela correspond donc à cette catégorie.

Nous allons la renommer et ajouter tous les types connus.

La doc officielle des type de catégories 1) nous propose 4 types :

  • VERTICAL_TILE
  • HORIZONTAL_TILE
  • LIST_TILE
  • FLOW

Mais singlet que 2 :

  • IconViewCategory (VERTICAL_TILE)
  • ListViewCategory (HORIZONTAL_TILE)

remplacer cette ligne par ce code, la méthode permet de peupler une catégorie :

    list_view_category = ListViewCategory("ListViewCategory", 'help')
    icon_view_category = IconViewCategory("IconViewCategory", 'help')
 
 
    def populate_category(self, category, results):
        for i in xrange(15):
            results.append('https://wiki.ubuntu.com/Unity/Lenses/Singlet',
                     'ubuntu-logo',
                     category,
                     "text/html",
                     'Learn More',
                     'Find out how to write your Unity Lens',
                     'https://wiki.ubuntu.com/Unity/Lenses/Singlet')
            results.append('https://wiki.ubuntu.com/Unity/Lenses/Singlet',
                     'ubuntu-logo',
                    category,
                     "text/html",
                     'Test sur un très très très très grand texte hahahahahaha ! ',
                     'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec',
                     'https://wiki.ubuntu.com/Unity/Lenses/Singlet')

Remplaçons le contenu de la méthode search par :

        self.populate_category(self.list_view_category, results)
        self.populate_category(self.icon_view_category, results)

Et comme on parle français et qu'on a envie de pouvoir mettre des accents utf-8, ajouter un première ligne du fichier :

# -*-coding:utf-8 -*

Testez !

Alors ok, ça fonctionne et on observe 2 types de catégorie, essayons quand même les autres (singlet nous le permet, et c'est tant mieux !) !

    list_tile_category = Category("CategoryRenderer.LIST_TILE", 'help', Unity.CategoryRenderer.LIST_TILE)
    flow_category = Category("CategoryRenderer.FLOW", 'help', Unity.CategoryRenderer.FLOW)
        self.populate_category(self.list_tile_category, results)
        self.populate_category(self.flow_category, results)

Nous ajouterons aussi les 2 imports suivants :

from singlet.lens.category import Category
from gi.overrides.Unity import Unity

Testez !

Bon, ok on comprend pourquoi il n'étaient pas inclus par défaut, je ne vois pas de différence avec IconViewCategory, mais ça valais le coup de tester.

Comment fait singlet pour connaître les catégories a afficher

En effet, ce sont juste des membre de notre classe !

Il utilise pour cela l'introspection 2) :

     for aName, a in attrs.items():
           if isinstance(a, Unity.Scope):
                new_class._meta.scope_dict[aName] = a
                if not hasattr(meta, 'scope_order'):
                    new_class._meta.scope_order.append(aName)
 
            elif isinstance(a, Unity.Category):
                new_class._meta.category_dict[aName] = a
                if not hasattr(meta, 'category_order'):
                    new_class._meta.category_order.append(aName)
                setattr(new_class, aName, new_class._meta.category_order.index(aName))
 
            elif isinstance(a, Unity.Filter):
                new_class._meta.filter_dict[aName] = a
                if not hasattr(meta, 'filter_order'):
                    new_class._meta.filter_order.append(aName)
 
            else:
                setattr(new_class, aName, a)

On vois ici que elif isinstance(a, Unity.Category): trouve toute les catégories de notre classe :)

Le code ci dessus montre aussi pourquoi nous avons accès aux variables de class dans notre object (self.categorie), en réalité ces membres sont injectés dans l'objet (cf code ci dessus), et ce sont uniquement les id des catégories qui sont accessible a travers ces membres !

On voit aussi un autre détail, on peux définir une certaine variable category_order . On vas donc essayer de la définir pour afficher nos catégories dans le meme ordre que ci dessus, car ce n'est pas le cas.

Pour cela, ajouter dans la classe Meta :

        category_order=['list_view_category','icon_view_category','list_tile_category','flow_category']

Réinstaller la lens, la lancer, on a bien nos catégories dans le bon ordre :)

Les filtres

On vois ci dessus que l'on peux aussi définir des filtres

Suivant la doc, voici l'arborescence des classes :

  • Unity.Filter
    • Unity.RatingsFilter
    • Unity.OptionsFilter
      • Unity.RadioOptionFilter
      • Unity.CheckOptionFilterCompact
      • Unity.CheckOptionFilter
      • Unity.MultiRangeFilter

Voila qui est intéressant, testons donc tous ces filtres !

On ajoutera aussi l'import :

from gi.overrides.Gio import Gio

Alors, quelques éléments a savoir a propos des filtres, je n'ai aucune référence pour ces affirmations a pars mes propres essais :

  1. On ne peux pas ajouter d'entré a un filtre après l'avoir ajouté en tant que filtre !

C'est très important car cela signifie que si on ajoute ces filtres en tant que membre de la classe, il *faut* qu'ils aient déja tous leur éléments !

Donc je propose d'ajouter cette fonction *en dessus* de la classe :

def populate_option_filter(option_filter):
    for i in xrange(3):
        title="Filtre"+str(i)
        option_filter.add_option(title,title, Gio.ThemedIcon.new("input-keyboard-symbolic"))

ensuite, ajouter en dessous des catégories non filtres :

    ratings_filter = Unity.RatingsFilter.new("ratings_filter",
                                         "Unity.RatingsFilter",
                                         Gio.ThemedIcon.new("input-keyboard-symbolic"),
                                         True)
    radio_option_filter = Unity.RadioOptionFilter.new("radio_option_filter",
                                         "Unity.RadioOptionFilter",
                                         Gio.ThemedIcon.new("input-keyboard-symbolic"),
                                         True)
    check_option_compact_filter = Unity.CheckOptionFilterCompact.new("check_option_compact_filter",
                                         "Unity.CheckOptionFilterCompact",
                                         Gio.ThemedIcon.new("input-keyboard-symbolic"),
                                         True)
    check_option_filter = Unity.CheckOptionFilter.new("check_option_filter",
                                         "Unity.CheckOptionFilter",
                                         Gio.ThemedIcon.new("input-keyboard-symbolic"),
                                         True)
    multi_range_filter = Unity.MultiRangeFilter.new("multi_range_filter",
                                         "Unity.MultiRangeFilter",
                                         Gio.ThemedIcon.new("input-keyboard-symbolic"),
                                         True)
    populate_option_filter(radio_option_filter)
    populate_option_filter(check_option_compact_filter)  
    populate_option_filter(check_option_filter)  
    populate_option_filter(multi_range_filter)     
    #rating no need to be fillful

Ok, on peux observer les différence :)

Pour récupérer les valeurs des filtres et pour en ajouter a posteriori, singlet n'est pas encore pres, nous allons donc devoir attendre un peu.

  • utilisateurs/quent57/tutoriel/singlet_unity_lens.txt
  • Dernière modification: Le 28/04/2018, 11:32
  • (modification externe)