ソースを参照

Add files via upload

clockworkpi 6 年 前
コミット
c5bd510210
63 ファイル変更5070 行追加0 行削除
  1. 114 0
      sys.py/UI/Emulator/__init__.py
  2. 415 0
      sys.py/UI/Emulator/fav_list_page.py
  3. 111 0
      sys.py/UI/Emulator/list_item.py
  4. 466 0
      sys.py/UI/Emulator/rom_list_page.py
  5. 122 0
      sys.py/UI/Emulator/rom_so_confirm_page.py
  6. 118 0
      sys.py/UI/above_all_patch.py
  7. 0 0
      sys.py/UI/blueselector_b64.py
  8. 142 0
      sys.py/UI/confirm_page.py
  9. 45 0
      sys.py/UI/constants.py
  10. 73 0
      sys.py/UI/delete_confirm_page.py
  11. 213 0
      sys.py/UI/download.py
  12. 225 0
      sys.py/UI/download_process_page.py
  13. 63 0
      sys.py/UI/fonts.py
  14. 161 0
      sys.py/UI/foot_bar.py
  15. 109 0
      sys.py/UI/icon_item.py
  16. 29 0
      sys.py/UI/icon_pool.py
  17. 14 0
      sys.py/UI/keyboard_keys.layout
  18. 58 0
      sys.py/UI/keys_def.py
  19. 56 0
      sys.py/UI/label.py
  20. 468 0
      sys.py/UI/main_screen.py
  21. 44 0
      sys.py/UI/multi_icon_item.py
  22. 86 0
      sys.py/UI/multilabel.py
  23. 606 0
      sys.py/UI/page.py
  24. 61 0
      sys.py/UI/scroller.py
  25. 12 0
      sys.py/UI/simple_name_space.py
  26. 40 0
      sys.py/UI/slider.py
  27. 290 0
      sys.py/UI/title_bar.py
  28. 63 0
      sys.py/UI/untitled_icon.py
  29. 100 0
      sys.py/UI/util_funcs.py
  30. 16 0
      sys.py/config.py
  31. BIN
      sys.py/gameshell/blank.png
  32. BIN
      sys.py/gameshell/footbar_icons/footbar.png
  33. BIN
      sys.py/gameshell/icons/about_bg.png
  34. BIN
      sys.py/gameshell/icons/empty.png
  35. BIN
      sys.py/gameshell/icons/heart.png
  36. BIN
      sys.py/gameshell/icons/icon_sd.png
  37. BIN
      sys.py/gameshell/icons/light.png
  38. BIN
      sys.py/gameshell/icons/needwifi_bg.png
  39. BIN
      sys.py/gameshell/icons/online.png
  40. BIN
      sys.py/gameshell/icons/rom_download.png
  41. BIN
      sys.py/gameshell/icons/scale.png
  42. BIN
      sys.py/gameshell/icons/star.png
  43. BIN
      sys.py/gameshell/icons/sys.png
  44. BIN
      sys.py/gameshell/icons/vol.png
  45. BIN
      sys.py/gameshell/titlebar_icons/battery_unknown.png
  46. BIN
      sys.py/gameshell/titlebar_icons/ic_battery_charging_full_black.png
  47. BIN
      sys.py/gameshell/titlebar_icons/ic_volume_up_black.png
  48. BIN
      sys.py/gameshell/titlebar_icons/soundvolume.png
  49. BIN
      sys.py/gameshell/titlebar_icons/wifi.png
  50. BIN
      sys.py/gameshell/titlebar_icons/withcharging.png
  51. BIN
      sys.py/gameshell/titlebar_icons/without_charging.png
  52. BIN
      sys.py/gameshell/wallpaper/gameover.png
  53. BIN
      sys.py/gameshell/wallpaper/loading.png
  54. BIN
      sys.py/gameshell/wallpaper/seeyou.png
  55. 112 0
      sys.py/libs/DBUS/__init__.py
  56. 190 0
      sys.py/libs/MPD/poller.py
  57. 7 0
      sys.py/libs/easing.py
  58. 1 0
      sys.py/libs/roundrects/__init__.py
  59. 60 0
      sys.py/libs/roundrects/roundrects.py
  60. 43 0
      sys.py/proc/cpuinfo
  61. 1 0
      sys.py/proc/driver/backlight
  62. 324 0
      sys.py/run.py
  63. 12 0
      sys.py/sys/class/power_supply/axp20x-battery/uevent

+ 114 - 0
sys.py/UI/Emulator/__init__.py

@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+
+## local UI import
+from UI.delete_confirm_page import DeleteConfirmPage
+from UI.icon_pool           import MyIconPool
+from UI.keys_def            import CurKeys
+
+from rom_list_page import RomListPage
+from fav_list_page import FavListPage
+
+class FavDeleteConfirmPage(DeleteConfirmPage):
+    
+    def KeyDown(self,event):
+        
+        if event.key == CurKeys["Menu"] or event.key == CurKeys["A"]:
+            
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+                
+        
+        if event.key == CurKeys["B"]:
+            try:
+                #self._FileName
+                stats = os.stat(self._FileName)
+                os.chown(self._FileName, stats.st_uid,stats.st_uid) ## normally uid and gid should be the same 
+            except:
+                print("error in FavDeleteConfirmPage chown ")
+
+            self.SnapMsg("Deleteing....")
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            self.Reset()
+                
+            pygame.time.delay(300)
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+            print(self._FileName)
+
+
+class MyEmulator(object):
+
+    _Icons = {}
+    RomListPage = None
+    FavListPage = None
+    _Emulator = None
+    
+    _FavGID = 31415
+    _FavGname = "cpifav"
+    
+    def __init__(self):
+        self._Icons = {}
+
+    def load_icons(self):
+        """
+        basepath = os.path.dirname(os.path.realpath(__file__))
+        files = os.listdir(basepath+"/icons")
+        for i in files:
+            if os.path.isfile(basepath+"/"+i) and i.endswith(".png"):
+                keyname = i.split(".")[0]
+                self._Icons[keyname] = pygame.image.load(basepath+"/"+i).convert_alpha()
+        """
+        self._Icons["sys"] = MyIconPool._Icons["sys"]
+        
+        
+    def InitDeleteConfirmPage(self,main_screen):
+        self.DeleteConfirmPage = DeleteConfirmPage()
+        self.DeleteConfirmPage._Screen = main_screen
+        self.DeleteConfirmPage._Name   = "Delete Confirm"
+        self.DeleteConfirmPage.Init()
+
+        self.FavDeleteConfirmPage = FavDeleteConfirmPage()
+        self.FavDeleteConfirmPage._Screen = main_screen
+        self.FavDeleteConfirmPage._Name   = "Delete Confirm"
+        self.FavDeleteConfirmPage.Init()
+        
+    def InitFavListPage(self,main_screen):
+        self.FavListPage = FavListPage()
+        self.FavListPage._Screen = main_screen
+        self.FavListPage._Name   = "Favourite Games"
+        self.FavListPage._Emulator = self._Emulator
+        self.FavListPage._Parent = self
+        
+        self.FavListPage.Init()
+    
+    def InitRomListPage(self,main_screen):
+        self.RomListPage = RomListPage()
+        self.RomListPage._Screen = main_screen
+        self.RomListPage._Name   = self._Emulator["TITLE"]
+        self.RomListPage._Emulator = self._Emulator
+        self.RomListPage._Parent = self
+        self.RomListPage.Init()
+    
+    def Init(self,main_screen):
+        self.load_icons()
+        self.InitDeleteConfirmPage(main_screen)    
+        self.InitRomListPage(main_screen)
+        self.InitFavListPage(main_screen)
+    
+    def API(self,main_screen):
+        if main_screen !=None:
+            main_screen.PushCurPage()
+            main_screen.SetCurPage(self.RomListPage)
+            main_screen.Draw()
+            main_screen.SwapAndShow()

+ 415 - 0
sys.py/UI/Emulator/fav_list_page.py

@@ -0,0 +1,415 @@
+# -*- coding: utf-8 -*- 
+
+import os
+import pygame
+import glob
+
+from libs.roundrects import aa_round_rect
+
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES,RUNEVT
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.icon_item import IconItem
+from UI.fonts  import fonts
+from UI.util_funcs import midRect,CmdClean,FileExists
+from UI.keys_def   import CurKeys
+from UI.multi_icon_item import MultiIconItem
+from UI.icon_pool import MyIconPool
+from UI.scroller  import ListScroller
+
+from rom_so_confirm_page import RomSoConfirmPage
+
+from list_item  import ListItem
+
+
+class FavStack:
+    _Emulator = None
+    
+    def __init__(self):
+        self.stack = list()
+
+    def Push(self,data):
+        if data not in self.stack:
+            self.stack.append(data)
+            return True
+        return False
+
+    def Pop(self):
+        if len(self.stack)<=0:
+            return None,False
+        return self.stack.pop(),True
+
+    def Last(self):
+        idx = len(self.stack) -1
+        if idx < 0:## empty stack,return root path
+            return self._Emulator["ROM"]
+        else:
+            return self.stack[ idx ]
+    
+    def Length(self):
+        return len(self.stack)
+
+class ListPageSelector(PageSelector):
+    _BackgroundColor = pygame.Color(131,199,219)
+
+    def __init__(self):
+        self._PosX = 0
+        self._PosY = 0
+        self._Height = 0
+        self._Width  = Width-12
+
+    def AnimateDraw(self,x2,y2):
+        pass
+
+    def Draw(self):
+        idx = self._Parent._PsIndex
+        if idx > (len(self._Parent._MyList)-1):
+            idx = len(self._Parent._MyList)
+            if idx > 0:
+                idx -=1
+            elif idx == 0:##nothing in _MyList
+                return
+
+        self._Parent._PsIndex = idx #sync PsIndex
+        
+        x = self._Parent._MyList[idx]._PosX+2
+        y = self._Parent._MyList[idx]._PosY+1
+        h = self._Parent._MyList[idx]._Height -3
+        
+        self._PosX = x
+        self._PosY = y
+        self._Height = h
+
+        aa_round_rect(self._Parent._CanvasHWND,  
+                    (x,y,self._Width-4,h),self._BackgroundColor,4,0,self._BackgroundColor)
+
+
+
+class FavListPage(Page):
+
+    _Icons = {}
+    _Selector=None
+    _FootMsg = ["Nav","Scan","Remove","","Run"]
+    _MyList = []
+    _ListFont = fonts["notosanscjk15"]
+    _MyStack = None
+    _Emulator = None
+    _Parent   = None
+    _Scroller = None
+    _Scrolled = 0
+    _BGwidth  = 75
+    _BGheight = 73
+    _RomSoConfirmDownloadPage = None
+
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}
+        self._CanvasHWND = None
+        self._MyList = []
+        self._MyStack = FavStack()
+        self._Emulator = {}
+        
+    def GeneratePathList(self,path):
+        if os.path.isdir(path) == False:
+            return False
+
+
+        files_path = glob.glob(path+"/*")
+
+        print(files_path)
+        ret = []
+
+        for i ,v in enumerate(files_path):
+            dirmap = {}
+            #if os.path.isdir(v):
+            #    continue
+            #    dir_base_name = os.path.basename(v)
+            #    if dir_base_name == ".Trash" or dir_base_name == ".Fav":
+            #        pass
+            #    else:
+            #        dirmap["directory"] = v
+            #        ret.append(dirmap)
+                    
+            if os.path.isfile(v):
+                stats = os.stat(v)
+                if stats.st_gid != self._Parent._FavGID:
+                    continue
+                bname = os.path.basename(v)  ### filter extension
+                if len(bname)> 1:
+                    pieces  = bname.split(".")
+                    if len(pieces) > 1:
+                        if pieces[ len(pieces)-1   ].lower() in self._Emulator["EXT"]:
+                            dirmap["file"] = v
+                            ret.append(dirmap)
+                
+            else:
+                print("not file or dir")
+
+        
+        return ret
+
+    def SyncList(self,path):
+        
+        alist = self.GeneratePathList(path)
+        
+        if alist == False:
+            print("listfiles return false")
+            return
+        print("fav list alist: ")
+        print(alist)
+        
+        self._MyList = []
+        start_x  = 0
+        start_y  = 0
+        hasparent = 0
+        if self._MyStack.Length() > 0:
+            hasparent = 1
+            li = ListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFont
+            li._MyType = ICON_TYPES["DIR"]
+            li._Parent = self
+            li.Init("[..]")
+            self._MyList.append(li)
+        
+        for i,v in enumerate(sorted(alist)):
+            li = ListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y + (i+hasparent)*ListItem._Height
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFont
+            li._MyType  = ICON_TYPES["FILE"]
+            li._Parent = self
+            if "directory" in v:
+                li._MyType = ICON_TYPES["DIR"]
+                li.Init(v["directory"])
+            elif "file" in v:
+                li.Init(v["file"])
+            else:
+                li.Init("NoName")
+            
+            self._MyList.append(li)
+
+        
+        
+    def Init(self):
+        self._PosX = self._Index * self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+
+        self._CanvasHWND = self._Screen._CanvasHWND
+
+        ps = ListPageSelector()
+        ps._Parent = self
+        self._Ps = ps
+        self._PsIndex = 0
+
+        self.SyncList(self._Emulator["ROM"])
+
+        self._MyStack._Emulator = self._Emulator
+
+        icon_for_list = MultiIconItem()
+        icon_for_list._ImgSurf = self._Parent._Icons["sys"]
+        icon_for_list._MyType = ICON_TYPES["STAT"]
+        icon_for_list._Parent = self
+        icon_for_list.Adjust(0,0,18,18,0)
+        
+        self._Icons["sys"] = icon_for_list
+
+
+        bgpng = IconItem()
+        bgpng._ImgSurf = MyIconPool._Icons["star"]
+        bgpng._MyType = ICON_TYPES["STAT"]
+        bgpng._Parent = self
+        bgpng.AddLabel("my favourites games", fonts["varela18"])
+        bgpng.SetLableColor(pygame.Color(204,204,204))
+        bgpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+
+        self._Icons["bg"] = bgpng
+
+        self._Scroller = ListScroller()
+        self._Scroller._Parent = self
+        self._Scroller._PosX = self._Width - 10
+        self._Scroller._PosY = 2
+        self._Scroller.Init()
+
+        rom_so_confirm_page = RomSoConfirmPage()
+        rom_so_confirm_page._Screen = self._Screen
+        rom_so_confirm_page._Name = "Download Confirm"
+        rom_so_confirm_page._Parent = self
+        rom_so_confirm_page.Init()
+
+        self._RomSoConfirmDownloadPage = rom_so_confirm_page
+        
+    def ScrollUp(self):
+        if len(self._MyList) == 0:
+            return
+        
+        self._PsIndex -= 1
+        if self._PsIndex < 0:
+            self._PsIndex = 0
+        
+        cur_li = self._MyList[self._PsIndex]
+        if cur_li._PosY < 0:
+            for i in range(0, len(self._MyList)):
+                self._MyList[i]._PosY += self._MyList[i]._Height
+
+            self._Scrolled += 1
+
+    def ScrollDown(self):
+        if len(self._MyList) == 0:
+            return
+        
+        self._PsIndex +=1
+        if self._PsIndex >= len(self._MyList):
+            self._PsIndex = len(self._MyList) -1
+
+        cur_li = self._MyList[self._PsIndex]
+        if cur_li._PosY +cur_li._Height > self._Height:
+            for i in range(0,len(self._MyList)):
+                self._MyList[i]._PosY -= self._MyList[i]._Height
+            self._Scrolled -=1
+    def SyncScroll(self):
+        ## 
+        if self._Scrolled == 0:
+            return
+
+        if self._PsIndex < len(self._MyList):
+            cur_li = self._MyList[self._PsIndex]
+            if self._Scrolled > 0:
+                if cur_li._PosY < 0:
+                    for i in range(0, len(self._MyList)):
+                        self._MyList[i]._PosY += self._Scrolled * self._MyList[i]._Height
+            elif self._Scrolled < 0:
+                if cur_li._PosY +cur_li._Height > self._Height:
+                    for i in range(0,len(self._MyList)):
+                        self._MyList[i]._PosY += self._Scrolled * self._MyList[i]._Height
+                
+    def Click(self):
+        
+        cur_li = self._MyList[self._PsIndex]
+
+        if cur_li._MyType == ICON_TYPES["DIR"]:
+            return
+        
+        if cur_li._MyType == ICON_TYPES["FILE"]: ## add to playlist only
+            self._Screen._MsgBox.SetText("Launching...")
+            self._Screen._MsgBox.Draw()
+            self._Screen.SwapAndShow()
+            print("Run ",cur_li._Path)
+            
+            # check ROM_SO exists
+            if FileExists(self._Emulator["ROM_SO"]):
+                escaped_path = CmdClean( cur_li._Path)
+                cmdpath = " ".join( (self._Emulator["LAUNCHER"],self._Emulator["ROM_SO"], escaped_path))
+                pygame.event.post( pygame.event.Event(RUNEVT, message=cmdpath))
+                return
+            else:
+                
+                self._Screen.PushPage(self._RomSoConfirmDownloadPage)
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+
+            return
+    
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+
+    def ReScan(self):
+        if self._MyStack.Length() == 0:
+            self.SyncList(self._Emulator["ROM"])
+        else:
+            self.SyncList( self._MyStack.Last() )
+            
+        idx = self._PsIndex
+        if idx > (len(self._MyList)-1):
+            idx = len(self._MyList)
+            if idx > 0:
+                idx -=1
+            elif idx == 0:##nothing in _MyList
+                pass
+        
+        self._PsIndex = idx ## sync PsIndex
+
+        self.SyncScroll()
+
+
+    def OnReturnBackCb(self):
+        self.ReScan()
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        
+    def OnLoadCb(self):
+        self.ReScan()
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        
+    def KeyDown(self,event):
+        
+        if event.key == CurKeys["Menu"] or event.key == CurKeys["Left"]: 
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+        
+        if event.key == CurKeys["Up"]:
+            self.ScrollUp()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        if event.key == CurKeys["Down"]:
+            self.ScrollDown()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+
+        if event.key == CurKeys["Enter"]:
+            self.Click()
+
+                
+        if event.key == CurKeys["X"]: #Scan current
+           self.ReScan() 
+           self._Screen.Draw()
+           self._Screen.SwapAndShow()
+
+        if event.key == CurKeys["Y"]: #del
+            if len(self._MyList) == 0:
+                return
+            
+            cur_li = self._MyList[self._PsIndex]
+            if cur_li.IsFile():
+                
+                self._Parent.FavDeleteConfirmPage.SetFileName(cur_li._Path)
+                self._Parent.FavDeleteConfirmPage.SetTrashDir(self._Emulator["ROM"])## Fav delete,return to ROM dir,not .Trash
+                
+                self._Screen.PushCurPage()
+                self._Screen.SetCurPage(self._Parent.FavDeleteConfirmPage)
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+            
+    def Draw(self):
+        self.ClearCanvas()
+        
+        if len(self._MyList) == 0:
+            self._Icons["bg"].NewCoord(self._Width/2,self._Height/2)
+            self._Icons["bg"].Draw()
+        else:
+            if len(self._MyList) * ListItem._Height > self._Height:
+                self._Ps._Width = self._Width - 10
+                self._Ps.Draw()
+                
+                for i in self._MyList:
+                    i.Draw()
+                self._Scroller.UpdateSize( len(self._MyList)*ListItem._Height, self._PsIndex*ListItem._Height)
+                self._Scroller.Draw()
+    
+            else:
+                self._Ps._Width = self._Width
+                self._Ps.Draw()
+                for i in self._MyList:
+                    i.Draw()

+ 111 - 0
sys.py/UI/Emulator/list_item.py

