Browse Source

rom_list_page,rom_so_confirm_page

cuu 5 years ago
parent
commit
9b56dd19b6

+ 0 - 1
sysgo/DBUS/dbus.go

@@ -219,5 +219,4 @@ func init() {
   
   go DBusHandler.ListenSignal()
   
-  
 }

+ 65 - 0
sysgo/UI/Emulator/emu_stack.go

@@ -0,0 +1,65 @@
+package Emulator
+
+import (
+  "sync"
+  "github.com/cuu/LauncherGoDev/sysgo/UI"
+
+)
+
+type element struct {
+    data interface{}
+    next *element
+}
+
+type EmuStack struct {
+    lock *sync.Mutex
+    head *element
+    Size int
+    EmulatorConfig *ActionConfig
+}
+
+func (stk *EmuStack) Push(data interface{}) {
+    stk.lock.Lock()
+
+    element := new(element)
+    element.data = data
+    temp := stk.head
+    element.next = temp
+    stk.head = element
+    stk.Size++
+
+    stk.lock.Unlock()
+}
+
+func (stk *EmuStack) Pop() interface{} {
+    if stk.head == nil {
+        return nil
+    }
+    stk.lock.Lock()
+    r := stk.head.data
+    stk.head = stk.head.next
+    stk.Size--
+
+    stk.lock.Unlock()
+
+    return r
+}
+
+func (stk *EmuStack) Length() int {
+	return stk.Size
+}
+
+func (stk *EmuStack) Last() string {
+  idx := stk.Length() -1
+  if idx < 0 {
+    return stk.EmulatorConfig.ROM
+  }else {
+    return stk.head.data.(string)
+  }
+}
+
+func NewEmuStack() *EmuStack {
+    stk := new(EmuStack)
+    stk.lock = &sync.Mutex{}
+    return stk
+}

+ 53 - 0
sysgo/UI/Emulator/emulator.go

@@ -0,0 +1,53 @@
+package Emulator
+
+import (
+
+  "github.com/cuu/LauncherGoDev/sysgo/UI"
+)
+
+type ActionConfig struct {
+	ROM string `json:"ROM"`
+	ROM_SO string `json:"ROM_SO"`
+	EXT []string   `json:"EXT"`
+	EXCLUDE []string `json:"EXCLUDE"`
+	FILETYPE string  `json:"FILETYPE"`   // defalut is file
+	LAUNCHER string  `json:"LAUNCHER"`
+	TITLE   string   `json:"TITLE"` // defaut is Game
+	SO_URL string    `json:"SO_URL"`
+	RETRO_CONFIG string `json:"RETRO_CONFIG"`
+}
+
+
+var (
+  FavGID = 31415
+  FavGname = "cpifav"
+  
+)
+
+
+type MyEmulator struct { // as leader of RomListPage and FavListPage, it's a PluginInterface
+  Name string
+  RomPage *RomListPage
+  FavPage *FavListPage
+}
+
+func NewMyEmulator() *MyEmulator{
+  p := &MyEmulator{}
+  
+  return p
+}
+
+func (self *MyEmulator) GetName() string {
+  return "MyEmulator"
+}
+
+func (self *MyEmulator) Init(main_screen  *UI.MainScreen) {
+  
+}
+
+func (self *MyEmulator) API(main_screen *UI.MainScreen) {
+  
+}
+
+
+

+ 11 - 0
sysgo/UI/Emulator/fav_list_page.go

@@ -0,0 +1,11 @@
+package Emulator
+
+import (
+  "path/filepath"
+  
+	"github.com/cuu/gogame/surface"
+  "github.com/cuu/LauncherGoDev/sysgo/UI"
+
+)
+
+

+ 210 - 0
sysgo/UI/Emulator/list_item.go

