Add mouse scrolling support to room list (ref #34)

This commit is contained in:
Tulir Asokan 2018-04-30 12:40:28 +03:00
parent d8dba100e0
commit c5ec94a78f
2 changed files with 118 additions and 33 deletions

View File

@ -46,6 +46,8 @@ type RoomList struct {
selected *rooms.Room
selectedTag string
scrollOffset int
// The item main text color.
mainTextColor tcell.Color
// The text color for selected items.
@ -60,6 +62,8 @@ func NewRoomList() *RoomList {
items: make(map[string][]*rooms.Room),
tags: []string{"m.favourite", "net.maunium.gomuks.fake.direct", "", "m.lowpriority"},
scrollOffset: 0,
mainTextColor: tcell.ColorWhite,
selectedTextColor: tcell.ColorWhite,
selectedBackgroundColor: tcell.ColorDarkGreen,
@ -217,6 +221,12 @@ func (list *RoomList) Clear() {
func (list *RoomList) SetSelected(tag string, room *rooms.Room) {
list.selected = room
list.selectedTag = tag
pos := list.index(tag, room)
_, _, _, height := list.GetRect()
if pos < list.scrollOffset || pos > list.scrollOffset+height {
// TODO this does weird stuff sometimes, needs to be fixed
//list.scrollOffset = pos
}
debug.Print("Selecting", room.GetTitle(), "in", list.GetTagDisplayName(tag))
}
@ -232,6 +242,18 @@ func (list *RoomList) SelectedRoom() *rooms.Room {
return list.selected
}
func (list *RoomList) AddScrollOffset(offset int) {
list.scrollOffset += offset
if list.scrollOffset < 0 {
list.scrollOffset = 0
}
_, _, _, viewHeight := list.GetRect()
contentHeight := list.ContentHeight()
if list.scrollOffset > contentHeight-viewHeight {
list.scrollOffset = contentHeight - viewHeight
}
}
func (list *RoomList) First() (string, *rooms.Room) {
for _, tag := range list.tags {
items := list.items[tag]
@ -326,7 +348,52 @@ func (list *RoomList) indexInTag(tag string, room *rooms.Room) int {
return roomIndex
}
func (list *RoomList) index(tag string, room *rooms.Room) int {
tagIndex := list.IndexTag(tag)
if tagIndex == -1 {
return -1
}
localIndex := list.indexInTag(tag, room)
if localIndex == -1 {
return -1
}
// Tag header
localIndex += 1
if tagIndex > 0 {
for i := 0; i < tagIndex; i++ {
previousTag := list.tags[i]
previousItems := list.items[previousTag]
tagDisplayName := list.GetTagDisplayName(previousTag)
if len(tagDisplayName) > 0 {
// Previous tag header + space
localIndex += 2
// Previous tag items
localIndex += len(previousItems)
}
}
}
return localIndex
}
func (list *RoomList) ContentHeight() (height int) {
for _, tag := range list.tags {
items := list.items[tag]
tagDisplayName := list.GetTagDisplayName(tag)
if len(tagDisplayName) == 0 {
continue
}
height += 2 + len(items)
}
return
}
func (list *RoomList) Get(n int) (string, *rooms.Room) {
n += list.scrollOffset
if n < 0 {
return "", nil
}
@ -377,12 +444,7 @@ func (list *RoomList) Draw(screen tcell.Screen) {
x, y, width, height := list.GetInnerRect()
bottomLimit := y + height
var offset int
/* TODO fix offset
currentItemIndex := list.Index(list.selected)
if currentItemIndex >= height {
offset = currentItemIndex + 1 - height
}*/
handledOffset := 0
// Draw the list items.
for _, tag := range list.tags {
@ -392,20 +454,32 @@ func (list *RoomList) Draw(screen tcell.Screen) {
continue
}
localOffset := 0
if handledOffset < list.scrollOffset {
if handledOffset+len(items) < list.scrollOffset {
handledOffset += len(items) + 2
continue
} else {
localOffset = list.scrollOffset - handledOffset
handledOffset += localOffset
}
}
widget.WriteLine(screen, tview.AlignLeft, tagDisplayName, x, y, width, tcell.StyleDefault.Underline(true).Bold(true))
y++
for i := len(items) - 1; i >= 0; i-- {
item := items[i]
index := len(items) - 1 - i
if index < offset {
continue
}
if y >= bottomLimit {
break
}
if index < localOffset {
continue
}
text := item.GetTitle()
lineWidth := width

View File

@ -213,39 +213,47 @@ func (view *MainView) MouseEventHandler(roomView *RoomView, event *tcell.EventMo
msgView := roomView.MessageView()
x, y := event.Position()
switch event.Buttons() {
case tcell.WheelUp:
if msgView.IsAtTop() {
go view.LoadHistory(roomView.Room.ID)
} else {
msgView.AddScrollOffset(WheelScrollOffsetDiff)
switch {
case isInArea(x, y, msgView):
mx, my, _, _ := msgView.GetRect()
switch event.Buttons() {
case tcell.WheelUp:
if msgView.IsAtTop() {
go view.LoadHistory(roomView.Room.ID)
} else {
msgView.AddScrollOffset(WheelScrollOffsetDiff)
view.parent.Render()
}
case tcell.WheelDown:
msgView.AddScrollOffset(-WheelScrollOffsetDiff)
view.parent.Render()
}
case tcell.WheelDown:
msgView.AddScrollOffset(-WheelScrollOffsetDiff)
view.parent.Render()
if msgView.ScrollOffset == 0 {
roomView.Room.MarkRead()
}
default:
if isInArea(x, y, msgView) {
mx, my, _, _ := msgView.GetRect()
if msgView.ScrollOffset == 0 {
roomView.Room.MarkRead()
}
default:
if msgView.HandleClick(x-mx, y-my, event.Buttons()) {
view.parent.Render()
}
} else if isInArea(x, y, view.roomList) && event.Buttons() == tcell.Button1 {
}
case isInArea(x, y, view.roomList):
switch event.Buttons() {
case tcell.WheelUp:
view.roomList.AddScrollOffset(-WheelScrollOffsetDiff)
view.parent.Render()
case tcell.WheelDown:
view.roomList.AddScrollOffset(WheelScrollOffsetDiff)
view.parent.Render()
case tcell.Button1:
_, rly, _, _ := msgView.GetRect()
n := y - rly + 1
view.SwitchRoom(view.roomList.Get(n))
} else {
debug.Print("Unhandled mouse event:", event.Buttons(), event.Modifiers(), x, y)
}
return event
default:
debug.Print("Unhandled mouse event:", event.Buttons(), event.Modifiers(), x, y)
}
return event
}
@ -305,7 +313,10 @@ func (view *MainView) GetRoom(roomID string) ifc.RoomView {
room, ok := view.rooms[roomID]
if !ok {
view.AddRoom(roomID)
room, _ := view.rooms[roomID]
room, ok := view.rooms[roomID]
if !ok {
return nil
}
return room
}
return room