diff --git a/sysgo/UI/.#main_screen.go b/sysgo/UI/.#main_screen.go deleted file mode 120000 index 10d67b4..0000000 --- a/sysgo/UI/.#main_screen.go +++ /dev/null @@ -1 +0,0 @@ -guu@guu-desktop.31499:1528607783 \ No newline at end of file diff --git a/sysgo/UI/fonts.go b/sysgo/UI/fonts.go new file mode 100644 index 0000000..91a7427 --- /dev/null +++ b/sysgo/UI/fonts.go @@ -0,0 +1,51 @@ +package UI + +import ( + + "fmt" + + "github.com/veandco/go-sdl2/ttf" + + "github.com/cuu/gogame/font" + "../sysgo" +) + +var Fonts map[string]*ttf.Font + +func init() { + font.Init() + + skinpath := "../skin/"+sysgo.SKIN+"/truetype" + + Fonts = make(map[string]*ttf.Font) + + fonts_path := make(map[string]string) + + + fonts_path["varela"] = fmt.Sprintf("%s/VarelaRound-Regular.ttf",skinpath) + fonts_path["veramono"] = fmt.Sprintf("%s/VeraMono.ttf",skinpath) + fonts_path["noto"] = fmt.Sprintf("%s/NotoSansMono-Regular.ttf", skinpath) + fonts_path["notocjk"] = fmt.Sprintf("%s/NotoSansCJK-Regular.ttf" ,skinpath) + + for i:=12;i<41;i++ { + keyname := fmt.Sprintf("varela%d",i) + Fonts[ keyname ] = font.Font(fonts_path["varela"],i) + } + + for i:=10;i<26;i++ { + keyname := fmt.Sprintf("veramono%d", i) + Fonts[keyname] = font.Font(fonts_path["veramono"],i) + } + + for i:= 10;i<18;i++ { + keyname := fmt.Sprintf("notosansmono%d", i) + Fonts[keyname] = font.Font(fonts_path["noto"], i) + } + + for i:=10;i<18;i++ { + keyname := fmt.Sprintf("notosanscjk%d",i) + Fonts[keyname] = font.Font(fonts_path["notocjk"],i) + } +} + + diff --git a/sysgo/UI/foot_bar.go b/sysgo/UI/foot_bar.go index e69de29..cf69d0b 100644 --- a/sysgo/UI/foot_bar.go +++ b/sysgo/UI/foot_bar.go @@ -0,0 +1,7 @@ +package UI + +var FootBar_BarHeight = 20 + +type FootBar struct { + +} diff --git a/sysgo/UI/label.go b/sysgo/UI/label.go index 97f7930..3f6172a 100644 --- a/sysgo/UI/label.go +++ b/sysgo/UI/label.go @@ -41,6 +41,7 @@ func (self *Label) Init(text string, font_obj *ttf.Font,col *color.Color ) { if col != nil { self.Color = col } + self.Text = text diff --git a/sysgo/UI/main_screen.go b/sysgo/UI/main_screen.go index 2ca4f4f..259cbb4 100644 --- a/sysgo/UI/main_screen.go +++ b/sysgo/UI/main_screen.go @@ -2,19 +2,273 @@ package UI import ( + "strings" + "github.com/veandco/go-sdl2/sdl" + "github.com/veandco/go-sdl2/ttf" + + "github.com/cuu/gogame/display" + "github.com/cuu/gogame/surface" + "github.com/cuu/gogame/color" ) +var ( + emulator_flag = "action.config" + plugin_flag = "plugin.config" +) + +type MessageBox struct { + Label + Parent *MainScreen + +} + +func NewMessageBox() *MessageBox { + m := &MessageBox{} + m.Color = &color.Color{83,83,83,255} + + return m +} + +func (self *MessageBox) Init( text string, font_obj *ttf.Font, col *color.Color) { + if col != nil { + self.Color = col + } + + self.Text = text + self.FontObj = font_obj + + self.Width = 0 + self.Height = 0 + + self.CanvasHWND = surface.Surface(self.Parent.Width, self.Parent.Height) + self.HWND = self.Parent.CanvasHWND + +} + +func (self *MessageBox) SetText( text string) { + self.Text = text +} + +func (self *MessageBox) Draw() { + self.Width = 0 + self.Height = 0 + surface.Fill(self.CanvasHWND, color.Color{255,255,255,255} ) + + words := strings.Split(self.Text," ") + space,_ := font.Size(self.FontObj," ") + + max_width := self.Parent.Width - 40 + x := 0 + y := 0 + + row_total_width := 0 + lines := 0 + + for _,word := range words { + word_surface := font.Render( self.FontObj, word, true, self.Color,nil) + word_width := word_surface.W + word_height := word_surface.H + row_total_width += word_width + if lines == 0 { + lines += word_height + } + + if (row_total_width + space ) >= max_width { + x = 0 + y += word_height + row_total_width = word_width + lines+=word_height + } + + dest_rect := rect.Rect(x,y, word_width,word_height) + surface.Blit(self.CanvasHWND, word_surface, &dest_rect,nil) + if len(words) == 1 { + x+=word_width + } else { + x += word_width+space + } + + if x > self.Width { + self.Width = x + } + + if lines >= self.Parent.Height - 40 { + break + } + } + + self.Height = lines + + padding := 5 + x = (self.Parent.Width - self.Width) / 2 + y = (self.Parent.Height - self.Height) /2 + + rect_ := rect.Rect(x-padding,y-padding, self.Width+padding*2, self.Height+padding*2) + + draw.Rect(self.HWND , &color.Color{255,255,255,255},&rect_,0) + + if self.HWND != nil { + rect__ := draw.MidRect(self.Parent.Width/2, self.Parent.Height/2,self.Width,self.Height,Width,Height) + dest_rect := rect.Rect(0,0,self.Width,self,Height) + surface.Blit(self.HWND, rect__, &dest_rect,nil) + } + + draw.Rect(self.HWND , &color.Color{0,0,0,255},&rect_,1) + +} + type MainScreen struct { - Pages []interface{} + Pages []PageInterface PageMax int PageIndex int PosX int PosY int - + Width int + Height int + MyPageStack *PageStack + CurrentPage PageInterface + CanvasHWND *sdl.Surface + HWND *sdl.Surface + TitleBar *TitleBar + FootBar *FootBar + MsgBox *MessageBox + MsgBoxFont *ttf.Font + IconFont *ttf.Font + SkinManager *SkinManager } func NewMainScreen() *MainScreen { m := &MainScreen{} + + m.PosY = TitleBar_BarHeight+1 + m.Width = Width + m.Height = Height - FootBar_BarHeight - TitleBar_BarHeight - 1 + m.MyPageStack = NewPageStack() + +} + +func (self *MainScreen) Init() { + self.CanvasHWND = surface.Surface(self.Width,self.Height) + + self.MsgBox = NewMessageBox() + self.MsgBox.Parent = self + self.MsgBox.Init(" ", self.MsgBoxFont, &color.Color{83,83,83}) + + self.SkinManager = NewSkinManager() + self.SkinManager.Init() +} + +func (self *MainScreen) FartherPages() { // right after ReadTheDirIntoPages + self.PageMax = len(self.Pages) + + for i:=0;i< self.PageMax; i++ { + self.Pages[i].SetIndex(i) + self.Pages[i].SetCanvasHWND(self.CanvasHWND) + self.Pages[i].UpdateIconNumbers() // IconNumbers always == len(Pages[i].Icons) + self.Pages[i].SetScreen(self) + + if self.Pages[i].GetIconNumbers() > 1 { + self.Pages[i].SetPsIndex(1) + self.Pages[i].SetIconIndex( 1 ) + } + } + + self.CurrentPage = self.Pages[ self.PageIndex ] + self.CurrentPage.SetOnShow(true) +} + + + +func (self *MainScreen) CurPage() PageInterface { + return self.CurrentPage +} + +func (self *MainScreen) PushCurPage() { + self.MyPageStack.Push(self.CurrentPage) +} + +func (self *MainScreen) SetCurPage( pg PageInterface) { + self.CurrentPage = pg + pg.OnLoadCb() +} + +func (self *MainScreen) PushPage( pg PageInterface) { + self.PushCurPage() + self.SetCurPage(pg) +} + +func (self *MainScreen) AppendPage( pg PageInterface ) { + self.Pages = append(self.Pages,pg) +} + +func (self *MainScreen) ClearCanvas() { + surface.Fill(self.CanvasHWND, color.Color{255,255,255,255} ) +} + +func (self *MainScreen) SwapAndShow() { + if self.HWND != nil { + rect_ := rect.Rect( self.PosX,self.PosY,self.Width,self.Height) + surface.Blit(self.HWND,self.CanvasHWND,*rect_, nil) + } +} + +func (self *MainScreen) ExtraName(name string) string { + + parts := strings.Split(name,"_") + if len(parts) > 1 { + return parts[1] + }else if len(parts) == 1 { + return parts[0] + }else { + return name + } +} + +func (self *MainScreen) IsPluginPackage(dirname string ) bool { + ret := false + files,err := ioutil.ReadDir(dirname) + if err != nil { + log.Fatal(err) + return false + } + + for _,f := range files { + if f.IsDir() { + //pass + }else { + if strings.HasSuffix(f.Name(),plugin_flag) == true { + ret = true + break + } + } + } + + return ret +} + +func (self *MainScreen) IsEmulatorPackage(dirname string ) bool { + ret := false + files,err := ioutil.ReadDir(dirname) + if err != nil { + log.Fatal(err) + return false + } + + for _,f := range files { + if f.IsDir() { + //pass + }else { + if strings.HasSuffix(f.Name(),emulator_flag) == true { + ret = true + break + } + } + } + + return ret +} + +func (self *MainScreen) ReadTheDirIntoPages(_dir string, pglevel int, cur_page PageInterface) { } diff --git a/sysgo/UI/page.go b/sysgo/UI/page.go index bb67a09..d2f76e2 100644 --- a/sysgo/UI/page.go +++ b/sysgo/UI/page.go @@ -155,6 +155,10 @@ type PageInterface interface { // GetIconIndex // Coord // Size + // UpdateIconNumbers + // GetIconNumbers + // SetOnShow + } @@ -445,6 +449,19 @@ func (self *Page) Adjust() { // default init way, } +func (self *Page) SetOnShow( on_show bool) { + self.OnShow = on_show +} + +func (self *Page) UpdateIconNumbers() { + + self.IconNumbers = len(self.Icons) + +} + +func (self *Page) GetIconNumbers() int { + return self.IconNumbers +} func (self *Page) Init() { @@ -760,6 +777,7 @@ func (self *Page) DrawIcons() { } + func (self *Page) KeyDown( ev *event.Event) { if ev.Data["Key"] == CurKeys["A"] { @@ -812,6 +830,14 @@ func (self *Page) KeyDown( ev *event.Event) { } +func (self *Page) OnLoadCb() { + +} + +func (self *Page) OnReturnBackCb() { + +} + func (self *Page) Draw() { self.ClearCanvas() self.DrawIcons() diff --git a/sysgo/UI/plugin.go b/sysgo/UI/plugin.go index 0b161bc..3468e22 100644 --- a/sysgo/UI/plugin.go +++ b/sysgo/UI/plugin.go @@ -1,15 +1,23 @@ package UI +import ( + "plugin" +) +var PluginPool = NewPluginPool() type PluginInterface { + Name() string Init(screen *MainScreen) Run(screen *MainScreen) } type Plugin struct { - + Name string // only ID for plugin } +func (self *Plugin) Name() string { + return self.Name +} func (self *Plugin) Init( screen *MainScreen) { @@ -19,3 +27,59 @@ func (self *Plugin) Init( screen *MainScreen) { func (self *Plugin) Run( screen *MainScreen) { } + + +func NewPluginPool() map[string]PluginInterface { + pp :=make( map[string]PluginInterface ) + return pp +} + +func PluginPoolRegister( pi PluginInterface ) bool { + name := pi.Name() + + if _,ok := PluginPool[name]; ok { + return false + } + + PluginPool[name] = pi +} + +func LoadPlugin( pname string) (*plugin.Plugin,error) { + return plugin.Load(pname) +} + +func InitPlugin(p *plugin.Plugin, main_screen *MainScreen) { + symAPI,err := p.Lookup("APIOBJ") + + if err!= nil { + log.Fatal( "init plugin failed") + return + } + + var pi PluginInterface + pi,ok := symAPI.(PluginInterface) + if !ok { + log.Fatal("unexpected type from module symbol") + return + } + + pi.Init(main_screen) +} + +func RunPlugin(p *plugin.Plugin, main_screen *MainScreen) { + symAPI,err := p.Lookup("APIOBJ") + + if err!= nil { + log.Fatal( "init plugin failed") + return + } + + var pi PluginInterface + pi,ok := symAPI.(PluginInterface) + if !ok { + log.Fatal("unexpected type from module symbol") + return + } + pi.Run(main_screen) +} + diff --git a/sysgo/UI/plugins/HelloWorld/helloworld.go b/sysgo/UI/plugins/HelloWorld/helloworld.go new file mode 100644 index 0000000..2023b9d --- /dev/null +++ b/sysgo/UI/plugins/HelloWorld/helloworld.go @@ -0,0 +1,16 @@ +package main + +import ( + "../../UI" +) + + +type HelloWorldPlugin struct { + UI.Plugin + +} + + + + + diff --git a/sysgo/UI/skin_manager.go b/sysgo/UI/skin_manager.go new file mode 100644 index 0000000..2783b7f --- /dev/null +++ b/sysgo/UI/skin_manager.go @@ -0,0 +1,86 @@ +package UI + + +import ( + "strings" + + "github.com/go-ini/ini" + + "github.com/cuu/gogame/color" + + "../sysgo" +) + +type SkinManager struct { + Colors map[string]*color.Color + +} + +func NewSkinManager() *SkinManager { + s := &SkinManager{} + + return s +} + + +func (self *SkinManager) ConvertToRGB(hexstr string) *color.Color { + if len(hexstr) < 7 || hexstr[0] != '#' { // # 00 00 00 + log.Fatalf("ConvertToRGB hex string format error %s", hexstr) + return nil + } + + h := strings.TrimLeft(hexstr,"#") + + r := strconv.ParseInt(hexstr[0:2], 16,0) + g := strconv.ParseInt(hexstr[2:4], 16,0) + b := strconv.ParseInt(hexstr[4:6], 16,0) + + col := &color.Color{ r,g,b,255 } + return col +} + +func (self *SkinManager) Init() { + self.Colors = make(map[string]*color.Color) + + self.Colors["High"] = &color.Color{51,166,255,255} + self.Colors["Text"] = &color.Color{83,83,83,255} + self.Colors["Front"] = &color.Color{131,199,219,255} + self.Colors["URL"] = &color.Color{51,166,255,255} + self.Colors["Line"] = &color.Color{169,169,169,255} + self.Colors["TitleBg"] = &color.Color{228,228,228,255} + self.Colors["Active"] = &color.Color{175,90,0,255} + self.Colors["White"] = &color.Color{255,255,255,255} + + + fname := "../skin/"+sysgo.SKIN+"/config.cfg" + + cfg, err := ini.Load( fname ) + if err != nil { + fmt.Printf("Fail to read file: %v", err) + return + } + + section := cfg.Section("Colors") + if section != nil { + colour_opts := section.KeyStrings() + for _,v := range colour_opts { + if _, ok := self.Colors[v]; ok { // has this Color key + parsed_color := self.ConvertToRGB( section.Key(v).String() ) + if parsed_color != nil { + self.Colors[v] = parsed_color + } + } + } + } +} + + +func (self *SkinManager) GiveColor(name string) *color.Color { + + if val,ok := self.Colors[name]; ok { + return val + }else { + return &color.Color{255,0,0,255} + } +} + diff --git a/test.go b/test.go index bfd33a0..bb0a47e 100644 --- a/test.go +++ b/test.go @@ -32,7 +32,7 @@ func run() int { //surface.FillRect(screen,&rect, 0xffff0000) rect1.X = 12 - draw.Rect(screen,color.Color{129,235,234,255},&rect1,1) + draw.Rect(screen,&color.Color{129,235,234,255},&rect1,1) fmt.Println(screen.Pitch) fmt.Println( screen.BytesPerPixel() ) @@ -62,7 +62,7 @@ func run() int { // draw.Line(screen,color.Color{255,44,255,0}, 10, 0, 10,250,4) rect2 := rect.Rect(3,120,200,30) - draw.AARoundRect(screen,&rect2,color.Color{0,213,222,255},10,0, color.Color{0,213,222,255}) + draw.AARoundRect(screen,&rect2,&color.Color{0,213,222,255},10,0, &color.Color{0,213,222,255}) font.Init() @@ -73,11 +73,11 @@ func run() int { fmt.Println( font.LineSize( notocjk15 )) - my_text := font.Render(notocjk15,"Test ㆑ ㆒ ㆓ ㆔ ㆕ ㆖ 豈 更 車 賈 滑 串 句 龜 龜 契 金 ",true, color.Color{234,123,12,255},nil) + my_text := font.Render(notocjk15,"Test ㆑ ㆒ ㆓ ㆔ ㆕ ㆖ 豈 更 車 賈 滑 串 句 龜 龜 契 金 ",true, &color.Color{234,123,12,255},nil) surface.Blit(screen,my_text,draw.MidRect(width/2,100,surface.GetWidth(my_text),surface.GetHeight(my_text),width,height),nil) - my_text2 := font.Render(notocjk15,"Test ㆑ ㆒ ㆓ ㆔ ㆕ ㆖ 豈 更 車 賈 滑 串 句 龜 龜 契 金 ",true, color.Color{234,123,12,255},&color.Color{0,0,111,255}) + my_text2 := font.Render(notocjk15,"Test ㆑ ㆒ ㆓ ㆔ ㆕ ㆖ 豈 更 車 賈 滑 串 句 龜 龜 契 金 ",true, &color.Color{234,123,12,255},&color.Color{0,0,111,255}) surface.Blit(screen,my_text2,draw.MidRect(width/2,100+font.LineSize(notocjk15),surface.GetWidth(my_text),surface.GetHeight(my_text),width,height),nil) display.Flip()