Skip to content

Commit

Permalink
support actual mouse support and focusing the main view
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed Jun 29, 2019
1 parent 405bb85 commit e220bed
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 72 deletions.
4 changes: 2 additions & 2 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 2 additions & 6 deletions pkg/gui/containers_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ func (gui *Gui) handleContainersClick(g *gocui.Gui, v *gocui.View) error {
}

func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View) error {
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
return err
}

container, err := gui.getSelectedContainer()
if err != nil {
if err != gui.Errors.ErrNoContainers {
Expand Down Expand Up @@ -314,7 +310,7 @@ func (gui *Gui) refreshContainersAndServices() error {
}

func (gui *Gui) handleContainersNextLine(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
if gui.popupPanelFocused() || gui.g.CurrentView() != v {
return nil
}

Expand All @@ -325,7 +321,7 @@ func (gui *Gui) handleContainersNextLine(g *gocui.Gui, v *gocui.View) error {
}

func (gui *Gui) handleContainersPrevLine(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
if gui.popupPanelFocused() || gui.g.CurrentView() != v {
return nil
}

Expand Down
8 changes: 2 additions & 6 deletions pkg/gui/images_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ func (gui *Gui) handleImagesClick(g *gocui.Gui, v *gocui.View) error {
}

func (gui *Gui) handleImageSelect(g *gocui.Gui, v *gocui.View) error {
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
return err
}

Image, err := gui.getSelectedImage(g)
if err != nil {
if err != gui.Errors.ErrNoImages {
Expand Down Expand Up @@ -151,7 +147,7 @@ func (gui *Gui) refreshStateImages() error {
}

func (gui *Gui) handleImagesNextLine(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
if gui.popupPanelFocused() || gui.g.CurrentView() != v {
return nil
}

Expand All @@ -162,7 +158,7 @@ func (gui *Gui) handleImagesNextLine(g *gocui.Gui, v *gocui.View) error {
}

func (gui *Gui) handleImagesPrevLine(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
if gui.popupPanelFocused() || gui.g.CurrentView() != v {
return nil
}

Expand Down
108 changes: 90 additions & 18 deletions pkg/gui/keybindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleStatusNextContext,
Description: gui.Tr.NextContext,
},
{
ViewName: "status",
Key: gocui.MouseLeft,
Modifier: gocui.ModNone,
Handler: gui.handleStatusClick,
Description: gui.Tr.NextContext,
},
{
ViewName: "status",
Key: 'm',
Expand Down Expand Up @@ -366,43 +373,108 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handlePruneVolumes,
Description: gui.Tr.PruneVolumes,
},
{
ViewName: "main",
Key: gocui.KeyEsc,
Modifier: gocui.ModNone,
Handler: gui.handleExitMain,
Description: gui.Tr.Return,
},
{
ViewName: "main",
Key: gocui.KeyArrowLeft,
Modifier: gocui.ModNone,
Handler: gui.scrollLeftMain,
},
{
ViewName: "main",
Key: gocui.KeyArrowRight,
Modifier: gocui.ModNone,
Handler: gui.scrollRightMain,
},
{
ViewName: "main",
Key: 'h',
Modifier: gocui.ModNone,
Handler: gui.scrollLeftMain,
},
{
ViewName: "main",
Key: 'l',
Modifier: gocui.ModNone,
Handler: gui.scrollRightMain,
},
{
ViewName: "",
Key: 'J',
Modifier: gocui.ModNone,
Handler: gui.scrollDownMain,
},
{
ViewName: "",
Key: 'K',
Modifier: gocui.ModNone,
Handler: gui.scrollUpMain,
},
{
ViewName: "",
Key: 'H',
Modifier: gocui.ModNone,
Handler: gui.scrollLeftMain,
},
{
ViewName: "",
Key: 'L',
Modifier: gocui.ModNone,
Handler: gui.scrollRightMain,
},
}

// TODO: add more views here
for _, viewName := range []string{"status", "services", "containers", "images", "volumes", "menu"} {
bindings = append(bindings, []*Binding{
{ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView},
{ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView},
{ViewName: viewName, Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.nextView},
{ViewName: viewName, Key: 'h', Modifier: gocui.ModNone, Handler: gui.previousView},
{ViewName: viewName, Key: 'l', Modifier: gocui.ModNone, Handler: gui.nextView},
}...)
}

listPanelMap := map[string]struct {
prevLine func(*gocui.Gui, *gocui.View) error
nextLine func(*gocui.Gui, *gocui.View) error
focus func(*gocui.Gui, *gocui.View) error
panelMap := map[string]struct {
onKeyUpPress func(*gocui.Gui, *gocui.View) error
onKeyDownPress func(*gocui.Gui, *gocui.View) error
onClick func(*gocui.Gui, *gocui.View) error
}{
"menu": {prevLine: gui.handleMenuPrevLine, nextLine: gui.handleMenuNextLine, focus: gui.handleMenuClick},
"services": {prevLine: gui.handleServicesPrevLine, nextLine: gui.handleServicesNextLine, focus: gui.handleServicesClick},
"containers": {prevLine: gui.handleContainersPrevLine, nextLine: gui.handleContainersNextLine, focus: gui.handleContainersClick},
"images": {prevLine: gui.handleImagesPrevLine, nextLine: gui.handleImagesNextLine, focus: gui.handleImagesClick},
"volumes": {prevLine: gui.handleVolumesPrevLine, nextLine: gui.handleVolumesNextLine, focus: gui.handleVolumesClick},
"menu": {onKeyUpPress: gui.handleMenuPrevLine, onKeyDownPress: gui.handleMenuNextLine, onClick: gui.handleMenuClick},
"services": {onKeyUpPress: gui.handleServicesPrevLine, onKeyDownPress: gui.handleServicesNextLine, onClick: gui.handleServicesClick},
"containers": {onKeyUpPress: gui.handleContainersPrevLine, onKeyDownPress: gui.handleContainersNextLine, onClick: gui.handleContainersClick},
"images": {onKeyUpPress: gui.handleImagesPrevLine, onKeyDownPress: gui.handleImagesNextLine, onClick: gui.handleImagesClick},
"volumes": {onKeyUpPress: gui.handleVolumesPrevLine, onKeyDownPress: gui.handleVolumesNextLine, onClick: gui.handleVolumesClick},
"main": {onKeyUpPress: gui.scrollUpMain, onKeyDownPress: gui.scrollDownMain, onClick: gui.handleMainClick},
}

for viewName, functions := range listPanelMap {
for viewName, functions := range panelMap {
bindings = append(bindings, []*Binding{
{ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: functions.prevLine},
{ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: functions.prevLine},
{ViewName: viewName, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: functions.prevLine},
{ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: functions.nextLine},
{ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: functions.nextLine},
{ViewName: viewName, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: functions.nextLine},
{ViewName: viewName, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: functions.focus},
{ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: functions.onKeyUpPress},
{ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: functions.onKeyUpPress},
{ViewName: viewName, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: functions.onKeyUpPress},
{ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: functions.onKeyDownPress},
{ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: functions.onKeyDownPress},
{ViewName: viewName, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: functions.onKeyDownPress},
{ViewName: viewName, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: functions.onClick},
}...)
}

for _, viewName := range []string{"status", "services", "containers", "images", "volumes"} {
bindings = append(bindings, &Binding{
ViewName: viewName,
Key: gocui.KeyEnter,
Modifier: gocui.ModNone,
Handler: gui.handleEnterMain,
Description: gui.Tr.FocusMain,
})
}

return bindings
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/gui/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error {
return nil
}

if !gui.isPopupPanel(newView.Name()) {
v.ParentView = nil
}

// refocusing because in responsive mode (when the window is very short) we want to ensure that after the view size changes we can still see the last selected item
if err := gui.focusPointInView(v); err != nil {
return err
Expand Down
44 changes: 42 additions & 2 deletions pkg/gui/main_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import (
)

func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error {
mainView, _ := g.View("main")
mainView := gui.getMainView()
mainView.Autoscroll = false
ox, oy := mainView.Origin()
newOy := int(math.Max(0, float64(oy-gui.Config.UserConfig.Gui.ScrollHeight)))
return mainView.SetOrigin(ox, newOy)
}

func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error {
mainView, _ := g.View("main")
mainView := gui.getMainView()
ox, oy := mainView.Origin()
y := oy
if !gui.Config.UserConfig.Gui.ScrollPastBottom {
Expand All @@ -27,6 +27,21 @@ func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error {
return mainView.SetOrigin(ox, oy+gui.Config.UserConfig.Gui.ScrollHeight)
}

func (gui *Gui) scrollLeftMain(g *gocui.Gui, v *gocui.View) error {
mainView := gui.getMainView()
ox, oy := mainView.Origin()
newOx := int(math.Max(0, float64(ox-gui.Config.UserConfig.Gui.ScrollHeight)))

return mainView.SetOrigin(newOx, oy)
}

func (gui *Gui) scrollRightMain(g *gocui.Gui, v *gocui.View) error {
mainView := gui.getMainView()
ox, oy := mainView.Origin()

return mainView.SetOrigin(ox+gui.Config.UserConfig.Gui.ScrollHeight, oy)
}

func (gui *Gui) autoScrollMain(g *gocui.Gui, v *gocui.View) error {
gui.getMainView().Autoscroll = true
return nil
Expand All @@ -37,6 +52,11 @@ func (gui *Gui) onMainTabClick(tabIndex int) error {

viewName := gui.currentViewName()

mainView := gui.getMainView()
if viewName == "main" && mainView.ParentView != nil {
viewName = mainView.ParentView.Name()
}

switch viewName {
case "services":
gui.State.Panels.Services.ContextIndex = tabIndex
Expand All @@ -57,3 +77,23 @@ func (gui *Gui) onMainTabClick(tabIndex int) error {

return nil
}

func (gui *Gui) handleEnterMain(g *gocui.Gui, v *gocui.View) error {
mainView := gui.getMainView()
mainView.ParentView = v

return gui.switchFocus(gui.g, v, mainView)
}

func (gui *Gui) handleExitMain(g *gocui.Gui, v *gocui.View) error {
v.ParentView = nil
return gui.returnFocus(gui.g, v)
}

func (gui *Gui) handleMainClick(g *gocui.Gui, v *gocui.View) error {
currentView := gui.g.CurrentView()

v.ParentView = currentView

return gui.switchFocus(gui.g, currentView, v)
}
22 changes: 22 additions & 0 deletions pkg/gui/options_menu_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@ func (gui *Gui) getBindings(v *gocui.View) []*Binding {
}
}

// check if we have any keybindings from our parent view to add
if v.ParentView != nil {
L:
for _, binding := range bindings {
if binding.GetKey() != "" && binding.Description != "" {
if binding.ViewName == v.ParentView.Name() {
// if we haven't got a conflict we will display the binding
for _, ownBinding := range bindingsPanel {
if ownBinding.GetKey() == binding.GetKey() {
continue L
}
}
bindingsPanel = append(bindingsPanel, binding)
}
}
}
}

// } else if v.ParentView != nil && binding.ViewName == v.ParentView.Name() {
// // only add this if we don't have our own matching binding
// bindingsPanel = append(bindingsPanel, binding)

// append dummy element to have a separator between
// panel and global keybindings
bindingsPanel = append(bindingsPanel, &Binding{})
Expand Down
8 changes: 2 additions & 6 deletions pkg/gui/services_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ func (gui *Gui) handleServicesClick(g *gocui.Gui, v *gocui.View) error {
}

func (gui *Gui) handleServiceSelect(g *gocui.Gui, v *gocui.View) error {
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
return err
}

service, err := gui.getSelectedService()
if err != nil {
return nil
Expand Down Expand Up @@ -133,7 +129,7 @@ func (gui *Gui) renderServiceLogs(service *commands.Service) error {
}

func (gui *Gui) handleServicesNextLine(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
if gui.popupPanelFocused() || gui.g.CurrentView() != v {
return nil
}

Expand All @@ -144,7 +140,7 @@ func (gui *Gui) handleServicesNextLine(g *gocui.Gui, v *gocui.View) error {
}

func (gui *Gui) handleServicesPrevLine(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
if gui.popupPanelFocused() || gui.g.CurrentView() != v {
return nil
}

Expand Down
10 changes: 9 additions & 1 deletion pkg/gui/status_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (gui *Gui) refreshStatus() error {
return nil
}

func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleStatusClick(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
return nil
}
Expand All @@ -48,6 +48,14 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
return err
}

return gui.handleStatusSelect(g, v)
}

func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
return nil
}

key := gui.getStatusContexts()[gui.State.Panels.Status.ContextIndex]
if !gui.shouldRefresh(key) {
return nil
Expand Down
Loading

0 comments on commit e220bed

Please sign in to comment.