Some changes in tui.
This commit is contained in:
parent
b33d5f036c
commit
9e9eb70cd2
15
tui/channel_all.go
Normal file
15
tui/channel_all.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package tui
|
||||
|
||||
func (t *TUI) launchAllChannels() error {
|
||||
var err error
|
||||
err = t.launchErrorsChannel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.errorsChannel <- t.launchInputChannel()
|
||||
t.errorsChannel <- t.launchInputChannel()
|
||||
t.errorsChannel <- t.launchMessageChannel()
|
||||
t.errorsChannel <- t.launchSignalsChannel()
|
||||
t.errorsChannel <- t.launchStateChannel()
|
||||
return nil
|
||||
}
|
17
tui/channel_errors.go
Normal file
17
tui/channel_errors.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package tui
|
||||
|
||||
import "git.qowevisa.me/Qowevisa/gotell/errors"
|
||||
|
||||
func (t *TUI) launchErrorsChannel() error {
|
||||
if t.errorsChannel == nil {
|
||||
return errors.WrapErr("t.errors", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for err := range t.errorsChannel {
|
||||
if err != nil {
|
||||
t.createNotification(err.Error(), CONST_ERROR_N_TITLE)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
71
tui/channel_input.go
Normal file
71
tui/channel_input.go
Normal file
|
@ -0,0 +1,71 @@
|
|||
package tui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"git.qowevisa.me/Qowevisa/gotell/errors"
|
||||
)
|
||||
|
||||
func (t *TUI) launchInputChannel() error {
|
||||
if t.inputChannel == nil {
|
||||
return errors.WrapErr("t.inputChannel", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for r := range t.inputChannel {
|
||||
log.Printf("Read rune: %#v from t.input\n", r)
|
||||
selWidget := t.selectedWidget
|
||||
// Enter
|
||||
if r == 13 {
|
||||
log.Printf("Debug: selWidget: %#v ; selWidget.Input: %#v", selWidget, selWidget.Input)
|
||||
if selWidget != nil && selWidget.Input != nil {
|
||||
t.errorsChannel <- selWidget.Handler(t, selWidget.Data)
|
||||
buf := selWidget.Clear()
|
||||
t.writeMu.Lock()
|
||||
err := t.write(buf)
|
||||
t.writeMu.Unlock()
|
||||
if err != nil {
|
||||
t.errorsChannel <- errors.WrapErr("t.write", err)
|
||||
}
|
||||
if selWidget.Next != nil {
|
||||
log.Printf("Seeing that widget.Next is not nil")
|
||||
t.errorsChannel <- t.addWidget(*selWidget.Next)
|
||||
t.errorsChannel <- t.drawSelectedWidget()
|
||||
} else {
|
||||
t.readInputState <- false
|
||||
}
|
||||
if selWidget.Finale != nil {
|
||||
log.Printf("Seeing that widget.Finale is not nil")
|
||||
t.errorsChannel <- selWidget.Finale(t, selWidget.FinaleData)
|
||||
}
|
||||
}
|
||||
continue
|
||||
} else if r == 127 {
|
||||
log.Printf("seeing r = 127")
|
||||
sliceLen := len(*selWidget.Input)
|
||||
log.Printf("sliceLen = %d\n", sliceLen)
|
||||
if sliceLen > 0 {
|
||||
log.Printf("sliceLen > 0")
|
||||
*selWidget.Input = (*selWidget.Input)[:sliceLen-1]
|
||||
t.writeMu.Lock()
|
||||
t.errorsChannel <- t.moveCursor(t.cursorPosRow, t.cursorPosCol-1)
|
||||
t.errorsChannel <- t.writeRune(' ')
|
||||
t.errorsChannel <- t.moveCursor(t.cursorPosRow, t.cursorPosCol-1)
|
||||
t.writeMu.Unlock()
|
||||
}
|
||||
continue
|
||||
}
|
||||
if selWidget != nil && selWidget.Input != nil {
|
||||
log.Printf("t.input: append %#v to widget input\n", r)
|
||||
*selWidget.Input = append(*selWidget.Input, r)
|
||||
log.Printf("t.input: trying to write %#v", r)
|
||||
t.writeMu.Lock()
|
||||
err := t.writeRune(r)
|
||||
t.writeMu.Unlock()
|
||||
if err != nil {
|
||||
t.errorsChannel <- err
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
37
tui/channel_message.go
Normal file
37
tui/channel_message.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package tui
|
||||
|
||||
import (
|
||||
"git.qowevisa.me/Qowevisa/gotell/communication"
|
||||
"git.qowevisa.me/Qowevisa/gotell/errors"
|
||||
)
|
||||
|
||||
// Basically every X_channel.go file launches some sort of channel
|
||||
|
||||
func (t *TUI) launchMessageChannel() error {
|
||||
if t.messageChannel == nil {
|
||||
return errors.WrapErr("t.messageChannel", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for message := range t.messageChannel {
|
||||
t.createNotification(string(message), "Message!")
|
||||
msg, err := communication.Decode(message)
|
||||
t.errorsChannel <- err
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
switch msg.Type {
|
||||
case communication.SERVER_COMMAND:
|
||||
t.handleServerCommands(msg.Data)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TUI) handleServerCommands(data []byte) {
|
||||
if len(data) == 1 {
|
||||
if data[0] == communication.NICKNAME {
|
||||
t.SendMessageToServer("Nickname", 16)
|
||||
}
|
||||
}
|
||||
}
|
24
tui/channel_signals.go
Normal file
24
tui/channel_signals.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package tui
|
||||
|
||||
import (
|
||||
"log"
|
||||
"syscall"
|
||||
|
||||
"git.qowevisa.me/Qowevisa/gotell/errors"
|
||||
)
|
||||
|
||||
func (t *TUI) launchSignalsChannel() error {
|
||||
if t.osSignals == nil {
|
||||
return errors.WrapErr("t.osSignals", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for sig := range t.osSignals {
|
||||
log.Printf("Receive OS.signal: %#v\n", sig)
|
||||
switch sig {
|
||||
case syscall.SIGWINCH:
|
||||
t.errorsChannel <- t.redraw()
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
21
tui/channel_state.go
Normal file
21
tui/channel_state.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package tui
|
||||
|
||||
import "git.qowevisa.me/Qowevisa/gotell/errors"
|
||||
|
||||
func (t *TUI) launchStateChannel() error {
|
||||
if t.stateChannel == nil {
|
||||
return errors.WrapErr("t.stateChannel", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for state := range t.stateChannel {
|
||||
t.writeMu.Lock()
|
||||
oldRow, oldCol := t.getCursorPos()
|
||||
t.errorsChannel <- t.moveCursor(t.height, len(footerStart)+1)
|
||||
t._clearLine()
|
||||
t.errorsChannel <- t.write(state)
|
||||
t.errorsChannel <- t.moveCursor(oldRow, oldCol)
|
||||
t.writeMu.Unlock()
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
|
@ -5,6 +5,10 @@ const (
|
|||
MY_SIGNAL_MESSAGE
|
||||
MY_SIGNAL_CONNECT
|
||||
MY_SIGNAL_CLOSE
|
||||
MY_SIGNAL_MOVE_CURSOR_UP
|
||||
MY_SIGNAL_MOVE_CURSOR_DOWN
|
||||
MY_SIGNAL_MOVE_CURSOR_LEFT
|
||||
MY_SIGNAL_MOVE_CURSOR_RIGHT
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -22,8 +26,8 @@ const (
|
|||
footerStart = "State: "
|
||||
)
|
||||
|
||||
func (c *cursorPosConfigValue) isGeneral() bool {
|
||||
switch *c {
|
||||
func (c cursorPosConfigValue) isGeneral() bool {
|
||||
switch c {
|
||||
case cursorPosGeneralCenter:
|
||||
return true
|
||||
case cursorPosGeneralLeft:
|
||||
|
@ -40,8 +44,8 @@ const (
|
|||
widgetPosGeneralRightCenter widgetPosConfigValue = -3
|
||||
)
|
||||
|
||||
func (w *widgetPosConfigValue) isGeneral() bool {
|
||||
switch *w {
|
||||
func (w widgetPosConfigValue) isGeneral() bool {
|
||||
switch w {
|
||||
case widgetPosGeneralCenter:
|
||||
return true
|
||||
case widgetPosGeneralLeftCenter:
|
||||
|
|
|
@ -15,7 +15,7 @@ func (t *TUI) launchReadingMessagesFromConnection(ctx context.Context, wg *sync.
|
|||
defer wg.Done() // Mark this goroutine as done when it exits
|
||||
|
||||
if t.messageChannel == nil {
|
||||
t.errors <- errors.WrapErr("t.messageChannel", errors.NOT_INIT)
|
||||
t.errorsChannel <- errors.WrapErr("t.messageChannel", errors.NOT_INIT)
|
||||
return
|
||||
}
|
||||
buf := make([]byte, CONST_MESSAGE_LEN)
|
||||
|
@ -27,7 +27,7 @@ func (t *TUI) launchReadingMessagesFromConnection(ctx context.Context, wg *sync.
|
|||
timeoutDuration := 5 * time.Second
|
||||
err := t.tlsConnection.SetReadDeadline(time.Now().Add(timeoutDuration))
|
||||
if err != nil {
|
||||
t.errors <- errors.WrapErr("SetReadDeadline", err)
|
||||
t.errorsChannel <- errors.WrapErr("SetReadDeadline", err)
|
||||
return
|
||||
}
|
||||
n, err := t.tlsConnection.Read(buf)
|
||||
|
@ -36,7 +36,7 @@ func (t *TUI) launchReadingMessagesFromConnection(ctx context.Context, wg *sync.
|
|||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||
continue
|
||||
}
|
||||
t.errors <- errors.WrapErr("t.tlsConnection.Read", err)
|
||||
t.errorsChannel <- errors.WrapErr("t.tlsConnection.Read", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
16
tui/types.go
16
tui/types.go
|
@ -60,6 +60,15 @@ type notifier struct {
|
|||
Buf string
|
||||
}
|
||||
|
||||
type dialog struct {
|
||||
Row int
|
||||
Col int
|
||||
Width int
|
||||
Height int
|
||||
Buf string
|
||||
Catcher RuneCatcher
|
||||
}
|
||||
|
||||
type widgetDraw struct {
|
||||
Buf string
|
||||
Row int
|
||||
|
@ -89,6 +98,8 @@ type closeData struct {
|
|||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
type RuneCatcher func(runes chan (rune)) error
|
||||
|
||||
type TUI struct {
|
||||
width int
|
||||
height int
|
||||
|
@ -97,11 +108,12 @@ type TUI struct {
|
|||
writeMu sync.Mutex
|
||||
sizeMutex sync.Mutex
|
||||
oldState *term.State
|
||||
input chan (rune)
|
||||
inputChannel chan (rune)
|
||||
inputCatcher RuneCatcher
|
||||
printRunes chan (rune)
|
||||
mySignals chan (mySignal)
|
||||
osSignals chan (os.Signal)
|
||||
errors chan (error)
|
||||
errorsChannel chan (error)
|
||||
readInputState chan (bool)
|
||||
readEnterState chan (bool)
|
||||
stateChannel chan (string)
|
||||
|
|
159
tui/ui.go
159
tui/ui.go
|
@ -17,10 +17,10 @@ import (
|
|||
|
||||
func (t *TUI) init() error {
|
||||
var err error
|
||||
t.input = make(chan rune, 32)
|
||||
t.inputChannel = make(chan rune, 32)
|
||||
t.printRunes = make(chan rune, 32)
|
||||
t.widgets = make([]*widget, 8)
|
||||
t.errors = make(chan error, 4)
|
||||
t.errorsChannel = make(chan error, 4)
|
||||
t.mySignals = make(chan mySignal, 1)
|
||||
t.osSignals = make(chan os.Signal, 1)
|
||||
t.writer = bufio.NewWriter(os.Stdout)
|
||||
|
@ -46,6 +46,10 @@ func (t *TUI) init() error {
|
|||
if err != nil {
|
||||
return errors.WrapErr("t.readRoutines", err)
|
||||
}
|
||||
err = t.launchAllChannels()
|
||||
if err != nil {
|
||||
return errors.WrapErr("t.launchAllChannels", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -64,7 +68,7 @@ func (t *TUI) Run() error {
|
|||
}
|
||||
//
|
||||
if t.mySignals == nil {
|
||||
return errors.WrapErr("t.signals", errors.NOT_INIT)
|
||||
return errors.WrapErr("t.mySignals", errors.NOT_INIT)
|
||||
}
|
||||
err = t.Draw()
|
||||
if err != nil {
|
||||
|
@ -73,8 +77,8 @@ func (t *TUI) Run() error {
|
|||
for mySignal := range t.mySignals {
|
||||
log.Printf("Receive signal: %#v\n", mySignal)
|
||||
if mySignal.Type == MY_SIGNAL_EXIT {
|
||||
t.errors <- t.clearScreen()
|
||||
t.errors <- t.moveCursor(0, 0)
|
||||
t.errorsChannel <- t.clearScreen()
|
||||
t.errorsChannel <- t.moveCursor(0, 0)
|
||||
break
|
||||
}
|
||||
switch mySignal.Type {
|
||||
|
@ -108,43 +112,23 @@ func (t *TUI) Run() error {
|
|||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.errors <- errors.WrapErr("t.addWidget", err)
|
||||
t.errorsChannel <- errors.WrapErr("t.addWidget", err)
|
||||
}
|
||||
err = t.drawSelectedWidget()
|
||||
if err != nil {
|
||||
t.errors <- errors.WrapErr("t.drawSelectedWidget", err)
|
||||
t.errorsChannel <- errors.WrapErr("t.drawSelectedWidget", err)
|
||||
}
|
||||
|
||||
case MY_SIGNAL_MESSAGE:
|
||||
if t.isConnected {
|
||||
var msg []rune
|
||||
h, d := SendMessageToConnectionEasy(&msg)
|
||||
err := t.addWidget(widgetConfig{
|
||||
Input: &msg,
|
||||
Title: "Message",
|
||||
MinWidth: 20,
|
||||
HasBorder: true,
|
||||
WidgetPosConfig: widgetPosGeneralCenter,
|
||||
CursorPosConfig: cursorPosGeneralCenter,
|
||||
DataHandler: h,
|
||||
Data: d,
|
||||
Next: nil,
|
||||
Finale: nil,
|
||||
})
|
||||
if err != nil {
|
||||
t.errors <- errors.WrapErr("t.addWidget", err)
|
||||
}
|
||||
err = t.drawSelectedWidget()
|
||||
if err != nil {
|
||||
t.errors <- errors.WrapErr("t.drawSelectedWidget", err)
|
||||
}
|
||||
t.SendMessageToServer("Message", 20)
|
||||
}
|
||||
|
||||
case MY_SIGNAL_CLOSE:
|
||||
if t.isConnected {
|
||||
CloseConnection(t.tlsConnCloseData.wg, t.tlsConnCloseData.cancel)
|
||||
t.isConnected = false
|
||||
t.errors <- t.tlsConnection.Close()
|
||||
t.errorsChannel <- t.tlsConnection.Close()
|
||||
t.stateChannel <- "Disconnected"
|
||||
}
|
||||
default:
|
||||
|
@ -157,23 +141,13 @@ func (t *TUI) Run() error {
|
|||
func (t *TUI) createNotification(text, title string) {
|
||||
notifier, err := createNotification(text, title)
|
||||
t.selectedNotifier = ¬ifier
|
||||
t.errors <- err
|
||||
t.errors <- t.write(notifier.Buf)
|
||||
t.errorsChannel <- err
|
||||
t.errorsChannel <- t.write(notifier.Buf)
|
||||
t.readEnterState <- true
|
||||
}
|
||||
|
||||
func (t *TUI) setRoutines() error {
|
||||
if t.errors == nil {
|
||||
return errors.WrapErr("t.errors", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for err := range t.errors {
|
||||
if err != nil {
|
||||
t.createNotification(err.Error(), CONST_ERROR_N_TITLE)
|
||||
}
|
||||
}
|
||||
}()
|
||||
if t.input == nil {
|
||||
if t.inputChannel == nil {
|
||||
return errors.WrapErr("t.input", errors.NOT_INIT)
|
||||
}
|
||||
if t.oldState == nil {
|
||||
|
@ -191,22 +165,6 @@ func (t *TUI) setRoutines() error {
|
|||
if t.messageChannel == nil {
|
||||
return errors.WrapErr("t.messageChannel", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for message := range t.messageChannel {
|
||||
t.createNotification(string(message), "Message!")
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for state := range t.stateChannel {
|
||||
t.writeMu.Lock()
|
||||
oldRow, oldCol := t.getCursorPos()
|
||||
t.errors <- t.moveCursor(t.height, len(footerStart)+1)
|
||||
t._clearLine()
|
||||
t.errors <- t.write(state)
|
||||
t.errors <- t.moveCursor(oldRow, oldCol)
|
||||
t.writeMu.Unlock()
|
||||
}
|
||||
}()
|
||||
var readInputMu sync.Mutex
|
||||
var readEnterdMu sync.Mutex
|
||||
readInput := false
|
||||
|
@ -239,7 +197,7 @@ func (t *TUI) setRoutines() error {
|
|||
if r == 13 {
|
||||
readEnter = false
|
||||
if t.selectedNotifier != nil {
|
||||
t.errors <- t.write(t.selectedNotifier.Clear())
|
||||
t.errorsChannel <- t.write(t.selectedNotifier.Clear())
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
@ -298,101 +256,26 @@ func (t *TUI) setRoutines() error {
|
|||
} else {
|
||||
if readInput {
|
||||
log.Printf("Send %c | %d to t.input", r, r)
|
||||
t.input <- r
|
||||
t.inputChannel <- r
|
||||
}
|
||||
}
|
||||
readInputMu.Lock()
|
||||
if readInput {
|
||||
switch r {
|
||||
case 13:
|
||||
t.input <- r
|
||||
t.inputChannel <- r
|
||||
case 127:
|
||||
t.input <- r
|
||||
t.inputChannel <- r
|
||||
}
|
||||
}
|
||||
readInputMu.Unlock()
|
||||
}
|
||||
}()
|
||||
//
|
||||
if t.osSignals == nil {
|
||||
return errors.WrapErr("t.osSignals", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for sig := range t.osSignals {
|
||||
log.Printf("Receive OS.signal: %#v\n", sig)
|
||||
switch sig {
|
||||
case syscall.SIGWINCH:
|
||||
t.errors <- t.redraw()
|
||||
}
|
||||
}
|
||||
}()
|
||||
if t.input == nil {
|
||||
return errors.WrapErr("t.input", errors.NOT_INIT)
|
||||
}
|
||||
go func() {
|
||||
for r := range t.input {
|
||||
log.Printf("Read rune: %#v from t.input\n", r)
|
||||
selWidget := t.selectedWidget
|
||||
// Enter
|
||||
if r == 13 {
|
||||
log.Printf("Debug: selWidget: %#v ; selWidget.Input: %#v", selWidget, selWidget.Input)
|
||||
if selWidget != nil && selWidget.Input != nil {
|
||||
t.errors <- selWidget.Handler(t, selWidget.Data)
|
||||
buf := selWidget.Clear()
|
||||
t.writeMu.Lock()
|
||||
err := t.write(buf)
|
||||
t.writeMu.Unlock()
|
||||
if err != nil {
|
||||
t.errors <- errors.WrapErr("t.write", err)
|
||||
}
|
||||
if selWidget.Next != nil {
|
||||
log.Printf("Seeing that widget.Next is not nil")
|
||||
t.errors <- t.addWidget(*selWidget.Next)
|
||||
t.errors <- t.drawSelectedWidget()
|
||||
} else {
|
||||
t.readInputState <- false
|
||||
}
|
||||
if selWidget.Finale != nil {
|
||||
log.Printf("Seeing that widget.Finale is not nil")
|
||||
t.errors <- selWidget.Finale(t, selWidget.FinaleData)
|
||||
}
|
||||
}
|
||||
continue
|
||||
} else if r == 127 {
|
||||
log.Printf("seeing r = 127")
|
||||
sliceLen := len(*selWidget.Input)
|
||||
log.Printf("sliceLen = %d\n", sliceLen)
|
||||
if sliceLen > 0 {
|
||||
log.Printf("sliceLen > 0")
|
||||
*selWidget.Input = (*selWidget.Input)[:sliceLen-1]
|
||||
t.writeMu.Lock()
|
||||
t.errors <- t.moveCursor(t.cursorPosRow, t.cursorPosCol-1)
|
||||
t.errors <- t.writeRune(' ')
|
||||
t.errors <- t.moveCursor(t.cursorPosRow, t.cursorPosCol-1)
|
||||
t.writeMu.Unlock()
|
||||
}
|
||||
continue
|
||||
}
|
||||
if selWidget != nil && selWidget.Input != nil {
|
||||
log.Printf("t.input: append %#v to widget input\n", r)
|
||||
*selWidget.Input = append(*selWidget.Input, r)
|
||||
log.Printf("t.input: trying to write %#v", r)
|
||||
t.writeMu.Lock()
|
||||
err := t.writeRune(r)
|
||||
t.writeMu.Unlock()
|
||||
if err != nil {
|
||||
t.errors <- err
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TUI) readRoutines() error {
|
||||
if t.input == nil {
|
||||
return errors.WrapErr("t.input", errors.NOT_INIT)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -457,7 +340,7 @@ func (t *TUI) getCursorPos() (int, int) {
|
|||
}
|
||||
|
||||
func (t *TUI) _clearLine() {
|
||||
t.errors <- t.write("\033[0K")
|
||||
t.errorsChannel <- t.write("\033[0K")
|
||||
}
|
||||
|
||||
func (t *TUI) moveCursor(row, col int) error {
|
||||
|
|
27
tui/util.go
Normal file
27
tui/util.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package tui
|
||||
|
||||
import "git.qowevisa.me/Qowevisa/gotell/errors"
|
||||
|
||||
func (t *TUI) SendMessageToServer(title string, minW int) {
|
||||
var msg []rune
|
||||
h, d := SendMessageToConnectionEasy(&msg)
|
||||
err := t.addWidget(widgetConfig{
|
||||
Input: &msg,
|
||||
Title: title,
|
||||
MinWidth: minW,
|
||||
HasBorder: true,
|
||||
WidgetPosConfig: widgetPosGeneralCenter,
|
||||
CursorPosConfig: cursorPosGeneralCenter,
|
||||
DataHandler: h,
|
||||
Data: d,
|
||||
Next: nil,
|
||||
Finale: nil,
|
||||
})
|
||||
if err != nil {
|
||||
t.errorsChannel <- errors.WrapErr("t.addWidget", err)
|
||||
}
|
||||
err = t.drawSelectedWidget()
|
||||
if err != nil {
|
||||
t.errorsChannel <- errors.WrapErr("t.drawSelectedWidget", err)
|
||||
}
|
||||
}
|
125
tui/widget_dialog.go
Normal file
125
tui/widget_dialog.go
Normal file
|
@ -0,0 +1,125 @@
|
|||
package tui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.qowevisa.me/Qowevisa/gotell/errors"
|
||||
)
|
||||
|
||||
func createDialog(message, title string) (dialog, error) {
|
||||
var buf string
|
||||
width, height := UI.getSizes()
|
||||
if width == 0 {
|
||||
return dialog{}, errors.WrapErr("width", errors.NOT_INIT)
|
||||
}
|
||||
if height == 0 {
|
||||
return dialog{}, errors.WrapErr("height", errors.NOT_INIT)
|
||||
}
|
||||
maxWidth := width / 3
|
||||
maxHeight := 5
|
||||
errMsgLen := len(message)
|
||||
innerPart := maxWidth - 2
|
||||
if errMsgLen <= innerPart {
|
||||
maxWidth = errMsgLen + 2
|
||||
} else {
|
||||
for {
|
||||
if errMsgLen <= innerPart {
|
||||
break
|
||||
}
|
||||
maxHeight++
|
||||
errMsgLen -= innerPart
|
||||
}
|
||||
}
|
||||
innerPart = maxWidth - 2
|
||||
col := (width - maxWidth) / 2
|
||||
row := (height - maxHeight) / 2
|
||||
startCol := col
|
||||
startRow := row
|
||||
|
||||
buf += getBufForMovingCursorTo(row, col)
|
||||
buf += strings.Repeat("-", maxWidth)
|
||||
|
||||
row++
|
||||
buf += getBufForMovingCursorTo(row, col)
|
||||
buf += centerText(maxWidth, title)
|
||||
|
||||
row++
|
||||
buf += getBufForMovingCursorTo(row, col)
|
||||
buf += strings.Repeat("-", maxWidth)
|
||||
|
||||
startI := 0
|
||||
endI := innerPart
|
||||
for i := 3; i < maxHeight-1; i++ {
|
||||
var tmp string
|
||||
if endI > len(message) {
|
||||
tmp = message[startI:]
|
||||
} else {
|
||||
tmp = message[startI:endI]
|
||||
}
|
||||
row++
|
||||
buf += getBufForMovingCursorTo(row, col)
|
||||
var spaces string
|
||||
if innerPart > len(tmp) {
|
||||
spaces = strings.Repeat(" ", innerPart-len(tmp))
|
||||
}
|
||||
buf += fmt.Sprintf("|%s%s|", tmp, spaces)
|
||||
startI += innerPart
|
||||
endI += innerPart
|
||||
}
|
||||
|
||||
row++
|
||||
buf += getBufForMovingCursorTo(row, col)
|
||||
buf += strings.Repeat("-", maxWidth)
|
||||
|
||||
row++
|
||||
buf += getBufForMovingCursorTo(row, col)
|
||||
buf += centerText(maxWidth, "YES | NO")
|
||||
|
||||
row++
|
||||
buf += getBufForMovingCursorTo(row, col)
|
||||
buf += strings.Repeat("-", maxWidth)
|
||||
return dialog{
|
||||
Row: startRow,
|
||||
Col: startCol,
|
||||
Width: maxWidth,
|
||||
Height: row - startRow + 1,
|
||||
Buf: buf,
|
||||
}, nil
|
||||
}
|
||||
|
||||
const (
|
||||
_int_CatcherNone = iota
|
||||
_int_Catcher1Arrow
|
||||
_int_Catcher2Arrow
|
||||
_int_CatcherArrow
|
||||
)
|
||||
|
||||
func dialogRuneCatcher(t *TUI, runes chan (rune)) error {
|
||||
state := _int_CatcherNone
|
||||
for r := range runes {
|
||||
if r == 27 && state == _int_CatcherNone {
|
||||
state = _int_Catcher1Arrow
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if r == 91 && state == _int_Catcher1Arrow {
|
||||
state = _int_Catcher2Arrow
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if state == _int_Catcher2Arrow {
|
||||
switch r {
|
||||
case 65:
|
||||
t.mySignals <- mySignal{Type: MY_SIGNAL_MOVE_CURSOR_UP}
|
||||
case 66:
|
||||
t.mySignals <- mySignal{Type: MY_SIGNAL_MOVE_CURSOR_DOWN}
|
||||
case 67:
|
||||
t.mySignals <- mySignal{Type: MY_SIGNAL_MOVE_CURSOR_RIGHT}
|
||||
case 68:
|
||||
t.mySignals <- mySignal{Type: MY_SIGNAL_MOVE_CURSOR_LEFT}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user