mirror of
https://github.com/issadarkthing/gomu.git
synced 2025-04-26 13:49:21 +08:00
first commit
This commit is contained in:
commit
fc065fd89a
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/issadarkthing/gomu
|
||||
|
||||
go 1.14
|
||||
|
||||
require github.com/rivo/tview v0.0.0-20200528200248-fe953220389f // indirect
|
22
go.sum
Normal file
22
go.sum
Normal file
@ -0,0 +1,22 @@
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell v1.3.0 h1:r35w0JBADPZCVQijYebl6YMWWtHRqVEGt7kL2eBADRM=
|
||||
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/rivo/tview v0.0.0-20200528200248-fe953220389f h1:tRx/LLIP2PSA7johw9xhf+6NUCLC4BbMhpGdm110MGI=
|
||||
github.com/rivo/tview v0.0.0-20200528200248-fe953220389f/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84=
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 h1:sfkvUWPNGwSV+8/fNqctR5lS2AqCSqYwXdrjCxp/dXo=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
316
gomu.go
Normal file
316
gomu.go
Normal file
@ -0,0 +1,316 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
app := tview.NewApplication()
|
||||
|
||||
start(app)
|
||||
|
||||
}
|
||||
|
||||
|
||||
func start(app *tview.Application) {
|
||||
// override default border
|
||||
// change double line border to one line border when focused
|
||||
tview.Borders.HorizontalFocus = tview.Borders.Horizontal
|
||||
tview.Borders.VerticalFocus = tview.Borders.Vertical
|
||||
tview.Borders.TopLeftFocus = tview.Borders.TopLeft
|
||||
tview.Borders.TopRightFocus = tview.Borders.TopRight
|
||||
tview.Borders.BottomLeftFocus = tview.Borders.BottomLeft
|
||||
tview.Borders.BottomRightFocus = tview.Borders.BottomRight
|
||||
tview.Styles.PrimitiveBackgroundColor = tcell.ColorDefault
|
||||
tview.Styles.BorderColor = tcell.ColorAntiqueWhite
|
||||
|
||||
child1, child2, child3 := playlist(), queue(), nowPlayingBar()
|
||||
|
||||
flex := layout(app, child1, child2, child3)
|
||||
|
||||
childrens := []Children{child1, child2, child3}
|
||||
|
||||
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||
|
||||
switch event.Key() {
|
||||
// cycle through each section
|
||||
case tcell.KeyTAB:
|
||||
cycleChildren(app, childrens)
|
||||
|
||||
}
|
||||
|
||||
switch event.Rune() {
|
||||
case 'q':
|
||||
confirmationPopup(app, flex, "Are you sure to exit?")
|
||||
}
|
||||
|
||||
return event
|
||||
})
|
||||
|
||||
|
||||
// fix transparent background issue
|
||||
app.SetBeforeDrawFunc(func(screen tcell.Screen) bool {
|
||||
screen.Clear()
|
||||
return false
|
||||
})
|
||||
|
||||
// main loop
|
||||
if err := app.SetRoot(flex, true).SetFocus(flex).Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func cycleChildren(app *tview.Application, childrens []Children) {
|
||||
|
||||
focusedColor := tcell.ColorDarkCyan
|
||||
unfocusedColor := tcell.ColorAntiqueWhite
|
||||
anyChildHasFocus := false
|
||||
|
||||
for i, child := range childrens {
|
||||
|
||||
if child.HasFocus() {
|
||||
|
||||
anyChildHasFocus = true
|
||||
|
||||
var nextChild Children
|
||||
|
||||
// if its the last element set the child back to one
|
||||
if i == len(childrens) - 1 {
|
||||
nextChild = childrens[0]
|
||||
} else {
|
||||
nextChild = childrens[i + 1]
|
||||
}
|
||||
|
||||
|
||||
child.SetBorderColor(unfocusedColor)
|
||||
child.SetTitleColor(unfocusedColor)
|
||||
|
||||
app.SetFocus(nextChild.(tview.Primitive))
|
||||
nextChild.SetBorderColor(focusedColor)
|
||||
nextChild.SetTitleColor(focusedColor)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if anyChildHasFocus == false {
|
||||
|
||||
app.SetFocus(childrens[0].(tview.Primitive))
|
||||
childrens[0].SetBorderColor(focusedColor)
|
||||
childrens[0].SetTitleColor(focusedColor)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// created so we can keep track of childrens in slices
|
||||
type Children interface {
|
||||
HasFocus() bool
|
||||
SetBorderColor(color tcell.Color) *tview.Box
|
||||
SetTitleColor(color tcell.Color) *tview.Box
|
||||
SetTitle(s string) *tview.Box
|
||||
GetTitle() string
|
||||
}
|
||||
|
||||
|
||||
func layout(
|
||||
app *tview.Application,
|
||||
child1 *tview.TreeView,
|
||||
child2 *tview.List,
|
||||
child3 *tview.Box,
|
||||
) *tview.Flex {
|
||||
|
||||
flex := tview.NewFlex().
|
||||
AddItem(child1, 0, 1, false).
|
||||
AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
|
||||
AddItem(child2, 0, 7, false).
|
||||
AddItem(child3, 0, 1, false), 0, 3, false)
|
||||
|
||||
return flex
|
||||
|
||||
}
|
||||
|
||||
func nowPlayingBar() *tview.Box {
|
||||
return tview.NewBox().SetBorder(true).
|
||||
SetTitle("Currently Playing")
|
||||
}
|
||||
|
||||
func queue() *tview.List {
|
||||
|
||||
list := tview.NewList().
|
||||
AddItem("Lorem", "ipsum", '1', nil).
|
||||
AddItem("Lorem", "ipsum", '2', nil).
|
||||
AddItem("Lorem", "ipsum", '3', nil).
|
||||
AddItem("Lorem", "ipsum", '4', nil).
|
||||
AddItem("Lorem", "ipsum", '5', nil).
|
||||
ShowSecondaryText(false)
|
||||
|
||||
list.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
|
||||
switch e.Rune() {
|
||||
case 'j':
|
||||
next(list)
|
||||
case 'k':
|
||||
prev(list)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
list.SetHighlightFullLine(true)
|
||||
list.SetBorder(true).SetTitle("Queue")
|
||||
list.SetSelectedBackgroundColor(tcell.ColorDarkCyan)
|
||||
list.SetSelectedTextColor(tcell.ColorAntiqueWhite)
|
||||
|
||||
return list
|
||||
|
||||
}
|
||||
|
||||
func confirmationPopup(app *tview.Application, flex *tview.Flex, text string) bool {
|
||||
|
||||
result := false
|
||||
|
||||
modal := tview.NewModal().
|
||||
SetText(text).
|
||||
SetBackgroundColor(tcell.ColorDefault).
|
||||
AddButtons([]string{"yes", "no"}).
|
||||
SetButtonBackgroundColor(tcell.ColorBlack).
|
||||
SetDoneFunc(func(_ int, buttonLabel string) {
|
||||
if buttonLabel == "yes" {
|
||||
result = true
|
||||
app.Stop()
|
||||
}
|
||||
|
||||
app.SetRoot(flex, true)
|
||||
});
|
||||
|
||||
|
||||
app.SetRoot(modal, false).SetFocus(modal)
|
||||
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
func next(l *tview.List) {
|
||||
currIndex := l.GetCurrentItem()
|
||||
idx := currIndex + 1
|
||||
if currIndex == l.GetItemCount() - 1 {
|
||||
idx = 0
|
||||
}
|
||||
l.SetCurrentItem(idx)
|
||||
}
|
||||
|
||||
func prev(l *tview.List) {
|
||||
currIndex := l.GetCurrentItem()
|
||||
l.SetCurrentItem(currIndex - 1)
|
||||
}
|
||||
|
||||
func playlist() *tview.TreeView {
|
||||
|
||||
rootDir := "~/Music"
|
||||
root := tview.NewTreeNode(rootDir)
|
||||
tree := tview.NewTreeView().SetRoot(root)
|
||||
tree.SetTitle("Playlist").SetBorder(true)
|
||||
tree.SetGraphicsColor(tcell.ColorWhite)
|
||||
|
||||
textColor := tcell.ColorAntiqueWhite
|
||||
backGroundColor := tcell.ColorDarkCyan
|
||||
|
||||
sample := [][]string{
|
||||
{"pop", "1", "2", "3"},
|
||||
{"rock", "1", "2", "3"},
|
||||
{"rap", "1", "2", "3"},
|
||||
{"country", "1", "2", "3"},
|
||||
{"edm", "1", "2", "3"},
|
||||
}
|
||||
|
||||
var childrens []*tview.TreeNode
|
||||
|
||||
// populate tree with sample
|
||||
for _, s := range sample {
|
||||
|
||||
node := tview.NewTreeNode(s[0])
|
||||
|
||||
node.SetExpanded(false)
|
||||
|
||||
for _, sy := range s[1:] {
|
||||
|
||||
child := tview.NewTreeNode(sy)
|
||||
child.SetIndent(5)
|
||||
child.SetReference(node)
|
||||
node.AddChild(child)
|
||||
|
||||
}
|
||||
childrens = append(childrens, node)
|
||||
root.AddChild(node)
|
||||
}
|
||||
|
||||
childrens[0].SetColor(backGroundColor)
|
||||
|
||||
tree.SetCurrentNode(childrens[0])
|
||||
// keep track of prev node so we can remove the color of highlight
|
||||
prevNode := childrens[0].SetColor(backGroundColor)
|
||||
|
||||
tree.SetChangedFunc(func (node *tview.TreeNode) {
|
||||
|
||||
prevNode.SetColor(textColor)
|
||||
root.SetColor(textColor)
|
||||
node.SetColor(backGroundColor)
|
||||
prevNode = node
|
||||
})
|
||||
|
||||
tree.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
|
||||
currNode := tree.GetCurrentNode()
|
||||
|
||||
switch e.Rune() {
|
||||
case 'l':
|
||||
currNode.SetExpanded(true)
|
||||
case 'h':
|
||||
|
||||
// if closing node with no children
|
||||
// close the node's parent
|
||||
if parent := currNode.GetReference(); parent != nil {
|
||||
// remove the color of the node
|
||||
currNode.SetColor(textColor)
|
||||
parent.(*tview.TreeNode).SetExpanded(false)
|
||||
parent.(*tview.TreeNode).SetColor(backGroundColor)
|
||||
prevNode = parent.(*tview.TreeNode)
|
||||
tree.SetCurrentNode(parent.(*tview.TreeNode))
|
||||
} else {
|
||||
currNode.SetExpanded(false)
|
||||
}
|
||||
}
|
||||
|
||||
return e
|
||||
})
|
||||
|
||||
tree.SetSelectedFunc(func(node *tview.TreeNode) {
|
||||
node.SetExpanded(!node.IsExpanded())
|
||||
})
|
||||
|
||||
return tree
|
||||
|
||||
}
|
||||
|
||||
func log(text string) {
|
||||
|
||||
f, err := os.OpenFile("message.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if _, err := f.Write([]byte(text)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := f.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user