mirror of
https://github.com/eeeXun/GTT.git
synced 2025-05-19 09:10:42 -07:00
refactor: to multi directory
This commit is contained in:
parent
e09e846077
commit
8efb962eee
123
color.go
123
color.go
@ -1,123 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gdamore/tcell/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
AllTheme = []string{"Gruvbox", "Nord"}
|
|
||||||
Palette = []string{"red", "green", "yellow", "blue", "purple", "cyan", "orange"}
|
|
||||||
Themes = map[string]map[string]tcell.Color{
|
|
||||||
"Gruvbox": {
|
|
||||||
"bg": tcell.NewHexColor(0x282828),
|
|
||||||
"fg": tcell.NewHexColor(0xebdbb2),
|
|
||||||
"gray": tcell.NewHexColor(0x665c54),
|
|
||||||
"red": tcell.NewHexColor(0xfb4934),
|
|
||||||
"green": tcell.NewHexColor(0xb8bb26),
|
|
||||||
"yellow": tcell.NewHexColor(0xfabd2f),
|
|
||||||
"blue": tcell.NewHexColor(0x83a598),
|
|
||||||
"purple": tcell.NewHexColor(0xd3869b),
|
|
||||||
"cyan": tcell.NewHexColor(0x8ec07c),
|
|
||||||
"orange": tcell.NewHexColor(0xfe8019),
|
|
||||||
},
|
|
||||||
"Nord": {
|
|
||||||
"bg": tcell.NewHexColor(0x3b4252),
|
|
||||||
"fg": tcell.NewHexColor(0xeceff4),
|
|
||||||
"gray": tcell.NewHexColor(0x4c566a),
|
|
||||||
"red": tcell.NewHexColor(0xbf616a),
|
|
||||||
"green": tcell.NewHexColor(0xa3be8c),
|
|
||||||
"yellow": tcell.NewHexColor(0xebcb8b),
|
|
||||||
"blue": tcell.NewHexColor(0x81a1c1),
|
|
||||||
"purple": tcell.NewHexColor(0xb48ead),
|
|
||||||
"cyan": tcell.NewHexColor(0x8fbcbb),
|
|
||||||
"orange": tcell.NewHexColor(0xd08770),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type WindowStyle struct {
|
|
||||||
borderColor string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Style struct {
|
|
||||||
src WindowStyle
|
|
||||||
dst WindowStyle
|
|
||||||
backgroundColor string
|
|
||||||
foregroundColor string
|
|
||||||
selectedColor string
|
|
||||||
prefixColor string
|
|
||||||
labelColor string
|
|
||||||
pressColor string
|
|
||||||
highLightColor string
|
|
||||||
Theme string
|
|
||||||
Transparent bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStyle() *Style {
|
|
||||||
return &Style{
|
|
||||||
backgroundColor: "bg",
|
|
||||||
foregroundColor: "fg",
|
|
||||||
selectedColor: "gray",
|
|
||||||
prefixColor: "cyan",
|
|
||||||
labelColor: "yellow",
|
|
||||||
pressColor: "purple",
|
|
||||||
highLightColor: "orange",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) BackgroundColor() tcell.Color {
|
|
||||||
if s.Transparent {
|
|
||||||
return tcell.ColorDefault
|
|
||||||
}
|
|
||||||
return Themes[s.Theme][s.backgroundColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) ForegroundColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.foregroundColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) SelectedColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.selectedColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) PrefixColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.prefixColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) LabelColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.labelColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) PressColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.pressColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) HighLightColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.highLightColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) SrcBorderColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.src.borderColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) DstBorderColor() tcell.Color {
|
|
||||||
return Themes[s.Theme][s.dst.borderColor]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) SrcBorderStr() string {
|
|
||||||
return s.src.borderColor
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Style) DstBorderStr() string {
|
|
||||||
return s.dst.borderColor
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Style) SetSrcBorderColor(color string) *Style {
|
|
||||||
s.src.borderColor = color
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Style) SetDstBorderColor(color string) *Style {
|
|
||||||
s.dst.borderColor = color
|
|
||||||
return s
|
|
||||||
}
|
|
12
config.go
12
config.go
@ -33,8 +33,8 @@ func configInit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
translator.srcLang = config.GetString("source.language")
|
translator.SrcLang = config.GetString("source.language")
|
||||||
translator.dstLang = config.GetString("destination.language")
|
translator.DstLang = config.GetString("destination.language")
|
||||||
style.Theme = config.GetString("theme")
|
style.Theme = config.GetString("theme")
|
||||||
style.Transparent = config.GetBool("transparent")
|
style.Transparent = config.GetBool("transparent")
|
||||||
style.SetSrcBorderColor(config.GetString("source.borderColor")).
|
style.SetSrcBorderColor(config.GetString("source.borderColor")).
|
||||||
@ -53,17 +53,17 @@ func updateConfig() {
|
|||||||
changed = true
|
changed = true
|
||||||
config.Set("transparent", style.Transparent)
|
config.Set("transparent", style.Transparent)
|
||||||
}
|
}
|
||||||
if config.GetString("source.language") != translator.srcLang {
|
if config.GetString("source.language") != translator.SrcLang {
|
||||||
changed = true
|
changed = true
|
||||||
config.Set("source.language", translator.srcLang)
|
config.Set("source.language", translator.SrcLang)
|
||||||
}
|
}
|
||||||
if config.GetString("source.borderColor") != style.SrcBorderStr() {
|
if config.GetString("source.borderColor") != style.SrcBorderStr() {
|
||||||
changed = true
|
changed = true
|
||||||
config.Set("source.borderColor", style.SrcBorderStr())
|
config.Set("source.borderColor", style.SrcBorderStr())
|
||||||
}
|
}
|
||||||
if config.GetString("destination.language") != translator.dstLang {
|
if config.GetString("destination.language") != translator.DstLang {
|
||||||
changed = true
|
changed = true
|
||||||
config.Set("destination.language", translator.dstLang)
|
config.Set("destination.language", translator.DstLang)
|
||||||
}
|
}
|
||||||
if config.GetString("destination.borderColor") != style.DstBorderStr() {
|
if config.GetString("destination.borderColor") != style.DstBorderStr() {
|
||||||
changed = true
|
changed = true
|
||||||
|
36
internal/color/color.go
Normal file
36
internal/color/color.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package color
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gdamore/tcell/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
AllTheme = []string{"Gruvbox", "Nord"}
|
||||||
|
Palette = []string{"red", "green", "yellow", "blue", "purple", "cyan", "orange"}
|
||||||
|
themes = map[string]map[string]tcell.Color{
|
||||||
|
"Gruvbox": {
|
||||||
|
"bg": tcell.NewHexColor(0x282828),
|
||||||
|
"fg": tcell.NewHexColor(0xebdbb2),
|
||||||
|
"gray": tcell.NewHexColor(0x665c54),
|
||||||
|
"red": tcell.NewHexColor(0xfb4934),
|
||||||
|
"green": tcell.NewHexColor(0xb8bb26),
|
||||||
|
"yellow": tcell.NewHexColor(0xfabd2f),
|
||||||
|
"blue": tcell.NewHexColor(0x83a598),
|
||||||
|
"purple": tcell.NewHexColor(0xd3869b),
|
||||||
|
"cyan": tcell.NewHexColor(0x8ec07c),
|
||||||
|
"orange": tcell.NewHexColor(0xfe8019),
|
||||||
|
},
|
||||||
|
"Nord": {
|
||||||
|
"bg": tcell.NewHexColor(0x3b4252),
|
||||||
|
"fg": tcell.NewHexColor(0xeceff4),
|
||||||
|
"gray": tcell.NewHexColor(0x4c566a),
|
||||||
|
"red": tcell.NewHexColor(0xbf616a),
|
||||||
|
"green": tcell.NewHexColor(0xa3be8c),
|
||||||
|
"yellow": tcell.NewHexColor(0xebcb8b),
|
||||||
|
"blue": tcell.NewHexColor(0x81a1c1),
|
||||||
|
"purple": tcell.NewHexColor(0xb48ead),
|
||||||
|
"cyan": tcell.NewHexColor(0x8fbcbb),
|
||||||
|
"orange": tcell.NewHexColor(0xd08770),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
92
internal/color/control.go
Normal file
92
internal/color/control.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package color
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gdamore/tcell/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type windowStyle struct {
|
||||||
|
borderColor string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Style struct {
|
||||||
|
src windowStyle
|
||||||
|
dst windowStyle
|
||||||
|
backgroundColor string
|
||||||
|
foregroundColor string
|
||||||
|
selectedColor string
|
||||||
|
prefixColor string
|
||||||
|
labelColor string
|
||||||
|
pressColor string
|
||||||
|
highLightColor string
|
||||||
|
Theme string
|
||||||
|
Transparent bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStyle() *Style {
|
||||||
|
return &Style{
|
||||||
|
backgroundColor: "bg",
|
||||||
|
foregroundColor: "fg",
|
||||||
|
selectedColor: "gray",
|
||||||
|
prefixColor: "cyan",
|
||||||
|
labelColor: "yellow",
|
||||||
|
pressColor: "purple",
|
||||||
|
highLightColor: "orange",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) BackgroundColor() tcell.Color {
|
||||||
|
if s.Transparent {
|
||||||
|
return tcell.ColorDefault
|
||||||
|
}
|
||||||
|
return themes[s.Theme][s.backgroundColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) ForegroundColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.foregroundColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) SelectedColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.selectedColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) PrefixColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.prefixColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) LabelColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.labelColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) PressColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.pressColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) HighLightColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.highLightColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) SrcBorderColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.src.borderColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) DstBorderColor() tcell.Color {
|
||||||
|
return themes[s.Theme][s.dst.borderColor]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) SrcBorderStr() string {
|
||||||
|
return s.src.borderColor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Style) DstBorderStr() string {
|
||||||
|
return s.dst.borderColor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Style) SetSrcBorderColor(color string) *Style {
|
||||||
|
s.src.borderColor = color
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Style) SetDstBorderColor(color string) *Style {
|
||||||
|
s.dst.borderColor = color
|
||||||
|
return s
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package translate
|
||||||
|
|
||||||
// https://cloud.google.com/translate/docs/languages
|
// https://cloud.google.com/translate/docs/languages
|
||||||
var (
|
var (
|
27
internal/translate/lock.go
Normal file
27
internal/translate/lock.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package translate
|
||||||
|
|
||||||
|
type Lock struct {
|
||||||
|
Stop bool
|
||||||
|
threadCount int8
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLock() *Lock {
|
||||||
|
return &Lock{
|
||||||
|
Stop: true,
|
||||||
|
threadCount: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lock) Available() bool {
|
||||||
|
return l.Stop && l.threadCount == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lock) Acquire() {
|
||||||
|
l.Stop = false
|
||||||
|
l.threadCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lock) Release() {
|
||||||
|
l.Stop = true
|
||||||
|
l.threadCount--
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package translate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -17,41 +17,15 @@ const (
|
|||||||
soundURL = "https://translate.google.com.vn/translate_tts?ie=UTF-8&q=%s&tl=%s&client=tw-ob"
|
soundURL = "https://translate.google.com.vn/translate_tts?ie=UTF-8&q=%s&tl=%s&client=tw-ob"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Lock struct {
|
|
||||||
stop bool
|
|
||||||
threadCount int8
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLock() *Lock {
|
|
||||||
return &Lock{
|
|
||||||
stop: true,
|
|
||||||
threadCount: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lock) Available() bool {
|
|
||||||
return l.stop && l.threadCount == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lock) Acquire() {
|
|
||||||
l.stop = false
|
|
||||||
l.threadCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lock) Release() {
|
|
||||||
l.stop = true
|
|
||||||
l.threadCount--
|
|
||||||
}
|
|
||||||
|
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
srcLang string
|
SrcLang string
|
||||||
dstLang string
|
DstLang string
|
||||||
soundLock *Lock
|
SoundLock *Lock
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTranslator() *Translator {
|
func NewTranslator() *Translator {
|
||||||
return &Translator{
|
return &Translator{
|
||||||
soundLock: NewLock(),
|
SoundLock: NewLock(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,8 +35,8 @@ func (t *Translator) Translate(message string) (string, error) {
|
|||||||
|
|
||||||
urlStr := fmt.Sprintf(
|
urlStr := fmt.Sprintf(
|
||||||
textURL,
|
textURL,
|
||||||
LangCode[t.srcLang],
|
LangCode[t.SrcLang],
|
||||||
LangCode[t.dstLang],
|
LangCode[t.DstLang],
|
||||||
url.QueryEscape(message),
|
url.QueryEscape(message),
|
||||||
)
|
)
|
||||||
res, err := http.Get(urlStr)
|
res, err := http.Get(urlStr)
|
||||||
@ -98,35 +72,35 @@ func (t *Translator) PlaySound(lang string, message string) error {
|
|||||||
)
|
)
|
||||||
res, err := http.Get(urlStr)
|
res, err := http.Get(urlStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.soundLock.Release()
|
t.SoundLock.Release()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
decoder, err := mp3.NewDecoder(res.Body)
|
decoder, err := mp3.NewDecoder(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.soundLock.Release()
|
t.SoundLock.Release()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
otoCtx, readyChan, err := oto.NewContext(decoder.SampleRate(), 2, 2)
|
otoCtx, readyChan, err := oto.NewContext(decoder.SampleRate(), 2, 2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.soundLock.Release()
|
t.SoundLock.Release()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
<-readyChan
|
<-readyChan
|
||||||
player := otoCtx.NewPlayer(decoder)
|
player := otoCtx.NewPlayer(decoder)
|
||||||
player.Play()
|
player.Play()
|
||||||
for player.IsPlaying() {
|
for player.IsPlaying() {
|
||||||
if t.soundLock.stop {
|
if t.SoundLock.Stop {
|
||||||
t.soundLock.Release()
|
t.SoundLock.Release()
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = player.Close(); err != nil {
|
if err = player.Close(); err != nil {
|
||||||
t.soundLock.Release()
|
t.SoundLock.Release()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
t.soundLock.Release()
|
t.SoundLock.Release()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
37
internal/ui/cycle.go
Normal file
37
internal/ui/cycle.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rivo/tview"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UICycle struct {
|
||||||
|
widget []tview.Primitive
|
||||||
|
index int
|
||||||
|
len int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUICycle(widgets ...tview.Primitive) *UICycle {
|
||||||
|
var w []tview.Primitive
|
||||||
|
|
||||||
|
for _, widget := range widgets {
|
||||||
|
w = append(w, widget)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &UICycle{
|
||||||
|
widget: w,
|
||||||
|
index: 0,
|
||||||
|
len: len(w),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ui *UICycle) Increase() {
|
||||||
|
ui.index = (ui.index + 1) % ui.len
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ui *UICycle) Decrease() {
|
||||||
|
ui.index = ((ui.index-1)%ui.len + ui.len) % ui.len
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ui *UICycle) GetCurrentUI() tview.Primitive {
|
||||||
|
return ui.widget[ui.index]
|
||||||
|
}
|
12
main.go
12
main.go
@ -3,23 +3,26 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/rivo/tview"
|
"github.com/rivo/tview"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"gtt/internal/color"
|
||||||
|
"gtt/internal/translate"
|
||||||
|
"gtt/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Translate
|
// Translate
|
||||||
translator = NewTranslator()
|
translator = translate.NewTranslator()
|
||||||
// UI
|
// UI
|
||||||
app = tview.NewApplication()
|
app = tview.NewApplication()
|
||||||
srcInput = tview.NewTextArea()
|
srcInput = tview.NewTextArea()
|
||||||
dstOutput = tview.NewTextView()
|
dstOutput = tview.NewTextView()
|
||||||
srcLangDropDown = tview.NewDropDown()
|
srcLangDropDown = tview.NewDropDown()
|
||||||
dstLangDropDown = tview.NewDropDown()
|
dstLangDropDown = tview.NewDropDown()
|
||||||
langCycle = NewUICycle(srcLangDropDown, dstLangDropDown)
|
langCycle = ui.NewUICycle(srcLangDropDown, dstLangDropDown)
|
||||||
themeDropDown = tview.NewDropDown()
|
themeDropDown = tview.NewDropDown()
|
||||||
transparentDropDown = tview.NewDropDown()
|
transparentDropDown = tview.NewDropDown()
|
||||||
srcBorderDropDown = tview.NewDropDown()
|
srcBorderDropDown = tview.NewDropDown()
|
||||||
dstBorderDropDown = tview.NewDropDown()
|
dstBorderDropDown = tview.NewDropDown()
|
||||||
styleCycle = NewUICycle(themeDropDown, transparentDropDown, srcBorderDropDown, dstBorderDropDown)
|
styleCycle = ui.NewUICycle(themeDropDown, transparentDropDown, srcBorderDropDown, dstBorderDropDown)
|
||||||
keyMapMenu = tview.NewTextView()
|
keyMapMenu = tview.NewTextView()
|
||||||
langButton = tview.NewButton("(1)Language")
|
langButton = tview.NewButton("(1)Language")
|
||||||
styleButton = tview.NewButton("(2)Style")
|
styleButton = tview.NewButton("(2)Style")
|
||||||
@ -31,7 +34,7 @@ var (
|
|||||||
mainPage = tview.NewPages()
|
mainPage = tview.NewPages()
|
||||||
// settings
|
// settings
|
||||||
config = viper.New()
|
config = viper.New()
|
||||||
style = NewStyle()
|
style = color.NewStyle()
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -49,5 +52,6 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if config need to update
|
||||||
defer updateConfig()
|
defer updateConfig()
|
||||||
}
|
}
|
||||||
|
130
ui.go
130
ui.go
@ -4,41 +4,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
"github.com/rivo/tview"
|
"github.com/rivo/tview"
|
||||||
|
"gtt/internal/color"
|
||||||
|
"gtt/internal/translate"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UICycle struct {
|
|
||||||
widget []tview.Primitive
|
|
||||||
index int
|
|
||||||
len int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUICycle(widgets ...tview.Primitive) *UICycle {
|
|
||||||
var w []tview.Primitive
|
|
||||||
|
|
||||||
for _, widget := range widgets {
|
|
||||||
w = append(w, widget)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &UICycle{
|
|
||||||
widget: w,
|
|
||||||
index: 0,
|
|
||||||
len: len(w),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ui *UICycle) Increase() {
|
|
||||||
ui.index = (ui.index + 1) % ui.len
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ui *UICycle) Decrease() {
|
|
||||||
ui.index = ((ui.index-1)%ui.len + ui.len) % ui.len
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ui *UICycle) GetCurrentUI() tview.Primitive {
|
|
||||||
return ui.widget[ui.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
keyMapText string = `[#%[1]s]<C-c>[-]
|
keyMapText string = `[#%[1]s]<C-c>[-]
|
||||||
Exit program.
|
Exit program.
|
||||||
@ -197,12 +167,12 @@ func updateAllColor() {
|
|||||||
|
|
||||||
// Update title and option
|
// Update title and option
|
||||||
func updateTitle() {
|
func updateTitle() {
|
||||||
srcInput.SetTitle(translator.srcLang)
|
srcInput.SetTitle(translator.SrcLang)
|
||||||
dstOutput.SetTitle(translator.dstLang)
|
dstOutput.SetTitle(translator.DstLang)
|
||||||
srcLangDropDown.SetCurrentOption(IndexOf(translator.srcLang, Lang))
|
srcLangDropDown.SetCurrentOption(IndexOf(translator.SrcLang, translate.Lang))
|
||||||
srcLangDropDown.SetTitle(translator.srcLang)
|
srcLangDropDown.SetTitle(translator.SrcLang)
|
||||||
dstLangDropDown.SetCurrentOption(IndexOf(translator.dstLang, Lang))
|
dstLangDropDown.SetCurrentOption(IndexOf(translator.DstLang, translate.Lang))
|
||||||
dstLangDropDown.SetTitle(translator.dstLang)
|
dstLangDropDown.SetTitle(translator.DstLang)
|
||||||
}
|
}
|
||||||
|
|
||||||
func attachButton() *tview.Flex {
|
func attachButton() *tview.Flex {
|
||||||
@ -223,25 +193,25 @@ func uiInit() {
|
|||||||
|
|
||||||
// dropdown
|
// dropdown
|
||||||
srcLangDropDown.SetBorder(true)
|
srcLangDropDown.SetBorder(true)
|
||||||
srcLangDropDown.SetOptions(Lang, nil)
|
srcLangDropDown.SetOptions(translate.Lang, nil)
|
||||||
dstLangDropDown.SetBorder(true)
|
dstLangDropDown.SetBorder(true)
|
||||||
dstLangDropDown.SetOptions(Lang, nil)
|
dstLangDropDown.SetOptions(translate.Lang, nil)
|
||||||
themeDropDown.SetLabel("Theme: ").
|
themeDropDown.SetLabel("Theme: ").
|
||||||
SetOptions(AllTheme, nil).
|
SetOptions(color.AllTheme, nil).
|
||||||
SetCurrentOption(IndexOf(style.Theme, AllTheme))
|
SetCurrentOption(IndexOf(style.Theme, color.AllTheme))
|
||||||
transparentDropDown.SetLabel("Transparent: ").
|
transparentDropDown.SetLabel("Transparent: ").
|
||||||
SetOptions([]string{"true", "false"}, nil).
|
SetOptions([]string{"true", "false"}, nil).
|
||||||
SetCurrentOption(
|
SetCurrentOption(
|
||||||
IndexOf(strconv.FormatBool(style.Transparent),
|
IndexOf(strconv.FormatBool(style.Transparent),
|
||||||
[]string{"true", "false"}))
|
[]string{"true", "false"}))
|
||||||
srcBorderDropDown.SetLabel("Border Color: ").
|
srcBorderDropDown.SetLabel("Border Color: ").
|
||||||
SetOptions(Palette, nil).
|
SetOptions(color.Palette, nil).
|
||||||
SetCurrentOption(IndexOf(style.SrcBorderStr(), Palette))
|
SetCurrentOption(IndexOf(style.SrcBorderStr(), color.Palette))
|
||||||
srcBorderDropDown.SetBorder(true).
|
srcBorderDropDown.SetBorder(true).
|
||||||
SetTitle("Source")
|
SetTitle("Source")
|
||||||
dstBorderDropDown.SetLabel("Border Color: ").
|
dstBorderDropDown.SetLabel("Border Color: ").
|
||||||
SetOptions(Palette, nil).
|
SetOptions(color.Palette, nil).
|
||||||
SetCurrentOption(IndexOf(style.DstBorderStr(), Palette))
|
SetCurrentOption(IndexOf(style.DstBorderStr(), color.Palette))
|
||||||
dstBorderDropDown.SetBorder(true).
|
dstBorderDropDown.SetBorder(true).
|
||||||
SetTitle("Destination")
|
SetTitle("Destination")
|
||||||
|
|
||||||
@ -303,19 +273,19 @@ func uiInit() {
|
|||||||
|
|
||||||
// handler
|
// handler
|
||||||
mainPage.SetInputCapture(mainPageHandler)
|
mainPage.SetInputCapture(mainPageHandler)
|
||||||
|
translateWindow.SetInputCapture(translatePageHandler)
|
||||||
langWindow.SetInputCapture(popOutWindowHandler)
|
langWindow.SetInputCapture(popOutWindowHandler)
|
||||||
styleWindow.SetInputCapture(popOutWindowHandler)
|
styleWindow.SetInputCapture(popOutWindowHandler)
|
||||||
keyMapWindow.SetInputCapture(popOutWindowHandler)
|
keyMapWindow.SetInputCapture(popOutWindowHandler)
|
||||||
translateWindow.SetInputCapture(translatePageHandler)
|
|
||||||
srcLangDropDown.SetDoneFunc(langDropDownHandler).
|
srcLangDropDown.SetDoneFunc(langDropDownHandler).
|
||||||
SetSelectedFunc(func(text string, index int) {
|
SetSelectedFunc(func(text string, index int) {
|
||||||
translator.srcLang = text
|
translator.SrcLang = text
|
||||||
srcInput.SetTitle(text)
|
srcInput.SetTitle(text)
|
||||||
srcLangDropDown.SetTitle(text)
|
srcLangDropDown.SetTitle(text)
|
||||||
})
|
})
|
||||||
dstLangDropDown.SetDoneFunc(langDropDownHandler).
|
dstLangDropDown.SetDoneFunc(langDropDownHandler).
|
||||||
SetSelectedFunc(func(text string, index int) {
|
SetSelectedFunc(func(text string, index int) {
|
||||||
translator.dstLang = text
|
translator.DstLang = text
|
||||||
dstOutput.SetTitle(text)
|
dstOutput.SetTitle(text)
|
||||||
dstLangDropDown.SetTitle(text)
|
dstLangDropDown.SetTitle(text)
|
||||||
})
|
})
|
||||||
@ -380,29 +350,6 @@ func mainPageHandler(event *tcell.EventKey) *tcell.EventKey {
|
|||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
func popOutWindowHandler(event *tcell.EventKey) *tcell.EventKey {
|
|
||||||
ch := event.Rune()
|
|
||||||
|
|
||||||
switch ch {
|
|
||||||
case '1':
|
|
||||||
mainPage.HidePage("stylePage")
|
|
||||||
mainPage.HidePage("keyMapPage")
|
|
||||||
mainPage.ShowPage("langPage")
|
|
||||||
app.SetFocus(langCycle.GetCurrentUI())
|
|
||||||
case '2':
|
|
||||||
mainPage.HidePage("langPage")
|
|
||||||
mainPage.HidePage("keyMapPage")
|
|
||||||
mainPage.ShowPage("stylePage")
|
|
||||||
app.SetFocus(styleCycle.GetCurrentUI())
|
|
||||||
case '3':
|
|
||||||
mainPage.HidePage("langPage")
|
|
||||||
mainPage.HidePage("stylePage")
|
|
||||||
mainPage.ShowPage("keyMapPage")
|
|
||||||
}
|
|
||||||
|
|
||||||
return event
|
|
||||||
}
|
|
||||||
|
|
||||||
func translatePageHandler(event *tcell.EventKey) *tcell.EventKey {
|
func translatePageHandler(event *tcell.EventKey) *tcell.EventKey {
|
||||||
key := event.Key()
|
key := event.Key()
|
||||||
|
|
||||||
@ -424,7 +371,7 @@ func translatePageHandler(event *tcell.EventKey) *tcell.EventKey {
|
|||||||
case tcell.KeyCtrlQ:
|
case tcell.KeyCtrlQ:
|
||||||
srcInput.SetText("", true)
|
srcInput.SetText("", true)
|
||||||
case tcell.KeyCtrlS:
|
case tcell.KeyCtrlS:
|
||||||
translator.srcLang, translator.dstLang = translator.dstLang, translator.srcLang
|
translator.SrcLang, translator.DstLang = translator.DstLang, translator.SrcLang
|
||||||
updateTitle()
|
updateTitle()
|
||||||
srcText := srcInput.GetText()
|
srcText := srcInput.GetText()
|
||||||
dstText := dstOutput.GetText(false)
|
dstText := dstOutput.GetText(false)
|
||||||
@ -437,13 +384,13 @@ func translatePageHandler(event *tcell.EventKey) *tcell.EventKey {
|
|||||||
dstOutput.SetText(srcText)
|
dstOutput.SetText(srcText)
|
||||||
case tcell.KeyCtrlO:
|
case tcell.KeyCtrlO:
|
||||||
// Play source sound
|
// Play source sound
|
||||||
if translator.soundLock.Available() {
|
if translator.SoundLock.Available() {
|
||||||
message := srcInput.GetText()
|
message := srcInput.GetText()
|
||||||
if len(message) > 0 {
|
if len(message) > 0 {
|
||||||
// Only play when message exist
|
// Only play when message exist
|
||||||
translator.soundLock.Acquire()
|
translator.SoundLock.Acquire()
|
||||||
go func() {
|
go func() {
|
||||||
err := translator.PlaySound(translator.srcLang, message)
|
err := translator.PlaySound(translator.SrcLang, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srcInput.SetText(err.Error(), true)
|
srcInput.SetText(err.Error(), true)
|
||||||
}
|
}
|
||||||
@ -453,13 +400,13 @@ func translatePageHandler(event *tcell.EventKey) *tcell.EventKey {
|
|||||||
}
|
}
|
||||||
case tcell.KeyCtrlP:
|
case tcell.KeyCtrlP:
|
||||||
// Play destination sound
|
// Play destination sound
|
||||||
if translator.soundLock.Available() {
|
if translator.SoundLock.Available() {
|
||||||
message := dstOutput.GetText(false)
|
message := dstOutput.GetText(false)
|
||||||
if len(message) > 0 {
|
if len(message) > 0 {
|
||||||
// Only play when message exist
|
// Only play when message exist
|
||||||
translator.soundLock.Acquire()
|
translator.SoundLock.Acquire()
|
||||||
go func() {
|
go func() {
|
||||||
err := translator.PlaySound(translator.dstLang, message)
|
err := translator.PlaySound(translator.DstLang, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dstOutput.SetText(err.Error())
|
dstOutput.SetText(err.Error())
|
||||||
}
|
}
|
||||||
@ -468,7 +415,30 @@ func translatePageHandler(event *tcell.EventKey) *tcell.EventKey {
|
|||||||
}
|
}
|
||||||
case tcell.KeyCtrlX:
|
case tcell.KeyCtrlX:
|
||||||
// Stop play sound
|
// Stop play sound
|
||||||
translator.soundLock.stop = true
|
translator.SoundLock.Stop = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func popOutWindowHandler(event *tcell.EventKey) *tcell.EventKey {
|
||||||
|
ch := event.Rune()
|
||||||
|
|
||||||
|
switch ch {
|
||||||
|
case '1':
|
||||||
|
mainPage.HidePage("stylePage")
|
||||||
|
mainPage.HidePage("keyMapPage")
|
||||||
|
mainPage.ShowPage("langPage")
|
||||||
|
app.SetFocus(langCycle.GetCurrentUI())
|
||||||
|
case '2':
|
||||||
|
mainPage.HidePage("langPage")
|
||||||
|
mainPage.HidePage("keyMapPage")
|
||||||
|
mainPage.ShowPage("stylePage")
|
||||||
|
app.SetFocus(styleCycle.GetCurrentUI())
|
||||||
|
case '3':
|
||||||
|
mainPage.HidePage("langPage")
|
||||||
|
mainPage.HidePage("stylePage")
|
||||||
|
mainPage.ShowPage("keyMapPage")
|
||||||
}
|
}
|
||||||
|
|
||||||
return event
|
return event
|
||||||
|
Loading…
x
Reference in New Issue
Block a user