Browse Source

Add files via upload

clockworkpi 6 years ago
parent
commit
ad93e5d889
59 changed files with 4734 additions and 0 deletions
  1. 345 0
      Menu/GameShell/10_Settings/About/__init__.py
  2. 17 0
      Menu/GameShell/10_Settings/Brightness/__init__.py
  3. 188 0
      Menu/GameShell/10_Settings/Brightness/brightness_page.py
  4. 6 0
      Menu/GameShell/10_Settings/Brightness/myvars.py
  5. 13 0
      Menu/GameShell/10_Settings/Brightness/pages.py
  6. 89 0
      Menu/GameShell/10_Settings/PowerOFF/__init__.py
  7. 17 0
      Menu/GameShell/10_Settings/Sound/__init__.py
  8. 6 0
      Menu/GameShell/10_Settings/Sound/myvars.py
  9. 13 0
      Menu/GameShell/10_Settings/Sound/pages.py
  10. 154 0
      Menu/GameShell/10_Settings/Sound/sound_page.py
  11. 137 0
      Menu/GameShell/10_Settings/Storage/__init__.py
  12. 359 0
      Menu/GameShell/10_Settings/Update/__init__.py
  13. 29 0
      Menu/GameShell/10_Settings/Wifi/__init__.py
  14. BIN
      Menu/GameShell/10_Settings/Wifi/icons/_L.png
  15. BIN
      Menu/GameShell/10_Settings/Wifi/icons/_R.png
  16. BIN
      Menu/GameShell/10_Settings/Wifi/icons/done.png
  17. BIN
      Menu/GameShell/10_Settings/Wifi/icons/lock.png
  18. 21 0
      Menu/GameShell/10_Settings/Wifi/icons/preload.py
  19. 340 0
      Menu/GameShell/10_Settings/Wifi/keyboard.py
  20. 5 0
      Menu/GameShell/10_Settings/Wifi/myvars.py
  21. 199 0
      Menu/GameShell/10_Settings/Wifi/net_item.py
  22. 61 0
      Menu/GameShell/10_Settings/Wifi/pages.py
  23. 28 0
      Menu/GameShell/10_Settings/Wifi/text_item.py
  24. 133 0
      Menu/GameShell/10_Settings/Wifi/textarea.py
  25. 820 0
      Menu/GameShell/10_Settings/Wifi/wifi_list.py
  26. 29 0
      Menu/GameShell/10_Settings/__init__.py
  27. 59 0
      Menu/GameShell/10_Settings/list_item.py
  28. 190 0
      Menu/GameShell/10_Settings/list_page.py
  29. 12 0
      Menu/GameShell/10_Settings/myvars.py
  30. 13 0
      Menu/GameShell/10_Settings/pages.py
  31. BIN
      Menu/GameShell/20_Retro Games/GBA.png
  32. 6 0
      Menu/GameShell/20_Retro Games/GBA/action.config
  33. BIN
      Menu/GameShell/20_Retro Games/MAME.png
  34. 6 0
      Menu/GameShell/20_Retro Games/MAME/action.config
  35. BIN
      Menu/GameShell/20_Retro Games/NES.png
  36. 7 0
      Menu/GameShell/20_Retro Games/NES/action.config
  37. BIN
      Menu/GameShell/CaveStroy.png
  38. 1 0
      Menu/GameShell/CaveStroy.sh
  39. BIN
      Menu/GameShell/Music Player.png
  40. 36 0
      Menu/GameShell/Music Player/__init__.py
  41. BIN
      Menu/GameShell/Music Player/icons/done.png
  42. 21 0
      Menu/GameShell/Music Player/icons/preload.py
  43. 135 0
      Menu/GameShell/Music Player/list_item.py
  44. 260 0
      Menu/GameShell/Music Player/mpd_spectrum_page.py
  45. 343 0
      Menu/GameShell/Music Player/music_lib_list_page.py
  46. 8 0
      Menu/GameShell/Music Player/myvars.py
  47. 38 0
      Menu/GameShell/Music Player/pages.py
  48. 279 0
      Menu/GameShell/Music Player/play_list_page.py
  49. BIN
      Menu/GameShell/PowerOFF.png
  50. 89 0
      Menu/GameShell/PowerOFF/__init__.py
  51. BIN
      Menu/GameShell/Retro Games.png
  52. BIN
      Menu/GameShell/RetroArch.png
  53. 1 0
      Menu/GameShell/RetroArch.sh
  54. BIN
      Menu/GameShell/Settings.png
  55. BIN
      Menu/GameShell/Sleep.png
  56. BIN
      Menu/GameShell/TinyCloud.png
  57. 220 0
      Menu/GameShell/TinyCloud/__init__.py
  58. BIN
      Menu/GameShell/freeDM.png
  59. 1 0
      Menu/GameShell/freeDM.sh

+ 345 - 0
Menu/GameShell/10_Settings/About/__init__.py

@@ -0,0 +1,345 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+#import math
+
+#from beeprint import pp
+from libs.roundrects import aa_round_rect
+#import gobject
+#from wicd import misc 
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect
+from UI.keys_def   import CurKeys
+from UI.scroller   import ListScroller
+from UI.icon_pool  import MyIconPool
+from UI.icon_item  import IconItem
+from UI.multilabel import MultiLabel
+
+
+
+class InfoPageListItem(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 20
+
+    _Labels = {}
+    _Icons  = {}
+    _Fonts  = {}
+
+    _LinkObj = None
+    
+    def __init__(self):
+        self._Labels = {}
+        self._Icons  = {}
+        self._Fonts  = {}
+
+    def SetSmallText(self,text):
+        
+        l = MultiLabel()
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+        l.Init(text,self._Fonts["small"])
+        
+        self._Labels["Small"] = l
+
+        #if self._Labels["Small"]._Width > self._Width:
+        #    self._Width = self._Labels["Small"]._Width
+        if self._Labels["Small"]._Height >= self._Height:
+            self._Height = self._Labels["Small"]._Height+10
+        
+    def Init(self,text):
+
+        #self._Fonts["normal"] = fonts["veramono12"]
+        
+        l = Label()
+        l._PosX = 10
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+
+        l.Init(text,self._Fonts["normal"])
+        self._Labels["Text"] = l
+        
+    def Draw(self):
+        
+        self._Labels["Text"]._PosY = self._PosY
+        self._Labels["Text"].Draw()
+
+        if "Small" in self._Labels:
+            self._Labels["Small"]._PosX = self._Labels["Text"]._Width + 16 
+            self._Labels["Small"]._PosY = self._PosY 
+            self._Labels["Small"].Draw()
+        
+        
+    
+
+class AboutPage(Page):
+    _FootMsg =  ["Nav.","","","Back",""]
+    _MyList = []
+    _ListFontObj = fonts["varela13"]
+    
+    _AList = {}
+
+    _Scrolled = 0
+    
+    _BGwidth = 320
+    _BGheight = 256
+
+    _DrawOnce = False
+    _Scroller = None
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}
+
+    def CpuMhz(self):
+        with open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq") as f:
+            content = f.readlines()
+        content = [x.strip() for x in content]
+
+        mhz = int(content[0]) / 1000.0
+
+        cpuscalemhz = {}
+        cpuscalemhz["key"] = "cpuscalemhz"
+        cpuscalemhz["label"] = "CPU Mhz:"
+        cpuscalemhz["value"] = str(mhz)
+        self._AList["cpuscalemhz"] = cpuscalemhz
+        
+        return 
+    
+    def CpuInfo(self):
+        last_processor = 0
+        with open("/proc/cpuinfo") as f:
+            for line in f:
+                if line.startswith("processor"):
+                    parts = line.split(":")
+                    cur_processor_number = int( parts[1].strip())
+                    if cur_processor_number > last_processor:
+                        last_processor = cur_processor_number
+                    
+                if line.startswith("model name"):
+                    parts = line.split(":")
+#                    print( parts[1].strip() )
+                    processor = {}
+                    processor["key"]="processor"
+                    processor["label"] = "Processor:"
+                    processor["value"] = parts[1].strip()
+                    
+                    self._AList["processor"] = processor
+                    
+                if line.startswith("cpu MHz"):
+                    parts = line.split(":")
+#                    print(parts[1].strip() )
+                    cpumhz = {}
+                    cpumhz["key"] = "cpumhz"
+                    cpumhz["label"] = "CPU MHz:"
+                    cpumhz["value"] = parts[1].strip()
+
+                    self._AList["cpumhz"] = cpumhz
+                if line.startswith("cpu cores"):
+                    parts = line.split(":")
+#                    print(parts[1].strip() )
+                    cpucores = {}
+                    cpucores["key"] = "cpucores"
+                    cpucores["label"] = "CPU cores:"
+                    cpucores["value"] = parts[1].strip()
+                    self._AList["cpucores"] = cpucores
+                if line.startswith("Features"):
+                    parts = line.split(":")
+#                    print(parts[1].strip() )
+                    f_ = {}
+                    f_["key"] = "features"
+                    f_["label"] = "Features:"
+                    f_["value"] = parts[1].strip()
+                    self._AList["features"] = f_
+                    
+                if line.startswith("flags"):
+                    parts = line.split(":")
+#                    print(parts[1].strip() )
+                    flags = {}
+                    flags["key"] = "flags"
+                    flags["label"] = "Flags:"
+                    flags["value"] = parts[1].strip()
+                    self._AList["flags"] = flags
+                    
+
+        if last_processor > 0:
+            arm_cores = {}
+            arm_cores["key"]= "armcores"
+            arm_cores["label"] = "CPU cores:"
+            arm_cores["value"] = str(last_processor + 1)
+            self._AList["armcores"] = arm_cores
+        
+    def MemInfo(self):
+
+        with open("/proc/meminfo") as f:
+            for line in f:
+                if line.startswith("MemTotal"):
+                    parts = line.split(":")
+                    parts[1] = parts[1].replace("kB","")
+                    print(   parts[1].strip() )
+
+                    memory = {}
+                    memory["key"] = "memory"
+                    memory["label"] = "Memory:"
+                    memory["value"] = str( int(parts[1].strip())/1000.0) +" Mb"
+                    self._AList["memory"] = memory                    
+                    break
+        
+    def GenList(self):
+        
+        self._MyList = []
+        
+        start_x  = 0
+        start_y  = 10
+        last_height = 0
+
+        for i,u in enumerate( ["processor","armcores","cpuscalemhz","features","memory"] ):
+        #for i,u in enumerate( ["processor","cpucores","cpumhz","flags","memory"] ):
+            if u not in self._AList:
+                continue
+            
+            v = self._AList[u]
+            
+            li = InfoPageListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y + last_height
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFontObj
+            li._Fonts["small"] = fonts["varela12"]
+            
+            if self._AList[u]["label"] != "":
+                li.Init(  self._AList[u]["label"] )
+            else:
+                li.Init( self._AList[u]["key"] )
+
+            li._Flag = self._AList[u]["key"]
+
+            li.SetSmallText( self._AList[u]["value"] )
+            
+            last_height += li._Height
+            
+            self._MyList.append(li)
+            
+    def Init(self):
+        if self._Screen != None:
+            if self._Screen._CanvasHWND != None and self._CanvasHWND == None:
+                self._HWND = self._Screen._CanvasHWND
+                self._CanvasHWND = pygame.Surface( (self._Screen._Width,self._BGheight) )
+
+        self._PosX = self._Index*self._Screen._Width 
+        self._Width = self._Screen._Width ## equal to screen width
+        self._Height = self._Screen._Height
+
+        bgpng = IconItem()
+        bgpng._ImgSurf = MyIconPool._Icons["about_bg"]
+        bgpng._MyType = ICON_TYPES["STAT"]
+        bgpng._Parent = self
+        bgpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+
+        self._Icons["bg"] = bgpng
+        
+        self.CpuInfo()
+        self.MemInfo()
+        self.CpuMhz()
+        
+        self.GenList()
+
+        self._Scroller = ListScroller()
+        self._Scroller._Parent = self
+        self._Scroller._PosX = self._Width - 10
+        self._Scroller._PosY = 2
+        self._Scroller.Init()
+        self._Scroller.SetCanvasHWND(self._HWND)
+        
+    def ScrollDown(self):
+        dis = 10
+        if abs(self._Scrolled) <  (self._BGheight - self._Height)/2 + 40:
+            self._PosY -= dis
+            self._Scrolled -= dis
+        
+    def ScrollUp(self):
+        dis = 10
+        if self._PosY < 0:
+            self._PosY += dis
+            self._Scrolled += dis
+
+        
+    def OnLoadCb(self):
+        self._Scrolled = 0
+        self._PosY = 0
+        self._DrawOnce = False
+
+    def OnReturnBackCb(self):
+        self.ReturnToUpLevelPage()
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        
+    def KeyDown(self,event):
+        if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]:
+            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()
+        
+                                
+    def Draw(self):
+
+        if self._DrawOnce == False:
+            self.ClearCanvas()
+            #self._Ps.Draw()
+        
+            self._Icons["bg"].NewCoord(self._Width/2,self._Height/2 + (self._BGheight - Height)/2 + self._Screen._TitleBar._Height)
+            self._Icons["bg"].Draw()
+
+            for i in self._MyList:
+                i.Draw()
+                
+            self._DrawOnce = True
+            
+        if self._HWND != None:
+            self._HWND.fill((255,255,255))
+            
+            self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width, self._Height ) )
+            
+            self._Scroller.UpdateSize(self._BGheight,abs(self._Scrolled)*3)
+            self._Scroller.Draw()
+        
+        
+
+
+class APIOBJ(object):
+
+    _Page = None
+    def __init__(self):
+        pass
+    def Init(self,main_screen):
+        self._Page = AboutPage()
+        self._Page._Screen = main_screen
+        self._Page._Name ="About"
+        self._Page.Init()
+        
+    def API(self,main_screen):
+        if main_screen !=None:
+            main_screen.PushPage(self._Page)
+            main_screen.Draw()
+            main_screen.SwapAndShow()
+
+OBJ = APIOBJ()
+def Init(main_screen):    
+    OBJ.Init(main_screen)
+def API(main_screen):
+    OBJ.API(main_screen)
+    
+        

+ 17 - 0
Menu/GameShell/10_Settings/Brightness/__init__.py

@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- 
+
+## local UI import
+import pages
+import myvars
+
+def Init(main_screen):
+    pages.InitBrightnessPage(main_screen)
+
+def API(main_screen):
+    
+    if main_screen !=None:
+        main_screen.PushCurPage()
+        main_screen.SetCurPage(myvars.BrightnessPage)
+        main_screen.Draw()
+        main_screen.SwapAndShow()
+        

+ 188 - 0
Menu/GameShell/10_Settings/Brightness/brightness_page.py