@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+#from beeprint import pp
+import os
+
+## local UI import
+from UI.constants import ICON_TYPES
+from UI.page   import Page
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.icon_item import IconItem
+from UI.util_funcs import midRect
+
+# a item for List
+# - - - - - - - - - - - -- 
+# | Icon  Text.....    > |
+# ------------------------
+
+
+class ListItemIcon(IconItem):
+
+    _CanvasHWND = None
+    _Parent     = None
+    _Width      = 18
+    _Height     = 18
+    
+    def Draw(self):
+        self._CanvasHWND.blit(self._ImgSurf,(self._PosX,self._PosY+(self._Parent._Height-self._Height)/2,self._Width,self._Height))
+        
+class ListItem(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 32
+
+    _Labels = {}
+    _Icons  = {}
+    _Fonts  = {}
+    _MyType = ICON_TYPES["EXE"]
+    _LinkObj = None
+    _Path    = ""
+    _Active  = False
+    _Playing = False ## play or pause
+    _Parent  = None
+    
+    def __init__(self):
+        self._Labels = {}
+        self._Icons  = {}
+        self._Fonts  = {}
+
+    def IsFile(self):
+        if self._MyType == ICON_TYPES["FILE"]:
+            return True
+
+        return False
+    def IsDir(self):
+        if self._MyType == ICON_TYPES["DIR"]:
+            return True
+
+        return False
+    
+    def Init(self,text):
+
+        #self._Fonts["normal"] = fonts["veramono12"]
+        
+        l = Label()
+        l._PosX = 20
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+
+        if self._MyType == ICON_TYPES["DIR"] or self._MyType == ICON_TYPES["FILE"]:
+            self._Path = text
+
+        label_text = os.path.basename(text)
+        
+        if self._MyType == ICON_TYPES["DIR"]:
+            l.Init(label_text,self._Fonts["normal"])
+        else:
+            l.Init(label_text,self._Fonts["normal"])
+
+
+        self._Labels["Text"] = l
+
+        
+
+    def Draw(self):
+        if self._Path != "[..]":
+            self._Labels["Text"]._PosX = 23
+        else:
+            self._Labels["Text"]._PosX = 3
+            
+        self._Labels["Text"]._PosY = self._PosY + (self._Height - self._Labels["Text"]._Height)/2
+        self._Labels["Text"].Draw()
+
+        """
+        if self._Active == True:
+            pass
+        """
+        if self._MyType == ICON_TYPES["DIR"] and self._Path != "[..]":
+            self._Parent._Icons["sys"]._IconIndex = 0
+            self._Parent._Icons["sys"].NewCoord(self._PosX+12,self._PosY+ (self._Height - self._Parent._Icons["sys"]._Height)/2+self._Parent._Icons["sys"]._Height/2)
+            self._Parent._Icons["sys"].Draw()
+
+        if self._MyType == ICON_TYPES["FILE"]:
+            self._Parent._Icons["sys"]._IconIndex = 1
+            self._Parent._Icons["sys"].NewCoord(self._PosX+12,self._PosY+ (self._Height - self._Parent._Icons["sys"]._Height)/2+self._Parent._Icons["sys"]._Height/2)
+            self._Parent._Icons["sys"].Draw()
+        
+        pygame.draw.line(self._Parent._CanvasHWND,(169,169,169),(self._PosX,self._PosY+self._Height-1),(self._PosX+self._Width,self._PosY+self._Height-1),1)
+    
+

+ 466 - 0
sys.py/UI/Emulator/rom_list_page.py

@@ -0,0 +1,466 @@
+# -*- coding: utf-8 -*- 
+
+import os
+import pygame
+
+import glob
+import shutil
+import gobject
+import validators
+#from pySmartDL import SmartDL
+
+
+from libs.roundrects import aa_round_rect
+
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES,RUNEVT
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.icon_item import IconItem
+from UI.fonts  import fonts
+from UI.util_funcs import midRect,CmdClean,FileExists
+from UI.keys_def   import CurKeys
+from UI.multi_icon_item import MultiIconItem
+from UI.icon_pool  import MyIconPool
+from UI.scroller   import ListScroller
+
+from rom_so_confirm_page import RomSoConfirmPage
+
+from list_item  import ListItem
+import config
+    
+class RomStack:
+    _Emulator = None
+    
+    def __init__(self):
+        self.stack = list()
+
+    def Push(self,data):
+        if data not in self.stack:
+            self.stack.append(data)
+            return True
+        return False
+
+    def Pop(self):
+        if len(self.stack)<=0:
+            return None,False
+        return self.stack.pop(),True
+
+    def Last(self):
+        idx = len(self.stack) -1
+        if idx < 0:## empty stack,return root path
+            return self._Emulator["ROM"]
+        else:
+            return self.stack[ idx ]
+    
+    def Length(self):
+        return len(self.stack)
+
+class ListPageSelector(PageSelector):
+    _BackgroundColor = pygame.Color(131,199,219)
+
+    def __init__(self):
+        self._PosX = 0
+        self._PosY = 0
+        self._Height = 0
+        self._Width  = Width-12
+
+    def AnimateDraw(self,x2,y2):
+        pass
+
+    def Draw(self):
+        idx = self._Parent._PsIndex
+        if idx > (len(self._Parent._MyList)-1):
+            idx = len(self._Parent._MyList)
+            if idx > 0:
+                idx -=1
+            elif idx == 0:##nothing in _MyList
+                return
+
+        self._Parent._PsIndex = idx ## sync PsIndex
+        
+        x = self._Parent._MyList[idx]._PosX+2
+        y = self._Parent._MyList[idx]._PosY+1
+        h = self._Parent._MyList[idx]._Height -3
+        
+        self._PosX = x
+        self._PosY = y
+        self._Height = h
+
+        aa_round_rect(self._Parent._CanvasHWND,  
+                    (x,y,self._Width-4,h),self._BackgroundColor,4,0,self._BackgroundColor)
+
+
+
+class RomListPage(Page):
+
+    _Icons = {}
+    _Selector=None
+    _FootMsg = ["Nav","Scan","Del","Add Fav","Run"]
+    _MyList = []
+    _ListFont = fonts["notosanscjk15"]
+    _MyStack = None
+    _Emulator = None
+    _Parent   = None
+
+    _Scroller = None
+    
+    _Scrolled = 0
+
+    _BGwidth = 56
+    _BGheight = 70
+
+    _RomSoConfirmDownloadPage = None
+    
+    
+    def __init__(self):
+        Page.__init__(self)
+        
+        self._Icons = {}
+        self._CanvasHWND = None
+        self._MyList = []
+        self._MyStack = RomStack()
+        self._Emulator = {}
+        
+    def GeneratePathList(self,path):
+        if os.path.isdir(path) == False:
+            return False
+
+
+        files_path = glob.glob(path+"/*")
+        
+        ret = []
+
+        for i ,v in enumerate(files_path):
+            dirmap = {}
+            #if os.path.isdir(v):
+            #    dir_base_name = os.path.basename(v)
+            #    if dir_base_name == ".Trash" or dir_base_name == ".Fav":
+            #        pass
+            #    else:
+            #        dirmap["directory"] = v
+            #        ret.append(dirmap)
+            if os.path.isfile(v):
+                stats = os.stat(v)
+                if stats.st_gid == self._Parent._FavGID:
+                    continue
+                
+                bname = os.path.basename(v)  ### filter extension
+                if len(bname)> 1:
+                    pieces  = bname.split(".")
+                    if len(pieces) > 1:
+                        if pieces[ len(pieces)-1   ].lower() in self._Emulator["EXT"]:
+                            dirmap["file"] = v
+                            ret.append(dirmap)
+            else:
+                print("not file or dir")
+
+        
+        return ret
+
+    def SyncList(self,path):
+        
+        alist = self.GeneratePathList(path)
+        
+        if alist == False:
+            print("listfiles return false")
+            return
+        print("rom list alist: ")
+        print(alist)
+        
+        self._MyList = []
+        start_x  = 0
+        start_y  = 0
+        hasparent = 0
+        if self._MyStack.Length() > 0:
+            hasparent = 1
+            li = ListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFont
+            li._MyType = ICON_TYPES["DIR"]
+            li._Parent = self
+            li.Init("[..]")
+            self._MyList.append(li)
+        
+        for i,v in enumerate(sorted(alist)):
+            li = ListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y + (i+hasparent)*ListItem._Height
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFont
+            li._MyType  = ICON_TYPES["FILE"]
+
+            li._Parent = self
+            
+            if "directory" in v:
+                li._MyType = ICON_TYPES["DIR"]
+                li.Init(v["directory"])
+            elif "file" in v:
+                li.Init(v["file"])
+            else:
+                li.Init("NoName")
+
+            
+            self._MyList.append(li)
+
+        
+    def Init(self):
+        self._PosX = self._Index * self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+
+        self._CanvasHWND = self._Screen._CanvasHWND
+
+        ps = ListPageSelector()
+        ps._Parent = self
+        self._Ps = ps
+        self._PsIndex = 0
+
+        self.SyncList(self._Emulator["ROM"])
+
+        ### will also mkdir of the ***ROM self
+        try: 
+            os.makedirs(self._Emulator["ROM"]+"/.Trash")
+        except OSError:
+            if not os.path.isdir(self._Emulator["ROM"]+"/.Trash"):
+                raise
+            
+
+        try: 
+            os.makedirs(self._Emulator["ROM"]+"/.Fav")
+        except OSError:
+            if not os.path.isdir(self._Emulator["ROM"]+"/.Fav"):
+                raise
+
+        self._MyStack._Emulator = self._Emulator
+
+        icon_for_list = MultiIconItem()
+        icon_for_list._ImgSurf = self._Parent._Icons["sys"]
+        icon_for_list._MyType = ICON_TYPES["STAT"]
+        icon_for_list._Parent = self
+        
+        icon_for_list.Adjust(0,0,18,18,0)
+        
+        self._Icons["sys"] = icon_for_list
+
+
+        bgpng = IconItem()
+        bgpng._ImgSurf = MyIconPool._Icons["empty"]
+        bgpng._MyType = ICON_TYPES["STAT"]
+        bgpng._Parent = self
+        bgpng.AddLabel("Please upload data over Wi-Fi", fonts["varela22"])
+        bgpng.SetLableColor(pygame.Color(204,204,204))
+        bgpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+
+        self._Icons["bg"] = bgpng
+
+        self._Scroller = ListScroller()
+        self._Scroller._Parent = self
+        self._Scroller._PosX = self._Width - 10
+        self._Scroller._PosY = 2
+        self._Scroller.Init()
+
+        rom_so_confirm_page = RomSoConfirmPage()
+        rom_so_confirm_page._Screen = self._Screen
+        rom_so_confirm_page._Name = "Download Confirm"
+        rom_so_confirm_page._Parent = self
+        rom_so_confirm_page.Init()
+
+        self._RomSoConfirmDownloadPage = rom_so_confirm_page
+        
+    def ScrollUp(self):
+        if len(self._MyList) == 0:
+            return
+        
+        self._PsIndex -= 1
+        if self._PsIndex < 0:
+            self._PsIndex = 0
+        cur_li = self._MyList[self._PsIndex]
+        if cur_li._PosY < 0:
+            for i in range(0, len(self._MyList)):
+                self._MyList[i]._PosY += self._MyList[i]._Height
+            self._Scrolled +=1
+
+    def ScrollDown(self):
+        if len(self._MyList) == 0:
+            return
+        
+        self._PsIndex +=1
+        if self._PsIndex >= len(self._MyList):
+            self._PsIndex = len(self._MyList) -1
+
+        cur_li = self._MyList[self._PsIndex]
+        if cur_li._PosY +cur_li._Height > self._Height:
+            for i in range(0,len(self._MyList)):
+                self._MyList[i]._PosY -= self._MyList[i]._Height
+            self._Scrolled -= 1
+            
+    def SyncScroll(self):
+        ## 
+        if self._Scrolled == 0:
+            return
+
+        if self._PsIndex < len(self._MyList):
+            cur_li = self._MyList[self._PsIndex]
+            if self._Scrolled > 0:
+                if cur_li._PosY < 0:
+                    for i in range(0, len(self._MyList)):
+                        self._MyList[i]._PosY += self._Scrolled * self._MyList[i]._Height
+            elif self._Scrolled < 0:
+                if cur_li._PosY +cur_li._Height > self._Height:
+                    for i in range(0,len(self._MyList)):
+                        self._MyList[i]._PosY += self._Scrolled * self._MyList[i]._Height
+                
+    def Click(self):
+        if len(self._MyList) == 0:
+            return
+        
+        cur_li = self._MyList[self._PsIndex]
+        
+        if cur_li._MyType == ICON_TYPES["DIR"]:
+            if cur_li._Path == "[..]":
+                self._MyStack.Pop()
+                self.SyncList( self._MyStack.Last() )
+                self._PsIndex = 0
+            else:
+                self._MyStack.Push( self._MyList[self._PsIndex]._Path )
+                self.SyncList( self._MyStack.Last() )
+                self._PsIndex = 0
+                
+        if cur_li._MyType == ICON_TYPES["FILE"]: ## add to playlist only
+            self._Screen._MsgBox.SetText("Launching...")
+            self._Screen._MsgBox.Draw()
+            self._Screen.SwapAndShow()
+            print("Run  ",cur_li._Path)
+
+            # check ROM_SO exists
+            if FileExists(self._Emulator["ROM_SO"]):
+                escaped_path = CmdClean( cur_li._Path)
+                cmdpath = " ".join( (self._Emulator["LAUNCHER"],self._Emulator["ROM_SO"], escaped_path))
+                pygame.event.post( pygame.event.Event(RUNEVT, message=cmdpath))
+                return
+            else:
+                
+                self._Screen.PushPage(self._RomSoConfirmDownloadPage)
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+    
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+
+    def ReScan(self):
+        if self._MyStack.Length() == 0:
+            self.SyncList(self._Emulator["ROM"])
+        else:
+            self.SyncList( self._MyStack.Last() )
+
+        
+        idx = self._PsIndex
+        if idx > (len(self._MyList)-1):
+            idx = len(self._MyList)
+            if idx > 0:
+                idx -=1
+            elif idx == 0:##nothing in _MyList
+                pass
+        
+        self._PsIndex = idx ## sync PsIndex
+
+        self.SyncScroll()
+
+    def OnReturnBackCb(self):
+        self.ReScan()        
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        
+    def KeyDown(self,event):
+
+        if event.key == CurKeys["Menu"] : 
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+        if event.key == CurKeys["Right"]:
+            self._Screen.PushCurPage()
+            self._Screen.SetCurPage(self._Parent.FavListPage)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+        if event.key == CurKeys["Up"]:
+            self.ScrollUp()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+        if event.key == CurKeys["Down"]:
+            self.ScrollDown()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+        if event.key == CurKeys["Enter"]:
+            self.Click()
+
+        if event.key == CurKeys["A"]:
+            if len(self._MyList) == 0:
+                return
+            
+            cur_li = self._MyList[self._PsIndex]
+            if cur_li.IsFile():
+                # remove any dup first
+                
+                try:
+                    os.system("chgrp " + self._Parent._FavGname +" "+ CmdClean(cur_li._Path))
+                except:
+                    pass
+                
+                self._Screen._MsgBox.SetText("Adding to Favourite list")
+                self._Screen._MsgBox.Draw()
+                self._Screen.SwapAndShow()
+                
+                pygame.time.delay(600)
+                self.ReScan()                    
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                
+        if event.key == CurKeys["X"]: #Scan current
+           self.ReScan() 
+           self._Screen.Draw()
+           self._Screen.SwapAndShow()
+           
+        if event.key == CurKeys["Y"]: #del
+            if len(self._MyList) == 0:
+                return
+            
+            cur_li = self._MyList[self._PsIndex]
+            if cur_li.IsFile():
+                
+                self._Parent.DeleteConfirmPage.SetFileName(cur_li._Path)
+                self._Parent.DeleteConfirmPage.SetTrashDir(self._Emulator["ROM"]+"/.Trash")
+            
+                self._Screen.PushCurPage()
+                self._Screen.SetCurPage(self._Parent.DeleteConfirmPage)
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+            
+    def Draw(self):
+        self.ClearCanvas()
+        if len(self._MyList) == 0:
+            self._Icons["bg"].NewCoord(self._Width/2,self._Height/2)
+            self._Icons["bg"].Draw()
+        else:
+            if len(self._MyList) * ListItem._Height > self._Height:
+                self._Ps._Width = self._Width - 10
+                self._Ps.Draw()
+                
+                for i in self._MyList:
+                    i.Draw()
+                self._Scroller.UpdateSize( len(self._MyList)*ListItem._Height, self._PsIndex*ListItem._Height)
+                self._Scroller.Draw()
+    
+            else:
+                self._Ps._Width = self._Width
+                self._Ps.Draw()
+                for i in self._MyList:
+                    i.Draw()

+ 122 - 0
sys.py/UI/Emulator/rom_so_confirm_page.py

@@ -0,0 +1,122 @@
+
+# -*- coding: utf-8 -*- 
+
+import os
+import pygame
+
+import glob
+import shutil
+import gobject
+import validators
+#from pySmartDL import SmartDL
+
+from libs.roundrects import aa_round_rect
+
+from UI.confirm_page import ConfirmPage
+from UI.download_process_page import DownloadProcessPage
+from UI.keys_def   import CurKeys
+from UI.fonts  import fonts
+from UI.multilabel import MultiLabel
+
+import config
+
+class RomSoConfirmPage(ConfirmPage):
+    _ListFont = fonts["veramono18"]
+
+    _ConfirmText = "Do you want to setup this game engine automatically?"
+
+    _MyDownloadPage = None
+    
+    def CheckBattery(self):
+        try:
+            f = open(config.Battery)
+        except IOError:
+            print( "RomSoConfirmPage open %s failed" % config.Battery)
+            return 0
+        else:
+            with f:
+                bat_uevent = {}
+                content = f.readlines()
+                content = [x.strip() for x in content]
+                for i in content:
+                    pis = i.split("=")
+                    if len(pis) > 1:
+                        bat_uevent[pis[0]] = pis[1]
+
+                if "POWER_SUPPLY_CAPACITY" in bat_uevent:
+                    cur_cap = int(bat_uevent["POWER_SUPPLY_CAPACITY"])
+                else:
+                    cur_cap = 0
+                
+                return cur_cap
+                    
+        return 0
+
+    def Init(self):
+        self._PosX = self._Index * self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+
+        self._CanvasHWND = self._Screen._CanvasHWND
+
+        li = MultiLabel()
+        li.SetCanvasHWND(self._CanvasHWND)
+        li._Width = 160
+        li.Init(self._ConfirmText,self._ListFont)
+        
+        li._PosX = (self._Width - li._Width)/2
+        li._PosY = (self._Height - li._Height)/2
+
+        self._BGPosX = li._PosX-20
+        self._BGPosY = li._PosY-20
+        self._BGWidth = li._Width+40
+        self._BGHeight = li._Height+40
+        
+        self._MyList.append(li)
+        
+    def SnapMsg(self,msg):
+        self._MyList[0].SetText(msg)
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        self._MyList[0].SetText(self._ConfirmText)
+
+    def OnReturnBackCb(self):
+        self.ReturnToUpLevelPage()
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+    
+    def KeyDown(self,event):    
+        if event.key == CurKeys["Menu"] or event.key == CurKeys["A"]:
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+        if event.key == CurKeys["B"]:
+            if self.CheckBattery() < 5:
+                self.SnapMsg("Battery must over 5%")
+            else:
+                if self._MyDownloadPage == None:
+                    self._MyDownloadPage = DownloadProcessPage()
+                    self._MyDownloadPage._Screen = self._Screen
+                    self._MyDownloadPage._Name = "Downloading..."
+                    self._MyDownloadPage.Init()
+                
+                self._Screen.PushPage(self._MyDownloadPage)
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+
+                if config.CurKeySet == "PC":
+                    so_url = self._Parent._Emulator["SO_URL"] ## [rom/fav]_list_page is _Parent
+                    so_url = so_url.replace("armhf","x86_64")
+                    print(so_url)
+                    self._MyDownloadPage.StartDownload(so_url,os.path.dirname(self._Parent._Emulator["ROM_SO"]))
+                else:
+                    self._MyDownloadPage.StartDownload(self._Parent._Emulator["SO_URL"],
+                                                       os.path.dirname(self._Parent._Emulator["ROM_SO"]))
+            
+
+    def Draw(self):
+        self.ClearCanvas()
+        self.DrawBG()
+        for i in self._MyList:
+            i.Draw()

+ 118 - 0
sys.py/UI/above_all_patch.py

@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+from libs.roundrects import aa_round_rect
+
+import alsaaudio
+
+## local package import
+from constants   import ICON_TYPES,icon_ext,icon_width,icon_height,RUNEVT
+from icon_item   import IconItem
+from page        import Page,PageStack
+from title_bar   import TitleBar
+from foot_bar    import FootBar
+from constants   import Width,Height,bg_color
+from util_funcs  import midRect
+from fonts       import fonts
+from keys_def    import CurKeys
+from label       import Label
+
+
+
+
+class AboveAllPatch(object):
+    _PosX  =Width/2
+    _PosY  =Height/2
+    _Width =50
+    _Height=120
+    
+    _Text  =""
+    _FontObj=fonts["veramono20"]
+    _Parent =None
+    _Color = pygame.Color(83,83,83)
+    _ValColor= pygame.Color(0,0,255)
+    _CanvasHWND = None
+    _TextSurf = None
+    _Icons   = {}
+    _Value   = 0
+    
+    def __init__(self):
+        self._Icons = {}
+    
+    def Init(self):
+        pass
+    
+    def SetCanvasHWND(self,_canvashwnd):
+        self._CanvasHWND = _canvashwnd
+
+    def Draw(self):
+        start_rect = midRect(self._PosX,self._PosY,self._Width,self._Height,Width,Height)
+        aa_round_rect(self._CanvasHWND,start_rect, self._Color,3,0, self._Color)
+
+        if self._Value > 10:
+            vol_height = int(self._Height * (float( self._Value)/100.0))
+            dheight    = self._Height - vol_height
+            
+            vol_rect = pygame.Rect(self._PosX-self._Width/2, self._PosY-self._Height/2+dheight, self._Width, vol_height)
+
+            aa_round_rect(self._CanvasHWND,vol_rect, self._ValColor,3,0, self._ValColor)
+        
+        else:
+            vol_height = 10
+            dheight    = self._Height - vol_height
+            vol_rect = pygame.Rect(self._PosX-self._Width/2, self._PosY-self._Height/2+dheight, self._Width, vol_height)
+
+            aa_round_rect(self._CanvasHWND,vol_rect, self._ValColor,3,0, self._ValColor)
+    
+
+class SoundPatch(AboveAllPatch):
+
+    _ValColor =  pygame.Color(131,199,219)
+    _Segs       = [0,15,29, 45,55,65, 75,90,100]
+    snd_segs = [ [0,20],[21,40],[41,50],[51,60],[61,70],[71,85],[86,90],[91,95],[96,100] ]
+
+    def Init(self):
+        self.SetCanvasHWND(self._Parent._CanvasHWND)
+        
+    def VolumeUp(self):
+        m = alsaaudio.Mixer()
+        vol = m.getvolume()[0]
+        vol += 10
+        if vol > 100:
+            vol = 100
+
+        m.setvolume(vol)
+
+        self._Value = vol
+        
+        return vol
+        
+    def VolumeDown(self):
+        m = alsaaudio.Mixer()
+        vol = m.getvolume()[0]
+        vol -= 10
+        if vol < 0:
+            vol = 0
+        m.setvolume(vol)
+
+        print(vol)
+        self._Value = vol
+        return vol
+
+
+    def Draw(self):
+        # 200 total width
+        # h = 40
+        ge = 0
+        for i,v in enumerate(self.snd_segs):
+            if  self._Value >= v[0] and self._Value <= v[1]:
+                ge = i
+                break
+        
+        for i in range(0,ge+1):
+            #w = 10,h = 40
+            vol_rect = pygame.Rect(80+i*20, self._Height/2+20,10, 40)
+            
+            aa_round_rect(self._CanvasHWND,vol_rect, self._ValColor,3,0, self._ValColor)
+    

ファイルの差分が大きいため隠しています
+ 0 - 0
sys.py/UI/blueselector_b64.py


+ 142 - 0
sys.py/UI/confirm_page.py

@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import os
+
+from libs.roundrects import aa_round_rect
+
+#UI lib
+from constants import Width,Height,ICON_TYPES
+from page   import Page,PageSelector
+from label  import Label
+from fonts  import fonts
+from util_funcs import midRect
+from keys_def   import CurKeys
+
+
+
+class ListPageSelector(PageSelector):
+    _BackgroundColor = pygame.Color(131,199,219)
+
+    def __init__(self):
+        self._PosX = 0
+        self._PosY = 0
+        self._Height = 0
+        self._Width  = Width
+
+    def AnimateDraw(self,x2,y2):
+        pass
+
+    def Draw(self):
+        idx = self._Parent._PsIndex
+        if idx > (len(self._Parent._MyList)-1):
+            idx = len(self._Parent._MyList)
+            if idx > 0:
+                idx -=1
+            elif idx == 0: #Nothing
+                return
+        
+        x = self._Parent._MyList[idx]._PosX+2
+        y = self._Parent._MyList[idx]._PosY+1
+        h = self._Parent._MyList[idx]._Height -3
+        
+        self._PosX = x
+        self._PosY = y
+        self._Height = h
+
+        aa_round_rect(self._Parent._CanvasHWND,  
+                    (x,y,self._Width-4,h),self._BackgroundColor,4,0,self._BackgroundColor)
+
+
+
+class ConfirmPage(Page):
+
+    _Icons = {}
+    _Selector=None
+    _FootMsg = ["Nav","","","Cancel","Yes"]
+    _MyList = []
+    _ListFont = fonts["veramono20"]
+    _MyStack = None
+    _FileName     = ""
+    _TrashDir     = ""
+    _ConfirmText = "Confirm?"
+    _BGPosX      = 0
+    _BGPosY      = 0
+    _BGWidth     = 0
+    _BGHeight    = 0
+    _Parent      = None
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}
+        self._CanvasHWND = None
+        self._MyList = []
+        
+    def Reset(self):
+        self._MyList[0].SetText(self._ConfirmText)
+        self._MyList[0]._PosX = (self._Width - self._MyList[0]._Width)/2
+        self._MyList[0]._PosY = (self._Height - self._MyList[0]._Height)/2
+        
+        self._BGPosX = self._MyList[0]._PosX-10
+        self._BGPosY = self._MyList[0]._PosY-10
+        self._BGWidth = self._MyList[0]._Width+20
+        self._BGHeight = self._MyList[0]._Height+20
+
+        
+    def SnapMsg(self,msg):
+        self._MyList[0].SetText(msg)
+        self._MyList[0]._PosX = (self._Width - self._MyList[0]._Width)/2
+        self._MyList[0]._PosY = (self._Height - self._MyList[0]._Height)/2
+
+        self._BGPosX = self._MyList[0]._PosX-10
+        self._BGPosY = self._MyList[0]._PosY-10
+        self._BGWidth = self._MyList[0]._Width+20
+        self._BGHeight = self._MyList[0]._Height+20
+        
+    def Init(self):
+        self._PosX = self._Index * self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+
+        self._CanvasHWND = self._Screen._CanvasHWND
+
+        ps = ListPageSelector()
+        ps._Parent = self
+        self._Ps = ps
+        self._PsIndex = 0
+
+        li = Label()
+        li.SetCanvasHWND(self._CanvasHWND)
+        li.Init(self._ConfirmText,self._ListFont)
+        
+        li._PosX = (self._Width - li._Width)/2
+        li._PosY = (self._Height - li._Height)/2
+
+        self._BGPosX = li._PosX-10
+        self._BGPosY = li._PosY-10
+        self._BGWidth = li._Width+20
+        self._BGHeight = li._Height+20
+        
+        self._MyList.append(li)
+        
+    def KeyDown(self,event):
+        
+        if event.key == CurKeys["Menu"] or event.key == CurKeys["A"]:            
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+    def DrawBG(self):
+        _rect = pygame.Rect(self._BGPosX,self._BGPosY,self._BGWidth,self._BGHeight)
+        
+        pygame.draw.rect(self._CanvasHWND,(255,255,255),_rect,0)
+        pygame.draw.rect(self._CanvasHWND,(83,83,83),_rect,1)
+        
+    def Draw(self):
+        #self.ClearCanvas()
+        
+        self.DrawBG()
+        for i in self._MyList:
+            i.Draw()
+
+        self.Reset()

