Python Symbian, Colour Picker per cellulari

colour pyckerEcco un’applicazione che ho scritto in breve tempo in un nuovo (per me) linguaggio di programmazione: Python.

È un semplice color picker, che ho chiamato Colour Pycker. Permette di selezionare un colore sia nella forma rosso, verde e blu, sia in esadecimale.
I “dosatori di colore” variano di velocità quando si tiene premuto il tasto selezione, in modo da velocizzare la scelta del colore desiderato. In alternativa è possibile visualizzare il colore inserendo i valori dei singoli primari direttamente in forma numerica o esadecimale.

Essendo scritta in Python richiede che il software Python S60 sia installato sul vostro cellulare. Potete trovarlo a questo indirizzo.

Ecco il file .py che dovete inserire nella cartella c:\python (oppure e:\ per la memory card):
Download ColourPycker.py –

In alternativa, ecco la versione .sis per Symbian 3rd:
– Download ColourPycker.sis –

Segue il codice sorgente.

#Colour Pycker by Ale152 - http://www.wirgilio.it/
import appuifw, graphics, key_codes, e32

#Disegna l'immagine sullo schermo
def draw(rect = None):
    c.blit(img)

#Chiude l'applicazione
def quit():
    global run
    run = False

#Imposta il colore nella forma (r, g, b)
def set_rgb():
    global r, g, b
    r = max(0, min(255, appuifw.query(u'Rosso (0-255):', 'number', r)))
    g = max(0, min(255, appuifw.query(u'Verde (0-255):', 'number', g)))
    b = max(0, min(255, appuifw.query(u'Blu (0-255):', 'number', b)))

#Imposta il colore nella forma esadecimale
def set_hex():
    global r, g, b
    hex = appuifw.query(u'Colore:', 'text', u'%02X%02X%02X' % (r, g, b))
    r = int(hex[:2], 16)
    g = int(hex[2:4], 16)
    b = int(hex[4:6], 16)

#Seleziona colore, giù
def select_down():
    global selezione, times
    times = 0
    selezione = min(selezione + 1, 2)

#Seleziona colore, su
def select_up():
    global selezione, times
    times = 0
    selezione = max(selezione - 1, 0)

#Diminuisce un colore
def select_left():
    global r, g, b, times, dire
    #Quando cambi direzione la velocità si azzera
    if dire == 'destra': times = 0
    dire = 'sinistra'
    #Selezione colore
    if selezione == 0:
        r -= times > nt and speed or 1
    elif selezione == 1:
        g -= times > nt and speed or 1
    elif selezione == 2:
        b -= times > nt and speed or 1
    #Limita i colori all'intervallo [0, 255]
    r = max(0, min(255, r))
    g = max(0, min(255, g))
    b = max(0, min(255, b))
    times += 1

#Aumenta un colore
def select_right():
    global r, g, b, times, dire
    #Quando cambi direzione la velocità si azzera
    if dire == 'sinistra': times = 0
    dire = 'destra'
    #Selezione colore
    if selezione == 0:
        r += times > nt and speed or 1
    elif selezione == 1:
        g += times > nt and speed or 1
    elif selezione == 2:
        b += times > nt and speed or 1
    #Limita i colori all'intervallo [0, 255]
    r = max(0, min(255, r))
    g = max(0, min(255, g))
    b = max(0, min(255, b))
    times += 1

#Variabili
r = g = b = 150 #Red, green, blue
selezione = 0   #Selezione colore
times = 0       #Numero di ripetizioni cambio colore
nt = 4          #Numero di ripetizioni prima del cambio velocità
speed = 10      #Velocità cambio colore
dire = None     #Direzione della selezione

#Colori default
BIANCO = (255, 255, 255)
NERO = (0, 0, 0)
AZZURRO = (0, 100, 255)

#Inizializzazione grafica e tastiera
appuifw.app.body = c = appuifw.Canvas(redraw_callback = draw)
img = graphics.Image.new(c.size)
appuifw.exit_key_handler = quit
appuifw.app.title = u'Colour Pycker'
appuifw.app.menu = [(u'Imposta colore RGB', set_rgb),
                    (u'Imposta colore HEX', set_hex),
                    (u'Esci', quit)]
c.bind(key_codes.EKeyUpArrow, select_up)
c.bind(key_codes.EKeyDownArrow, select_down)
c.bind(key_codes.EKeyLeftArrow, select_left)
c.bind(key_codes.EKeyRightArrow, select_right)

#Grafica
pad = [
        45,  #Padding sinistro descrizione colore
        160, #Padding sinistro valore colore
        60,  #Padding sinistro linea
        150, #Padding sinistro linea
        70   #Padding superiore
]
margin = 30  #Margine tra le scritte
line = 90    #Lunghezza linea

#Applicazione
run = True
while run:
    img.clear((r, g, b))
    #Sfondo testo
    img.rectangle((40, 50, c.size[1]-40, 160), fill = BIANCO, outline = NERO)
    #Descrizione/Valore colore
    img.text((pad[0], pad[4]), u'R') #Descrizione rosso
    img.text((pad[1], pad[4]), u'%d' % r) #Valore rosso
    img.text((pad[0], pad[4] + margin), u'G') #Descrizione verde
    img.text((pad[1], pad[4] + margin), u'%d' % g) #Valore verde
    img.text((pad[0], pad[4] + 2 * margin), u'B') #Descrizione blu
    img.text((pad[1], pad[4] + 2 * margin), u'%d' % b) #Valore blu
    #Linee
    img.line((pad[2], pad[4] - 5,
              pad[3], pad[4] - 5),
             outline = NERO)
    img.line((pad[2], pad[4] + margin - 5,
              pad[3], pad[4] + margin - 5),
             outline = NERO)
    img.line((pad[2], pad[4] + 2 * margin - 5,
              pad[3], pad[4] + 2 * margin - 5),
             outline = NERO)
    #Quadrato
    rR = (pad[2]-5 + (r/255.0)*line,
          pad[2],
          pad[2]+5 + (r/255.0)*line,
          pad[2]+10)
    #Quadrato verde
    rG = (pad[2]-5 + (g/255.0)*line,
          pad[2] + margin,
          pad[2]+5 + (g/255.0)*line,
          pad[2] + margin + 10)
    #Quadrato blu
    rB = (pad[2]-5 + (b/255.0)*line,
          pad[2] + 2*margin,
          pad[2]+5 + (b/255.0)*line,
          pad[2] + 2*margin + 10)
    #Selezione
    if selezione == 0:
        img.rectangle(rR, fill = AZZURRO) #Selezionato
        img.rectangle(rG, fill = NERO) #Non selezionato
        img.rectangle(rB, fill = NERO) #Non selezionato
    elif selezione == 1:
        img.rectangle(rR, fill = NERO)
        img.rectangle(rG, fill = AZZURRO)
        img.rectangle(rB, fill = NERO)
    elif selezione == 2:
        img.rectangle(rR, fill = NERO)
        img.rectangle(rG, fill = NERO)
        img.rectangle(rB, fill = AZZURRO)
    #HEX
    img.text((45, 150), u'Esadecimale: #%02X%02X%02X' % (r, g, b))
    draw()
    e32.ao_sleep(0.1)