aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-03-25 14:21:59 +0300
committerTulir Asokan <tulir@maunium.net>2018-03-25 14:21:59 +0300
commit23bb46b18fa88ec870ba78cb7f08b296257b4ac5 (patch)
treeda1013995db1fd1187621fb9ccfd79976493570c
parentc1286661090731729e76e48d5e47988ad0175a20 (diff)
Move room list to custom widget
-rw-r--r--ui/view-main.go30
-rw-r--r--ui/widget/message-view.go55
-rw-r--r--ui/widget/room-list.go128
-rw-r--r--ui/widget/util.go47
4 files changed, 195 insertions, 65 deletions
diff --git a/ui/view-main.go b/ui/view-main.go
index a5580b3..2014aea 100644
--- a/ui/view-main.go
+++ b/ui/view-main.go
@@ -37,7 +37,7 @@ import (
type MainView struct {
*tview.Flex
- roomList *tview.List
+ roomList *widget.RoomList
roomView *tview.Pages
rooms map[string]*widget.RoomView
currentRoomIndex int
@@ -54,7 +54,7 @@ type MainView struct {
func (ui *GomuksUI) NewMainView() tview.Primitive {
mainView := &MainView{
Flex: tview.NewFlex(),
- roomList: tview.NewList(),
+ roomList: widget.NewRoomList(),
roomView: tview.NewPages(),
rooms: make(map[string]*widget.RoomView),
@@ -64,12 +64,6 @@ func (ui *GomuksUI) NewMainView() tview.Primitive {
parent: ui,
}
- mainView.roomList.
- ShowSecondaryText(false).
- SetSelectedBackgroundColor(tcell.ColorDarkGreen).
- SetSelectedTextColor(tcell.ColorWhite).
- SetBorderPadding(0, 0, 1, 0)
-
mainView.SetDirection(tview.FlexColumn)
mainView.AddItem(mainView.roomList, 25, 0, false)
mainView.AddItem(widget.NewBorder(), 1, 0, false)
@@ -186,13 +180,12 @@ func (view *MainView) KeyEventHandler(roomView *widget.RoomView, key *tcell.Even
k := key.Key()
if key.Modifiers() == tcell.ModCtrl || key.Modifiers() == tcell.ModAlt {
- if k == tcell.KeyDown {
+ switch k {
+ case tcell.KeyDown:
view.SwitchRoom(view.currentRoomIndex + 1)
- view.roomList.SetCurrentItem(view.currentRoomIndex)
- } else if k == tcell.KeyUp {
+ case tcell.KeyUp:
view.SwitchRoom(view.currentRoomIndex - 1)
- view.roomList.SetCurrentItem(view.currentRoomIndex)
- } else {
+ default:
return key
}
} else if k == tcell.KeyPgUp || k == tcell.KeyPgDn || k == tcell.KeyUp || k == tcell.KeyDown || k == tcell.KeyEnd || k == tcell.KeyHome {
@@ -265,7 +258,7 @@ func (view *MainView) SwitchRoom(roomIndex int) {
}
view.currentRoomIndex = roomIndex % len(view.roomIDs)
view.roomView.SwitchToPage(view.CurrentRoomID())
- view.roomList.SetCurrentItem(roomIndex)
+ view.roomList.SetSelected(view.rooms[view.CurrentRoomID()].Room)
view.gmx.App().SetFocus(view)
view.parent.Render()
}
@@ -289,9 +282,7 @@ func (view *MainView) SaveAllHistory() {
func (view *MainView) addRoom(index int, room string) {
roomStore := view.matrix.GetRoom(room)
- view.roomList.AddItem(roomStore.GetTitle(), "", 0, func() {
- view.SwitchRoom(index)
- })
+ view.roomList.Add(roomStore)
if !view.roomView.HasPage(room) {
roomView := widget.NewRoomView(roomStore).
SetInputSubmitFunc(view.InputSubmit).
@@ -334,7 +325,8 @@ func (view *MainView) AddRoom(room string) {
}
func (view *MainView) RemoveRoom(room string) {
- if !view.HasRoom(room) {
+ roomView := view.GetRoom(room)
+ if roomView == nil {
return
}
removeIndex := 0
@@ -344,7 +336,7 @@ func (view *MainView) RemoveRoom(room string) {
} else {
removeIndex = sort.StringSlice(view.roomIDs).Search(room)
}
- view.roomList.RemoveItem(removeIndex)
+ view.roomList.Remove(roomView.Room)
view.roomIDs = append(view.roomIDs[:removeIndex], view.roomIDs[removeIndex+1:]...)
view.roomView.RemovePage(room)
delete(view.rooms, room)
diff --git a/ui/widget/message-view.go b/ui/widget/message-view.go
index 50de405..6f07c55 100644
--- a/ui/widget/message-view.go
+++ b/ui/widget/message-view.go
@@ -24,7 +24,6 @@ import (
"time"
"github.com/gdamore/tcell"
- "github.com/mattn/go-runewidth"
"maunium.net/go/gomuks/ui/debug"
"maunium.net/go/gomuks/ui/types"
"maunium.net/go/tview"
@@ -248,42 +247,6 @@ func (view *MessageView) IsAtTop() bool {
return view.ScrollOffset >= totalHeight-height+PaddingAtTop
}
-func (view *MessageView) writeLine(screen tcell.Screen, line string, x, y int, color tcell.Color) {
- offsetX := 0
- for _, ch := range line {
- chWidth := runewidth.RuneWidth(ch)
- if chWidth == 0 {
- continue
- }
-
- for localOffset := 0; localOffset < chWidth; localOffset++ {
- screen.SetContent(x+offsetX+localOffset, y, ch, nil, tcell.StyleDefault.Foreground(color))
- }
- offsetX += chWidth
- }
-}
-
-func (view *MessageView) writeLineRight(screen tcell.Screen, line string, x, y, maxWidth int, color tcell.Color) {
- offsetX := maxWidth - runewidth.StringWidth(line)
- if offsetX < 0 {
- offsetX = 0
- }
- for _, ch := range line {
- chWidth := runewidth.RuneWidth(ch)
- if chWidth == 0 {
- continue
- }
-
- for localOffset := 0; localOffset < chWidth; localOffset++ {
- screen.SetContent(x+offsetX+localOffset, y, ch, nil, tcell.StyleDefault.Foreground(color))
- }
- offsetX += chWidth
- if offsetX > maxWidth {
- break
- }
- }
-}
-
const (
TimestampSenderGap = 1
SenderSeparatorGap = 1
@@ -293,11 +256,11 @@ const (
func (view *MessageView) Draw(screen tcell.Screen) {
view.Box.Draw(screen)
- x, y, _, height := view.GetInnerRect()
+ x, y, width, height := view.GetInnerRect()
view.recalculateBuffers()
if len(view.textBuffer) == 0 {
- view.writeLine(screen, "It's quite empty in here.", x, y+height, tcell.ColorDefault)
+ writeLine(screen, tview.AlignLeft,"It's quite empty in here.", x, y+height, width, tcell.ColorDefault)
return
}
@@ -311,7 +274,7 @@ func (view *MessageView) Draw(screen tcell.Screen) {
if view.LoadingMessages {
message = "Loading more messages..."
}
- view.writeLine(screen, message, messageX, y, tcell.ColorGreen)
+ writeLine(screen, tview.AlignLeft, message, messageX, y, width, tcell.ColorGreen)
}
if len(view.textBuffer) != len(view.metaBuffer) {
@@ -355,16 +318,16 @@ func (view *MessageView) Draw(screen tcell.Screen) {
text, meta := view.textBuffer[index], view.metaBuffer[index]
if meta != prevMeta {
if len(meta.GetTimestamp()) > 0 {
- view.writeLine(screen, meta.GetTimestamp(), x, y+line, meta.GetTimestampColor())
+ writeLine(screen, tview.AlignLeft, meta.GetTimestamp(), x, y+line, width, meta.GetTimestampColor())
}
if prevMeta == nil || meta.GetSender() != prevMeta.GetSender() {
- view.writeLineRight(
- screen, meta.GetSender(),
- usernameX, y+line,
- view.widestSender, meta.GetSenderColor())
+ writeLine(
+ screen, tview.AlignRight, meta.GetSender(),
+ usernameX, y+line, view.widestSender,
+ meta.GetSenderColor())
}
prevMeta = meta
}
- view.writeLine(screen, text, messageX, y+line, meta.GetTextColor())
+ writeLine(screen, tview.AlignLeft, text, messageX, y+line, width, meta.GetTextColor())
}
}
diff --git a/ui/widget/room-list.go b/ui/widget/room-list.go
new file mode 100644
index 0000000..b908510
--- /dev/null
+++ b/ui/widget/room-list.go
@@ -0,0 +1,128 @@
+// gomuks - A terminal Matrix client written in Go.
+// Copyright (C) 2018 Tulir Asokan
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package widget
+
+import (
+ "github.com/gdamore/tcell"
+ "maunium.net/go/gomuks/matrix/rooms"
+ "maunium.net/go/tview"
+)
+
+type RoomList struct {
+ *tview.Box
+
+ indices map[*rooms.Room]int
+ items []*rooms.Room
+ selected *rooms.Room
+
+ // The item main text color.
+ mainTextColor tcell.Color
+ // The text color for selected items.
+ selectedTextColor tcell.Color
+ // The background color for selected items.
+ selectedBackgroundColor tcell.Color
+}
+
+func NewRoomList() *RoomList {
+ return &RoomList{
+ Box: tview.NewBox(),
+ indices: make(map[*rooms.Room]int),
+ items: []*rooms.Room{},
+
+ mainTextColor: tcell.ColorWhite,
+ selectedTextColor: tcell.ColorWhite,
+ selectedBackgroundColor: tcell.ColorDarkGreen,
+ }
+}
+
+func (list *RoomList) Add(room *rooms.Room) {
+ list.indices[room] = len(list.items)
+ list.items = append(list.items, room)
+ if list.selected == nil {
+ list.selected = room
+ }
+}
+
+func (list *RoomList) Remove(room *rooms.Room) {
+ index, ok := list.indices[room]
+ if !ok {
+ return
+ }
+ delete(list.indices, room)
+ list.items = append(list.items[0:index], list.items[index+1:]...)
+ if len(list.items) == 0 {
+ list.selected = nil
+ }
+}
+
+func (list *RoomList) Clear() {
+ list.indices = make(map[*rooms.Room]int)
+ list.items = []*rooms.Room{}
+ list.selected = nil
+}
+
+func (list *RoomList) SetSelected(room *rooms.Room) {
+ list.selected = room
+}
+
+// Draw draws this primitive onto the screen.
+func (list *RoomList) Draw(screen tcell.Screen) {
+ list.Box.Draw(screen)
+
+ x, y, width, height := list.GetInnerRect()
+ bottomLimit := y + height
+
+ var offset int
+ currentItemIndex, hasSelected := list.indices[list.selected]
+ if hasSelected && currentItemIndex >= height {
+ offset = currentItemIndex + 1 - height
+ }
+
+ // Draw the list items.
+ for index, item := range list.items {
+ if index < offset {
+ continue
+ }
+
+ if y >= bottomLimit {
+ break
+ }
+
+ text := item.GetTitle()
+
+ writeLine(screen, tview.AlignLeft, text, x, y, width, list.mainTextColor)
+
+ // Background color of selected text.
+ if item == list.selected {
+ textWidth := tview.StringWidth(text)
+ for bx := 0; bx < textWidth && bx < width; bx++ {
+ m, c, style, _ := screen.GetContent(x+bx, y)
+ fg, _, _ := style.Decompose()
+ if fg == list.mainTextColor {
+ fg = list.selectedTextColor
+ }
+ style = style.Background(list.selectedBackgroundColor).Foreground(fg)
+ screen.SetContent(x+bx, y, m, c, style)
+ }
+ }
+
+ y++
+ if y >= bottomLimit {
+ break
+ }
+ }
+}
diff --git a/ui/widget/util.go b/ui/widget/util.go
new file mode 100644
index 0000000..5bde263
--- /dev/null
+++ b/ui/widget/util.go
@@ -0,0 +1,47 @@
+// gomuks - A terminal Matrix client written in Go.
+// Copyright (C) 2018 Tulir Asokan
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package widget
+
+import (
+ "github.com/gdamore/tcell"
+ "github.com/mattn/go-runewidth"
+ "maunium.net/go/tview"
+)
+
+func writeLine(screen tcell.Screen, align int, line string, x, y, maxWidth int, color tcell.Color) {
+ offsetX := 0
+ if align == tview.AlignRight {
+ offsetX = maxWidth - runewidth.StringWidth(line)
+ }
+ if offsetX < 0 {
+ offsetX = 0
+ }
+ for _, ch := range line {
+ chWidth := runewidth.RuneWidth(ch)
+ if chWidth == 0 {
+ continue
+ }
+
+ for localOffset := 0; localOffset < chWidth; localOffset++ {
+ screen.SetContent(x+offsetX+localOffset, y, ch, nil, tcell.StyleDefault.Foreground(color))
+ }
+ offsetX += chWidth
+ if offsetX > maxWidth {
+ break
+ }
+ }
+}