From c1286661090731729e76e48d5e47988ad0175a20 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 25 Mar 2018 12:35:50 +0300 Subject: Refactor things and add proper wheel scroll support --- ui/view-main.go | 51 +++++++++++++++++++++++++++++++++++++---------- ui/widget/message-view.go | 39 ++++++++++++++++-------------------- 2 files changed, 57 insertions(+), 33 deletions(-) (limited to 'ui') diff --git a/ui/view-main.go b/ui/view-main.go index e5c6792..a5580b3 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -195,16 +195,26 @@ func (view *MainView) KeyEventHandler(roomView *widget.RoomView, key *tcell.Even } else { return key } - } else if k == tcell.KeyPgUp || k == tcell.KeyPgDn || k == tcell.KeyUp || k == tcell.KeyDown { + } else if k == tcell.KeyPgUp || k == tcell.KeyPgDn || k == tcell.KeyUp || k == tcell.KeyDown || k == tcell.KeyEnd || k == tcell.KeyHome { msgView := roomView.MessageView() - if k == tcell.KeyPgUp || k == tcell.KeyUp { - if msgView.IsAtTop() { - go view.LoadHistory(roomView.Room.ID, false) - } else { - msgView.MoveUp(k == tcell.KeyPgUp) - } - } else { - msgView.MoveDown(k == tcell.KeyPgDn) + + if msgView.IsAtTop() && (k == tcell.KeyPgUp || k == tcell.KeyUp) { + go view.LoadHistory(roomView.Room.ID, false) + } + + switch k { + case tcell.KeyPgUp: + msgView.AddScrollOffset(msgView.Height() / 2) + case tcell.KeyPgDn: + msgView.AddScrollOffset(-msgView.Height() / 2) + case tcell.KeyUp: + msgView.AddScrollOffset(1) + case tcell.KeyDown: + msgView.AddScrollOffset(-1) + case tcell.KeyHome: + msgView.AddScrollOffset(msgView.TotalHeight()) + case tcell.KeyEnd: + msgView.AddScrollOffset(-msgView.TotalHeight()) } } else { return key @@ -212,9 +222,28 @@ func (view *MainView) KeyEventHandler(roomView *widget.RoomView, key *tcell.Even return nil } +const WheelScrollOffsetDiff = 3 + func (view *MainView) MouseEventHandler(roomView *widget.RoomView, event *tcell.EventMouse) *tcell.EventMouse { - if event.Buttons() != tcell.ButtonNone { - view.BumpFocus() + if event.Buttons() == tcell.ButtonNone { + return event + } + view.BumpFocus() + + msgView := roomView.MessageView() + x, y := event.Position() + + switch event.Buttons() { + case tcell.WheelUp: + if msgView.IsAtTop() { + go view.LoadHistory(roomView.Room.ID, false) + } else { + msgView.AddScrollOffset(WheelScrollOffsetDiff) + } + case tcell.WheelDown: + msgView.AddScrollOffset(-WheelScrollOffsetDiff) + default: + debug.Print("Mouse event received:", event.Buttons(), event.Modifiers(), x, y) } return event diff --git a/ui/widget/message-view.go b/ui/widget/message-view.go index a3a7942..50de405 100644 --- a/ui/widget/message-view.go +++ b/ui/widget/message-view.go @@ -211,46 +211,41 @@ func (view *MessageView) recalculateBuffers() { const PaddingAtTop = 5 -func (view *MessageView) MoveUp(page bool) { +func (view *MessageView) AddScrollOffset(diff int) { _, _, _, height := view.GetInnerRect() totalHeight := len(view.textBuffer) - if view.ScrollOffset >= totalHeight-height { + if diff >= 0 && view.ScrollOffset >= totalHeight-height { // If the user is at the top and presses page up again, add a bit of blank space. - if page { + if view.ScrollOffset+diff >= totalHeight-height+PaddingAtTop { view.ScrollOffset = totalHeight - height + PaddingAtTop - } else if view.ScrollOffset < totalHeight-height+PaddingAtTop { - view.ScrollOffset++ + } else { + view.ScrollOffset += diff } return } - if page { - view.ScrollOffset += height / 2 - } else { - view.ScrollOffset++ - } + view.ScrollOffset += diff if view.ScrollOffset > totalHeight-height { view.ScrollOffset = totalHeight - height + } else if view.ScrollOffset < 0 { + view.ScrollOffset = 0 } } -func (view *MessageView) IsAtTop() bool { +func (view *MessageView) Height() int { _, _, _, height := view.GetInnerRect() - totalHeight := len(view.textBuffer) - return view.ScrollOffset >= totalHeight-height+PaddingAtTop + return height +} + +func (view *MessageView) TotalHeight() int { + return len(view.textBuffer) } -func (view *MessageView) MoveDown(page bool) { +func (view *MessageView) IsAtTop() bool { _, _, _, height := view.GetInnerRect() - if page { - view.ScrollOffset -= height / 2 - } else { - view.ScrollOffset-- - } - if view.ScrollOffset < 0 { - view.ScrollOffset = 0 - } + totalHeight := len(view.textBuffer) + return view.ScrollOffset >= totalHeight-height+PaddingAtTop } func (view *MessageView) writeLine(screen tcell.Screen, line string, x, y int, color tcell.Color) { -- cgit v1.2.3