@@ -0,0 +1,188 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+
+#import math
+
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES
+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
+from UI.keys_def   import CurKeys
+from UI.slider     import Slider
+from UI.icon_pool  import MyIconPool
+from UI.multi_icon_item import MultiIconItem
+from config import BackLight
+import myvars
+
+class BSlider(Slider):
+
+    
+    OnChangeCB = None
+    _BGpng = None
+    _BGwidth = 179
+    _BGheight = 153
+
+    _NeedleSurf = None
+    _Scale      = None
+    _Parent     = None
+    _Icons      = {}
+    
+    def __init__(self):
+        Slider.__init__(self)
+        self._Icons = {}
+    def Init(self):
+        self._Width = self._Parent._Width
+        self._Height = self._Parent._Height
+        
+        bgpng = IconItem()
+        bgpng._ImgSurf = MyIconPool._Icons["light"]
+        bgpng._MyType = ICON_TYPES["STAT"]
+        bgpng._Parent = self
+        bgpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+        self._Icons["bg"] = bgpng
+        ##self._NeedleSurf = pygame.Surface( (38,12),pygame.SRCALPHA )
+        
+        scale = MultiIconItem()
+        scale._MyType = ICON_TYPES["STAT"]
+        scale._Parent = self
+        scale._ImgSurf = MyIconPool._Icons["scale"]
+        scale._IconWidth = 82
+        scale._IconHeight = 63
+        scale.Adjust(0,0,82,63,0)
+        self._Icons["scale"] = scale
+
+    def SetValue(self,brt):#pct 0-100
+        
+        self._Value = brt
+        
+    def Further(self):
+        self._Value+=1
+        if self._Value < 9:
+            if self.OnChangeCB != None:
+                if callable(self.OnChangeCB):
+                    self.OnChangeCB(self._Value)
+        else:
+            self._Value = 8
+                    
+    def StepBack(self):
+        self._Value-=1
+
+        if self._Value < 0:
+            self._Value = 0
+
+        if self.OnChangeCB != None:
+            if callable(self.OnChangeCB):
+                self.OnChangeCB(self._Value)
+    
+    def Draw(self):
+
+        self._Icons["bg"].NewCoord(self._Width/2,self._Height/2 +11 )
+        self._Icons["bg"].Draw()
+
+        self._Icons["scale"].NewCoord(self._Width/2,self._Height/2 )
+
+        self._Icons["scale"]._IconIndex = self._Value
+        self._Icons["scale"].Draw()
+        """
+        pygame.draw.line(self._CanvasHWND,(255,0,0), (posx,self._PosY),(self._Width,self._PosY),3) ## range line
+        pygame.draw.line(self._CanvasHWND,(0,0,255), (self._PosX,self._PosY),(posx,self._PosY),3) ## range line
+        
+        pygame.draw.circle(self._CanvasHWND,(255,255,255),( posx, self._PosY),7,0)        
+        pygame.draw.circle(self._CanvasHWND,(0,0,0)      ,( posx, self._PosY),7,1)## outer border
+        """
+        
+        
+        
+class BrightnessPage(Page):
+
+    _MySlider = None
+    _FootMsg = ["Nav","","","Back","Enter"]
+
+    def Init(self):
+        self._CanvasHWND = self._Screen._CanvasHWND
+        self._Width =  self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        self._MySlider = BSlider()
+#        self._MySlider._Width = Width - 20
+#        self._MySlider._Height = 30
+#        self._MySlider._PosX  = (self._Width - self._MySlider._Width)/2
+#        self._MySlider._PosY  = 40
+        self._MySlider._Parent = self
+        self._MySlider.SetCanvasHWND(self._CanvasHWND)
+        self._MySlider.OnChangeCB = self.WhenSliderDrag
+        self._MySlider.Init()
+
+        brt  = self.ReadBackLight()
+        
+        self._MySlider.SetValue( brt)
+
+    
+    def ReadBackLight(self):
+        try:
+            f = open(BackLight)
+        except IOError:
+            return 0
+        else:
+            with f:
+                content = f.readlines()
+                content = [x.strip() for x in content]
+                return int(content[0])
+
+        return 0
+
+    def OnLoadCb(self):
+         brt  = self.ReadBackLight()
+         self._MySlider.SetValue( brt)
+         
+    def SetBackLight(self,newbrt):
+        try:
+            f = open(BackLight,'w')
+        except IOError:
+            print("Open write %s failed" % BackLight)
+            return False
+        else:
+            with f:
+                f.write(str(newbrt))
+                return True
+        
+    def WhenSliderDrag(self,value): ##value 0-100
+        if value < 0 or value > 8:
+            return
+
+        if value == 0: ## 0 == total black
+            value = 1
+        
+        self.SetBackLight(value)
+        
+    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["Right"]:
+            self._MySlider.Further()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+        if event.key == CurKeys["Left"]:
+            self._MySlider.StepBack()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+    def Draw(self):
+        self.ClearCanvas()
+        
+        self._MySlider.Draw()
+
+        
+
+
+    

+ 6 - 0
Menu/GameShell/10_Settings/Brightness/myvars.py

@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*- 
+
+import os
+import sys
+
+SoundPage = None

+ 13 - 0
Menu/GameShell/10_Settings/Brightness/pages.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*- 
+
+from brightness_page import BrightnessPage
+
+import myvars
+
+def InitBrightnessPage(main_screen):
+
+    myvars.BrightnessPage = BrightnessPage()
+    
+    myvars.BrightnessPage._Screen = main_screen
+    myvars.BrightnessPage._Name = "Brightness"
+    myvars.BrightnessPage.Init()

+ 89 - 0
Menu/GameShell/10_Settings/PowerOFF/__init__.py

@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+#UI lib
+from UI.constants    import RUNSYS
+from UI.keys_def     import CurKeys
+from UI.confirm_page import ConfirmPage
+
+import config
+
+class PowerOffConfirmPage(ConfirmPage):
+    
+    _ConfirmText = "Confirm Power OFF?"
+    
+
+    def CheckBattery(self):
+        try:
+            f = open(config.Battery)
+        except IOError:
+            print( "PowerOFF 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 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() < 20:
+                cmdpath = "feh --bg-center gameshell/wallpaper/gameover.png;"
+            else:
+                cmdpath = "feh --bg-center gameshell/wallpaper/seeyou.png;"
+            
+            cmdpath += "sleep 3;"
+            
+            #cmdpath += "echo 'halt -p' > /tmp/halt_cmd"
+            
+            cmdpath += "sudo halt -p"
+            pygame.event.post( pygame.event.Event(RUNSYS, message=cmdpath))
+
+
+
+class APIOBJ(object):
+
+    _StoragePage = None
+    def __init__(self):
+        pass
+    def Init(self,main_screen):
+        self._Page = PowerOffConfirmPage()
+
+        self._Page._Screen = main_screen
+        self._Page._Name ="Power OFF"
+        self._Page.Init()
+        
+        
+    def API(self,main_screen):
+        if main_screen !=None:
+            main_screen.PushPage(self._Page)
+            main_screen.Draw()
+            main_screen.SwapAndShow()
+
+OBJ = APIOBJ()
+def Init(main_screen):    
+    OBJ.Init(main_screen)
+def API(main_screen):
+    OBJ.API(main_screen)
+    

+ 17 - 0
Menu/GameShell/10_Settings/Sound/__init__.py

@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- 
+
+## local UI import
+import pages
+import myvars
+
+def Init(main_screen):
+    pages.InitSoundPage(main_screen)
+
+def API(main_screen):
+    
+    if main_screen !=None:
+        main_screen.PushCurPage()
+        main_screen.SetCurPage(myvars.SoundPage)
+        main_screen.Draw()
+        main_screen.SwapAndShow()
+        

+ 6 - 0
Menu/GameShell/10_Settings/Sound/myvars.py

@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*- 
+
+import os
+import sys
+
+SoundPage = None

+ 13 - 0
Menu/GameShell/10_Settings/Sound/pages.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*- 
+
+from sound_page import SoundPage
+
+import myvars
+
+def InitSoundPage(main_screen):
+
+    myvars.SoundPage = SoundPage()
+    
+    myvars.SoundPage._Screen = main_screen
+    myvars.SoundPage._Name = "Sound volume"
+    myvars.SoundPage.Init()

+ 154 - 0
Menu/GameShell/10_Settings/Sound/sound_page.py

@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+#from libs.roundrects import aa_round_rect
+
+import alsaaudio
+
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES
+from UI.page   import Page,PageSelector
+from UI.icon_item import IconItem
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect
+from UI.keys_def   import CurKeys
+from UI.slider     import Slider
+from UI.multi_icon_item import MultiIconItem
+
+
+from UI.icon_pool  import MyIconPool
+
+import myvars
+
+class SoundSlider(Slider):
+    OnChangeCB = None
+    
+    _BGpng = None
+    _BGwidth = 192
+    _BGheight = 173
+
+    _NeedleSurf = None
+    _Scale      = None
+    _Parent     = None
+    _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):
+        Slider.__init__(self)
+        
+    def Init(self):
+        self._Width = self._Parent._Width
+        self._Height = self._Parent._Height
+        
+        self._BGpng = IconItem()
+        self._BGpng._ImgSurf = MyIconPool._Icons["vol"]
+        self._BGpng._MyType = ICON_TYPES["STAT"]
+        self._BGpng._Parent = self
+        self._BGpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+
+        ##self._NeedleSurf = pygame.Surface( (38,12),pygame.SRCALPHA )
+        
+        self._Scale = MultiIconItem()
+        self._Scale._MyType = ICON_TYPES["STAT"]
+        self._Scale._Parent = self
+        self._Scale._ImgSurf = MyIconPool._Icons["scale"]
+        self._Scale._IconWidth = 82
+        self._Scale._IconHeight = 63
+        self._Scale.Adjust(0,0,82,63,0)
+        
+    def SetValue(self,pct):#pct 0-100
+
+        for i,v in enumerate(self.snd_segs):
+            if pct  >= v[0] and pct <= v[1]:
+                self._Value = i
+        
+    def Further(self):
+        self._Value+=1
+        if self._Value < len(self._Segs):
+            if self.OnChangeCB != None:
+                if callable(self.OnChangeCB):
+                    self.OnChangeCB( self._Segs[ self._Value ] )
+        else:
+            self._Value = len(self._Segs)-1
+        
+    def StepBack(self):
+        self._Value-=1
+
+        if self._Value < 0:
+            self._Value = 0
+
+        if self.OnChangeCB != None:
+            if callable(self.OnChangeCB):
+                self.OnChangeCB(self._Segs[self._Value] )
+    
+    def Draw(self):
+        
+        self._BGpng.NewCoord(self._Width/2,self._Height/2 )
+        self._BGpng.Draw()
+
+        self._Scale.NewCoord(self._Width/2,self._Height/2)
+        
+        self._Scale._IconIndex = self._Value
+        
+        self._Scale.Draw()
+        
+        
+        
+class SoundPage(Page):
+
+    _MySlider = None
+    _FootMsg = ["Nav","","","Back","Enter"]
+
+    def Init(self):
+        self._CanvasHWND = self._Screen._CanvasHWND
+        self._Width =  self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        self._MySlider = SoundSlider()
+        
+
+        self._MySlider._Parent = self        
+        self._MySlider.SetCanvasHWND(self._CanvasHWND)
+
+        self._MySlider.OnChangeCB = self.WhenSliderDrag
+
+        self._MySlider.Init()
+        
+        m = alsaaudio.Mixer()
+        self._MySlider.SetValue(m.getvolume()[0])
+        
+    def WhenSliderDrag(self,value): ##value 0-100
+        if value < 0 or value > 100:
+            return
+        
+        m = alsaaudio.Mixer()
+        m.setvolume(int(value))
+        
+    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["Right"]:
+            self._MySlider.Further()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+        if event.key == CurKeys["Left"]:
+            self._MySlider.StepBack()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+    def Draw(self):
+        self.ClearCanvas()
+        
+        self._MySlider.Draw()
+
+        
+
+
+    

+ 137 - 0
Menu/GameShell/10_Settings/Storage/__init__.py

@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import os
+
+
+## local UI import
+from UI.page  import Page
+from UI.constants import ICON_TYPES,Width,Height
+from UI.icon_item import IconItem
+from UI.icon_pool import MyIconPool
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect
+
+from libs.roundrects import aa_round_rect
+
+class StoragePage(Page):
+
+    _Icons = {}
+    _BGpng  = None
+    _BGwidth = 96
+    _BGheight = 73
+    _BGlabel  = None
+    _FreeLabel = None
+    
+    _BGmsg    = "%.1fGB of %.1fGB Used"
+    _DskUsg   = None
+
+    _HighColor = pygame.Color(51,166,255)
+    
+    def __init__(self):
+        Page.__init__(self)
+        
+        self._Icons = {}
+
+
+    def DiskUsage(self):
+        statvfs = os.statvfs('/')
+
+        total_space = (statvfs.f_frsize * statvfs.f_blocks)/1024.0/1024.0/1024.0
+
+        avail_space = ( statvfs.f_frsize * statvfs.f_bavail) / 1024.0 / 1024.0/ 1024.0
+
+        return avail_space,total_space
+        
+    def Init(self):
+
+        self._DskUsg = self.DiskUsage()
+        
+        self._CanvasHWND = self._Screen._CanvasHWND
+        self._Width =  self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        self._BGpng = IconItem()
+        self._BGpng._ImgSurf = MyIconPool._Icons["icon_sd"]
+        self._BGpng._MyType = ICON_TYPES["STAT"]
+        self._BGpng._Parent = self
+        
+        self._BGpng.AddLabel(self._BGmsg % (self._DskUsg[1]-self._DskUsg[0], self._DskUsg[1]), fonts["varela15"])
+        self._BGpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+
+        
+        self._BGlabel = Label()
+        self._BGlabel.SetCanvasHWND(self._CanvasHWND)
+
+        usage_percent = (self._DskUsg[0]/self._DskUsg[1] )*100.0
+        
+        self._BGlabel.Init("%d%%"% int(usage_percent),fonts["varela25"])
+        self._BGlabel.SetColor( self._HighColor )
+        
+        self._FreeLabel = Label()
+        self._FreeLabel.SetCanvasHWND(self._CanvasHWND)
+        self._FreeLabel.Init("Free",fonts["varela13"])
+        self._FreeLabel.SetColor(self._BGlabel._Color)
+
+        
+    def OnLoadCb(self):
+        pass
+    
+    def Draw(self):
+        self.ClearCanvas()
+        
+        self._BGpng.NewCoord(self._Width/2,self._Height/2-10)
+        self._BGpng.Draw()
+        self._BGlabel.NewCoord(self._Width/2-28,self._Height/2-30)
+        self._BGlabel.Draw()
+
+        self._FreeLabel.NewCoord(self._BGlabel._PosX+10   ,self._Height/2)
+        self._FreeLabel.Draw()
+
+        #bgcolor = (238,238,238), fgcolor = (126,206,244)
+        #aa_round_rect
+        usage_percent = (self._DskUsg[0]/self._DskUsg[1] )
+        if usage_percent < 0.1:
+            usage_percent = 0.1
+
+        rect_ = midRect(self._Width/2,self._Height-30,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-30,int(170*(1.0-usage_percent)),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))        
+        
+class APIOBJ(object):
+
+    _StoragePage = None
+    def __init__(self):
+        pass
+    def Init(self,main_screen):
+        self._StoragePage = StoragePage()
+
+        self._StoragePage._Screen = main_screen
+        self._StoragePage._Name ="Storage"
+        self._StoragePage.Init()
+        
+        
+    def API(self,main_screen):
+        if main_screen !=None:
+            main_screen.PushPage(self._StoragePage)
+            main_screen.Draw()
+            main_screen.SwapAndShow()
+    
+
+
+OBJ = APIOBJ()
+def Init(main_screen):    
+    OBJ.Init(main_screen)
+def API(main_screen):
+    OBJ.API(main_screen)
+    
+        

+ 359 - 0
Menu/GameShell/10_Settings/Update/__init__.py

