sdl_elm.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. #!/usr/bin/python3
  2. import pygame
  3. import pygame.gfxdraw
  4. import pygame.font
  5. from lib.xcolor import *
  6. font0 = pygame.font.SysFont("freesans",10)
  7. font0b = pygame.font.SysFont("freesansbold",10)
  8. font = pygame.font.SysFont("freemonobold",22)
  9. font10 = pygame.font.SysFont("freemonobold",10)
  10. font12 = pygame.font.SysFont("freemonobold",12)
  11. font15 = pygame.font.SysFont("freemonobold",15)
  12. font22 = pygame.font.SysFont("FreeSans",22)
  13. #font = pygame.font.SysFont(None,30)
  14. class VALUE():
  15. def __init__(self,v=0,_min=0,_max=255):
  16. self._val = v
  17. self._max = _max
  18. self._min = _min
  19. def _check(self):
  20. if self._val > self._max:
  21. self._val = self._max
  22. if self._val < self._min:
  23. self._val = self._min
  24. def get(self):
  25. self._check()
  26. return self._val
  27. def set(self,val):
  28. if val <= self._max and val >= self._min:
  29. self._val = val
  30. def inc(self,v):
  31. self._val += v
  32. self._check()
  33. class ELEM_KILLGROUP():
  34. def __init__(self):
  35. self.data = []
  36. def insert(self,elm):
  37. if elm not in self.data:
  38. self.data.append(elm)
  39. return 1
  40. return 0
  41. def clean(self,elm):
  42. v = elm.val
  43. for i in self.data:
  44. i.clear()
  45. #elm.set(v)
  46. return v
  47. class CALLBACK():
  48. def __init__(self):
  49. self._cb = self.dummy
  50. self.ok = 0
  51. def cb(self,*args):
  52. if self.ok:
  53. print("CALLBACK.cb",args)
  54. #try:
  55. self._cb(args)
  56. #except Exception as e:
  57. # print(" Exception CALLBACK.cb",args)
  58. def dummy(self,arg):
  59. print("CALLBACK.dummy",arg)
  60. def set(self,cb):
  61. self._cb = cb
  62. self.ok = 1
  63. print("CALLBACK",cb)
  64. class ELEM_BUF():
  65. def __init__(self,kill=None,name="ELEM_BUF"):
  66. self.val = VALUE() #0
  67. self.increment = 10
  68. self.name = name
  69. self.cb_on = CALLBACK()
  70. self.cb_off = CALLBACK()
  71. self.nr_on = [0]
  72. self.nr_off = [0]
  73. self.color = [0,255,0]
  74. self.color_on = [255,255,0]
  75. self.type="flash" #"toggle" #"flash",fade
  76. self.killgroup = kill
  77. self.events = []
  78. def get_event(self):
  79. out = self.events[:]
  80. self.events = []
  81. return out
  82. def get(self):
  83. return self.val.get()
  84. def get_color(self):
  85. if self.val.get():
  86. return self.color_on
  87. return self.color
  88. def clean(self):
  89. self.val.set(0)
  90. def press(self):
  91. #print("ELEM_BUF.press",[self.name,self.type,self.val.get()])
  92. if self.type == "fader":
  93. self.inc(self.increment)
  94. if self.type == "toggle":
  95. if self.val.get():
  96. self.val.set(0)
  97. else:
  98. self.val.set(1)
  99. if self.type == "flash":
  100. self.val.set(1)
  101. self.events.append("press")
  102. self.cb_on.cb("ho")
  103. def release(self):
  104. if self.type == "fader":
  105. self.inc(-self.increment)
  106. return
  107. if self.type == "flash":
  108. self.val.set(0)
  109. self.events.append("release")
  110. def inc(self,v):
  111. self.val.inc(v)
  112. class Layout():
  113. def __init__(self,master):
  114. self.master = master
  115. def pack(self,**args):
  116. pass
  117. def grid(self,**args):
  118. pass
  119. def bind(self,**args):
  120. pass
  121. def get_font_hight(font):
  122. fr = font.render("test_font_hight" ,1, (0,0,0))
  123. r = fr.get_rect()
  124. h = r[3]
  125. return h
  126. def draw_bd(pos=[0,0,10,10],delta=0):
  127. d = delta
  128. xpos = (
  129. (pos[0]-d ,pos[1]-d),
  130. (pos[0]+pos[2]+d-1 ,pos[1]-d),
  131. (pos[0]+pos[2]+d-1 ,pos[1]+pos[3]+d-1),
  132. (pos[0]-d ,pos[1]+pos[3]+d-1)
  133. )
  134. i_old = None
  135. ypos = []
  136. for i in xpos:
  137. if i_old:
  138. ypos.append( (i_old,i) )
  139. i_old = i
  140. ypos.append( (i_old,xpos[0]) )
  141. return ypos
  142. def check_area_v(v1,v2,event_v):#elm_pos,event_pos):
  143. if event_v < v1+1:
  144. return 0
  145. if event_v > v2-1:
  146. return 0
  147. return 1
  148. def check_area(pos,event_pos):
  149. v2 = pos[0]+pos[2]
  150. x = check_area_v(pos[0],v2,event_pos[0])
  151. v2 = pos[1]+pos[3]
  152. y = check_area_v(pos[1],v2,event_pos[1])
  153. if x and y:
  154. return 1
  155. def check_area2(R1,R2): #pos,mouse_box
  156. btn_box = R1[:] #btn_box
  157. r2 = R2[:] #mouse_box
  158. w=btn_box[2]
  159. h=btn_box[3]
  160. p1 = [btn_box[0],btn_box[1]]
  161. p4 = [btn_box[0]+w,btn_box[1]+h]
  162. if r2[0] > r2[2]:
  163. r2[0],r2[2] = r2[2],r2[0]
  164. if r2[1] > r2[3]:
  165. r2[1],r2[3] = r2[3],r2[1]
  166. x=0
  167. if r2[2] > p1[0] and r2[0] < p4[0]:
  168. x+=1
  169. y=0
  170. if r2[3] > p1[1] and r2[1] < p4[1]:
  171. y+=1
  172. if x and y:#> 4:
  173. print("btn",R1,"mouse",R2)
  174. print("btn",btn_box,"mouse",r2)
  175. print("area2",x,y)
  176. return 1
  177. class Button():
  178. def __init__(self,window,pos):
  179. self.window = window
  180. self.event_pos = [0,0]
  181. self.font0 = pygame.font.SysFont("freesans-bold",16)
  182. self.w = 20
  183. self.h = 10
  184. self.pos = pos
  185. self.fader = 1
  186. self.btn1 = ELEM_BUF()
  187. self.btn1.name = "BUTTON"
  188. self.btn1.nr_on = [1,3]
  189. self.btn1.nr_off = [1,3]
  190. #self.btn1.color = LIGHTGRAY
  191. self.btn1.color = GRAY
  192. self.btn1.color_on = RED
  193. self.btn2 = ELEM_BUF() # sel elem
  194. self.btn2.name = "SELECT BUF"
  195. self.btn2.nr_on = [2]
  196. self.btn2.nr_off = [0]
  197. self.btn2.color = GRAY
  198. self.btn2.color_on = YELLOW
  199. self.btn2.type = "toggle"
  200. self.btn3 = ELEM_BUF()
  201. self.btn3.name = "MOUSE FOCUS"
  202. self.btn3.color = GRAY
  203. self.btn3.color_on = WHITHE
  204. self.btn4 = ELEM_BUF()
  205. self.btn4.name = "MOUSE ECODER"
  206. self.btn4.increment = 4.4
  207. self.btn4.type = "fader"
  208. self.btn4.nr_on = [4]
  209. self.btn4.nr_off = [5]
  210. self.btn4.color = GRAY
  211. self.btn4.color_on = WHITHE
  212. self.btns = []
  213. self.btns.append(self.btn1)
  214. self.btns.append(self.btn2)
  215. self.btns.append(self.btn3)
  216. self.btns.append(self.btn4)
  217. self.__layout = Layout(self)
  218. self.pack = self.__layout.pack
  219. self.grid = self.__layout.grid
  220. self.bind = self.__layout.bind
  221. self.text = "line1\nline2"
  222. self.type = "toggle" # flash, kill
  223. self.dbg = 0
  224. self.text2 = []
  225. def check(self):
  226. if self.dbg:
  227. self.text2 = []
  228. #self.text2.append(self.val)
  229. b = []
  230. for btn in self.btns:
  231. b.append(btn.get())
  232. self.text2.append(b)
  233. self.text2.append(self.btn1.type)
  234. self._check_event()
  235. self._check_min_hight()
  236. def draw(self,text="GOBO1"):
  237. self.check()
  238. self.window.set_alpha(128)
  239. self._draw_bg()
  240. self._draw_fader()
  241. self._draw_font(text="")
  242. rgb = self.btn2.get_color()
  243. self._draw_bd(color=rgb)
  244. self._draw_bd(delta=-1)
  245. rgb = self.btn3.get_color()
  246. self._draw_bd(delta=-2,color=rgb)
  247. def get_rect(self):
  248. self.check()
  249. return self.pos[:]
  250. def _check_min_hight(self):
  251. c = 1+ self.text.count("\n") #+1
  252. c += len(self.text2)
  253. fh = get_font_hight(self.font0)
  254. h = (fh+1)*c +6#8 #+8
  255. if self.pos[3] < h:
  256. self.pos[3] = h #ah+20
  257. def _draw_bg(self):
  258. pos = self.pos
  259. rgb = self.btn1.get_color()
  260. pygame.draw.rect(self.window,rgb,pos)
  261. def _draw_fader(self):
  262. rgb = [0,200,0]
  263. rgb = self.btn4.color_on
  264. pos2 = self.pos[:]
  265. v = self.btn4.val.get() #self.val.get()
  266. fh = get_font_hight(self.font0)
  267. if self.fader:
  268. pos2[1] += 2 #fh+2
  269. pos2[3] = 4 #fh+2
  270. if v > 0:
  271. pos2[2] = int(pos2[2]* v/255)
  272. else:
  273. pos2[2] = 4
  274. pygame.draw.rect(self.window,rgb,pos2)
  275. def _draw_font(self,text=""):
  276. pos = self.pos
  277. a = pos[0]+4
  278. r = pos[1]+4
  279. v = "{:4.02f}".format(self.btn4.val.get())
  280. lines = self.text.split("\n")
  281. lines.extend(self.text2)
  282. for i in lines:
  283. i = str(i)
  284. if "<val>" in i:
  285. i = i.replace("<val>",v)
  286. fr = self.font0.render(i ,1, (0,0,0))
  287. fr_r=fr.get_rect()
  288. p2 = [pos[0]+4,r,fr_r[2],fr_r[3]]
  289. if 0:# dbg # bg highlight
  290. pygame.draw.rect(self.window,[0,0,255],p2)
  291. self.window.blit(fr,(a,r))
  292. r+=fr_r[3]+1
  293. def _set_mouse_focus(self,state):
  294. if state:
  295. self.btn3.press() # mouse focus on
  296. else:
  297. self.btn3.release()
  298. def _check_event(self):
  299. pass
  300. def _draw_bd(self,delta=0,color=GRAY):#BLACK):
  301. l_pos = draw_bd(pos=self.pos,delta=delta)
  302. for i in l_pos:
  303. pygame.draw.aaline(self.window,color,i[0],i[1],1)
  304. def event(self,event=None):
  305. r_event = {}
  306. if "pos" in event.dict:
  307. self.event_pos = event.pos
  308. self._check_event()
  309. self._set_mouse_focus(0)
  310. if check_area(self.pos,self.event_pos):
  311. self._set_mouse_focus(1)
  312. if "button" in event.dict:
  313. mode = ""
  314. if event.type == 5:
  315. mode = "press"
  316. if event.type == 6:
  317. mode = "release"
  318. e = [event.button,mode]
  319. #print("e",e)
  320. for btn in self.btns:
  321. if e[0] in btn.nr_on and e[1] == "press":
  322. btn.press()
  323. if e[0] in btn.nr_off and e[1] == "release":
  324. btn.release()
  325. re = btn.get_event()
  326. if re and btn.name not in ['MOUSE FOCUS']:
  327. print("----------------",btn.name,re)
  328. r_event[btn.name] = re
  329. return r_event
  330. def draw_mouse_box(window,pos1,pos2,color=[128,128,128],text=1):
  331. color = [200,0,0,127]
  332. if text:
  333. fr = font15.render("A" ,1, (200,200,200))
  334. window.blit(fr,pos1)
  335. fr = font15.render("B" ,1, (200,200,200))
  336. window.blit(fr,[pos2[0]-10,pos2[1]-10])
  337. # h unten
  338. _pos1 = [pos1[0],pos2[1]]
  339. _pos2 = [pos2[0],pos2[1]]
  340. pygame.draw.aaline(window,color,_pos1,_pos2,1)
  341. color = [255,255,0,127]
  342. # h rechts
  343. _pos1 = [pos2[0],pos1[1]]
  344. _pos2 = [pos2[0],pos2[1]]
  345. pygame.draw.aaline(window,color,_pos1,_pos2,1)
  346. color = [0,200,0,127]
  347. # h links
  348. _pos1 = [pos1[0],pos1[1]]
  349. _pos2 = [pos1[0],pos2[1]]
  350. pygame.draw.aaline(window,color,_pos1,_pos2,1)
  351. color = [0,0,200,127]
  352. # h oben
  353. _pos1 = [pos1[0],pos1[1]]
  354. _pos2 = [pos2[0],pos1[1]]
  355. pygame.draw.aaline(window,color,_pos1,_pos2,1)