aboutsummaryrefslogtreecommitdiff
path: root/ui/widget
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 /ui/widget
parentc1286661090731729e76e48d5e47988ad0175a20 (diff)
Move room list to custom widget
Diffstat (limited to 'ui/widget')
-rw-r--r--ui/widget/message-view.go55
-rw-r--r--ui/widget/room-list.go128
-rw-r--r--ui/widget/util.go47
3 files changed, 184 insertions, 46 deletions
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
+ }
+ }
+}