@@ -0,0 +1,210 @@
+package Emulator
+
+import (
+  "path/filepath"
+  
+	"github.com/cuu/gogame/surface"
+  "github.com/cuu/LauncherGoDev/sysgo/UI"
+
+)
+
+type EmulatorPageInterface {
+  UI.PageInterface
+  GetIcons() map[string]UI.IconItemInterface
+}
+
+
+type ListItemIcon struct {
+  UI.IconItem
+
+}
+
+func NewListItemIcon() *ListItemIcon {
+  p := &ListItemIcon{}
+  p.MyType = UI.ICON_TYPES["EXE"]
+
+	p.Align = UI.ALIGN["VCenter"]
+  
+  p.Width = 18
+  p.Height = 18
+  
+  return p
+}
+
+func (self *ListItemIcon) Draw() {
+  _,h := self.Parent.Size()
+  
+  rect_ := rect.Rect(self.PosX,self.PosY+(h-self.Height)/2,self.Width,self.Height)
+  
+  surface.Blit(self.CanvasHWND, self.ImgSurf,&rect_,nil)
+}
+
+/// [..] [.] 
+type HierListItem struct {
+  UI.ListItem
+  MyType int
+  Path  string
+  Active bool
+  Playing bool
+}
+
+var HierListItemDefaultHeight = 32
+
+func NewHierListItem() *HierListItem {
+  p := &HierListItem{}
+  p.Labels = make(map[string]LabelInterface)
+	p.Icons  = make( map[string]IconItemInterface)
+	p.Fonts  = make(map[string]*ttf.Font)
+  
+  p.MyType = UI.ICON_TYPES["EXE"]
+	p.Height = HierListItemDefaultHeight
+	p.Width  = 0
+  
+  return p
+}
+
+func (self *HierListItem) IsFile() bool {
+  if self.MyType == UI.ICON_TYPES["FILE"] {
+    return true
+  }
+  
+  return false
+}
+
+
+func (self *HierListItem) IsDir() bool {
+  if self.MyType == UI.ICON_TYPES["DIR"] {
+    return true
+  }
+  
+  return false
+}
+
+
+func (self *HierListItem) Init(text string) {
+  l := UI.NewLabel()
+  l.PosX = 20
+  l.SetCanvasHWND(self.Parent.GetCanvasHWND())
+  
+  if self.IsDir() == true || self.IsFile() == true {
+    self.Path = text
+  }
+  
+  label_text := filepath.Base(text)
+  ext:= filepath.Ext(text)
+  if ext != "" {
+    alias_file := strings.Replace(text,ext,"",-1) + ".alias"
+    
+    if UI.FileExists(alias_file) == true {
+      b, err := ioutil.ReadFile(alias_file) 
+      if err != nil {
+        fmt.Print(err)
+      }else {
+        label_text = string(b)
+      }
+    }
+    
+  }
+  
+  if self.IsDir() == true {
+    l.Init(label_text, self.Fonts["normal"])
+  }else {
+    l.Init(label_text,self.Fonts["normal"])
+  }
+  
+  self.Labels["Text"] = l
+}
+
+func (self *HierListItem) Draw() {
+  
+  x,y := self.Labels["Text"].Coord()
+  _,h := self.Labels["Text"].Size()
+  
+  if self.Path != "[..]" {
+    self.Labels["Text"].NewCoord(23,y)
+    
+  }else {
+    self.Labels["Text"].NewCoord(3,y)
+  }
+  
+  x,y = self.Labels["Text"].Coord()
+  self.Labels["Text"].NewCoord(x, self.PosY + (self.Height-h)/2)
+  
+  self.Labels["Text"].Draw()
+  
+  
+  /*
+  w,h := self.Parent.Icons["sys"].Size()
+  
+  if self.IsDir() == true && self.Path != "[..]" {
+    self.Parent.Icons["sys"].IconIndex = 0
+    self.Parent.Icons["sys"].NewCoord(self.PosX+12,self.PosY+(self.Height-h)/2+h/2)
+    self.Parent.Icons["sys"].Draw()
+  }
+  
+  if self.IsFile() == true {
+    self.Parent.Icons["sys"].IconIndex = 1
+    self.Parent.Icons["sys"].NewCoord(self.PosX+12,self.PosY+(self.Height-h)/2+h/2)
+    self.Parent.Icons["sys"].Draw()
+  }
+  */
+  
+  draw.Line(self.Parent.GetCanvasHWND(),&color.Color{169,169,169,255},
+    self.PosX,self.PosY+self.Height-1,self.PosX+self.Width,self.PosY+self.Height-1,1)
+  
+}
+
+type EmulatorListItem struct {
+  HierListItem
+  Parent EmulatorPageInterface
+}
+
+func NewEmulatorListItem() *EmulatorListItem {
+  p := &EmulatorListItem{}
+  p.Labels = make(map[string]LabelInterface)
+	p.Icons  = make( map[string]IconItemInterface)
+	p.Fonts  = make(map[string]*ttf.Font)
+  
+  p.MyType = UI.ICON_TYPES["EXE"]
+	p.Height = 32
+	p.Width  = 0  
+  return p
+}
+
+func (self *EmulatorListItem) Draw() {
+  x,y := self.Labels["Text"].Coord()
+  _,h := self.Labels["Text"].Size()
+  
+  if self.Path != "[..]" {
+    self.Labels["Text"].NewCoord(23,y)
+    
+  }else {
+    self.Labels["Text"].NewCoord(3,y)
+  }
+  
+  x,y = self.Labels["Text"].Coord()
+  self.Labels["Text"].NewCoord(x, self.PosY + (self.Height-h)/2)
+  
+  self.Labels["Text"].Draw()
+  
+  parent_icons := self.Parent.GetIcons()
+  w,h := parent_cons["sys"].Size()
+  
+  if self.IsDir() == true && self.Path != "[..]" {
+    parent_icons["sys"].IconIndex = 0
+    parent_icons["sys"].NewCoord(self.PosX+12,self.PosY+(self.Height-h)/2+h/2)
+    parent_icons["sys"].Draw()
+  }
+  
+  if self.IsFile() == true {
+    parent_icons["sys"].IconIndex = 1
+    parent_icons["sys"].NewCoord(self.PosX+12,self.PosY+(self.Height-h)/2+h/2)
+    parent_icons["sys"].Draw()
+  }
+  
+  draw.Line(self.Parent.GetCanvasHWND(),&color.Color{169,169,169,255},
+    self.PosX,self.PosY+self.Height-1,self.PosX+self.Width,self.PosY+self.Height-1,1)
+
+}
+
+

+ 539 - 0
sysgo/UI/Emulator/rom_list_page.go

