package controller import ( "github.com/boolean-maybe/tiki/model" "github.com/boolean-maybe/tiki/store" "github.com/rivo/tview" ) // View and ViewFactory interfaces decouple controllers from view implementations. // FocusSettable is implemented by views that need focus management for their subcomponents. // This is used to wire up tview focus changes when the view needs to transfer focus to // different primitives (e.g., edit fields, select lists). type FocusSettable interface { SetFocusSetter(setter func(p tview.Primitive)) } // View represents a renderable view with its action registry type View interface { // GetPrimitive returns the tview primitive for this view GetPrimitive() tview.Primitive // GetActionRegistry returns the actions available in this view GetActionRegistry() *ActionRegistry // GetViewID returns the identifier for this view type GetViewID() model.ViewID // OnFocus is called when the view becomes active OnFocus() // OnBlur is called when the view becomes inactive OnBlur() } // ViewFactory creates views on demand type ViewFactory interface { // CreateView instantiates a view by ID with optional parameters CreateView(viewID model.ViewID, params map[string]interface{}) View } // SelectableView is a view that tracks selection state type SelectableView interface { View // GetSelectedID returns the ID of the currently selected item GetSelectedID() string // SetSelectedID sets the selection to a specific item SetSelectedID(id string) } // InputSubmitResult controls what happens to the input box after a submit callback. type InputSubmitResult int const ( InputKeepEditing InputSubmitResult = iota // keep the box open and focused for correction InputShowPassive // keep the box visible but unfocused/non-editable InputClose // close/hide the box ) // InputableView is a view that supports an input box (for search, action input, etc.) type InputableView interface { View // ShowInputBox displays the input box for action-input mode. // If search is passive, it temporarily replaces the search indicator. ShowInputBox(prompt, initial string) tview.Primitive // ShowSearchBox opens the input box in search-editing mode. ShowSearchBox() tview.Primitive // HideInputBox hides the input box (generic widget teardown only, no search state) HideInputBox() // CancelInputBox triggers mode-aware cancel (search clears results, action-input restores passive search) CancelInputBox() // IsInputBoxVisible returns whether the input box is currently visible (any mode) IsInputBoxVisible() bool // IsInputBoxFocused returns whether the input box currently has focus IsInputBoxFocused() bool // IsSearchPassive returns true if search is applied and the box is in passive/unfocused mode IsSearchPassive() bool // SetInputSubmitHandler sets the callback for when input is submitted SetInputSubmitHandler(handler func(text string) InputSubmitResult) // SetInputCancelHandler sets the callback for when input is cancelled SetInputCancelHandler(handler func()) // SetFocusSetter sets the callback for requesting focus changes SetFocusSetter(setter func(p tview.Primitive)) } // FullscreenView is a view that can toggle fullscreen rendering type FullscreenView interface { View // EnterFullscreen switches the view into fullscreen mode EnterFullscreen() // ExitFullscreen returns the view to its normal layout ExitFullscreen() // IsFullscreen reports whether the view is currently fullscreen IsFullscreen() bool } // FullscreenChangeNotifier is a view that notifies when fullscreen state changes type FullscreenChangeNotifier interface { // SetFullscreenChangeHandler sets the callback for when fullscreen state changes SetFullscreenChangeHandler(handler func(isFullscreen bool)) } // DescriptionEditableView is a view that supports description editing functionality type DescriptionEditableView interface { View // ShowDescriptionEditor displays the description text area and returns the primitive to focus ShowDescriptionEditor() tview.Primitive // HideDescriptionEditor hides the description text area HideDescriptionEditor() // IsDescriptionEditing returns whether the description is currently being edited IsDescriptionEditing() bool // IsDescriptionTextAreaFocused returns whether the description text area currently has focus IsDescriptionTextAreaFocused() bool // SetDescriptionSaveHandler sets the callback for when description is saved SetDescriptionSaveHandler(handler func(string)) // SetDescriptionCancelHandler sets the callback for when description editing is cancelled SetDescriptionCancelHandler(handler func()) // SetFocusSetter sets the callback for requesting focus changes SetFocusSetter(setter func(p tview.Primitive)) } // TitleEditableView is a view that supports title editing functionality type TitleEditableView interface { View // ShowTitleEditor displays the title input field and returns the primitive to focus ShowTitleEditor() tview.Primitive // HideTitleEditor hides the title input field HideTitleEditor() // IsTitleEditing returns whether the title is currently being edited IsTitleEditing() bool // IsTitleInputFocused returns whether the title input currently has focus IsTitleInputFocused() bool // SetTitleSaveHandler sets the callback for when title is saved (explicit save via Enter) SetTitleSaveHandler(handler func(string)) // SetTitleChangeHandler sets the callback for when title changes (auto-save on keystroke) SetTitleChangeHandler(handler func(string)) // SetTitleCancelHandler sets the callback for when title editing is cancelled SetTitleCancelHandler(handler func()) // SetFocusSetter sets the callback for requesting focus changes SetFocusSetter(setter func(p tview.Primitive)) } // TaskEditView exposes edited task fields for save operations type TaskEditView interface { View // GetEditedTitle returns the current title text in the editor GetEditedTitle() string // GetEditedDescription returns the current description text in the editor GetEditedDescription() string // GetEditedTags returns the current tags from the tags editor GetEditedTags() []string } // TagsEditableView is a view that supports tags editing functionality type TagsEditableView interface { View // ShowTagsEditor displays the tags text area and returns the primitive to focus ShowTagsEditor() tview.Primitive // SetTagsSaveHandler sets the callback for when tags are saved SetTagsSaveHandler(handler func(string)) // SetTagsCancelHandler sets the callback for when tags editing is cancelled SetTagsCancelHandler(handler func()) } // FieldFocusableView is a view that supports field-level focus in edit mode type FieldFocusableView interface { View // SetFocusedField changes the focused field and re-renders SetFocusedField(field model.EditField) // GetFocusedField returns the currently focused field GetFocusedField() model.EditField // FocusNextField advances to the next field in edit order FocusNextField() bool // FocusPrevField moves to the previous field in edit order FocusPrevField() bool // IsEditFieldFocused returns whether any editable field has tview focus IsEditFieldFocused() bool } // ValueCyclableView is a view that supports cycling through field values with arrow keys type ValueCyclableView interface { View // CycleFieldValueUp cycles the currently focused field's value upward CycleFieldValueUp() bool // CycleFieldValueDown cycles the currently focused field's value downward CycleFieldValueDown() bool } // StatusEditableView is a view that supports status editing functionality type StatusEditableView interface { View // SetStatusSaveHandler sets the callback for when status is saved SetStatusSaveHandler(handler func(string)) } // TypeEditableView is a view that supports type editing functionality type TypeEditableView interface { View // SetTypeSaveHandler sets the callback for when type is saved SetTypeSaveHandler(handler func(string)) } // PriorityEditableView is a view that supports priority editing functionality type PriorityEditableView interface { View // SetPrioritySaveHandler sets the callback for when priority is saved SetPrioritySaveHandler(handler func(int)) } // AssigneeEditableView is a view that supports assignee editing functionality type AssigneeEditableView interface { View // SetAssigneeSaveHandler sets the callback for when assignee is saved SetAssigneeSaveHandler(handler func(string)) } // PointsEditableView is a view that supports story points editing functionality type PointsEditableView interface { View // SetPointsSaveHandler sets the callback for when story points is saved SetPointsSaveHandler(handler func(int)) } // DueEditableView is a view that supports due date editing functionality type DueEditableView interface { View // SetDueSaveHandler sets the callback for when due date is saved SetDueSaveHandler(handler func(string)) } // RecurrenceEditableView is a view that supports recurrence editing functionality type RecurrenceEditableView interface { View // SetRecurrenceSaveHandler sets the callback for when recurrence is saved SetRecurrenceSaveHandler(handler func(string)) } // RecurrencePartNavigable is a view that supports Left/Right navigation between // the two logical parts of a recurrence field (frequency and value). type RecurrencePartNavigable interface { MoveRecurrencePartLeft() bool MoveRecurrencePartRight() bool IsRecurrenceValueFocused() bool } // PaletteActionHandler is implemented by views that handle palette-dispatched actions // directly (e.g., DokiView replays navigation as synthetic key events). // The palette tries this before falling back to InputRouter.HandleAction. type PaletteActionHandler interface { HandlePaletteAction(id ActionID) bool } // FocusRestorer is implemented by views that can recover focus after the palette closes // when the originally saved focused primitive is no longer valid (e.g., TaskDetailView // rebuilds its description primitive during store-driven refresh). type FocusRestorer interface { RestoreFocus() bool } // ActionChangeNotifier is implemented by views that mutate their action registry // or live enablement/presentation state while the same view instance stays active. // RootLayout wires the handler and reruns syncViewContextFromView when fired. type ActionChangeNotifier interface { SetActionChangeHandler(handler func()) } // ViewInfoProvider is a view that provides its name and description for the header info section type ViewInfoProvider interface { GetViewName() string GetViewDescription() string } // StatsProvider is a view that provides statistics for the statusline type StatsProvider interface { // GetStats returns stats to display in the statusline for this view GetStats() []store.Stat } // NavigationProvider is implemented by views that declare whether plugin // navigation keys should be shown in the header when this view is active. type NavigationProvider interface { ShowNavigation() bool }