Editor is now fully in a DocTab

This commit is contained in:
Marcel M. Otte 2023-03-31 15:38:20 +02:00
parent b65c9c27f7
commit 52bff71153
4 changed files with 163 additions and 103 deletions

View File

@ -1,6 +1,7 @@
package ui
import (
"fmt"
"strings"
"fyne.io/fyne/v2"
@ -8,8 +9,6 @@ import (
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocol"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocolctl"
)
type Representationer interface {
@ -24,8 +23,10 @@ type FileHandler interface {
SaveAs(path string) error
Close() error
Changed()
SetChanged()
HasChanged() bool
GetReference() interface{}
}
type ppfApp struct {
@ -39,7 +40,7 @@ type ppfApp struct {
// tbd
// center opened objects
OpenTabs *container.DocTabs // DocTabs
OpenObjects []*FileHandler // actual files
OpenObjects []FileHandler // actual files
// Global important stuff
Settings map[string]interface{}
@ -66,30 +67,20 @@ func NewPPF(fyneApp fyne.App, w fyne.Window) ppfApp {
PPF.App = fyneApp
PPF.Window = w
PPF.Toolbar = CreateToolbar(fyneApp)
/*PPF.Workarea = CreateWorkarea()
PPF.Extensions = container.NewCenter()
PPF.ProtocolMeta = NewMetadataProtocol()
PPF.Metadata = &PPF.ProtocolMeta.Metadata
PPF.ContextBar = container.NewCenter() //*/
PPF.OpenTabs = CreateWorkarea()
return PPF
}
func (ppf *ppfApp) GetContainer() *fyne.Container {
return container.NewBorder(
PPF.Toolbar,
nil, //PPF.ContextBar,
nil, //PPF.Metadata.Representation,
nil, //PPF.Extensions,
PPF.OpenTabs,
ppf.Toolbar, //top
nil, //bottom
nil, //left // maybe Accordion with existing protocols, your protocols, your packets?
nil, //right
ppf.OpenTabs,
)
}
func (ppf *ppfApp) OpenFile(path string) {
pfh := LoadProtocolFileHandler(path)
ppf.OpenProtocolFiles = append(PPF.OpenProtocolFiles, pfh)
ppf.Workarea.Append(container.NewTabItem(pfh.Filename, pfh.GetWorkarea()))
}
func (ppf *ppfApp) NewProtocolFile() {
//TODO: show entry screen with choosable ways of:
// PROTOCOL editor
@ -99,32 +90,71 @@ func (ppf *ppfApp) NewProtocolFile() {
// create a binary packet
// edit an existing binary packet
pfh := NewProtocolFileHandler()
PPF.OpenProtocolFiles = append(PPF.OpenProtocolFiles, pfh)
ppf.Workarea.Append(container.NewTabItem(pfh.Filename, pfh.GetWorkarea()))
ppf.OpenObjects = append(ppf.OpenObjects, pfh)
item := ppf.OpenTabs.Selected()
item.Text = pfh.Name()
item.Content = pfh.GetWorkarea()
}
func (ppf *ppfApp) NewPacketFile() {
}
func (ppf *ppfApp) SaveFile(path string) {
item := ppf.Workarea.Selected()
for _, pfh := range ppf.OpenProtocolFiles {
if pfh.Filename == item.Text {
protocolctl.Save(pfh.ProtocolEditor.Reference, path)
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
}
}
item.Text = path
ppf.Workarea.Refresh()
pfh := NewProtocolFileHandler()
pfh.Open(path)
ppf.OpenObjects = append(ppf.OpenObjects, pfh)
item := ppf.OpenTabs.Selected()
item.Text = pfh.Path()
item.Content = pfh.GetWorkarea()
}
func (ppf *ppfApp) GetReferenceForFile(s string) *protocol.ProtocolStructure {
for _, pfh := range ppf.OpenProtocolFiles {
if pfh.Filename == s {
return pfh.ProtocolEditor.Reference
func (ppf *ppfApp) OpenPacketFile(path string) {
}
func (ppf *ppfApp) SaveFile(path string) {
item := ppf.OpenTabs.Selected()
for _, fh := range ppf.OpenObjects {
if fh.Path() == item.Text {
fh.SaveAs(path)
}
}
return nil
// if there exists another one with the same path, (max one!!!)
existingTab := -1
for i, v := range ppf.OpenTabs.Items {
fmt.Printf("tab %d, path %s", 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 {
@ -132,16 +162,8 @@ func CreateToolbar(fyneApp fyne.App) fyne.CanvasObject {
toolbar.Append(widget.NewToolbarAction(theme.ContentAddIcon(), func() {
PPF.NewFile()
}))
toolbar.Append(widget.NewToolbarAction(theme.FolderOpenIcon(), func() {
dialog.NewFileOpen(func(uri fyne.URIReadCloser, err error) {
if uri == nil {
return
}
PPF.OpenFile(uri.URI().Path())
}, PPF.Window).Show()
}))
toolbar.Append(widget.NewToolbarAction(theme.DocumentSaveIcon(), func() {
if strings.HasPrefix(PPF.Workarea.Selected().Text, "*new") {
if strings.HasPrefix(PPF.OpenTabs.Selected().Text, "*new") {
dialog.NewFileSave(func(uri fyne.URIWriteCloser, err error) {
if uri == nil {
return
@ -149,7 +171,7 @@ func CreateToolbar(fyneApp fyne.App) fyne.CanvasObject {
PPF.SaveFile(uri.URI().Path())
}, PPF.Window).Show()
} else {
PPF.SaveFile(PPF.Workarea.Selected().Text)
PPF.SaveFile(PPF.OpenTabs.Selected().Text)
}
}))
toolbar.Append(widget.NewToolbarAction(theme.StorageIcon(), func() {
@ -175,15 +197,9 @@ func CreateToolbar(fyneApp fyne.App) fyne.CanvasObject {
func CreateWorkarea() *container.DocTabs {
tabs := container.NewDocTabs()
tabs.OnClosed = func(ti *container.TabItem) {
if len(tabs.Items) == 0 {
PPF.Metadata.Representation.Hide()
}
}
tabs.OnSelected = func(ti *container.TabItem) {
PPF.ProtocolMeta.SetProtocol(PPF.GetReferenceForFile(ti.Text))
PPF.Metadata = &PPF.ProtocolMeta.Metadata
PPF.Metadata.Representation.Refresh()
PPF.Metadata.Representation.Show()
}
return tabs
}

View File

@ -3,6 +3,8 @@ package ui
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/widget"
)
@ -20,34 +22,49 @@ func CreateNewObjectDialog() *NewObjectDialog {
if pnod == nil {
pnod = &NewObjectDialog{}
pnod.representation = container.NewMax(nil)
// representation
// grid layout 100x100px elements in a center layout, 4 buttons, new Protocol, edit protocol, new Packet, edit Packet
buttons := []widget.Button{}
buttons = append(buttons, *widget.NewButton("New protocol", func() {
buttons := []*widget.Button{
widget.NewButton("New protocol", func() {
// two ways: either backreference to PPF, open new tab with file and close the NOD
// or replace the content of the tab of the NOD, with changing the title in OpenTabs backreference to PPF aswell
PPF.NewProtocolFile()
}))
buttons = append(buttons, *widget.NewButton("Open/Edit protocol", func() {
pnod.representation.RemoveAll()
pnod.representation.Add(pnod.protocolChooser)
}))
buttons = append(buttons, *widget.NewButton("New packet", func() {
}),
widget.NewButton("Open/Edit protocol", func() {
opendialog := dialog.NewFileOpen(func(uri fyne.URIReadCloser, err error) {
if uri == nil {
return
}
PPF.OpenProtocolFile(uri.URI().Path())
}, PPF.Window)
opendialog.SetFilter(storage.NewExtensionFileFilter([]string{".protocoljson"}))
opendialog.Show()
}),
widget.NewButton("New packet", func() {
PPF.NewPacketFile()
}))
buttons = append(buttons, *widget.NewButton("Open/Edit packet", func() {
pnod.representation.RemoveAll()
pnod.representation.Add(pnod.packetChooser)
}))
selectgrid := container.NewGridWithColumns(2, nil)
}),
widget.NewButton("Open/Edit packet", func() {
opendialog := dialog.NewFileOpen(func(uri fyne.URIReadCloser, err error) {
if uri == nil {
return
}
PPF.OpenPacketFile(uri.URI().Path())
}, PPF.Window)
opendialog.SetFilter(storage.NewExtensionFileFilter([]string{".packetjson"}))
opendialog.Show()
}),
}
selectgrid := container.NewGridWithColumns(2)
for _, v := range buttons {
selectgrid.Add(&v)
selectgrid.Add(v)
}
pnod.selection = container.NewMax(selectgrid)
pnod.representation = pnod.selection
pnod.representation.Add(pnod.selection) // add selection per default
//pnod.representation.Add(pnod.selection) // add selection per default
// generate protocol chooser view
// App Tabs or vertical Accordion (doesnt exist yet)
pnod.protocolChooser = container.NewAppTabs(nil)
//pnod.protocolChooser = container.NewAppTabs(nil)
// first tab -> official protocol repo, for viewing and editing/improvement
// file chooser embedded
// second tab -> own protocols, in a folder somewhere.

View File

@ -11,21 +11,18 @@ import (
type ProtocolEditor struct {
Representation *fyne.Container
FieldContainer *fyne.Container
Metadata *ProtocolMetadata
Fields []*FieldEditor
Reference *protocol.ProtocolStructure
}
func GetProtocolEditor() *ProtocolEditor {
container := container.NewGridWrap(fyne.NewSize(300, 400))
protocolEditor := &ProtocolEditor{container, []*FieldEditor{}, protocolctl.NewProtocolStructure()}
container.Add(GetAdder(protocolEditor))
return protocolEditor
}
func NewProtocolEditor(ref *protocol.ProtocolStructure) *ProtocolEditor {
container := container.NewGridWrap(fyne.NewSize(300, 400))
protocolEditor := &ProtocolEditor{container, []*FieldEditor{}, ref}
metadata := NewMetadataProtocol()
fields := container.NewGridWrap(fyne.NewSize(300, 400))
container := container.NewBorder(nil, nil, metadata.Representation, nil, container.NewVScroll(fields))
protocolEditor := &ProtocolEditor{container, fields, metadata, []*FieldEditor{}, ref}
protocolEditor.Redraw()
return protocolEditor
}
@ -38,11 +35,14 @@ func (ed *ProtocolEditor) AddFieldCreator(fieldCreator *FieldEditor) {
func (ed *ProtocolEditor) Redraw() {
json := protocolctl.ToJson(ed.Reference)
fmt.Printf("%s", json)
ed.Representation.RemoveAll()
ed.FieldContainer.RemoveAll()
// existing fields
for i, v := range ed.Reference.Structure {
ed.Representation.Add(CreateFieldEditor(ed, i, v).Representation)
ed.FieldContainer.Add(CreateFieldEditor(ed, i, v).Representation)
}
if len(ed.Reference.Structure) == 0 {
ed.Representation.Add(GetAdder(ed))
ed.FieldContainer.Add(GetAdder(ed))
}
// Metadata
ed.Metadata.SetProtocol(ed.Reference)
}

View File

@ -1,48 +1,75 @@
package ui
import (
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocol"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocolctl"
)
// implements FileHandler
type ProtocolFileHandler struct {
ProtocolEditor *ProtocolEditor
Filename string
Changed bool
name string
path string
changed bool
Reference *protocol.ProtocolStructure
}
func NewProtocolFileHandler() *ProtocolFileHandler {
pfh := ProtocolFileHandler{}
pfh.Filename = "*new"
pfh.Changed = true
pfh.ProtocolEditor = GetProtocolEditor()
pfh.name = "*new"
pfh.changed = true
pfh.ProtocolEditor = NewProtocolEditor(protocolctl.NewProtocolStructure())
return &pfh
}
func LoadProtocolFileHandler(path string) *ProtocolFileHandler {
pfh := ProtocolFileHandler{}
pfh.Filename = path
pfh.Load()
return &pfh
}
func (pfh *ProtocolFileHandler) Load() {
prot, err := protocolctl.LoadNew(pfh.Filename)
func (pfh *ProtocolFileHandler) Load() error {
prot, err := protocolctl.LoadNew(pfh.Path())
if err != nil {
// process error
err = nil
}
pfh.ProtocolEditor = NewProtocolEditor(prot)
pfh.Reference = prot
PPF.ProtocolMeta.SetProtocol(prot)
pfh.name = prot.Metadata.Name
return err
}
func (pfh *ProtocolFileHandler) GetWorkarea() *fyne.Container {
return pfh.ProtocolEditor.Representation
}
func (pfh *ProtocolFileHandler) Save() {
pfh.Changed = false
func (pfh *ProtocolFileHandler) Name() string {
return pfh.name
}
func (pfh *ProtocolFileHandler) GetWorkarea() *container.Scroll {
return container.NewVScroll(pfh.ProtocolEditor.Representation)
func (pfh *ProtocolFileHandler) Path() string {
return pfh.path
}
func (pfh *ProtocolFileHandler) Open(path string) error {
pfh.path = path
return pfh.Load()
}
func (pfh *ProtocolFileHandler) Save() error {
protocolctl.Save(pfh.Reference, pfh.path)
pfh.changed = false
return nil
}
func (pfh *ProtocolFileHandler) SaveAs(path string) error {
pfh.path = path
pfh.Save()
return nil
}
func (pfh *ProtocolFileHandler) Close() error {
return pfh.Save()
}
func (pfh *ProtocolFileHandler) SetChanged() {
pfh.changed = true
}
func (pfh *ProtocolFileHandler) HasChanged() bool {
return pfh.changed
}
func (pfh *ProtocolFileHandler) GetReference() interface{} {
return pfh.Reference
}