@@ -0,0 +1,359 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import os
+import requests
+import validators
+import gobject
+
+
+## local UI import
+from UI.page  import Page
+from UI.constants import ICON_TYPES,Width,Height,RUNEVT
+from UI.icon_item import IconItem
+from UI.icon_pool import MyIconPool
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect,CmdClean
+from UI.keys_def import CurKeys
+from UI.confirm_page import ConfirmPage
+from UI.download     import Download
+from UI.download_process_page import DownloadProcessPage
+
+from libs.roundrects import aa_round_rect
+
+import config
+
+class UpdateDownloadPage(DownloadProcessPage):
+    _MD5 = ""
+
+    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 = self._Downloader.get_dest()
+                    
+                    if filename.endswith(".tar.gz"):                    
+                        #/home/cpi/apps/[launcher]
+                        cmdpath = "tar zxf " + CmdClean(filename) + " -C /home/cpi/apps ;rm -rf "+ filename
+                        pygame.event.post( pygame.event.Event(RUNEVT, message=cmdpath))
+                        
+                    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
+
+                    filename = self._Downloader.get_dest()
+                    print(filename)
+                    os.system("rm -rf %s" % CmdClean(filename))
+                    
+                    self._Screen._MsgBox.SetText("Download failed")
+                    self._Screen._MsgBox.Draw()
+                    self._Screen.SwapAndShow()
+                    return False
+            else:
+                self._Value =  self._Downloader.get_progress()
+                print("Progress: %d%%" % (self._Value))
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                return True
+        else:
+            return False
+    
+    def StartDownload(self,url,dst_dir):
+        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()            
+            return
+        
+        self._Downloader = Download(url,dst_dir,None)
+        if self._MD5 != None:
+            if len(self._MD5) == 32:
+                self._Downloader.add_hash_verification('md5' ,self._MD5) ## hashlib provide algorithms
+
+        self._Downloader.start()
+        
+        self._DownloaderTimer = gobject.timeout_add(100, self.GObjectUpdateProcessInterval)
+
+    
+
+class UpdateConfirmPage(ConfirmPage):
+    _ConfirmText = "Confirm Update ?"
+    
+    _DownloadPage = None
+
+    _URL = ""
+    _MD5 = ""
+    _Version = ""
+    _GIT = False
+    
+    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._GIT == True:
+                cmdpath = "cd /home/cpi/apps/launcher ;git pull "
+                pygame.event.post( pygame.event.Event(RUNEVT, message=cmdpath))
+                self._GIT = False
+                return
+            
+            if self._DownloadPage == None:
+                self._DownloadPage = UpdateDownloadPage()
+                self._DownloadPage._Screen = self._Screen
+                self._DownloadPage._Name   = "Downloading..."                
+                self._DownloadPage.Init()
+
+            self._DownloadPage._MD5 = self._MD5
+            self._Screen.PushPage(self._DownloadPage)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+            if self._URL != None and validators.url(self._URL):
+                self._DownloadPage.StartDownload(self._URL, "/tmp")
+            else:
+                print "error url  %s " % self._URL
+            
+
+    def OnReturnBackCb(self):
+        self.ReturnToUpLevelPage()
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+            
+    def Draw(self):
+        self.ClearCanvas()
+        self.DrawBG()
+        for i in self._MyList:
+            i.Draw()
+        
+        self.Reset()
+
+
+class InfoPageListItem(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 30
+
+    _Labels = {}
+    _Icons  = {}
+    _Fonts  = {}
+
+    _LinkObj = None
+    
+    def __init__(self):
+        self._Labels = {}
+        self._Icons  = {}
+        self._Fonts  = {}
+
+    def SetSmallText(self,text):
+        
+        l = Label()
+        l._PosX = 40
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+        l.Init(text,self._Fonts["small"])
+        self._Labels["Small"] = l
+        
+    def Init(self,text):
+
+        #self._Fonts["normal"] = fonts["veramono12"]
+        
+        l = Label()
+        l._PosX = 10
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+
+        l.Init(text,self._Fonts["normal"])
+        self._Labels["Text"] = l
+
+    def Draw(self):
+        
+        self._Labels["Text"]._PosY = self._PosY + (self._Height - self._Labels["Text"]._Height)/2
+        self._Labels["Text"].Draw()
+
+        if "Small" in self._Labels:
+            self._Labels["Small"]._PosX = self._Width - self._Labels["Small"]._Width-5
+            
+            self._Labels["Small"]._PosY = self._PosY + (self._Height - self._Labels["Small"]._Height)/2
+            self._Labels["Small"].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)
+        
+
+class UpdatePage(Page):
+    _Icons = {}
+    _FootMsg = ["Nav.","Check Update","","Back",""]
+
+    _ListFontObj = fonts["varela15"]    
+    _ConfirmPage = None
+    _AList    = {}
+    _MyList   = []
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}    
+
+    def GenList(self):
+        
+        start_x  = 0
+        start_y  = 0
+        
+        for i,v in enumerate( self._AList):
+            li = InfoPageListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y + i*InfoPageListItem._Height
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFontObj
+            li._Fonts["small"] = fonts["varela12"]
+            
+            if self._AList[v]["label"] != "":
+                li.Init(  self._AList[v]["label"] )
+            else:
+                li.Init( self._AList[v]["key"] )
+
+            li._Flag = self._AList[v]["key"]
+
+            li.SetSmallText( self._AList[v]["value"] )
+            
+            self._MyList.append(li)
+        
+    def Init(self):
+        self._CanvasHWND = self._Screen._CanvasHWND
+        self._Width =  self._Screen._Width
+        self._Height = self._Screen._Height
+
+        self._ConfirmPage = UpdateConfirmPage()
+        self._ConfirmPage._Screen = self._Screen
+        self._ConfirmPage._Name  = "Update Confirm"
+        self._ConfirmPage._Parent = self
+        self._ConfirmPage.Init()
+
+        it = {}
+        it["key"] = "version"
+        it["label"] = "Version"
+        it["value"] = config.VERSION
+        self._AList["version"] = it
+        
+        self.GenList()
+        
+    def CheckUpdate(self):
+        self._Screen._MsgBox.SetText("Checking update...")
+        self._Screen._MsgBox.Draw()
+        self._Screen.SwapAndShow()
+
+        try:
+            r = requests.get(config.UPDATE_URL, verify=False, timeout=8)
+        except:
+            print("requests get error")
+            return
+        else:
+            if r.status_code == requests.codes.ok:
+                try:
+                    json_ = r.json()
+
+                    if "version" in json_ and "updatepath" in json_ and "md5sum" in json_:
+                        if config.VERSION != json_["version"]:
+                            
+                            self._ConfirmPage._URL = json_["updatepath"]
+                            self._ConfirmPage._MD5 = json_["md5sum"]
+                            self._ConfirmPage._GIT = False
+                            
+                            self._Screen.PushPage(self._ConfirmPage)
+                            
+                            self._Screen.Draw()
+                            self._ConfirmPage.SnapMsg("Confirm Update to %s ?" % json_["version"] )
+                            self._Screen.SwapAndShow()
+                            
+                    elif "gitversion" in json_: ### just use git to  run update
+                        if confirm.VERSION != json_["gitversion"]:
+                            self._ConfirmPage._URL = None
+                            self._ConfirmPage._MD5 = None
+                            self._ConfirmPage._GIT = True
+                        
+                            self._Screen.PushPage(self._ConfirmPage)
+                            
+                            self._Screen.Draw()
+                            self._ConfirmPage.SnapMsg("Update to %s ?" % json_["gitversion"] )
+                            self._Screen.SwapAndShow()
+                        
+                    return True
+                except:
+                    print("r.json error")
+                
+            else:
+                print(" requests get error %d ", r.status_code)
+                    
+
+        return False
+    
+    def OnLoadCb(self):
+        pass
+
+    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["X"]:
+            if self.CheckUpdate() == True:
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+            else:
+                self._Screen.Draw()
+                self._Screen._MsgBox.SetText("Checking update failed")
+                self._Screen._MsgBox.Draw()
+                self._Screen.SwapAndShow()         
+
+    def Draw(self):
+        self.ClearCanvas()
+#        self._Ps.Draw()
+
+        for i in self._MyList:
+            i.Draw()
+        
+    
+class APIOBJ(object):
+
+    _UpdatePage = None
+    def __init__(self):
+        pass
+    def Init(self,main_screen):
+        self._UpdatePage = UpdatePage()
+
+        self._UpdatePage._Screen = main_screen
+        self._UpdatePage._Name ="Update"
+        self._UpdatePage.Init()
+        
+    def API(self,main_screen):
+        if main_screen !=None:
+            main_screen.PushPage(self._UpdatePage)
+            main_screen.Draw()
+            main_screen.SwapAndShow()
+    
+
+
+OBJ = APIOBJ()
+def Init(main_screen):    
+    OBJ.Init(main_screen)
+def API(main_screen):
+    OBJ.API(main_screen)
+    
+        

+ 29 - 0
Menu/GameShell/10_Settings/Wifi/__init__.py

@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*- 
+
+
+## local UI import
+import pages
+import myvars
+"""
+try:
+    from icons import preload
+except:
+    print("No icons package")
+"""
+from icons import preload
+
+def Init(main_screen):
+    
+    preload.load_icons()
+    pages.InitPasswordPage(main_screen)
+    pages.InitScanPage(main_screen)
+
+def API(main_screen):
+    
+    if main_screen != None:
+        main_screen.PushCurPage()
+        main_screen.SetCurPage(myvars.ScanPage)
+        main_screen.Draw()
+        main_screen.SwapAndShow()
+
+

BIN
Menu/GameShell/10_Settings/Wifi/icons/_L.png


BIN
Menu/GameShell/10_Settings/Wifi/icons/_R.png


BIN
Menu/GameShell/10_Settings/Wifi/icons/done.png


BIN
Menu/GameShell/10_Settings/Wifi/icons/lock.png


+ 21 - 0
Menu/GameShell/10_Settings/Wifi/icons/preload.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+from beeprint import pp
+
+ICONS_PRELOAD={}
+
+
+def load_icons():
+    basepath = os.path.dirname(os.path.realpath(__file__))
+
+    files = os.listdir(basepath)
+    for i in files:
+        if os.path.isfile(basepath+"/"+i) and i.endswith(".png"):
+            keyname = i.split(".")[0]
+            ICONS_PRELOAD[keyname] = pygame.image.load(basepath+"/"+i).convert_alpha()

+ 340 - 0
Menu/GameShell/10_Settings/Wifi/keyboard.py

@@ -0,0 +1,340 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+from libs import easing
+
+## local UI import
+from UI.constants  import Width,Height,ICON_TYPES
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect
+from UI.keys_def import CurKeys
+from UI.icon_item import IconItem
+
+from textarea  import Textarea
+from text_item import TextItem
+from icons     import preload
+
+import myvars
+
+class KeyboardIcon(IconItem):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 0
+    _Color = pygame.Color(83,83,83)
+    _MyType  = ICON_TYPES["NAV"] 
+    _Parent  = None
+    _Str     = ""
+    
+    def Draw(self):
+        self._Parent._CanvasHWND.blit(self._ImgSurf, \
+            midRect(self._PosX,self._PosY,self._Width,self._Height,Width,Height))
+
+
+class KeyboardSelector(PageSelector):
+    
+    def Draw(self):
+        sec_idx = self._Parent._SectionIndex
+        row_idx = self._Parent._RowIndex
+        idx     = self._Parent._PsIndex
+        
+        x       = self._Parent._SecsKeys[sec_idx][row_idx][idx]._PosX
+        y       = self._Parent._SecsKeys[sec_idx][row_idx][idx]._PosY
+        w       = self._Parent._SecsKeys[sec_idx][row_idx][idx]._Width
+        h       = self._Parent._SecsKeys[sec_idx][row_idx][idx]._Height
+
+        rect    = midRect(x,y,w,h,self._Parent._Width,self._Parent._Height)
+        if rect.width <=0 or rect.height <= 0 :
+            return
+
+        pygame.draw.rect(self._Parent._CanvasHWND,(0,0,0),rect,1)
+
+class Keyboard(Page):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 0
+    _SectionNumbers = 3
+    _SectionIndex = 1
+
+    _Icons = {}
+    _Secs = {}
+    _SecsKeys = {}
+    _KeyboardLayoutFile = "UI/keyboard_keys.layout"
+    _Textarea = None
+    _Selector = None
+    _LeftOrRight = 1
+    _FootMsg           = ["Nav.","ABC","Done","Backspace","Enter"]
+
+    _RowIndex    = 0
+    
+    def __init__(self):
+        self._Secs     = {}
+        self._SecsKeys = {}
+        self._Icons    = {}
+
+    def ReadLayoutFile(self,fname):
+        LayoutIndex = 0
+        with open(fname) as f:
+            content = f.readlines()
+
+        content = [ x.strip() for x in content]
+        content = [ x.split(" ") for x in content]
+
+        for i in content:
+            i = [ x.strip() for x in i]
+            if len(i) > 2:
+                if LayoutIndex in self._Secs:
+                    self._Secs[LayoutIndex].append(i)
+                else:
+                    self._Secs[LayoutIndex] = []
+                    self._Secs[LayoutIndex].append(i)
+            else:
+                LayoutIndex+=1
+
+    def SetPassword(self,pwd):
+        
+        pwd_list = list(pwd)
+        self._Textarea.ResetMyWords()
+        for i in pwd_list:
+            self._Textarea.AppendText(i)
+            #self._Textarea.BlitText()
+        
+    def Init(self):
+        self._CanvasHWND = self._Screen._CanvasHWND
+        self.ReadLayoutFile(self._KeyboardLayoutFile) ## assign to _Secs
+        self._SectionNumbers = len(self._Secs)
+        self._PosX = self._Index*self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+        
+        fontobj = fonts["veramono24"]
+        word_margin = 15
+
+        start_x = (self._Width - fontobj.size( "".join(self._Secs[0][0]))[0]-len(self._Secs[0][0])*word_margin)/2+word_margin/2
+        start_y = 0
+        cnt = 0
+        for i in range(0,self._SectionNumbers):
+            self._SecsKeys[i] = []
+            for j in range(0,len(self._Secs[i])):
+                self._SecsKeys[i].append( [] )
+                
+                start_x = (self._Width - fontobj.size( "".join(self._Secs[i][j]))[0]-len(self._Secs[i][j])*word_margin)/2+word_margin/2
+                start_x = start_x + i*Width
+                start_y = 84+j*(word_margin+14)
+                for idx,val in enumerate(self._Secs[i][j]):
+                    ti = TextItem()
+                    ti._FontObj = fontobj
+                    ti._Parent = self
+
+                    if val == "_L" or val == "_R":
+                        it  = KeyboardIcon()
+                        it._ImgSurf = preload.ICONS_PRELOAD[val]
+                        it._Parent = self
+                        it._Str = val
+                        it.Init(start_x+it._ImgSurf.get_width()/2  ,start_y,it._ImgSurf.get_width(),it._ImgSurf.get_height(),0)
+                        #self._Icons[val] = it
+                        self._SecsKeys[i][j].append(it)
+                        self._IconNumbers+=1
+                        start_x = start_x + it._ImgSurf.get_width()+word_margin
+                        
+                    else:
+                        if val == "_S":
+                            val = "Space"
+                            ti._FontObj = fonts["veramono15"]
+                            ti._Bold = True
+                        
+                        cur_alpha_size  = ti._FontObj.size( val)
+                        ti.Init(start_x + cur_alpha_size[0]/2,start_y,cur_alpha_size[0],cur_alpha_size[1],0)
+                        ti._Str = val
+                    
+                        start_x = start_x + cur_alpha_size[0]+word_margin # prepare for next alpha
+                        self._SecsKeys[i][j].append(ti)
+    
+        self._SectionIndex = 0
+
+        self._Textarea = Textarea()
+        
+        self._Textarea._PosX = 4
+        self._Textarea._PosY = 4
+        self._Textarea._Width= self._Width - 4*2
+        self._Textarea._Height = 60
+        self._Textarea._CanvasHWND = self._CanvasHWND
+        self._Textarea.Init()
+
+
+        ps = KeyboardSelector()
+        ps._Parent = self
+        ps.Init(start_x,start_y,25,25,128)
+        self._Ps = ps
+        self._PsIndex = 0
+        self._Ps._OnShow = True
+
+    def SelectUpChar(self):
+        sec_idx = self._SectionIndex
+        self._RowIndex-=1
+        if self._RowIndex <0:
+            self._RowIndex = len(self._SecsKeys[sec_idx])-1
+
+        if self._PsIndex >=len(self._SecsKeys[sec_idx][self._RowIndex]):
+            self._PsIndex = len(self._SecsKeys[sec_idx][self._RowIndex])-1
+
+
+        self.ClearCanvas()
+        self.Draw()
+        self._Screen.SwapAndShow()
+            
+    def SelectDownChar(self):
+        sec_idx = self._SectionIndex
+        self._RowIndex+=1
+        if self._RowIndex >= len(self._SecsKeys[sec_idx]):
+            self._RowIndex = 0
+
+        if self._PsIndex >=len(self._SecsKeys[sec_idx][self._RowIndex]):
+            self._PsIndex = len(self._SecsKeys[sec_idx][self._RowIndex])-1
+
+        self.ClearCanvas()
+        self.Draw()
+        self._Screen.SwapAndShow()
+        
+    def SelectNextChar(self):
+        sec_idx = self._SectionIndex
+        row_idx = self._RowIndex
+        self._PsIndex+=1
+        if self._PsIndex >= len(self._SecsKeys[sec_idx][row_idx]):
+            self._PsIndex = 0
+            self._RowIndex+=1
+            if self._RowIndex >= len(self._SecsKeys[sec_idx]):
+                self._RowIndex = 0
+        
+        self.ClearCanvas()
+        self.Draw()
+        self._Screen.SwapAndShow()
+
+    def SelectPrevChar(self):
+        sec_idx = self._SectionIndex    
+        self._PsIndex-=1
+        if self._PsIndex < 0:
+            self._RowIndex-=1
+            if self._RowIndex <=0:
+                self._RowIndex = len(self._SecsKeys[sec_idx])-1
+            self._PsIndex = len(self._SecsKeys[sec_idx][self._RowIndex]) -1
+
+        self.ClearCanvas()
+        self.Draw()
+        self._Screen.SwapAndShow()
+      
+    def ClickOnChar(self):
+        sec_idx = self._SectionIndex        
+        alphabet = self._SecsKeys[sec_idx][self._RowIndex][self._PsIndex]._Str
+
+        if alphabet == "Space":
+            alphabet = " "
+        
+        if alphabet == "_L" or alphabet == "_R":
+            if alphabet == "_L":
+                self._Textarea.SubTextIndex()
+            elif alphabet == "_R":
+                self._Textarea.AddTextIndex()
+        else:
+            self._Textarea.AppendText(alphabet)
+        
+        self._Textarea.Draw()
+        self._Screen.SwapAndShow()
+
+
+    def KeyboardShift(self):
+        current_time = 0.0
+        start_posx   = 0.0
+        current_posx = start_posx
+        final_posx   = 320.0
+        posx_init    = 0.0
+        dur          = 30
+        last_posx    = 0.0 
+        all_last_posx = []
+
+        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:
+            for j in range(0,self._SectionNumbers):
+                for u in self._SecsKeys[j]:
+                    for x in u: 
+                        x._PosX += self._LeftOrRight*i
+            
+            self.ResetPageSelector()
+            self.ClearCanvas()
+            self.Draw()
+            self._Screen.SwapAndShow()
+        
+    def KeyDown(self,event):# event from pygame.event.get()
+        if event.key == CurKeys["Up"]:
+            self.SelectUpChar()
+        if event.key == CurKeys["Down"]:
+            self.SelectDownChar()
+        if event.key == CurKeys["Right"]:
+            self.SelectNextChar()
+        if event.key == CurKeys["Left"]:
+            self.SelectPrevChar()
+        if event.key == CurKeys["B"] or event.key == CurKeys["Enter"]:
+            self.ClickOnChar()
+        if event.key == CurKeys["X"]:
+            if self._SectionIndex <= 0:
+                self._LeftOrRight = -1
+            if self._SectionIndex >= (self._SectionNumbers -1):
+                self._LeftOrRight = 1
+            self.KeyboardShift()
+
+            self._SectionIndex -= self._LeftOrRight
+
+            #print(self._SectionIndex) # on which keyboard section now
+            self.Draw()
+            self._Screen.SwapAndShow()
+        
+        if event.key == CurKeys["Menu"]: # we assume keyboard always be child page
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+        if event.key == CurKeys["Y"]: #done 
+            print("".join(self._Textarea._MyWords))
+            self.ReturnToUpLevelPage()
+            self._Screen.SwapAndShow()
+            ## config and connect now
+            myvars.ScanPage.ConfigWireless( "".join(self._Textarea._MyWords)) 
+
+        if event.key == CurKeys["A"]:
+            self._Textarea.RemoveFromLastText()
+            self._Textarea.Draw()
+            self._Screen.SwapAndShow()
+
+    def Draw(self):
+        self.ClearCanvas()
+        for i in range(0,self._SectionNumbers):
+            for j in self._SecsKeys[i]:
+                for u in j:
+                    u.Draw()
+
+        
+        self._Textarea.Draw()
+        self._Ps.Draw()
+
+

