123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- package UI
- import (
- "fmt"
- "strings"
- "github.com/veandco/go-sdl2/sdl"
- "github.com/veandco/go-sdl2/ttf"
- "github.com/cuu/gogame/color"
- "github.com/cuu/gogame/draw"
- "github.com/cuu/gogame/font"
- "github.com/cuu/gogame/rect"
- "github.com/cuu/gogame/surface"
- )
- 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()
- }
|