+ 45 - 0
sys.py/UI/constants.py

@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+from datetime import datetime
+
+import base64
+from beeprint import pp
+
+
+Width = 320
+Height = 240
+bg_color =  pygame.Color(255,255,255)
+
+icon_width  = 80
+icon_height = 80
+icon_ext = ".sh"
+
+
+ICON_TYPES={"Emulator":7,"FILE":6,"STAT":5,"NAV":4,"LETTER":3,"FUNC":2,"DIR":1,"EXE":0,"None":-1} # FUNC is like UI widget's function,DIR contains child page,EXE just execute a binary
+
+## H=horizontal  ,V=vertical S=Single Line
+#SLeft start from left, single line
+#SCenter star from center ,single line
+ALIGN = {"HLeft":0,"HCenter":1,"HRight":2,"VMiddle":3,"SLeft":4,"VCenter":5,"SCenter":6}
+
+DT = pygame.time.Clock().tick(30)   # fps in ms,eg:50
+
+
+GMEVT = pygame.USEREVENT+1
+update_titlebar_event = pygame.event.Event(GMEVT, message="titlebar")
+
+RUNEVT = pygame.USEREVENT+2
+RUNSYS = pygame.USEREVENT+3
+
+
+LOWLIGHT = pygame.USEREVENT+4 ## when dim screen backlight
+
+FOOTMSG = pygame.USEREVENT+5 ## when dim screen backlight
+
+

+ 73 - 0
sys.py/UI/delete_confirm_page.py

@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import os
+import shutil
+
+
+#UI lib
+from constants import Width,Height,ICON_TYPES
+from page   import Page,PageSelector
+from label  import Label
+from fonts  import fonts
+from util_funcs import midRect
+from keys_def   import CurKeys
+from confirm_page import ConfirmPage
+
+class DeleteConfirmPage(ConfirmPage):
+
+    _FileName     = ""
+    _TrashDir     = ""
+    _ConfirmText = "Confirm delete?"
+    
+    def SetTrashDir(self,d):
+        self._TrashDir = d
+        
+        if os.path.isdir(self._TrashDir) == False:
+            raise IOError("Trash not existed")
+        
+    def SetFileName(self,fn):
+        self._FileName = fn
+        
+    def KeyDown(self,event):
+        
+        if event.key == CurKeys["Menu"] or event.key == CurKeys["A"]:
+            
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+                
+        
+        if event.key == CurKeys["B"]:
+            try:
+                os.remove(self._TrashDir+"/"+os.path.basename(self._FileName))
+            except:
+                pass
+
+            try:
+                shutil.move(self._FileName, self._TrashDir)
+            except shutil.Error as e:
+                if "already exists" in str(e):
+                        self._Screen._MsgBox.SetText("Already existed")
+                else:
+                    self._Screen._MsgBox.SetText("Error ")
+                
+                self._Screen._MsgBox.Draw()
+                self._Screen.SwapAndShow()
+            else:    
+                #self._Screen._MsgBox.SetText("Deleteing..")
+                #self._Screen._MsgBox.Draw()
+                #self._Screen.SwapAndShow()
+                self.SnapMsg("Deleteing....")
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                self.Reset()
+                
+                pygame.time.delay(300)
+                self.ReturnToUpLevelPage()
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+
+            print(self._FileName)
+
+    

+ 213 - 0
sys.py/UI/download.py

@@ -0,0 +1,213 @@
+import os
+import pycurl
+import sys
+import time
+import urllib2
+import hashlib
+
+from threading import Thread
+
+class Download(Thread):
+    _dst_path = ""
+    _is_finished = False
+    _is_successful = False
+    _errors = []
+    _HashFunc = None
+    _HashValue = ""
+
+    def __init__(self, url, path, cookies=False, useragent=False):
+        super(Download, self).__init__()
+        self.url = url
+        self.path = path
+        self.useragent = useragent
+        self.cookies = cookies
+        self.downloaded = 0
+        
+        self.progress = { 'downloaded': 0, 'total': 0, 'percent': 0,'stopped':False }
+        self.stop = False
+        self.filename = ""
+    
+    def isFinished(self):
+        return self._is_finished
+
+    def isSuccessful(self):
+        return self._is_successful
+
+    def get_dest(self):
+        return self._dst_path
+
+    def get_errors(self):
+        return self._errors
+
+    def run(self):
+        
+        c = pycurl.Curl()
+        c.setopt(pycurl.URL, self.url)
+        c.setopt(pycurl.FOLLOWLOCATION, 1)
+        c.setopt(pycurl.MAXREDIRS, 5)
+        c.setopt(pycurl.NOBODY, 1)
+
+        c.setopt(pycurl.CONNECTTIMEOUT, 10)
+        
+        if self.useragent:
+            c.setopt(pycurl.USERAGENT, self.useragent)
+        
+        # add cookies, if available
+        if self.cookies:
+            c.setopt(pycurl.COOKIE, self.cookies)
+        c.perform()
+        realurl = c.getinfo(pycurl.EFFECTIVE_URL)
+        
+        self.filename = realurl.split("/")[-1].strip()
+        
+        c = pycurl.Curl()
+        c.setopt(pycurl.CONNECTTIMEOUT, 10)
+        c.setopt(pycurl.URL, realurl)
+        c.setopt(pycurl.FOLLOWLOCATION, 0)
+        c.setopt(pycurl.NOPROGRESS, False)
+        c.setopt(pycurl.XFERINFOFUNCTION, self.getProgress)
+        if self.useragent:
+            c.setopt(pycurl.USERAGENT, self.useragent)
+        
+        # configure pycurl output file
+        if self.path == False:
+            self.path = os.getcwd()
+        filepath = os.path.join(self.path, self.filename)
+            
+        if os.path.exists(filepath):## remove old file,restart download 
+            os.system("rm -rf " + filepath)
+            f = open(filepath, "wb")
+        else:
+            f = open(filepath, "wb")
+        
+        c.setopt(pycurl.WRITEDATA, f)
+        
+        self._dst_path = filepath
+
+        # add cookies, if available
+        if self.cookies:
+            c.setopt(pycurl.COOKIE, self.cookies)
+    
+        # download file
+        try:
+            c.perform()
+        except pycurl.error, error:
+            errno,errstr = error
+            print("curl error: %s" % errstr)
+            self._errors.append(errstr)
+            self.stop = True
+            self.progress["stopped"] = True
+        finally:
+
+            code = c.getinfo( c.RESPONSE_CODE )
+            c.close()            
+            self._is_finished = True
+        
+            if self.progress["percent"] < 100:
+                self._is_successful = False
+            else:
+                if self._HashFunc != None:
+                    hashed = self.hashlib_hash(self._HashFunc, self._dst_path)
+                    if hashed == self._HashValue:
+                        self._is_successful= True
+                    else:
+                        self._is_successful = False
+                        self._errors.append("hash failed")
+                else:
+                    if code != 200:
+                        self._is_successful = False
+                        os.system("rm -rf " + self._dst_path) ## clear garbage file
+                        self._errors.append("response error %d " % code)
+                    else:
+                        self._is_successful = True ## 100% downloaded without hash check
+ 
+    def getProgress(self,download_t, download_d, upload_t, upload_d):
+        if download_t and download_d:
+            self.progress['downloaded'] = download_d + self.downloaded
+            self.progress['total'] = download_t + self.downloaded 
+            self.progress['percent'] = ( float(self.progress['downloaded']) / float(self.progress['total'])) * 100.0
+            self.progress["stopped"] = False            
+        if self.stop:
+            self.progress["stopped"] = True
+            return 1
+    
+    def hashlib_hash(method,fname): #eg: method == hashlib.md5(),function pointer
+        hash_ = method
+        with open(fname, "rb") as f:
+            for chunk in iter(lambda: f.read(4096), b""):
+                hash_.update(chunk)
+
+        return hash_.hexdigest()
+
+    def add_hash_verification(self,method_name,method_value):
+        if method_name == "md5":
+            self._HashFunc = hashlib.md5()
+        else:
+            self._HashFunc = None
+ 
+        self._HashValue = method_value
+
+    def get_progress(self):
+        return self.progress["percent"]
+    
+    def stop(self):
+        self.stop = True
+ 
+    def cancel(self):
+        # sets the boolean to stop the thread.
+        self.stop = True
+        
+def main():
+    from optparse import OptionParser
+    
+    parser = OptionParser(usage="%prog [options] <url>")
+    parser.add_option(  "-p", "--path", default=False, dest="path", help="download file to PATH", metavar="PATH")
+    parser.add_option(  "-c", "--cookies", default=False, dest="cookies", help="specify cookie(s)", metavar="COOKIES")
+    opts, args = parser.parse_args()
+
+    if len(args) == 0:
+        parser.error("No url supplied")
+    
+    for url in args:
+        print("Downloading: %s" % url)
+        if opts.path:
+            print("to: %s" % opts.path)
+        else:
+            print("to current directory")
+        d = Download(url, opts.path, opts.cookies)
+        d.start()
+
+        last_downloaded = 0
+        sleep_time = 0.05
+        while 1:
+            try:
+                progress = d.progress['percent']
+                
+                download_dx = d.progress["downloaded"] - last_downloaded
+
+                speed = float(download_dx) / ( sleep_time * 1000.0)
+                
+                last_downloaded = d.progress["downloaded"]
+                
+                if d.progress["stopped"] == True:
+                    break
+
+                print("%.2f percent | %d of %d | %.1f KB/s" % (progress, d.progress['downloaded'], d.progress['total'], speed))
+
+                if progress == 100:
+                    print("")
+                    print("Download complete: %s" % d.filename)
+                    break
+                time.sleep(sleep_time)
+
+            # tell thread to terminate on keyboard interrupt,
+            # otherwise the process has to be killed manually
+            except KeyboardInterrupt:
+                d.cancel()
+                break
+
+            except:
+                raise
+            
+if __name__ == "__main__":
+    main()

+ 225 - 0
sys.py/UI/download_process_page.py

@@ -0,0 +1,225 @@
+# -*- coding: utf-8 -*- 
+import os
+import pygame
+
+import gobject
+import validators
+
+
+from libs.roundrects import aa_round_rect
+
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES,RUNEVT
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.icon_item import IconItem
+from UI.fonts  import fonts
+from UI.util_funcs import midRect,CmdClean,FileExists
+from UI.keys_def   import CurKeys
+from UI.multi_icon_item import MultiIconItem
+from UI.icon_pool  import MyIconPool
+from UI.download   import Download
+
+from libs.DBUS     import is_wifi_connected_now
+
+import config
+
+class DownloadProcessPage(Page):
+    _FootMsg = ["Nav.","","","Back",""]
+    _Downloader = None
+    _DownloaderTimer = -1
+    _Value = 0
+
+    _URL = ""
+    _DST_DIR = ""
+
+    _PngSize = {}
+
+    _FileNameLabel = None
+    _SizeLabel     = None
+
+    _URLColor  = pygame.Color(51,166,255)
+    _TextColor = pygame.Color(83,83,83)
+    
+    def __init__(self):
+        Page.__init__(self)        
+        self._Icons = {}
+        self._CanvasHWND = None
+        
+    def Init(self):
+        self._PosX = self._Index * self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+
+        self._CanvasHWND = self._Screen._CanvasHWND
+
+        self._PngSize["bg"] = (48,79)
+        self._PngSize["needwifi_bg"] = (253,132)
+        
+        bgpng = IconItem()
+        bgpng._ImgSurf = MyIconPool._Icons["rom_download"]
+        bgpng._MyType = ICON_TYPES["STAT"]
+        bgpng._Parent = self
+        bgpng.Adjust(0,0,self._PngSize["bg"][0],self._PngSize["bg"][1],0)
+        self._Icons["bg"] = bgpng
+
+        needwifi_bg = IconItem()
+        needwifi_bg._ImgSurf = MyIconPool._Icons["needwifi_bg"]
+        needwifi_bg._MyType = ICON_TYPES["STAT"]
+        needwifi_bg._Parent = self
+        needwifi_bg.Adjust(0,0,self._PngSize["needwifi_bg"][0],self._PngSize["needwifi_bg"][1],0)
+
+        self._Icons["needwifi_bg"] = needwifi_bg
+
+        
+        self._FileNameLabel = Label()
+        self._FileNameLabel.SetCanvasHWND(self._CanvasHWND)
+        self._FileNameLabel.Init("", fonts["varela12"])
+
+        self._SizeLabel = Label()
+        self._SizeLabel.SetCanvasHWND(self._CanvasHWND)
+        self._SizeLabel.Init("0/0Kb",fonts["varela12"])
+        self._SizeLabel.SetColor( self._URLColor )
+
+        
+    def OnExitCb(self,event):
+        print("DownloadProcessPage OnExitCb")
+        if self._Downloader == None:
+            return        
+        try:
+            self._Downloader.stop()
+        except:
+            pass
+        return
+    
+    def GObjectUpdateProcessInterval(self):
+        if self._Screen.CurPage() == self:
+            if self._Downloader.isFinished():
+                if self._Downloader.isSuccessful():
+                    print("Success!")
+                    # Do something with obj.get_dest()
+                    filename = os.path.basename(self._Downloader.get_dest())
+                    cur_dir = os.getcwd()
+                    
+                    if filename.endswith(".zip"):
+                        os.chdir(self._DST_DIR)
+                        os.system( "unzip " + filename )
+                    
+                    elif filename.endswith(".zsync"):
+                        os.chdir(self._DST_DIR)
+                        os.system( "rm -rf " + filename)
+                        
+                    elif filename.endswith(".tar.xz"):                    
+                        os.chdir(self._DST_DIR)
+                        os.system( "tar xf " + filename)
+                        os.system( "rm -rf " + filename)
+                    
+                    os.chdir(cur_dir)    
+                    self.ReturnToUpLevelPage()
+                    self._Screen.Draw()
+                    self._Screen.SwapAndShow()
+                    
+                else:
+                    print("Download failed with the following exceptions:")
+                    for e in self._Downloader.get_errors():
+                        print(unicode(e))
+
+                    try:
+                        self._Downloader.stop()
+                    except:
+                        pass
+                    
+                    self._Screen._MsgBox.SetText("Download failed")
+                    self._Screen._MsgBox.Draw()
+                    self._Screen.SwapAndShow()
+                    return False
+            else:
+                self._Value =  self._Downloader.get_progress()
+
+                filename = os.path.basename(self._Downloader.get_dest())
+                self._FileNameLabel.SetText( filename )
+
+                downloaded = self._Downloader.progress["downloaded"]
+                total      = self._Downloader.progress["total"]
+
+                downloaded = downloaded/1000.0/1000.0
+                total      = total/1000.0/1000.0
+                
+                self._SizeLabel.SetText( "%.2f" % downloaded+"/"+ "%.2f" % total +"Mb")
+                
+                print("Progress: %d%%" % (self._Value))
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                return True
+        else:
+            return False
+    
+    def StartDownload(self,url,dst_dir):
+        if is_wifi_connected_now() == False:
+            return
+        
+        if validators.url(url) and os.path.isdir(dst_dir):
+            self._URL = url
+            self._DST_DIR = dst_dir
+        else:
+            self._Screen._MsgBox.SetText("Invaid")
+            self._Screen._MsgBox.Draw()
+            self._Screen.SwapAndShow()            
+            print("url or dst dir error")
+            return
+        
+        self._Downloader = Download(url,dst_dir,None)
+        self._Downloader.start()
+        
+        self._DownloaderTimer = gobject.timeout_add(100, self.GObjectUpdateProcessInterval)
+        
+    def KeyDown(self,event):
+        if event.key == CurKeys["Menu"] or event.key == CurKeys["A"]:
+            gobject.source_remove(self._DownloaderTimer)
+            self._DownloaderTimer = -1
+            
+            if self._Downloader != None:
+                try:
+                    self._Downloader.stop()
+                except:
+                    print("user canceled ")
+            
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+    def Draw(self):
+        self.ClearCanvas()
+
+        if is_wifi_connected_now() == False:
+            self._Icons["needwifi_bg"].NewCoord(self._Width/2, self._Height/2)
+            self._Icons["needwifi_bg"].Draw()
+            return
+        
+        self._Icons["bg"].NewCoord(self._Width/2,self._Height/2-20)
+        self._Icons["bg"].Draw()
+        
+        percent = self._Value
+        if percent < 10:
+            percent = 10
+
+        
+        rect_ = midRect(self._Width/2,self._Height/2+33,170,17, Width,Height)
+        aa_round_rect(self._CanvasHWND,rect_, (238,238,238),5,0,(238,238,238))
+        
+        rect2 = midRect(self._Width/2,self._Height/2+33,int(170*(percent/100.0)),17, Width,Height)
+        rect2.left = rect_.left
+        rect2.top  = rect_.top
+        aa_round_rect(self._CanvasHWND,rect2, (126,206,244),5,0,(126,206,244))
+
+        rect3 = midRect(self._Width/2,self._Height/2+53,self._FileNameLabel._Width, self._FileNameLabel._Height,Width,Height)
+
+        rect4 = midRect(self._Width/2,self._Height/2+70,self._SizeLabel._Width, self._SizeLabel._Height,Width,Height)
+
+        self._FileNameLabel.NewCoord(rect3.left,rect3.top)
+        self._SizeLabel.NewCoord(rect4.left, rect4.top)
+
+        self._FileNameLabel.Draw()
+        self._SizeLabel.Draw()
+        
+        

