First protocol editor interface prototype working

This commit is contained in:
Marcel M. Otte 2023-01-04 13:38:16 +01:00
parent 6b310e4b89
commit b8c3d7f856
8 changed files with 148 additions and 30 deletions

View File

@ -9,6 +9,7 @@ import (
"fyne.io/fyne/v2/widget"
"gitea.mmo.to/ProtocolPacketForger/ppf/internal/ui"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocol"
)
var fyneApp fyne.App
@ -17,7 +18,7 @@ var w fyne.Window
func Appmain() {
fyneApp = app.New()
w = fyneApp.NewWindow("ProtocolPacketForger")
w.Resize(fyne.NewSize(800, 600))
w.Resize(fyne.NewSize(1024, 768))
w.SetContent(CreateApp())
@ -27,14 +28,14 @@ func Appmain() {
type ppfApp struct {
// Container for the borderlayout
Toolbar fyne.CanvasObject
Metadata *fyne.Container
Metadata *Metadata
Extensions *fyne.Container
ContextBar *fyne.Container
ContentTabs *fyne.Container
Workarea *fyne.Container
// Once initialized metadata containers for swapping
ProtocolMeta *fyne.Container
PacketMeta *fyne.Container
ProtocolMeta *ProtocolMetadata
PacketMeta *PacketMetadata
// Global important stuff
Settings map[string]string
ProtocolForging bool
@ -45,17 +46,32 @@ type ppfApp struct {
var ppf ppfApp
type Metadata struct {
Representation *fyne.Container
}
type PacketMetadata struct {
Metadata
}
type ProtocolMetadata struct {
Metadata
NameValue *widget.Entry
VersionValue *widget.Entry
ExtendsValue *widget.Entry
DescValue *widget.Entry
}
func CreateApp() *fyne.Container {
ppf.Toolbar = CreateToolbar()
ppf.Workarea = CreateWorkarea()
ppf.Extensions = container.NewCenter()
ppf.Metadata = container.NewCenter()
ppf.ProtocolMeta = CreateMetadataProtocol()
ppf.ContextBar = container.NewCenter()
return container.NewBorder(
ppf.Toolbar,
ppf.Metadata,
ppf.ContextBar,
ppf.Metadata.Representation,
ppf.Extensions,
container.NewVScroll(ppf.Workarea),
)
@ -92,7 +108,8 @@ func CreateWorkarea() *fyne.Container {
return ui.GetProtocolEditor().Representation
}
func CreateMetadataProtocol() *fyne.Container {
func CreateMetadataProtocol() *ProtocolMetadata {
md := ProtocolMetadata{}
vbox := container.NewVBox()
vbox.Add(widget.NewLabel("Protocol Metadata"))
form := container.New(layout.NewFormLayout())
@ -107,11 +124,12 @@ func CreateMetadataProtocol() *fyne.Container {
multiline := widget.NewMultiLineEntry()
multiline.SetMinRowsVisible(3)
vbox.Add(multiline)
return vbox
md.Representation = vbox
return &md
}
func CreateMetadataPacket() *fyne.Container {
func CreateMetadataPacket() *PacketMetadata {
md := PacketMetadata{}
vbox := container.NewVBox()
vbox.Add(widget.NewLabel("Packet Metadata"))
form := container.New(layout.NewFormLayout())
@ -122,5 +140,9 @@ func CreateMetadataPacket() *fyne.Container {
multiline := widget.NewMultiLineEntry()
multiline.SetMinRowsVisible(3)
vbox.Add(multiline)
return vbox
return &md
}
func UpdateProtocolMetadata(prot *protocol.ProtocolStructure) {
// md := ppfApp.ProtocolMeta
}

View File

@ -2,11 +2,14 @@ package ui
import (
"fyne.io/fyne/v2/widget"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocolctl"
)
func GetAdder(pEd *ProtocolEditor) *widget.Button {
fieldAdder := widget.NewButton("Add Field", func() {
pEd.AddFieldCreator(CreateFieldEditor())
f := protocolctl.NewEmptyField()
index := protocolctl.AppendField(pEd.Reference, f)
pEd.AddFieldCreator(CreateFieldEditor(pEd, index, f))
})
return fieldAdder
}

View File

@ -1,11 +1,16 @@
package ui
import (
"fmt"
"strconv"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocol"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocolctl"
)
type FieldEditor struct {
@ -16,30 +21,72 @@ type FieldEditor struct {
SizeLabel *widget.Label
SizeValue *widget.Entry
SizeInBits bool
OptionalCheck *widget.Check
PayloadCheck *widget.Check
// to be filled with needed things
Reference *protocol.Field
Index int
}
func CreateFieldEditor() *FieldEditor {
func CreateFieldEditor(ed *ProtocolEditor, index int, ref *protocol.Field) *FieldEditor {
fc := &FieldEditor{}
fc.Reference = ref
fc.Index = index
setfunc := func(s string) {
bits := 0
if !fc.SizeInBits {
bits, _ = strconv.Atoi(fc.SizeValue.Text)
bits *= 8
} else {
bits, _ = strconv.Atoi(fc.SizeValue.Text)
}
protocolctl.UpdateFieldByElement(
ed.Reference,
fc.Index,
protocolctl.NewField(
fc.NameValue.Text,
fc.DescValue.Text,
fc.RegExValue.Text,
bits,
nil, //TODO: implement subfields
fc.OptionalCheck.Checked,
fc.PayloadCheck.Checked,
),
)
fmt.Printf("%s", protocolctl.ToJson(ed.Reference))
}
fc.Representation = container.New(layout.NewFormLayout())
fc.Representation.Add(widget.NewLabel(""))
fc.Representation.Add(widget.NewLabel("Field Values"))
toolbar := widget.NewToolbar()
toolbar.Append(widget.NewToolbarAction(theme.DeleteIcon(), func() {
protocolctl.RemoveFieldByElement(ed.Reference, fc.Index)
ed.Redraw()
}))
fc.Representation.Add(toolbar)
addtool := widget.NewToolbar()
addtool.Append(widget.NewToolbarSpacer())
addtool.Append(widget.NewToolbarAction(theme.ContentAddIcon(), func() {
protocolctl.AddField(ed.Reference, fc.Index+1, protocolctl.NewEmptyField())
ed.Redraw()
}))
fc.Representation.Add(container.NewBorder(nil, nil, nil, addtool, widget.NewLabel("Field Values")))
fc.Representation.Add(widget.NewLabel("Name"))
fc.NameValue = widget.NewEntry()
fc.NameValue.OnChanged = setfunc
fc.Representation.Add(fc.NameValue)
fc.Representation.Add(widget.NewLabel("Description"))
fc.DescValue = widget.NewEntry()
fc.DescValue.MultiLine = true
fc.DescValue.OnChanged = setfunc
fc.DescValue.SetMinRowsVisible(3)
fc.Representation.Add(fc.DescValue)
fc.Representation.Add(widget.NewLabel("RegEx"))
fc.RegExValue = widget.NewEntry()
fc.RegExValue.OnChanged = setfunc
fc.Representation.Add(fc.RegExValue)
fc.SizeLabel = widget.NewLabel("Bytes")
@ -51,9 +98,31 @@ func CreateFieldEditor() *FieldEditor {
fc.SizeLabel.SetText("Bits")
}
fc.SizeInBits = !fc.SizeInBits
setfunc("") // bogus call to reflect the change
})
fc.Representation.Add(container.NewHBox(toggleBtn, fc.SizeLabel))
fc.SizeValue = widget.NewEntry()
fc.SizeValue.OnChanged = setfunc
fc.Representation.Add(fc.SizeValue)
fc.Representation.Add(widget.NewLabel("Settings"))
fc.OptionalCheck = widget.NewCheck("Optional", func(b bool) {
fc.Reference.Optional = b
setfunc("")
})
fc.PayloadCheck = widget.NewCheck("Payload", func(b bool) {
fc.Reference.Payload = b
setfunc("")
})
fc.Representation.Add(container.NewHBox(fc.OptionalCheck, fc.PayloadCheck))
fc.NameValue.Text = fc.Reference.Name
fc.DescValue.Text = fc.Reference.Desc
fc.RegExValue.Text = fc.Reference.Regex
fc.SizeValue.Text = strconv.Itoa(fc.Reference.Size)
fc.SizeInBits = true
fc.SizeLabel.SetText("Bits")
fc.OptionalCheck.Checked = fc.Reference.Optional
fc.PayloadCheck.Checked = fc.Reference.Payload
fc.Representation.Refresh()
return fc
}

View File

@ -1,6 +1,8 @@
package ui
import (
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"gitea.mmo.to/ProtocolPacketForger/ppf/protocol"
@ -15,7 +17,7 @@ type ProtocolEditor struct {
}
func GetProtocolEditor() *ProtocolEditor {
container := container.NewGridWrap(fyne.NewSize(300, 300))
container := container.NewGridWrap(fyne.NewSize(300, 400))
protocolEditor := &ProtocolEditor{container, []*FieldEditor{}, protocolctl.NewProtocolStructure()}
container.Add(GetAdder(protocolEditor))
return protocolEditor
@ -27,9 +29,13 @@ func (ed *ProtocolEditor) AddFieldCreator(fieldCreator *FieldEditor) {
}
func (ed *ProtocolEditor) Redraw() {
json := protocolctl.ToJson(ed.Reference)
fmt.Printf("%s", json)
ed.Representation.RemoveAll()
for _, v := range ed.Fields {
ed.Representation.Add(v.Representation)
for i, v := range ed.Reference.Structure {
ed.Representation.Add(CreateFieldEditor(ed, i, v).Representation)
}
if len(ed.Reference.Structure) == 0 {
ed.Representation.Add(GetAdder(ed))
}
}

View File

@ -6,7 +6,7 @@ type Field struct {
Name string // Name of the Field
Desc string // Lengthy description
Regex string // Regex to recognize values
Size uint // Size in bits!
Size int // Size in bits!
SubFields []Field // Possible sub-fields
Optional bool // Is this field required?
Payload bool // Is this field the payload or next protocol level?

View File

@ -2,7 +2,7 @@ package protocol
type ProtocolStructure struct {
Metadata DOPMeta
Structure []Field
Structure []*Field
DefaultValues []DefaultValue
JavaScript string
}

View File

@ -34,11 +34,16 @@ func UpdateMetaData(
prot.Metadata.LowerLayerIdentification = lowerLayerIdent
}
func NewEmptyField() *protocol.Field {
f := protocol.Field{}
return &f
}
func NewField(
name string,
desc string,
regex string,
size uint,
size int,
subfields []protocol.Field,
optional bool,
payload bool,
@ -55,8 +60,21 @@ func NewField(
return &f
}
func AppendField(prot *protocol.ProtocolStructure, field *protocol.Field) {
prot.Structure = append(prot.Structure, *field)
func AppendField(prot *protocol.ProtocolStructure, field *protocol.Field) int {
i := len(prot.Structure)
prot.Structure = append(prot.Structure, field)
return i
}
func AddField(prot *protocol.ProtocolStructure, index int, field *protocol.Field) {
if len(prot.Structure) == index {
AppendField(prot, field)
return
}
ret := make([]*protocol.Field, 0)
ret = append(ret, prot.Structure[:index]...)
ret = append(ret, field)
ret = append(ret, prot.Structure[index:]...)
prot.Structure = ret
}
func UpdateFieldByName(prot *protocol.ProtocolStructure, name string, field *protocol.Field) {
@ -67,12 +85,12 @@ func UpdateFieldByName(prot *protocol.ProtocolStructure, name string, field *pro
}
}
if fnd != -1 {
prot.Structure[fnd] = *field
prot.Structure[fnd] = field
}
}
func UpdateFieldByElement(prot *protocol.ProtocolStructure, element int, field *protocol.Field) {
prot.Structure[element] = *field
prot.Structure[element] = field
}
func RemoveFieldByName(prot *protocol.ProtocolStructure, name string) {
@ -89,7 +107,7 @@ func RemoveFieldByName(prot *protocol.ProtocolStructure, name string) {
}
func RemoveFieldByElement(prot *protocol.ProtocolStructure, field int) {
ret := make([]protocol.Field, 0)
ret := make([]*protocol.Field, 0)
ret = append(ret, prot.Structure[:field]...)
ret = append(ret, prot.Structure[field+1:]...)
prot.Structure = ret
@ -111,7 +129,7 @@ func LoadNew(path string) (*protocol.ProtocolStructure, error) {
}
func ToJson(prot *protocol.ProtocolStructure) string {
data, err := json.Marshal(*prot)
data, err := json.MarshalIndent(*prot, "", " ")
if err != nil {
return ""
}
@ -119,7 +137,7 @@ func ToJson(prot *protocol.ProtocolStructure) string {
}
func Save(prot *protocol.ProtocolStructure, path string) error {
data, err := json.Marshal(*prot)
data, err := json.MarshalIndent(*prot, "", " ")
if err != nil {
return err
}

View File

@ -49,7 +49,7 @@ func GenerateFields() []protocol.Field {
fmt.Sprintf("testfield%d", i),
fmt.Sprintf("Description %d", i),
"",
uint(i*8),
int(i*8),
nil,
false,
false,