From 59c9b3ae78d097939a3acc40d9b592352ed08d53 Mon Sep 17 00:00:00 2001 From: Graham Clark Date: Mon, 27 Jul 2020 00:24:36 -0400 Subject: [PATCH] Rethink how menus are instantiated in termshark To make menus work originally, I added a gowid API, via the app struct, to register a menu. It was on the app because it replaces the app's top-level view of the UI with a menu which itself then pointed to the top-level view, but supported a menu overlay if the menu is activated. I implemented it this way because I needed to generate the lower app canvas first to return to the menu a list of coordinates which were menu "sites"; then the overlay will draw the menus at the right positions on the screen according to the coordinates. BUT - this API is unnecessary pollution in the app because the menu will work just as well by having the gowid app author use it as the top-level view. So now I am doing that, and also giving termshark the ability to layer a widget *above* the menus. This widget is the new key mapper, to provide vim-like key macros. Putting it above the menus means the macro-generated key sequences can be sent to menus too - this allowing macros to invokes menu options. --- ui/ui.go | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/ui/ui.go b/ui/ui.go index a197c9c..a7abc5c 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -57,6 +57,7 @@ import ( "github.com/gcla/termshark/v2/widgets/filter" "github.com/gcla/termshark/v2/widgets/hexdumper2" "github.com/gcla/termshark/v2/widgets/ifwidget" + "github.com/gcla/termshark/v2/widgets/mapkeys" "github.com/gcla/termshark/v2/widgets/minibuffer" "github.com/gcla/termshark/v2/widgets/resizable" "github.com/gcla/termshark/v2/widgets/rossshark" @@ -75,6 +76,7 @@ var Goroutinewg *sync.WaitGroup // test var appViewNoKeys *holder.Widget var appView *holder.Widget +var mbView *holder.Widget var mainViewNoKeys *holder.Widget var mainView *appkeys.KeyWidget var pleaseWaitSpinner *spinner.Widget @@ -123,6 +125,7 @@ var loadProgress *progress.Widget var loadSpinner *spinner.Widget var savedListBoxWidgetHolder *holder.Widget var singlePacketViewMsgHolder *holder.Widget // either empty or "loading..." +var keyMapper *mapkeys.Widget var tabViewsForward map[gowid.IWidget]gowid.IWidget var tabViewsBackward map[gowid.IWidget]gowid.IWidget @@ -3238,7 +3241,10 @@ func Build() (*gowid.App, error) { ), } - Fin = rossshark.New(appViewWithKeys) + // For minibuffer + mbView = holder.New(appViewWithKeys) + + Fin = rossshark.New(mbView) if !termshark.ConfBool("main.disable-shark-fin", false) { steerableFin := appkeys.NewMouse( @@ -3276,12 +3282,41 @@ func Build() (*gowid.App, error) { appView = holder.New(steerableFin) } else { - appView = holder.New(appViewWithKeys) + appView = holder.New(mbView) + } + + var lastMenu gowid.IWidget = appView + menus := []gowid.IMenuCompatible{ + savedMenu, + analysisMenu, + generalMenu, + conversationMenu, + filterConvsMenu1, + filterConvsMenu2, + } + + menus = append(menus, FilterWidget.Menus()...) + + for _, w := range menus { + w.SetSubWidget(lastMenu, app) + lastMenu = w + } + + keyMapper = mapkeys.New(lastMenu) + keyMappings := termshark.LoadKeyMappings() + for _, km := range keyMappings { + log.Infof("Applying keymapping %v --> %v", km.From, km.To) + keyMapper.AddMapping(km.From, km.To, app) + } + + if err = termshark.LoadGlobalMarks(globalMarksMap); err != nil { + // Not fatal + log.Error(err) } // Create app, etc, but don't init screen which sets ICANON, etc app, err = gowid.NewApp(gowid.AppArgs{ - View: appView, + View: keyMapper, Palette: palette, DontActivate: true, Log: log.StandardLogger(), @@ -3291,16 +3326,6 @@ func Build() (*gowid.App, error) { return nil, err } - for _, m := range FilterWidget.Menus() { - app.RegisterMenu(m) - } - app.RegisterMenu(savedMenu) - app.RegisterMenu(analysisMenu) - app.RegisterMenu(generalMenu) - app.RegisterMenu(conversationMenu) - app.RegisterMenu(filterConvsMenu1) - app.RegisterMenu(filterConvsMenu2) - gowid.SetFocusPath(mainview, mainviewPaths[0], app) gowid.SetFocusPath(altview1, altview1Paths[0], app) gowid.SetFocusPath(altview2, altview2Paths[0], app)