Paintworks est un logiciel de dessin directement utilisable sur Calculatrice Numworks.
Il a été testé sur N0110 mais devrait marcher sur les modèles plus récents.
Ce programme de 500 lignes a quasiment été tapé entièrement sur Calculatrice… Il comprend un choix de 50 couleurs différentes, un outil pinceau et un outil remplissage. Il possède un système de chargement automatique des dessins et un système d’enregistrement manuel des dessins (Car on ne peut pas écrire (et techniquement lire) automatiquement dans le stockage ).
Vous pouvez me faire des retours sur le site de Planet Casio
import kandinsky import numpy as np import ion import time from math import ceil,sqrt spx=kandinsky.set_pixel ds=kandinsky.draw_string fr=kandinsky.fill_rect iokd=ion.keydown IOKU=ion.KEY_UP IOKD=ion.KEY_DOWN IOKR=ion.KEY_RIGHT IOKL=ion.KEY_LEFT IOKK=ion.KEY_OK S_W=320 S_H=222 BG_C=(230,230,230) BGM_C=(200,200,200) BC=(0,0,0) MAX_DATA_LEN=213 pa="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-*/():;%=<>?![]{}_" pa=[i for i in pa] def cl():fr(0,0,S_W,S_H,BG_C) class Ehandler: def __init__(s):s.kp=[] def k_pressed(s,k): ap=k in s.kp if iokd(k): if not ap:s.kp.append(k);return True elif ap:s.kp.remove(k) return False class Engine: def __init__(s): s.sheet=None s.curs_x=0 s.curs_y=0 s.zoom=10 s.move_s=0 s.move_cd=0 s.co_menu_o=False s.tb_menu_o=False s.ev_handler=Ehandler() s.c_select=0 s.tb_select=0 s.open=False def controls_curs(s): t=0 lcx=s.curs_x lcy=s.curs_y if s.move_cd-time.monotonic()<0: if iokd(IOKR): s.curs_x+=1 t=1 if iokd(IOKL): s.curs_x-=1 t=1 if iokd(IOKU): s.curs_y-=1 t=1 if iokd(IOKD): s.curs_y+=1 t=1 if not t: s.move_s=0 if t: if s.curs_x<-s.sheet.w//2: s.curs_x=-s.sheet.w//2 if s.curs_x>s.sheet.w//2-1: s.curs_x=s.sheet.w//2-1 if s.curs_y<-s.sheet.h//2: s.curs_y=-s.sheet.h//2 if s.curs_y>s.sheet.h//2-1: s.curs_y=s.sheet.h//2-1 if s.move_s==0: s.move_s=1 s.move_cd=time.monotonic()+0.6 elif s.move_s==1: s.move_cd=time.monotonic()+0.05 if iokd(IOKK): if s.tb_select==0: s.sheet.set_at(s.curs_x+s.sheet.w//2,s.curs_y+s.sheet.h//2,s.c_select) t=1 if s.tb_select==1 and not IOKK in s.ev_handler.kp: s.sheet.fill(s.curs_x+s.sheet.w//2,s.curs_y+s.sheet.h//2,s.c_select) t=2 if not IOKK in s.ev_handler.kp: s.ev_handler.kp.append(IOKK) elif IOKK in s.ev_handler.kp: s.ev_handler.kp.remove(IOKK) if iokd(ion.KEY_BACKSPACE): s.open=False return t,lcx,lcy def check_menu(s): t=False if s.ev_handler.k_pressed(ion.KEY_TOOLBOX): s.tb_menu_o=not s.tb_menu_o s.co_menu_o=False t=True if s.ev_handler.k_pressed(ion.KEY_VAR): s.co_menu_o=not s.co_menu_o s.tb_menu_o=False t=True return t def new(s,w,h): s.sheet=Sheet(w,h) def render_curs(s): x=s.curs_x*s.zoom+S_W//2+s.zoom//2 y=s.curs_y*s.zoom+S_H//2+s.zoom//2 c=(0,0,0) spx(x-1,y,c);spx(x+1,y,c);spx(x-1,y-1,c);spx(x-1,y+1,c);spx(x+1,y-1,c);spx(x+1,y+1,c);spx(x,y+1,c);spx(x,y-1,c) spx(x,y+2,c);spx(x,y-2,c);spx(x,y+3,c);spx(x,y-3,c);spx(x-2,y,c);spx(x+2,y,c);spx(x-3,y,c);spx(x+3,y,c) def menus_controls(s): t=False if s.co_menu_o or s.tb_menu_o: if s.ev_handler.k_pressed(IOKR): if s.co_menu_o: if s.c_select<len(s.sheet.colorp)-1: s.c_select+=1 t=True elif s.tb_menu_o: s.tb_select+=1 if s.tb_select>4: s.tb_select=4 t=True if s.ev_handler.k_pressed(IOKL): if s.co_menu_o: if s.c_select>0: s.c_select-=1 t=True elif s.tb_menu_o: s.tb_select-=1 if s.tb_select<0: s.tb_select=0 t=True if s.ev_handler.k_pressed(IOKD): if s.co_menu_o: s.c_select+=5 t=True if s.c_select+1>=len(s.sheet.colorp): s.c_select=len(s.sheet.colorp)-1 if s.ev_handler.k_pressed(IOKU): if s.co_menu_o: s.c_select-=5 t=True if s.c_select<0: s.c_select=0 return t def render_menus(s): if s.co_menu_o: fr(15,S_H-50,S_W-30,50,BGM_C) fr(15,S_H-50,S_W-30,1,(100,100,100)) fr(15,S_H-50,1,50,(100,100,100)) fr(S_W-15,S_H-50,1,50,(100,100,100)) c_per_row=5 yi=s.c_select//c_per_row for i in range(c_per_row): gi=yi*c_per_row+i if gi<len(s.sheet.colorp): if gi==s.c_select: fr(37+i*54,S_H-38,32,32,(255,200,0)) else: fr(39+i*54,S_H-36,28,28,(100,100,100)) if gi==0:# if transparent fr(40,S_H-35,26,26,(230,230,230)) fr(40,S_H-35,13,13,(50,50,50)) fr(40+13,S_H-35+13,13,13,(50,50,50)) else: if gi<len(s.sheet.colorp): c=s.sheet.colorp[gi] fr(40+i*54,S_H-35,26,26,c) if s.tb_menu_o: fr(15,S_H-50,S_W-30,50,BGM_C) c=(100,100,100) fr(15,S_H-50,S_W-30,1,c) fr(15,S_H-50,1,50,c) fr(S_W-15,S_H-50,1,50,c) for i in range(5): if i==s.tb_select: fr(37+i*54,S_H-38,32,32,(255,200,0)) else: fr(39+i*54,S_H-36,28,28,(100,100,100)) fr(40+i*54,S_H-35,26,26,(200,200,200)) x=41+i*54 y=S_H-35 s.place_ico(i,x,y) def place_ico(s,i,x,y): cc=s.sheet.colorp[s.c_select] if i==0: fr(x+5,y+9,1,1,BC);fr(x+6,y+8,1,3,BC);fr(x+7,y+7,1,5,BC);fr(x+8,y+8,1,5,BC);fr(x+9,y+9,1,5,BC);fr(x+10,y+10,1,5,BC);fr(x+11,y+11,1,5,BC);fr(x+12,y+12,1,5,BC);fr(x+13,y+13,1,3,BC);fr(x+14,y+14,1,1,BC) fr(x+14,y+18,1,1,cc);fr(x+15,y+17,1,2,cc);fr(x+16,y+16,1,3,cc) elif i==1: fr(x+5,y+6,12,15,BC);fr(x+7,y+6,8,13,(150,150,150));fr(x+7,y+8,8,11,cc) fr(x+3,y+8,2,6,BC);fr(x+20,y+7,3,3,cc) def render_UI(s): ds("md:",5,22,(0,0,0),BG_C) s.place_ico(s.tb_select,33,20) def render(s,full=True,lcx=0,lcy=0): if full: cl() if s.sheet != None: s.sheet.render(s.zoom,0,0) s.render_menus() s.render_UI() else: if s.sheet != None: s.sheet.render_area(lcx-s.sheet.w//2,lcy-s.sheet.h//2,1,1,0,0,s.zoom) s.render_curs() def update(s): tt=s.check_menu() tm=s.menus_controls() t=False if not (s.co_menu_o or s.tb_menu_o): t,lcx,lcy=s.controls_curs() if t==1: s.render(False,lcx,lcy) if tt or t==2: s.render() if tm: s.render_menus() def loop(s): s.curs_x=s.curs_y=0 s.ev_handler.kp.append(IOKK) s.render() s.open=True while s.open: s.update() class Sheet: def __init__(s,w,h): s.pixels=np.zeros((w,h),dtype=np.int8) s.w,s.h=w,h s.colorp=[(0,0,0)] s.c_i=1 #0 =no c def load(s,pixels,w,h): s.pixels=pixels s.w=w;s.h=h def colorp_add(s,rgb): s.colorp.append(rgb) s.c_i+=1 def set_at(s,x,y,c): s.pixels[x,y]=c def fill(s,x,y,rc): bc=s.pixels[x,y] if rc==bc: return todo=[(x,y)] while len(todo)>0: for p in todo.copy(): x,y=p if x+1<s.w and s.pixels[x+1,y]==bc and not (x+1,y) in todo: todo.append((x+1,y)) if x-1>=0 and s.pixels[x-1,y]==bc and not (x-1,y) in todo: todo.append((x-1,y)) if y+1<s.h and s.pixels[x,y+1]==bc and not (x,y+1) in todo: todo.append((x,y+1)) if y-1>=0 and s.pixels[x,y-1]==bc and not (x,y-1) in todo: todo.append((x,y-1)) if s.pixels[x,y]==bc: s.set_at(x,y,rc) todo.remove(p) def render(s,z,cx,cy): xs=cx-int(s.w*z/2)+S_W//2 ys=cy-int(s.h*z/2)+S_H//2 for x in range(s.w): for y in range(s.h): v=s.pixels[x,y] if v: fr(xs+x*z,ys+y*z,z,z,s.colorp[v]) xe=xs+s.w*z;ye=ys+s.h*z for y in range(ys-1,ye+1): spx(xs-1,y,(0,0,0));spx(xe,y,(0,0,0)) for x in range(xs-1,xe+1): spx(x,ys-1,(0,0,0));spx(x,ye,(0,0,0)) def render_area(s,x,y,w,h,cx,cy,z): cx+=S_W//2+s.w*z//2 cy+=S_H//2+s.h*z//2 for xx in range(x,x+w): for yy in range(y,y+h): v=s.pixels[xx,yy] if v: fr(cx+xx*z,cy+yy*z,z,z,s.colorp[v]) else: fr(cx+xx*z,cy+yy*z,z,z,BG_C) class SavingMng: def __init__(s): s.open=False s.ev_handler=Ehandler() s.select_i=0 @staticmethod def get_save(sh): d="";i=0 for y in range(sh.h): for x in range(sh.w): p=sh.pixels[x,y] d+=pa[p] return d @staticmethod def print_save(sh): sav=SavingMng.get_save(sh) print("Copy the following string:") for i in range(int(ceil(len(sav)/MAX_DATA_LEN))): print("'"+sav[i*MAX_DATA_LEN:i*MAX_DATA_LEN+MAX_DATA_LEN]+"'") def render_list(s,l): fr(15,65,S_W-30,S_H-75,BGM_C) c=(230,230,230) scr_y=s.select_i//4 for i in range(min(len(l)-scr_y*4,4)): if i+scr_y*4==s.select_i: fr(17,67+i*35,S_W-34,36,(200,200,0)) fr(20,70+i*35,S_W-40,30,c) ds(l[i][:26],25,75+i*35,(0,0,0),c) def controls(s,l): t=0 if s.ev_handler.k_pressed(IOKU): s.select_i-=1 t=1 if s.ev_handler.k_pressed(IOKD): s.select_i+=1 t=1 s.select_i%=len(l) if s.ev_handler.k_pressed(IOKK): t=2 return t def render(s,l): cl() ds("Select img:",10,10,BC,BG_C) s.render_list(l) def loop(s,m,file): s.ev_handler.kp.append(IOKK) if m and file!=None: l=list(file.img.keys()) l.sort() s.render(l) t=0 while t!=2: t=s.controls(l) if t==1:s.render(l) d=file.img[l[s.select_i]] return d,int(sqrt(len(d))) else: cl() ds("To load img in paint, create a",5,20,BC,BG_C);ds('"paintload.py" file and put',5,40,BC,BG_C);ds("your images into it like this:",5,60,BC,BG_C) ds("img={",5,100,BC,BG_C);ds(' "img name 1":',5,120,BC,BG_C);ds(' "data 1"',5,140,BC,BG_C) ds(' +"data 2", # other data',5,160,BC,BG_C);ds('}" # other images',5,180,BC,BG_C) time.sleep(6) def ask_code(s): try: file=__import__("paintload") if type(file.img)==dict: d=s.loop(1,file);sz=d[1];dt=np.zeros((sz,sz),dtype=np.int8) for i in range(sz*sz): dt[i%sz,i//sz]=pa.index(d[0][i]) return dt,sz except (ImportError,AttributeError): s.loop(0,None) class Main: def __init__(s): s.en=Engine() s.en.new(16,16) s.m=MainMenu() s.sav_mng=SavingMng() def load_c(s): for i in colors: s.en.sheet.colorp_add(i) def mainmenu(s): t=s.m.loop() if t==0: s.startpaint() return 1 if t==1: n_sh=s.sav_mng.ask_code() if n_sh is None:return 1 s.en.sheet.load(n_sh[0],n_sh[1],n_sh[1]) if n_sh[1]: s.startpaint() return 1 if t==2: s.sav_mng.print_save(s.en.sheet) return 0 def startpaint(s): s.en.loop() def loop(s): s.curs_x=s.curs_y=0 cont=1 while cont: cont=s.mainmenu() class MainMenu: def __init__(s): s.select_btn=0 s.ev_handler=Ehandler() s.open=False def controls(s): t=0 if s.ev_handler.k_pressed(IOKD): s.select_btn+=1 t=1 if s.ev_handler.k_pressed(IOKU): if s.select_btn==1 or s.select_btn==2: s.select_btn=0 t=1 if s.ev_handler.k_pressed(IOKR): if s.select_btn==1: s.select_btn+=1 t=1 if s.ev_handler.k_pressed(IOKL): if s.select_btn==2: s.select_btn-=1 t=1 if s.select_btn<0: s.select_btn=0 t=0 elif s.select_btn>2: s.select_btn=2 t=0 if iokd(IOKK): s.open=False return t def loop(s): s.open=True s.render() while s.open: s.update() return s.select_btn def update(s): if s.controls(): s.rend_btns() def render(s): cl() ds("PaintWorks",(S_W-10*10)//2,45,(0,0,0),BG_C) s.rend_btns() def rend_btns(s): s.r_btn("New/continue drawing",250,0,100,s.select_btn==0) s.r_btn("Load art",120,-65,140,s.select_btn==1) s.r_btn("Save art",120,65,140,s.select_btn==2) def r_btn(s,txt,w,x,y,select): if select: c=(170,170,170) else: c=(200,200,200) fr((S_W-w)//2+x,y,w,30,c);fr((S_W-w)//2+x,y,w,1,(150,150,150));fr((S_W-w)//2+x,y+30,w+1,1,(150,150,150));fr((S_W-w)//2+x,y,1,30,(150,150,150));fr((S_W+w)//2+x,y,1,30,(150,150,150)) ds(txt,(S_W-10*len(txt))//2+x,y+6,(0,0,0),c) colors=[ (0,0,0),(85,85,85),(170,170,170),(255,255,255), (51,0,0),(102,0,0),(153,0,0),(204,0,0),(255,0,0), (0,51,0),(0,102,0),(0,153,0),(0,191,0),(0,255,0), (0,0,51),(0,0,102),(0,0,153),(0,0,191),(0,0,255), (51,51,0),(102,102,0),(153,153,0),(191,191,0),(255,255,0), (0,51,51),(0,102,102),(0,153,153),(0,191,191),(0,255,255), (51,0,51),(102,0,102),(153,0,153),(191,0,191),(255,0,255), (42,255,255),(85,255,255),(127,255,255),(170,255,255),(212,255,255), (255,42,255),(255,85,255),(255,127,255),(255,170,255),(255,212,255), (255,255,42),(255,255,85),(255,255,127),(255,255,170),(255,255,212), (42,42,255),(85,85,255),(127,127,255),(170,170,255),(212,212,255), (255,42,42),(255,85,85),(255,127,127),(255,170,170),(255,212,212), (42,255,42),(85,255,85),(127,255,127),(170,255,170),(212,255,212), ] main=Main() main.load_c() try: main.loop() except KeyboardInterrupt: pass cl() ds("Press [ok] to exit.",10,10,(0,0,0),BG_C)