+ 63 - 0
sys.py/UI/fonts.py

@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+from datetime import datetime
+
+
+if not pygame.font.get_init():
+    pygame.font.init()
+
+fonts_path = {}
+
+fonts_path["varela"]   = "../truetype/VarelaRound-Regular.ttf"
+fonts_path["veramono"] = "../truetype/VeraMono.ttf"
+fonts_path["noto"]     = "../truetype/NotoSansMono-Regular.ttf"
+fonts_path["notocjk"]     = "../truetype/NotoSansCJK-Regular.ttf"
+
+fonts = {}
+fonts["varela12"] = pygame.font.Font(fonts_path["varela"],12)
+fonts["varela13"] = pygame.font.Font(fonts_path["varela"],13)
+fonts["varela14"] = pygame.font.Font(fonts_path["varela"],14)
+fonts["varela15"] = pygame.font.Font(fonts_path["varela"],15)
+
+fonts["varela16"] = pygame.font.Font(fonts_path["varela"],16)
+fonts["varela18"] = pygame.font.Font(fonts_path["varela"],18)
+fonts["varela20"] = pygame.font.Font(fonts_path["varela"],20)
+fonts["varela22"] = pygame.font.Font(fonts_path["varela"],22)
+fonts["varela23"] = pygame.font.Font(fonts_path["varela"],23)
+fonts["varela24"] = pygame.font.Font(fonts_path["varela"],24)
+fonts["varela25"] = pygame.font.Font(fonts_path["varela"],25)
+fonts["varela26"] = pygame.font.Font(fonts_path["varela"],26)
+fonts["varela27"] = pygame.font.Font(fonts_path["varela"],27)
+fonts["varela28"] = pygame.font.Font(fonts_path["varela"],28)
+fonts["varela34"] = pygame.font.Font(fonts_path["varela"],34)
+fonts["varela40"] = pygame.font.Font(fonts_path["varela"],40)
+
+fonts["veramono25"] = pygame.font.Font(fonts_path["veramono"],25)
+fonts["veramono24"] = pygame.font.Font(fonts_path["veramono"],24)
+fonts["veramono23"] = pygame.font.Font(fonts_path["veramono"],23)
+fonts["veramono22"] = pygame.font.Font(fonts_path["veramono"],22)
+fonts["veramono21"] = pygame.font.Font(fonts_path["veramono"],21)
+fonts["veramono20"] = pygame.font.Font(fonts_path["veramono"],20)
+fonts["veramono18"] = pygame.font.Font(fonts_path["veramono"],18)
+fonts["veramono16"] = pygame.font.Font(fonts_path["veramono"],16)
+fonts["veramono15"] = pygame.font.Font(fonts_path["veramono"],15)
+fonts["veramono14"] = pygame.font.Font(fonts_path["veramono"],14)
+fonts["veramono13"] = pygame.font.Font(fonts_path["veramono"],13)
+fonts["veramono12"] = pygame.font.Font(fonts_path["veramono"],12)
+fonts["veramono11"] = pygame.font.Font(fonts_path["veramono"],11)
+fonts["veramono10"] = pygame.font.Font(fonts_path["veramono"],10)
+
+for i in range(10,18):
+    fonts["notosansmono"+str(i)] = pygame.font.Font(fonts_path["noto"],i)
+
+for i in range(10,18):
+    fonts["notosanscjk"+str(i)] = pygame.font.Font(fonts_path["notocjk"],i)
+    
+fonts["arial"] = pygame.font.SysFont("arial",16)
+

+ 161 - 0
sys.py/UI/foot_bar.py

@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import os
+
+
+##local import 
+from constants  import Width,Height,ICON_TYPES,ALIGN
+from util_funcs import FileExists,midRect
+from icon_item  import IconItem
+from fonts      import fonts
+from multi_icon_item import MultiIconItem
+
+from libs.roundrects import aa_round_rect
+
+icon_base_path = "gameshell/footbar_icons/"
+
+class FootBarIcon(MultiIconItem):
+
+    def TotalWidth(self):
+        return self._Width+self._Label._Width
+    
+    def Draw(self):
+        if self._Align==ALIGN["VCenter"]: #default
+            if self._Label != None:
+                self._Label._PosX = self._PosX - self._Label._Width/2
+                self._Label._PosY = self._PosY + self._Height/2 + 12
+                
+        elif self._Align ==ALIGN["HLeft"]:
+            if self._Label != None:
+                self._Label._PosX = self._PosX + self._Width/2 + 3
+                self._Label._PosY = self._PosY - self._Label._Height/2
+
+        if self._Label!=None:
+            self._Label.Draw()
+        
+        if self._ImgSurf != None:
+            self._Parent._CanvasHWND.blit(self._ImgSurf,midRect(self._PosX,
+                                                                self._PosY,
+                                                                self._Width,self._Height,Width,Height),
+                                          (0,self._IconIndex*self._IconHeight,self._IconWidth,self._IconHeight))
+class FootBar:
+    _PosX      = 0
+    _PosY      = Height-20
+    _Width     = Width
+    _Height    = 20
+    _BarHeight = 20.5 
+    _BorderWidth = 1
+    _CanvasHWND = None
+    _HWND       = None
+    _Icons      = {}
+    _IconWidth   = 18
+    _IconHeight  = 18
+    _LabelFont   = fonts["veramono10"]
+    _State       = "normal"
+    _BgColor     = pygame.Color(255,255,255)
+    
+    def __init__(self):
+        self._Icons = {}
+
+
+    def ReadFootBarIcons(self,icondir):
+        if FileExists(icondir) == False and os.path.isdir(icondir) == False:
+            return
+
+        keynames = ["nav","x","y","a","b"]
+
+        share_surf = pygame.image.load(icon_base_path+"footbar.png").convert_alpha()
+        
+        files = os.listdir(icondir)
+        for _i,i in enumerate( keynames):
+            it = FootBarIcon()
+            it._MyType = ICON_TYPES["NAV"]
+            it._Parent = self
+            it._ImgSurf= share_surf
+            it._Align = ALIGN["HLeft"] # (x)text <= 
+
+            it.AddLabel("game",self._LabelFont)
+            it.Adjust(self._IconWidth/2+_i*self._IconWidth, self._IconHeight/2+2, self._IconWidth, self._IconHeight,0)
+            it._IconIndex = _i
+            self._Icons[i] = it
+
+        
+    def Init(self,screen):
+        self._HWND       = screen
+        self._CanvasHWND = pygame.Surface((Width,int(self._BarHeight)))
+
+        self.ReadFootBarIcons(icon_base_path)
+
+    def ResetNavText(self):
+        self._Icons["nav"]._Label.SetText("Nav.")
+        self._State = "normal"
+        self.Draw()
+        
+    def UpdateNavText(self,texts):
+        self._State = "tips"
+        my_text = self._LabelFont.render(texts,True,(83,83,83))
+        """
+        _w = 0
+        for i, x in enumerate(("b","a","y","x")):
+            if self._Icons[x]._Label._Text!="":
+                if i==0:
+                    _w += self._Icons[x].TotalWidth()
+                else:
+                    _w += self._Icons[x].TotalWidth()+5
+        """
+        left_width = self._Width  - 18
+
+        final_piece = ""
+        for i ,v in enumerate(texts):
+            text_slice = texts[:i+1]
+            my_text = self._LabelFont.render(text_slice,True,(83,83,83))
+            final_piece = text_slice
+            if my_text.get_width() >= left_width:
+                break
+            
+        print("finalpiece %s" %final_piece)
+        self._Icons["nav"]._Label.SetText( final_piece )
+
+        self.Draw()
+        
+    def SetLabelTexts(self,texts):
+        for idx,x in enumerate(("nav","x","y","a","b")):
+            try:
+                self._Icons[x]._Label.SetText(texts[idx])
+            except IndexError:
+                print("Index "+x+" doesn't exist!")
+
+    
+    def ClearCanvas(self):
+        self._CanvasHWND.fill((0,0,0))
+        aa_round_rect(self._CanvasHWND,  
+                    (0,0,self._Width,self._Height),self._BgColor,8,0, self._BgColor)
+
+        pygame.draw.rect(self._CanvasHWND,self._BgColor,(0,0,Width,self._BarHeight/2), 0 )
+        
+    def Draw(self):
+        self.ClearCanvas()
+        self._Icons["nav"].NewCoord(self._IconWidth/2+3,self._IconHeight/2+2)
+        self._Icons["nav"].Draw()
+
+        if self._State == "normal":
+            _w=0
+            #for i,x in enumerate(("a","b","x","y")):
+            for i, x in enumerate(("b","a","y","x")):
+                if self._Icons[x]._Label._Text!="":
+                    if i==0:
+                        _w += self._Icons[x].TotalWidth()
+                    else:
+                        _w += self._Icons[x].TotalWidth()+5
+                    
+                    start_x = self._Width - _w
+                    start_y = self._IconHeight/2+2
+                    self._Icons[x].NewCoord(start_x,start_y)
+                    self._Icons[x].Draw()
+
+
+        pygame.draw.line(self._CanvasHWND,(169,169,169),(0,0),(Width,0),self._BorderWidth)
+
+        if self._HWND  != None:
+            self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,Width,self._BarHeight))

+ 109 - 0
sys.py/UI/icon_item.py

@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+## local import
+from constants  import icon_width,icon_height,ICON_TYPES,ALIGN,icon_ext,Width,Height
+from util_funcs import color_surface,midRect
+from label      import Label
+
+class IconItem:
+    _PosX=0
+    _PosY=0
+    _Width=0
+    _Height=0
+    _ImageName=""
+    _ImgSurf = None
+    _Parent = None
+    _Index  = 0
+    _MyType = ICON_TYPES["EXE"]
+    _CmdPath = ""
+    _LinkPage = None
+    _Label   = None
+    _Align   = ALIGN["VCenter"] # set for the Icon Image and Text Label
+    
+    def __init__(self):
+        self._ImgSurf=None
+        
+
+    def Init(self,x,y,w,h,at): # the Surface is assigned in Screen 
+        self._PosX = x
+        self._PosY = y
+        self._Width = w
+        self._Height = h
+        self._AnimationTime = at
+
+    def SetLableColor(self,color):
+        self._Label.SetColor(color)
+        
+    def NewCoord(self,x,y):
+        self._PosX = x
+        self._PosY = y
+
+    def AddLabel(self,text,fontobj):
+        if self._Label == None:
+            self._Label = Label()
+            self._Label.Init(text,fontobj)
+        else:
+            #just replace the text
+            self._Label._Init(text,fontobj)
+
+    def Adjust(self,x,y,w,h,at): # the Surface is assigned in Screen 
+        self.Init(x,y,w,h,at)
+
+        if self._Label != None:
+            self._Label.SetCanvasHWND( self._Parent._CanvasHWND)
+
+        self.CreateImageSurf()
+        self.AdjustLinkPage()
+
+    def AdjustLinkPage(self):
+        if self._MyType==ICON_TYPES["DIR"] and self._LinkPage != None:
+            self._LinkPage._Index = 0
+            self._LinkPage._Align = ALIGN["SLeft"]
+            self._LinkPage._IconNumbers = len(self._LinkPage._Icons)
+            self._LinkPage._Screen = self._Parent._Screen
+            self._LinkPage._CanvasHWND       = self._Parent._Screen._CanvasHWND
+            
+            self._LinkPage._FootMsg =  ["Nav.","","","Back","Enter"] ## Default Page Foot info
+            
+            if self._LinkPage._Align == ALIGN["HLeft"]:
+                self._LinkPage.AdjustHLeftAlign()
+            elif self._LinkPage._Align == ALIGN["SLeft"]:
+                self._LinkPage.AdjustSAutoLeftAlign()
+                if self._LinkPage._IconNumbers > 1:
+                    self._LinkPage._PsIndex = 1
+                    self._LinkPage._IconIndex = self._LinkPage._PsIndex
+
+    def CreateImageSurf(self):
+        
+        if self._ImgSurf == None and self._ImageName != "":
+#            print(self._ImageName)
+            self._ImgSurf = pygame.image.load( self._ImageName ).convert_alpha() 
+            if self._ImgSurf.get_width() > icon_width or self._ImgSurf.get_height() > icon_height:
+                self._ImgSurf = pygame.transform.scale(self._ImgSurf,(icon_width,icon_height))
+   
+    def ChangeImgSurfColor(self,color):
+        color_surface(self._ImgSurf,color)
+
+    def Clear(self):
+        pass
+
+    def Draw(self):
+        if self._Align==ALIGN["VCenter"]: #default
+            if self._Label != None:
+                self._Label._PosX = self._PosX - self._Label._Width/2 + self._Parent._PosX
+                self._Label._PosY = self._PosY + self._Height/2 +6  + self._Parent._PosY
+                
+        elif self._Align ==ALIGN["HLeft"]:
+            if self._Label != None:
+                self._Label._PosX = self._PosX + self._Width/2 + 3 + self._Parent._PosX
+                self._Label._PosY = self._PosY - self._Label._Height/2 + self._Parent._PosY
+
+        if self._Label!=None:
+            self._Label.Draw()
+        
+        if self._ImgSurf != None:
+            self._Parent._CanvasHWND.blit(self._ImgSurf,midRect(self._PosX+self._Parent._PosX,
+                                       self._PosY+self._Parent._PosY,
+                                       self._Width,self._Height,Width,Height))

+ 29 - 0
sys.py/UI/icon_pool.py

@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+
+##pool only store surfaces
+
+class IconPool(object):
+
+    _GameShellIconPath = "gameshell/icons/"
+    _Icons = {}
+    def __init__(self):
+        self._Icons= {}
+
+    def Init(self):
+        
+        files = os.listdir(self._GameShellIconPath)
+        for i in files:
+            if os.path.isfile(self._GameShellIconPath+"/"+i) and i.endswith(".png"):
+                keyname = i.split(".")[0]
+                self._Icons[keyname] = pygame.image.load(self._GameShellIconPath+"/"+i).convert_alpha()
+                
+
+MyIconPool = IconPool()
+

+ 14 - 0
sys.py/UI/keyboard_keys.layout

