123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- package widget
- // import "fmt"
- import "strings"
- import "gitlab.com/beoran/ebsgo/zori/keycode"
- import "gitlab.com/beoran/ebsgo/zori/types"
- // import _ "gitlab.com/beoran/ebsgo/zori/backend"
- // import "gitlab.com/beoran/ebsgo/zori/state"
- // import "gitlab.com/beoran/ebsgo/zori/style"
- import "gitlab.com/beoran/ebsgo/zori/event"
- type ConsoleCommand func(cw *Console, command string, data interface{}) int
- const ConsoleLimit = 1000
- type Console struct {
- * Basic
- Lines []string
- Input string
- Position int
- Cursor int
- Command ConsoleCommand
- Data interface{}
- }
- func (cw * Console) Dispatch(ev event.Event) event.Result {
- return event.Dispatch(ev, cw)
- }
- /** Let the console perform a command if possible. returns nonzero on error,
- zero if OK. */
- func (cw *Console) DoCommand(text string) int {
- if cw.Command == nil {
- return -1
- }
- return cw.Command(cw, text, cw.Data)
- }
-
- /** Adds a line of text to the console. */
- func (cw * Console) AddLine(line string) {
- cw.Lines = append(cw.Lines, line)
- if len(cw.Lines) > ConsoleLimit {
- cw.Lines[0] = ""
- cw.Lines = cw.Lines[1:]
- }
- }
- /** Puts a string on the console .*/
- func (cw * Console) Puts(text string) {
- font := cw.TextFont()
- // Assume a fixed width font for the console.
- charw := font.TextWidth("W")
- lines := strings.Split(text, "\n")
- for _, line := range lines {
- runes := []rune(line)
- max_chars := cw.Inner.W / charw
- for len(runes) > max_chars {
- sub := string(runes[0:max_chars-1])
- runes = runes[max_chars:]
- cw.AddLine(sub)
- }
- cw.AddLine(string(runes))
- }
- }
- /** Draws a console. */
- func (cw * Console) Draw(ev event.Draw) event.Result {
- cw.DrawBackground()
- font := cw.TextFont()
- colo := cw.TextColor()
- be := cw.Backend()
- linehigh := font.LineHeight()
- available := (cw.Inner.H / linehigh - 1)
- x := cw.Inner.X
- y := cw.Inner.Y
- start := len(cw.Lines) - available - cw.Position
- if start < 0 {
- start = 0
- } else if start >= len(cw.Lines) {
- start = len(cw.Lines) - 1
- }
-
- for index := start; index < len(cw.Lines) ; index ++ {
- be.DrawText(font, colo, x, y, cw.Lines[index])
- x += linehigh
- }
-
- // input = cw.Input[0:cw.Cursor-1] + "|" + cw.Input[cw.Cursor:]
- // XXX draw cursor.
- be.DrawText(font, colo, x, y, cw.Input)
- return event.Pass
- }
- func (cw * Console) Scroll (dir int) event.Result {
- cw.Position += dir
- if cw.Position < 0 {
- cw.Position = 0
- } else if cw.Position >= len(cw.Lines) {
- cw.Position = len(cw.Lines) - 1
- }
- return event.Done
- }
- func (cw * Console) Backspace() event.Result {
- if len(cw.Input) > 0 {
- runes := []rune(cw.Input)
- runes = runes[0:len(runes)-1]
- cw.Input = string(runes)
- }
- return event.Done
- }
- /* Key input event handler for console. */
- func (cw *Console) KeyChar(ke event.Key) event.Result {
- cw.Basic.KeyChar(ke)
- ru := ke.Unichar()
- kc := ke.KeyCode()
- switch (kc) {
- // ignore the start-console key
- case keycode.KEY_F1: fallthrough
- case keycode.KEY_F3: return event.Done
- case keycode.KEY_PGUP: return cw.Scroll(1)
- case keycode.KEY_PGDN: return cw.Scroll(-1)
- case keycode.KEY_BACKSPACE: return cw.Backspace()
- case keycode.KEY_ENTER:
- if cw.DoCommand(cw.Input) < 0 {
- cw.Puts("Error executing command.");
- }
- cw.Input = ""
- return event.Done
- default:
- cw.Input = string(append([]rune(cw.Input), ru))
- return event.Done
- }
- }
- func (cw *Console) KeyPress(ke event.Key) event.Result {
- cw.Basic.KeyPress(ke)
- kc := ke.KeyCode()
- switch (kc) {
- // ignore the start-console key
- case keycode.KEY_F1: fallthrough
- case keycode.KEY_F3:
- cw.SetLive(false)
- return event.Done
- default:
- return event.Pass
- }
- }
- func (cw * Console) MouseAxes(ev event.Mouse) event.Result {
- dz := ev.DZ()
- if dz == 0 {
- return event.Pass
- } else if dz < 0 {
- return cw.Scroll(-1)
- } else {
- return cw.Scroll(+1)
- }
- }
- func NewConsole(parent Widget, bounds * types.Box,
- com ConsoleCommand) * Console {
- con := &Console{}
- con.Basic = NewBasic(parent, bounds, nil)
- con.Command = com
- return con
- }
|