+ 5 - 0
Menu/GameShell/10_Settings/Wifi/myvars.py

@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*- 
+
+
+ScanPage = None
+PasswordPage = None

+ 199 - 0
Menu/GameShell/10_Settings/Wifi/net_item.py

@@ -0,0 +1,199 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+## local UI import
+from UI.page   import Page
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.icon_item import IconItem
+from UI.multi_icon_item  import MultiIconItem
+
+from icons  import preload
+
+class NetItemMultiIcon(MultiIconItem):
+    _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),
+                              (0,self._IconIndex*self._IconHeight,self._IconWidth,self._IconHeight))
+    
+class NetItemIcon(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 NetItem(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 30
+
+    _Bssid=""    # 50:3A:A0:51:18:3C
+    _Essid=""    # MERCURY_EB88
+
+    ## extra infomations
+    _dhcphostname = "GameShell"
+    _ip   = None      #eg 192.168.31.141
+    _dns_domain = None
+    _gateway    = None  #eg 192.168.31.1
+    _use_global_dns = 0 ## eg 0 == False, 1 == True
+    _netmask    = None ##eg 255.255.255.0
+    _usedhcphostname= 0
+    _bitrate = "auto"
+    _allow_lower_bitrates = 0
+    _dns3 = None
+    _dns2 = None  ## eg 1.1.1.1
+    _dns1 = None  ## eg 8.8.8.8
+    _use_settings_globally = 0 
+    _use_static_dns = 0 # eg: 1 == True
+    _search_domain = None
+    
+    _Encrypt=""  # WPA2
+    _Channel=""  # '10' 
+    _Stren = ""  ## 19%
+    _NetId    = 0   ##  0-n
+    _Mode  = ""  ## Master or AdHoc
+    _Parent = None
+    _IsActive = False
+
+    _Icons  = {} ## wifi strength and security icons
+    _Labels = {}
+    _FontObj = None
+    
+    def __init__(self):
+        self._Labels = {}
+        self._Icons = {}
+
+    def SetActive(self,act):
+        self._IsActive = act
+    
+    def UpdateStrenLabel(self, strenstr): ## strenstr should be 'number',eg:'90'
+        self._Stren = self._Parent._Daemon.FormatSignalForPrinting(strenstr) 
+        self._Labels["stren"]._Text = self._Stren
+
+    def Init(self, i, is_active):
+        # Pick which strength measure to use based on what the daemon says
+        # gap allocates more space to the first module
+        if self._Parent._Daemon.GetSignalDisplayType() == 0:
+            strenstr = 'quality'
+            gap = 4  # Allow for 100%
+        else:
+            strenstr = 'strength'
+            gap = 7  # -XX dbm = 7
+        self._NetId = i
+        # All of that network property stuff
+        self._Stren = self._Parent._Daemon.FormatSignalForPrinting(
+                str(self._Parent._Wireless.GetWirelessProperty(self._NetId, strenstr)))
+        
+        self._Essid = self._Parent._Wireless.GetWirelessProperty(self._NetId, 'essid')
+        self._Bssid = self._Parent._Wireless.GetWirelessProperty(self._NetId, 'bssid')
+
+        if self._Parent._Wireless.GetWirelessProperty(self._NetId, 'encryption'):
+            self._Encrypt = \
+                self._Parent._Wireless.GetWirelessProperty(self._NetId, 'encryption_method')
+        else:
+            self._Encrypt = 'Unsecured'
+
+        self._Mode = \
+            self._Parent._Wireless.GetWirelessProperty(self._NetId, 'mode')  # Master, Ad-Hoc
+        self._Channel = self._Parent._Wireless.GetWirelessProperty(self._NetId, 'channel')
+        theString = '  %-*s %25s %9s %17s %6s %4s' % \
+            (gap, self._Stren, self._Essid, self._Encrypt, self._Bssid, self._Mode,
+                self._Channel)
+        
+        if is_active:
+            theString = ">> "+theString[1:]
+            self.SetActive(is_active)
+        
+
+
+        essid_label = Label()
+        essid_label._PosX = 36
+        #essid_label._PosY = self._PosY +  (self._Height - self._FontObj.render(self._Essid,True,(83,83,83)).get_height())/2
+        essid_label._CanvasHWND = self._Parent._CanvasHWND
+
+        if len(self._Essid) > 19:
+            essid_ = self._Essid[:20]
+        else:
+            essid_ = self._Essid
+        
+        essid_label.Init(essid_,self._FontObj)
+        self._Labels["essid"] = essid_label
+
+        stren_label = Label()
+        #stren_label._PosY = self._PosY +  (self._Height - self._FontObj.render(self._Stren,True,(83,83,83)).get_height())/2
+        stren_label._CanvasHWND = self._Parent._CanvasHWND
+
+        stren_label.Init(self._Stren,self._FontObj)
+        stren_label._PosX = self._Width - 23 - stren_label.Width() - 2
+        self._Labels["stren"] = stren_label
+        
+
+        lock_icon = NetItemIcon()
+        lock_icon._ImgSurf = preload.ICONS_PRELOAD["lock"]
+        lock_icon._CanvasHWND = self._Parent._CanvasHWND
+        lock_icon._Parent = self
+        self._Icons["lock"] = lock_icon
+        
+        done_icon = NetItemIcon()
+        done_icon._ImgSurf = preload.ICONS_PRELOAD["done"]
+        done_icon._CanvasHWND = self._Parent._CanvasHWND
+        done_icon._Parent = self
+        
+        self._Icons["done"] = done_icon
+
+
+        ## reuse the resource from TitleBar
+        nimt = NetItemMultiIcon()
+        nimt._ImgSurf = self._Parent._Screen._TitleBar._Icons["wifistatus"]._ImgSurf
+        nimt._CanvasHWND = self._Parent._CanvasHWND
+        nimt._Parent = self
+        self._Icons["wifistatus"] = nimt
+
+        #pp(theString)
+    
+    
+    def Connect(self,notworkentry=None):
+        """ Execute connection. """
+        self._Parent._Wireless.ConnectWireless(self._NetId)
+
+    
+    def Draw(self):
+        #pygame.draw.line(self._Parent._CanvasHWND,(169,169,169),(self._PosX,self._PosY),(self._PosX+self._Width,self._PosY),1)        
+        for i in self._Labels:
+            self._Labels[i]._PosY = self._PosY + (self._Height - self._Labels[i]._Height)/2
+            self._Labels[i].Draw()
+            
+        if self._IsActive:
+            self._Icons["done"].NewCoord(14,self._PosY)
+            self._Icons["done"].Draw()
+
+        if self._Encrypt != "Unsecured":
+            self._Icons["lock"].NewCoord( self._Width -23 - self._Labels["stren"].Width() - 2 - 18, self._PosY)
+            self._Icons["lock"].Draw()
+        
+        ge = self._Parent._Screen._TitleBar.GetWifiStrength( self._Stren.replace('%',''))
+        
+        if ge > 0:
+            self._Icons["wifistatus"]._IconIndex = ge
+            self._Icons["wifistatus"].NewCoord(self._Width-23,self._PosY)
+            self._Icons["wifistatus"].Draw()
+            
+        else:
+            self._Icons["wifistatus"]._IconIndex = 0
+            self._Icons["wifistatus"].NewCoord(self._Width-23,self._PosY)
+            self._Icons["wifistatus"].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)        
+        
+

+ 61 - 0
Menu/GameShell/10_Settings/Wifi/pages.py

@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*- 
+
+
+#import dbus
+#import dbus.service
+#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
+
+
+## local UI import
+from libs.DBUS      import bus,daemon,wireless,wired
+
+from keyboard import Keyboard
+from wifi_list import WifiList
+
+import myvars
+
+
+def InitScanPage(main_screen):
+    global wireless
+    global daemon
+    global bus
+    
+    myvars.ScanPage = WifiList()
+    myvars.ScanPage._Name = "Scan wifi"
+   
+    myvars.ScanPage._Wireless = wireless
+    myvars.ScanPage._Daemon = daemon
+    myvars.ScanPage._Dbus = bus
+   
+
+    myvars.ScanPage._Screen = main_screen
+    myvars.ScanPage.Init()
+
+
+    if daemon != None:
+        #Bind signals
+        myvars.ScanPage._Dbus.add_signal_receiver(myvars.ScanPage.DbusScanFinishedSig, 'SendEndScanSignal',
+                                                  'org.wicd.daemon.wireless')
+        myvars.ScanPage._Dbus.add_signal_receiver(myvars.ScanPage.DbusScanStarted, 'SendStartScanSignal',
+                                                  'org.wicd.daemon.wireless')
+        #
+        myvars.ScanPage._Dbus.add_signal_receiver(myvars.ScanPage.DbusDaemonStatusChangedSig, 'StatusChanged',
+                                                  'org.wicd.daemon')
+        myvars.ScanPage._Dbus.add_signal_receiver(myvars.ScanPage.DbusConnectResultsSent, 'ConnectResultsSent',
+                                                  'org.wicd.daemon')
+
+def InitPasswordPage(main_screen):
+
+    myvars.PasswordPage = Keyboard()
+    myvars.PasswordPage._Name = "Enter wifi password"
+
+    myvars.PasswordPage._Screen = main_screen
+    myvars.PasswordPage.Init()
+

+ 28 - 0
Menu/GameShell/10_Settings/Wifi/text_item.py

@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*- 
+#local import
+from UI.constants import Width,Height,ICON_TYPES
+from UI.icon_item import IconItem
+from UI.util_funcs import midRect
+
+class TextItem(IconItem):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 0
+    _Str    = ""
+    _Color = (83,83,83)
+    _FontObj = None
+    _Bold    = False
+    _MyType  = ICON_TYPES["LETTER"] 
+    _Parent  = None
+
+    def Draw(self):
+        self._FontObj.set_bold(self._Bold)
+        my_text = self._FontObj.render(self._Str,True,self._Color)
+        if my_text.get_width() != self._Width:
+            self._Width = my_text.get_width()
+        if my_text.get_height() != self._Height:
+            self._Height = my_text.get_height()
+
+        self._Parent._CanvasHWND.blit(my_text, \
+            midRect(self._PosX,self._PosY,self._Width,self._Height,Width,Height))

+ 133 - 0
Menu/GameShell/10_Settings/Wifi/textarea.py

@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from libs.roundrects import aa_round_rect
+
+
+
+
+## local UI import
+from UI.page         import Page,PageStack,PageSelector
+from UI.label        import Label
+from UI.fonts        import fonts
+
+class Textarea:
+    _PosX =0 
+    _PosY = 0
+    _Width = 0
+    _Height = 0
+    _BackgroundColor = pygame.Color(229,229,229)
+    _CanvasHWND  = None
+    _MyWords     = []
+    _FontObj     = None
+    _LineNumber  = 0
+    _TextFull    = False
+    _TextIndex   = 0
+
+    def __init__(self):
+        pass
+    
+    def Init(self):
+        self._FontObj = fonts["veramono24"] 
+        #pygame.font.Font(fonts_path["veramono"],24)
+
+    def SubTextIndex(self):
+
+        self._TextIndex-=1
+        if self._TextIndex < 0:
+            self._TextIndex = 0
+
+    def AddTextIndex(self):
+        self._TextIndex +=1
+        if self._TextIndex > len(self._MyWords):
+            self._TextIndex = len(self._MyWords)
+        
+    def ResetMyWords(self):
+        self._MyWords = []
+        self._TextIndex = 0
+        
+    def RemoveFromLastText(self):
+        if len(self._MyWords) > 0:
+            self.SubTextIndex()
+            
+            del self._MyWords[self._TextIndex]
+            
+            return self._MyWords
+
+    def AppendText(self,alphabet):
+        
+        self.AppendAndBlitText(alphabet)
+
+    def AppendAndBlitText(self,alphabet):
+        
+        if self._TextFull != True:
+            
+            self._MyWords.insert(self._TextIndex,alphabet)
+            self.BlitText()
+            self.AddTextIndex()
+        else:
+            print("is Full %s" % "".join(self._MyWords))
+
+            
+    def BlitText(self):
+        """
+        blit every single word into surface and calc the width ,check multi line 
+        """
+        w = 0
+        xmargin = 5
+        endmargin = 15
+        x = self._PosX+xmargin
+        y = self._PosY
+        linenumber = 0
+        self._TextFull = False
+        for i,v in enumerate(self._MyWords):
+            t = self._FontObj.render(v,True,(8,135,174))
+            w += t.get_width()
+
+            if w >= self._Width-endmargin and linenumber == 0:
+                x = self._PosX+xmargin
+                y = self._PosY+ t.get_height()
+                w = 0
+                linenumber +=1
+            
+            if w >= self._Width-endmargin*4 and linenumber > 0:
+                self._TextFull = True
+                self._CanvasHWND.blit(t, (x,y))
+                break
+            self._CanvasHWND.blit(t, (x,y))
+            x += t.get_width()
+        
+    def Cursor(self):
+        w = 0
+        xmargin = 5
+        endmargin = 15
+        x = self._PosX+xmargin
+        y = self._PosY
+        linenumber = 0
+        for i,v in enumerate(self._MyWords[:self._TextIndex]):
+            t = self._FontObj.render(v,True,(8,135,174))
+            w += t.get_width()
+
+            if w >= self._Width-endmargin and linenumber == 0:
+                x = self._PosX+xmargin
+                y = self._PosY+ t.get_height()
+                w = 0
+                linenumber +=1
+            
+            if w >= self._Width-endmargin*3 and linenumber > 0:
+                x += t.get_width()
+                break
+            x += t.get_width()
+            
+        self._CanvasHWND.blit(self._FontObj.render("_",True,(0,0,0)),(x+1,y-2))
+    
+    def Draw(self):
+        #aa_round_rect(self._CanvasHWND, (4,24.5+6,312,60),self._BackgroundColor,4,0,self._BackgroundColor)
+
+        aa_round_rect(self._CanvasHWND,  
+                    (self._PosX,self._PosY,self._Width,self._Height),self._BackgroundColor,4,0,self._BackgroundColor)
+
+
+        
+        self.BlitText()
+        self.Cursor()

+ 820 - 0
Menu/GameShell/10_Settings/Wifi/wifi_list.py

@@ -0,0 +1,820 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+from beeprint import pp
+from libs.roundrects import aa_round_rect
+import gobject
+from wicd import misc 
+## local UI import
+from UI.constants import Width,Height
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect,SwapAndShow
+from UI.keys_def   import CurKeys
+from UI.scroller   import ListScroller
+from UI.confirm_page import ConfirmPage
+
+from net_item import NetItem
+
+import myvars
+
+
+class InfoPageListItem(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 30
+
+    _Labels = {}
+    _Icons  = {}
+    _Fonts  = {}
+
+    _LinkObj = None
+    
+    def __init__(self):
+        self._Labels = {}
+        self._Icons  = {}
+        self._Fonts  = {}
+
+    def SetSmallText(self,text):
+        
+        l = Label()
+        l._PosX = 40
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+        l.Init(text,self._Fonts["small"])
+        self._Labels["Small"] = l
+        
+    def Init(self,text):
+
+        #self._Fonts["normal"] = fonts["veramono12"]
+        
+        l = Label()
+        l._PosX = 10
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+
+        l.Init(text,self._Fonts["normal"])
+        self._Labels["Text"] = l
+
+    def Draw(self):
+        
+        self._Labels["Text"]._PosY = self._PosY + (self._Height - self._Labels["Text"]._Height)/2
+        self._Labels["Text"].Draw()
+
+        if "Small" in self._Labels:
+            self._Labels["Small"]._PosX = self._Width - self._Labels["Small"]._Width-5
+            
+            self._Labels["Small"]._PosY = self._PosY + (self._Height - self._Labels["Small"]._Height)/2
+            self._Labels["Small"].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)
+    
+
+
+class WifiDisconnectConfirmPage(ConfirmPage):
+
+    _ConfirmText = "Confirm Disconnect?"
+    
+    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"]:
+            self.SnapMsg("Disconnecting...")
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+            self._Parent._Daemon.Disconnect()
+            
+            pygame.time.delay(400)
+            
+            self.ReturnToUpLevelPage()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+                    
+    def Draw(self):
+        #self.ClearCanvas()
+        self.DrawBG()
+        for i in self._MyList:
+            i.Draw()
+        
+        self.Reset()
+        
+class WifiInfoPageSelector(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):
+            x = 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 WifiInfoPage(Page):
+    _FootMsg =  ["Nav.","Disconnect","","Back",""]
+    _MyList = []
+    _ListFontObj = fonts["varela15"]
+
+    _Wireless = None
+    _Daemon   = None
+    
+    _AList = {}
+    _NetworkId = -1
+    
+    def GenList(self):
+        
+        self._MyList = []
+        if self._NetworkId != -1:
+            self._AList["ip"]["value"] = "Not Connected"
+            
+            if self._Wireless.GetCurrentNetworkID(self._Wireless.GetIwconfig()) == self._NetworkId:
+                ip = self._Wireless.GetWirelessIP('')
+            
+                if ip is not None:
+                    self._AList["ip"]["value"] = ip
+            
+            self._AList["bssid"]["value"] = self._Wireless.GetWirelessProperty(self._NetworkId,"bssid")
+        
+        start_x  = 0
+        start_y  = 0
+        
+        for i,v in enumerate( self._AList):
+            li = InfoPageListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y + i*InfoPageListItem._Height
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFontObj
+            li._Fonts["small"] = fonts["varela12"]
+            
+            if self._AList[v]["label"] != "":
+                li.Init(  self._AList[v]["label"] )
+            else:
+                li.Init( self._AList[v]["key"] )
+
+            li._Flag = self._AList[v]["key"]
+
+            li.SetSmallText( self._AList[v]["value"] )
+            
+            self._MyList.append(li)
+            
+    def Init(self):
+        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
+
+        ps = WifiInfoPageSelector()
+        ps._Parent = self
+        self._Ps = ps
+        self._PsIndex = 0
+
+        ip = {}
+        ip["key"] = "ip"
+        ip["label"] = "IP"
+        ip["value"] = "Not Connected"
+        
+        bssid = {}
+        bssid["key"] = "bssid"
+        bssid["label"] = "BSSID"
+        bssid["value"] = ""
+        
+        self._AList["ip"] = ip
+        self._AList["bssid"] = bssid
+        
+        self.GenList()
+
+        self._DisconnectConfirmPage = WifiDisconnectConfirmPage()
+        self._DisconnectConfirmPage._Screen = self._Screen
+        self._DisconnectConfirmPage._Name   = "Confirm Disconnect"
+        self._DisconnectConfirmPage._Parent = self
+        self._DisconnectConfirmPage.Init()
+        
+    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
+        
+
+    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
+
+    def Click(self):
+        cur_li = self._MyList[self._PsIndex]
+        print(cur_li._Flag)        
+
+    def TryDisconnect(self):
+        if self._Wireless.GetCurrentNetworkID(self._Wireless.GetIwconfig()) == self._NetworkId \
+           and self._Wireless.GetWirelessIP('') is not None:
+            self._Screen.PushPage(self._DisconnectConfirmPage)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        else:
+            return
+        
+    def OnLoadCb(self):
+        if self._Wireless.GetCurrentNetworkID(self._Wireless.GetIwconfig()) == self._NetworkId \
+           and self._Wireless.GetWirelessIP('') is not None:
+            self._FootMsg[1] = "Disconnect"
+        else:
+            self._FootMsg[1] =  ""
+
+        self.GenList()
+
+    def OnReturnBackCb(self):
+        self.ReturnToUpLevelPage()
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        
+    def KeyDown(self,event):
+        if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]:
+            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"]:
+            self.TryDisconnect()
+                                
+    def Draw(self):
+        self.ClearCanvas()
+        self._Ps.Draw()
+
+        for i in self._MyList:
+            i.Draw()
+
+
+        
+    
+class WifiListSelector(PageSelector):
+    _BackgroundColor = pygame.Color(131,199,219)
+
+    def __init__(self):
+        self._PosX = 0
+        self._PosY = 0
+        self._Height = 0
+
+    def AnimateDraw(self,x2,y2):
+        pass 
+
+
+    def Draw(self):
+        idx = self._Parent._PsIndex
+        if idx < len( self._Parent._WirelessList):
+            x = self._Parent._WirelessList[idx]._PosX+11
+            y = self._Parent._WirelessList[idx]._PosY+1
+            h = self._Parent._WirelessList[idx]._Height -3
+        
+            self._PosX = x
+            self._PosY = y
+            self._Height = h
+
+            aa_round_rect(self._Parent._CanvasHWND,  
+                          (x,y,self._Width,h),self._BackgroundColor,4,0,self._BackgroundColor)
+
+
+class WifiListMessageBox(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))
+
+class WifiList(Page):
+    _WirelessList = []
+    #Wicd dbus part
+    _Wireless = None
+    _Daemon   = None
+    _Dbus     = None
+    _WifiPassword = ""
+    _Connecting = False
+    _Scanning   = False 
+    
+    _PrevWicdState = None
+    
+    _Selector = None
+    
+    _ShowingMessageBox = False 
+    _MsgBox            = None
+    _ConnectTry        = 0
+    _BlockingUI        = False
+    _BlockCb           = None
+    
+    _LastStatusMsg     = ""
+    _FootMsg           = ["Nav.","Scan","Info","Back","Enter"]
+    _EncMethods        = None
+    _Scroller          = None
+    _ListFontObj       = fonts["notosanscjk15"]
+
+    _InfoPage          = None
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._WirelessList = []
+        self._CanvasHWND = None
+    
+    def ShowBox(self,msg):
+        self._MsgBox._Text = msg
+        self._ShowingMessageBox = True
+        self._Screen.Draw()
+        self._MsgBox.Draw()
+        self._Screen.SwapAndShow()
+    
+    def HideBox(self):
+        self.Draw()
+        self._ShowingMessageBox = False
+        self._Screen.SwapAndShow()
+
+    def GenNetworkList(self):
+        self._WirelessList = []
+        start_x = 0
+        start_y = 0
+
+        for network_id in range(0,self._Wireless.GetNumberOfNetworks()):
+            is_active = \
+                self._Wireless.GetCurrentSignalStrength("") != 0 and \
+                self._Wireless.GetCurrentNetworkID(self._Wireless.GetIwconfig()) == network_id \
+                and self._Wireless.GetWirelessIP('') is not None
+
+            ni = NetItem()
+            ni._Parent = self
+            ni._PosX = start_x
+            ni._PosY = start_y + network_id* NetItem._Height
+            ni._Width = Width
+            ni._FontObj = self._ListFontObj
+            #ni._Bssid   = self._Wireless.GetWirelessProperty(network_id,"bssid")
+            
+            ni.Init(network_id,is_active)
+            self._WirelessList.append(ni)
+
+        self._PsIndex = 0
+        
+    def Disconnect(self):
+        self._Connecting= False
+        self._Daemon.Disconnect()
+    ## force to disconnect
+    def ShutDownConnecting(self):
+        print("Shutdownconnecting...",self._ConnectTry)
+        self._Daemon.CancelConnect()
+        self._Daemon.SetForcedDisconnect(True)
+        self._Connecting = False
+
+    def Rescan(self,sync=False):
+        print("start Rescan")
+        if self._Wireless != None:
+            self._Wireless.Scan(sync)
+
+## dbus signal functions
+    def DbusScanFinishedSig(self):
+
+        if self._Screen._CurrentPage != self:
+            return
+        self.ResetPageSelector()
+        
+        self.UpdateNetList(force_check=True)
+
+        self._Scanning = False
+        self.HideBox()
+        self._BlockingUI = False
+        print("dbus says scan finished")
+
+    def DbusScanStarted(self):
+        if self._Screen._CurrentPage !=self:
+            return
+        
+        self._Scanning = True
+        self.ShowBox("Wifi scanning...")
+        self._BlockingUI = True
+        print("dbus says start scan...")
+
+
+    def UpdateNetList(self,state=None,info=None,force_check=False,firstrun=False):
+
+        if self._Daemon == None:
+            return
+        
+        if not state:
+            state,trash = self._Daemon.GetConnectionStatus()
+            print("state")
+            pp(state)
+            print("Trash: ")
+            pp(trash)
+
+        if force_check or self._PrevWicdState != state:
+            self.GenNetworkList() ## refresh the network list 
+        
+        if info != None:
+            if len(info) > 3:
+                _id  = int(info[3])
+                if _id < len(self._WirelessList):
+                    self._WirelessList[_id].UpdateStrenLabel( str(info[2]))
+
+        self._PrevWicdState = state
+        
+    def SetConnectingStatus(self,fast):
+        wireless_connecting = self._Wireless.CheckIfWirelessConnecting()
+
+        """
+        if self._ConnectTry > 5000:
+            #wicd itself will take a very long time to try to connect ,will not block forever,just make it faster to dropout
+            self.ShutDownConnecting()
+            self._ConnectTry = 0
+            self._BlockingUI = False
+            return False
+        """
+        
+        if wireless_connecting:
+            if not fast:
+                iwconfig = self._Wireless.GetIwconfig()
+            else:
+                iwconfig = ''
+            essid = self._Wireless.GetCurrentNetwork(iwconfig)
+            stat = self._Wireless.CheckWirelessConnectingMessage()
+            if self._LastStatusMsg != "%s: %s"%(essid,stat):
+                print("%s: %s" %(essid,stat))
+                self._LastStatusMsg = "%s: %s"%(essid,stat)
+                self.ShowBox(self._LastStatusMsg)
+                
+                self._Screen._FootBar.UpdateNavText(self._LastStatusMsg)
+                SwapAndShow()
+                
+            #self._ConnectTry+=1
+
+            return True
+        else:
+            self._Connecting = False
+            return self._Connecting
+
+    def UpdateStatus(self):
+        print("UpdateStatus")
+        wireless_connecting = self._Wireless.CheckIfWirelessConnecting()
+        fast = not self._Daemon.NeedsExternalCalls()
+        
+        self._Connecting = wireless_connecting
+        
+        if self._Connecting:
+            gobject.timeout_add(250,self.SetConnectingStatus,fast)
+        else:
+            if not fast:
+                iwconfig = self._Wireless.GetIwconfig()
+            else:
+                iwconfig = ''
+
+            if self.CheckForWireless(iwconfig,self._Wireless.GetWirelessIP(''),None):
+                return True
+            else:
+                print("Not Connected")
+                return True
+
+    def DbusDaemonStatusChangedSig(self,state=None,info=None):
+        print("in DbusDaemonStatusChangedSig")
+        """
+        dbus.UInt32(2L)
+        ['192.168.31.141', 'TP-LINK4G', '88', '0', '72.2 Mb/s']
+        """
+        pp(info)
+        self.UpdateNetList(state,info)
+        if info != None:
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+
+    def DbusConnectResultsSent(self,result):
+        print(" in DbusConnectResultsSent")
+        """
+         in DbusConnectResultsSent
+        'dhcp_failed'
+        dbus says start scan...
+
+        """
+        if result != None:
+            print(result)
+            
+        self._Connecting = False
+        self._BlockingUI = False
+        if self._BlockCb != None:
+            self._BlockCb()
+            self._BlockCb = None
+
+        self._Screen._FootBar.ResetNavText()
+    
+    def CheckForWireless(self,iwconfig,wireless_ip,set_status):
+        if not wireless_ip:
+            return False
+        network = self._Wireless.GetCurrentNetwork(iwconfig)
+        if not network:
+            return False
+        network = misc.to_unicode(network)
+        if daemon.GetSignalDisplayType() == 0:
+            strength = self._Wireless.GetCurrentSignalStrength(iwconfig)
+        else:
+            strength = self._Wireless.GetCurrentDBMStrength(iwconfig)
+
+        if strength is None:
+            return False
+        strength = misc.to_unicode(self._Daemon.FormatSignalForPrinting(strength))
+        ip = misc.to_unicode(wireless_ip)
+
+        print(_('Connected to $A at $B (IP: $C)').replace
+                    ('$A', network).replace
+                    ('$B', strength).replace
+                    ('$C', ip))
+        
+        return True
+
+    def ConfigWireless(self,password):
+        netid = self._PsIndex
+        print(netid," ", password)
+        """
+        self._Wireless.SetWirelessProperty(netid,"dhcphostname","GameShell")
+        self._Wireless.SetWirelessProperty(netid,"ip","None")
+        self._Wireless.SetWirelessProperty(netid,"dns_domain","None")
+        self._Wireless.SetWirelessProperty(netid,"gateway","None")
+        self._Wireless.SetWirelessProperty(netid,"use_global_dns",0)
+        self._Wireless.SetWirelessProperty(netid,"netmask","None")
+        self._Wireless.SetWirelessProperty(netid,"usedhcphostname",0) ## set 1 to use hostname above
+        self._Wireless.SetWirelessProperty(netid,"bitrate","auto")
+        self._Wireless.SetWirelessProperty(netid,"allow_lower_bitrates",0)
+        self._Wireless.SetWirelessProperty(netid,"dns3","None")
+        self._Wireless.SetWirelessProperty(netid,"dns2","None")
+        self._Wireless.SetWirelessProperty(netid,"dns1","None")
+        self._Wireless.SetWirelessProperty(netid,"use_settings_globally",0)
+        self._Wireless.SetWirelessProperty(netid,"use_static_dns",0)
+        self._Wireless.SetWirelessProperty(netid,"search_domain","None")
+        """
+        self._Wireless.SetWirelessProperty(netid,"enctype","wpa-psk")
+        self._Wireless.SetWirelessProperty(netid,"apsk",password)
+        self._Wireless.SetWirelessProperty(netid,"automatic",1)
+
+        
+        self._WirelessList[netid].Connect()
+        print("after Connect")
+        self.UpdateStatus()
+
+    def GetWirelessEncrypt(self,network_id):
+        results = []
+        activeID = -1
+        for x,enc_type in enumerate(self._EncMethods):
+            if enc_type["type"] == self._Wireless.GetWirelessProperty(network_id,"enctype"):
+                activeID = x
+                break
+
+        if activeID == -1:
+            return results
+        
+        for type_ in ['required','optional']:
+            fields = self._EncMethods[activeID][type_]
+            for field in fields:
+                try:
+                    text = field[1].lower().replace(' ','_')
+                except KeyError:
+                    text = field[1].replace(' ','_')
+                
+                value = self._Wireless.GetWirelessProperty(network_id, field[0])
+                results.append({text:value})
+        """
+        [{'preshared_key': 'blah blah blah',},]
+
+        or nothing 
+        [{'identity': None,},{'password': None,},]
+
+        """
+        return results
+
+    def ScrollUp(self):
+        if len(self._WirelessList) == 0:
+            return
+        self._PsIndex-=1
+        if self._PsIndex < 0:
+            self._PsIndex = 0
+        
+        cur_ni = self._WirelessList[self._PsIndex]
+        if cur_ni._PosY < 0:
+            for i in range(0,len(self._WirelessList)):
+                self._WirelessList[i]._PosY += self._WirelessList[i]._Height
+            
+    def ScrollDown(self):
+        if len(self._WirelessList) == 0:
+            return
+        self._PsIndex+=1
+        if self._PsIndex >= len(self._WirelessList):
+            self._PsIndex = len(self._WirelessList) -1
+       
+        cur_ni = self._WirelessList[self._PsIndex]
+        if cur_ni._PosY + cur_ni._Height > self._Height:
+            for i in range(0,len(self._WirelessList)):
+                self._WirelessList[i]._PosY -= self._WirelessList[i]._Height
+    
+
+    def AbortedAndReturnToUpLevel(self):
+        self.HideBox()
+        self._Screen._FootBar.ResetNavText()
+        self.ReturnToUpLevelPage()
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        
+    def KeyDown(self,event):
+
+        if self._BlockingUI == True:
+            print("UI blocking ...")
+            return
+        
+        if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]:
+            if self._Wireless != None:
+                wireless_connecting = self._Wireless.CheckIfWirelessConnecting()
+                if wireless_connecting:
+                    self.ShutDownConnecting()
+                    self.ShowBox("ShutDownConnecting...")
+                    self._BlockingUI=True
+                    self._BlockCb = self.AbortedAndReturnToUpLevel
+                else:
+                    self.AbortedAndReturnToUpLevel()
+            else:
+                self.HideBox()
+                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"]: ## enter to set password,enter is B on GM
+            if len(self._WirelessList) == 0:
+                return
+            
+            wicd_wirelss_encrypt_pwd = self.GetWirelessEncrypt(self._PsIndex)
+            
+            if self._WirelessList[self._PsIndex]._IsActive:
+                self.ShowBox( self._Wireless.GetWirelessIP('')    )
+            else:
+                self._Screen.PushCurPage()
+                self._Screen.SetCurPage( myvars.PasswordPage )
+                
+                thepass = ""
+                for i in wicd_wirelss_encrypt_pwd:
+                    if "preshared_key" in i:
+                        if i["preshared_key"] != None:
+                            if len(i["preshared_key"]) > 0:
+                                thepass = i["preshared_key"]
+                                break
+                
+                myvars.PasswordPage.SetPassword(thepass)
+                self._Screen.Draw()
+                self._Screen.SwapAndShow()
+                
+                """
+                try:
+                    self._Screen.Draw()
+                    self._Screen.SwapAndShow()
+                except Exception as e: 
+                    print(e)
+                    exit(-1)
+                """
+        if event.key == CurKeys["X"]:
+            self.Rescan(False)
+            
+        if event.key == CurKeys["Y"]:
+            if len(self._WirelessList) == 0:
+                return
+
+            self._InfoPage._NetworkId = self._PsIndex
+            self._InfoPage._Wireless  = self._Wireless
+            self._InfoPage._Daemon    = self._Daemon
+            
+            self._Screen.PushPage(self._InfoPage)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+
+    def Init(self):
+        
+        self._PosX = self._Index * self._Screen._Width
+        self._Width = self._Screen._Width
+        self._Height = self._Screen._Height
+
+        #self._CanvasHWND = pygame.Surface((self._Width,self._Height))
+        self._CanvasHWND = self._Screen._CanvasHWND
+
+        ps = WifiListSelector()
+        ps._Parent = self
+        ps._Width = Width - 12
+        
+        self._Ps = ps
+        self._PsIndex = 0
+        
+        msgbox = WifiListMessageBox()
+        msgbox._CanvasHWND = self._CanvasHWND
+        msgbox.Init(" ",fonts["veramono12"])
+        msgbox._Parent = self
+        
+        self._MsgBox = msgbox 
+
+        self._EncMethods = misc.LoadEncryptionMethods() # load predefined templates from /etc/wicd/...
+
+        """
+  {
+    'fields': [],
+    'name': 'WPA 1/2 (Passphrase)',
+    'optional': [],
+    'protected': [
+      ['apsk', 'Preshared_Key'],
+    ],
+    'required': [
+      ['apsk', 'Preshared_Key'],
+    ],
+    'type': 'wpa-psk',
+  },
+        """
+        
+        self.UpdateNetList(force_check=True,firstrun=True)
+
+        self._Scroller = ListScroller()
+        self._Scroller._Parent = self
+        self._Scroller._PosX = 2
+        self._Scroller._PosY = 2
+        self._Scroller.Init()
+
+
+        self._InfoPage = WifiInfoPage()
+        self._InfoPage._Screen = self._Screen
+        self._InfoPage._Name   = "Wifi info"
+        self._InfoPage.Init()
+        
+    def Draw(self):
+        self.ClearCanvas()
+
+        if len(self._WirelessList) == 0:
+            return
+        
+        self._Ps.Draw()
+        for i in self._WirelessList:
+            i.Draw()
+
+        
+        self._Scroller.UpdateSize( len(self._WirelessList)*NetItem._Height, self._PsIndex*NetItem._Height)
+        self._Scroller.Draw()