@@ -0,0 +1,14 @@
+1 2 3 4 5 6 7 8 9 0
+q w e r t y u i o p
+a s d f g h j k l
+_L z x c v b n m _R
+
+1 2 3 4 5 6 7 8 9 0
+Q W E R T Y U I O P
+A S D F G H J K L
+_L Z X C V B N M _R
+
+! @ # $ % ^ & * ( )
+- _ + = ~ ` [ ] { }
+| \ : ; " ' < > , .
+_L ? / _R _S

+ 58 - 0
sys.py/UI/keys_def.py

@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+
+from config import CurKeySet
+
+GameShell = {}
+"""
+GameShell["Up"]   = pygame.K_w
+GameShell["Down"] = pygame.K_s
+GameShell["Left"] = pygame.K_a
+GameShell["Right"]= pygame.K_d
+"""
+GameShell["Up"]   = pygame.K_UP
+GameShell["Down"] = pygame.K_DOWN
+GameShell["Left"] = pygame.K_LEFT
+GameShell["Right"]= pygame.K_RIGHT
+
+GameShell["Menu"] = pygame.K_ESCAPE
+GameShell["X"]    = pygame.K_u
+GameShell["Y"]    = pygame.K_i
+GameShell["A"]    = pygame.K_j
+GameShell["B"]    = pygame.K_k
+
+GameShell["Vol-"] = pygame.K_SPACE
+GameShell["Vol+"] = pygame.K_RETURN
+GameShell["Space"] = pygame.K_SPACE
+
+GameShell["Enter"] = pygame.K_k
+GameShell["Start"] = pygame.K_RETURN
+
+
+PC = {}
+
+PC["Up"]    = pygame.K_UP
+PC["Down"]  = pygame.K_DOWN
+PC["Left"]  = pygame.K_LEFT
+PC["Right"] = pygame.K_RIGHT
+PC["Menu"]  = pygame.K_ESCAPE
+PC["X"]     = pygame.K_x
+PC["Y"]     = pygame.K_y
+PC["A"]     = pygame.K_a
+PC["B"]     = pygame.K_b
+PC["Vol-"]  = pygame.K_SPACE
+PC["Vol+"]  = pygame.K_RETURN
+PC["Enter"] = pygame.K_RETURN
+PC["Space"] = pygame.K_SPACE
+PC["Start"] = pygame.K_s
+
+if CurKeySet == "PC":
+    CurKeys = PC
+else:
+    CurKeys = GameShell

+ 56 - 0
sys.py/UI/label.py

@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+#import base64
+#from beeprint import pp
+
+class Label:
+    _PosX=0
+    _PosY=0
+    _Width=0
+    _Height=0
+    _Text=""
+    _FontObj=None
+    _Color = pygame.Color(83,83,83)
+    _CanvasHWND = None
+    _TextSurf = None
+    def __init__(self):
+        pass
+    
+    def Init(self,text,font_obj,color=pygame.Color(83,83,83)):
+        self._Color = color
+        self._FontObj = font_obj
+        self._Text = text
+
+        my_text = self._FontObj.render(self._Text,True,self._Color)
+        self._Width = my_text.get_width()
+        self._Height = my_text.get_height()
+
+    def NewCoord(self,x,y):
+        self._PosX = x
+        self._PosY = y
+        
+    def SetColor(self,color):
+        self._Color = color
+    
+    def GetText(self):
+        return self._Text
+    
+    def SetText(self,text):
+        self._Text = text
+        
+        my_text = self._FontObj.render(self._Text,True,self._Color)
+        self._Width = my_text.get_width()
+        self._Height = my_text.get_height()
+
+    def Width(self):
+        return self._Width
+    
+    def SetCanvasHWND(self,_canvashwnd):
+        self._CanvasHWND = _canvashwnd
+
+    def Draw(self):
+        my_text = self._FontObj.render( self._Text,True,self._Color)
+        
+        self._CanvasHWND.blit(my_text,(self._PosX,self._PosY,self._Width,self._Height))

+ 468 - 0
sys.py/UI/main_screen.py

@@ -0,0 +1,468 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+from libs import easing
+from datetime import datetime
+
+import base64
+from beeprint import pp
+
+## local package import
+from constants   import ICON_TYPES,icon_ext,icon_width,icon_height,RUNEVT
+from icon_item   import IconItem
+from page        import Page,PageStack
+from title_bar   import TitleBar
+from foot_bar    import FootBar
+from constants   import Width,Height,bg_color
+from util_funcs  import FileExists,ReplaceSuffix,ReadTheFileContent,CmdClean,MakeExecutable
+from fonts       import fonts
+from keys_def    import CurKeys
+from label       import Label
+from untitled_icon import UntitledIcon
+from Emulator    import MyEmulator
+
+class MessageBox(Label):
+    _Parent = None
+    
+    def Draw(self):
+        my_text = self._FontObj.render( self._Text,True,self._Color)
+        w  = my_text.get_width()
+        h  = my_text.get_height()
+        x  = (self._Parent._Width - w)/2
+        y =  (self._Parent._Height - h)/2
+        
+        padding = 10 
+        pygame.draw.rect(self._CanvasHWND,(255,255,255),(x-padding,y-padding, w+padding*2,h+padding*2))        
+
+        pygame.draw.rect(self._CanvasHWND,(0,0,0),(x-padding,y-padding, w+padding*2,h+padding*2),1)
+
+        self._CanvasHWND.blit(my_text,(x,y,w,h))
+
+
+python_package_flag = "__init__.py"
+emulator_flag       = "action.config"
+
+##Abstract object for manage Pages ,not the pygame's physic screen
+class MainScreen(object):
+    _Pages = []
+    _PageMax = 0
+    _PageIndex = 0
+    _PosX  = 0
+    _PosY  = TitleBar._BarHeight+1
+    _Width = Width 
+    _Height = Height -FootBar._BarHeight -TitleBar._BarHeight-1
+    _MyPageStack = None
+    _CurrentPage = None # pointer to the current displaying Page Class
+    _CanvasHWND  = None
+    _HWND        = None
+    _TitleBar    = None
+    _FootBar     = None
+    _MsgBox      = None
+    _MsgBoxFont  = fonts["veramono20"]
+    _IconFont    = fonts["varela15"]
+    
+    def __init__(self):
+        self._Pages = []
+        self._MyPageStack = PageStack()
+
+    def Init(self):
+        self._CanvasHWND = pygame.Surface((self._Width,self._Height))
+        self._MsgBox= MessageBox()
+        self._MsgBox._Parent= self
+        self._MsgBox.SetCanvasHWND(self._CanvasHWND)
+        self._MsgBox.Init(" ", self._MsgBoxFont)
+        
+    def FartherPages(self):
+        self._PageMax = len(self._Pages)
+        for i in range(0,self._PageMax):
+            self._Pages[i]._Index = i
+            self._Pages[i]._CanvasHWND = self._CanvasHWND
+            self._Pages[i]._IconNumbers = len(self._Pages[i]._Icons)
+            self._Pages[i]._Screen = self
+            self._Pages[i].Adjust()
+            
+            if self._Pages[i]._IconNumbers > 1:
+                self._Pages[i]._PsIndex = 1
+                self._Pages[i]._IconIndex = self._Pages[i]._PsIndex
+            
+                
+        self._CurrentPage = self._Pages[self._PageIndex]
+        self._CurrentPage._OnShow = True
+
+    def GetMyRightSidePage(self):
+        ret = self._PageIndex +1
+        if ret > (self._PageMax -1):
+            ret = self._PageMax -1
+        return ret
+    
+    def PageMoveLeft(self):
+        self._Pages[self._PageIndex]._OnShow = False
+        if self._PageIndex < (self._PageMax - 1):
+            my_right_side_page  = self.GetMyRightSidePage()
+            for i in range(0,self._PageMax):
+                if i!= self._PageIndex and i != my_right_side_page:
+                    self._Pages[i].MoveLeft(Width)
+
+            self._Pages[self._PageIndex].EasingLeft(Width)
+
+            if self._PageIndex != my_right_side_page:
+                self._Pages[my_right_side_page].EasingLeft(Width)
+
+            self._Pages[self._PageIndex].ResetPageSelector()
+            
+        self._PageIndex+=1
+        if self._PageIndex > (self._PageMax -1):
+            self._PageIndex = (self._PageMax -1)
+
+        self._Pages[self._PageIndex]._OnShow = True
+        self._CurrentPage = self._Pages[self._PageIndex]
+
+    def GetMyLeftSidePage(self):
+        ret = self._PageIndex -1
+        if ret < 0:
+            ret = 0
+        return ret
+
+    def PageMoveRight(self):
+        self._Pages[self._PageIndex]._OnShow = False
+        if self._PageIndex > 0:
+            my_left_side_page = self.GetMyLeftSidePage()
+            for i in range(0,self._PageMax):
+                if i!= self._PageIndex and i!= my_left_side_page:
+                    pass
+                #self._Pages[i].MoveRight(Width)
+
+            self._Pages[self._PageIndex].EasingRight(Width)
+
+            if self._PageIndex != my_left_side_page:
+                self._Pages[my_left_side_page].EasingRight(Width)
+
+            self._Pages[self._PageIndex].ResetPageSelector()
+
+        self._PageIndex-=1
+        if self._PageIndex < 0:
+            self._PageIndex = 0
+
+        self._Pages[self._PageIndex]._OnShow = True
+        self._CurrentPage = self._Pages[self._PageIndex]
+
+
+    def EasingAllPageLeft(self):
+        current_time = 0.0
+        start_posx = 0.0
+        current_posx = start_posx
+        final_posx   = float(Width)
+        posx_init    = 0
+        dur          = 30
+        last_posx    = 0.0
+        all_last_posx = []
+        if self._PageIndex >= (self._PageMax - 1):
+            return
+        for i in range(0,Width*dur):
+            current_posx = easing.SineIn(current_time,start_posx,final_posx-start_posx,float(dur))
+            if current_posx >= final_posx:
+                current_posx = final_posx
+
+            dx  = current_posx - last_posx
+            all_last_posx.append(int(dx))
+            current_time+=1
+            last_posx = current_posx
+            if current_posx >= final_posx:
+                break
+
+        c = 0
+        for i in all_last_posx:
+            c+=i
+        if c < final_posx - start_posx:
+            all_last_posx.append( final_posx - c )
+
+        for i in all_last_posx:
+            self.ClearCanvas()
+            for j in self._Pages:
+                j._PosX -= i
+                j.DrawIcons()
+                j._Screen.SwapAndShow()
+                
+        
+        self._Pages[self._PageIndex]._OnShow = False
+
+        self._PageIndex+=1
+        if self._PageIndex > (self._PageMax -1):
+            self._PageIndex = (self._PageMax -1)
+
+        self._Pages[self._PageIndex]._OnShow = True
+        self._CurrentPage = self._Pages[self._PageIndex]
+        
+    def EasingAllPageRight(self):
+        current_time = 0.0
+        start_posx = 0.0
+        current_posx = start_posx
+        final_posx   = float(Width)
+        posx_init    = 0
+        dur          = 30
+        last_posx    = 0.0
+        all_last_posx = []
+        if self._PageIndex <= 0:
+            return
+        for i in range(0,Width*dur):
+            current_posx = easing.SineIn(current_time,start_posx,final_posx-start_posx,float(dur))
+            if current_posx >= final_posx:
+                current_posx = final_posx
+
+            dx  = current_posx - last_posx
+            all_last_posx.append(int(dx))
+            current_time+=1
+            last_posx = current_posx
+            if current_posx >= final_posx:
+                break
+
+        c = 0
+        for i in all_last_posx:
+            c+=i
+        if c < final_posx - start_posx:
+            all_last_posx.append( final_posx - c )
+
+        for i in all_last_posx:
+            self.ClearCanvas()
+            for j in reversed(self._Pages):
+                j._PosX += i
+                j.DrawIcons()
+                j._Screen.SwapAndShow()
+                
+        
+        self._Pages[self._PageIndex]._OnShow = False
+        
+        self._PageIndex-=1
+        if self._PageIndex < 0:
+            self._PageIndex = 0
+
+        self._Pages[self._PageIndex]._OnShow = True
+        self._CurrentPage = self._Pages[self._PageIndex]
+
+    def CurPage(self):
+        return self._CurrentPage
+    
+    def PushCurPage(self):
+        self._MyPageStack.Push(self._CurrentPage)
+        
+    def SetCurPage(self,page):
+        self._CurrentPage = page
+        on_load_cb = getattr(self._CurrentPage,"OnLoadCb",None)
+        if on_load_cb != None:
+            if callable( on_load_cb ):
+                self._CurrentPage.OnLoadCb()
+
+    def PushPage(self,page):
+        self.PushCurPage()
+        self.SetCurPage(page)
+        
+    def AppendPage(self,Page):
+        self._Pages.append(Page)
+
+    def ClearCanvas(self):
+        self._CanvasHWND.fill((255,255,255))
+        
+    def SwapAndShow(self):
+        if self._HWND != None:
+            self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width,self._Height))
+            pygame.display.update()
+            
+    def ExtraName(self,name):
+        ## extra name like 1_xxx to be => xxx, 
+        parts = name.split("_")
+        if len(parts) > 1:
+            return parts[1]
+        elif len(parts) == 1:
+            return parts[0]
+        else:
+            return name
+
+    def IsEmulatorPackage(self,dirname):
+        files = os.listdir(dirname)
+        for i in sorted(files):
+            if i.endswith(emulator_flag):
+                return True
+        return False
+    
+    def IsPythonPackage(self,dirname):
+        files = os.listdir(dirname)
+        for i in sorted(files):
+            if i.endswith(python_package_flag):
+                return True
+        return False
+
+    def ReadTheDirIntoPages(self,_dir,pglevel,cur_page):
+
+        if FileExists(_dir) == False and os.path.isdir(_dir) == False:
+            return
+        
+        files = os.listdir(_dir)
+        for i in sorted(files):
+            if os.path.isdir(_dir+"/"+i): # TOPLEVEL only is dir
+                if pglevel == 0:
+                    page = Page()
+                    page._Name = self.ExtraName(i)
+                    page._Icons = []
+                    self._Pages.append(page)
+                    self.ReadTheDirIntoPages(_dir+"/"+i, pglevel+1 ,self._Pages[ len(self._Pages) -1])
+                else: ## On CurPage now
+                    i2 = self.ExtraName(i)
+                    iconitem = IconItem()
+                    iconitem._CmdPath = ""
+                    iconitem.AddLabel(i2,self._IconFont)
+                    if FileExists(_dir+"/"+i2+".png"):
+                        iconitem._ImageName = _dir+"/"+i2+".png"
+                    else:
+                        untitled = UntitledIcon()
+                        untitled.Init()
+                        if len(i2) > 1:
+                            untitled.SetWords(i2[:2])
+                        elif len(i2) == 1:
+                            untitled.SetWords([i2[0],i2[0]])
+                        else:
+                            untitled.SetWords(["G","s"])
+                    
+                        iconitem._ImgSurf = untitled.Surface()
+                        iconitem._ImageName = ""
+                        
+                    if self.IsPythonPackage(_dir+"/"+i):
+                        iconitem._MyType  = ICON_TYPES["FUNC"]
+                        sys.path.append(_dir)
+                        iconitem._CmdPath = __import__(i)
+                        init_cb  = getattr(iconitem._CmdPath,"Init",None)
+                        if init_cb != None:
+                            if callable(init_cb):
+                                iconitem._CmdPath.Init(self)
+                                cur_page._Icons.append(iconitem)
+
+                    elif self.IsEmulatorPackage(_dir+"/"+i):
+                        obj = {}
+                        obj["ROM"] = ""
+                        obj["ROM_SO"] =""
+                        obj["EXT"]    = []
+                        obj["LAUNCHER"] = ""
+                        obj["TITLE"]    = "Game"
+                        obj["SO_URL"]   = ""
+                        
+                        try:
+                            f = open(_dir+"/"+i+"/"+emulator_flag)
+                        except IOError:
+                            print("action config open failed")
+                            return
+                        else:
+                            with f:
+                                content = f.readlines()
+                                content = [x.strip() for x in content] 
+                        for i in content:
+                            pis = i.split("=")
+                            if len(pis) > 1:
+                                if "EXT" in pis[0]:
+                                    obj[pis[0]] = pis[1].split(",")
+                                else:
+                                    obj[pis[0]] = pis[1]
+                        
+                        em = MyEmulator()
+                        em._Emulator = obj
+                        
+                        em.Init(self)
+                        iconitem._CmdPath = em
+                        iconitem._MyType  = ICON_TYPES["Emulator"]
+                        cur_page._Icons.append(iconitem)
+                        
+                    else:                            
+                        iconitem._MyType  = ICON_TYPES["DIR"]
+                        iconitem._LinkPage = Page()
+                        iconitem._LinkPage._Name = i2
+                        cur_page._Icons.append(iconitem)
+                        self.ReadTheDirIntoPages(_dir+"/"+i,pglevel+1,iconitem._LinkPage)
+                        
+            elif os.path.isfile(_dir+"/"+i) and pglevel > 0:
+                if i.lower().endswith(icon_ext):
+                    i2 = self.ExtraName(i)
+                    
+                    #cmd      =  ReadTheFileContent(_dir+"/"+i)
+                    iconitem = IconItem()
+                    iconitem._CmdPath = _dir+"/"+i
+                    MakeExecutable(iconitem._CmdPath)
+                    iconitem._MyType  = ICON_TYPES["EXE"]
+                    if FileExists(_dir+"/"+ReplaceSuffix(i2,"png")):
+                        iconitem._ImageName = _dir+"/"+ReplaceSuffix(i2,"png")
+                    else:
+                        untitled = UntitledIcon()
+                        untitled.Init()
+                        if len(i2) > 1:
+                            untitled.SetWords(i2[:2])
+                        elif len(i2) == 1:
+                            untitled.SetWords([i2[0],i2[0]])                            
+                        else:
+                            untitled.SetWords(["G","s"])
+                        
+                        iconitem._ImgSurf = untitled.Surface()
+                        
+                        iconitem._ImageName = ""
+                        
+                    iconitem.AddLabel(i2.split(".")[0],self._IconFont)
+                    iconitem._LinkPage = None
+                    cur_page._Icons.append(iconitem)
+
+    def RunEXE(self,cmdpath):
+        self.DrawRun()
+        self.SwapAndShow()
+        pygame.time.delay(1000)
+        cmdpath = cmdpath.strip()
+        cmdpath = CmdClean(cmdpath)
+
+        pygame.event.post( pygame.event.Event(RUNEVT, message=cmdpath))
+
+    def OnExitCb(self,event):
+        ## leave rest to Pages
+        on_exit_cb = getattr(self._CurrentPage,"OnExitCb",None)
+        if on_exit_cb != None:
+            if callable( on_exit_cb ):
+                self._CurrentPage.OnExitCb(event)
+        return
+
+    def KeyDown(self,event):
+        """
+        if event.key == pygame.K_PAGEUP:
+            self.EasingAllPageLeft()
+            #self.SwapAndShow()
+        if event.key == pygame.K_PAGEDOWN:
+            self.EasingAllPageRight()
+            #self.SwapAndShow()
+        """
+        if event.key == pygame.K_t:
+            self.DrawRun()
+            self.SwapAndShow()
+        
+        if event.key == CurKeys["Space"]:
+            self.Draw()
+            self.SwapAndShow()
+            
+        ## leave rest to Pages
+        current_page_key_down_cb = getattr(self._CurrentPage,"KeyDown",None)
+        if current_page_key_down_cb != None:
+            if callable( current_page_key_down_cb ):
+                self._CurrentPage.KeyDown(event)
+                
+    
+    def DrawRun(self):
+        self._MsgBox.SetText("Launching....")
+        self._MsgBox.Draw()
+    
+    def Draw(self):
+        self._CurrentPage.Draw()
+        #if self._HWND != None:
+        #    self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width,self._Height))
+        if self._TitleBar != None:
+            self._TitleBar.Draw(self._CurrentPage._Name)
+        if self._FootBar  != None:
+            if hasattr(self._CurrentPage,"_FootMsg"):
+                self._FootBar.SetLabelTexts(self._CurrentPage._FootMsg)
+                self._FootBar.Draw()
+

+ 44 - 0
sys.py/UI/multi_icon_item.py

@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+#from beeprint import pp
+
+## local import
+from constants  import icon_width,icon_height,ICON_TYPES,ALIGN,icon_ext,Width,Height
+from util_funcs import color_surface,midRect
+from label      import Label
+from icon_item  import IconItem
+
+##Resource file contains multi icons in single image
+##usually the Image contains icons in Vertical, convert 1.png 2.png 3.png -append out.png
+
+class MultiIconItem(IconItem):
+    _IconWidth=18
+    _IconHeight=18
+    _IconIndex = 0  # icon index on the resource Image 
+    
+    def CreateImageSurf(self):        
+        if self._ImgSurf == None and self._ImageName != "":
+#            print(self._ImageName)
+            self._ImgSurf = pygame.image.load( self._ImageName ).convert_alpha() 
+            
+
+    def Draw(self):
+        if self._Align==ALIGN["VCenter"]: #default
+            if self._Label != None:
+                self._Label._PosX = self._PosX - self._Label._Width/2 + self._Parent._PosX
+                self._Label._PosY = self._PosY + self._Height/2 +6  + self._Parent._PosY
+                
+        elif self._Align ==ALIGN["HLeft"]:
+            if self._Label != None:
+                self._Label._PosX = self._PosX + self._Width/2 + 3 + self._Parent._PosX
+                self._Label._PosY = self._PosY - self._Label._Height/2 + self._Parent._PosY
+
+        if self._Label!=None:
+            self._Label.Draw()
+        
+        if self._ImgSurf != None:
+            self._Parent._CanvasHWND.blit(self._ImgSurf,midRect(self._PosX+self._Parent._PosX,
+                                                                self._PosY+self._Parent._PosY,
+                                                                self._Width,self._Height,Width,Height),
+                                          (0,self._IconIndex*self._IconHeight,self._IconWidth,self._IconHeight))

+ 86 - 0
sys.py/UI/multilabel.py

@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+
+class MultiLabel: ##Multi Line Label 
+    _PosX=0
+    _PosY=0
+    _Width=135
+    _Height=100
+    _Text=""
+    _FontObj=None
+    _Color = pygame.Color(83,83,83)
+    _CanvasHWND = None
+    _TextSurf = None
+    _MaxWidth = 0
+    
+    def __init__(self):
+        pass
+    
+    def Init(self,text,font_obj,color=pygame.Color(83,83,83)):
+        self._Color = color
+        self._FontObj = font_obj
+        self._Text = text
+        
+        self.blit_text(self._CanvasHWND,self._Text,(self._PosX,self._PosY),self._FontObj)
+        
+    def NewCoord(self,x,y):
+        self._PosX = x
+        self._PosY = y
+
+    def SetColor(self,color):
+        self._Color = color
+    
+    def GetText(self):
+        return self._Text
+    
+    def SetText(self,text):
+        self._Text = text
+        
+        self.blit_text(text)
+        
+    def Width(self):
+        return self._Width
+    
+    def SetCanvasHWND(self,_canvashwnd):
+        self._CanvasHWND = _canvashwnd
+
+    def blit_text(self, surface,text, pos, font):
+        color = self._Color
+        words = [word.split(' ') for word in text.splitlines()]
+        space = font.size(' ')[0]
+        max_width = self._Width
+        x ,y = pos
+        row_total_width = 0
+        lines = 0 
+        for i,line in enumerate(words[:4]):
+            for word in line[:12]:
+                #print(word)
+                word_surface = font.render(word, True, color)
+                word_width = word_surface.get_width()
+                word_height = word_surface.get_height()
+                row_total_width += word_width
+                if row_total_width+space  >= max_width:
+                    x = pos[0]  # Reset the x.
+                    y += word_height  # Start on new row.
+                    row_total_width = 0
+                    
+                    if lines == 0:
+                        lines += word_height
+                    else:
+                        lines += word_height
+                    
+                surface.blit(word_surface, (x, y))
+                x += word_width + space
+            x = pos[0]  # Reset the x.
+            y += word_height  # Start on new row.
+            lines += word_height        
+        self._Height = lines
+
+    
+    def Draw(self):
+        #my_text = self._FontObj.render( self._Text,True,self._Color)
+        self.blit_text(self._CanvasHWND,self._Text,(self._PosX,self._PosY),self._FontObj)
+        #pygame.draw.rect(self._CanvasHWND,(83,83,83), (self._PosX,self._PosY,self._Width,self._Height) , 1 )
+        #self._CanvasHWND.blit(my_text,(self._PosX,self._PosY,self._Width,self._Height))

+ 606 - 0
sys.py/UI/page.py

@@ -0,0 +1,606 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+import math
+
+from libs import easing
+
+import base64
+from beeprint import pp
+
+### local import
+from constants    import ALIGN,icon_width,icon_height,Width,Height,ICON_TYPES
+from util_funcs   import midRect
+from keys_def     import CurKeys
+
+from blueselector_b64 import blueselector
+
+
+blueselector_surf = pygame.image.frombuffer(base64.b64decode(blueselector),(92,92),"RGBA")
+
+class PageStack:
+    def __init__(self):
+        self.stack = list()
+
+    def Push(self,data):
+        if data not in self.stack:
+            self.stack.append(data)
+            return True
+        return False
+
+    def Pop(self):
+        if len(self.stack)<=0:
+            return None,False
+        return self.stack.pop(),True
+    
+    def Length(self):
+        return len(self.stack)
+
+class PageSelector:
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 0
+    _Parent = None
+    _Alpha  = 0
+    _OnShow = True
+    _IconSurf = None 
+    def __init__(self):
+        pass
+
+    def Init(self,x,y,w,h,alpha):
+        self._PosX   = x
+        self._PosY   = y
+        self._Width   = w
+        self._Height  = h
+        self._Alpha   = alpha
+
+    def Adjust(self,x,y,w,h,alpha):
+        self._PosX   = x
+        self._PosY   = y
+        self._Width   = w
+        self._Height  = h
+        self._Alpha   = alpha
+
+    def Draw(self):
+        canvas  = self._Parent._CanvasHWND
+        idx     = self._Parent._PsIndex
+        iconidx = self._Parent._IconIndex
+
+        if idx < len(self._Parent._Icons):
+            x       = self._Parent._Icons[idx]._PosX+self._Parent._PosX
+            y       = self._Parent._Icons[iconidx]._PosY ## only use current icon's PosY
+        
+            rect    = midRect(x,y,self._Width,self._Height,self._Parent._Width,self._Parent._Height)
+            if rect.width <=0 or rect.height <= 0 :
+                return
+
+            #color = (244,197,66,50)
+            #pygame.draw.rect(canvas,color,rect,1)
+            if self._IconSurf != None:
+                self._Parent._CanvasHWND.blit(self._IconSurf,rect)
+            
+class Page(object):
+    _PosX=0
+    _PosY=0
+    _Width=0
+    _Height=0
+    _Icons = []
+    _Ps = None
+    _PsIndex = 0
+    _IconNumbers = 0
+    _IconIndex   = 0 ## shows which icon current selected, the Selector can not move here
+    _PrevIconIndex = 0 ## for remember the  Highlighted Icon ,restore it's PosY to average
+    _Index = 0
+    _Align = ALIGN["SLeft"]
+    _CanvasHWND = None # 
+    _HWND       = None # 
+    _OnShow     = False
+    _Name       = ""
+    _Screen     = None ## Should be the Screen Class
+    _PageIconMargin = 20
+    _FootMsg    = ["Nav.","","","","Enter"] ## Default Page Foot info
+
+    _SelectedIconTopOffset=20
+    _EasingDur   = 30
+    def __init__(self):
+        self._Icons = []
+
+
+    def AdjustHLeftAlign(self): ## adjust coordinator and append the PageSelector
+        self._PosX = self._Index*self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        cols = int(Width /icon_width)
+        rows = int( (self._IconNumbers * icon_width)/Width + 1)
+        if rows < 1:
+            rows = 1
+            cnt = 0
+        for i in range(0,rows):
+            for j in range(0,cols):
+                start_x = icon_width/2  + j*icon_width
+                start_y = icon_height/2 + i*icon_height
+                icon = self._Icons[cnt]
+                icon.Adjust(start_x,start_y,icon_width-4,icon_height-4,0)
+                icon._Index = cnt
+                icon._Parent = self
+                if cnt >= (self._IconNumbers -1):
+                    break
+                cnt+=1
+                #icon的实际surface是要另行赋值的,这儿只创建空的icon,输入了坐标等信息
+        ps = PageSelector()
+        ps._IconSurf = blueselector_surf
+        ps._Parent = self
+        ps.Init(icon_width/2, TitleBar._BarHeight+icon_height/2,92,92,128)
+        self._Ps = ps
+        self._PsIndex = 0
+        self._OnShow = False
+
+
+    def AdjustSLeftAlign(self): ## adjust coordinator and append the PageSelector
+        self._PosX = self._Index*self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        start_x = (self._PageIconMargin + icon_width+self._PageIconMargin) /2
+        start_y = self._Height/2
+        
+        for i in range(0,self._IconNumbers):
+            it = self._Icons[i]
+            it._Parent = self
+            it._Index = i
+            it.Adjust(start_x+i*self._PageIconMargin+i*icon_width,start_y,icon_width-6,icon_height-6,0)
+            it._ImgSurf = pygame.transform.smoothscale(it._ImgSurf,(it._Width,it._Height))
+
+        ps = PageSelector()
+        ps._IconSurf = blueselector_surf
+        ps._Parent = self
+        ps.Init(start_x,start_y,92,92,128)
+        
+        self._Ps = ps
+        self._PsIndex = 0
+        self._OnShow = False
+        
+        if self._IconNumbers > 1:
+            self._PsIndex = 1
+            self._IconIndex = self._PsIndex
+            self._PrevIconIndex = self._IconIndex
+            self._Icons[self._IconIndex]._PosY -= self._SelectedIconTopOffset
+
+    def AdjustSAutoLeftAlign(self): ## adjust coordinator and append the PageSelector
+        self._PosX = self._Index*self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        start_x = (self._PageIconMargin + icon_width+self._PageIconMargin) /2
+        start_y = self._Height/2
+
+        if self._IconNumbers == 1:
+            start_x = self._Width / 2
+            start_y = self._Height/2
+            
+            it = self._Icons[0]
+            it._Parent = self
+            it._Index = 0
+            it.Adjust(start_x,start_y,icon_width-6,icon_height-6,0)
+            it._ImgSurf = pygame.transform.smoothscale(it._ImgSurf,(it._Width,it._Height))
+
+        elif self._IconNumbers == 2:
+            start_x = (self._Width - self._PageIconMargin - self._IconNumbers*icon_width) / 2 + icon_width/2
+            start_y = self._Height /2
+
+            for i in range(0,self._IconNumbers):
+                it = self._Icons[i]
+                it._Parent = self
+                it._Index = i
+                it.Adjust(start_x+i*self._PageIconMargin + i*icon_width,start_y, icon_width-6, icon_height-6,0)
+                it._ImgSurf = pygame.transform.smoothscale(it._ImgSurf,(it._Width,it._Height))
+                
+        elif self._IconNumbers > 2:
+            for i in range(0,self._IconNumbers):
+                it = self._Icons[i]
+                it._Parent = self
+                it._Index = i
+                it.Adjust(start_x+i*self._PageIconMargin + i*icon_width,start_y,icon_width-6,icon_height-6,0)
+                
+                it._ImgSurf = pygame.transform.smoothscale(it._ImgSurf,(it._Width,it._Height))
+
+        ps = PageSelector()
+        ps._IconSurf = blueselector_surf
+        ps._Parent = self
+        ps.Init(start_x,start_y,92,92,128)
+        
+        self._Ps = ps
+        self._PsIndex = 0
+        self._OnShow = False
+
+        if self._IconNumbers > 1:
+            self._PsIndex = 1
+            self._IconIndex = self._PsIndex
+            self._PrevIconIndex = self._IconIndex
+            self._Icons[self._IconIndex]._PosY -= self._SelectedIconTopOffset
+
+    def InitLeftAlign(self):
+        self._PosX = self._Index*Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        cols = int(self._Width /icon_width)
+        rows = int((self._IconNumbers * icon_width)/self._Width + 1)
+        if rows < 1:
+            rows = 1
+            cnt = 0
+        for i in range(0,rows):
+            for j in range(0,cols):
+                start_x = icon_width/2  + j*icon_width
+                start_y = TitleBar._BarHeight + icon_height/2 + i*icon_height
+                icon = IconItem()
+                icon.Init(start_x,start_y,icon_width-4,icon_height-4,0)
+                icon._Index = cnt
+                icon._Parent = self
+                self._Icons.append(icon)
+                if cnt >= (self._IconNumbers -1):
+                    break
+                cnt+=1
+                #icon的实际surface是要另行赋值的,这儿只创建空的icon,输入了坐标等信息
+        ps = PageSelector()
+        ps._IconSurf = blueselector_surf        
+        ps._Parent = self
+        ps.Init(icon_width/2,icon_height/2,92,92,128)
+        self._Ps = ps
+        self._PsIndex = 0
+        self._OnShow = False
+
+    def Adjust(self): ## default init way, 
+        self._PosX = self._Index*self._Screen._Width 
+        self._Width = self._Screen._Width ## equal to screen width
+        self._Height = self._Screen._Height
+
+        if self._Align == ALIGN["HLeft"]:
+            start_x = (self._Width - self._IconNumbers*icon_width)/2 + icon_width/2
+            start_y = self._Height/2
+
+            for i in range(0,self._IconNumbers):
+                it = self._Icons[i]
+                it._Parent = self
+                it._Index = i
+                it.Adjust(start_x+i*icon_width,start_y,icon_width,icon_height,0)
+                ps = PageSelector()
+                ps._IconSurf = blueselector_surf
+
+            ps._Parent = self
+            ps.Init(start_x,start_y,92,92,128)
+            self._Ps = ps
+            self._PsIndex = 0
+            self._OnShow = False
+        elif self._Align == ALIGN["SLeft"]:
+            start_x = (self._PageIconMargin + icon_width+self._PageIconMargin) /2
+            start_y = self._Height/2
+            
+            for i in range(0,self._IconNumbers):
+                it = self._Icons[i]
+                it._Parent = self
+                it._Index = i
+                it.Adjust(start_x+i*self._PageIconMargin+i*icon_width,start_y,icon_width,icon_height,0)
+                
+
+       
+            ps = PageSelector()
+            ps._IconSurf = blueselector_surf
+            ps._Parent = self
+            ps.Init(start_x,start_y-self._SelectedIconTopOffset,92,92,128)
+            
+            self._Ps = ps
+            self._PsIndex = 0
+            self._OnShow = False
+            
+            if self._IconNumbers > 1:
+                self._PsIndex = 1
+                self._IconIndex = self._PsIndex
+                self._PrevIconIndex = self._IconIndex
+                self._Icons[self._IconIndex]._PosY -= self._SelectedIconTopOffset
+                
+                
+    def Init(self): ## default init way, 
+        if self._Screen != None:
+            if self._Screen._CanvasHWND != None and self._CanvasHWND == None:
+                self._CanvasHWND = self._Screen._CanvasHWND
+
+        self._PosX = self._Index*self._Screen._Width 
+        self._Width = self._Screen._Width ## equal to screen width
+        self._Height = self._Screen._Height
+
+        start_x = (self._Width - self._IconNumbers*icon_width)/2 + icon_width/2
+        start_y = self._Height/2
+
+        for i in range(0,self._IconNumbers):
+            it = IconItem()
+            it._Parent = self
+            it._Index = i
+            it.Init(start_x+i*icon_width,start_y,icon_width,icon_height,0)
+            self._Icons.append(it)
+            #icon的实际surface是要另行赋值的,这儿只创建空的icon,输入了坐标等信息
+        if self._IconNumbers > 0:
+            ps = PageSelector()
+            ps._IconSurf = blueselector_surf        
+            ps._Parent = self
+            ps.Init(start_x,start_y,icon_width+4,icon_height+4,128)
+            self._Ps = ps
+            self._PsIndex = 0
+            self._OnShow = False
+            
+    def IconStepMoveData(self,icon_eh,cuts):## no Sine,No curve,plain movement steps data
+        all_pieces = []
+        piece = icon_eh / cuts
+
+        c = 0.0
+        prev = 0.0
+        for i in range(0,cuts):
+            c+=piece
+            dx = c-prev
+            if dx < 0.5:
+                dx = 1.0
+                
+            all_pieces.append( math.ceil(dx) )
+            if c >= icon_eh:
+                break
+
+        c = 0
+        bidx = 0
+        for i in all_pieces:
+            c+=i
+            bidx+=1
+            if c >= icon_eh:
+                break
+
+        all_pieces = all_pieces[0:bidx]
+
+        if len(all_pieces) < cuts:
+            dff = cuts - len(all_pieces)
+            diffa = []
+            for i in range(0,dff):
+                diffa.append(0)
+                all_pieces.extend( diffa)
+                
+        return all_pieces
+
+    def EasingData(self,start,distance):##generate easing steps data
+        current_time  = 0.0
+        start_posx    = 0.0
+        current_posx  = start_posx
+        final_posx    = float(distance)
+        posx_init     = start
+        dur           = self._EasingDur
+        last_posx     = 0.0
+        all_last_posx = []
+        for i in range(0,distance*dur):
+            current_posx = easing.SineIn(current_time,start_posx,final_posx-start_posx,float(dur))
+            if current_posx >= final_posx:
+                current_posx = final_posx
+
+            dx = current_posx - last_posx
+            all_last_posx.append(int(dx))
+            current_time+=1
+            last_posx = current_posx
+            if current_posx >= final_posx:
+                break
+            c = 0
+        for i in all_last_posx:
+            c+=i
+        if c < final_posx -start_posx:
+            all_last_posx.append(final_posx - c)
+
+        return all_last_posx
+
+    def IconSmoothUp(self,icon_ew):
+        data = self.EasingData(self._PosX,icon_ew)
+        data2 = self.IconStepMoveData(self._SelectedIconTopOffset,len(data))
+        
+        for i,v in enumerate(data):
+            
+            self.ClearCanvas()
+            
+            self._Icons[self._IconIndex]._PosY -= data2[i]
+            
+            if self._Icons[self._PrevIconIndex]._PosY < self._Height/2:
+                self._Icons[self._PrevIconIndex]._PosY+=data2[i]
+                self.DrawIcons()
+                self._Screen.SwapAndShow()        
+                
+    def IconsEasingLeft(self,icon_ew):
+
+        data = self.EasingData(self._PosX,icon_ew)
+        data2 = self.IconStepMoveData(self._SelectedIconTopOffset,len(data))
+        
+        for i,v in enumerate(data):
+            
+            self.ClearCanvas()
+            self._PosX -= v
+            
+            self._Icons[self._IconIndex]._PosY -= data2[i]
+            
+            if self._Icons[self._PrevIconIndex]._PosY < self._Height/2:
+                self._Icons[self._PrevIconIndex]._PosY+=data2[i]
+            self.DrawIcons()
+            self._Screen.SwapAndShow()
+                
+    def IconsEasingRight(self,icon_ew):
+        
+        data = self.EasingData(self._PosX,icon_ew)
+        data2 = self.IconStepMoveData(self._SelectedIconTopOffset,len(data))
+        
+        for i,v in enumerate(data):
+            self.ClearCanvas()
+            self._PosX += v
+
+            
+            self._Icons[self._IconIndex]._PosY-=data2[i]
+            
+            if self._Icons[self._PrevIconIndex]._PosY < self._Height/2:
+                self._Icons[self._PrevIconIndex]._PosY+=data2[i]
+                
+            self.DrawIcons()
+            self._Screen.SwapAndShow()
+            
+    def EasingLeft(self,ew): #ew int
+
+        data = self.EasingData(self._PosX,ew)
+        
+        for i in data:
+            self._PosX -=i
+            self.Draw()
+            self._Screen.SwapAndShow()
+            
+    def EasingRight(self,ew):
+
+        data = self.EasingData(self._PosX,ew)
+        
+        for i in data:
+            self._PosX += i
+            self.Draw()
+            self._Screen.SwapAndShow()
+            
+    def MoveLeft(self,ew):
+        self._PosX -= ew
+    def MoveRight(self,ew):
+        self._PosX += ew
+        
+    def ResetPageSelector(self):
+        self._PsIndex = 0
+        self._IconIndex = 0
+        self._Ps._OnShow = True
+
+    def DrawPageSelector(self):
+        if self._Ps._OnShow == True:
+            self._Ps.Draw()
+            
+    def MoveIconIndexPrev(self):
+        
+        self._IconIndex-=1
+        if self._IconIndex < 0:
+            self._IconIndex = 0
+            self._PrevIconIndex = self._IconIndex
+            return False
+        self._PrevIconIndex = self._IconIndex+1
+        return True
+    
+    def MoveIconIndexNext(self):
+        #True for Moved,False is boundary
+        self._IconIndex+=1
+        if self._IconIndex > (self._IconNumbers - 1):
+            self._IconIndex = self._IconNumbers -1
+            self._PrevIconIndex = self._IconIndex
+            return False
+        self._PrevIconIndex = self._IconIndex-1
+        return True
+
+    
+    def IconClick(self):
+        
+        if self._IconIndex > (len(self._Icons) -1):
+            return
+
+        cur_icon = self._Icons[self._IconIndex]
+        if self._Ps._OnShow == False:
+            return
+        if cur_icon._MyType == ICON_TYPES["EXE"]:
+            print("IconClick: %s %d"%(cur_icon._CmdPath,cur_icon._Index))
+            self._Screen.RunEXE(cur_icon._CmdPath)
+            
+        elif cur_icon._MyType == ICON_TYPES["DIR"]:
+            child_page = self._Icons[self._IconIndex]._LinkPage
+            if child_page != None:
+                child_page.Draw()
+                self._Screen._MyPageStack.Push(self._Screen._CurrentPage)
+                self._Screen._CurrentPage = child_page
+        elif cur_icon._MyType == ICON_TYPES["FUNC"]:
+            print("IconClick API: %d"%(cur_icon._Index))
+            print("%s"% cur_icon._CmdPath)
+            api_cb = getattr(cur_icon._CmdPath,"API",None)
+            if api_cb != None:
+                if callable(api_cb):
+                    cur_icon._CmdPath.API(self._Screen)
+        elif cur_icon._MyType == ICON_TYPES["Emulator"]:
+            cur_icon._CmdPath.API(self._Screen)
+            
+    def ReturnToUpLevelPage(self):
+        pop_page,ok = self._Screen._MyPageStack.Pop()
+        if ok == True:
+            #self._Screen._CurrentPage.ResetPageSelector()
+            pop_page.Draw()
+            self._Screen._CurrentPage = pop_page
+            on_return_back_cb = getattr(self._Screen._CurrentPage,"OnReturnBackCb",None)
+            if on_return_back_cb != None:
+                if callable(on_return_back_cb):
+                    self._Screen._CurrentPage.OnReturnBackCb()
+        else:
+            if self._Screen._MyPageStack.Length() == 0:
+                if len(self._Screen._Pages) > 0:
+                    self._Screen._CurrentPage = self._Screen._Pages[self._Screen._PageIndex]
+                    self._Screen._CurrentPage.Draw()
+                    print("OnTopLevel ",self._Screen._PageIndex)
+
+    def ClearCanvas(self):
+        self._CanvasHWND.fill((255,255,255)) 
+
+    def ClearIcons(self):
+        for i in range(0,self._IconNumbers):
+            self._Icons[i].Clear()
+
+    def DrawIcons(self):
+        for i in range(0,self._IconNumbers):
+            self._Icons[i].Draw()
+            
+
+    def KeyDown(self,event):##default keydown,every inherited page class should have it's own KeyDown
+        if event.key == CurKeys["A"]:
+            if self._FootMsg[3] == "Back":
+                self.ReturnToUpLevelPage()
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                return
+    
+        if event.key == CurKeys["Menu"]:
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+        if event.key == CurKeys["Right"]:
+            if self.MoveIconIndexNext() == True:
+                if self._IconIndex == (self._IconNumbers -1) or self._PrevIconIndex == 0:
+                    self.IconSmoothUp(icon_width+ self._PageIconMargin) # only move up selected icon,no horizontal translation
+                else:
+                    self.IconsEasingLeft(icon_width + self._PageIconMargin)
+
+                self._PsIndex  = self._IconIndex
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                
+            
+        if event.key == CurKeys["Left"]:
+            if self.MoveIconIndexPrev() == True:
+                if self._IconIndex == 0 or self._PrevIconIndex == (self._IconNumbers -1):
+                    self.IconSmoothUp(icon_width+ self._PageIconMargin)
+                else:
+                    self.IconsEasingRight(icon_width + self._PageIconMargin)
+
+                self._PsIndex = self._IconIndex
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                
+        if event.key == CurKeys["Enter"]:
+            self.IconClick()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+    def Draw(self):
+        self.ClearCanvas()
+        self.DrawIcons()
+        self.DrawPageSelector()
+
+

+ 61 - 0
sys.py/UI/scroller.py

@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*- 
+import pygame
+
+from util_funcs  import midRect
+
+from libs.roundrects import aa_round_rect
+
+class ListScroller(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 7
+    _Height = 0
+    _MinHeight = 6 ## tested 
+    _Parent    = None
+    _Color     = pygame.Color(131,199,219)
+    
+    _StartX   = 0
+    _StartY   = 0
+    _EndX     = 0
+    _EndY     = 0
+    _Value    = 0
+    _CanvasHWND = None
+    
+    def __init__(self):
+        pass
+
+    def Init(self):
+        self.SetCanvasHWND(self._Parent._CanvasHWND)
+
+    def SetCanvasHWND(self,canvas):
+        self._CanvasHWND = canvas
+        
+    def AnimateDraw(self,x2,y2):
+        pass
+
+    def UpdateSize(self,bigheight,dirtyheight):
+        bodyheight =  float(self._Parent._Height) / float(bigheight)
+        if bodyheight > 1:
+            bodyheight = 1 ## 100%
+
+        margin = 4
+        self._Height  = bodyheight * self._Parent._Height - margin ## Draw body
+        
+        if self._Height < self._MinHeight:
+            self._Height = self._MinHeight
+        
+        self._StartX = self._Width/2
+        self._StartY = margin/2+self._Height/2
+
+        self._EndX   = self._Width/2
+        self._EndY   = self._Parent._Height - margin/2 - self._Height/2
+
+        process  = float(dirtyheight) / float(bigheight)
+        value    = process* (self._EndY - self._StartY)
+
+        self._Value = int(value)
+        
+    def Draw(self):
+        
+        start_rect = midRect(self._PosX+self._StartX,self._StartY+self._Value,self._Width,self._Height,self._Parent._Width,self._Parent._Height)
+        aa_round_rect(self._CanvasHWND,start_rect, self._Color,3,0, self._Color)

+ 12 - 0
sys.py/UI/simple_name_space.py

@@ -0,0 +1,12 @@
+
+class SimpleNamespace:
+    def __init__(self, **kwargs):
+        self.__dict__.update(kwargs)
+
+    def __repr__(self):
+        keys = sorted(self.__dict__)
+        items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
+        return "{}({})".format(type(self).__name__, ", ".join(items))
+
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__

+ 40 - 0
sys.py/UI/slider.py

@@ -0,0 +1,40 @@
+
+
+class Slider(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 0
+        
+    _Value = 0
+    _CanvasHWND = None
+    
+    _Range = []
+    
+    def __init__(self):
+        self._Range = [0,255]
+
+    def Init(self):
+        self._Value = 0
+        
+    def SetValue(self,v):
+        self._Value = int(v)
+
+    def SetRange(self,m1,m2):
+        if m1 >= m2:
+            return
+        
+        self._Range[0] = m1
+        self._Range[1] = m2
+
+
+    def SetCanvasHWND(self,cav):
+        self._CanvasHWND = cav
+        
+    def KeyDown(self):
+        pass
+
+    def Draw(self):
+        pass
+
+    

+ 290 - 0
sys.py/UI/title_bar.py

@@ -0,0 +1,290 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import os
+import sys
+
+from datetime import datetime
+
+#from beeprint import pp
+
+import alsaaudio
+
+##local import
+from constants   import ICON_TYPES,Width,Height
+from fonts       import fonts
+from icon_item   import IconItem
+from multi_icon_item import MultiIconItem
+
+from util_funcs  import midRect,SwapAndShow
+
+from config import Battery
+
+from libs.roundrects import aa_round_rect
+
+from libs.DBUS        import is_wifi_connected_now,wifi_strength
+
+icon_base_path = "gameshell/titlebar_icons/"
+class TitleBar:
+    _PosX      = 0
+    _PosY      = 0
+    _Width     = Width
+    _Height    = 25
+    _IconColor = pygame.Color(114,114,144)
+    _BarHeight  = 24.5
+    _LOffset    = 3
+    _ROffset    = 3
+    _BgColor    = pygame.Color(228,228,228)
+    _TxtColor   = pygame.Color(83,83,83)
+    _BottomLineColor = pygame.Color(169,169,169)
+    _Icons      = {}
+    _icon_width = 18
+    _icon_height = 18
+    _BorderWidth = 1
+    _CanvasHWND  = None
+    _HWND        = None
+    _Title       = ""
+
+    _InLowBackLight = -1
+    
+    def __init__(self):
+        self._Icons = {}
+
+
+    def GObjectRoundRobin(self):
+        if self._InLowBackLight < 0:
+            self.CheckBatteryStat()
+            self.SyncSoundVolume()
+            self.UpdateWifiStrength()
+            SwapAndShow()
+        else:
+            self._InLowBackLight+=1
+
+            if self._InLowBackLight > 10:
+                self.CheckBatteryStat()
+                self.SyncSoundVolume()
+                self.UpdateWifiStrength()
+                SwapAndShow()
+                self._InLowBackLight = 0
+        
+        return True
+    
+    def UpdateWifiStrength(self):
+        self.Draw(self._Title)
+        
+    def GetWifiStrength(self,stren): ##invoke anytime to change title bar icon status
+        #0-25
+        #25-50
+        #50-75
+        #75-100
+        
+        segs = [[-2,-1], [0,25],[25,50],[50,75],[75,100] ]
+        
+        stren = int(stren)
+        ge    = 0
+
+        if stren == 0:
+            return ge
+
+        for i,v in enumerate(segs):
+            if stren >= v[0] and stren <= v[1]:
+                ge = i
+                break
+        
+        return ge
+
+    def SyncSoundVolume(self):
+        m = alsaaudio.Mixer()
+        vol = m.getvolume()[0]
+
+        snd_segs = [ [0,10],[10,30],[30,70],[70,100] ]
+
+        ge = 0
+        for i,v in enumerate(snd_segs):
+            if vol >= v[0] and vol <= v[1]:
+                ge = i
+                break
+
+        self._Icons["soundvolume"]._IconIndex = ge
+        self._Icons["sound"]       = self._Icons["soundvolume"]
+
+        
+    def SetSoundVolume(self,vol):
+        pass
+    
+    def CheckBatteryStat(self): ## 100ms check interval
+        content = ""
+        bat_uevent = {}
+        bat_segs=[ [0,6],[7,15],[16,20], [21,30],[31,50],[51,60],  [61,80],[81,90],[91,100] ]
+        
+        try:
+            f = open(Battery)
+        except IOError:
+            self._Icons["battery"] = self._Icons["battery_unknown"]
+            print("CheckBatteryStat open failed")
+            return False
+        else:
+            with f:
+                content = f.readlines()
+                content = [x.strip() for x in content]
+                f.close()
+                
+                for i in content:
+                    pis = i.split("=")
+                    if len(pis) > 1:
+                        bat_uevent[pis[0]] = pis[1]
+
+                #        print(bat_uevent["POWER_SUPPLY_CAPACITY"])
+
+                """
+                power_current = int(bat_uevent["POWER_SUPPLY_CURRENT_NOW"])
+                if power_current < 270000:
+                self._Icons["battery"] = self._Icons["battery_unknown"]
+                return False
+                """
+
+                if "POWER_SUPPLY_CAPACITY" in bat_uevent:
+                    cur_cap = int(bat_uevent["POWER_SUPPLY_CAPACITY"])
+                else:
+                    cur_cap = 0
+                    
+                cap_ge = 0
+                
+                for i,v in enumerate(bat_segs):
+                    if cur_cap >= v[0] and cur_cap <= v[1]:
+                        cap_ge = i
+                        break
+        
+                if bat_uevent["POWER_SUPPLY_STATUS"] == "Charging":
+                    self._Icons["battery_charging"]._IconIndex = cap_ge
+                    self._Icons["battery"] = self._Icons["battery_charging"]
+            
+                    print("Charging %d" % cap_ge)
+                else:
+                    self._Icons["battery_discharging"]._IconIndex = cap_ge
+                    self._Icons["battery"] = self._Icons["battery_discharging"]
+                    print("Discharging %d" % cap_ge)
+                    
+                
+        return True
+    
+    def SetBatteryStat(self,bat):
+        pass
+    
+    def Init(self,screen):
+        
+        
+        start_x = 0
+        self._CanvasHWND = pygame.Surface((self._Width,self._Height))
+        self._HWND       = screen
+        
+        icon_snd = IconItem()
+        icon_snd._MyType = ICON_TYPES["STAT"]
+        icon_snd._Parent = self
+        icon_snd._ImageName = icon_base_path+"ic_volume_up_black.png"
+        icon_snd.Adjust(start_x,self._icon_height/2+(self._BarHeight-self._icon_height)/2,self._icon_width,self._icon_height,0)
+        icon_snd.ChangeImgSurfColor(self._IconColor)
+
+
+        icon_wifi_status = MultiIconItem()
+        icon_wifi_status._MyType = ICON_TYPES["STAT"]
+        icon_wifi_status._ImageName = icon_base_path+"wifi.png"
+        icon_wifi_status._Parent = self
+        icon_wifi_status.Adjust(start_x+self._icon_width+5,self._icon_height/2+(self._BarHeight-self._icon_height)/2,self._icon_width,self._icon_height,0)
+        self._Icons["wifistatus"] = icon_wifi_status    
+        
+        battery_charging = MultiIconItem()
+        battery_charging._MyType = ICON_TYPES["STAT"]
+        battery_charging._Parent = self
+        battery_charging._ImageName = icon_base_path+"withcharging.png"
+        battery_charging.Adjust(start_x+self._icon_width+self._icon_width+8,self._icon_height/2+(self._BarHeight-self._icon_height)/2,self._icon_width,self._icon_height,0)
+        
+        self._Icons["battery_charging"] = battery_charging
+
+        battery_discharging = MultiIconItem()
+        battery_discharging._MyType = ICON_TYPES["STAT"]
+        battery_discharging._Parent = self
+        battery_discharging._ImageName = icon_base_path+"without_charging.png"
+        battery_discharging.Adjust(start_x+self._icon_width+self._icon_width+8,self._icon_height/2+(self._BarHeight-self._icon_height)/2,self._icon_width,self._icon_height,0)
+
+        self._Icons["battery_discharging"] = battery_discharging
+
+        battery_unknown   = IconItem()
+        battery_unknown._MyType = ICON_TYPES["STAT"]
+        battery_unknown._Parent = self
+        battery_unknown._ImageName = icon_base_path+"battery_unknown.png"
+        battery_unknown.Adjust(start_x+self._icon_width+self._icon_width+8,self._icon_height/2+(self._BarHeight-self._icon_height)/2,self._icon_width,self._icon_height,0)
+
+        self._Icons["battery_unknown"] = battery_unknown
+                        
+        self.CheckBatteryStat()
+
+        sound_volume   =  MultiIconItem()
+        sound_volume._MyType = ICON_TYPES["STAT"]
+        sound_volume._Parent = self
+        sound_volume._ImageName = icon_base_path+"soundvolume.png"
+        sound_volume.Adjust(start_x+self._icon_width+self._icon_width+8,self._icon_height/2+(self._BarHeight-self._icon_height)/2,self._icon_width,self._icon_height,0)
+
+        self._Icons["soundvolume"] = sound_volume
+
+        self.SyncSoundVolume()
+        
+        if is_wifi_connected_now():
+            print("wifi is connected")
+            print( wifi_strength())
+
+    def ClearCanvas(self):
+        self._CanvasHWND.fill((0,0,0))
+        aa_round_rect(self._CanvasHWND,  
+                      (0,0,self._Width,self._Height),self._BgColor,8,0, self._BgColor)
+
+        pygame.draw.rect(self._CanvasHWND,self._BgColor,(0,self._Height/2,Width,self._BarHeight), 0 )
+        
+    def Draw(self,title):
+        self.ClearCanvas()
+        
+        self._Title = title
+        
+        cur_time =  datetime.now().strftime("%H:%M")
+        time_text_size = fonts["varela12"].size(cur_time)
+        title_text_size = fonts["varela16"].size(title)
+
+        self._CanvasHWND.blit(fonts["varela16"].render(title,True,self._TxtColor),midRect(title_text_size[0]/2+self._LOffset,
+                                                                    title_text_size[1]/2+(self._BarHeight-title_text_size[1])/2,
+                                                                    title_text_size[0],title_text_size[1],Width,Height))
+        self._CanvasHWND.blit(fonts["varela12"].render(cur_time,True,self._TxtColor),midRect(Width-time_text_size[0]/2-self._ROffset,
+                                                                        time_text_size[1]/2+(self._BarHeight-time_text_size[1])/2,
+                                                                        time_text_size[0],time_text_size[1],Width,Height))
+
+        start_x = Width-time_text_size[0]-self._ROffset-self._icon_width*3 # near by the time_text
+        
+        self._Icons["sound"].NewCoord(start_x,                      self._icon_height/2+(self._BarHeight-self._icon_height)/2)
+        
+        #self._Icons["wifi"].NewCoord(start_x+self._icon_width+5,    self._icon_height/2+(self._BarHeight-self._icon_height)/2)
+        
+        self._Icons["battery"].NewCoord(start_x+self._icon_width+self._icon_width+8,self._icon_height/2+(self._BarHeight-self._icon_height)/2)
+
+        
+        if is_wifi_connected_now():
+            ge = self.GetWifiStrength(wifi_strength())
+            if ge > 0:
+                self._Icons["wifistatus"]._IconIndex = ge
+                self._Icons["wifistatus"].NewCoord(start_x+self._icon_width+5,self._icon_height/2+(self._BarHeight-self._icon_height)/2)
+                self._Icons["wifistatus"].Draw()
+            else:
+                self._Icons["wifistatus"]._IconIndex = 0
+                self._Icons["wifistatus"].Draw()
+                print("strength error")
+        else:
+            self._Icons["wifistatus"]._IconIndex = 0
+            self._Icons["wifistatus"].NewCoord(start_x+self._icon_width+5,self._icon_height/2+(self._BarHeight-self._icon_height)/2)
+            self._Icons["wifistatus"].Draw()
+        
+        self._Icons["sound"].Draw()
+        
+        self._Icons["battery"].Draw()
+        
+        pygame.draw.line(self._CanvasHWND,self._BottomLineColor,(0,self._BarHeight),(self._Width,self._BarHeight),self._BorderWidth)
+
+        if self._HWND != None:
+            self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width,self._Height))

+ 63 - 0
sys.py/UI/untitled_icon.py

@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+from datetime import datetime
+
+import base64
+from beeprint import pp
+
+from util_funcs  import midRect
+from fonts       import fonts
+
+BlankPng = "gameshell/blank.png"  ## 80x80
+## use blank circle as bg, Two alpha As Icon Label
+#Upper and Lower
+class UntitledIcon(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 80
+    _Height = 80
+    
+    _Words = ["G","s"]
+    _FontObj= fonts["varela40"]
+    
+    _BG     = None  ## initial surface 
+
+    _Color  = pygame.Color(83,83,83)
+
+    
+    def __init__(self):
+        self._Words = ["G","s"]
+
+    def Init(self):
+        self._BG = pygame.image.load(BlankPng).convert_alpha()
+
+
+    def SetWords(self,TwoWords):
+        if len(TwoWords) == 1:
+            self._Words[0] = TwoWords[0].upper()
+
+        if len(TwoWords) == 2:
+            self._Words[0] = TwoWords[0].upper()
+            self._Words[1] = TwoWords[1].lower()
+
+        self._Text = self._FontObj.render("".join(self._Words),True,self._Color)
+        
+    def Draw(self):
+        if self._BG != None:
+            w_ = self._Text.get_width()
+            h_ = self._Text.get_height()
+            
+            self._BG.blit(self._Text,midRect(self._Width/2,self._Height/2,w_,h_,self._Width,self._Height))
+
+    def Surface(self):
+        self.Draw()
+
+        return self._BG
+
+    

+ 100 - 0
sys.py/UI/util_funcs.py

@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import os
+
+#from libs import easing
+#from datetime import datetime
+
+#import base64
+#from beeprint import pp
+import string
+from Xlib import X,display
+
+def X_center_mouse():
+    d = display.Display()
+    s = d.screen()
+    root = s.root
+    width = s.width_in_pixels
+    height = s.height_in_pixels
+#    print(width,height)
+    root.warp_pointer(width/2,height/2)
+        
+    d.sync()
+
+
+def IsPythonPackage(self,dirname):
+    files = os.listdir(dirname)
+    for i in sorted(files):
+        if i.endswith("__init__.py"):
+            return True
+    return False
+    
+def MakeExecutable(path):
+    mode = os.stat(path).st_mode
+    mode |= (mode & 0o444) >> 2    # copy R bits to X
+    os.chmod(path, mode)
+
+def GetExePath():# get self dir
+    #dir_path = os.path.dirname(os.path.realpath(__file__))
+    dir_path = os.getcwd()
+    return dir_path
+
+def CmdClean(cmdpath):#escape spec chars
+    spchars = "\\`$();|{}&'\"*?<>[]!^~-#\n\r "
+    for i in spchars:
+        cmdpath = string.replace(cmdpath,i,"\\"+i)
+
+    return cmdpath
+
+def ReplaceSuffix(orig_file_str,new_ext):
+    filename,ext = os.path.splitext(orig_file_str)
+    ext = ext.strip()
+    if ext != "":
+        return "%s.%s"%(filename,new_ext)
+
+def FileExists(name): # both file and dir checked
+    return os.path.exists(name)
+
+
+def ReadTheFileContent(filename):
+    data = ""
+    with open(filename, 'r') as myfile:
+        data = myfile.read()
+    return data
+
+def midRect(x,y,width,height,canWidth,canHeight):
+    return pygame.Rect(min(canWidth,x-width/2),min(canHeight,y-height/2),width,height)
+
+#surface color change
+def color_surface(surface, color):
+    red = color.r
+    green = color.g
+    blue = color.b
+    arr = pygame.surfarray.pixels3d(surface)
+    arr[:,:,0] = red
+    arr[:,:,1] = green
+    arr[:,:,2] = blue
+
+
+def DrawText(canvas,text, x,y,width,height,canWidth,canHeight,fontObj):# text for content,fontObj for pygame.font.Font
+    _w = 0
+    _tp = len(text)
+
+    for idx,t in enumerate(fontObj.metrics(text)):
+        _w = _w + t[1] - t[0]
+        if _w > icon_width:
+            _tp = idx
+            break
+    width = _w #recalc the width of text
+    if width > icon_width: ##Label width max is icon width
+        width = icon_width
+
+    if _tp < len(text):##cut the text to fit width
+        text = text[0:_tp]
+
+    canvas.blit(fontObj.render(text,True,(83,83,83)),midRect(x,y,width,height,canWidth,canHeight))
+
+
+def SwapAndShow():
+    pygame.display.update()

