main_screen.py 16 KB

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