+ 29 - 0
Menu/GameShell/10_Settings/__init__.py

@@ -0,0 +1,29 @@
+# -*- 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
+
+
+## local UI import
+import pages
+import myvars
+
+def Init(main_screen):
+    pages.InitListPage(main_screen)
+
+def API(main_screen):
+    
+    if main_screen !=None:
+        main_screen.PushCurPage()
+        main_screen.SetCurPage(myvars.ListPage)
+        main_screen.Draw()
+        main_screen.SwapAndShow()
+        

+ 59 - 0
Menu/GameShell/10_Settings/list_item.py

@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+
+
+## local UI import
+from UI.page   import Page
+from UI.label  import Label
+from UI.fonts  import fonts
+
+# a item for List
+# - - - - - - - - - - - -- 
+# | Icon  Text.....    > |
+# ------------------------
+
+import myvars # icons_path
+
+
+class ListItem(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 30
+
+    _Labels = {}
+    _Icons  = {}
+    _Fonts  = {}
+
+    _LinkObj = None
+    
+    def __init__(self):
+        self._Labels = {}
+        self._Icons  = {}
+        self._Fonts  = {}
+
+
+    
+    
+    def Init(self,text):
+
+        #self._Fonts["normal"] = fonts["veramono12"]
+        
+        l = Label()
+        l._PosX = 16
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+
+        l.Init(text,self._Fonts["normal"])
+        self._Labels["Text"] = l
+
+
+    def Draw(self):
+
+        self._Labels["Text"]._PosY = self._PosY + (self._Height - self._Labels["Text"]._Height)/2
+        self._Labels["Text"].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)
+    
+

