Fix and/or break scroll bar
This commit is contained in:
parent
ef326eae82
commit
6095638fbb
@ -232,11 +232,16 @@ func (view *MainView) MouseEventHandler(roomView *widget.RoomView, event *tcell.
|
|||||||
go view.LoadHistory(roomView.Room.ID, false)
|
go view.LoadHistory(roomView.Room.ID, false)
|
||||||
} else {
|
} else {
|
||||||
msgView.AddScrollOffset(WheelScrollOffsetDiff)
|
msgView.AddScrollOffset(WheelScrollOffsetDiff)
|
||||||
|
|
||||||
|
view.parent.Render()
|
||||||
}
|
}
|
||||||
case tcell.WheelDown:
|
case tcell.WheelDown:
|
||||||
msgView.AddScrollOffset(-WheelScrollOffsetDiff)
|
msgView.AddScrollOffset(-WheelScrollOffsetDiff)
|
||||||
|
|
||||||
|
view.parent.Render()
|
||||||
default:
|
default:
|
||||||
debug.Print("Mouse event received:", event.Buttons(), event.Modifiers(), x, y)
|
debug.Print("Mouse event received:", event.Buttons(), event.Modifiers(), x, y)
|
||||||
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
return event
|
return event
|
||||||
|
@ -214,20 +214,16 @@ func (view *MessageView) AddScrollOffset(diff int) {
|
|||||||
_, _, _, height := view.GetInnerRect()
|
_, _, _, height := view.GetInnerRect()
|
||||||
|
|
||||||
totalHeight := len(view.textBuffer)
|
totalHeight := len(view.textBuffer)
|
||||||
if diff >= 0 && view.ScrollOffset >= totalHeight-height {
|
if diff >= 0 && view.ScrollOffset+diff >= totalHeight-height+PaddingAtTop {
|
||||||
// If the user is at the top and presses page up again, add a bit of blank space.
|
view.ScrollOffset = totalHeight - height + PaddingAtTop
|
||||||
if view.ScrollOffset+diff >= totalHeight-height+PaddingAtTop {
|
} else {
|
||||||
view.ScrollOffset = totalHeight - height + PaddingAtTop
|
view.ScrollOffset += diff
|
||||||
} else {
|
|
||||||
view.ScrollOffset += diff
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view.ScrollOffset += diff
|
if view.ScrollOffset > totalHeight-height+PaddingAtTop {
|
||||||
if view.ScrollOffset > totalHeight-height {
|
view.ScrollOffset = totalHeight - height + PaddingAtTop
|
||||||
view.ScrollOffset = totalHeight - height
|
}
|
||||||
} else if view.ScrollOffset < 0 {
|
if view.ScrollOffset < 0 {
|
||||||
view.ScrollOffset = 0
|
view.ScrollOffset = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,6 +249,30 @@ const (
|
|||||||
SenderMessageGap = 3
|
SenderMessageGap = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getScrollbarStyle(scrollbarHere, isTop, isBottom bool) (char rune, style tcell.Style) {
|
||||||
|
char = '│'
|
||||||
|
style = tcell.StyleDefault
|
||||||
|
if scrollbarHere {
|
||||||
|
style = style.Foreground(tcell.ColorGreen)
|
||||||
|
}
|
||||||
|
if isTop {
|
||||||
|
if scrollbarHere {
|
||||||
|
char = '╥'
|
||||||
|
} else {
|
||||||
|
char = '┬'
|
||||||
|
}
|
||||||
|
} else if isBottom {
|
||||||
|
if scrollbarHere {
|
||||||
|
char = '╨'
|
||||||
|
} else {
|
||||||
|
char = '┴'
|
||||||
|
}
|
||||||
|
} else if scrollbarHere {
|
||||||
|
char = '║'
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (view *MessageView) Draw(screen tcell.Screen) {
|
func (view *MessageView) Draw(screen tcell.Screen) {
|
||||||
view.Box.Draw(screen)
|
view.Box.Draw(screen)
|
||||||
|
|
||||||
@ -260,7 +280,7 @@ func (view *MessageView) Draw(screen tcell.Screen) {
|
|||||||
view.recalculateBuffers()
|
view.recalculateBuffers()
|
||||||
|
|
||||||
if len(view.textBuffer) == 0 {
|
if len(view.textBuffer) == 0 {
|
||||||
writeLine(screen, tview.AlignLeft,"It's quite empty in here.", x, y+height, width, tcell.ColorDefault)
|
writeLine(screen, tview.AlignLeft, "It's quite empty in here.", x, y+height, width, tcell.ColorDefault)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,37 +302,38 @@ func (view *MessageView) Draw(screen tcell.Screen) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
totalHeight := float64(len(view.textBuffer))
|
var scrollBarHeight, scrollBarPos int
|
||||||
// The height of the scrollbar: ceil(height / (totalHeight / height))
|
// Black magic (aka math) used to figure out where the scroll bar should be put.
|
||||||
scrollBarHeight := int(math.Ceil(float64(height) / (totalHeight / float64(height))))
|
{
|
||||||
// The position of the scrollbar from the bottom: height - ceil(scrollOffset) / totalHeight * height
|
viewportHeight := float64(height)
|
||||||
scrollBarPos := height - int(math.Ceil(float64(view.ScrollOffset)/totalHeight*float64(height)))
|
contentHeight := float64(len(view.textBuffer))
|
||||||
|
|
||||||
|
scrollBarHeight = int(math.Ceil(viewportHeight / (contentHeight / viewportHeight)))
|
||||||
|
|
||||||
|
scrollBarPos = height - int(math.Round(float64(view.ScrollOffset)/contentHeight*viewportHeight))
|
||||||
|
}
|
||||||
|
|
||||||
var prevMeta types.MessageMeta
|
var prevMeta types.MessageMeta
|
||||||
firstLine := true
|
firstLine := true
|
||||||
|
skippedLines := 0
|
||||||
|
|
||||||
for line := 0; line < height; line++ {
|
for line := 0; line < height; line++ {
|
||||||
index := indexOffset + line
|
index := indexOffset + line
|
||||||
if index < 0 {
|
if index < 0 {
|
||||||
|
skippedLines++
|
||||||
continue
|
continue
|
||||||
} else if index >= len(view.textBuffer) {
|
} else if index >= len(view.textBuffer) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
borderChar := '│'
|
showScrollbar := line-skippedLines >= scrollBarPos-scrollBarHeight && line-skippedLines < scrollBarPos
|
||||||
borderStyle := tcell.StyleDefault
|
isTop := firstLine && view.ScrollOffset+height >= len(view.textBuffer)
|
||||||
if firstLine && view.ScrollOffset+height >= len(view.textBuffer) {
|
isBottom := line == height-1 && view.ScrollOffset == 0
|
||||||
// At top of loaded message history
|
|
||||||
borderChar = '┬'
|
borderChar, borderStyle := getScrollbarStyle(showScrollbar, isTop, isBottom)
|
||||||
} else if line == height-1 && view.ScrollOffset == 0 {
|
|
||||||
// At bottom of message history
|
|
||||||
borderChar = '┴'
|
|
||||||
} else if line >= scrollBarPos && line < scrollBarPos+scrollBarHeight {
|
|
||||||
// Scroll bar
|
|
||||||
borderChar = '║'
|
|
||||||
borderStyle = borderStyle.Foreground(tcell.ColorGreen)
|
|
||||||
}
|
|
||||||
firstLine = false
|
firstLine = false
|
||||||
|
|
||||||
screen.SetContent(separatorX, y+line, borderChar, nil, borderStyle)
|
screen.SetContent(separatorX, y+line, borderChar, nil, borderStyle)
|
||||||
|
|
||||||
text, meta := view.textBuffer[index], view.metaBuffer[index]
|
text, meta := view.textBuffer[index], view.metaBuffer[index]
|
||||||
|
Loading…
Reference in New Issue
Block a user