@@ -0,0 +1,539 @@
+package Emulator
+
+import (
+  "path/filepath"
+  
+  
+  "github.com/cuu/gogame/color"
+	"github.com/cuu/gogame/surface"
+  "github.com/cuu/LauncherGoDev/sysgo/UI"
+
+)
+
+type RomListPage struct {
+  UI.Page
+  Icons  map[string]UI.IconItemInterface
+  ListFont *ttf.Font
+  MyStack *EmuStack
+  EmulatorConfig *ActionConfig
+  
+  RomSoConfirmDownloadPage *RomSoConfirmPage
+  
+  MyList []*EmulatorListItem
+  BGwidth int
+  BGheight 70
+  
+  Leader *MyEmulator
+  
+}
+
+func NewRomListPage() *RomListPage {
+  p := &RomListPage{}
+  p.PageIconMargin = 20
+	p.SelectedIconTopOffset = 20
+	p.EasingDur = 10
+
+	p.Align = ALIGN["SLeft"]
+	
+	p.FootMsg = [5]string{ "Nav","Scan","Del","AddFav","Run" }
+  
+  p.Icons=make(map[string]UI.IconItemInterface)
+  p.ListFont =  UI.Fonts["notosanscjk15"]
+  
+  p.MyStack = NewEmuStack()
+  
+  p.BGwidth = 56
+  p.BGheight = 70
+  
+  return p
+}
+
+
+func (self *RomListPage) GeneratePathList(path string) []map[string]string {
+  if UI.IsDirectory(path) == false {
+    return nil
+  }
+  dirmap := make(map[string]string)
+  var ret []map[string]string
+  
+  file_paths,err := filepath.Glob(path+"/*")//sorted
+  if err != nil {
+    fmt.Println(err)
+    return false
+  }
+  
+  for i,v := range file_paths {
+    if UI.IsDirectory(v) && self.EmulatorConfig.FILETYPE == "dir" { // like DOSBOX
+      gameshell_bat := self.EmulatorConfig.EXT[0]
+      if UI.GetGid(v) == FavGID { // skip fav roms
+        continue
+      }
+      
+      if UI.FileExists( filepath.Join(v,gameshell_bat))  == true {
+        dirmap["gamedir"] = v
+        ret = append(ret,dirmap)
+      }
+    }
+    
+    if UI.IsFile(v) && self.EmulatorConfig.FILETYPE == "file" {
+      if UI.GetGid(v) == FavGID {
+        continue
+      }
+      
+      bname := filepath.Base(v)
+      if len(bname) > 1 {
+        is_excluded := false
+        for _,exclude_pattern := range self.EmulatorConfig.EXCLUDE {
+          if matched, err := regexp.MatchString(exclude_pattern,bname); err == nil {
+            if matched == true {
+              is_excluded = true
+              break
+            }
+          }
+        }
+        
+        if is_excluded == false {
+          pieces := strings.Split(bname,".")
+          if len(pieces) > 1 {
+            pieces_ext := strings.ToLower( pieces[len(pieces)-1])
+            for _,v := range self.EmulatorConfig.EXT {
+              if pieces_ext == v {
+                dirmap["file"] = v
+                ret = append(ret,dirmap)
+                break
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  
+  return ret
+  
+}
+
+func (self *RomListPage) SyncList( path string ) {
+  
+  alist := self.GeneratePathList(path) 
+
+  if alist == nil {
+    fmt.Println("listfiles return false")
+    return
+  }
+  
+  self.MyList = nil 
+  
+  start_x := 0 
+  start_y := 0
+  
+  hasparent := 0 
+  
+  if self.MyStack.Length() > 0 {
+    hasparent = 1
+    
+    li := NewEmulatorListItem()
+    li.Parent = self
+    li.PosX   = start_x
+    li.PosY   = start_y
+    li.Width  = UI.Width
+    li.Fonts["normal"] = self.ListFont
+    li.MyType = UI.ICON_TYPES["DIR"]
+    li.Init("[..]")
+    self.MyList = append(self.MyList,li)
+  }
+  
+  for i,v := range alist {
+    li := NewEmulatorListItem()
+    li.Parent = self
+    li.PosX   = start_x
+    li.PosY   = start_y + (i+hasparent)*li.Height
+    li.Fonts["normal"] = self.ListFont
+    li.MyType = UI.ICON_TYPES["FILE"]
+    
+    init_val = "NoName"
+    
+    if val, ok := v["directory"]; ok {
+      li.MyType = UI.ICON_TYPES["DIR"]
+      init_val = val
+    }
+    
+    if val, ok := v["file"]; ok {
+      init_val = val
+    }
+    
+    if val, ok := v["gamedir"]; ok {
+      init_val = val
+    }
+    
+    li.Init(init_val)
+    
+    self.MyList = append(self.MyList,li)
+  }
+}
+
+func (self *RomListPage) Init() {
+  self.PosX = self.Index *self.Screen.Width
+  self.Width = self.Screen.Width
+  self.Height = self.Screen.Height
+  
+  sefl.CanvasHWND = self.Screen.CanvasHWND
+  
+  ps := UI.NewInfoPageSelector()
+  ps.Width  = UI.Width - 12
+  ps.PosX = 2
+  ps.Parent = self
+  
+  self.Ps = ps
+  self.PsIndex = 0
+  
+  self.SyncList( self.EmulatorConfig.ROM )
+  
+  err := os.MkdirAll( self.EmulatorConfig.ROM+"/.Trash", 0700)
+  if err != nil {
+    panic(err)
+  }
+  
+  err = os.MkdirAll( self.EmulatorConfig.ROM+"/.Fav", 0700)
+  if err != nil {
+    panic(err)
+  }
+  
+  self.MyStack.EmulatorConfig = self.EmulatorConfig
+  
+  icon_for_list := UI.NewMultiIconItem()
+  icon_for_list.ImgSurf = UI.MyIconPool.GetImgSurf("sys")
+  icon_for_list.MyType = UI.ICON_TYPES["STAT"]
+  icon_for_list.Parent = self
+  
+  icon_for_list.Adjust(0,0,18,18,0)
+        
+  self.Icons["sys"] = icon_for_list  
+  
+  bgpng := UI.NewIconItem()
+  bgpng.ImgSurf = UI.MyIconPool.GetImgSurf("empty")
+  bgpng.MyType = UI.ICON_TYPES["STAT"]
+  bgpng.Parent = self
+  bgpng.AddLabel("Please upload data over Wi-Fi",UI.Fonts["varela22"])
+  bgpng.SetLableColor(&color.Color{204,204,204,255}  )
+  bgpng.Adjust(0,0,self.BGwidth,self.BGheight,0)
+
+  self.Icons["bg"] = bgpng
+  
+  self._Scroller = UI.NewListScroller()
+  self._Scroller.Parent = self
+  self._Scroller.PosX = self.Width - 10
+  self._Scroller.PosY = 2
+  self._Scroller.Init()
+  
+  rom_so_confirm_page := NewRomSoConfirmPage()
+  rom_so_confirm_page.Screen = self.Screen
+  rom_so_confirm_page.Name = "Download Confirm"
+  rom_so_confirm_page.Parent = self
+  rom_so_confirm_page.Init()
+
+  self.RomSoConfirmDownloadPage = rom_so_confirm_page 
+}
+
+
+func (self *RomListPage) ScrollUp() {
+  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,_ := range self.MyList{
+      self.MyList[i].PosY += self.MyList[i].Height
+    }
+    
+    self.Scrolled +=1
+  }
+}
+
+
+func (self *RomListPage) ScrollDown(){
+  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,_ := range self.MyList{
+      self.MyList[i].PosY -= self.MyList[i].Height
+    }
+    self.Scrolled -=1    
+  }
+
+}
+
+func (self *RomListPage) SyncScroll() {
+
+  if self.Scrolled == 0 {
+    return
+  }
+  
+  if self.PsIndex < len(self.MyList) {
+    cur_li := self.MyList[self.PsIndex]
+    if self.Scrolled > 0 {
+      if cur_li.PosY < 0 {
+        for i,_ := range self.MyList{
+          self.MyList[i].PosY += self.Scrolled*self.MyList[i].Height
+        }
+      }
+    } if self.Scrolled < 0 {
+      if cur_li.PosY + cur_li.Height > self.Height{
+        for i,_ := range self.MyList{
+          self.MyList[i].PosY += self.Scrolled*self.MyList[i].Height
+        }
+      }
+    }
+  
+  }
+}
+
+
+func (self *RomListPage) Click() {
+
+  if len(self.MyList) == 0 {
+    return
+  }
+  
+  
+  if self.PsIndex > len(self.MyList) - 1 {
+    return
+  }
+  
+  
+  cur_li := self.MyList[self.PsIndex]
+  
+  if cur_li.MyType == UI.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 == UI.ICON_TYPES["FILE"] {
+    self.Screen.MsgBox.SetText("Launching")
+    self.Screen.MsgBox.Draw()
+    self.Screen.SwapAndShow()
+    
+    path := ""
+    if self.EmulatorConfig.FILETYPE == "dir" {
+      path = filepath.Join(cur_li.Path,self.EmulatorConfig.EXT[0])
+    }else{
+      path  = cur_li.Path
+    }
+    
+    fmt.Println("Run ",path)
+    
+    escaped_path := UI.CmdClean(path)
+    
+    if self.EmulatorConfig.FILETYPE == "dir" {
+      escaped_path = UI.CmdClean(path)
+    }
+    
+    custom_config := ""
+    
+    if self.EmulatorConfig.RETRO_CONFIG != "" && len(self.EmulatorConfig.RETRO_CONFIG) 5 {
+      custom_config = " -c " + self.EmulatorConfig.RETRO_CONFIG
+    }
+    
+    partsofpath := []string{self.EmulatorConfig.LAUNCHER,self.EmulatorConfig.ROM_SO,custom_config,escaped_path}
+    
+    cmdpath := strings.Join( partsofpath," ")
+    
+    if self.EmulatorConfig.ROM_SO =="" { //empty means No needs for rom so 
+      event.POST(UI.RUNEVT,cmdpath)
+    }else{
+      
+      if UI.FileExists(self.EmulatorConfig.ROM_SO) == true {
+        event.POST(UI.RUNEVT,cmdpath)
+      } else {
+        self.Screen.PushCurPage()
+        self.Screen.SetCurPage( self.RomSoConfirmDownloadPage)
+        self.Screen.Draw()
+        self.Screen.SwapAndShow()
+      }
+    }
+    
+    return
+    
+  }
+  
+  self.Screen.Draw()
+  self.Screen.SwapAndShow() 
+}
+
+func (self *RomListPage) ReScan() {
+  if self.MyStack.Length() == 0 {
+    self.SyncList(self.EmulatorConfig.ROM)
+  }else{
+    self.SyncList(self.MyStack.Last())
+  }
+  
+  
+  idx := self.PsIndex
+  
+  if idx > len(self.MyList) - 1 {
+    idx = len(self.MyList)
+    if idx > 0 {
+      idx -= 1
+    }else if idx == 0 {
+      //nothing in MyList
+    }
+  }
+  
+  self.PsIndex = idx //sync PsIndex
+  
+  self.SyncScroll()
+}
+
+
+func (self *RomListPage) OnReturnBackCb() {
+  self.ReScan()
+  self.Screen.Draw()
+  self.Screen.SwapAndShow()
+}
+
+
+func (self *RomListPage) KeyDown(ev *event.Event) {
+
+  if ev.Data["Key"] == UI.CurKeys["Menu"]{
+    self.ReturnToUpLevelPage()
+    self.Screen.Draw()
+    self.Screen.SwapAndShow()
+  }
+  
+  if ev.Data["Key"] == UI.CurKeys["Right"]{
+    self.Screen.PushCurPage()
+    self.Screen.SetCurPage(self.Leader.FavPage)
+    self.Screen.Draw()
+    self.Screen.SwapAndShow()
+        
+  if ev.Data["Key"] == UI.CurKeys["Up"]{
+    self.ScrollUp()
+    self.Screen.Draw()
+    self.Screen.SwapAndShow()
+  }
+  
+  if ev.Data["Key"] == UI.CurKeys["Down"] {
+    self.ScrollDown()
+    self.Screen.Draw()
+    self.Screen.SwapAndShow()
+  }
+  
+  if ev.Data["Key"] == UI.CurKeys["Enter"] {
+    self.Click()
+  }
+  
+  if ev.Data["Key"] == UI.CurKeys["A"] {
+    if len(self.MyList) == 0{
+      return
+    }
+    
+    cur_li := self.MyList[self.PsIndex]
+    
+    if cur_li.IsFile() {
+      cmd := exec.Command("chgrp", FavGname, UI.CmdClean(cur_li.Path))
+      err := cmd.Run()
+      if err != nil {
+        fmt.Println(err)
+      }
+      
+      self.Screen.MsgBox.SetText("Add to favourite list")
+      self.Screen.MsgBox.Draw()
+      self.Screen.SwapAndShow()
+      time.BlockDelay(600)
+      self.ReScan()
+      self.Screen.Draw()
+      self.Screen.SwapAndShow()
+    
+    }
+  }
+  
+  if ev.Data["Key"] == UI.CurKeys["X"] { //Scan current
+    self.ReScan()
+    self.Screen.Draw()
+    self.Screen.SwapAndShow()        
+  }
+  
+  if ev.Data["Key"] == UI.CurKeys["Y"] {// del
+    if len(self.MyList) == 0 {
+      return
+    }
+    
+    cur_li := self.MyList[self.PsIndex] 
+    if cur_li.IsFile() {
+      self.Leader.DeleteConfirmPage.SetFileName(cur_li.Path)
+      self.Leader.DeleteConfirmPage.SetTrashDir(filepath.Join(self.EmulatorConfig.ROM,"/.Trash") )
+      
+      self.Screen.PushCurPage()
+      self.Screen.SetCurPage(self.Leader.DeleteConfirmPage)
+      self.Screen.Draw()
+      self.Screen.SwapAndShow()
+      
+    }
+  }
+}
+
+func (self *RomListPage) Draw() {
+  self.ClearCanvas()
+  
+  if len(self.MyList) == 0 {
+    self.Icons["bg"].NewCoord(self.Width/2,self.Height/2)
+    self.Icons["bg"].Draw()
+  }else{
+    
+    if len(self.MyList) * HierListItemDefaultHeight > self.Height {
+      self.Ps.Width  = self.Width - 10
+      self.Ps.Draw()
+      
+      
+      for i,v := range self.MyList {
+        if v.PosY > self.Height + self.Height/2 {
+          break
+        }
+        
+        if v.PosY < 0 {
+          continue
+        }
+        
+        v.Draw()
+      }
+      
+      self.Scroller.UpdateSize( len(self.MyList)*HierListItemDefaultHeight, self.PsIndex*HierListItemDefaultHeight)
+      self.Scroller.Draw()
+      
+      
+      
+    }else {
+      self.Ps.Width = self.Width
+      self.Ps.Draw()
+      for _,v := range self.MyList {
+        v.Draw()
+      }
+    }
+  }
+}
+
+

+ 119 - 0
sysgo/UI/Emulator/rom_so_confirm_page.go

@@ -0,0 +1,119 @@
+package Emulator
+
+import (
+  "strconv"
+  "strings"
+  
+  "path/filepath"
+  
+	"github.com/cuu/gogame/surface"
+  "github.com/cuu/LauncherGoDev/sysgo"
+  "github.com/cuu/LauncherGoDev/sysgo/UI"
+
+)
+
+type RomSoConfirmPage struct {
+  UI.ConfirmPage
+  
+  DownloadPage *UI.DownloadProcessPage
+  
+}
+
+func NewRomSoConfirmPage() *RomSoConfirmPage {
+  p := &RomSoConfirmPage{}
+  p.PageIconMargin = 20
+	p.SelectedIconTopOffset = 20
+	p.EasingDur = 10
+	p.Align = ALIGN["SLeft"]
+  
+  p.ListFont = UI.Fonts["veramono18"]
+  p.FootMsg = [5]string{"Nav","","","Cancel","Yes"}
+  p.ConfirmText ="Do you want to setup this game engine automatically?"
+  
+  return p
+  
+}
+
+func (self *RomSoConfirmPage) Init() {
+  self.PosX = self.Index * self.Screen.Width
+  self.Width = self.Screen.Width
+  self.Height = self.Screen.Height
+
+  self.CanvasHWND = self.Screen.CanvasHWND
+  
+  li := UI.NewMultiLabel()
+  li.SetCanvasHWND(self.CanvasHWND)
+  li.Width = 160
+  li.Init(self.ConfirmText,self.ListFont)
+  
+  li.PosX = (self.Width - li.Width)/2
+  li.PosY = (self.Height - li.Height)/2
+
+  self.BGPosX = li.PosX-20
+  self.BGPosY = li.PosY-20
+  self.BGWidth = li.Width+40
+  self.BGHeight = li.Height+40  
+  
+  self.MyList = append(self.MyList ,li )
+  
+}
+
+func (self *RomSoConfirmPage) SnapMsg(msg string) {
+  self.MyList[0].SetText(msg)
+  self.Screen.Draw()
+  self.Screen.SwapAndShow()
+  self.MyList[0].SetText(self.ConfirmText)
+}
+
+func (self *RomSoConfirmPage) OnReturnBackCb() {
+  self.ReturnToUpLevelPage()
+  self.Screen.Draw()
+  self.Screen.SwapAndShow()
+}
+
+func (self *RomSoConfirmPage) KeyDown(ev *event.Event) {
+  
+  if ev.Data["Key"] == UI.CurKeys["Menu"] || ev.Data["Key"] == UI.CurKeys["A"] {
+    self.ReturnToUpLevelPage()
+    self.Screen.Draw()
+    self.Screen.SwapAndShow()
+  }
+  
+  if ev.Data["Key"] == UI.CurKeys["B"] {
+    if UI.CheckBattery < 5 {
+      self.SnapMsg("Battery must over 5%")
+    }else {
+      if self.DownloadPage == nil {
+        self.DownloadPage = UI.NewDownloadProcessPage()
+        self.DownloadPage.Screen = self.Screen
+        self.DownloadPage.Name   = "Downloading"
+        self.DownloadPage.Init()
+      }
+      
+      self.Screen.PushPage(self.DownloadPage)
+      self.Screen.Draw()
+      self.Screen.SwapAndShow()
+      
+      if sysgo.CurKeySet == "PC" {
+        so_url := self.Parent.EmulatorConfig.SO_URL
+        so_url = strings.Replace(so_url,"armhf","x86_64",-1)
+        fmt.Println(so_url)
+        self.DownloadPage.StartDownload(so_url,filepath.Dir(self.Parent.EmulatorConfig.ROM_SO))
+        
+      }else{
+        so_url := self.Parent.EmulatorConfig.SO_URL
+        self.DownloadPage.StartDownload(so_url,filepath.Dir(self.Parent.EmulatorConfig.ROM_SO))
+      }
+    }
+  }
+}
+
+func (self *RomSoConfirmPage) Draw() {
+  self.ClearCanvas()
+  self.DrawBG()
+  for _,v := range self.MyList{
+    v.Draw()
+  }  
+    
+
+}

+ 7 - 1
sysgo/UI/UI.go

@@ -42,7 +42,7 @@ func (self *Widget) NewCoord(x,y int) {
 	self.PosY = y
 }
 
-
+//invoked in main.go
 func Init() {
 	font.Init()
 
@@ -78,3 +78,9 @@ func Init() {
 		Fonts[keyname] = font.Font(fonts_path["notocjk"],i)
 	}
 }
+
+func init() {
+  if MyIconPool == nil {
+    MyIconPool = NewIconPool()
+  }
+}

+ 255 - 0
sysgo/UI/download_process_page.go

@@ -0,0 +1,255 @@
+package UI
+
+import (
+  gotime "time"
+  "net/url"
+  
+  "github.com/cuu/grab"
+  "github.com/cuu/gogame/color"
+)
+
+type DownloadProcessPage struct {
+  UI.Page
+    
+  URL string
+  DST_DIR string
+  Value   int
+  PngSize map[string][2]int
+  
+  FileNameLabel LabelInterface
+  SizeLabel     LabelInterface
+  
+  Icons  map[string]IconItemInterface
+
+  URLColor  *color.Color
+  TextColor  *color.Color
+  TheTicker *gotime.Ticker
+  
+  Downloader *grab.Client
+  resp *grab.Response
+  req *grab.Request
+  
+}
+
+
+func NewDownloadProcessPage() *DownloadProcessPage {
+  
+  p := &DownloadProcessPage{}
+  
+  p.FootMsg = [5]string{"Nav","","","Back",""}
+  
+  p.URLColor = &color.Color{51, 166, 255,255 } // URL
+  p.TextColor = &color.Color{83,83,83,255 } // Text
+  
+  p.PngSize = make(map[string][2]int,0)
+  
+  p.Icons=make(map[string]IconItemInterface)
+  
+  return p
+}
+
+func (self *DownloadProcessPage) Init() {
+  self.PosX = self.Index * self.Screen.Width
+  self.Width  = self.Screen.Width
+  self.Height = self.Screen.Height
+  
+  self.CanvasHWND = self.Screen.CanvasHWND
+  self.PngSize["bg"] = [2]int{48,79}
+  self.PngSize["needwifi_bg"] = [2]int{253,132}
+  
+  bgpng := NewIconItem()
+  bgpng.ImgSurf = MyIconPool.GetImgSurf("rom_download")
+  bgpng.MyType = ICON_TYPES["STAT"]
+  bgpng.Parent = self
+  bgpng.Adjust(0,0,self.PngSize["bg"][0],self.PngSize["bg"][1],0)
+  self.Icons["bg"] = bgpng
+  
+  needwifi_bg = NewIconItem()
+  needwifi_bg.ImgSurf = MyIconPool.GetImgSurf("needwifi_bg")
+  needwifi_bg.MyType = ICON_TYPES["STAT"]
+  needwifi_bg.Parent = self
+  needwifi_bg.Adjust(0,0,self.PngSize["needwifi_bg"][0],self.PngSize["needwifi_bg"][1],0)
+  
+  self.Icons["needwifi_bg"] = needwifi_bg
+
+  self.FileNameLabel = NewLabel()
+  self.FileNameLabel.SetCanvasHWND(self.CanvasHWND)
+  self.FileNameLabel.Init("", Fonts["varela12"])
+  
+  self.SizeLabel = NewLabel()
+  self.SizeLabel.SetCanvasHWND(self.CanvasHWND)
+  self.SizeLabel.Init("0/0Kb",Fonts["varela12"])
+  self.SizeLabel.SetColor( self.URLColor )
+  
+  self.Downloader = grab.NewClient()
+  
+}
+
+func (self *DownloadProcessPage) OnExitCb() {
+  
+  //Stop Ticker and the Grab
+  if self.TheTicker != nil {
+    self.TheTicker.Stop()
+  }
+  
+}
+
+// should be in a gorotine
+func (self *DownloadProcessPage) UpdateProcessInterval() {
+  if self.TheTicker == nil {
+    return
+  }
+  
+  if self.Screen.CurPage() != self {
+    return
+  }
+  
+  
+  for {
+		select {
+		case <-self.TheTicker.C:
+			fmt.Printf("  transferred %v / %v bytes (%.2f%%)\n",
+				self.resp.BytesComplete(),
+				self.resp.Size,
+				100*self.resp.Progress())
+    self.Value = int(100*self.resp.Progress())
+    
+		case <-self.resp.Done:
+			// download is complete
+      fmt.Println("download is complete ",self.Value)
+      self.Value = 0 
+      
+      
+			break
+		}
+  }
+  
+	if err := self.resp.Err(); err != nil {
+    self.DownloadErr()
+		fmt.Fprintf(os.Stderr, "Download failed: %v\n", err)
+	}
+
+  fmt.Printf("Download saved to %s/%v \n",self.DST_DIR, self.resp.Filename)
+  
+  filename := filepath.Base(self.resp.Filename)
+  
+  if strings.HasSuffix(filename,".zip") {
+    cmd := exec.Command("unzip",filename)
+    cmd.Dir = self.DST_DIR
+    cmd.Run()
+  }else if strings.HasSuffix(filename,".zsync") {
+    cmd := exec.Command("rm","-rf",filename)
+    cmd.Dir = self.DST_DIR
+    cmd.Run()
+  }else if strings.HasSuffix(filename,".tar.gz") {
+    cmd := exec.Command("tar", "xf", filename)
+    cmd.Dir= self.DST_DIR
+    cmd.Run()
+  }
+  
+  cmd := exec.Command("rm","-rf",filename)
+  cmd.Dir = self.DST_DIR
+  cmd.Run()
+    
+  self.TheTicker.Stop()
+  
+  self.DoneAndReturnUpLevel()
+  
+}
+
+func (self *DownloadProcessPage) DownloadErr()  {
+  self.Screen.MsgBox.SetText("Download Failed")
+  self.Screen.MsgBox.Draw()
+  self.Screen.SwapAndShow()  
+}
+
+func (self *DownloadProcessPage) DoneAndReturnUpLevel() {
+  self.ReturnToUpLevelPage()
+  self.Screen.Draw()
+  self.Screen.SwapAndShow()
+}
+
+
+
+func (self *DownloadProcessPage) StartDownload(_url,dst_dir string) {
+  
+  if self.Screen.DBusManager.IsWifiConnectedNow() == false {
+    return
+  }
+  
+  _, err := url.ParseRequestURI(_url)
+  if err == nil && UI.IsDirectory(dst_dir) {
+    self.URL = _url
+    self.DST_DIR = dst_dir
+  }else{
+  
+    self.Screen.MsgBox.SetText("Invaid")
+    self.Screen.MsgBox.Draw()
+    self.Screen.SwapAndShow() 
+    fmt.Println("DownloadProcessPage StartDownload Invalid ",err)
+    return
+  }
+
+  self.req, _ := grab.NewRequest(self.DST_DIR, _url)
+  
+  fmt.Printf("Downloading %v...\n", self.req.URL())
+  
+  self.resp = self.Downloader.Do(self.req)
+  
+  fmt.Printf("  %v\n", self.resp.HTTPResponse.Status)
+  
+  self.TheTicker = gotime.NewTicker(100 * gotime.Millisecond)
+  
+  go self.UpdateProcessInterval()
+  
+}
+
+
+func (self *DownloadProcessPage) Draw() {
+
+  self.ClearCanvas()
+  
+  if self.Screen.DBusManager.IsWifiConnectedNow() == false {
+    self.Icons["needwifi_bg"].NewCoord(self.Width/2,self.Height/2)
+    self.Icons["needwifi_bg"].Draw()
+    return
+    
+  }
+  
+  self.Icons["bg"].NewCoord(self.Width/2,self.Height/2)
+  self.Icons["bg"].Draw()
+  
+  percent := self.Value
+  if percent < 10 {
+    percent = 10
+  }
+  
+  rect_ := draw.MidRect(self.Width/2,self.Height/2+33,170,17, UI.Width,UI.Height)
+  
+  draw.AARoundRect(self.CanvasHWND,rect_,
+                  &color.Color{228,228,228,255},5,0,&color.Color{228,228,228,255})
+  
+  
+  rect2_ := draw.MidRect( self.Width/2,self.Height/2+33,int(170.0*((float64)percent/100.0)),17, UI.Width,UI.Height )
+  
+  rect2_.X = rect_.X
+  rect2_.Y = rect_.Y
+  
+  draw.AARoundRect(self.CanvasHWND,rect2_,
+                  &color.Color{131, 199, 219,255},5,0,&color.Color{131, 199, 219,255})
+  
+  w,h: = self.FileNameLabel.Size()
+  
+  rect3_ := draw.MidRect(self.Width/2,self.Height/2+53,w, h,UI.Width,UI.Height)
+
+  w, h = self.SizeLabel.Size()
+  
+  rect4 := draw.MidRect(self.Width/2,self.Height/2+70,w, h,UI.Width,UI.Height)
+  
+  self.FileNameLabel.NewCoord(int(rect3_.X),int(rect3_.Y))
+  self.FileNameLabel.Draw()
+  
+  self.SizeLabel.NewCoord(int(rect4_.X),int(rect4_.Y))
+  self.SizeLabel.Draw()
+  
+}

+ 2 - 1
sysgo/UI/icon_pool.go

@@ -55,5 +55,6 @@ func (self *IconPool) GetImgSurf(keyname string) *sdl.Surface {
 	}
 }
 
-var MyIconPool = NewIconPool()
+var MyIconPool *IconPool
+// = NewIconPool()
 

+ 0 - 12
sysgo/UI/main_screen.go

@@ -28,18 +28,6 @@ var (
 	plugin_flag   = "plugin.json"
 )
 
-type ActionConfig struct {
-	ROM string `json:"ROM"`
-	ROM_SO string `json:"ROM_SO"`
-	EXT []string   `json:"EXT"`
-	EXCLUDE []string `json:"EXCLUDE"`
-	FILETYPE string  `json:"FILETYPE"`   // defalut is file
-	LAUNCHER string  `json:"LAUNCHER"`
-	TITLE   string   `json:"TITLE"` // defaut is Game
-	SO_URL string    `json:"SO_URL"`
-	RETRO_CONFIG string `json:"RETRO_CONFIG"`
-}
-
 type PluginConfig struct {
 	NAME string    `json:"NAME"`  // plugin name,default could be the same as Plugin Folder's name
 	SO_FILE string `json:"SO_FILE"`

+ 52 - 1
sysgo/UI/util_funcs.go

@@ -9,7 +9,8 @@ import (
 	"bufio"
   "bytes"
   "io"
-	
+	"strconv"
+  
 	"github.com/cuu/gogame/display"
 
 	"github.com/cuu/LauncherGoDev/sysgo"
@@ -173,4 +174,54 @@ func WriteLines(lines [] string,path string)(err error){
 }
 
 
+func GetGid(path string) int {
+	s, err := os.Stat(path)
+	if err != nil {
+		return -1
+	}
+
+	sys_interface := s.(os.FileInfo).Sys()
+	if sys_interface == nil {
+		return -1
+	}
+
+	return int(sys_interface.(*syscall.Stat_t).Gid)
+}
+
+
+func GetUid(path string) int {
+	s, err := os.Stat(path)
+	if err != nil {
+		return -1
+	}
+
+	sys_interface := s.(os.FileInfo).Sys()
+	if sys_interface == nil {
+		return -1
+	}
+
+	return int(sys_interface.(*syscall.Stat_t).Uid)
+}
+
+func  CheckBattery() int {
+  batinfos,err := ReadLines(sysgo.Battery)
+  if err == nil {
+    for i,v := range batinfos {
+      if strings.HasPrefix(v,"POWER_SUPPLY_CAPACITY") {
+        parts := strings.Split(v,"=")
+        if len(parts) > 1 {
+          cur_cap,err := strconv.Atoi(parts[1])
+          if err == nil {
+            return cur_cap
+          }else {
+            return 0 
+          }
+        }
+      }
+    }
+  }else{
+    fmt.Println(err)
+  }
+  return 0  
+}