You are here: Links of Interest » HEIG-VD » [PRO] Virtual Comics Library » Rapport » Implémentation » Application Desktop » Liseuse
Liseuse
This is an old revision of the document!
Liseuse
La liseuse permet de lire les différents volumes de la bibliothèque. Elle est à part de le bibliothèque et ne fait que prendre un volume en entrée. Elle offre à l'utilisateur plusieurs option de navigation telle que:
- Changer le sens de lecture: Cela permet, pour certains mangas, de lire de droite à gauche plutôt que de gauche à droite. Cela est surtout pratique quand on utilise les doubles pages.
- Simple ou double pages: Cela gère l'affichage et définit si une seule page à la fois ou deux pages en même temps doivent être affichées. L'affichage de deux pages simultanées simule l'expérience qu'un utilisateur pourrait avoir si il lisait un livre physique.
- Redimmensionnement de la page: Il est possible de définir le redimmensionnement automatique de la page sois sur la hauteur, sois sur la largeur de la fenêtre.
L'implémentation de la logique de la liseuse est faites grâce à un Navigator
implémenté dans le package navigation
. La classe Navigator
étant abstraite, elle donne la possibilité de créer des Navigator
pour un nombre de pages voulu. Nous avons décidé de ne l'implémenter que pour les pages simple (SimpleNavigator
) et pour les pages doubles, c'est à dire 2 pages simples (DoubleNavigator
) car cela n'a pas de sens dans notre contexte de l'utiliser pour plus de pages.
Chaque Navigator
contient un volume et une page courante qui est affichée. Ces pages sont définie au tant que DisplayPage
, qui est aussi une classe abstraite permettant d'implémenter des classes définies sur un nombre de pages voulu. Nous avons implémenté les classes pour des pages simples (SimplePage
) et des pages double, c'est à dire 2 pages simples (DoublePage
). Une fois encore, nous n'avons pas implémenté d'autre classe, cela n'ayant pas de sens pour nous mais cela serait tout à fait possible.
En résumé, le Navigator
permet d'implémenter la logique par laquelle les pages doivent être parcourues alors que les DisplayPage
permettent simplement de contenir une page de manière contrôlée et définie dans le programme.
Voici un diagramme de classe pour le Navigator:
<uml> hide empty fields hide empty methods
abstract class Navigator{
- vol: Volume
- direction: Direction
- currentPage: DisplayPage
+setDirection(sens: Direction) : void
+setCurrentPage(page: DisplayPage) : void +getVolume() : Volume +getDirection(): Direction +getCurrentPage(): DisplayPage
} class SimpleNavigator {
+SimpleNavigator(volume: Volume, direction: Direction, beginIndex: Int) +SimpleNavigator(nav: DoubleNavigator) +nextPages(): DisplayPage +previousPages(): DisplayPage +goTo(index: int): DisplayPage
} class DoubleNavigator {
+DoubleNavigator(volume: Volume, direction: Direction, beginIndex: Int) +DoubleNavigator(nav: SimpleNavigator) +update(): void +nextPages(): DisplayPage +previousPages(): DisplayPage +goTo(index: int): DisplayPage
} interface INavigator {
+nextPages() : DisplayPage +previousPages() : DisplayPage +goTo(index: int): DisplayPage +setDirection(sens: Direction) : void +setCurrentPage(page: DisplayPage) : void +getVolume() : Volume +getDirection(): Direction +getCurrentPage(): DisplayPage
}
enum Direction{
LTR,RTL
}
Navigator –> SimpleNavigator Navigator –> DoubleNavigator INavigator –> Navigator </uml>
On peut voir que l'on utilise une interface INavigator
qui oblige les implémentations de définir les méthodes essentielles à la logique d'un navigateur. Le Navigator
implémente partiellement certaines méthodes qui sont communes à n'importe quel navigateur.
Voici un diagramme de classe pour le DisplayPage: <uml> hide empty fields hide empty methods
abstract class DisplayPage{
- imageIndexes: ArrayList<Integer>
- imageReferences: ArrayList<Image>
- direction: Direction
+DisplayPage(indexes: ArrayList<Integer>, images: ArrayList<Image>, dir: Direction)
+getImageIndexes(): ArrayList<Integer> +getImageReferences(): ArrayList<Image> +getDirection(): Direction
} class SinglePage {
+SinglePage(index: int, image: Image, dir: Direction) +getImage(): Image +getIndex(): int
} class DoublePage {
+DoublePage(index1: int, index2: int, image1: Image, image2: Image, dir: Direction) +getFirstImage(): Image +getSecondeImage(): Image +getFirstIndex(): int +getSecondIndex(): int
} interface IDisplayPage {
+getImageIndexes(): ArrayList<Integer> +getImageReferences(): ArrayList<Image> +getDirection(): Direction
}
DisplayPage –> SinglePage DisplayPage –> DoublePage IDisplayPage –> DisplayPage </uml>
Ici, la logique est la même que pour le navigateur. Une interface définissant les méthodes obligatoires et une classe DisplayPage qui permet de faire une implémentation partielle des pages.
Une subtilité réside dans le DoubleNavigator
. En effet, il est possible que des page doubles, c'est à dire des pages qui, dans un livre physique sont en paysage, se trouvent dans le volume. Ces pages ont été mises par les gens qui ont numérisé le livre comme une grande page qui est plus large que haute. Cela a été fait pour conserver le travail de l'auteur et ne pas dénaturer ces images en les séparant sur deux pages différentes. Dans ce cas, si jamais le DoubleNavigator
voit qu'il y'a une double page, il va uniquement afficher la prochaine page et non les 2 prochaines pages. Cela à pour effet que la page courante dans le navigateur sera une SimplePage
et non une DoublePage
comme on pourrait s'y attendre. Avec ce système, la vue n'a pas à ce soucier du type de navigateur qu'elle utilise, étant donné qu'elle reçoit une DisplayPage
et de ce fait, il lui suffit de faire un contrôle du type de page qu'elle a pour donner le bon affichage.
Exemple d'image simple
Exemple d'image double