mirror of
https://github.com/ankitects/anki.git
synced 2025-12-13 23:00:58 -05:00
Propagate editor UI state transitions to add-ons (#2711)
* Propagate editor UI state transitions to add-ons * Also set initial Python state to EditorState.INITIAL --------- Co-authored-by: Glutanimate <glutanimate@users.noreply.github.com>
This commit is contained in:
parent
9e147c6335
commit
7ce1c4439a
4 changed files with 89 additions and 0 deletions
|
|
@ -90,6 +90,18 @@ class EditorMode(Enum):
|
|||
BROWSER = 2
|
||||
|
||||
|
||||
class EditorState(Enum):
|
||||
"""
|
||||
Current input state of the editing UI.
|
||||
"""
|
||||
|
||||
INITIAL = -1
|
||||
FIELDS = 0
|
||||
IO_PICKER = 1
|
||||
IO_MASKS = 2
|
||||
IO_FIELDS = 3
|
||||
|
||||
|
||||
class Editor:
|
||||
"""The screen that embeds an editing widget should listen for changes via
|
||||
the `operation_did_execute` hook, and call set_note() when the editor needs
|
||||
|
|
@ -124,6 +136,7 @@ class Editor:
|
|||
self.last_field_index: int | None = None
|
||||
# current card, for card layout
|
||||
self.card: Card | None = None
|
||||
self.state: EditorState = EditorState.INITIAL
|
||||
self._init_links()
|
||||
self.setupOuter()
|
||||
self.add_webview()
|
||||
|
|
@ -474,6 +487,12 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
|||
collapsed = collapsed_string == "true"
|
||||
self.setTagsCollapsed(collapsed)
|
||||
|
||||
elif cmd.startswith("editorState"):
|
||||
(_, new_state_id, old_state_id) = cmd.split(":", 2)
|
||||
self.signal_state_change(
|
||||
EditorState(int(new_state_id)), EditorState(int(old_state_id))
|
||||
)
|
||||
|
||||
elif cmd in self._links:
|
||||
return self._links[cmd](self)
|
||||
|
||||
|
|
@ -483,6 +502,12 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
|||
def mungeHTML(self, txt: str) -> str:
|
||||
return gui_hooks.editor_will_munge_html(txt, self)
|
||||
|
||||
def signal_state_change(
|
||||
self, new_state: EditorState, old_state: EditorState
|
||||
) -> None:
|
||||
self.state = new_state
|
||||
gui_hooks.editor_state_did_change(self, new_state, old_state)
|
||||
|
||||
# Setting/unsetting the current note
|
||||
######################################################################
|
||||
|
||||
|
|
|
|||
|
|
@ -1152,6 +1152,16 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
|
|||
or by a right-click paste.
|
||||
""",
|
||||
),
|
||||
Hook(
|
||||
name="editor_state_did_change",
|
||||
args=[
|
||||
"editor: aqt.editor.Editor",
|
||||
"new_state: aqt.editor.EditorState",
|
||||
"old_state: aqt.editor.EditorState",
|
||||
],
|
||||
doc="""Called when the input state of the editor changes, e.g. when
|
||||
switching to an image occlusion note type.""",
|
||||
),
|
||||
# Tag
|
||||
###################
|
||||
Hook(name="tag_editor_did_process_key", args=["tag_edit: TagEdit", "evt: QEvent"]),
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import RichTextInput, { editingInputIsRichText } from "./rich-text-input";
|
||||
import RichTextBadge from "./RichTextBadge.svelte";
|
||||
import type { NotetypeIdAndModTime, SessionOptions } from "./types";
|
||||
import { EditorState } from "./types";
|
||||
|
||||
function quoteFontFamily(fontFamily: string): string {
|
||||
// generic families (e.g. sans-serif) must not be quoted
|
||||
|
|
@ -496,6 +497,44 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
return false;
|
||||
}
|
||||
|
||||
// Signal editor UI state changes to add-ons
|
||||
|
||||
let editorState: EditorState = EditorState.Initial;
|
||||
let lastEditorState: EditorState = editorState;
|
||||
|
||||
function getEditorState(
|
||||
ioMaskEditorVisible: boolean,
|
||||
isImageOcclusion: boolean,
|
||||
isIOImageLoaded: boolean,
|
||||
imageOcclusionMode: IOMode | undefined,
|
||||
): EditorState {
|
||||
if (isImageOcclusion && ioMaskEditorVisible && !isIOImageLoaded) {
|
||||
return EditorState.ImageOcclusionPicker;
|
||||
} else if (imageOcclusionMode && ioMaskEditorVisible) {
|
||||
return EditorState.ImageOcclusionMasks;
|
||||
} else if (!ioMaskEditorVisible && isImageOcclusion) {
|
||||
return EditorState.ImageOcclusionFields;
|
||||
}
|
||||
return EditorState.Fields;
|
||||
}
|
||||
|
||||
function signalEditorState(newState: EditorState) {
|
||||
tick().then(() => {
|
||||
globalThis.editorState = newState;
|
||||
bridgeCommand(`editorState:${newState}:${lastEditorState}`);
|
||||
lastEditorState = newState;
|
||||
});
|
||||
}
|
||||
|
||||
$: signalEditorState(editorState);
|
||||
|
||||
$: editorState = getEditorState(
|
||||
$ioMaskEditorVisible,
|
||||
isImageOcclusion,
|
||||
isIOImageLoaded,
|
||||
imageOcclusionMode,
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
function wrap(before: string, after: string): void {
|
||||
if (!$focusedInput || !editingInputIsRichText($focusedInput)) {
|
||||
|
|
@ -537,6 +576,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
...oldEditorAdapter,
|
||||
});
|
||||
|
||||
editorState = getEditorState(
|
||||
$ioMaskEditorVisible,
|
||||
isImageOcclusion,
|
||||
isIOImageLoaded,
|
||||
imageOcclusionMode,
|
||||
);
|
||||
|
||||
document.addEventListener("visibilitychange", saveOnPageHide);
|
||||
return () => document.removeEventListener("visibilitychange", saveOnPageHide);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,3 +19,11 @@ export type NotetypeIdAndModTime = {
|
|||
id: number;
|
||||
modTime: number;
|
||||
};
|
||||
|
||||
export enum EditorState {
|
||||
Initial = -1,
|
||||
Fields = 0,
|
||||
ImageOcclusionPicker = 1,
|
||||
ImageOcclusionMasks = 2,
|
||||
ImageOcclusionFields = 3,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue