mirror of
https://github.com/jroimartin/gocui.git
synced 2025-04-24 13:48:51 +08:00
Full mouse support. Add mouse example. Make golint happy.
- Full mouse support based on hazbo's initial work. - Add example to show mouse support. - Fix comments, naming conventions, etc. to make golint happy.
This commit is contained in:
parent
c36dfefa9b
commit
faa12e105a
@ -17,7 +17,7 @@ Minimalist Go package aimed at creating Console User Interfaces.
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
if v, err := g.SetView("center", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, "This is an example")
|
||||
@ -25,7 +25,7 @@ func layout(g *gocui.Gui) error {
|
||||
return nil
|
||||
}
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
func main() {
|
||||
var err error
|
||||
@ -39,7 +39,7 @@ func main() {
|
||||
log.Panicln(err)
|
||||
}
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
@ -38,22 +38,23 @@ func main() {
|
||||
}
|
||||
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, _ := g.Size()
|
||||
v, err := g.SetView("legend", maxX-22, 0, maxX-1, 6)
|
||||
v, err := g.SetView("legend", maxX-25, 0, maxX-1, 7)
|
||||
if err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, "KEYBINDINGS")
|
||||
fmt.Fprintln(v, "Space: New View")
|
||||
fmt.Fprintln(v, "Tab: Next View")
|
||||
fmt.Fprintln(v, "← ↑ → ↓: Move View")
|
||||
fmt.Fprintln(v, "Backspace: Delete View")
|
||||
fmt.Fprintln(v, "^C: Exit")
|
||||
}
|
||||
return nil
|
||||
@ -109,7 +110,7 @@ func initKeybindings(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func newView(g *gocui.Gui) error {
|
||||
@ -117,7 +118,7 @@ func newView(g *gocui.Gui) error {
|
||||
name := fmt.Sprintf("v%v", idxView)
|
||||
v, err := g.SetView(name, maxX/2-5, maxY/2-5, maxX/2+5, maxY/2+5)
|
||||
if err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
v.Wrap = true
|
||||
|
@ -58,7 +58,7 @@ func getLine(g *gocui.Gui, v *gocui.View) error {
|
||||
|
||||
maxX, maxY := g.Size()
|
||||
if v, err := g.SetView("msg", maxX/2-30, maxY/2, maxX/2+30, maxY/2+2); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, l)
|
||||
@ -80,7 +80,7 @@ func delMsg(g *gocui.Gui, v *gocui.View) error {
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func keybindings(g *gocui.Gui) error {
|
||||
@ -158,7 +158,7 @@ func saveVisualMain(g *gocui.Gui, v *gocui.View) error {
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
if v, err := g.SetView("side", -1, -1, 30, maxY); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
v.Highlight = true
|
||||
@ -169,7 +169,7 @@ func layout(g *gocui.Gui) error {
|
||||
fmt.Fprint(v, "deleted\rItem 4\nItem 5")
|
||||
}
|
||||
if v, err := g.SetView("main", 30, -1, maxX, maxY); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
b, err := ioutil.ReadFile("Mark.Twain-Tom.Sawyer.txt")
|
||||
@ -204,7 +204,7 @@ func main() {
|
||||
g.ShowCursor = true
|
||||
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
@ -13,22 +13,22 @@ import (
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
if _, err := g.SetView("side", -1, -1, int(0.2*float32(maxX)), maxY-5); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("main", int(0.2*float32(maxX)), -1, maxX, maxY-5); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("cmdline", -1, maxY-5, maxX, maxY); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -47,7 +47,7 @@ func main() {
|
||||
}
|
||||
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
94
_examples/mouse.go
Normal file
94
_examples/mouse.go
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/jroimartin/gocui"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
g := gocui.NewGui()
|
||||
if err := g.Init(); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
defer g.Close()
|
||||
|
||||
g.SetLayout(layout)
|
||||
if err := keybindings(g); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
g.EnableMouse = true
|
||||
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func layout(g *gocui.Gui) error {
|
||||
if v, err := g.SetView("but1", 2, 2, 12, 4); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, "Button 1")
|
||||
}
|
||||
if v, err := g.SetView("but2", 14, 2, 24, 4); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, "Button 2")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func keybindings(g *gocui.Gui) error {
|
||||
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range []string{"but1", "but2"} {
|
||||
if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, delMsg); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func showMsg(g *gocui.Gui, v *gocui.View) error {
|
||||
var l string
|
||||
var err error
|
||||
|
||||
_, cy := v.Cursor()
|
||||
if l, err = v.Line(cy); err != nil {
|
||||
l = ""
|
||||
}
|
||||
|
||||
maxX, maxY := g.Size()
|
||||
if v, err := g.SetView("msg", maxX/2-5, maxY/2, maxX/2+5, maxY/2+2); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, l)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func delMsg(g *gocui.Gui, v *gocui.View) error {
|
||||
if err := g.DeleteView("msg"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -13,46 +13,46 @@ import (
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
if _, err := g.SetView("v1", -1, -1, 10, 10); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v2", maxX-10, -1, maxX, 10); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v3", maxX/2-5, -1, maxX/2+5, 10); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v4", -1, maxY/2-5, 10, maxY/2+5); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v5", maxX-10, maxY/2-5, maxX, maxY/2+5); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v6", -1, maxY-10, 10, maxY); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v7", maxX-10, maxY-10, maxX, maxY); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v8", maxX/2-5, maxY-10, maxX/2+5, maxY); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if _, err := g.SetView("v9", maxX/2-5, maxY/2-5, maxX/2+5, maxY/2+5); err != nil &&
|
||||
err != gocui.ErrorUnkView {
|
||||
err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -70,7 +70,7 @@ func main() {
|
||||
}
|
||||
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func main() {
|
||||
g.ShowCursor = true
|
||||
|
||||
err := g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,7 @@ func layout(g *gocui.Gui) error {
|
||||
maxX, _ := g.Size()
|
||||
|
||||
if v, err := g.SetView("legend", maxX-23, 0, maxX-1, 5); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, "KEYBINDINGS")
|
||||
@ -47,7 +47,7 @@ func layout(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
if v, err := g.SetView("stdin", 0, 0, 80, 35); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
if err := g.SetCurrentView("stdin"); err != nil {
|
||||
@ -88,7 +88,7 @@ func initKeybindings(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func autoscroll(g *gocui.Gui, v *gocui.View) error {
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
if v, err := g.SetView("main", 1, 1, maxX-1, maxY-1); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
v.Wrap = true
|
||||
@ -28,7 +28,7 @@ func layout(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -46,7 +46,7 @@ func main() {
|
||||
}
|
||||
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,9 @@ package gocui
|
||||
|
||||
import "github.com/nsf/termbox-go"
|
||||
|
||||
// Attributes can be combined using bitwise OR (|). Note that it is not
|
||||
// possible to combine multiple color attributes.
|
||||
// Attribute represents a terminal attribute, like color, font style, etc. They
|
||||
// can be combined using bitwise OR (|). Note that it is not possible to
|
||||
// combine multiple color attributes.
|
||||
type Attribute termbox.Attribute
|
||||
|
||||
// Color attributes.
|
||||
|
6
doc.go
6
doc.go
@ -10,7 +10,7 @@ Example:
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
if v, err := g.SetView("center", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2); err != nil {
|
||||
if err != gocui.ErrorUnkView {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(v, "This is an example")
|
||||
@ -18,7 +18,7 @@ Example:
|
||||
return nil
|
||||
}
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.Quit
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
func main() {
|
||||
var err error
|
||||
@ -32,7 +32,7 @@ Example:
|
||||
log.Panicln(err)
|
||||
}
|
||||
err = g.MainLoop()
|
||||
if err != nil && err != gocui.Quit {
|
||||
if err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
14
edit.go
14
edit.go
@ -11,7 +11,7 @@ const maxInt = int(^uint(0) >> 1)
|
||||
// default.
|
||||
var Edit = EditorFunc(DefaultEditor)
|
||||
|
||||
// Objects implementing the Editor interface can be used as gocui editors.
|
||||
// Editor interface must be satisfied by gocui editors.
|
||||
type Editor interface {
|
||||
Edit(v *View, key Key, ch rune, mod Modifier)
|
||||
}
|
||||
@ -159,7 +159,7 @@ func (v *View) MoveCursor(dx, dy int, writeMode bool) {
|
||||
v.ox = 0
|
||||
}
|
||||
v.cx = 0
|
||||
cy += 1
|
||||
cy++
|
||||
} else { // vertical movement
|
||||
if curLineWidth > 0 { // move cursor to the EOL
|
||||
if v.Wrap {
|
||||
@ -185,7 +185,7 @@ func (v *View) MoveCursor(dx, dy int, writeMode bool) {
|
||||
}
|
||||
} else if cx < 0 {
|
||||
if !v.Wrap && v.ox > 0 { // move origin to the left
|
||||
v.ox -= 1
|
||||
v.ox--
|
||||
} else { // move to previous line
|
||||
if prevLineWidth > 0 {
|
||||
if !v.Wrap { // set origin so the EOL is visible
|
||||
@ -203,14 +203,14 @@ func (v *View) MoveCursor(dx, dy int, writeMode bool) {
|
||||
}
|
||||
v.cx = 0
|
||||
}
|
||||
cy -= 1
|
||||
cy--
|
||||
}
|
||||
} else { // stay on the same line
|
||||
if v.Wrap {
|
||||
v.cx = cx
|
||||
} else {
|
||||
if cx >= maxX {
|
||||
v.ox += 1
|
||||
v.ox++
|
||||
} else {
|
||||
v.cx = cx
|
||||
}
|
||||
@ -219,10 +219,10 @@ func (v *View) MoveCursor(dx, dy int, writeMode bool) {
|
||||
|
||||
// adjust cursor's y position and view's y origin
|
||||
if cy >= maxY {
|
||||
v.oy += 1
|
||||
v.oy++
|
||||
} else if cy < 0 {
|
||||
if v.oy > 0 {
|
||||
v.oy -= 1
|
||||
v.oy--
|
||||
}
|
||||
} else {
|
||||
v.cy = cy
|
||||
|
67
gui.go
67
gui.go
@ -12,11 +12,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// Quit is used to decide if the MainLoop finished succesfully.
|
||||
Quit error = errors.New("quit")
|
||||
// ErrQuit is used to decide if the MainLoop finished succesfully.
|
||||
ErrQuit = errors.New("quit")
|
||||
|
||||
// ErrorUnkView allows to assert if a View must be initialized.
|
||||
ErrorUnkView error = errors.New("unknown view")
|
||||
// ErrUnknownView allows to assert if a View must be initialized.
|
||||
ErrUnknownView = errors.New("unknown view")
|
||||
)
|
||||
|
||||
// Gui represents the whole User Interface, including the views, layouts
|
||||
@ -43,7 +43,7 @@ type Gui struct {
|
||||
// If ShowCursor is true then the cursor is enabled.
|
||||
ShowCursor bool
|
||||
|
||||
// If EnableMouse is true then mouse clicks will be recognized.
|
||||
// If EnableMouse is true then mouse events will be enabled.
|
||||
EnableMouse bool
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ func (g *Gui) Rune(x, y int) (rune, error) {
|
||||
// SetView creates a new view with its top-left corner at (x0, y0)
|
||||
// and the bottom-right one at (x1, y1). If a view with the same name
|
||||
// already exists, its dimensions are updated; otherwise, the error
|
||||
// ErrorUnkView is returned, which allows to assert if the View must
|
||||
// ErrUnknownView is returned, which allows to assert if the View must
|
||||
// be initialized. It checks if the position is valid.
|
||||
func (g *Gui) SetView(name string, x0, y0, x1, y1 int) (*View, error) {
|
||||
if x0 >= x1 || y0 >= y1 {
|
||||
@ -123,29 +123,40 @@ func (g *Gui) SetView(name string, x0, y0, x1, y1 int) (*View, error) {
|
||||
v.BgColor, v.FgColor = g.BgColor, g.FgColor
|
||||
v.SelBgColor, v.SelFgColor = g.SelBgColor, g.SelFgColor
|
||||
g.views = append(g.views, v)
|
||||
return v, ErrorUnkView
|
||||
return v, ErrUnknownView
|
||||
}
|
||||
|
||||
// View returns a pointer to the view with the given name, or error
|
||||
// ErrorUnkView if a view with that name does not exist.
|
||||
// ErrUnknownView if a view with that name does not exist.
|
||||
func (g *Gui) View(name string) (*View, error) {
|
||||
for _, v := range g.views {
|
||||
if v.name == name {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrorUnkView
|
||||
return nil, ErrUnknownView
|
||||
}
|
||||
|
||||
// Position returns the coordinates of the view with the given name,
|
||||
// or error ErrorUnkView if a view with that name does not exist.
|
||||
// ViewByPosition returns a pointer to a view matching the given position, or
|
||||
// error ErrUnknownView if a view in that position does not exist.
|
||||
func (g *Gui) ViewByPosition(x, y int) (*View, error) {
|
||||
for _, v := range g.views {
|
||||
if x >= v.x0 && x <= v.x1 && y >= v.y0 && y <= v.y1 {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrUnknownView
|
||||
}
|
||||
|
||||
// ViewPosition returns the coordinates of the view with the given name, or
|
||||
// error ErrUnknownView if a view with that name does not exist.
|
||||
func (g *Gui) ViewPosition(name string) (x0, y0, x1, y1 int, err error) {
|
||||
for _, v := range g.views {
|
||||
if v.name == name {
|
||||
return v.x0, v.y0, v.x1, v.y1, nil
|
||||
}
|
||||
}
|
||||
return 0, 0, 0, 0, ErrorUnkView
|
||||
return 0, 0, 0, 0, ErrUnknownView
|
||||
}
|
||||
|
||||
// DeleteView deletes a view by name.
|
||||
@ -156,7 +167,7 @@ func (g *Gui) DeleteView(name string) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return ErrorUnkView
|
||||
return ErrUnknownView
|
||||
}
|
||||
|
||||
// SetCurrentView gives the focus to a given view.
|
||||
@ -167,7 +178,7 @@ func (g *Gui) SetCurrentView(name string) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return ErrorUnkView
|
||||
return ErrUnknownView
|
||||
}
|
||||
|
||||
// CurrentView returns the currently focused view, or nil if no view
|
||||
@ -205,7 +216,7 @@ func (g *Gui) SetLayout(layout func(*Gui) error) {
|
||||
}
|
||||
|
||||
// MainLoop runs the main loop until an error is returned. A successful
|
||||
// finish should return Quit.
|
||||
// finish should return ErrQuit.
|
||||
func (g *Gui) MainLoop() error {
|
||||
go func() {
|
||||
for {
|
||||
@ -213,11 +224,11 @@ func (g *Gui) MainLoop() error {
|
||||
}
|
||||
}()
|
||||
|
||||
termbox.SetInputMode(termbox.InputAlt)
|
||||
|
||||
inputMode := termbox.InputAlt
|
||||
if g.EnableMouse == true {
|
||||
termbox.SetInputMode(termbox.InputMouse)
|
||||
inputMode |= termbox.InputMouse
|
||||
}
|
||||
termbox.SetInputMode(inputMode)
|
||||
|
||||
if err := g.Flush(); err != nil {
|
||||
return err
|
||||
@ -459,23 +470,29 @@ func horizontalRune(ch rune) bool {
|
||||
}
|
||||
|
||||
// onKey manages key-press events. A keybinding handler is called when
|
||||
// a key-press event satisfies a configured keybinding. Furthermore,
|
||||
// a key-press or mouse event satisfies a configured keybinding. Furthermore,
|
||||
// currentView's internal buffer is modified if currentView.Editable is true.
|
||||
func (g *Gui) onKey(ev *termbox.Event) error {
|
||||
var curView *View
|
||||
|
||||
switch ev.Type {
|
||||
case termbox.EventKey:
|
||||
if g.currentView != nil && g.currentView.Editable && Edit != nil {
|
||||
Edit(g.currentView, Key(ev.Key), ev.Ch, Modifier(ev.Mod))
|
||||
}
|
||||
|
||||
var cv string
|
||||
if g.currentView != nil {
|
||||
cv = g.currentView.name
|
||||
curView = g.currentView
|
||||
case termbox.EventMouse:
|
||||
if v, err := g.ViewByPosition(ev.MouseX, ev.MouseY); err == nil {
|
||||
curView = v
|
||||
}
|
||||
}
|
||||
|
||||
for _, kb := range g.keybindings {
|
||||
if kb.h == nil {
|
||||
continue
|
||||
}
|
||||
if kb.matchKeypress(Key(ev.Key), ev.Ch, Modifier(ev.Mod)) && kb.matchView(cv) {
|
||||
if err := kb.h(g, g.currentView); err != nil {
|
||||
if kb.matchKeypress(Key(ev.Key), ev.Ch, Modifier(ev.Mod)) && kb.matchView(curView) {
|
||||
if err := kb.h(g, curView); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,12 @@ package gocui
|
||||
import "github.com/nsf/termbox-go"
|
||||
|
||||
type (
|
||||
// Keys represent special keys or keys combinations.
|
||||
// Key represents special keys or keys combinations.
|
||||
Key termbox.Key
|
||||
// Modifiers allow to define special keys combinations. They can be used
|
||||
// Modifier allows to define special keys combinations. They can be used
|
||||
// in combination with Keys or Runes when a new keybinding is defined.
|
||||
Modifier termbox.Modifier
|
||||
// KeybindingHandlers represent the actions linked to keybindings. The
|
||||
// KeybindingHandler represents the actions linked to keybindings. The
|
||||
// handler is called when a key-press event satisfies a configured
|
||||
// keybinding.
|
||||
KeybindingHandler func(*Gui, *View) error
|
||||
@ -125,12 +125,15 @@ func newKeybinding(viewname string, key Key, ch rune, mod Modifier, h Keybinding
|
||||
return kb
|
||||
}
|
||||
|
||||
// match returns if the keybinding matches the keypress
|
||||
// matchKeypress returns if the keybinding matches the keypress.
|
||||
func (kb *keybinding) matchKeypress(key Key, ch rune, mod Modifier) bool {
|
||||
return kb.key == key && kb.ch == ch && kb.mod == mod
|
||||
}
|
||||
|
||||
// match returns if the keybinding matches the current view
|
||||
func (kb *keybinding) matchView(viewname string) bool {
|
||||
return kb.viewName == "" || kb.viewName == viewname
|
||||
// matchView returns if the keybinding matches the current view.
|
||||
func (kb *keybinding) matchView(v *View) bool {
|
||||
if kb.viewName == "" {
|
||||
return true
|
||||
}
|
||||
return v != nil && kb.viewName == v.name
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user