package UI import ( "fmt" "strings" "github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/ttf" "github.com/cuu/gogame/surface" "github.com/cuu/gogame/color" "github.com/cuu/gogame/draw" "github.com/cuu/gogame/font" "github.com/cuu/gogame/rect" ) type Textarea struct { Widget BackgroundColor *color.Color CanvasHWND *sdl.Surface MyWords []string BlitWords []string FontObj *ttf.Font LineNumber int TextLimit int TextFull bool TextIndex int BlitIndex int } func NewTextarea() *Textarea { p := &Textarea{} p.TextLimit = 63 p.TextFull = false p.MyWords = make([]string,0) p.BlitWords = make([]string,0) p.BackgroundColor = &color.Color{228,228,228,255} return p } func (self *Textarea) Init() { self.FontObj = Fonts["veramono24"] } func (self *Textarea) SubTextIndex() { self.TextIndex -= 1 if self.TextIndex < 0 { self.TextIndex = 0 } } func (self *Textarea) AddTextIndex() { self.TextIndex += 1 if self.TextIndex > len(self.MyWords) { self.TextIndex = len(self.MyWords) } } func (self *Textarea) ResetMyWords() { self.MyWords = nil self.TextIndex = 0 } func (self *Textarea) RemoveFromLastText() []string { if len(self.MyWords) > 0 { self.SubTextIndex() if self.TextIndex < len(self.MyWords) { self.MyWords = append(self.MyWords[:self.TextIndex],self.MyWords[(self.TextIndex+1):]...) } } return self.MyWords } func (self *Textarea) AppendText( alphabet string) { self.AppendAndBlitText(alphabet) } func (self *Textarea) AppendAndBlitText(alphabet string) { if self.TextFull == false { if self.TextIndex <= len(self.MyWords) { self.MyWords = append(self.MyWords[:self.TextIndex], append([]string{alphabet},self.MyWords[self.TextIndex:]...)...) self.BlitText() self.AddTextIndex() } }else { fmt.Printf("is Full %s\n",strings.Join(self.MyWords,"")) } } func (self *Textarea) BuildBlitText() { blit_rows := make([][]string,0) blit_rows = append(blit_rows,[]string{}) w := 0 // xmargin := 5 endmargin :=15 linenumber := 0 cursor_row := 0 for i,v := range self.MyWords { t := font.Render(self.FontObj,v,true,&color.Color{8,135,174,255},nil) t_width := surface.GetWidth(t) w+=t_width blit_rows[linenumber] = append(blit_rows[linenumber],v) if i == self.TextIndex - 1 { cursor_row = linenumber } if w + t_width >= self.Width - endmargin { w = 0 linenumber += 1 blit_rows = append(blit_rows,[]string{}) } t.Free() } if len(blit_rows) == 1 { self.BlitWords = blit_rows[0] self.BlitIndex = self.TextIndex }else if len(blit_rows) == 2 || cursor_row < 2 { self.BlitWords = append(blit_rows[0], blit_rows[1]...) self.BlitIndex = self.TextIndex }else { self.BlitWords = append(blit_rows[cursor_row-1], blit_rows[cursor_row]...) self.BlitIndex = self.TextIndex for i,v := range blit_rows { if i == cursor_row - 1 { break } self.BlitIndex -= len(v) } } } func (self *Textarea) BlitText() { //blit every single word into surface and calc the width ,check multi line self.BuildBlitText() w := 0 xmargin := 5 endmargin := 15 x := self.PosX + xmargin y := self.PosY linenumber := 0 if len(self.MyWords) > self.TextLimit { self.TextFull = true }else { self.TextFull = false } for _,v := range self.BlitWords { t := font.Render(self.FontObj,v,true,&color.Color{8,135,174,255},nil) w += surface.GetWidth(t) if w >= self.Width - endmargin && linenumber == 0 { linenumber += 1 x = self.PosX + xmargin y = self.PosY + surface.GetHeight(t) * linenumber w = 0 } rect_ := rect.Rect(x,y,0,0) surface.Blit(self.CanvasHWND,t,&rect_,nil) x += surface.GetWidth(t) t.Free() } } func (self *Textarea) Cursor() { w := 0 xmargin := 5 endmargin := 15 x := self.PosX+xmargin y := self.PosY linenumber := 0 for _,v := range self.BlitWords[:self.BlitIndex] { t := font.Render(self.FontObj,v,true,&color.Color{8,135,174,255},nil) w += surface.GetWidth(t) if w >= self.Width - endmargin && linenumber == 0 { x = self.PosX + xmargin y = self.PosY + surface.GetHeight(t) w = 0 linenumber +=1 } if w >= self.Width - endmargin*3 && linenumber > 0 { x += surface.GetWidth(t) break } x += surface.GetWidth(t) t.Free() } c_t := font.Render(self.FontObj,"_",true,&color.Color{0,0,0,255},nil) rect_ := rect.Rect(x+1,y-2,0,0) surface.Blit(self.CanvasHWND,c_t,&rect_,nil) c_t.Free() } func (self *Textarea) Draw() { rect_:= rect.Rect(self.PosX,self.PosY,self.Width,self.Height) draw.AARoundRect(self.CanvasHWND,&rect_,self.BackgroundColor,4,0,self.BackgroundColor) self.BlitText() self.Cursor() }