Skip to content

Commit

Permalink
refactor/fix: Refactor/fix editors' status
Browse files Browse the repository at this point in the history
  • Loading branch information
ja-he committed Jul 1, 2024
1 parent ed95dfc commit 155c9e4
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 63 deletions.
27 changes: 22 additions & 5 deletions internal/control/edit/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,32 @@ type Editor interface {
type EditorStatus string

const (
// EditorInactive indicates that the editor is not active.
//
// In other words, the editor is not in the active chain.
EditorInactive EditorStatus = "inactive"

// EditorSelected here means that the editor is the one currently selected for
// editing within its parent, while its parent is either
// EditorSelected indicates that the editor is the one currently selected for
// editing within its parent, while its parent is focussed.
//
// In other words, the editor is not yet in the active chain but just beyond
// the end of it, and currently the "closest" to being added to the end of
// the chain, as only some sort of "confirm-selection" operation in the
// parent is now needed to focus this editor.
EditorSelected EditorStatus = "selected"

// EditorFocussed means that the editor is the one currently receiving input, i.e.
// that it is the "lowestmost" active editor.
// EditorFocussed indicates the editor is the editor that currently has focus
// and receives inputs.
//
// In other words, the editor is on the active chain and is the lowestmost on
// the chain, ie. the end of the chain.
EditorFocussed EditorStatus = "focussed"

EditorChildActive EditorStatus = "child-active"
// EditorDescendantActive indicates that an descendent of the editor (a child,
// grandchild, ...) is active.
//
// In other words, the editor is in the active chain but is not the end of
// the chain, ie. there is at least one lower editor on the chain (a
// descendant). The editor may be the beginning of the active chain.
EditorDescendantActive EditorStatus = "descendant-active"
)
100 changes: 45 additions & 55 deletions internal/control/edit/editors/composite_editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Composite struct {
fieldOrder []EditorID
inField bool

statusFn func() edit.EditorStatus
parent *Composite

id EditorID
quitCallback func()
Expand Down Expand Up @@ -93,29 +93,8 @@ func ConstructEditor(id string, obj any, extraSpec map[string]any, parentEditor
fields: make(map[EditorID]edit.Editor),
activeFieldID: "___unassigned", // NOTE: this must be done in the following
fieldOrder: nil, // NOTE: this must be done in the following
statusFn: func() edit.EditorStatus {
// if there is no parent editor we are the root, ergo we can assume to have focus
if parentEditor == nil {
return edit.EditorFocussed
}
parentStatus := parentEditor.GetStatus()
switch parentStatus {
case edit.EditorInactive, edit.EditorSelected:
return edit.EditorInactive
case edit.EditorChildActive, edit.EditorFocussed:
if parentEditor.activeFieldID == id {
if parentEditor.inField {
return edit.EditorFocussed
}
return edit.EditorSelected
}
return edit.EditorInactive
default:
log.Error().Msgf("invalid edit state found (%s) likely logic error", parentStatus)
return edit.EditorInactive
}
},
id: id,
id: id,
parent: parentEditor,
}

// go through all tags
Expand Down Expand Up @@ -159,31 +138,14 @@ func ConstructEditor(id string, obj any, extraSpec map[string]any, parentEditor
Name: editspec.ID,
Content: f.String(),
CursorPos: 0,
StatusFn: func() edit.EditorStatus {
editStatus := constructedCompositeEditor.GetStatus()
switch editStatus {
case edit.EditorInactive, edit.EditorSelected:
return edit.EditorInactive
case edit.EditorChildActive, edit.EditorFocussed:
if constructedCompositeEditor.activeFieldID == editspec.ID {
if constructedCompositeEditor.inField {
return edit.EditorFocussed
}
return edit.EditorSelected
}
return edit.EditorInactive
default:
log.Error().Msgf("invalid edit state found (%s) likely logic error", editStatus)
return edit.EditorInactive
}
},
QuitCallback: func() {
if constructedCompositeEditor.activeFieldID == editspec.ID {
constructedCompositeEditor.inField = false
}
},
Mode: input.TextEditModeNormal,
CommitFn: func(v string) { f.SetString(v) },
parent: constructedCompositeEditor,
}
case reflect.Struct:

Expand Down Expand Up @@ -231,6 +193,47 @@ func ConstructEditor(id string, obj any, extraSpec map[string]any, parentEditor
return constructedCompositeEditor, nil
}

// GetStatus informs on whether the editor is active and focussed.
//
// "active" here means that the editor is in use, i.e. the user is currently
// editing within the editor.
// "focussed" means that the editor is the one currently receiving input,
// i.e. that it is the "lowestmost" active editor.
//
// E.g. when there is merely a single string editor, it must be active and
// focused.
// E.g. when there is a composite editor it must be active but the focus may
// lie with it or with a child editor.
func (e *Composite) GetStatus() edit.EditorStatus {
parentEditor := e.parent
// if there is no parent editor we are the root, ergo we can assume to have focus
if parentEditor == nil {
if e.inField {
return edit.EditorDescendantActive
}
return edit.EditorFocussed
}
parentStatus := parentEditor.GetStatus()
switch parentStatus {
case edit.EditorInactive, edit.EditorSelected:
return edit.EditorInactive
case edit.EditorDescendantActive, edit.EditorFocussed:
if parentEditor.activeFieldID == e.id {
if parentEditor.inField {
if e.inField {
return edit.EditorDescendantActive
}
return edit.EditorFocussed
}
return edit.EditorSelected
}
return edit.EditorInactive
default:
log.Error().Msgf("invalid edit state found (%s) likely logic error", parentStatus)
return edit.EditorInactive
}
}

type dpedit struct {
ID string
Ignore bool
Expand Down Expand Up @@ -304,19 +307,6 @@ func (e *Composite) GetActiveFieldID() EditorID { return e.activeFieldID }
// IsInField informs on whether the editor is currently in a field.
func (e *Composite) IsInField() bool { return e.inField }

// GetStatus informs on whether the editor is active and focussed.
//
// "active" here means that the editor is in use, i.e. the user is currently
// editing within the editor.
// "focussed" means that the editor is the one currently receiving input,
// i.e. that it is the "lowestmost" active editor.
//
// E.g. when there is merely a single string editor, it must be active and
// focused.
// E.g. when there is a composite editor it must be active but the focus may
// lie with it or with a child editor.
func (e *Composite) GetStatus() edit.EditorStatus { return e.statusFn() }

// GetFields returns the subeditors of this composite editor.
//
// TOOD: should this exist / be public (what is it good for)?
Expand Down
25 changes: 24 additions & 1 deletion internal/control/edit/editors/string_editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type StringEditor struct {
Mode input.TextEditMode
StatusFn func() edit.EditorStatus

parent *Composite

QuitCallback func()

CommitFn func(string)
Expand All @@ -49,7 +51,28 @@ type StringEditor struct {
func (e *StringEditor) GetType() string { return "string" }

// GetStatus ...
func (e StringEditor) GetStatus() edit.EditorStatus { return e.StatusFn() }
func (e StringEditor) GetStatus() edit.EditorStatus {
if e.parent == nil {
return edit.EditorFocussed
}

parentEditorStatus := e.parent.GetStatus()
switch parentEditorStatus {
case edit.EditorInactive, edit.EditorSelected:
return edit.EditorInactive
case edit.EditorDescendantActive, edit.EditorFocussed:
if e.parent.activeFieldID == e.Name {
if e.parent.inField {
return edit.EditorFocussed
}
return edit.EditorSelected
}
return edit.EditorInactive
default:
log.Error().Msgf("invalid edit state found (%s) likely logic error", parentEditorStatus)
return edit.EditorInactive
}
}

// GetName returns the name of the editor.
func (e StringEditor) GetName() string { return e.Name }
Expand Down
2 changes: 1 addition & 1 deletion internal/ui/panes/composite_editor_ui_pane.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (p *CompositeEditorPane) Draw() {
status := p.e.GetStatus()
c := '?'
switch status {
case edit.EditorChildActive:
case edit.EditorDescendantActive:
c = '.'
case edit.EditorFocussed:
c = '*'
Expand Down
2 changes: 1 addition & 1 deletion internal/ui/panes/string_editor_ui_pane.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (p *StringEditorPane) Draw() {
status := p.e.GetStatus()
c := '?'
switch status {
case edit.EditorChildActive:
case edit.EditorDescendantActive:
c = '.'
case edit.EditorFocussed:
c = '*'
Expand Down

0 comments on commit 155c9e4

Please sign in to comment.