+ 190 - 0
Menu/GameShell/10_Settings/list_page.py

@@ -0,0 +1,190 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+import sys
+
+from libs.roundrects import aa_round_rect
+
+## local UI import
+from UI.constants import Width,Height
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect
+from UI.keys_def   import CurKeys
+from UI.scroller   import ListScroller
+
+from list_item  import ListItem
+
+import myvars
+
+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):
+            x = 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 ListPage(Page):
+
+    _Icons = {}
+    _Selector=None
+    
+    _FootMsg = ["Nav","","","Back","Enter"]
+    _MyList = []
+    _ListFontObj = fonts["varela15"]
+
+    _Scroller = None
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}
+        self._CanvasHWND = None
+        self._MyList = []
+        
+    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
+
+        #                ""   pkgname, label
+        alist         = [["","Wifi","Wi-Fi"],
+                         ["","Sound","Sound Volume"],
+                         ["","Brightness","BackLight Brightness"],
+                         ["","Storage",""],
+                         ["","Update", ""],
+                         ["","About",  "About"],
+                         ["","PowerOFF","PowerOFF"]]
+
+        start_x  = 0
+        start_y  = 0
+
+        sys.path.append(myvars.basepath)# add self as import path
+        
+        for i,v in enumerate(alist):
+            li = ListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y + i*ListItem._Height
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFontObj
+
+            if v[2] != "":
+                li.Init(v[2])
+            else:
+                li.Init(v[1])
+            
+            if v[1] == "Wifi" or v[1] == "Sound" or v[1] == "Brightness" or v[1] == "Storage" or v[1] == "Update" or v[1] == "About" or v[1] == "PowerOFF":
+                li._LinkObj = __import__(v[1])
+                init_cb   = getattr(li._LinkObj,"Init",None)
+                if init_cb != None:
+                    if callable(init_cb):
+                        li._LinkObj.Init(self._Screen)
+            self._MyList.append(li)
+
+        self._Scroller = ListScroller()
+        self._Scroller._Parent = self
+        self._Scroller._PosX = self._Width - 10
+        self._Scroller._PosY = 2
+        self._Scroller.Init()
+
+    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
+        
+
+    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
+
+    def Click(self):
+        cur_li = self._MyList[self._PsIndex]
+        if cur_li._LinkObj != None:
+            api_cb = getattr(cur_li._LinkObj,"API",None)
+            if api_cb != None:
+                if callable(api_cb):
+                    cur_li._LinkObj.API(self._Screen)
+
+        
+    def KeyDown(self,event):
+        if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]:
+            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()
+            
+    def Draw(self):
+        self.ClearCanvas()
+
+        if len(self._MyList) * ListItem._Height > self._Height:
+            self._Ps._Width = self._Width - 11
+            
+            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()
+
+            

+ 12 - 0
Menu/GameShell/10_Settings/myvars.py

@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*- 
+
+from sys import exit
+import os
+import sys
+
+
+basepath = os.path.dirname(os.path.realpath(__file__))
+
+icons_path = basepath+"/icons"
+
+ListPage = None

+ 13 - 0
Menu/GameShell/10_Settings/pages.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*- 
+
+from list_page import ListPage
+
+import myvars
+
+def InitListPage(main_screen):
+
+    myvars.ListPage = ListPage()
+    
+    myvars.ListPage._Screen = main_screen
+    myvars.ListPage._Name = "Setting List"
+    myvars.ListPage.Init()

BIN
Menu/GameShell/20_Retro Games/GBA.png


+ 6 - 0
Menu/GameShell/20_Retro Games/GBA/action.config

@@ -0,0 +1,6 @@
+ROM=/home/cpi/games/GBX
+ROM_SO=/home/cpi/apps/emulators/mgba_libretro.so
+EXT=gba,gbx
+LAUNCHER=retroarch -L
+TITLE=GBA Roms
+SO_URL=http://buildbot.libretro.com/nightly/linux/armhf/latest/mgba_libretro.so.zip

BIN
Menu/GameShell/20_Retro Games/MAME.png


+ 6 - 0
Menu/GameShell/20_Retro Games/MAME/action.config

@@ -0,0 +1,6 @@
+ROM=/home/cpi/games/MAME
+ROM_SO=/home/cpi/apps/emulators/mame2003_plus_libretro.so
+EXT=zip
+LAUNCHER=retroarch -L
+TITLE=MAME Roms
+SO_URL=http://buildbot.libretro.com/nightly/linux/armhf/latest/mame2003_plus_libretro.so.zip

BIN
Menu/GameShell/20_Retro Games/NES.png


+ 7 - 0
Menu/GameShell/20_Retro Games/NES/action.config

@@ -0,0 +1,7 @@
+ROM=/home/cpi/games/NES
+ROM_SO=/home/cpi/apps/emulators/fceumm_libretro.so
+EXT=zip
+LAUNCHER=retroarch -L
+TITLE=NES Roms
+SO_URL=http://buildbot.libretro.com/nightly/linux/armhf/latest/nestopia_libretro.so.zip
+

BIN
Menu/GameShell/CaveStroy.png


+ 1 - 0
Menu/GameShell/CaveStroy.sh

@@ -0,0 +1 @@
+retroarch -L /home/cpi/apps/emulators/nxengine_libretro.so /home/cpi/games/nxengine/cavestory/data

BIN
Menu/GameShell/Music Player.png


+ 36 - 0
Menu/GameShell/Music Player/__init__.py

@@ -0,0 +1,36 @@
+# -*- 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
+
+
+## local UI import
+import pages
+import myvars
+from icons import preload
+
+def Init(main_screen):
+    pages.InitPoller()
+
+    preload.load_icons()
+    pages.InitListPage(main_screen)
+    pages.InitMusicLibPage(main_screen)
+    pages.InitSpectrumPage(main_screen)
+    
+def API(main_screen):
+    
+    if main_screen !=None:
+        main_screen.PushCurPage()
+        main_screen.SetCurPage(myvars.PlayListPage)
+        main_screen.Draw()
+        main_screen.SwapAndShow()
+
+

BIN
Menu/GameShell/Music Player/icons/done.png


+ 21 - 0
Menu/GameShell/Music Player/icons/preload.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from pygame.locals import *
+from sys import exit
+import os
+import sys
+
+from beeprint import pp
+
+ICONS_PRELOAD={}
+
+
+def load_icons():
+    basepath = os.path.dirname(os.path.realpath(__file__))
+
+    files = os.listdir(basepath)
+    for i in files:
+        if os.path.isfile(basepath+"/"+i) and i.endswith(".png"):
+            keyname = i.split(".")[0]
+            ICONS_PRELOAD[keyname] = pygame.image.load(basepath+"/"+i).convert_alpha()

+ 135 - 0
Menu/GameShell/Music Player/list_item.py