+ 16 - 0
sys.py/config.py

@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*- 
+
+CurKeySet = "GameShell" ## >>>    PC or GameShell   <<<
+
+DontLeave = False
+
+BackLight = "/proc/driver/backlight"
+Battery   = "/sys/class/power_supply/axp20x-battery/uevent"
+
+
+MPD_socket = "/tmp/mpd.socket"
+
+UPDATE_URL="http://192.168.31.236:81/version.php"
+
+
+VERSION="1.0"

BIN
sys.py/gameshell/blank.png


BIN
sys.py/gameshell/footbar_icons/footbar.png


BIN
sys.py/gameshell/icons/about_bg.png


BIN
sys.py/gameshell/icons/empty.png


BIN
sys.py/gameshell/icons/heart.png


BIN
sys.py/gameshell/icons/icon_sd.png


BIN
sys.py/gameshell/icons/light.png


BIN
sys.py/gameshell/icons/needwifi_bg.png


BIN
sys.py/gameshell/icons/online.png


BIN
sys.py/gameshell/icons/rom_download.png


BIN
sys.py/gameshell/icons/scale.png


BIN
sys.py/gameshell/icons/star.png


BIN
sys.py/gameshell/icons/sys.png


BIN
sys.py/gameshell/icons/vol.png


BIN
sys.py/gameshell/titlebar_icons/battery_unknown.png


