mirror of
https://github.com/rivo/tview.git
synced 2025-04-26 13:49:06 +08:00
Added suspended mode to Application. (Swallows one key event, tcell issue pending.) Resolves #70
This commit is contained in:
parent
7e4958256f
commit
11727c933b
@ -1,6 +1,8 @@
|
||||
package tview
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
@ -38,6 +40,9 @@ type Application struct {
|
||||
// An optional callback function which is invoked after the root primitive
|
||||
// was drawn.
|
||||
afterDraw func(screen tcell.Screen)
|
||||
|
||||
// If this value is true, the application has entered suspended mode.
|
||||
suspended bool
|
||||
}
|
||||
|
||||
// NewApplication creates and returns a new application.
|
||||
@ -98,9 +103,12 @@ func (a *Application) Run() error {
|
||||
|
||||
// Start event loop.
|
||||
for {
|
||||
a.RLock()
|
||||
a.Lock()
|
||||
screen := a.screen
|
||||
a.RUnlock()
|
||||
if a.suspended {
|
||||
a.suspended = false // Clear previous suspended flag.
|
||||
}
|
||||
a.Unlock()
|
||||
if screen == nil {
|
||||
break
|
||||
}
|
||||
@ -108,7 +116,17 @@ func (a *Application) Run() error {
|
||||
// Wait for next event.
|
||||
event := a.screen.PollEvent()
|
||||
if event == nil {
|
||||
break // The screen was finalized.
|
||||
a.Lock()
|
||||
if a.suspended {
|
||||
// This screen was renewed due to suspended mode.
|
||||
a.suspended = false
|
||||
a.Unlock()
|
||||
continue // Resume.
|
||||
}
|
||||
a.Unlock()
|
||||
|
||||
// The screen was finalized. Exit the loop.
|
||||
break
|
||||
}
|
||||
|
||||
switch event := event.(type) {
|
||||
@ -162,6 +180,57 @@ func (a *Application) Stop() {
|
||||
a.screen = nil
|
||||
}
|
||||
|
||||
// Suspend temporarily suspends the application by exiting terminal UI mode and
|
||||
// invoking the provided function "f". When "f" returns, terminal UI mode is
|
||||
// entered again and the application resumes.
|
||||
//
|
||||
// A return value of true indicates that the application was suspended and "f"
|
||||
// was called. If false is returned, the application was already suspended,
|
||||
// terminal UI mode was not exited, and "f" was not called.
|
||||
func (a *Application) Suspend(f func()) bool {
|
||||
a.Lock()
|
||||
|
||||
if a.suspended || a.screen == nil {
|
||||
// Application is already suspended.
|
||||
a.Unlock()
|
||||
return false
|
||||
}
|
||||
|
||||
// Enter suspended mode.
|
||||
a.suspended = true
|
||||
a.Unlock()
|
||||
a.Stop()
|
||||
|
||||
// Deal with panics during suspended mode. Exit the program.
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
fmt.Println(p)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for "f" to return.
|
||||
f()
|
||||
|
||||
// Make a new screen and redraw.
|
||||
a.Lock()
|
||||
var err error
|
||||
a.screen, err = tcell.NewScreen()
|
||||
if err != nil {
|
||||
a.Unlock()
|
||||
panic(err)
|
||||
}
|
||||
if err = a.screen.Init(); err != nil {
|
||||
a.Unlock()
|
||||
panic(err)
|
||||
}
|
||||
a.Unlock()
|
||||
a.Draw()
|
||||
|
||||
// Continue application loop.
|
||||
return true
|
||||
}
|
||||
|
||||
// Draw refreshes the screen. It calls the Draw() function of the application's
|
||||
// root primitive and then syncs the screen buffer.
|
||||
func (a *Application) Draw() *Application {
|
||||
|
Loading…
x
Reference in New Issue
Block a user