@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+from libs.roundrects import aa_round_rect
+
+## 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.....    > |
+# ------------------------
+
+import myvars # icons_path
+from icons import preload
+
+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 ListItemLabel(Label):
+
+    _ActiveColor  = pygame.Color(175,90,0)
+    _Active = False
+    def Draw(self):
+
+        self._FontObj.set_bold(self._Active)
+        
+        """
+        if self._Active == True:
+            my_text = self._FontObj.render( self._Text,True,self._ActiveColor)
+        else:
+            my_text = self._FontObj.render( self._Text,True,self._Color)
+        """
+        
+        my_text = self._FontObj.render( self._Text,True,self._Color)
+        self._CanvasHWND.blit(my_text,(self._PosX,self._PosY,self._Width,self._Height))
+
+    
+class ListItem(object):
+    _PosX = 0
+    _PosY = 0
+    _Width = 0
+    _Height = 30
+
+    _Labels = {}
+    _Icons  = {}
+    _Fonts  = {}
+    _MyType = ICON_TYPES["EXE"]
+    _LinkObj = None
+    _Path    = ""
+    _Active  = False
+    _Playing = False ## play or pause
+    _PlayingProcess = 0 # 0 - 100
+    _Parent  = None
+    
+    _ActiveBackgroundColor = pygame.Color(232,232,232)
+    
+    def __init__(self):
+        self._Labels = {}
+        self._Icons  = {}
+        self._Fonts  = {}
+
+
+    def Init(self,text):
+
+        #self._Fonts["normal"] = fonts["veramono12"]
+        
+        l = ListItemLabel()
+        l._PosX = 22
+        l.SetCanvasHWND(self._Parent._CanvasHWND)
+
+        if self._MyType == ICON_TYPES["DIR"]:
+            l.Init(text,self._Fonts["normal"])
+            self._Path = text
+        else:
+            l.Init(text,self._Fonts["normal"])
+            self._Path = text
+
+
+        self._Labels["Text"] = l
+        
+        
+    def NewCoord(self,x,y):
+        self._PosX = x
+        self._PosY = y
+
+    def Draw(self):
+
+        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()
+        
+        if self._Active == True:
+            self._Labels["Text"]._Active = True
+        else:
+            self._Labels["Text"]._Active = False
+
+        
+        self._Labels["Text"]._PosY = self._PosY + (self._Height - self._Labels["Text"]._Height)/2
+            
+        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)
+
+        if self._Playing == True:
+            self._Labels["Text"]._Active =True
+            self._Labels["Text"].Draw()
+            #_rect = midRect(10,self._PosY+15,10,10,self._Parent._Width,self._Parent._Height)
+            #aa_round_rect(self._Parent._CanvasHWND,_rect,(0,0,0),3,0,(0,0,0))
+            #pygame.draw.polygon(self._Parent._CanvasHWND, (0,0,0), [[6, self._PosY+7], [11, self._PosY+14],[6, self._PosY+21]], 2)
+            
+            if self._PlayingProcess > 0:
+                seek_posx = int(self._Width * self._PlayingProcess/100.0)
+                pygame.draw.line(self._Parent._CanvasHWND,(255,169,169),(self._PosX,self._PosY+self._Height-2),(self._PosX+seek_posx,self._PosY+self._Height-2),2)   
+
+        else:
+            self._Labels["Text"].Draw()
+

+ 260 - 0
Menu/GameShell/Music Player/mpd_spectrum_page.py

@@ -0,0 +1,260 @@
+# -*- coding: utf-8 -*- 
+
+import time
+import pygame
+
+from numpy import fromstring,ceil,abs,log10,isnan,isinf,int16
+from numpy import fft as Fft
+
+import gobject
+
+from beeprint import pp
+
+## local UI import
+from UI.constants import Width,Height
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect
+from UI.keys_def   import CurKeys
+
+from Queue import Queue, Empty
+from threading  import Thread
+
+
+
+from list_item  import ListItem
+
+import myvars
+
+class PIFI(object):
+    _MPD_FIFO = "/tmp/mpd.fifo"
+    _SAMPLE_SIZE = 256
+    _SAMPLING_RATE = 44100
+    _FIRST_SELECTED_BIN = 5
+    _NUMBER_OF_SELECTED_BINS = 10
+    _SCALE_WIDTH = Height/2 - 20
+
+    count = 0
+    average = 0
+    
+    def __init__(self):
+        self.sampleSize = self._SAMPLE_SIZE
+        self.samplingRate = self._SAMPLING_RATE
+        self.firstSelectedBin = self._FIRST_SELECTED_BIN
+        self.numberOfSelectedBins = self._NUMBER_OF_SELECTED_BINS
+        
+        # Initialization : frequency bins
+        freq = Fft.fftfreq(self.sampleSize) * self.samplingRate
+        freqR = freq[:self.sampleSize/2]
+        self.bins = freqR[self.firstSelectedBin:self.firstSelectedBin+self.numberOfSelectedBins]
+        
+        self.resetSmoothing()
+    
+    def resetSmoothing(self):
+        self.count = 0
+        self.average = 0
+        
+    def smoothOut(self, x):
+        self.count += 1
+        self.average = (self.average*self.count + x) / (self.count+1)
+        return self.average
+    
+    def scaleList(self, _list):
+        for i,x in enumerate(_list):
+            if isnan(x) or isinf(x):
+                _list[i] = 0
+
+        # Compute a simple just-above 'moving average' of maximums
+        maximum = 1.1*self.smoothOut(max( _list ))
+        if maximum == 0:
+            scaleFactor = 0.0
+        else:
+            scaleFactor = self._SCALE_WIDTH/float(maximum)
+            
+        # Compute the scaled list of values
+        scaledList = [int(x*scaleFactor) for x in _list ]
+        return scaledList
+        
+    def computeSpectrum(self, fifoFile):
+        
+        # Read PCM samples from fifo
+        rawSamples = fifoFile.read(self.sampleSize)    # will return empty lines (non-blocking)
+        if len(rawSamples) == 0:
+            print("computeSpectrum read zero")
+            return [],[]
+        else:
+            pass
+##            print("computeSpectrum %d " % len(rawSamples))
+            
+        pcm = fromstring(rawSamples, dtype=int16)
+        
+        # Normalize [-1; +1]
+        pcm = pcm / (2.**15)
+        
+        # Compute FFT
+        N = pcm.size
+        fft = Fft.fft(pcm)
+        uniquePts = ceil((N+1)/2.0)
+        fft = fft[0:int(uniquePts)]
+        
+        # Compute amplitude spectrum
+        amplitudeSpectrum = abs(fft) / float(N)
+        
+        # Compute power spectrum
+        p = amplitudeSpectrum**2
+        
+        # Multiply by two to keep same energy
+        # See explanation:
+        # https://web.archive.org/web/20120615002031/http://www.mathworks.com/support/tech-notes/1700/1702.html
+        if N % 2 > 0: 
+            # odd number of points
+            # odd nfft excludes Nyquist point
+            p[1:len(p)] = p[1:len(p)] * 2 
+        else:
+            # even number of points
+            p[1:len(p) -1] = p[1:len(p) - 1] * 2
+        
+        # Power in logarithmic scale (dB)
+        logPower = 10*log10(p)
+        
+        # Compute RMS from power
+        #rms = numpy.sqrt(numpy.sum(p))
+        #print "RMS(power):", rms
+        
+        # Select a significant range in the spectrum
+        spectrum = logPower[self.firstSelectedBin:self.firstSelectedBin+self.numberOfSelectedBins]
+            
+        # Scale the spectrum 
+        scaledSpectrum = self.scaleList(spectrum)
+        
+        return (self.bins, scaledSpectrum)
+    
+
+class MPDSpectrumPage(Page):
+
+    _Icons = {}
+    _Selector=None
+    _FootMsg = ["Nav","","","Back","Pause"]
+    _MyList = []
+    _ListFont = fonts["veramono12"]
+
+    _PIFI   =  None
+    _FiFo   = None
+    _Color  = pygame.Color(126,206,244)
+    _GobjectIntervalId = -1
+    _Queue = None
+    _KeepReading = True
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}
+        self._CanvasHWND = None
+        self._MyList = []
+        self._PIFI = PIFI()
+            
+    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.Start()
+
+        self._GobjectIntervalId = gobject.timeout_add(50,self.Playing)
+        
+    def Start(self):
+        
+        try:
+            self._FIFO = open(self._PIFI._MPD_FIFO)
+            q = Queue()
+            self._Queue = q
+            
+            t = Thread(target=self.GetSpectrum)
+            t.daemon = True # thread dies with the program
+            t.start()
+            
+        except IOError:
+            print("open %s failed"%self._PIFI._MPD_FIFO)
+            self._FIFO = None
+            return
+
+
+    def GetSpectrum(self):
+        if self._FIFO == None:
+            print("self._FIFO none")
+            return
+        
+        (bins,scaledSpectrum) = self._PIFI.computeSpectrum(self._FIFO)
+        self._Queue.put( scaledSpectrum )
+
+        self._KeepReading = False
+        
+        return ## Thread ends
+
+    def Playing(self):
+        if self._Screen.CurPage() == self:
+            if self._KeepReading == False:
+                self._KeepReading = True
+                
+                t = Thread(target=self.GetSpectrum)
+                t.daemon=True
+                t.start()
+                
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+        else:
+            
+            return False
+        
+        return True
+    
+    def OnLoadCb(self):
+
+        if self._Queue != None:
+            with self._Queue.mutex:
+                self._Queue.queue.clear()
+        
+        try:
+            if self._GobjectIntervalId != -1:
+                gobject.source_remove(self._GobjectIntervalId)
+        except:
+            pass
+        
+        self._GobjectIntervalId = gobject.timeout_add(50,self.Playing)
+
+    
+    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["Start"]:
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+        if event.key == CurKeys["Enter"]:
+            pass
+
+        
+    def Draw(self):
+        self.ClearCanvas()
+
+        bw = 10
+        spects = None
+        try:
+            spects = self._Queue.get_nowait()
+#            print("get_nowait: " , spects)
+        except Empty:
+            return
+        else: # got line
+            if len(spects) == 0:
+                return
+            w = self._Width / len(spects)
+            left_margin = (w-bw)/2
+            for i,v in enumerate(spects):
+                pygame.draw.rect(self._CanvasHWND,self._Color,(i*w+left_margin,self._Height-v,bw,v),0)
+        

+ 343 - 0
Menu/GameShell/Music Player/music_lib_list_page.py

