Add mouse scrolling support to room list (ref #34)
This commit is contained in:
parent
d8dba100e0
commit
c5ec94a78f
@ -46,6 +46,8 @@ type RoomList struct {
|
|||||||
selected *rooms.Room
|
selected *rooms.Room
|
||||||
selectedTag string
|
selectedTag string
|
||||||
|
|
||||||
|
scrollOffset int
|
||||||
|
|
||||||
// The item main text color.
|
// The item main text color.
|
||||||
mainTextColor tcell.Color
|
mainTextColor tcell.Color
|
||||||
// The text color for selected items.
|
// The text color for selected items.
|
||||||
@ -60,6 +62,8 @@ func NewRoomList() *RoomList {
|
|||||||
items: make(map[string][]*rooms.Room),
|
items: make(map[string][]*rooms.Room),
|
||||||
tags: []string{"m.favourite", "net.maunium.gomuks.fake.direct", "", "m.lowpriority"},
|
tags: []string{"m.favourite", "net.maunium.gomuks.fake.direct", "", "m.lowpriority"},
|
||||||
|
|
||||||
|
scrollOffset: 0,
|
||||||
|
|
||||||
mainTextColor: tcell.ColorWhite,
|
mainTextColor: tcell.ColorWhite,
|
||||||
selectedTextColor: tcell.ColorWhite,
|
selectedTextColor: tcell.ColorWhite,
|
||||||
selectedBackgroundColor: tcell.ColorDarkGreen,
|
selectedBackgroundColor: tcell.ColorDarkGreen,
|
||||||
@ -217,6 +221,12 @@ func (list *RoomList) Clear() {
|
|||||||
func (list *RoomList) SetSelected(tag string, room *rooms.Room) {
|
func (list *RoomList) SetSelected(tag string, room *rooms.Room) {
|
||||||
list.selected = room
|
list.selected = room
|
||||||
list.selectedTag = tag
|
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))
|
debug.Print("Selecting", room.GetTitle(), "in", list.GetTagDisplayName(tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,6 +242,18 @@ func (list *RoomList) SelectedRoom() *rooms.Room {
|
|||||||
return list.selected
|
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) {
|
func (list *RoomList) First() (string, *rooms.Room) {
|
||||||
for _, tag := range list.tags {
|
for _, tag := range list.tags {
|
||||||
items := list.items[tag]
|
items := list.items[tag]
|
||||||
@ -326,7 +348,52 @@ func (list *RoomList) indexInTag(tag string, room *rooms.Room) int {
|
|||||||
return roomIndex
|
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) {
|
func (list *RoomList) Get(n int) (string, *rooms.Room) {
|
||||||
|
n += list.scrollOffset
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
@ -377,12 +444,7 @@ func (list *RoomList) Draw(screen tcell.Screen) {
|
|||||||
x, y, width, height := list.GetInnerRect()
|
x, y, width, height := list.GetInnerRect()
|
||||||
bottomLimit := y + height
|
bottomLimit := y + height
|
||||||
|
|
||||||
var offset int
|
handledOffset := 0
|
||||||
/* TODO fix offset
|
|
||||||
currentItemIndex := list.Index(list.selected)
|
|
||||||
if currentItemIndex >= height {
|
|
||||||
offset = currentItemIndex + 1 - height
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Draw the list items.
|
// Draw the list items.
|
||||||
for _, tag := range list.tags {
|
for _, tag := range list.tags {
|
||||||
@ -392,20 +454,32 @@ func (list *RoomList) Draw(screen tcell.Screen) {
|
|||||||
continue
|
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))
|
widget.WriteLine(screen, tview.AlignLeft, tagDisplayName, x, y, width, tcell.StyleDefault.Underline(true).Bold(true))
|
||||||
y++
|
y++
|
||||||
for i := len(items) - 1; i >= 0; i-- {
|
for i := len(items) - 1; i >= 0; i-- {
|
||||||
item := items[i]
|
item := items[i]
|
||||||
index := len(items) - 1 - i
|
index := len(items) - 1 - i
|
||||||
|
|
||||||
if index < offset {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if y >= bottomLimit {
|
if y >= bottomLimit {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if index < localOffset {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
text := item.GetTitle()
|
text := item.GetTitle()
|
||||||
|
|
||||||
lineWidth := width
|
lineWidth := width
|
||||||
|
@ -213,39 +213,47 @@ func (view *MainView) MouseEventHandler(roomView *RoomView, event *tcell.EventMo
|
|||||||
msgView := roomView.MessageView()
|
msgView := roomView.MessageView()
|
||||||
x, y := event.Position()
|
x, y := event.Position()
|
||||||
|
|
||||||
switch event.Buttons() {
|
switch {
|
||||||
case tcell.WheelUp:
|
case isInArea(x, y, msgView):
|
||||||
if msgView.IsAtTop() {
|
mx, my, _, _ := msgView.GetRect()
|
||||||
go view.LoadHistory(roomView.Room.ID)
|
switch event.Buttons() {
|
||||||
} else {
|
case tcell.WheelUp:
|
||||||
msgView.AddScrollOffset(WheelScrollOffsetDiff)
|
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()
|
view.parent.Render()
|
||||||
}
|
|
||||||
case tcell.WheelDown:
|
|
||||||
msgView.AddScrollOffset(-WheelScrollOffsetDiff)
|
|
||||||
|
|
||||||
view.parent.Render()
|
if msgView.ScrollOffset == 0 {
|
||||||
|
roomView.Room.MarkRead()
|
||||||
if msgView.ScrollOffset == 0 {
|
}
|
||||||
roomView.Room.MarkRead()
|
default:
|
||||||
}
|
|
||||||
default:
|
|
||||||
if isInArea(x, y, msgView) {
|
|
||||||
mx, my, _, _ := msgView.GetRect()
|
|
||||||
if msgView.HandleClick(x-mx, y-my, event.Buttons()) {
|
if msgView.HandleClick(x-mx, y-my, event.Buttons()) {
|
||||||
view.parent.Render()
|
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()
|
_, rly, _, _ := msgView.GetRect()
|
||||||
n := y - rly + 1
|
n := y - rly + 1
|
||||||
view.SwitchRoom(view.roomList.Get(n))
|
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
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +313,10 @@ func (view *MainView) GetRoom(roomID string) ifc.RoomView {
|
|||||||
room, ok := view.rooms[roomID]
|
room, ok := view.rooms[roomID]
|
||||||
if !ok {
|
if !ok {
|
||||||
view.AddRoom(roomID)
|
view.AddRoom(roomID)
|
||||||
room, _ := view.rooms[roomID]
|
room, ok := view.rooms[roomID]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return room
|
return room
|
||||||
}
|
}
|
||||||
return room
|
return room
|
||||||
|
Loading…
Reference in New Issue
Block a user