EXEC.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. import json
  2. import time
  3. import sys
  4. import tkinter as tk
  5. from tkinter import font
  6. import traceback
  7. import _thread as thread
  8. import dialog
  9. DIALOG = dialog.Dialog()
  10. gui=None
  11. GLOBAL_old_btn_nr = -1
  12. def Dcb(exec_nr): #DAILOG CONFIG CALLBACK
  13. def _Dcb(*args):
  14. print("Dcb:",args)
  15. msg=json.dumps([{"event":"EXEC-CFG","EXEC":exec_nr,"VALUE":255,"DATA":args[0]}]).encode("utf-8")
  16. cprint("SEND DIALOG.cb",msg,color="green")
  17. cmd_client.send(msg)
  18. def _X_refresh():
  19. global GLOBAL_old_btn_nr
  20. if 1:#REFRESH:
  21. btn_nr = exec_nr
  22. time.sleep(1.2)
  23. print()
  24. print("CFG CB REFRESH !?",btn_nr)
  25. nr = btn_nr-1
  26. b = gui.elem_exec[nr]
  27. gui._refresh_exec_single(nr,b) #,METAS):
  28. time.sleep(0.2)
  29. nr2= GLOBAL_old_btn_nr
  30. if nr2 >= 0 and nr2 != nr:
  31. gui._refresh_exec_single(nr2,b) #,METAS):
  32. print("CFG CB2 REFRESH ",nr,nr2)
  33. if 1:
  34. GLOBAL_old_btn_nr = nr
  35. thread.start_new_thread(_X_refresh,())
  36. return _Dcb
  37. DIALOG._cb = Dcb(-3)
  38. #d = dialog.Dialog()
  39. #d.ask_exec_config(str(nr+1),button=button,label=label,cfg=cfg)
  40. import __main__ as MAIN
  41. _file_path = "/opt/LibreLight/Xdesk/"
  42. sys.path.insert(0,"/opt/LibreLight/Xdesk/")
  43. import tool.git as git
  44. #CAPTION += git.get_all()
  45. CAPTION = "TK-EXEC"
  46. title = CAPTION
  47. title += git.get_all()
  48. INIT_OK = 1
  49. IS_GUI = 0
  50. from lib.cprint import cprint
  51. import lib.libtk as libtk
  52. import lib.zchat as chat
  53. import lib.mytklib as mytklib
  54. import lib.tkevent as tkevent
  55. #import tkgui.draw as draw
  56. def draw_exec(gui,xframe,EXEC):
  57. i=0
  58. c=0
  59. r=0
  60. root = xframe
  61. frame = tk.Frame(root,bg="black")
  62. frame.pack(fill=tk.X, side=tk.TOP)
  63. gui.elem_exec = {}
  64. i=0
  65. for k in EXEC.val_exec:
  66. if i%(10*8)==0 or i ==0:
  67. c=0
  68. b = tk.Canvas(frame,bg="black", height=4,bd=0,width=6,highlightthickness=0) #,bd="black")
  69. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  70. r+=1
  71. c=0
  72. b = tk.Button(frame,bg="lightblue", text="EXEC " )
  73. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  74. c+=1
  75. b = tk.Button(frame,bg="lightblue", text="BANK " + str(int(i/(8*8))+1) )
  76. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  77. c+=1
  78. b = tk.Button(frame,bg="lightblue", text="NAME" )
  79. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  80. c+=7
  81. if i == 0:
  82. b = tk.Button(frame,bg="darkgrey", text="HELP",command=libtk.online_help("librelight:20-exec")) #"0&do=index"))
  83. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  84. r+=1
  85. c=0
  86. i+=1
  87. v=0
  88. label = ""
  89. sdata=EXEC.val_exec[k]
  90. BTN="go"
  91. if "CFG" in sdata:#["BUTTON"] = "GO"
  92. if "BUTTON" in sdata["CFG"]:
  93. BTN = sdata["CFG"]["BUTTON"]
  94. txt=str(k+1)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label
  95. b = mytklib.ExecButton(frame,text=txt)
  96. b.bind("<Button>", tkevent.tk_event(fix=0,elem=b,attr=k,data=gui,mode="EXEC").cb)
  97. b.bind("<ButtonRelease>",tkevent.tk_event(fix=0,elem=b,attr=k,data=gui,mode="EXEC").cb)
  98. if k not in gui.elem_exec:
  99. gui.elem_exec[k] = b
  100. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  101. b.config(text="xx"+str(i))
  102. c+=1
  103. if c >=10:
  104. c=0
  105. r+=1
  106. time.sleep(0.1)
  107. gui._refresh_exec()
  108. print("##################################")
  109. import tool.movewin as movewin
  110. #movewin.check_is_started(CAPTION,_file_path)
  111. movewin.check_is_started("EXEC","/opt/LibreLight/Xdesk/tkgui/EXEC.py")
  112. _global_short_key = 1
  113. root = None
  114. cmd_client = chat.Client(port=30003)
  115. try:
  116. import memcache
  117. mc = memcache.Client(['127.0.0.1:11211'], debug=0)
  118. except:
  119. mc = None
  120. class Refresher(): # DUMMY
  121. def __init__(self,*arg,**args):
  122. print(self,"__init__",arg,args)
  123. def reset(*arg,**args):
  124. print(self,"reset",arg,args)
  125. class Command():
  126. def __init__(self):
  127. self.elem = {}
  128. class MASTER(): # DUMMY
  129. def __init__(self,*arg,**args):
  130. print(self,"__init__",arg,args)
  131. #self.refresh_fix = Refresher()
  132. self.commands = Command()
  133. def refresh_fix(self,*arg,**args):# = Refresher()
  134. print(self,"refresh_fix",arg,args)
  135. def exec_go(self,nr,*arg,**args): #val=None,xfade=None,event=None,button="",ptfade=None):
  136. if _global_key_lock:
  137. return
  138. #def exec_go(nr,xfade=None,val=0):
  139. print(self,"MASTER",nr,arg,args)
  140. btn_nr = nr
  141. v = args["val"]
  142. msg=json.dumps([{"event":"EXEC","EXEC":btn_nr+1,"VAL":v,"NR-KEY":btn_nr}]).encode("utf-8")
  143. cprint("SEND MASTER.EXEC_GO:",msg,color="green")
  144. cmd_client.send(msg)
  145. def refresh_fix(*arg,**args): # DUMMY
  146. print("refresh_fix",arg,args)
  147. class Refresher_fix(): # DUMMY
  148. def __init__(self,*arg,**args):
  149. print(self,"init",arg,args)
  150. def reset(self,*arg,**args):
  151. print(self,"reset",arg,args)
  152. refresher_fix = Refresher_fix()
  153. class Modes(): # DUMMY
  154. def __init__(self,*arg,**args):
  155. print("Modes.__init__",arg,args)
  156. self.modes = {}
  157. def val(self,*arg,**args):
  158. #print("Modes.val",arg,args)
  159. pass
  160. master = MASTER() #{}
  161. modes = Modes()
  162. import tkinter as tk
  163. class Exec(): # DUMMY
  164. def __init__(self):
  165. self.val_exec = {}
  166. for i in range(512):
  167. k=i #"ABC-{}".format(i+1)
  168. self.val_exec[k] = {"NAME":"XX"}
  169. EXEC = Exec()
  170. class Gui(): # DUMMY
  171. def __init__(self):
  172. self.elem_exec = []
  173. self.elem_meta = [None]*512
  174. self.old_btn_nr = -1
  175. self.METAS = []
  176. for i in range(512):
  177. self.METAS.append({})
  178. def _refresh_exec(self,*arg,**args):
  179. #print("EXEC_Gui._refresh_exec",arg,args)
  180. nr = 14-1
  181. METAS = []
  182. for i in range(512):
  183. nr = i #+1
  184. try:
  185. data = mc.get("EXEC-META-"+str(nr)) #,json.dumps(index))
  186. data = json.loads(data)
  187. METAS.append(data)
  188. except Exception as e:
  189. print(" ER1R mc...",e)
  190. self.METAS = METAS
  191. for nr,b in enumerate( self.elem_exec): #[nr]
  192. self._refresh_exec_single(nr,b,METAS)
  193. #time.sleep(0.001)
  194. def _refresh_exec_single(self,nr,b,METAS=None):
  195. if not METAS:
  196. try:
  197. data = mc.get("EXEC-META-"+str(nr)) #,json.dumps(index))
  198. data = json.loads(data)
  199. self.METAS[nr] = data #.append(data)
  200. print(time.time())
  201. print(" _REFRESH_EXEC_SINGLE",nr,b,data)
  202. except Exception as e:
  203. print(" ER1R mc...",e)
  204. METAS = self.METAS
  205. _bg = "grey"
  206. _ba = "grey"
  207. _bg = "grey"
  208. _fg = "#555" #darkgrey"
  209. _text = "0 N/V 0\n N/V"
  210. txt = "None/nNone"
  211. txt1 = "None/nNone"
  212. out = {} # default
  213. out["fx"] = ""
  214. out["bg"] = _bg # "grey"
  215. out["ba"] = _ba #"grey"
  216. out["fg"] = _fg
  217. out["text"] = _text #"? "+str(nr+1)
  218. META = {'LABEL': 'ERR', 'CFG': {}}
  219. META["CFG"] = {'FADE': 3.0, 'DEALY': 0, 'DELAY': 4.0, 'BUTTON': 'ON', 'HTP-MASTER': 100
  220. ,'SIZE-MASTER': 100, 'SPEED-MASTER': 100, 'OFFSET-MASTER': 100, 'OUT-FADE': 10.0
  221. ,'FIX-COUNT':0 ,'HAVE-FX':0,'HAVE-VAL':0
  222. }
  223. try:
  224. META = METAS[nr]
  225. label = "{} {} {}\n{}".format(nr+1,META["CFG"]["BUTTON"],META["CFG"]["FIX-COUNT"],META["LABEL"])
  226. out["text"] = str(label)
  227. except Exception as e:
  228. print(" ER4R",e,nr)
  229. time.sleep(0.001)
  230. try:
  231. txt1 = META["CFG"]["BUTTON"]
  232. except:
  233. pass
  234. if META["CFG"]["FIX-COUNT"]:
  235. _fg = "black"
  236. if META["CFG"]["HAVE-VAL"]:
  237. _fg = "black"
  238. _bg = "gold"
  239. _ba = "#ffaa55"
  240. if "SEL" in txt1:
  241. #_bg = "blue"
  242. #_fg = "blue"
  243. _bg = "#77f"
  244. elif "ON" in txt1:
  245. _fg = "#040"
  246. _fg = "black"
  247. elif "GO" in txt1:
  248. _fg = "#555"
  249. _fg = "black"
  250. out["fx"] = ""
  251. if META["CFG"]["HAVE-FX"] >= 1:
  252. out["fx"] = META["CFG"]["HAVE-FX"] # show FX on EXEC-BTN
  253. if META["CFG"]["HAVE-FX"] >= 1 and META["CFG"]["HAVE-VAL"] == 0:
  254. _bg = "cyan"
  255. if "FL" in txt1:
  256. _fg = "#00e"
  257. out["fg"] = _fg #= "#00e"
  258. out["bg"] = _bg #= "#00e"
  259. cfg = out
  260. self.elem_meta[nr] = META
  261. b = self.elem_exec[nr]
  262. b.configure(fg=cfg["fg"],bg=cfg["bg"],activebackground=cfg["ba"],text=cfg["text"],fx=cfg["fx"])
  263. def exec_go(self,*arg,**args):
  264. print("Gui.exec_go",arg,args)
  265. btn_nr = arg[0]
  266. v=args["val"]
  267. if "CFG-BTN" in modes.modes:
  268. button = self.elem_exec[btn_nr]
  269. label = str(btn_nr) #self.elem_meta[nr] = META
  270. if v:
  271. META = self.elem_meta[btn_nr]
  272. print("META",META)
  273. cfg = META["CFG"]
  274. label = META["LABEL"]
  275. button = cfg["BUTTON"]
  276. DIALOG._cb = Dcb(btn_nr+1)
  277. DIALOG.ask_exec_config(str(btn_nr+1),button=button,label=label,cfg=cfg)
  278. #print("INFO",master.commands.elem)
  279. return #STOP
  280. PREFIX = ""
  281. REFRESH = 0
  282. for k in ["REC","EDIT","COPY","MOVE","DEL","REC-FX"]:#,"SELECT","FLASH","GO","EDIT"]:
  283. if k in modes.modes:
  284. PREFIX = str(k) #+"-"
  285. for k in ["REC","COPY","MOVE","DEL","REC-FX"]:
  286. if k in modes.modes:
  287. REFRESH = 1
  288. print(" ",[arg,args])
  289. edata={}
  290. if "event" in args:
  291. edata = serialize_event(args["event"])
  292. print(" ",edata)
  293. num = -1
  294. MOUSE = ""
  295. out={"event": "EXEC","EXEC":btn_nr+1,"VAL":v,"NR-KEY":btn_nr}
  296. if "num" in edata:
  297. num = edata["num"]
  298. if num == 1:
  299. out["MOUSE"]="LEFT"
  300. if num == 3:
  301. out["MOUSE"]="RIGHT"
  302. msg=json.dumps([out]).encode("utf-8")
  303. if not _global_key_lock:
  304. cmd_client.send(msg)
  305. cprint("SEND GUI.EXEC_GO",msg,color="green")
  306. def _X_refresh():
  307. #if 1:#REFRESH:
  308. time.sleep(0.2)
  309. print()
  310. print("REC REFRESH !?",PREFIX)
  311. nr = btn_nr
  312. b = self.elem_exec[nr]
  313. self._refresh_exec_single(nr,b) #,METAS):
  314. time.sleep(0.4)
  315. if self.old_btn_nr >= 0 and self.old_btn_nr != nr:
  316. self._refresh_exec_single(self.old_btn_nr,b) #,METAS):
  317. print(" REFRESH EXEC ",nr,self.old_btn_nr)
  318. #time.sleep(0.2)
  319. #self._refresh_exec()
  320. if v:
  321. self.old_btn_nr = nr
  322. thread.start_new_thread(_X_refresh,())
  323. gui = Gui()
  324. #import memcache
  325. #mc = memcache.Client(['127.0.0.1:11211'], debug=0)
  326. #import time
  327. #while 1:
  328. # x=mc.get("MODE")
  329. # print(x)
  330. # time.sleep(1)
  331. import lib.libwin as libwin
  332. name="EXEC"
  333. pos_list = libwin.read_window_position()
  334. geo = libwin.split_window_position(pos_list,name)
  335. args = {"title":name,"master":0,"width":600,"height":113,"left":30+5,"top":30+5+400*2+10}
  336. if geo:
  337. args.update(geo)
  338. root = tk.Tk()
  339. win_title="TK-EXEC"
  340. store = movewin.load_all_sdl(win_title)
  341. print(store)
  342. W=850
  343. H=460
  344. POS=None
  345. if store:
  346. W = store[-4]
  347. H = store[-3]
  348. POS=[store[-2],store[-1]]
  349. root.geometry('%dx%d+%d+%d' % (W, H, POS[0],POS[1]))
  350. #win_con = movewin.Control()
  351. #win_con.title = win_title
  352. #def asdf(event=None):
  353. # time.sleep(3)
  354. # win_con.winfo()
  355. # if POS:
  356. # #print(" REPOS ---")
  357. # win_con.move(POS[0],POS[1])
  358. #thread.start_new_thread(asdf,())
  359. #print(POS,win_con.title)
  360. #root.withdraw() # do not draw
  361. #root.resizable(1,1)
  362. root.tk_setPalette(background='#bbb', foreground='black', activeBackground='#aaa', activeForeground="black")
  363. defaultFont = tk.font.nametofont("TkDefaultFont")
  364. #cprint(defaultFont)
  365. defaultFont.configure(family="FreeSans",
  366. size=10,
  367. weight="bold")
  368. # MAIN MENUE
  369. try:
  370. ico_path = "/opt/LibreLight/Xdesk/icon/"
  371. root.iconphoto(False, tk.PhotoImage(file=ico_path+"exec.png"))
  372. except Exception as e:
  373. print(" Exception GUIWindowContainer.__init__",e)
  374. #xframe=root
  375. xframe = libtk.ScrollFrame(root,width=820,height=400,bd=1,bg="black",head=None,foot=None)
  376. #draw.draw_exec(gui,xframe,EXEC)
  377. draw_exec(gui,xframe,EXEC)
  378. #xframe.pack()
  379. root.title(title)#"TK-EXEC")
  380. def serialize_event(event):
  381. data = {}
  382. for k in dir(event):
  383. if k.startswith("_"):
  384. continue
  385. v = event.__getattribute__(k)
  386. if v == '??':
  387. continue
  388. if type(v) not in [int,str,float]:
  389. continue
  390. data[k] = v
  391. data["event"] = str(event).split()[0][1:]
  392. if "state" in data:
  393. del data["state"]
  394. if "time" in data:
  395. del data["time"]
  396. if "serial" in data:
  397. del data["serial"]
  398. keys = list(data.keys())
  399. keys.sort()
  400. data2={}
  401. for k in keys:
  402. data2[k] = data[k]
  403. return data2
  404. Control_L = 0
  405. Alt_L = 0
  406. def tk_event(event,data={}):
  407. #print("tk_event",event,data)
  408. global Control_L,Alt_L
  409. if _global_key_lock:
  410. return
  411. #print(" ",dir(event)) #.dict())
  412. data = serialize_event(event)
  413. if 'keysym' in data:
  414. keysym = data["keysym"]
  415. if keysym == 'Control_L':
  416. if "Press" in data["event"]:
  417. Control_L = 1
  418. if "Release" in data["event"]:
  419. Control_L = 0
  420. if keysym == 'Alt_L':
  421. if "Press" in data["event"]:
  422. Alt_L = 1
  423. if "Release" in data["event"]:
  424. Alt_L = 0
  425. data["Alt_L"] = Alt_L
  426. data["Control_L"] = Control_L
  427. print("tk_event",data)
  428. ok=0
  429. # CONTROL + KEY
  430. key_code = {"s":"SAVE\nSHOW","c":"RESTART" }
  431. if 'keysym' in data:
  432. keysym = data["keysym"]
  433. if keysym in key_code:
  434. if "Press" in data['event'] and data["Control_L"]:
  435. MOD = key_code[keysym]
  436. msg=json.dumps([{"event":MOD}]).encode("utf-8")
  437. cprint("SEND tk_event",msg,color="green")
  438. cmd_client.send(msg)
  439. if MOD in ["RESTART"]:
  440. time.sleep(2)
  441. exit()
  442. ok = 1
  443. if ok:
  444. return
  445. # NORMAL KEY
  446. key_code = {"r":"REC","x":"REC-FX","e":"EDIT","c":"CFG-BTN"
  447. ,"m":"MOVE","Delete":"DEL","End":"FX-OFF"
  448. ,"Escape":"ESC","s":"SELECT","f":"FLASH"
  449. ,"C":"COPY","d":"DEL"
  450. }
  451. if 'keysym' in data:
  452. keysym = data["keysym"]
  453. if keysym in key_code:
  454. if "Press" in data['event']:
  455. MOD = key_code[keysym]
  456. msg=json.dumps([{"event":MOD}]).encode("utf-8")
  457. cprint("SEND tk_event",msg,color="green")
  458. cmd_client.send(msg)
  459. ok = 1
  460. if not ok:
  461. libtk.tk_keyboard_callback(event,data=data)
  462. root.bind("<Button>",tk_event)#
  463. root.bind("<Key>",tk_event)#,self.callback)
  464. root.bind("<KeyRelease>",tk_event)#,self.callback)
  465. #root.bind("<FocusIn>",tk_event)#, on_focus(self.args["title"],"In").cb)
  466. #root.bind("<FocusOut>",tk_event)#, on_focus(self.args["title"],"Out").cb)
  467. import os
  468. _global_key_lock = 0
  469. def focus_in(event=None):
  470. _global_short_key = 0 # protect key-press-repeat
  471. cmd = "xset -display :0.0 r off"
  472. print("FOCUS_IN1", cmd)
  473. os.system(cmd)
  474. time.sleep(0.3)
  475. print("FOCUS_IN2", cmd)
  476. os.system(cmd)
  477. _global_short_key = 1 # protect key-press-repeat
  478. time.sleep(0.3)
  479. _global_key_lock = 0
  480. def focus_out(event=None):
  481. _global_key_lock = 1
  482. _global_short_key = 0
  483. cmd="xset -display :0.0 r rate 240 20"
  484. print("FOCUS_OUT", cmd)
  485. #os.system(cmd) # DISABLED
  486. root.bind("<FocusIn>", focus_in)
  487. root.bind("<FocusOut>", focus_out)
  488. def _refr_loop():
  489. time.sleep(3)
  490. while 1:
  491. gui._refresh_exec()
  492. time.sleep(10)
  493. thread.start_new_thread(_refr_loop,())
  494. def _refr_loop2():
  495. time.sleep(3)
  496. while 1:
  497. try:
  498. global root,title
  499. data = mc.get("MODES")
  500. title2 = title +" "+str(data)
  501. data = json.loads(data)
  502. #print("MODES",data)
  503. modes.modes = data
  504. if "S-KEY" in data:
  505. _global_short_key = 0
  506. if data["S-KEY"]:
  507. _global_short_key = 1
  508. if root:
  509. root.title(title2)
  510. except Exception as e:
  511. print(" ER7R mc...",e)
  512. time.sleep(3)
  513. time.sleep(0.1)
  514. thread.start_new_thread(_refr_loop2,())
  515. root.mainloop()