main_screen.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. # -*- coding: utf-8 -*-
  2. import pygame
  3. from pygame.locals import *
  4. from sys import exit
  5. import os
  6. import sys
  7. from libs import easing
  8. from datetime import datetime
  9. import base64
  10. from beeprint import pp
  11. ## local package import
  12. from constants import ICON_TYPES,icon_ext,icon_width,icon_height,RUNEVT
  13. from icon_item import IconItem
  14. from page import Page,PageStack
  15. from title_bar import TitleBar
  16. from foot_bar import FootBar
  17. from constants import Width,Height,bg_color
  18. from util_funcs import midRect,FileExists,ReplaceSuffix,ReadTheFileContent,CmdClean,MakeExecutable
  19. from fonts import fonts
  20. from keys_def import CurKeys
  21. from label import Label
  22. from untitled_icon import UntitledIcon
  23. from Emulator import MyEmulator
  24. class MessageBox(Label):
  25. _Parent = None
  26. def __init__(self):
  27. pass
  28. def Init(self,text,font_obj,color=pygame.Color(83,83,83)):
  29. self._Color = color
  30. self._FontObj = font_obj
  31. self._Text = text
  32. self._Width = 0
  33. self._Height = 0
  34. self._CanvasHWND = pygame.Surface( ( int(self._Parent._Width),int(self._Parent._Height)))
  35. self._HWND = self._Parent._CanvasHWND
  36. def SetText(self,text):
  37. self._Text = text
  38. def Draw(self):
  39. self._CanvasHWND.fill( (255,255,255))
  40. words = self._Text.split(' ')
  41. space = self._FontObj.size(' ')[0]
  42. max_width = self._Parent._Width-40
  43. x ,y = (0,0)
  44. row_total_width = 0
  45. lines = 0
  46. for word in words:
  47. word_surface = self._FontObj.render(word, True, self._Color)
  48. word_width = word_surface.get_width()
  49. word_height = word_surface.get_height()
  50. row_total_width += word_width
  51. if lines == 0:
  52. lines += word_height
  53. if row_total_width+space >= max_width:
  54. x = 0 # Reset the x.
  55. y += word_height # Start on new row.
  56. row_total_width = 0
  57. lines += word_height
  58. self._CanvasHWND.blit(word_surface, (x, y))
  59. x += word_width + space
  60. if x > self._Width:
  61. self._Width = x
  62. if lines >= (self._Parent._Height - 40):
  63. break
  64. self._Height = lines
  65. padding = 5
  66. x = (self._Parent._Width - self._Width)/2
  67. y = (self._Parent._Height - self._Height)/2
  68. print("x %d y %d w %d h %d" %(x,y,self._Width,self._Height ))
  69. pygame.draw.rect(self._HWND,(255,255,255),(x-padding,y-padding, self._Width+padding*2,self._Height+padding*2))
  70. if self._HWND != None:
  71. rect = midRect(self._Parent._Width/2,self._Parent._Height/2,self._Width,self._Height,Width,Height)
  72. self._HWND.blit(self._CanvasHWND,rect,(0,0,self._Width,self._Height))
  73. pygame.draw.rect(self._HWND,(0,0,0),(x-padding,y-padding, self._Width+padding*2,self._Height+padding*2),1)
  74. python_package_flag = "__init__.py"
  75. emulator_flag = "action.config"
  76. ##Abstract object for manage Pages ,not the pygame's physic screen
  77. class MainScreen(object):
  78. _Pages = []
  79. _PageMax = 0
  80. _PageIndex = 0
  81. _PosX = 0
  82. _PosY = TitleBar._BarHeight+1
  83. _Width = Width
  84. _Height = Height -FootBar._BarHeight -TitleBar._BarHeight-1
  85. _MyPageStack = None
  86. _CurrentPage = None # pointer to the current displaying Page Class
  87. _CanvasHWND = None
  88. _HWND = None
  89. _TitleBar = None
  90. _FootBar = None
  91. _MsgBox = None
  92. _MsgBoxFont = fonts["veramono20"]
  93. _IconFont = fonts["varela15"]
  94. def __init__(self):
  95. self._Pages = []
  96. self._MyPageStack = PageStack()
  97. def Init(self):
  98. self._CanvasHWND = pygame.Surface((self._Width,self._Height))
  99. self._MsgBox= MessageBox()
  100. self._MsgBox._Parent= self
  101. self._MsgBox.Init(" ", self._MsgBoxFont)
  102. def FartherPages(self):
  103. self._PageMax = len(self._Pages)
  104. for i in range(0,self._PageMax):
  105. self._Pages[i]._Index = i
  106. self._Pages[i]._CanvasHWND = self._CanvasHWND
  107. self._Pages[i]._IconNumbers = len(self._Pages[i]._Icons)
  108. self._Pages[i]._Screen = self
  109. self._Pages[i].Adjust()
  110. if self._Pages[i]._IconNumbers > 1:
  111. self._Pages[i]._PsIndex = 1
  112. self._Pages[i]._IconIndex = self._Pages[i]._PsIndex
  113. self._CurrentPage = self._Pages[self._PageIndex]
  114. self._CurrentPage._OnShow = True
  115. def GetMyRightSidePage(self):
  116. ret = self._PageIndex +1
  117. if ret > (self._PageMax -1):
  118. ret = self._PageMax -1
  119. return ret
  120. def PageMoveLeft(self):
  121. self._Pages[self._PageIndex]._OnShow = False
  122. if self._PageIndex < (self._PageMax - 1):
  123. my_right_side_page = self.GetMyRightSidePage()
  124. for i in range(0,self._PageMax):
  125. if i!= self._PageIndex and i != my_right_side_page:
  126. self._Pages[i].MoveLeft(Width)
  127. self._Pages[self._PageIndex].EasingLeft(Width)
  128. if self._PageIndex != my_right_side_page:
  129. self._Pages[my_right_side_page].EasingLeft(Width)
  130. self._Pages[self._PageIndex].ResetPageSelector()
  131. self._PageIndex+=1
  132. if self._PageIndex > (self._PageMax -1):
  133. self._PageIndex = (self._PageMax -1)
  134. self._Pages[self._PageIndex]._OnShow = True
  135. self._CurrentPage = self._Pages[self._PageIndex]
  136. def GetMyLeftSidePage(self):
  137. ret = self._PageIndex -1
  138. if ret < 0:
  139. ret = 0
  140. return ret
  141. def PageMoveRight(self):
  142. self._Pages[self._PageIndex]._OnShow = False
  143. if self._PageIndex > 0:
  144. my_left_side_page = self.GetMyLeftSidePage()
  145. for i in range(0,self._PageMax):
  146. if i!= self._PageIndex and i!= my_left_side_page:
  147. pass
  148. #self._Pages[i].MoveRight(Width)
  149. self._Pages[self._PageIndex].EasingRight(Width)
  150. if self._PageIndex != my_left_side_page:
  151. self._Pages[my_left_side_page].EasingRight(Width)
  152. self._Pages[self._PageIndex].ResetPageSelector()
  153. self._PageIndex-=1
  154. if self._PageIndex < 0:
  155. self._PageIndex = 0
  156. self._Pages[self._PageIndex]._OnShow = True
  157. self._CurrentPage = self._Pages[self._PageIndex]
  158. def EasingAllPageLeft(self):
  159. current_time = 0.0
  160. start_posx = 0.0
  161. current_posx = start_posx
  162. final_posx = float(Width)
  163. posx_init = 0
  164. dur = 30
  165. last_posx = 0.0
  166. all_last_posx = []
  167. if self._PageIndex >= (self._PageMax - 1):
  168. return
  169. for i in range(0,Width*dur):
  170. current_posx = easing.SineIn(current_time,start_posx,final_posx-start_posx,float(dur))
  171. if current_posx >= final_posx:
  172. current_posx = final_posx
  173. dx = current_posx - last_posx
  174. all_last_posx.append(int(dx))
  175. current_time+=1
  176. last_posx = current_posx
  177. if current_posx >= final_posx:
  178. break
  179. c = 0
  180. for i in all_last_posx:
  181. c+=i
  182. if c < final_posx - start_posx:
  183. all_last_posx.append( final_posx - c )
  184. for i in all_last_posx:
  185. self.ClearCanvas()
  186. for j in self._Pages:
  187. j._PosX -= i
  188. j.DrawIcons()
  189. j._Screen.SwapAndShow()
  190. self._Pages[self._PageIndex]._OnShow = False
  191. self._PageIndex+=1
  192. if self._PageIndex > (self._PageMax -1):
  193. self._PageIndex = (self._PageMax -1)
  194. self._Pages[self._PageIndex]._OnShow = True
  195. self._CurrentPage = self._Pages[self._PageIndex]
  196. def EasingAllPageRight(self):
  197. current_time = 0.0
  198. start_posx = 0.0
  199. current_posx = start_posx
  200. final_posx = float(Width)
  201. posx_init = 0
  202. dur = 30
  203. last_posx = 0.0
  204. all_last_posx = []
  205. if self._PageIndex <= 0:
  206. return
  207. for i in range(0,Width*dur):
  208. current_posx = easing.SineIn(current_time,start_posx,final_posx-start_posx,float(dur))
  209. if current_posx >= final_posx:
  210. current_posx = final_posx
  211. dx = current_posx - last_posx
  212. all_last_posx.append(int(dx))
  213. current_time+=1
  214. last_posx = current_posx
  215. if current_posx >= final_posx:
  216. break
  217. c = 0
  218. for i in all_last_posx:
  219. c+=i
  220. if c < final_posx - start_posx:
  221. all_last_posx.append( final_posx - c )
  222. for i in all_last_posx:
  223. self.ClearCanvas()
  224. for j in reversed(self._Pages):
  225. j._PosX += i
  226. j.DrawIcons()
  227. j._Screen.SwapAndShow()
  228. self._Pages[self._PageIndex]._OnShow = False
  229. self._PageIndex-=1
  230. if self._PageIndex < 0:
  231. self._PageIndex = 0
  232. self._Pages[self._PageIndex]._OnShow = True
  233. self._CurrentPage = self._Pages[self._PageIndex]
  234. def CurPage(self):
  235. return self._CurrentPage
  236. def PushCurPage(self):
  237. self._MyPageStack.Push(self._CurrentPage)
  238. def SetCurPage(self,page):
  239. self._CurrentPage = page
  240. on_load_cb = getattr(self._CurrentPage,"OnLoadCb",None)
  241. if on_load_cb != None:
  242. if callable( on_load_cb ):
  243. self._CurrentPage.OnLoadCb()
  244. def PushPage(self,page):
  245. self.PushCurPage()
  246. self.SetCurPage(page)
  247. def AppendPage(self,Page):
  248. self._Pages.append(Page)
  249. def ClearCanvas(self):
  250. self._CanvasHWND.fill((255,255,255))
  251. def SwapAndShow(self):
  252. if self._HWND != None:
  253. self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width,self._Height))
  254. pygame.display.update()
  255. def ExtraName(self,name):
  256. ## extra name like 1_xxx to be => xxx,
  257. parts = name.split("_")
  258. if len(parts) > 1:
  259. return parts[1]
  260. elif len(parts) == 1:
  261. return parts[0]
  262. else:
  263. return name
  264. def IsEmulatorPackage(self,dirname):
  265. files = os.listdir(dirname)
  266. for i in sorted(files):
  267. if i.endswith(emulator_flag):
  268. return True
  269. return False
  270. def IsPythonPackage(self,dirname):
  271. files = os.listdir(dirname)
  272. for i in sorted(files):
  273. if i.endswith(python_package_flag):
  274. return True
  275. return False
  276. def ReadTheDirIntoPages(self,_dir,pglevel,cur_page):
  277. if FileExists(_dir) == False and os.path.isdir(_dir) == False:
  278. return
  279. files = os.listdir(_dir)
  280. for i in sorted(files):
  281. if os.path.isdir(_dir+"/"+i): # TOPLEVEL only is dir
  282. if pglevel == 0:
  283. page = Page()
  284. page._Name = self.ExtraName(i)
  285. page._Icons = []
  286. self._Pages.append(page)
  287. self.ReadTheDirIntoPages(_dir+"/"+i, pglevel+1 ,self._Pages[ len(self._Pages) -1])
  288. else: ## On CurPage now
  289. i2 = self.ExtraName(i)
  290. iconitem = IconItem()
  291. iconitem._CmdPath = ""
  292. iconitem.AddLabel(i2,self._IconFont)
  293. if FileExists(_dir+"/"+i2+".png"):
  294. iconitem._ImageName = _dir+"/"+i2+".png"
  295. else:
  296. untitled = UntitledIcon()
  297. untitled.Init()
  298. if len(i2) > 1:
  299. untitled.SetWords(i2[:2])
  300. elif len(i2) == 1:
  301. untitled.SetWords([i2[0],i2[0]])
  302. else:
  303. untitled.SetWords(["G","s"])
  304. iconitem._ImgSurf = untitled.Surface()
  305. iconitem._ImageName = ""
  306. if self.IsPythonPackage(_dir+"/"+i):
  307. iconitem._MyType = ICON_TYPES["FUNC"]
  308. sys.path.append(_dir)
  309. iconitem._CmdPath = __import__(i)
  310. init_cb = getattr(iconitem._CmdPath,"Init",None)
  311. if init_cb != None:
  312. if callable(init_cb):
  313. iconitem._CmdPath.Init(self)
  314. cur_page._Icons.append(iconitem)
  315. elif self.IsEmulatorPackage(_dir+"/"+i):
  316. obj = {}
  317. obj["ROM"] = ""
  318. obj["ROM_SO"] =""
  319. obj["EXT"] = []
  320. obj["LAUNCHER"] = ""
  321. obj["TITLE"] = "Game"
  322. obj["SO_URL"] = ""
  323. try:
  324. f = open(_dir+"/"+i+"/"+emulator_flag)
  325. except IOError:
  326. print("action config open failed")
  327. return
  328. else:
  329. with f:
  330. content = f.readlines()
  331. content = [x.strip() for x in content]
  332. for i in content:
  333. pis = i.split("=")
  334. if len(pis) > 1:
  335. if "EXT" in pis[0]:
  336. obj[pis[0]] = pis[1].split(",")
  337. else:
  338. obj[pis[0]] = pis[1]
  339. em = MyEmulator()
  340. em._Emulator = obj
  341. em.Init(self)
  342. iconitem._CmdPath = em
  343. iconitem._MyType = ICON_TYPES["Emulator"]
  344. cur_page._Icons.append(iconitem)
  345. else:
  346. iconitem._MyType = ICON_TYPES["DIR"]
  347. iconitem._LinkPage = Page()
  348. iconitem._LinkPage._Name = i2
  349. cur_page._Icons.append(iconitem)
  350. self.ReadTheDirIntoPages(_dir+"/"+i,pglevel+1,iconitem._LinkPage)
  351. elif os.path.isfile(_dir+"/"+i) and pglevel > 0:
  352. if i.lower().endswith(icon_ext):
  353. i2 = self.ExtraName(i)
  354. #cmd = ReadTheFileContent(_dir+"/"+i)
  355. iconitem = IconItem()
  356. iconitem._CmdPath = _dir+"/"+i
  357. MakeExecutable(iconitem._CmdPath)
  358. iconitem._MyType = ICON_TYPES["EXE"]
  359. if FileExists(_dir+"/"+ReplaceSuffix(i2,"png")):
  360. iconitem._ImageName = _dir+"/"+ReplaceSuffix(i2,"png")
  361. else:
  362. untitled = UntitledIcon()
  363. untitled.Init()
  364. if len(i2) > 1:
  365. untitled.SetWords(i2[:2])
  366. elif len(i2) == 1:
  367. untitled.SetWords([i2[0],i2[0]])
  368. else:
  369. untitled.SetWords(["G","s"])
  370. iconitem._ImgSurf = untitled.Surface()
  371. iconitem._ImageName = ""
  372. iconitem.AddLabel(i2.split(".")[0],self._IconFont)
  373. iconitem._LinkPage = None
  374. cur_page._Icons.append(iconitem)
  375. def RunEXE(self,cmdpath):
  376. self.DrawRun()
  377. self.SwapAndShow()
  378. pygame.time.delay(1000)
  379. cmdpath = cmdpath.strip()
  380. cmdpath = CmdClean(cmdpath)
  381. pygame.event.post( pygame.event.Event(RUNEVT, message=cmdpath))
  382. def OnExitCb(self,event):
  383. ## leave rest to Pages
  384. on_exit_cb = getattr(self._CurrentPage,"OnExitCb",None)
  385. if on_exit_cb != None:
  386. if callable( on_exit_cb ):
  387. self._CurrentPage.OnExitCb(event)
  388. return
  389. def KeyDown(self,event):
  390. """
  391. if event.key == pygame.K_PAGEUP:
  392. self.EasingAllPageLeft()
  393. #self.SwapAndShow()
  394. if event.key == pygame.K_PAGEDOWN:
  395. self.EasingAllPageRight()
  396. #self.SwapAndShow()
  397. """
  398. if event.key == pygame.K_t:
  399. self.DrawRun()
  400. self.SwapAndShow()
  401. if event.key == CurKeys["Space"]:
  402. self.Draw()
  403. self.SwapAndShow()
  404. ## leave rest to Pages
  405. current_page_key_down_cb = getattr(self._CurrentPage,"KeyDown",None)
  406. if current_page_key_down_cb != None:
  407. if callable( current_page_key_down_cb ):
  408. self._CurrentPage.KeyDown(event)
  409. def DrawRun(self):
  410. self._MsgBox.SetText("Launching....")
  411. self._MsgBox.Draw()
  412. def Draw(self):
  413. self._CurrentPage.Draw()
  414. #if self._HWND != None:
  415. # self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width,self._Height))
  416. if self._TitleBar != None:
  417. self._TitleBar.Draw(self._CurrentPage._Name)
  418. if self._FootBar != None:
  419. if hasattr(self._CurrentPage,"_FootMsg"):
  420. self._FootBar.SetLabelTexts(self._CurrentPage._FootMsg)
  421. self._FootBar.Draw()