ppforge/internal/ui/main.go

219 lines
5.3 KiB
Go

package ui
import (
"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"
)
// A Representationer provides a representation as fyne.Container
type Representationer interface {
Representation() *fyne.Container
}
// A FileHandler handles files in the application
type FileHandler interface {
Name() string
Path() string
Open(path string) error
Save() error
SaveAs(path string) error
Close() error
SetChanged()
HasChanged() bool
GetReference() interface{}
}
// A TabProvider gives back a container.TabItem and allows to set it for internal storage
type TabProvider interface {
SetTab(tab *container.TabItem)
Tab() *container.TabItem
}
// ppfApp is the internal struct holding all the required main objects/elements for the application
type ppfApp struct {
App fyne.App
Window fyne.Window
// Container for the main layout, toolbar at top, in Center the doctabs.
MainContainer *fyne.Container
// toolbar
Toolbar fyne.CanvasObject
// left optional the local/remote library
// tbd
// center opened objects
OpenTabs *container.DocTabs // DocTabs
OpenObjects []FileHandler // actual files
// Global important stuff
Settings map[string]interface{}
/*/ will be part of the Editor
Metadata *Metadata
Extensions *fyne.Container
ContextBar *fyne.Container
ContentTabs *fyne.Container
Workarea *container.DocTabs
// Once initialized metadata containers for swapping
ProtocolMeta *ProtocolMetadata
PacketMeta *PacketMetadata
// Once initialized instances of the editor views
EditorPacket *PacketEditor
EditorProtocol *ProtocolEditor
// workspace handling
OpenProtocolFiles []*ProtocolFileHandler//*/
}
// PPF is the global variable holding the application struct
var PPF ppfApp
// NewPPF is the entrypoint to create the application
func NewPPF(fyneApp fyne.App, w fyne.Window) ppfApp {
PPF.App = fyneApp
PPF.Window = w
PPF.Toolbar = CreateToolbar(fyneApp)
PPF.OpenTabs = CreateWorkarea()
return PPF
}
func (ppf *ppfApp) GetContainer() *fyne.Container {
return container.NewBorder(
ppf.Toolbar, //top
nil, //bottom
nil, //left // maybe Accordion with existing protocols, your protocols, your packets?
nil, //right
ppf.OpenTabs,
)
}
func (ppf *ppfApp) NewProtocolFile() {
//TODO: show entry screen with choosable ways of:
// PROTOCOL editor
// create a new protocol
// edit an existing protocol
// PACKET editor
// create a binary packet
// edit an existing binary packet
pfh := NewProtocolFileHandler()
ppf.OpenObjects = append(ppf.OpenObjects, pfh)
item := ppf.OpenTabs.Selected()
item.Text = pfh.Name()
item.Content = pfh.GetWorkarea()
pfh.SetTab(item)
}
func (ppf *ppfApp) NewPacketFile() {
}
func (ppf *ppfApp) OpenProtocolFile(path string) {
for _, v := range ppf.OpenTabs.Items {
if v.Text == path {
// do not open a file twice!
ppf.OpenTabs.Select(v)
return
}
}
pfh := NewProtocolFileHandler()
pfh.Open(path)
ppf.OpenObjects = append(ppf.OpenObjects, pfh)
item := ppf.OpenTabs.Selected()
item.Text = pfh.Path()
item.Content = pfh.GetWorkarea()
pfh.SetTab(item)
}
func (ppf *ppfApp) OpenPacketFile(path string) {
}
func (ppf *ppfApp) SaveFile(path string) {
item := ppf.OpenTabs.Selected()
for _, fh := range ppf.OpenObjects {
if fh.(TabProvider).Tab() == item {
fh.SaveAs(path)
}
}
// if there exists another one with the same path, (max one!!!)
/* // skip that check for now
existingTab := -1
for i, v := range ppf.OpenTabs.Items {
fmt.Printf("existing tab %d, path %s\n", i, v.Text)
if v.Text == path && i != ppf.OpenTabs.SelectedIndex() {
existingTab = i
}
}
if existingTab > 0 {
ppf.OpenTabs.Items = append(ppf.OpenTabs.Items[:existingTab], ppf.OpenTabs.Items[existingTab+1:]...)
fmt.Printf("removing %d", existingTab)
ppf.OpenTabs.Refresh()
} */
item.Text = path
ppf.OpenTabs.Refresh()
}
func (ppf *ppfApp) NewFile() {
for _, v := range ppf.OpenTabs.Items {
if v.Text == "[new item dialog]" {
ppf.OpenTabs.Select(v)
return
}
}
item := container.NewTabItem("[new item dialog]", CreateNewObjectDialog().Representation())
ppf.OpenTabs.Append(item)
ppf.OpenTabs.Select(item)
}
func CreateToolbar(fyneApp fyne.App) fyne.CanvasObject {
toolbar := widget.NewToolbar()
toolbar.Append(widget.NewToolbarAction(theme.ContentAddIcon(), func() {
PPF.NewFile()
}))
toolbar.Append(widget.NewToolbarAction(theme.DocumentSaveIcon(), func() {
if strings.HasPrefix(PPF.OpenTabs.Selected().Text, "*new") {
dialog.NewFileSave(func(uri fyne.URIWriteCloser, err error) {
if uri == nil {
return
}
PPF.SaveFile(uri.URI().Path())
}, PPF.Window).Show()
} else {
PPF.SaveFile(PPF.OpenTabs.Selected().Text)
}
}))
toolbar.Append(widget.NewToolbarAction(theme.StorageIcon(), func() {
dialog.NewFileSave(func(uri fyne.URIWriteCloser, err error) {
if uri == nil {
return
}
PPF.SaveFile(uri.URI().Path())
}, PPF.Window).Show()
}))
toolbar.Append(widget.NewToolbarAction(theme.SettingsIcon(), func() {
}))
toolbar.Append(widget.NewToolbarSpacer())
toolbar.Append(widget.NewToolbarAction(theme.LogoutIcon(), func() {
fyneApp.Quit()
}))
return toolbar
}
func CreateWorkarea() *container.DocTabs {
tabs := container.NewDocTabs()
tabs.OnClosed = func(ti *container.TabItem) {
}
tabs.OnSelected = func(ti *container.TabItem) {
}
return tabs
}