349 lines
8.8 KiB
Go
349 lines
8.8 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
"go_dreamfactory/cmd/v2/lib/common"
|
|
"go_dreamfactory/cmd/v2/service"
|
|
"go_dreamfactory/cmd/v2/service/observer"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/modules/user"
|
|
"go_dreamfactory/pb"
|
|
"strings"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/dialog"
|
|
"fyne.io/fyne/v2/theme"
|
|
"fyne.io/fyne/v2/widget"
|
|
"github.com/BabySid/gobase"
|
|
"github.com/Pallinder/go-randomdata"
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/go-vgo/robotgo"
|
|
)
|
|
|
|
var (
|
|
globalWin *MainWindowImpl
|
|
toolWin *ToolWindowImpl
|
|
)
|
|
|
|
type MainWindow interface {
|
|
WindowInterface
|
|
}
|
|
|
|
type MainWindowImpl struct {
|
|
UIImpl
|
|
WindowDefaultOptions
|
|
parent fyne.Window
|
|
w fyne.Window
|
|
tb *toolBar //工具条
|
|
toys *toys // side
|
|
sb *statusBar //状态栏
|
|
at *appContainer //tabs
|
|
}
|
|
|
|
func NewMainWindow(ui *UIImpl, parent fyne.Window) MainWindow {
|
|
gobase.NewScheduler().Start()
|
|
gobase.RegisterAtExit(gobase.GlobalScheduler.Stop)
|
|
mw := &MainWindowImpl{
|
|
UIImpl: *ui,
|
|
parent: parent,
|
|
}
|
|
|
|
globalWin = mw
|
|
|
|
ui.obs.AddListener(observer.EVENT_PING, observer.Listener{
|
|
OnNotify: func(data interface{}, args ...interface{}) {
|
|
logrus.Debug("即将与服务器断开链接")
|
|
conf := dialog.NewConfirm("链接中断", data.(error).Error(), func(
|
|
b bool) {
|
|
ui.app.Quit()
|
|
}, globalWin.w)
|
|
conf.SetDismissText("取消")
|
|
conf.SetConfirmText("退出")
|
|
conf.Show()
|
|
},
|
|
})
|
|
return mw
|
|
}
|
|
|
|
func GetGlobalWin() *MainWindowImpl {
|
|
return globalWin
|
|
}
|
|
|
|
// createWindowContainer create a container with the window content
|
|
func (ui *MainWindowImpl) createWindowContainer() {
|
|
// create main layout
|
|
|
|
// status bar
|
|
ui.sb = newStatusBar()
|
|
|
|
// tool bar
|
|
toolbar := widget.NewToolbar(
|
|
widget.NewToolbarAction(theme.MediaVideoIcon(), func() {
|
|
openApp2(common.TOOLBAR_MONITOR)
|
|
}),
|
|
widget.NewToolbarAction(theme.DocumentIcon(), func() {
|
|
openApp2(common.TOOLBAR_TESTER)
|
|
}),
|
|
widget.NewToolbarSpacer(),
|
|
widget.NewToolbarAction(theme.FileIcon(), func() {
|
|
newLogViewer().Win.Show()
|
|
}),
|
|
)
|
|
ui.tb = newToolBar(toolbar)
|
|
|
|
// Fun Toys
|
|
ui.toys = newToys(ui.obs)
|
|
|
|
// main app tabs
|
|
ui.at = newAppContainer(appRegister, ui.obs)
|
|
content := container.NewBorder(ui.tb.toolbar, ui.sb.widget, nil, ui.toys.widget, ui.at)
|
|
ui.w.SetContent(content)
|
|
// 屏幕最大
|
|
width, height := robotgo.GetScaleSize()
|
|
ui.w.Resize(fyne.NewSize(float32(width), float32(height)))
|
|
ui.w.CenterOnScreen()
|
|
ui.w.SetCloseIntercept(ui.quiteHandle)
|
|
}
|
|
|
|
func (ui *MainWindowImpl) SetStatusMsg(msg string) {
|
|
ui.sb.setMessage(fmt.Sprintf("err:%s", msg))
|
|
}
|
|
|
|
func (ui *MainWindowImpl) quiteHandle() {
|
|
dialog.ShowConfirm("推出系统", "确定退出吗", func(b bool) {
|
|
if !b {
|
|
return
|
|
}
|
|
ui.app.Quit()
|
|
}, ui.w)
|
|
|
|
}
|
|
|
|
// CreateWindow ....
|
|
func (ui *MainWindowImpl) CreateWindow(_ string, width, height float32, _ bool) {
|
|
// init window
|
|
title := fmt.Sprintf(common.APP_WIN_TITLE, "登录", ui.app.Metadata().Version, ui.app.Metadata().Build, common.APP_NAME)
|
|
w := ui.app.NewWindow(title)
|
|
ui.AddWindow("main", w)
|
|
ui.w = w
|
|
|
|
if ui.windowAspect == common.WindowAspect_FullScreen {
|
|
w.SetFullScreen(true)
|
|
} else {
|
|
w.Resize(fyne.NewSize(width, height))
|
|
}
|
|
|
|
// w.SetMaster()
|
|
w.CenterOnScreen()
|
|
w.Canvas().SetOnTypedKey(func(ke *fyne.KeyEvent) {
|
|
switch ke.Name {
|
|
case fyne.KeyEscape:
|
|
{
|
|
w.Close()
|
|
ui.parent.Show()
|
|
}
|
|
}
|
|
})
|
|
w.SetCloseIntercept(func() {
|
|
ui.parent.Show()
|
|
})
|
|
_ = ui.createChooseServerPopUp(w)
|
|
}
|
|
|
|
// createChooseServerPopUp
|
|
func (ui *MainWindowImpl) createChooseServerPopUp(w fyne.Window) error {
|
|
ch := make(chan string)
|
|
|
|
title := fmt.Sprintf(common.APP_WIN_TITLE, "选服", ui.app.Metadata().Version, ui.app.Metadata().Build, common.APP_NAME)
|
|
selServerWin := ui.createChooseServerWindow(title, ch)
|
|
|
|
go func() {
|
|
data := <-ch
|
|
selServerWin.Hide()
|
|
ui.NewWelcomeLabel(data)
|
|
ui.w.Show()
|
|
}()
|
|
return nil
|
|
}
|
|
|
|
// createChooseServerWindow
|
|
func (ui *MainWindowImpl) createChooseServerWindow(
|
|
title string,
|
|
ch chan string) fyne.Window {
|
|
// choose server button func
|
|
makeButton := func(s *service.ServiceConf, parent fyne.Window) *widget.Button {
|
|
btn := widget.NewButton(s.Name, func() {
|
|
d := dialog.NewInformation("", common.INFO_WAIT, parent)
|
|
d.SetDismissText(common.BUTTON_CANCEL)
|
|
d.Show()
|
|
|
|
logrus.WithFields(logrus.Fields{"server": s.Name, "sid": s.SId}).Debug("choose server")
|
|
//conn server
|
|
if err := ui.connService.WsConnect(s.Url); err != nil {
|
|
d.Hide()
|
|
dialog.ShowError(err, parent)
|
|
} else {
|
|
ch <- fmt.Sprintf("%s:%s", s.SId, s.Name)
|
|
}
|
|
})
|
|
return btn
|
|
}
|
|
w := fyne.CurrentApp().NewWindow(title)
|
|
sGrid := container.NewGridWithColumns(2)
|
|
config := ui.configService.GetConfig()
|
|
if config != nil {
|
|
for _, s := range config.Services {
|
|
box := makeButton(s.Service, w)
|
|
sGrid.Add(box)
|
|
}
|
|
}
|
|
|
|
w.SetContent(sGrid)
|
|
w.SetFixedSize(true)
|
|
w.Resize(fyne.NewSize(500, 200))
|
|
w.Show()
|
|
w.SetCloseIntercept(func() {
|
|
ui.parent.Show()
|
|
w.Close()
|
|
})
|
|
w.CenterOnScreen()
|
|
return w
|
|
}
|
|
|
|
// createLoginWin
|
|
func (ui *MainWindowImpl) createLoginWin(sid, sname string) {
|
|
account := widget.NewEntry()
|
|
// account.Text = "user8080" //default account
|
|
|
|
items := []*widget.FormItem{
|
|
widget.NewFormItem(common.LABEL_ACCOUNT, account),
|
|
}
|
|
|
|
dialog.ShowForm(common.FORM_TITLE_LOGIN, common.BUTTON_LOGIN, common.BUTTON_CANCEL, items, func(b bool) {
|
|
if !b {
|
|
logrus.Debug("cancel login")
|
|
} else {
|
|
if account.Text != "" {
|
|
logrus.WithField("account", account.Text).Debug("submit login")
|
|
ui.createWindowContainer()
|
|
appName, err := ui.at.openDefaultApp()
|
|
if err != nil {
|
|
logrus.WithField("appName", appName).Error(err)
|
|
}
|
|
// hide toolbar
|
|
ui.tb.toolbar.Hide()
|
|
// call after ui.createWindowContainer
|
|
ui.connService.ListenerPush()
|
|
if code := ui.pttService.Login(sid, account.Text); code != pb.ErrorCode_Success {
|
|
err := fmt.Errorf("login err: %v[%d]", code, int32(code))
|
|
dialog.ShowError(err, ui.w)
|
|
} else {
|
|
ui.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{
|
|
OnNotify: func(data interface{}, args ...interface{}) {
|
|
if data == nil {
|
|
return
|
|
}
|
|
msg := data.(*pb.UserMessage)
|
|
if msg.MainType == string(comm.ModuleUser) &&
|
|
msg.SubType == user.UserSubTypeLogin {
|
|
rsp := &pb.UserLoginResp{}
|
|
if !comm.ProtoUnmarshal(msg, rsp) {
|
|
logrus.Error("unmarshal err")
|
|
return
|
|
}
|
|
|
|
// reset main window title
|
|
subTitle := fmt.Sprintf("%s[%s]", sname, sid)
|
|
ui.w.SetTitle(fmt.Sprintf(common.APP_WIN_TITLE, subTitle, ui.app.Metadata().Version, ui.app.Metadata().Build, common.APP_NAME))
|
|
ui.pttService.SetUser(rsp.Data, rsp.Ex)
|
|
// isCreateRole
|
|
if rsp.Data.Created {
|
|
// set statusbar message
|
|
ui.sb.setMessage(common.LABEL_WELCOME + rsp.Data.Binduid)
|
|
// update userinfo
|
|
ui.obs.Notify(observer.EVENT_USERINFO, ui.pttService.GetUser())
|
|
// show toolbar
|
|
ui.tb.toolbar.Show()
|
|
} else {
|
|
// create role
|
|
ui.createRoleWindowPopUp()
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}, ui.w)
|
|
}
|
|
|
|
// createMainWindowMenu create the main window menu
|
|
func (ui *MainWindowImpl) createMainWindowMenu() *fyne.MainMenu {
|
|
|
|
menuItems := []*fyne.MenuItem{}
|
|
|
|
menu := fyne.Menu{
|
|
Label: common.MENU_FILE,
|
|
Items: menuItems,
|
|
}
|
|
|
|
return fyne.NewMainMenu(&menu)
|
|
}
|
|
|
|
// createRoleWindowPopUp
|
|
func (ui *MainWindowImpl) createRoleWindowPopUp() {
|
|
nickname := widget.NewEntry()
|
|
c := container.NewBorder(nil, nil, nil,
|
|
widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), func() {
|
|
nickname.SetText(randomdata.SillyName())
|
|
}),
|
|
nickname,
|
|
)
|
|
items := []*widget.FormItem{
|
|
widget.NewFormItem(common.LABEL_NICKNAME, c),
|
|
}
|
|
|
|
d := dialog.NewForm(common.FORM_TITLE_CREATEROLE, common.BUTTON_OK, common.BUTTON_CANCEL, items, func(b bool) {
|
|
if nickname.Text != "" {
|
|
logrus.WithField("nickname", nickname.Text).Debug("submit crete role")
|
|
if code := ui.pttService.CreateRole(nickname.Text); code != pb.ErrorCode_Success {
|
|
err := fmt.Errorf("login err: %v[%d]", code, int32(code))
|
|
dialog.ShowError(err, ui.w)
|
|
} else {
|
|
user := ui.pttService.GetUser()
|
|
logrus.WithField("uid", user.DbUser.Uid).Debug("create role succ")
|
|
ui.obs.Notify(observer.EVENT_USERINFO, ui.pttService.GetUser())
|
|
ui.tb.toolbar.Show()
|
|
}
|
|
}
|
|
}, ui.w)
|
|
d.Resize(fyne.NewSize(300, 200))
|
|
d.Show()
|
|
}
|
|
|
|
// NewWelcomeLabel
|
|
func (ui *MainWindowImpl) NewWelcomeLabel(data string) {
|
|
p := strings.Split(data, ":")
|
|
if len(p) != 2 {
|
|
logrus.WithField("param", p).Error("choose service")
|
|
return
|
|
}
|
|
c := container.NewCenter(container.NewVBox(
|
|
widget.NewLabelWithStyle(fmt.Sprintf(common.LABEL_CHOOSE, p[0], p[1]),
|
|
fyne.TextAlignCenter,
|
|
fyne.TextStyle{Bold: true}),
|
|
container.NewCenter(container.NewHBox(
|
|
widget.NewButton(common.BUTTON_LOGIN, func() {
|
|
ui.createLoginWin(p[0], p[1])
|
|
}),
|
|
)),
|
|
))
|
|
ui.w.SetContent(c)
|
|
ui.w.SetCloseIntercept(func() {
|
|
ui.w.Close()
|
|
ui.parent.Show()
|
|
})
|
|
}
|