You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
6.2 KiB
Python
205 lines
6.2 KiB
Python
import curses
|
|
import sys
|
|
from . import constantes_curses as constantes
|
|
#import constantes_curses as constantes
|
|
|
|
def create_newwin():
|
|
"""Initialise une fenêtre
|
|
"""
|
|
window = curses.newwin(0,0)
|
|
window.border(0)
|
|
return window
|
|
|
|
def init_curses():
|
|
"""Initialise la biliothèque curses
|
|
"""
|
|
stdscr = curses.initscr()
|
|
curses.noecho()
|
|
curses.cbreak()
|
|
stdscr.keypad(True)
|
|
return stdscr
|
|
|
|
def close_curses(stdscr):
|
|
"""Ferme la fenêtre
|
|
"""
|
|
stdscr.keypad(0)
|
|
curses.nocbreak()
|
|
curses.echo()
|
|
curses.endwin()
|
|
|
|
def init_colors():
|
|
"""Initialisation des couleurs de la fenêtre
|
|
"""
|
|
curses.start_color()
|
|
curses.init_pair(1,curses.COLOR_RED,curses.COLOR_BLACK)
|
|
curses.init_pair(2,curses.COLOR_BLACK,curses.COLOR_RED)
|
|
|
|
class Echo():
|
|
"""Décorateur permettant de garantir que ce qui est écrit au clavier sera vu à l'écran
|
|
"""
|
|
|
|
|
|
def __init__(self,f):
|
|
self.f = f
|
|
|
|
def __call__(self,*args,**kwargs):
|
|
curses.echo()
|
|
return self.f(*args,**kwargs)
|
|
curses.noecho()
|
|
|
|
def add_line(window,pos,nombre_lignes):
|
|
"""Permet de passer à la ligne suivante lors d'une saisie utilisateur : on ré-initialise la fenêtre si on est descendu trop bas.
|
|
"""
|
|
if pos == nombre_lignes-2:
|
|
pos = 1
|
|
window = curses.newwin(0,0)
|
|
window.border(0)
|
|
window.refresh()
|
|
return pos
|
|
else:
|
|
pos +=1
|
|
return pos
|
|
|
|
@Echo
|
|
def get_user_entry(window,encoding=constantes.encoding):
|
|
"""Récupère la saisie d'un message à l'écran
|
|
"""
|
|
userentry = window.getstr()
|
|
return userentry.decode(encoding)
|
|
|
|
def get_entry(window,message,pos,nombre_lignes,encoding=constantes.encoding):
|
|
"""
|
|
Récupère la saisie utilisateur, en affichant un message d'erreur et demandant la re-saisie si la fonction decode plante (effacement d'un seul caractère au lieu de deux lors d'une saisie erronée d'un caractère accentué).
|
|
"""
|
|
while True:
|
|
try:
|
|
window.addstr(pos,1,message,curses.color_pair(1))
|
|
return [get_user_entry(window,encoding),add_line(window,pos,nombre_lignes)]
|
|
except:
|
|
pos = add_line(window,pos,nombre_lignes)
|
|
window.addstr(pos,1,"Erreur de saisie, merci de recommencer",curses.color_pair(1))
|
|
pos = add_line(window,pos,nombre_lignes)
|
|
|
|
def display_menu(title,menu,window,active=1):
|
|
"""Affiche un menu, qui ne doit pas avoir plus de lignes que la taille de l'écran (non vérifié).
|
|
"""
|
|
window.addstr(1,1,title,curses.color_pair(1))
|
|
item_pos = 6 ## WTF ??
|
|
pos = 1
|
|
for item in menu:
|
|
if pos == active:
|
|
color = curses.color_pair(2)
|
|
else:
|
|
color = curses.A_NORMAL
|
|
if item == 'Quitter':
|
|
item_pos +=1
|
|
window.addstr(item_pos,1," %d. %s" %(pos,item),color)
|
|
pos +=1
|
|
else:
|
|
window.addstr(item_pos,1," %d. %s" %(pos,item),color)
|
|
item_pos +=1
|
|
pos +=1
|
|
window.refresh()
|
|
|
|
def getkey(final,title,menu,window,active_pos=1):
|
|
"""Permet de se balader dans un menu
|
|
"""
|
|
c = None
|
|
while c != constantes.touche_entree:
|
|
c = window.getch()
|
|
if c == ord(constantes.touche_bas):
|
|
if active_pos != final:
|
|
active_pos +=1
|
|
else:
|
|
active_pos = 1
|
|
elif c == ord(constantes.touche_haut):
|
|
if active_pos != 1:
|
|
active_pos -=1
|
|
else:
|
|
active_pos = final
|
|
display_menu(title,menu,window,active_pos)
|
|
return active_pos
|
|
|
|
|
|
class Stdscr():
|
|
"""Décorateur permettant d'initialiser une fenêtre curses
|
|
"""
|
|
|
|
|
|
def __init__(self,f):
|
|
self.f = f
|
|
|
|
def __call__(self,*args):
|
|
window = init_curses()
|
|
nombre_lignes = curses.LINES
|
|
init_colors()
|
|
window = create_newwin()
|
|
window.refresh()
|
|
try:
|
|
return self.f(*args,window,nombre_lignes)
|
|
finally:
|
|
close_curses(window)
|
|
|
|
@Stdscr
|
|
def saisie_message_std(message,window,nombre_lignes):
|
|
"""Retourne la saisie de l'utilisateur, et quitte le programme si cette saisie est constantes.quitter
|
|
"""
|
|
pos = 1
|
|
user_entry = get_entry(window,message,pos,nombre_lignes,encoding=constantes.encoding)[0]
|
|
if user_entry.lower() == constantes.quitter:
|
|
quit() # pourquoi pas sys.exit() ?
|
|
else:
|
|
return user_entry
|
|
|
|
@Stdscr
|
|
def afficher_message_std(message,window,nombre_lignes):
|
|
"""Permet d'afficher un unique message à l'écran
|
|
"""
|
|
pos = 1
|
|
fin_message = " (appuyer sur une touche pour continuer) "
|
|
c = None
|
|
window.addstr(pos,1,message+fin_message,curses.color_pair(1))
|
|
while c == None:
|
|
c = window.getch()
|
|
return None
|
|
|
|
def saisie_message(pos,message,window,nombre_lignes):
|
|
"""Retourne la saisie de l'utilisateur, et quitte le programme si cette saisie est constantes.quitter
|
|
"""
|
|
user_entry,pos = get_entry(window,message,pos,nombre_lignes,encoding=constantes.encoding)
|
|
if user_entry.lower() == constantes.quitter:
|
|
sys.exit()
|
|
else:
|
|
return [user_entry, pos]
|
|
|
|
def afficher_message(pos,message,window,nombre_lignes):
|
|
"""Permet d'afficher un message à l'écran dans une fenêtre déjà initialisée
|
|
"""
|
|
fin_message = " (appuyer sur une touche pour continuer) "
|
|
c = None
|
|
window.addstr(pos,1,message+fin_message,curses.color_pair(1))
|
|
while c == None:
|
|
c = window.getch()
|
|
return add_line(window,pos,nombre_lignes)
|
|
|
|
def is_forceable(info,type_info):
|
|
"""Détermine si l'info peut être considérée comme un 'type_info'
|
|
"""
|
|
try:
|
|
return type_info(info)
|
|
except:
|
|
return False
|
|
|
|
def get_clean_info(type_info,message,pos,window,nombre_lignes):
|
|
"""Permet de s'assurer que l'information récupérée est bien du type voulue.
|
|
"""
|
|
var = False
|
|
while not var:
|
|
var,pos = saisie_message(pos,message,window,nombre_lignes)
|
|
if var == constantes.terminer: #cas particulier de nécessité de sortie de boucle
|
|
return [var,pos]
|
|
var = is_forceable(var,type_info)
|
|
if (var is 0) and type_info == int: #cas particulier du zéro interprété comme False
|
|
return [var, pos]
|
|
return [var, pos]
|