@@ -0,0 +1,343 @@
+# -*- coding: utf-8 -*- 
+import os
+import pygame
+
+from libs.roundrects import aa_round_rect
+
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES
+from UI.page   import Page,PageSelector
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.icon_item import IconItem
+from UI.util_funcs import midRect
+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 list_item  import ListItem
+
+
+import myvars
+
+
+class MusicLibStack:
+    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:
+            return "/"
+        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
+
+    def AnimateDraw(self,x2,y2):
+        pass
+
+    def Draw(self):
+        idx = self._Parent._PsIndex
+        
+        if idx < len(self._Parent._MyList):
+            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 MusicLibListPage(Page):
+
+    _Icons = {}
+    _Selector=None
+    _FootMsg = ["Nav","Scan","","Back","Add to Playlist"]
+    _MyList = []
+    _SwapMyList = []
+    _ListFont = fonts["notosanscjk15"]
+    _MyStack = None
+
+    _Scroller = None
+    
+    _BGpng = None
+    _BGwidth = 56
+    _BGheight = 70
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}
+        self._CanvasHWND = None
+        self._MyList = []
+        self._SwapMyList = []
+        self._MyStack = MusicLibStack()
+        
+    def SyncList(self,path):
+        if myvars.Poller == None:
+            return
+        
+        alist = myvars.Poller.listfiles(path)
+        if alist == False:
+            print("listfiles return false")
+            return 
+
+        self._MyList = []
+        self._SwapMyList = []
+        
+        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"]
+                dir_base_name = os.path.basename(v["directory"])
+                li.Init(  dir_base_name )
+                li._Path = v["directory"] 
+            elif "file" in v:
+                bname = os.path.basename(v["file"])
+                li.Init( bname  )
+                li._Path = v["file"]
+                
+            else:
+                li.Init("NoName")
+            
+            self._MyList.append(li)
+
+        for i in self._MyList:
+            self._SwapMyList.append(i)
+        
+    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("/")
+
+        icon_for_list = MultiIconItem()
+        icon_for_list._ImgSurf = MyIconPool._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
+
+
+        self._BGpng = IconItem()
+        self._BGpng._ImgSurf = MyIconPool._Icons["empty"]
+        self._BGpng._MyType = ICON_TYPES["STAT"]
+        self._BGpng._Parent = self
+        self._BGpng.AddLabel("Please upload data over Wi-Fi", fonts["varela22"])
+        self._BGpng.SetLableColor(pygame.Color(204,204,204))
+        self._BGpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+
+
+        self._Scroller = ListScroller()
+        self._Scroller._Parent = self
+        self._Scroller._PosX = self._Width - 10
+        self._Scroller._PosY = 2
+        self._Scroller.Init()
+        
+
+    def ScrollUp(self,Step=1):
+        if len(self._MyList) == 0:
+            return
+        tmp = self._PsIndex
+        self._PsIndex -= Step
+        
+        if self._PsIndex < 0:
+            self._PsIndex = 0
+        dy = tmp-self._PsIndex 
+        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*dy
+        
+
+    def ScrollDown(self,Step=1):
+        if len(self._MyList) == 0:
+            return
+        tmp = self._PsIndex
+        self._PsIndex +=Step
+        if self._PsIndex >= len(self._MyList):
+            self._PsIndex = len(self._MyList) -1
+        dy = self._PsIndex - tmp
+        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*dy
+
+    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
+            myvars.Poller.addfile(cur_li._Path)
+            myvars.PlayListPage.SyncList()            
+            print("add" , cur_li._Path)
+            
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+
+    def Rescan(self):
+        self.SyncList("/")
+        self._PsIndex = 0
+        
+    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["Right"]:
+            self.ScrollDown(Step=5)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+        if event.key == CurKeys["Left"]:
+            self.ScrollUp(Step=5)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        """
+        
+        if event.key == CurKeys["X"]:
+            self.Rescan()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+                                     
+        if event.key == CurKeys["Enter"]:
+            self.Click()
+            
+    def Draw(self):
+        self.ClearCanvas()
+
+
+        """
+        start_x = 0
+        start_y = 0
+        counter = 0
+        
+        self._MyList = []
+        
+        for i,v in enumerate(self._SwapMyList):
+            if myvars.PlayListPage.InPlayList(v._Path):
+                v._Active = True
+            else:
+                v._Active = False
+
+            if v._Active == False:
+                v.NewCoord(start_x, start_y+counter* ListItem._Height)
+                counter+=1
+                self._MyList.append(v)
+        """
+
+        if len(self._MyList) == 0:
+            self._BGpng.NewCoord(self._Width/2,self._Height/2)
+            self._BGpng.Draw()
+            return
+        
+        else:
+            if len(self._MyList) * ListItem._Height > self._Height:
+                self._Ps._Width = self._Width - 11
+            
+                self._Ps.Draw()
+                for i in self._MyList:
+                    if myvars.PlayListPage.InPlayList(i._Path):
+                        i._Active = True
+                    else:
+                        i._Active = False
+                    
+                    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:
+                    if myvars.PlayListPage.InPlayList(i._Path):
+                        i._Active = True
+                    else:
+                        i._Active = False
+                    
+                    i.Draw()    

+ 8 - 0
Menu/GameShell/Music Player/myvars.py

@@ -0,0 +1,8 @@
+
+
+Poller = None # MPD Poller
+PlayListPage = None
+MusicLibListPage = None
+
+SpectrumPage = None
+

+ 38 - 0
Menu/GameShell/Music Player/pages.py

@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*- 
+
+from libs.MPD import poller
+
+from play_list_page      import PlayListPage
+from music_lib_list_page import MusicLibListPage
+from mpd_spectrum_page   import MPDSpectrumPage
+import myvars
+
+from config import MPD_socket
+
+def InitPoller():
+    try:
+        myvars.Poller = poller.MPDPoller(host=MPD_socket)
+        myvars.Poller.connect()
+    except:
+        myvars.Poller = None
+        
+
+def InitMusicLibPage(main_screen):
+    myvars.MusicLibListPage = MusicLibListPage()
+    myvars.MusicLibListPage._Screen = main_screen
+    myvars.MusicLibListPage._Name   = "Music Library"
+    myvars.MusicLibListPage.Init()
+
+def InitListPage(main_screen):
+
+    myvars.PlayListPage = PlayListPage()
+    
+    myvars.PlayListPage._Screen = main_screen
+    myvars.PlayListPage._Name = "Music List"
+    myvars.PlayListPage.Init()
+
+def InitSpectrumPage(main_screen):
+    myvars.SpectrumPage = MPDSpectrumPage()
+    myvars.SpectrumPage._Screen = main_screen
+    myvars.SpectrumPage._Name   = "Spectrum"
+    myvars.SpectrumPage.Init()

+ 279 - 0
Menu/GameShell/Music Player/play_list_page.py

@@ -0,0 +1,279 @@
+# -*- coding: utf-8 -*- 
+import os
+import pygame
+import gobject
+
+from libs.roundrects import aa_round_rect
+
+## local UI import
+from UI.constants import Width,Height,ICON_TYPES
+from UI.page   import Page,PageSelector
+from UI.icon_item import IconItem
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.util_funcs import midRect
+from UI.keys_def   import CurKeys
+from UI.icon_pool  import MyIconPool
+
+from UI.scroller   import ListScroller
+
+from list_item  import ListItem
+
+import myvars
+
+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 PlayListPage(Page):
+
+    _Icons = {}
+    _Selector=None
+    _FootMsg = ["Nav","","Remove","Back","Play/Pause"]
+    _MyList = []
+    _ListFont = fonts["notosanscjk15"]
+
+    _Scroller = None
+    
+    _BGpng  = None
+    _BGwidth = 75
+    _BGheight = 70
+    
+    def __init__(self):
+        self._Icons = {}
+        Page.__init__(self)
+        self._CanvasHWND = None
+        self._MyList = []
+
+    def SyncList(self):
+        self._MyList = []
+        start_x  = 0
+        start_y  = 0
+        if myvars.Poller == None:
+            return
+        
+        play_list = myvars.Poller.playlist()
+        for i,v in enumerate(play_list):
+            li = ListItem()
+            li._Parent = self
+            li._PosX   = start_x
+            li._PosY   = start_y + i*ListItem._Height
+            li._Width  = Width
+            li._Fonts["normal"] = self._ListFont
+
+            if "title" in v:
+                li.Init( v["title"])
+                if "file" in v:
+                    li._Path = v["file"]
+                
+            elif "file" in v:
+                li.Init(os.path.basename(v["file"]))
+                li._Path = v["file"] 
+            else:
+                li.Init("NoName")
+
+            li._Labels["Text"]._PosX = 7
+            self._MyList.append(li)
+
+            
+        self.SyncPlaying()
+
+    def GObjectInterval(self): ## 250 ms 
+        if self._Screen.CurPage() == self:
+            self.SyncPlaying()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+
+        return True
+    
+    def SyncPlaying(self):
+        if myvars.Poller == None:
+            return
+        
+        current_song = myvars.Poller.poll()
+        
+        for i ,v in enumerate(self._MyList):
+            self._MyList[i]._Playing = False
+            self._MyList[i]._PlayingProcess = 0
+            
+        if current_song != None:
+            if "song" in current_song:
+                posid = int(current_song["song"])
+                if posid < len(self._MyList): # out of index
+                    if "state" in current_song:
+                        if current_song["state"] == "stop":
+                            self._MyList[posid]._Playing = False
+                        else:
+                            self._MyList[posid]._Playing = True
+                    if "time" in current_song:
+                        times_ = current_song["time"].split(":")
+                        if len(times_)> 1:
+                            cur = float(times_[0])
+                            end = float(times_[1])
+                            pros = int((cur/end)*100.0)
+                            self._MyList[posid]._PlayingProcess = pros
+                        
+                
+    def InPlayList(self,path):
+        for i,v in enumerate(self._MyList):
+            if v._Path == path:
+                return True
+    
+    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()
+        gobject.timeout_add(850,self.GObjectInterval)
+
+        self._BGpng = IconItem()
+        self._BGpng._ImgSurf = MyIconPool._Icons["heart"]
+        self._BGpng._MyType = ICON_TYPES["STAT"]
+        self._BGpng._Parent = self
+        self._BGpng.AddLabel("my favourites", fonts["varela18"])
+        self._BGpng.SetLableColor(pygame.Color(204,204,204))
+        self._BGpng.Adjust(0,0,self._BGwidth,self._BGheight,0)
+
+        self._Scroller = ListScroller()
+        self._Scroller._Parent = self
+        self._Scroller._PosX = self._Width - 10
+        self._Scroller._PosY = 2
+        self._Scroller.Init()
+        
+        
+    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
+        
+
+    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
+
+    def Click(self):
+        if len(self._MyList) == 0:
+            return
+        
+        cur_li = self._MyList[self._PsIndex]
+        play_pos_id = myvars.Poller.play(self._PsIndex)
+
+        self.SyncPlaying()
+
+        self._Screen.Draw()
+        self._Screen.SwapAndShow()
+        
+    def OnReturnBackCb(self):
+        self.SyncList()
+    
+    def KeyDown(self,event):
+        if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]:
+            if myvars.Poller != None:
+                myvars.Poller.stop()
+            
+            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["Right"]:#add
+            self._Screen.PushCurPage()
+            self._Screen.SetCurPage(myvars.MusicLibListPage)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+        
+        if event.key == CurKeys["Y"]:# del selected songs
+            myvars.Poller.delete(self._PsIndex)
+            self.SyncList()
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+        if event.key == CurKeys["Enter"]:
+            self.Click()
+
+        if event.key == CurKeys["Start"]: # start spectrum
+            self._Screen.PushPage(myvars.SpectrumPage)
+            self._Screen.Draw()
+            self._Screen.SwapAndShow()
+            
+    def Draw(self):
+        self.ClearCanvas()
+
+        if len(self._MyList) == 0:
+            self._BGpng.NewCoord(self._Width/2,self._Height/2)
+            self._BGpng.Draw()
+            return
+        else:
+            if len(self._MyList) * ListItem._Height > self._Height:
+                self._Ps._Width = self._Width - 11
+                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()
+                

BIN
Menu/GameShell/PowerOFF.png


+ 89 - 0
Menu/GameShell/PowerOFF/__init__.py

@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*- 
+
+import pygame
+
+#UI lib
+from UI.constants    import RUNSYS
+from UI.keys_def     import CurKeys
+from UI.confirm_page import ConfirmPage
+
+import config
+
+class PowerOffConfirmPage(ConfirmPage):
+    
+    _ConfirmText = "Confirm Power OFF?"
+    
+
+    def CheckBattery(self):
+        try:
+            f = open(config.Battery)
+        except IOError:
+            print( "PowerOFF 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 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() < 20:
+                cmdpath = "feh --bg-center gameshell/wallpaper/gameover.png;"
+            else:
+                cmdpath = "feh --bg-center gameshell/wallpaper/seeyou.png;"
+            
+            cmdpath += "sleep 3;"
+            
+            #cmdpath += "echo 'halt -p' > /tmp/halt_cmd"
+            
+            cmdpath += "sudo halt -p"
+            pygame.event.post( pygame.event.Event(RUNSYS, message=cmdpath))
+
+
+
+class APIOBJ(object):
+
+    _StoragePage = None
+    def __init__(self):
+        pass
+    def Init(self,main_screen):
+        self._Page = PowerOffConfirmPage()
+
+        self._Page._Screen = main_screen
+        self._Page._Name ="Power OFF"
+        self._Page.Init()
+        
+        
+    def API(self,main_screen):
+        if main_screen !=None:
+            main_screen.PushPage(self._Page)
+            main_screen.Draw()
+            main_screen.SwapAndShow()
+
+OBJ = APIOBJ()
+def Init(main_screen):    
+    OBJ.Init(main_screen)
+def API(main_screen):
+    OBJ.API(main_screen)
+    

BIN
Menu/GameShell/Retro Games.png


BIN
Menu/GameShell/RetroArch.png


+ 1 - 0
Menu/GameShell/RetroArch.sh

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

BIN
Menu/GameShell/Settings.png


BIN
Menu/GameShell/Sleep.png


BIN
Menu/GameShell/TinyCloud.png


+ 220 - 0
Menu/GameShell/TinyCloud/__init__.py

@@ -0,0 +1,220 @@
+# -*- coding: utf-8 -*- 
+import pygame
+import validators
+
+from UI.constants import Width,Height,ICON_TYPES
+from UI.simple_name_space import SimpleNamespace
+from UI.page  import Page
+from UI.label  import Label
+from UI.fonts  import fonts
+from UI.icon_item import IconItem
+from UI.icon_pool import MyIconPool
+
+from libs.DBUS  import is_wifi_connected_now,get_wifi_ip
+
+class TinyCloudPage(Page):
+    _FootMsg =  ["Nav.","","","Back",""]
+    _MyList = []
+    
+    _ListFontObj = fonts["varela13"]
+    
+    _AList = {}
+    _Labels = {}
+
+    _Coords = {}
+    
+    _URLColor  = pygame.Color(51,166,255)
+    _TextColor = pygame.Color(83,83,83)
+    _Scrolled = 0
+    
+    _PngSize = {}
+    
+    _DrawOnce = False
+    _Scroller = None
+    _Scrolled = 0
+    
+    def __init__(self):
+        Page.__init__(self)
+        self._Icons = {}
+
+    def OnLoadCb(self):
+        self._Scrolled = 0
+        self._PosY = 0
+        self._DrawOnce = False
+
+    def SetCoords(self):
+
+        self._Coords["forID"] = SimpleNamespace()
+        self._Coords["forID"].x = 15
+        self._Coords["forID"].y = 11
+
+        self._Coords["forKey"] = SimpleNamespace()
+        self._Coords["forKey"].x = 71
+        self._Coords["forKey"].y = self._Coords["forID"].y
+
+        self._Coords["key_and_pass"] = SimpleNamespace()
+        self._Coords["key_and_pass"].x = 36 # 141
+        self._Coords["key_and_pass"].y = self._Coords["forID"].y
+
+        self._Coords["forssh"] = SimpleNamespace()
+        self._Coords["forssh"].x = self._Coords["forID"].x
+        self._Coords["forssh"].y = 47
+
+        self._Coords["ssh_addr"] = SimpleNamespace()
+        self._Coords["ssh_addr"].x = self._Coords["forID"].x
+        self._Coords["ssh_addr"].y = 65
+
+        self._Coords["forwin"] = SimpleNamespace()
+        self._Coords["forwin"].x = self._Coords["forID"].x
+        self._Coords["forwin"].y = 101
+
+        self._Coords["samba_games"] = SimpleNamespace()
+        self._Coords["samba_games"].x = self._Coords["forID"].x
+        self._Coords["samba_games"].y = 118
+
+        self._Coords["samba_music"] = SimpleNamespace()
+        self._Coords["samba_music"].x = self._Coords["samba_games"].x
+        self._Coords["samba_music"].y = 136
+
+        self._Coords["for_airplay"] = SimpleNamespace()
+        self._Coords["for_airplay"].x = self._Coords["forID"].x
+        self._Coords["for_airplay"].y = 173
+
+        self._Coords["airplay_name"] = SimpleNamespace()
+        self._Coords["airplay_name"].x = 68
+        self._Coords["airplay_name"].y = self._Coords["for_airplay"].y
+        
+
+        self._Coords["bg"]          = SimpleNamespace()
+        self._Coords["bg"].x        = self._Width/2
+        self._Coords["bg"].y        = self._Height/2
+
+        self._Coords["online"]          = SimpleNamespace()
+        self._Coords["online"].x        = 266
+        self._Coords["online"].y        = 99
+
+    def SetLabels(self):
+        if is_wifi_connected_now():
+            self._IP = get_wifi_ip()
+            print("TinyCould : %s" % self._IP)
+            try:
+                if validators.ip_address.ipv4(self._IP) == False:
+                    self._IP = "xxx.xxx.xxx.xxx"
+            except:
+                print("ip error %s " % self._IP)
+                self._IP = "xxx.xxx.xxx.xxx"
+            
+        else:
+            self._IP = "xxx.xxx.xxx.xxx"
+        
+        labels = \
+        [["forssh","For ssh and scp:",self._ListFontObj,self._TextColor],
+         ["ssh_addr","ssh cpi@%s" % self._IP, self._ListFontObj,self._URLColor],
+         ["forwin", "For Windows network:",    self._ListFontObj, self._TextColor],
+         ["samba_games", "\\\\%s\games" % self._IP, self._ListFontObj,self._URLColor],
+         ["samba_music", "\\\\%s\music" % self._IP, self._ListFontObj,self._URLColor],
+         ["forID",      "ID:",                     self._ListFontObj, self._TextColor],
+         ["forKey",     "Key:",                    self._ListFontObj, self._TextColor],
+         ["key_and_pass", "cpi",                   self._ListFontObj, self._URLColor],
+         ["for_airplay", "Airplay:",               self._ListFontObj, self._TextColor],
+         ["airplay_name","clockworkpi",            self._ListFontObj, self._URLColor]]
+
+        for i in labels:
+            l = Label()
+            l.SetCanvasHWND(self._CanvasHWND)
+            l.Init(i[1],i[2])
+            l.SetColor(i[3])
+            self._Labels[ i[0] ] = l
+
+        self.SetCoords() ##
+        
+    def Init(self):
+
+        
+        if self._Screen != None:
+            if self._Screen._CanvasHWND != None and self._CanvasHWND == None:
+                self._HWND = self._Screen._CanvasHWND
+                self._CanvasHWND = pygame.Surface( (self._Screen._Width,self._Screen._Height) )
+        
+        self._PosX = self._Index*self._Screen._Width 
+        self._Width = self._Screen._Width ## equal to screen width
+        self._Height = self._Screen._Height
+
+        self._PngSize["bg"] = (253,132)
+        self._PngSize["online"] = (75,122)
+        
+        bgpng = IconItem()
+        bgpng._ImgSurf = MyIconPool._Icons["needwifi_bg"]
+        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
+        
+        onlinepng = IconItem()
+        onlinepng._ImgSurf = MyIconPool._Icons["online"]
+        onlinepng._MyType = ICON_TYPES["STAT"]
+        onlinepng._Parent = self
+        onlinepng.Adjust(0,0,self._PngSize["online"][0], self._PngSize["online"][1],0)
+
+        self._Icons["online"] = onlinepng
+
+        self.SetLabels()
+
+        
+    def Draw(self):
+        if self._DrawOnce == False:
+            self.ClearCanvas()
+
+            if is_wifi_connected_now():
+                
+                self._Icons["online"].NewCoord(self._Coords["online"].x, self._Coords["online"].y)
+                self._Icons["online"].Draw()
+
+                self.SetLabels()
+                
+                for i in self._Labels:
+                    if i in self._Coords:
+                        self._Labels[i].NewCoord( self._Coords[i].x, self._Coords[i].y)
+                        self._Labels[i].Draw()
+
+                self._Labels["key_and_pass"].NewCoord( 103,self._Coords["key_and_pass"].y)
+                self._Labels["key_and_pass"].Draw()
+
+            else:
+                self._Icons["bg"].NewCoord(self._Coords["bg"].x, self._Coords["bg"].y)
+                self._Icons["bg"].Draw()
+
+                
+            self._DrawOnce = True
+            
+        if self._HWND != None:
+            self._HWND.fill((255,255,255))
+            self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width, self._Height ) )
+            
+            
+        
+class APIOBJ(object):
+
+    _Page = None
+    def __init__(self):
+        pass
+    def Init(self,main_screen):
+        self._Page = TinyCloudPage()
+        self._Page._Screen = main_screen
+        self._Page._Name ="Tiny cloud"
+        self._Page.Init()
+        
+    def API(self,main_screen):
+        if main_screen !=None:
+            main_screen.PushPage(self._Page)
+            main_screen.Draw()
+            main_screen.SwapAndShow()
+
+OBJ = APIOBJ()
+def Init(main_screen):    
+    OBJ.Init(main_screen)
+def API(main_screen):
+    OBJ.API(main_screen)
+    
+        

BIN
Menu/GameShell/freeDM.png


+ 1 - 0
Menu/GameShell/freeDM.sh

@@ -0,0 +1 @@
+chocolate-doom -iwad /home/cpi/games/FreeDM/freedoom1.wad