From 492a8752f1f5493915da4e2bec9516ed7557dc23 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 22 Mar 2018 16:44:24 +0200 Subject: [PATCH] Move input field to RoomView --- interface/ui.go | 1 - ui/view-main.go | 87 +++++++++++++++++++----------------------- ui/widget/room-view.go | 70 ++++++++++++++++++++++++++++++--- 3 files changed, 105 insertions(+), 53 deletions(-) diff --git a/interface/ui.go b/interface/ui.go index 088c2f4..36a733b 100644 --- a/interface/ui.go +++ b/interface/ui.go @@ -39,7 +39,6 @@ type GomuksUI interface { } type MainView interface { - InputTabComplete(text string, cursorOffset int) string GetRoom(roomID string) *widget.RoomView HasRoom(roomID string) bool AddRoom(roomID string) diff --git a/ui/view-main.go b/ui/view-main.go index 8ff925c..f6efd8e 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -41,7 +41,6 @@ type MainView struct { roomList *tview.List roomView *tview.Pages rooms map[string]*widget.RoomView - input *widget.AdvancedInputField currentRoomIndex int roomIDs []string @@ -52,7 +51,7 @@ type MainView struct { } func (view *MainView) addItem(p tview.Primitive, x, y, w, h int) { - view.Grid.AddItem(p, x, y, w, h, 0, 0, false) + view.Grid.AddItem(p, y, x, w, h, 0, 0, false) } func (ui *GomuksUI) NewMainView() tview.Primitive { @@ -61,7 +60,6 @@ func (ui *GomuksUI) NewMainView() tview.Primitive { roomList: tview.NewList(), roomView: tview.NewPages(), rooms: make(map[string]*widget.RoomView), - input: widget.NewAdvancedInputField(), matrix: ui.gmx.MatrixContainer(), gmx: ui.gmx, @@ -69,7 +67,7 @@ func (ui *GomuksUI) NewMainView() tview.Primitive { parent: ui, } - mainView.SetColumns(30, 1, 0).SetRows(0, 1) + mainView.SetColumns(30, 1, 0).SetRows(0) mainView.roomList. ShowSecondaryText(false). @@ -77,30 +75,20 @@ func (ui *GomuksUI) NewMainView() tview.Primitive { SetSelectedTextColor(tcell.ColorWhite). SetBorderPadding(0, 0, 1, 0) - mainView.input. - SetDoneFunc(mainView.InputDone). - SetChangedFunc(mainView.InputChanged). - SetTabCompleteFunc(mainView.InputTabComplete). - SetFieldBackgroundColor(tcell.ColorDefault). - SetPlaceholder("Send a message..."). - SetPlaceholderExtColor(tcell.ColorGray). - SetInputCapture(mainView.InputCapture) - - mainView.addItem(mainView.roomList, 0, 0, 2, 1) - mainView.addItem(widget.NewBorder(), 0, 1, 2, 1) - mainView.addItem(mainView.roomView, 0, 2, 1, 1) - mainView.AddItem(mainView.input, 1, 2, 1, 1, 0, 0, true) + mainView.addItem(mainView.roomList, 0, 0, 1, 1) + mainView.addItem(widget.NewBorder(), 1, 0, 1, 1) + mainView.addItem(mainView.roomView, 2, 0, 1, 1) ui.mainView = mainView return mainView } -func (view *MainView) InputChanged(text string) { +func (view *MainView) InputChanged(roomView *widget.RoomView, text string) { if len(text) == 0 { - go view.matrix.SendTyping(view.CurrentRoomID(), false) + go view.matrix.SendTyping(roomView.Room.ID, false) } else if text[0] != '/' { - go view.matrix.SendTyping(view.CurrentRoomID(), true) + go view.matrix.SendTyping(roomView.Room.ID, true) } } @@ -116,42 +104,35 @@ func findWordToTabComplete(text string) string { return output } -func (view *MainView) InputTabComplete(text string, cursorOffset int) string { - roomView, _ := view.rooms[view.CurrentRoomID()] - if roomView != nil { - str := runewidth.Truncate(text, cursorOffset, "") - word := findWordToTabComplete(str) - userCompletions := roomView.AutocompleteUser(word) - if len(userCompletions) == 1 { - startIndex := len(str) - len(word) - completion := userCompletions[0] - if startIndex == 0 { - completion = completion + ": " - } - text = str[0:startIndex] + completion + text[len(str):] - } else if len(userCompletions) > 1 && len(userCompletions) < 6 { - roomView.SetStatus(fmt.Sprintf("Completions: %s", strings.Join(userCompletions, ", "))) +func (view *MainView) InputTabComplete(roomView *widget.RoomView, text string, cursorOffset int) string { + str := runewidth.Truncate(text, cursorOffset, "") + word := findWordToTabComplete(str) + userCompletions := roomView.AutocompleteUser(word) + if len(userCompletions) == 1 { + startIndex := len(str) - len(word) + completion := userCompletions[0] + if startIndex == 0 { + completion = completion + ": " } + text = str[0:startIndex] + completion + text[len(str):] + } else if len(userCompletions) > 1 && len(userCompletions) < 6 { + roomView.SetStatus(fmt.Sprintf("Completions: %s", strings.Join(userCompletions, ", "))) } return text } -func (view *MainView) InputDone(key tcell.Key) { - if key != tcell.KeyEnter { - return - } - room, text := view.CurrentRoomID(), view.input.GetText() +func (view *MainView) InputSubmit(roomView *widget.RoomView, text string) { if len(text) == 0 { return } else if text[0] == '/' { args := strings.SplitN(text, " ", 2) command := strings.ToLower(args[0]) args = args[1:] - go view.HandleCommand(room, command, args) + go view.HandleCommand(roomView.Room.ID, command, args) } else { - view.SendMessage(room, text) + view.SendMessage(roomView.Room.ID, text) } - view.input.SetText("") + roomView.SetInputText("") } func (view *MainView) SendMessage(room, text string) { @@ -205,7 +186,7 @@ func (view *MainView) HandleCommand(room, command string, args []string) { } } -func (view *MainView) InputCapture(key *tcell.EventKey) *tcell.EventKey { +func (view *MainView) InputKeyHandler(roomView *widget.RoomView, key *tcell.EventKey) *tcell.EventKey { k := key.Key() if key.Modifiers() == tcell.ModCtrl || key.Modifiers() == tcell.ModAlt { if k == tcell.KeyDown { @@ -218,10 +199,10 @@ func (view *MainView) InputCapture(key *tcell.EventKey) *tcell.EventKey { return key } } else if k == tcell.KeyPgUp || k == tcell.KeyPgDn || k == tcell.KeyUp || k == tcell.KeyDown { - msgView := view.rooms[view.CurrentRoomID()].MessageView() + msgView := roomView.MessageView() if k == tcell.KeyPgUp || k == tcell.KeyUp { if msgView.IsAtTop() { - go view.LoadMoreHistory(view.CurrentRoomID()) + go view.LoadMoreHistory(roomView.Room.ID) } else { msgView.MoveUp(k == tcell.KeyPgUp) } @@ -252,9 +233,17 @@ func (view *MainView) SwitchRoom(roomIndex int) { view.currentRoomIndex = roomIndex % len(view.roomIDs) view.roomView.SwitchToPage(view.CurrentRoomID()) view.roomList.SetCurrentItem(roomIndex) + view.gmx.App().SetFocus(view) view.parent.Render() } +func (view *MainView) Focus(delegate func(p tview.Primitive)) { + roomView, ok := view.rooms[view.CurrentRoomID()] + if ok { + delegate(roomView) + } +} + func (view *MainView) addRoom(index int, room string) { roomStore := view.matrix.GetRoom(room) @@ -262,7 +251,11 @@ func (view *MainView) addRoom(index int, room string) { view.SwitchRoom(index) }) if !view.roomView.HasPage(room) { - roomView := widget.NewRoomView(roomStore) + roomView := widget.NewRoomView(roomStore). + SetInputSubmitFunc(view.InputSubmit). + SetInputChangedFunc(view.InputChanged). + SetTabCompleteFunc(view.InputTabComplete). + SetInputCapture(view.InputKeyHandler) view.rooms[room] = roomView view.roomView.AddPage(room, roomView, true, false) roomView.UpdateUserList() diff --git a/ui/widget/room-view.go b/ui/widget/room-view.go index b103490..69d5b29 100644 --- a/ui/widget/room-view.go +++ b/ui/widget/room-view.go @@ -23,7 +23,7 @@ import ( "time" "github.com/gdamore/tcell" - rooms "maunium.net/go/gomuks/matrix/room" + "maunium.net/go/gomuks/matrix/room" "maunium.net/go/gomuks/ui/types" "maunium.net/go/tview" ) @@ -35,6 +35,7 @@ type RoomView struct { content *MessageView status *tview.TextView userList *tview.TextView + input *AdvancedInputField Room *rooms.Room FetchHistoryLock *sync.Mutex @@ -47,33 +48,92 @@ func NewRoomView(room *rooms.Room) *RoomView { content: NewMessageView(), status: tview.NewTextView(), userList: tview.NewTextView(), + input: NewAdvancedInputField(), FetchHistoryLock: &sync.Mutex{}, Room: room, } + + view.input. + SetFieldBackgroundColor(tcell.ColorDefault). + SetPlaceholder("Send a message..."). + SetPlaceholderExtColor(tcell.ColorGray) + view.topic. SetText(strings.Replace(room.GetTopic(), "\n", " ", -1)). SetBackgroundColor(tcell.ColorDarkGreen) + view.status.SetBackgroundColor(tcell.ColorDimGray) + view.userList.SetDynamicColors(true) + return view } +func (view *RoomView) SetTabCompleteFunc(fn func(room *RoomView, text string, cursorOffset int) string) *RoomView { + view.input.SetTabCompleteFunc(func(text string, cursorOffset int) string { + return fn(view, text, cursorOffset) + }) + return view +} + +func (view *RoomView) SetInputCapture(fn func(room *RoomView, event *tcell.EventKey) *tcell.EventKey) *RoomView { + view.input.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + return fn(view, event) + }) + return view +} + +func (view *RoomView) SetInputSubmitFunc(fn func(room *RoomView, text string)) *RoomView { + view.input.SetDoneFunc(func(key tcell.Key) { + if key == tcell.KeyEnter { + fn(view, view.input.GetText()) + } + }) + return view +} + +func (view *RoomView) SetInputChangedFunc(fn func(room *RoomView, text string)) *RoomView { + view.input.SetChangedFunc(func(text string) { + fn(view, text) + }) + return view +} + +func (view *RoomView) SetInputText(newText string) *RoomView { + view.input.SetText(newText) + return view +} + +func (view *RoomView) GetInputText() string { + return view.input.GetText() +} + +func (view *RoomView) GetInputField() *AdvancedInputField { + return view.input +} + +func (view *RoomView) Focus(delegate func(p tview.Primitive)) { + delegate(view.input) +} + func (view *RoomView) Draw(screen tcell.Screen) { view.Box.Draw(screen) x, y, width, height := view.GetRect() view.topic.SetRect(x, y, width, 1) - view.content.SetRect(x, y+1, width-30, height-2) - view.status.SetRect(x, y+height-1, width, 1) - view.userList.SetRect(x+width-29, y+1, 29, height-2) + view.content.SetRect(x, y+1, width-30, height-3) + view.status.SetRect(x, y+height-2, width, 1) + view.userList.SetRect(x+width-29, y+1, 29, height-3) + view.input.SetRect(x, y+height-1, width, 1) view.topic.Draw(screen) view.content.Draw(screen) view.status.Draw(screen) + view.input.Draw(screen) borderX := x + width - 30 background := tcell.StyleDefault.Background(view.GetBackgroundColor()).Foreground(view.GetBorderColor()) - for borderY := y + 1; borderY < y+height-1; borderY++ { + for borderY := y + 1; borderY < y+height-2; borderY++ { screen.SetContent(borderX, borderY, tview.GraphicsVertBar, nil, background) } view.userList.Draw(screen)