BIN
sys.py/gameshell/titlebar_icons/ic_battery_charging_full_black.png


BIN
sys.py/gameshell/titlebar_icons/ic_volume_up_black.png


BIN
sys.py/gameshell/titlebar_icons/soundvolume.png


BIN
sys.py/gameshell/titlebar_icons/wifi.png


BIN
sys.py/gameshell/titlebar_icons/withcharging.png


BIN
sys.py/gameshell/titlebar_icons/without_charging.png


BIN
sys.py/gameshell/wallpaper/gameover.png


BIN
sys.py/gameshell/wallpaper/loading.png


BIN
sys.py/gameshell/wallpaper/seeyou.png


+ 112 - 0
sys.py/libs/DBUS/__init__.py

@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*- 
+
+import dbus
+import dbus.service
+
+import sys
+from wicd import misc 
+##misc.to_bool
+##misc.misc.noneToString
+##misc.to_unicode
+##misc.Noneify
+from wicd.translations import _
+from wicd import wpath
+from wicd import dbusmanager
+from wicd import misc
+
+import time
+import gobject
+
+if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):
+    import dbus.glib
+else:
+    from dbus.mainloop.glib import DBusGMainLoop
+    DBusGMainLoop(set_as_default=True)
+
+bus = daemon = wireless = wired = None
+
+
+def setup_dbus(force=True):
+    global bus,daemon,wireless,wired
+    try:
+        dbusmanager.connect_to_dbus()
+    except dbus.DBusException:
+        print >> sys.stderr,\
+            _("Can't connect to wicd daemon,trying to start it automatically...")
+    else:
+        bus = dbusmanager.get_bus()
+        dbus_ifaces = dbusmanager.get_dbus_ifaces()
+        daemon      = dbus_ifaces["daemon"] ## @dbus.service.method('org.wicd.daemon')
+        wireless    = dbus_ifaces["wireless"] ## @dbus.service.method('org.wicd.daemon.wireless')
+        wired       = dbus_ifaces["wired"]    ## @
+
+        if not daemon:
+            print("Error connecting to wicd via D-Bus")
+
+    
+    return True
+
+
+def wifi_strength():
+    fast = not daemon.NeedsExternalCalls()
+    if not fast:
+        iwconfig = wireless.GetIwconfig()
+    else:
+        iwconfig = ''
+    
+    if daemon.GetSignalDisplayType() == 0:
+        strength = wireless.GetCurrentSignalStrength(iwconfig)
+    else:
+        strength = wireless.GetCurrentDBMStrength(iwconfig)
+
+    return strength
+
+
+def get_wifi_ip():
+    if wireless == None:
+        return None
+    return wireless.GetWirelessIP('')
+
+def is_wifi_connected_now():
+    if wireless == None:
+        return False
+    
+    wireless_connecting = wireless.CheckIfWirelessConnecting()
+    fast = not daemon.NeedsExternalCalls()        
+    if wireless_connecting:
+        return False
+    else:
+        if not fast:
+            iwconfig = wireless.GetIwconfig()
+        else:
+            iwconfig = ''
+        if check_for_wireless(iwconfig,wireless.GetWirelessIP(''),None):
+            return True
+        else:
+            return False
+
+def check_for_wireless(iwconfig,wireless_ip,set_status):
+    if not wireless_ip:
+        return False
+    network = wireless.GetCurrentNetwork(iwconfig)
+    if not network:
+        return False
+    network = misc.to_unicode(network)
+    if daemon.GetSignalDisplayType() == 0:
+        strength = wireless.GetCurrentSignalStrength(iwconfig)
+    else:
+        strength = wireless.GetCurrentDBMStrength(iwconfig)
+
+    if strength is None:
+        return False
+    
+    strength = misc.to_unicode(daemon.FormatSignalForPrinting(strength))
+    ip = misc.to_unicode(wireless_ip)
+
+    """
+    print(_('dbus Connected to $A at $B (IP: $C)').replace
+          ('$A', network).replace
+          ('$B', strength).replace
+          ('$C', ip))
+    """
+    return True

