From 23b2f6caf894c5d5412c7009896c83a3df46ff3b Mon Sep 17 00:00:00 2001 From: cuu Date: Wed, 20 Oct 2021 01:34:36 +0800 Subject: [PATCH] start to clone warehouse --- .../aria2_download_process_page.go | 51 ++++ .../image_download_process_page.go | 197 +++++++++++++ .../GameShell/21_Warehouse/load_house_page.go | 194 +++++++++++++ Menu/GameShell/21_Warehouse/plugin_init.go | 38 +++ .../21_Warehouse/ware_house_list_item.go | 123 ++++++++ .../GameShell/21_Warehouse/ware_house_page.go | 269 ++++++++++++++++++ .../21_Warehouse/ware_house_stack.go | 64 +++++ sysgo/UI/icon_pool.go | 29 +- sysgo/UI/keys_def.go | 8 + sysgo/UI/page.go | 12 +- sysgo/UI/util_funcs.go | 57 ++++ sysgo/UI/yes_cancel__confirm_page.go | 63 ++++ 12 files changed, 1102 insertions(+), 3 deletions(-) create mode 100644 Menu/GameShell/21_Warehouse/aria2_download_process_page.go create mode 100644 Menu/GameShell/21_Warehouse/image_download_process_page.go create mode 100644 Menu/GameShell/21_Warehouse/load_house_page.go create mode 100644 Menu/GameShell/21_Warehouse/plugin_init.go create mode 100644 Menu/GameShell/21_Warehouse/ware_house_list_item.go create mode 100644 Menu/GameShell/21_Warehouse/ware_house_page.go create mode 100644 Menu/GameShell/21_Warehouse/ware_house_stack.go create mode 100644 sysgo/UI/yes_cancel__confirm_page.go diff --git a/Menu/GameShell/21_Warehouse/aria2_download_process_page.go b/Menu/GameShell/21_Warehouse/aria2_download_process_page.go new file mode 100644 index 0000000..1a045b5 --- /dev/null +++ b/Menu/GameShell/21_Warehouse/aria2_download_process_page.go @@ -0,0 +1,51 @@ +package Warehouse + +import ( + //"fmt" + //"os" + //gotime "time" + + //"github.com/cuu/gogame/image" + //"github.com/cuu/gogame/draw" + "github.com/cuu/gogame/color" + "github.com/clockworkpi/LauncherGoDev/sysgo/UI" +) + +type Aria2DownloadProcessPage struct { + UI.Page + URLColor *color.Color + TextColor *color.Color + + Icons map[string]UI.IconItemInterface + FileNameLabel UI.LabelInterface + SizeLabel UI.LabelInterface + +} + +func NewAria2DownloadProcessPage() *Aria2DownloadProcessPage { + p := &Aria2DownloadProcessPage{} + p.Icons = make(map[string]UI.IconItemInterfac) + + p.URLColor = UI.MySkinManager.GiveColor("URL") + p.TextColor = UI.MySkinManager.GiveColor("Text") + + p.FootMsg = [5]string{"Nav.","","Pause","Back","Cancel"} + + return p +} + +func (self *Aria2DownloadProcessPage) Init() { + self.PosX = self.Index * self.Screen.Width + self.Width = self.Screen.Width + self.Height = self.Screen.Height + + self.CanvasHWND = self.Screen.CanvasHWND + + bgpng := UI.NewIconItem() + bgpng.ImgSurf = UI.MyIconPool.GiveIconSurface("rom_download") + bgpng.MyType = UI.ICON_TYPES["STAT"] + bgpng.Parent = self + bgpng.Adjust(0,0,UI.MyIconPool.Width("rom_download"),UI.MyIconPool.Height("rom_download"),0) + self.Icons["bg"] = bgpng + +} diff --git a/Menu/GameShell/21_Warehouse/image_download_process_page.go b/Menu/GameShell/21_Warehouse/image_download_process_page.go new file mode 100644 index 0000000..67a451e --- /dev/null +++ b/Menu/GameShell/21_Warehouse/image_download_process_page.go @@ -0,0 +1,197 @@ +package Warehouse + +import ( + "fmt" + "os" + gotime "time" + "encoding/json" + + "github.com/veandco/go-sdl2/ttf" + "github.com/clockworkpi/LauncherGoDev/sysgo/UI" + "github.com/cuu/gogame/image" + "github.com/cuu/gogame/draw" + "github.com/cuu/gogame/color" + "github.com/cuu/grab" +) + +type WareHouseIndex struct { + List []map[string]string `json:"list"` +} + + +type ImageDownloadProcessPage struct { + UI.Page + + ListFontObj *ttf.Font + + URLColor *color.Color + TextColor *color.Color + + Downloader *grab.Client + resp *grab.Response + req *grab.Request + URL string + Value int + LoadingLabel *UI.LabelInterface + + Img *sdl.Surface + Downloading chan bool + Parent *WareHouse + +} + + +func NewImageDownloadProcessPage() *ImageDownloadProcessPage { + p := &ImageDownloadProcessPage{} + p.ListFontObj = UI.MyLangManager.TrFont("varela13") + p.URLColor = UI.MySkinManager.GiveColor("URL") + p.TextColor = UI.MySkinManager.GiveColor("Text") + p.FootMsg = [5]string{"Nav.","","","Back",""} + + return p +} + +func (self *ImageDownloadProcessPage) Init() { + self.PosX = self.Index * self.Screen.Width + self.Width = self.Screen.Width + self.Height = self.Screen.Height + + self.CanvasHWND = self.Screen.CanvasHWND + self.LoadingLabel = UI.NewLabel() + self.LoadingLabel.SetCanvasHWND(self.CanvasHWND) + self.LoadingLabel.Init("Loading",self.ListFontObj,nil) + self.LoadingLabel.SetColor(self.TextColor) + + self.Downloader = grab.NewClient() + self.Downloading = make(chan bool) +} + + +func (self *ImageDownloadProcessPage) OnLoadCb() { + + if len(self.URL) < 10 { + return + } + + self.ClearCanvas() + self.Screen.Draw() + self.Screen.SwapAndShow() + + parts := strings.Split(self.URL,"/") + filename := strings.TrimSpace(parts[len(parts)-1]) + local_dir := strings.Split(self.URL,"raw.githubusercontent.com") + home_path, _ := os.UserHomeDir() + + if len(local_dir) > 1 { + menu_file := local_dir[1] + local_menu_file := fmt.Sprintf("%s/aria2downloads%s", + home_path,menu_file) + + if UI.FileExists(local_menu_file) { + self.Img = image.Load(local_menu_file) + self.Screen.Draw() + self.Screen.SwapAndShow() + }else { + + self.req,_ = grab.NewRequest("/tmp",self.URL) + self.resp = self.Downloader.Do(self.req) + for len(self.Downloading) > 0 { + <-self.Downloading + } + self.Downloading <- true + + go self.UpdateProcessInterval(400) + + } + } +} + +func (self *ImageDownloadProcessPage) UpdateProcessInterval(ms int) { + + t := gotime.NewTicker(ms * time.Millisecond) + defer t.Stop() + + for { + select { + case <-t.C: + fmt.Printf(" transferred %v / %v bytes (%.2f%%)\n", + self.resp.BytesComplete(), + self.resp.Size, + 100*self.resp.Progress()) + + case <-self.resp.Done: + // download is complete + break + case v:= <-self.Downloading + if v == false { + t.Stop() + break + } + } + } + + dst_filename := self.resp.Filename + + if err := self.resp.Err(); err == nil {//download successfully + home_path, _ := os.UserHomeDir() + parts := strings.Split(self.URL,"/") + filename := strings.TrimSpace(parts[len(parts)-1]) + local_dir := strings.Split(self.URL,"raw.githubusercontent.com") + + local_menu_file := "" + menu_file := "" + + if len(local_dir) > 1 { + menu_file = local_dir[1] + local_menu_file = fmt.Sprintf("%s/aria2downloads%s", + home_path,menu_file) + } + + dl_file := path.Join("/tmp",filename) + if UI.IsDirectory( Path.Base(local_menu_file) ) == false { + merr := os.MkdirAll( Path.Base(local_menu_file), os.ModePerm) + if merr != nil { + panic(merr) + } + } + + UI.CopyFile(dl_file,local_menu_file) + + } + + if UI.FileExists(dst_filename) { + if self.Screen.CurPage() == self { + self.Img = image.Load(dst_filename) + self.Screen.Draw() + self.Screen.SwapAndShow() + } + } + + +} + + +func (self *ImageDownloadProcessPage) KeyDown(ev *event.Event) { + + if IsKeyMenuOrB(ev.Data["Key")) { + + self.Downloading <- false + + self.ReturnToUpLevelPage() + self.Screen.Draw() + self.Screen.SwapAndShow() + self.URL = "" + } +} + +func (self *ImageDownloadProcessPage) Draw() { + self.ClearCanvas() + self.LoadingLabel.NewCoord( (UI.Width - self.LoadingLabel.Width)/2,(UI.Height-44)/2); + self.LoadingLabel.Draw() + if self.Img != nil { + self.CanvasHWND.Blit(self.Img,draw.MidRect(UI.Width/2,(UI.Height-44)/2, + self.Img.Width,self.Img.Height, + UI.Width,UI.Height-44)) + } +} + diff --git a/Menu/GameShell/21_Warehouse/load_house_page.go b/Menu/GameShell/21_Warehouse/load_house_page.go new file mode 100644 index 0000000..7eab57f --- /dev/null +++ b/Menu/GameShell/21_Warehouse/load_house_page.go @@ -0,0 +1,194 @@ +package Warehouse + +import ( + "fmt" + "os" + gotime "time" + "encoding/json" + + "github.com/veandco/go-sdl2/ttf" + + "github.com/cuu/gogame/image" + "github.com/cuu/gogame/draw" + "github.com/cuu/gogame/color" + "github.com/clockworkpi/LauncherGoDev/sysgo/UI" + "github.com/cuu/grab" +) + +type LoadHousePage struct { + UI.Page + ListFontObj *ttf.Font + URLColor *color.Color + TextColor *color.Color + + Downloader *grab.Client + resp *grab.Response + req *grab.Request + + URL string + Downloading chan bool + LoadingLabel *UI.LabelInterface + + Parent *WareHouse +} + +func NewLoadHousePage() *LoadHousePage { + p := &LoadHousePage{} + + p.ListFontObj = UI.MyLangManager.TrFont("varela18") + p.URLColor = UI.MySkinManager.GiveColor("URL") + p.TextColor = UI.MySkinManager.GiveColor("Text") + p.FootMsg = [5]string{"Nav.","","","Back","Cancel"} + + return p +} + +func (self *LoadHousePage) Init() { + + self.PosX = self.Index * self.Screen.Width + self.Width = self.Screen.Width + self.Height = self.Screen.Height + + self.CanvasHWND = self.Screen.CanvasHWND + self.LoadingLabel = UI.NewLabel() + self.LoadingLabel.SetCanvasHWND(self.CanvasHWND) + self.LoadingLabel.Init("Loading",self.ListFontObj,nil) + self.LoadingLabel.SetColor(self.TextColor) + + self.Downloader = grab.NewClient() + self.Downloading = make(chan bool) + +} + +func (self *LoadHousePage) OnLoadCb() { + + if len(self.URL) < 10 { + return + } + self.ClearCanvas() + self.Screen.Draw() + self.Screen.SwapAndShow() + + parts := strings.Split(self.URL,"/") + filename := strings.TrimSpace(parts[len(parts)-1]) + local_dir := strings.Split(self.URL,"raw.githubusercontent.com") + home_path, _ := os.UserHomeDir() + + if len(local_dir) > 1 { + menu_file := local_dir[1] + local_menu_file := fmt.Sprintf("%s/aria2downloads%s", + home_path,menu_file) + + if UI.FileExists(local_menu_file) { + var result WareHouseIndex + jsonFile, err := os.Open(local_menu_file) + if err != nil { + fmt.Println(err) + return + } + defer jsonFile.Close() + byteValue, _ := ioutil.ReadAll(jsonFile) + json.Unmarshal([]byte(JSON), &result) + + for _, repo := range result.List { + self.Parent.MyStack.Push(repo) + } + + self.Leave() + } else { + self.req,_ = grab.NewRequest("/tmp",self.URL) + self.resp = self.Downloader.Do(self.req) + + for len(self.Downloading) > 0 { + <-self.Downloading + } + + self.Downloading <- true + go self.UpdateProcessInterval(400) + } + + } +} + +func (self *LoadHousePage) UpdateProcessInterval(ms int) { + t := gotime.NewTicker(ms * time.Millisecond) + defer t.Stop() + + for { + select { + case <-t.C: + fmt.Printf(" transferred %v / %v bytes (%.2f%%)\n", + self.resp.BytesComplete(), + self.resp.Size, + 100*self.resp.Progress()) + + case <-self.resp.Done: + // download is complete + break + case v:= <-self.Downloading + if v == false { + t.Stop() + break + } + } + } + + dst_filename := self.resp.Filename + + if err := self.resp.Err(); err == nil {//download successfully + home_path, _ := os.UserHomeDir() + parts := strings.Split(self.URL,"/") + filename := strings.TrimSpace(parts[len(parts)-1]) + local_dir := strings.Split(self.URL,"raw.githubusercontent.com") + + local_menu_file := "" + menu_file := "" + + if len(local_dir) > 1 { + menu_file = local_dir[1] + local_menu_file = fmt.Sprintf("%s/aria2downloads%s", + home_path,menu_file) + } + dl_file := path.Join("/tmp",filename) + if UI.IsDirectory( Path.Base(local_menu_file) ) == false { + merr := os.MkdirAll( Path.Base(local_menu_file), os.ModePerm) + if merr != nil { + panic(merr) + } + } + + UI.CopyFile(dl_file,local_menu_file) + var result WareHouseIndex + jsonFile, err := os.Open(local_menu_file) + if err != nil { + fmt.Println(err) + return + } + defer jsonFile.Close() + byteValue, _ := ioutil.ReadAll(jsonFile) + json.Unmarshal([]byte(JSON), &result) + + for _, repo := range result.List { + self.Parent.MyStack.Push(repo) + } + + self.Leave() + + } else { + self.Screen.MsgBox.SetText("Fetch house failed") + self.Screen.MsgBox.Draw() + self.Screen.SwapAndShow() + } + +} + +func (self *LoadHousePage) Leave() { + + self.Download <- false + + self.ReturnToUpLevelPage() + self.Screen.Draw() + self.Screen.SwapAndShow() + self.URL = "" + +} diff --git a/Menu/GameShell/21_Warehouse/plugin_init.go b/Menu/GameShell/21_Warehouse/plugin_init.go new file mode 100644 index 0000000..4d84c40 --- /dev/null +++ b/Menu/GameShell/21_Warehouse/plugin_init.go @@ -0,0 +1,38 @@ +package Warehouse + +import ( + /* + "github.com/veandco/go-sdl2/ttf" + + "github.com/cuu/gogame/surface" + "github.com/cuu/gogame/event" + "github.com/cuu/gogame/rect" + "github.com/cuu/gogame/color" + */ + "github.com/clockworkpi/LauncherGoDev/sysgo/UI" + //"github.com/clockworkpi/LauncherGoDev/sysgo/DBUS" +) + +/******************************************************************************/ +type WareHousePlugin struct { + UI.Plugin + MainPage *WareHousePage +} + +func (self *WareHousePlugin) Init(main_screen *UI.MainScreen) { + self.MainPage = NewWareHousePage() + self.MainPage.SetScreen(main_screen) + self.MainPage.SetName("Tiny cloud") + self.MainPage.Init() +} + +func (self *WareHousePlugin) Run(main_screen *UI.MainScreen) { + if main_screen != nil { + main_screen.PushCurPage() + main_screen.SetCurPage(self.MainPage) + main_screen.Draw() + main_screen.SwapAndShow() + } +} + +var APIOBJ WareHousePlugin diff --git a/Menu/GameShell/21_Warehouse/ware_house_list_item.go b/Menu/GameShell/21_Warehouse/ware_house_list_item.go new file mode 100644 index 0000000..0f231b6 --- /dev/null +++ b/Menu/GameShell/21_Warehouse/ware_house_list_item.go @@ -0,0 +1,123 @@ +package Warehouse + +import ( + "github.com/clockworkpi/LauncherGoDev/sysgo/UI" + +) + +//GameStoreListItem in py +type WareHouseListItem struct { + UI.InfoPageListItem + + Type string +} + + + + +func NewWareHouseListItem() *WareHouseListItem { + + p := &WareHouseListItem{} + p.Height = UI.DefaultInfoPageListItemHeight + + p.Labels = make(map[string]UI.LabelInterface) + p.Icons = make(map[string]UI.IconItemInterface) + p.Fonts = make(map[string]*ttf.Font) + + return p +} + +func (self *WareHouseListItem) Init( text string) { + + l := UI.NewLabel() + l.CanvasHWND = self.Parent.GetCanvasHWND() + l.PosX = 10 + l.Init(text,self.Fonts["normal"]) + + self.Labels["text"] = l + + add_icon := NewIconItem() + add_icon.ImgSurf = UI.MyIconPool.GetImgSurf("add") + add_icon.Parent = self + add_icon.Init(0,0,UI.MyIconPool.Width("add"),UI.MyIconPool.Height("add"),0) + + ware_icon := NewIconItem() + ware_icon.ImgSurf = UI.MyIconPool.GetImgSurf("ware") + ware_icon.Parent = self + ware_icon.Init(0,0,UI.MyIconPool.Width("ware"),UI.MyIconPool.Height("ware"),0) + + app_icon := NewIconItem() + app_icon.ImgSurf = UI.MyIconPool.GetImgSurf("app") + app_icon.Parent = self + app_icon.Init(0,0,UI.MyIconPool.Width("app"),UI.MyIconPool.Height("app"),0) + + appdling_icon := NewIconItem() + appdling_icon.ImgSurf = UI.MyIconPool.GetImgSurf("appdling") + appdling_icon.Parent = self + appdling_icon.Init(0,0,UI.MyIconPool.Width("appdling"),UI.MyIconPool.Height("appdling"),0) + + blackheart_icon := NewIconItem() + blackheart_icon.ImgSurf = UI.MyIconPool.GetImgSurf("blackheart") + blackheart_icon.Parent = self + blackheart_icon.Init(0,0,UI.MyIconPool.Width("blackheart"),UI.MyIconPool.Height("blackheart"),0) + + self.Icons["add"] = add_icon + self.Icons["ware"] = ware_icon + self.Icons["app"] = app_icon + self.Icons["appdling"] = appdling_icon + self.Icons["blackheart"] = blackheart_icon + +} + +func (self *WareHouseListItem) Draw() { + if self.ReadOnly == true { + self.Labels["text"].SetColor( UI.MySkinManager.GiveColor("ReadOnlyText")) + } else { + self.Labels["text"].SetColor( UI.MySkinManager.GiveColor("Text")) + } + + padding := 17 + + if self.Type == "" { + padding = 0 + } + + if self.Type == "source" || self.Type == "dir" { + self.Icons["ware"].NewCoord(4,(self.Height - self.Icons["ware"].Height)/2) + self.Icons["ware"].DrawTopLeft() + } + + if self.Type == "launcher" || self.Type == "pico8" || self.Type == "tic80" { + _icon := app + if self.ReadOnly == true { + _icon = "appdling" + } + self.Icons[_icon].NewCoord(4,(self.Height - self.Icons[_icon].Height)/2) + self.Icons[_icon].DrawTopLeft() + } + + if self.Type == "add_house" { + self.Icons["add"].NewCoord(4,(self.Height-self.Icons["add"].Height)/2) + self.Icons["add"].DrawTopLeft() + } + + self.Labels["text"].PosX = self.Labels["text"].PosX + self.PosX + padding + self.Labels["text"].PosY = self.PosY + (self.Height-self.Labels["text"].Height)/2 + self.Labels["text"].Draw() + self.Labels["text"].PosX = self.Labels["text"].PosX - self.PosX - padding + + if _, ok := self.Labels["Small"]; ok { + x, _ = self.Labels["Small"].Coord() + w, h = self.Labels["Small"].Size() + + self.Labels["Small"].NewCoord(self.Width-w-5, self.PosY+(self.Height-h)/2) + self.Labels["Small"].Draw() + } + + canvas_ := self.Parent.GetCanvasHWND() + draw.Line(canvas_,UI.MySkinManager.GiveColor("Line"), + self.PosX,self.PosY + self.Height -1, + self.PosX+self.Width,self.PosY+self.Height-1, + 1) + +} diff --git a/Menu/GameShell/21_Warehouse/ware_house_page.go b/Menu/GameShell/21_Warehouse/ware_house_page.go new file mode 100644 index 0000000..3dfa772 --- /dev/null +++ b/Menu/GameShell/21_Warehouse/ware_house_page.go @@ -0,0 +1,269 @@ +package Warehouse + +import ( + "fmt" + "log" + + "database/sql" + _ "github.com/mattn/go-sqlite3" + +) + +type WareHouse struct { + + UI.Page + + ListFontObj15 *ttf.Font + ListFontObj12 *ttf.Font + + BGwidth int + BGheight int + DrawOnce bool + Scroller *UI.ListScroller + RemovePage *UI.YesCancelConfirmPage + Keyboard *UI.Keyboard + + WareHouseDB string + MyStack *WareHouseStack +} + +func NewWareHouse() *WareHouse { + + p := &WareHouse{} + p.ListFontObj12 = UI.MyLangManager.TrFont("notosanscjk12") + p.ListFontObj15 = UI.MyLangManager.TrFont("varela15") + + p.FootMsg = [5]string{"Nav","Update","Up","Back","Select"} + + p.WareHouseDB = "foo.db" + + p.BGWidth = 320 + p.BGheight = 240-24-20 + + p.MyStack = NewWareHouseStack() + + repo := make(map[string]string) + repo["title"] = "github.com/clockworkpi/warehouse" + repo["file"] = "https://raw.githubusercontent.com/clockworkpi/warehouse/master/index.json" + repo["type"] = "source" + + p.MyStack.Push(repo) + + return p +} + +func (self*WareHouse) UpdateProcessInterval(ms int) { + dirty := false + +} + +func (self *WareHouse) SyncWareHouse() []map[string]string { + db, err := sql.Open("sqlite3", self.WareHouseDB) + if err != nil { + log.Fatal(err) + } + defer db.Close() + + + //id,title,file,type + rows, err = db.Query("select * from warehouse") + if err != nil { + log.Fatal(err) + } + defer rows.Close() + + var ret []map[string]string + + for rows.Next() { + var id int + var title string + var file string + var type_ string + + err = rows.Scan(&id, &title,&file,&type_) + if err != nil { + log.Fatal(err) + } + + w_dbt := m = make(map[string]string) + w_dbt["title"] = title + w_dbt["file"] = file + w_dbt["type"] = type_ + ret = append(ret,w_dbt) + + } + return ret +} + +func (self *WareHouse) SyncTasks() []map[string]string { + db, err := sql.Open("sqlite3", self.WareHouseDB) + if err != nil { + log.Fatal(err) + } + defer db.Close() + + + //id,gid,title,file,type,status,totalLength,completedLength,fav + rows, err = db.Query("select * from tasks") + if err != nil { + log.Fatal(err) + } + defer rows.Close() + + var ret []map[string]string + + for rows.Next() { + var id int + var gid string + var title string + var file string + var type_ string + var status string + var totalLength string + var completedLength string + var fav string + + err = rows.Scan(&id,&gid, &title,&file,&type_,&status,&totalLength,&completedLength,&fav) + if err != nil { + log.Fatal(err) + } + + w_dbt := make(map[string]string) + w_dbt["gid"] = gid + w_dbt["title"] = title + w_dbt["file"] = file + w_dbt["type"] = type_ + w_dbt["status"] = status + w_dbt["totalLength"] = totalLength + w_dbt["completedLength"] = completedLength + + ret = append(ret,w_dbt) + + } + return ret +} + + +func (self *WareHouse) SyncList() { + + self.MyList = self.MyList[:0] + + start_x := 0 + start_y := 0 + + last_height := 0 + + var repos []map[string]string + + stk := self.MyStack.Last() + stk_len := self.MyStack.Length() + + repos = append(repos, stk) + + add_new_house := make(map[string]string) + add_new_house["title"] = "Add new warehouse..." + add_new_house["file"] = "master/index.json" + add_new_house["type"] = "add_house" + add_new_house["status"] = "complete" + + if stk_len == 1 {//on top + ware_menu := self.SyncWareHouse() + if len(ware_menu) > 0 { + repos = append(repos,ware_menu...) + } + + tasks_menu := self.SyncTasks() + if len(tasks_menu) > 0 { + repos = append(repos,tasks_menu...) + } + + repos = append(repos,add_new_house) + } + + for i, u := range repos { + li := WareHouseListItem{} + li.Parent = self + li.PosX = start_x + li.PosY = start_y + last_height + li.Width = UI.Width + li.Fonts["normal"] = self.ListFontObj15 + li.Fonts["small"] = self.ListFontObj12 + li.ReadOnly = true + li.Type = u["type"] + li.init(u["title"]) + + if stk_len > 1 { + remote_file_url := u["file"] + menu_file := strings.Split(remote_file_url,"raw.githubusercontent.com")[1] + home_path, err := os.UserHomeDir() + if err != nil { + log.Fatal( err ) + } + local_menu_file := fmt.Sprintf("%s/aria2download%s",home_path,menu_file) + if UI.FileExists(local_menu_file) { + li.ReadOnly = false + }else { + li.ReadOnly = true + } + } else if stk_len == 1 { + if _,ok := u["status"];ok { + if u["status"] == "complete" { + li.ReadOnly = false + } + } + + if u["type"] == "source" { + li.ReadOnly = false + } + } + + last_height += li.Height + if li.Type == "launcher" || li.Type == "pico8" || li.Type == "tic80" { + li.SetSmallText("") + } + self.MyList = append(self.MyList,li) + } + + self.RefreshPsIndex() +} + + +func (self *WareHouse) Init() { + + if self.Screen != nil { + if self.Screen.CanvasHWND != nil && self.CanvasHWND == nil { + self.HWND = self.Screen.CanvasHWND + self.CanvasHWND = surface.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 + + done := NewIconItem() + done.ImgSurf = UI.MyIconPool.GetImgSurf() + done.MyType = UI.ICON_TYPES["STAT"] + done.Parent = self + + self.Icons["done"] = done + + ps := UI.NewInfoPageSelector() + ps.Parent = self + self.Ps = ps + self.PsIndex = 0 + + self.SyncList() + + self.Scroller = UI.NewListScroller() + self.Scroller.Parent = self + self.Scroller.PosX = self.Width - 10 + self.Scroller.PosY = 2 + self.Scroller.Init() + self.Scroller.SetCanvasHWND(self.CanvasHWND) + + + + + } + +} diff --git a/Menu/GameShell/21_Warehouse/ware_house_stack.go b/Menu/GameShell/21_Warehouse/ware_house_stack.go new file mode 100644 index 0000000..c971e7d --- /dev/null +++ b/Menu/GameShell/21_Warehouse/ware_house_stack.go @@ -0,0 +1,64 @@ +package Warehouse + +import ( + "sync" +) + +type element struct { + data interface{} + next *element +} + +type WareHouseStack struct { + lock *sync.Mutex + head *element + Size int +} + +func (stk *WareHouseStack) 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 *WareHouseStack) 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 *WareHouseStack) Length() int { + return stk.Size +} + +func (stk *WareHouseStack) Last() interface{} { + idx := stk.Length() -1 + if idx < 0 { + return nil + } else { + return stk.head.data + } +} + +func NewWareHouseStack() *WareHouseStack { + stk := new(WareHouseStack) + stk.lock = &sync.Mutex{} + return stk +} + + diff --git a/sysgo/UI/icon_pool.go b/sysgo/UI/icon_pool.go index 85fc587..47d0e06 100644 --- a/sysgo/UI/icon_pool.go +++ b/sysgo/UI/icon_pool.go @@ -38,6 +38,7 @@ func (self *IconPool) Init() { keyname := strings.Split(f.Name(), ".") if len(keyname) > 1 { self.Icons[keyname[0]] = image.Load(self.GameShellIconPath + "/" + f.Name()) + } } } @@ -48,8 +49,32 @@ func (self *IconPool) GetImgSurf(keyname string) *sdl.Surface { if _, ok := self.Icons[keyname]; ok { return self.Icons[keyname] } else { - fmt.Println("IconPool GetImgSurf ", keyname, " failed") - return nil + icon_file := self.GameShellIconPath+"/"+keyname+".png" + if IsAFile(icon_file) { + self.Icons[keyname] = image.Load(icon_file) + return self.Icons[keyname] + }else { + fmt.Println("IconPool GetImgSurf ", keyname, " failed") + return nil + } + } +} + +func (self *IconPool) Width(keyname string) int { + if _,ok := self.Icons[keyname]; ok { + return int(self.Icons[keyname].W) + }else { + fmt.Println("IconPool lookup ", keyname, " failed") + return 0 + } +} + +func (self *IconPool) Height(keyname string) int { + if _,ok := self.Icons[keyname]; ok { + return int(self.Icons[keyname].W) + }else { + fmt.Println("IconPool lookup ", keyname, " failed") + return 0 } } diff --git a/sysgo/UI/keys_def.go b/sysgo/UI/keys_def.go index 8b01036..997cf40 100644 --- a/sysgo/UI/keys_def.go +++ b/sysgo/UI/keys_def.go @@ -65,3 +65,11 @@ func keys_def_init() { CurKeys = PC } } + +func IsKeyStartOrA(key string) bool { + return key == CurKeys["Start"] || key == CurKeys["A"] +} + +func IsKeyMenuOrB(key string) bool { + return key == CurKeys["Menu"] || key == CurKeys["B"] +} diff --git a/sysgo/UI/page.go b/sysgo/UI/page.go index b2bc00d..6e530e5 100644 --- a/sysgo/UI/page.go +++ b/sysgo/UI/page.go @@ -177,7 +177,8 @@ type PageInterface interface { SetIconIndex(idx int) GetIconIndex() int - + RefreshPsIndex() + Coord() (int, int) NewCoord(x, y int) Size() (int, int) @@ -959,6 +960,15 @@ func (self *Page) GetPsIndex() int { return self.PsIndex } +func (self *Page) RefreshPsIndex() { + if len(self.MyList) == 0 { + self.SetPsIndex(0) + } + if self.GetPsIndex() > len(self.MyList) -1 { + self.SetPsIndex( len(self.MyList) - 1) + } +} + func (self *Page) SetIconIndex(idx int) { self.IconIndex = idx } diff --git a/sysgo/UI/util_funcs.go b/sysgo/UI/util_funcs.go index 39bbce1..e1ea01b 100644 --- a/sysgo/UI/util_funcs.go +++ b/sysgo/UI/util_funcs.go @@ -292,3 +292,60 @@ func ExecCmd(cmdArgs []string) ([]byte, error) { } return out, err } + +func CopyFile(src, dst string) (err error) { + sfi, err := os.Stat(src) + if err != nil { + return + } + if !sfi.Mode().IsRegular() { + // cannot copy non-regular files (e.g., directories, + // symlinks, devices, etc.) + return fmt.Errorf("CopyFile: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String()) + } + dfi, err := os.Stat(dst) + if err != nil { + if !os.IsNotExist(err) { + return + } + } else { + if !(dfi.Mode().IsRegular()) { + return fmt.Errorf("CopyFile: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String()) + } + if os.SameFile(sfi, dfi) { + return + } + } + if err = os.Link(src, dst); err == nil { + return + } + err = copyFileContents(src, dst) + return +} + +// copyFileContents copies the contents of the file named src to the file named +// by dst. The file will be created if it does not already exist. If the +// destination file exists, all it's contents will be replaced by the contents +// of the source file. +func copyFileContents(src, dst string) (err error) { + in, err := os.Open(src) + if err != nil { + return + } + defer in.Close() + out, err := os.Create(dst) + if err != nil { + return + } + defer func() { + cerr := out.Close() + if err == nil { + err = cerr + } + }() + if _, err = io.Copy(out, in); err != nil { + return + } + err = out.Sync() + return +} diff --git a/sysgo/UI/yes_cancel__confirm_page.go b/sysgo/UI/yes_cancel__confirm_page.go new file mode 100644 index 0000000..826454b --- /dev/null +++ b/sysgo/UI/yes_cancel__confirm_page.go @@ -0,0 +1,63 @@ +package UI + +import ( + //"fmt" + //"os" + //"path/filepath" + //"strings" + + "github.com/cuu/gogame/event" + //"github.com/cuu/gogame/time" +) + +type Func func() + +type YesCancelConfirmPage struct { + ConfirmPage + StartOrAEvent Func + KeyXEvent Func + KeyYEvent Func +} + +func NewYesCancelConfirmPage() *YesCancelConfirmPage { + p := &YesCancelConfirmPage{} + p.FootMsg = [5]string{"Nav","","","Cancel","Yes"} + p.ConfirmText = MyLangManager.Tr("Awaiting Input") + + p.StartOrAEvent = nil + p.KeyXEvent = nil + p.KeyYEvent = nil + + return p +} + +func (self *YesCancelConfirmPage) KeyDown(ev *event.Event) { + + if UI.IsKeyMenuOrB(ev.Data["Key"]) { + self.ReturnToUpLevelPage() + self.Screen.Draw() + self.Screen.SwapAndShow() + } + + if UI.IsKeyStartOrA(ev.Data["Key"]) { + if self.StartOrAEvent != nil { + self.StartOrAEvent() + self.ReturnToUpLevelPage() + } + } + + if ev.Data["Key"] == CurKeys["X"] { + if self.KeyXEvent != nil { + self.KeyXEvent() + self.ReturnToUpLevelPage() + } + } + + if ev.Data["Key"] == CurKeys["Y"] { + if self.KeyYEvent != nil { + self.KeyYEvent() + self.ReturnToUpLevelPage() + } + } + +}