package door import "strings" type BorderStyle int const ( NONE BorderStyle = iota SINGLE DOUBLE DOUBLE_SINGLE SINGLE_DOUBLE ) type Panel struct { X int Y int Width int Style BorderStyle BorderColor string Lines []Line Title string TitleOffset int } // Output the panel func (p *Panel) Output() string { var style int = int(p.Style) var box_style *BoxStyle var output string if style > 0 { box_style = &BOXES[style-1] } row := p.Y if style > 0 { // Top line / border output += Goto(p.X, row) + p.BorderColor + box_style.top_left if p.Title != "" { output += strings.Repeat(box_style.top, p.TitleOffset) + p.Title } output += strings.Repeat(box_style.top, p.Width-(p.TitleOffset+len(p.Title))) + box_style.top_right row++ } for _, line := range p.Lines { output += Goto(p.X, row) var joined bool = false if style > 0 { top := box_style.top if line.Text[0:len(top)] == top { // Yes, this line needs to be joined... output += p.BorderColor + box_style.middle_left + line.Output() + p.BorderColor + box_style.middle_right joined = true } } if !joined { if style > 0 { output += p.BorderColor + box_style.side } output += line.Output() if style > 0 { output += p.BorderColor + box_style.side } } row++ } if style > 0 { // Bottom / border output += Goto(p.X, row) + p.BorderColor + box_style.bottom_left output += strings.Repeat(box_style.top, p.Width) + box_style.bottom_right } return output } // Output anything that has updated func (p *Panel) Update() string { var output string var style int = int(p.Style) row := p.Y col := p.X if style > 0 { row++ col++ } for idx, _ := range p.Lines { if p.Lines[idx].Update() { // Yes, line was updated output += Goto(col, row) + p.Lines[idx].Output() } row++ } return output } // Output the updated line func (p *Panel) UpdateLine(index int) string { var output string var style int = int(p.Style) p.Lines[index].Update() row := p.Y + index col := p.X if style > 0 { row++ col++ } line := &p.Lines[index] output += Goto(col, row) + line.Output() return output } // Goto the end func (p *Panel) GotoEnd() string { row := p.Y col := p.X if p.Style > 0 { row++ col += 2 } row += len(p.Lines) col += p.Width return Goto(col, row) } // Is the top line of this style a single line? func Single(bs BorderStyle) bool { switch bs { case SINGLE, SINGLE_DOUBLE: return true default: return false } } // Create a spacer line that will be connected maybe to the sides. func (p *Panel) Spacer() Line { l := Line{} var pos int if Single(p.Style) { pos = 0 } else { pos = 1 } l.Text = strings.Repeat(BOXES[pos].top, p.Width) return l }