+ 190 - 0
sys.py/libs/MPD/poller.py

@@ -0,0 +1,190 @@
+# -*- coding: utf-8 -*- 
+#
+
+from mpd import MPDClient, MPDError, CommandError
+import sys
+import os
+
+
+class PollerError(Exception):
+    """Fatal error in poller."""
+
+
+class MPDPoller(object):
+    _host="/tmp/mpd/socket"
+    #_host = "localhost"
+    _port="6600"
+    _client= None
+
+    def __init__(self, host, port="6600"):
+        self._host = host
+        self._port = port
+        self._client = MPDClient(use_unicode=True)
+        self._client.timeout = 60*60*1000
+
+    def connect(self):
+        try:
+            self._client.connect(self._host, self._port)
+        # Catch socket errors
+        except IOError as err:
+            errno, strerror = err
+            raise PollerError("Could not connect to '%s': %s" %
+                              (self._host, strerror))
+
+        # Catch all other possible errors
+        except MPDError as e:
+            raise PollerError("Could not connect to '%s': %s" %
+                              (self._host, e))
+
+
+    def disconnect(self):
+        # Try to tell MPD to close the connection first
+        try:
+            self._client.close()
+
+        # If that fails, ignore it and disconnect
+        except (MPDError, IOError):
+            pass
+
+        try:
+            self._client.disconnect()
+
+        # Disconnecting failed, setup a new client object instead
+        # This should never happen.  If it does, something is seriously broken,
+        # and the client object shouldn't be trusted to be re-used.
+        except (MPDError, IOError):
+            self._client = MPDClient(use_unicode=True)
+            self._client.timeout = 60*60*1000
+    
+    def general(self,func,*args):
+        ret = None
+        try:
+            ret = func( *args )
+        except CommandError:
+            return False
+        except (MPDError, IOError):
+            print("first error")
+            self.disconnect()
+
+            try:
+                self.connect()
+
+            except PollerError as e:
+                raise PollerError("Reconnecting failed: %s" % e)
+
+            try:
+                ret = func(*args)
+            except (MPDError, IOError) as e:
+                raise PollerError("Couldn't retrieve current song: %s" % e)
+        
+        return ret
+    
+    def ping(self):
+        return self.general(self._client.ping)
+         
+    def poll(self):
+        song = self.general( self._client.status )
+        """ 
+        while playing:
+        {u'songid': u'4', u'playlistlength': u'4', u'playlist': u'7', u'repeat': u'0', u'consume': u'0', u'mixrampdb': u'0.000000', u'random': u'0', u'state': u'play', u'elapsed': u'148.758', u'volume': u'100', u'single': u'0', u'time': u'149:436', u'duration': u'435.670', u'song': u'3', u'audio': u'44100:24:2', u'bitrate': u'192'}
+        
+        """
+
+#        print(song)
+        return song
+ 
+    def stop(self):
+        self.general(self._client.stop)
+   
+    def addfile(self,url):
+        self.general(self._client.add, url)
+ 
+    def delete(self,posid):
+        self.general(self._client.delete,posid)
+ 
+    def play(self,posid):
+
+        song = self.poll()
+
+        if "song" in song:
+            if int(song["song"]) != posid:
+                self.general(self._client.play,posid)
+            else:
+                if  "state" in song:
+                    if song["state"] == "play":
+                        self.general(self._client.pause)
+                    elif song["state"] == "pause":
+                        self.general(self._client.pause)
+                    elif song["state"] == "stop":
+                        self.general(self._client.play,posid)
+        else:
+            self.general(self._client.play,posid)
+        
+        self.general(self._client.setvol,100)
+   
+        return posid
+ 
+    def playlist(self):
+        lst  = self.general(self._client.playlistinfo)
+        return lst
+        for i in lst:
+            if "title" in i:
+                print( i["title"] )
+            elif "file"  in i:
+                print( os.path.basename( i["file"] ) )
+    
+    def listfiles(self,path):
+        files = self.general(self._client.lsinfo,path)
+        return files
+        for i in sorted(files):
+            if "directory" in i:
+                print( "D %s" % i["directory"] )
+            elif "file" in i:
+                print(i["file"])
+        
+    def rootfiles(self):
+        files = self.general(self._client.lsinfo, "/")
+        return files
+        for i in sorted(files):
+            if "directory" in i:
+                print( "D %s" % i["directory"] )
+            elif "file" in i:
+                print(i["file"])
+    
+def main():
+    from time import sleep
+
+    poller = MPDPoller()
+    poller.connect()
+
+    while True:
+        print("poll:")
+        print( poller.poll() )
+
+        """
+        print("playlist:")
+        print(poller.playlist())
+        print("rootfiles:")
+        poller.rootfiles()
+        """
+        sleep(120)
+
+
+if __name__ == "__main__":
+    import sys
+
+    try:
+        main()
+
+    except PollerError as e:
+        print("Fatal poller error: %s" % e)
+        sys.exit(1)
+
+    except Exception as e:
+        print("Unexpected exception: %s" % e)
+        sys.exit(1)
+
+    except:
+        sys.exit(0)
+
+

+ 7 - 0
sys.py/libs/easing.py

@@ -0,0 +1,7 @@
+
+import math
+
+
+def SineIn(t, b, c, d):
+	return -c * math.cos(t/d * (math.pi/2)) + c + b
+

+ 1 - 0
sys.py/libs/roundrects/__init__.py

@@ -0,0 +1 @@
+from .roundrects import aa_round_rect, round_rect

+ 60 - 0
sys.py/libs/roundrects/roundrects.py

@@ -0,0 +1,60 @@
+"""
+Rounded rectangles in both non-antialiased and antialiased varieties.
+"""
+
+import pygame as pg
+
+from pygame import gfxdraw
+
+
+def round_rect(surface, rect, color, rad=20, border=0, inside=(0,0,0,0)):
+    """
+    Draw a rect with rounded corners to surface.  Argument rad can be specified
+    to adjust curvature of edges (given in pixels).  An optional border
+    width can also be supplied; if not provided the rect will be filled.
+    Both the color and optional interior color (the inside argument) support
+    alpha.
+    """
+    rect = pg.Rect(rect)
+    zeroed_rect = rect.copy()
+    zeroed_rect.topleft = 0,0
+    image = pg.Surface(rect.size).convert_alpha()
+    image.fill((0,0,0,0))
+    _render_region(image, zeroed_rect, color, rad)
+    if border:
+        zeroed_rect.inflate_ip(-2*border, -2*border)
+        _render_region(image, zeroed_rect, inside, rad)
+    surface.blit(image, rect)
+
+
+def _render_region(image, rect, color, rad):
+    """Helper function for round_rect."""
+    corners = rect.inflate(-2*rad, -2*rad)
+    for attribute in ("topleft", "topright", "bottomleft", "bottomright"):
+        pg.draw.circle(image, color, getattr(corners,attribute), rad)
+    image.fill(color, rect.inflate(-2*rad,0))
+    image.fill(color, rect.inflate(0,-2*rad))
+
+
+def aa_round_rect(surface, rect, color, rad=20, border=0, inside=(0,0,0)):
+    """
+    Draw an antialiased rounded rect on the target surface.  Alpha is not
+    supported in this implementation but other than that usage is identical to
+    round_rect.
+    """
+    rect = pg.Rect(rect)
+    _aa_render_region(surface, rect, color, rad)
+    if border:
+        rect.inflate_ip(-2*border, -2*border)
+        _aa_render_region(surface, rect, inside, rad)
+
+
+def _aa_render_region(image, rect, color, rad):
+    """Helper function for aa_round_rect."""
+    corners = rect.inflate(-2*rad-1, -2*rad-1)
+    for attribute in ("topleft", "topright", "bottomleft", "bottomright"):
+        x, y = getattr(corners, attribute)
+        gfxdraw.aacircle(image, x, y, rad, color)
+        gfxdraw.filled_circle(image, x, y, rad, color)
+    image.fill(color, rect.inflate(-2*rad,0))
+    image.fill(color, rect.inflate(0,-2*rad))

+ 43 - 0
sys.py/proc/cpuinfo

@@ -0,0 +1,43 @@
+processor       : 0
+model name      : ARMv7 Processor rev 5 (v7l)
+BogoMIPS        : 48.00
+Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant     : 0x0
+CPU part        : 0xc07
+CPU revision    : 5
+
+processor       : 1
+model name      : ARMv7 Processor rev 5 (v7l)
+BogoMIPS        : 48.00
+Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant     : 0x0
+CPU part        : 0xc07
+CPU revision    : 5
+
+processor       : 2
+model name      : ARMv7 Processor rev 5 (v7l)
+BogoMIPS        : 48.00
+Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant     : 0x0
+CPU part        : 0xc07
+CPU revision    : 5
+
+processor       : 3
+model name      : ARMv7 Processor rev 5 (v7l) 
+BogoMIPS        : 48.00
+Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant     : 0x0
+CPU part        : 0xc07
+CPU revision    : 5
+
+Hardware        : Generic DT based system
+Revision        : 0000
+Serial          : 165541530903875e

+ 1 - 0
sys.py/proc/driver/backlight

@@ -0,0 +1 @@
+1

+ 324 - 0
sys.py/run.py

@@ -0,0 +1,324 @@
+# -*- coding: utf-8 -*- 
+
+import dbus
+import dbus.service
+import sys
+from wicd import misc 
+##misc.to_bool
+##misc.misc.noneToString
+##misc.to_unicode
+##misc.Noneify
+from wicd.translations import _
+from wicd import wpath
+from wicd import dbusmanager
+import time
+import gobject
+
+
+import pygame
+from sys import exit
+import os
+
+from beeprint import pp
+########
+if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):
+    import dbus.glib
+else:
+    from dbus.mainloop.glib import DBusGMainLoop
+    DBusGMainLoop(set_as_default=True)
+
+
+#local UI import
+from UI.constants    import Width,Height,bg_color,icon_width,icon_height,DT,GMEVT,RUNEVT,RUNSYS
+from UI.util_funcs   import ReplaceSuffix,FileExists, ReadTheFileContent,midRect,color_surface,SwapAndShow,GetExePath,X_center_mouse
+from UI.page         import PageStack,PageSelector,Page
+from UI.label        import Label
+from UI.icon_item    import IconItem
+#from UI.fonts        import fonts
+from UI.title_bar    import TitleBar
+from UI.foot_bar     import FootBar
+from UI.main_screen  import MainScreen
+from UI.above_all_patch import SoundPatch
+from UI.icon_pool    import MyIconPool
+
+from libs.DBUS            import setup_dbus
+
+import config
+
+if not pygame.display.get_init():
+    pygame.display.init()
+if not pygame.font.get_init():
+    pygame.font.init()
+
+gobject_main_loop = None
+
+sound_patch = None
+
+myscriptname = os.path.basename(os.path.realpath(__file__))
+
+everytime_keydown = time.time()
+
+last_brt = -1
+
+def gobject_loop():
+    """
+    here to receive dbus signal 
+    """ 
+    try:
+        gobject_main_loop.run()
+    except KeyboardInterrupt:
+        gobject_main_loop.quit()
+        exit(-1)
+
+
+def RestoreLastBackLightBrightness(main_screen):
+    global last_brt
+    
+    if last_brt == -1:
+        return
+
+    try:
+        f = open(config.BackLight,"r+")
+    except IOError:
+        print( "RestoreLastBackLightBrightness open %s failed, try to adjust brightness in Settings" % config.BackLight)
+        pass
+    else:
+        with f:
+            content = f.readlines()
+            content = [x.strip() for x in content]
+            brt=int(content[0])        
+            if brt < last_brt:
+                f.seek(0)
+                f.write(str( last_brt ))
+                f.truncate()
+                f.close()
+                last_brt = -1
+                main_screen._TitleBar._InLowBackLight = -1
+            else:
+                
+                f.close()
+                return
+
+def InspectionTeam(main_screen):
+    global everytime_keydown,last_brt
+    
+    cur_time = time.time()
+
+    if cur_time - everytime_keydown > 40:
+        print("timeout, dim screen %d" % int(cur_time - everytime_keydown))
+
+        try:
+            f = open(config.BackLight,"r+")
+        except IOError:
+            pass
+        else:
+            with f:
+                content = f.readlines()
+                content = [x.strip() for x in content]
+                brt=int(content[0])
+                if brt > 1:
+                    last_brt = brt ## remember brt for restore
+                    brt = 1
+                    f.seek(0)
+                    f.write(str(brt))
+                    f.truncate()
+                    f.close()
+
+                    main_screen._TitleBar._InLowBackLight = 0
+                    
+        everytime_keydown = cur_time
+        
+    return True
+
+def event_process(event,main_screen):
+    global sound_patch
+    global everytime_keydown 
+    if event != None:
+
+        pygame.event.clear()
+        
+        if event.type == pygame.ACTIVEEVENT:
+            print(" ACTIVEEVENT !")
+            return
+        if event.type == pygame.QUIT:
+            exit()
+        if event.type == GMEVT:
+            main_screen.Draw()
+            main_screen.SwapAndShow()
+            pygame.event.clear(GMEVT)
+            return
+        if event.type == RUNEVT:
+
+            if config.DontLeave==True:
+                os.chdir(GetExePath())
+                os.system( "/bin/sh -c "+event.message)
+            else:
+                on_exit_cb = getattr(main_screen,"OnExitCb",None)
+                if on_exit_cb != None:
+                    if callable( on_exit_cb ):
+                        main_screen.OnExitCb(event)
+                
+                pygame.quit()
+                gobject_main_loop.quit()
+                os.chdir( GetExePath())
+                exec_app_cmd = event.message
+                exec_app_cmd += "; sync & cd "+GetExePath()+"; exec python "+myscriptname
+                print(exec_app_cmd)
+                os.execlp("/bin/sh","/bin/sh","-c", exec_app_cmd)
+                os.chdir( GetExePath())
+                os.exelp("python","python"," "+myscriptname)
+                sys.exit(-1)
+            return
+
+        if event.type == RUNSYS:
+            if config.DontLeave==True:
+                os.chdir(GetExePath())
+                os.system( "/bin/sh -c "+event.message)
+            else:
+                pygame.quit()
+                gobject_main_loop.quit()
+                os.chdir( GetExePath())
+                exec_app_cmd = event.message
+                exec_app_cmd += "; sync & cd "+GetExePath()+"; exec python "+myscriptname
+                print(exec_app_cmd)
+                os.execlp("/bin/sh","/bin/sh","-c", exec_app_cmd)
+                os.chdir( GetExePath())
+                os.exelp("python","python"," "+myscriptname)
+            return
+        if event.type == pygame.KEYUP:
+            
+            pygame.event.clear(pygame.KEYDOWN)
+            return
+        if event.type == pygame.KEYDOWN:
+            everytime_keydown = time.time()
+            RestoreLastBackLightBrightness(main_screen)
+            ###########################################################
+            if event.key == pygame.K_q:
+                on_exit_cb = getattr(main_screen,"OnExitCb",None)
+                if on_exit_cb != None:
+                    if callable( on_exit_cb ):
+                        main_screen.OnExitCb(event)
+                
+                gobject_main_loop.quit()
+                exit()
+
+            if event.key == pygame.K_KP_PLUS:
+                
+                main_screen.Draw()
+                sound_patch.VolumeUp()
+                sound_patch.Draw()
+                
+                main_screen.SwapAndShow()
+                #pygame.time.delay(200)
+                #main_screen.Draw()
+                #main_screen.SwapAndShow()
+                
+            if event.key == pygame.K_KP_MINUS:
+                main_screen.Draw()
+                
+                sound_patch.VolumeDown()
+                sound_patch.Draw()
+                
+                main_screen.SwapAndShow()
+                #pygame.time.delay(200)
+                #main_screen.Draw()
+                #main_screen.SwapAndShow()
+                
+            
+            ###########################################################
+            if event.key == pygame.K_ESCAPE:
+                pygame.event.clear()
+            
+            key_down_cb = getattr(main_screen,"KeyDown",None)
+            if key_down_cb != None:
+                if callable( key_down_cb ):
+                    main_screen.KeyDown(event)
+            
+            return
+                    
+def gobject_pygame_event_poll_timer(main_screen):
+    
+    event = pygame.event.poll()
+
+    event_process(event,main_screen)
+
+    InspectionTeam(main_screen)
+    
+    return True 
+
+def gobject_pygame_event_timer(main_screen):
+    global sound_patch
+    
+    for event in pygame.event.get():
+        event_process(event,main_screen)
+    
+    return True 
+
+def big_loop():
+    global sound_patch
+    
+    title_bar = TitleBar()
+    title_bar.Init(screen)
+    foot_bar  = FootBar()
+    foot_bar.Init(screen)
+
+    main_screen = MainScreen()
+    main_screen._HWND = screen
+    main_screen._TitleBar = title_bar 
+    main_screen._FootBar  = foot_bar
+    main_screen.Init()
+    main_screen.ReadTheDirIntoPages("../Menu",0,None)
+    main_screen.FartherPages()
+
+
+    sound_patch = SoundPatch()
+    sound_patch._Parent = main_screen
+    sound_patch.Init()
+    #pp(main_screen._Pages[0],True,6)
+
+    screen.fill(bg_color)
+    main_screen.Draw()
+    main_screen.SwapAndShow()
+
+    #gobject.timeout_add(DT,gobject_pygame_event_timer,main_screen)
+    gobject.timeout_add(DT,gobject_pygame_event_poll_timer,main_screen)
+    gobject.timeout_add(3000,title_bar.GObjectRoundRobin)
+
+    
+    gobject_loop()
+    
+
+###MAIN()###
+if __name__ == '__main__':
+    
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    X_center_mouse()
+    
+    os.chdir( os.path.dirname(os.path.realpath(__file__)) )
+    
+    SCREEN_SIZE = (Width,Height)
+    screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
+
+    pygame.event.set_allowed(None) 
+    pygame.event.set_allowed([pygame.KEYDOWN,pygame.KEYUP,GMEVT,RUNEVT,RUNSYS])
+    
+    pygame.key.set_repeat(DT+234, DT+123)
+
+
+    MyIconPool.Init()
+    
+    setup_dbus()
+
+    gobject.threads_init()
+    
+    gobject_main_loop = gobject.MainLoop()
+
+#    if pygame.display.get_active() == True:
+#        print("I am actived")
+    
+    if pygame.image.get_extended() == False:
+        print("This pygame does not support PNG")
+        exit()
+    
+    big_loop()
+    

+ 12 - 0
sys.py/sys/class/power_supply/axp20x-battery/uevent

@@ -0,0 +1,12 @@
+POWER_SUPPLY_NAME=axp20x-battery
+POWER_SUPPLY_PRESENT=1
+POWER_SUPPLY_ONLINE=1
+POWER_SUPPLY_STATUS=Discharging
+POWER_SUPPLY_VOLTAGE_NOW=3967000
+POWER_SUPPLY_CURRENT_NOW=258000
+POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=1200000
+POWER_SUPPLY_CONSTANT_CHARGE_CURRENT_MAX=1200000
+POWER_SUPPLY_HEALTH=Good
+POWER_SUPPLY_VOLTAGE_MAX_DESIGN=4200000
+POWER_SUPPLY_VOLTAGE_MIN_DESIGN=2900000
+POWER_SUPPLY_CAPACITY=30

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません