Skip to content
Open
66 changes: 66 additions & 0 deletions source/_magnifier/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
getDefaultFilter,
getDefaultFullscreenMode,
ZoomLevel,
getFollowState,
setFollowState,
toggleAllFollowStates,
)
from .magnifier import Magnifier
from .fullscreenMagnifier import FullScreenMagnifier
Expand All @@ -25,6 +28,7 @@
MagnifierType,
FullScreenMode,
MagnifierAction,
MagnifierFollowFocusType,
)
from logHandler import log

Expand Down Expand Up @@ -175,6 +179,68 @@ def toggleFilter() -> None:
)


def toggleFollow(focusType: MagnifierFollowFocusType) -> None:
"""
Toggle the specified follow mode setting and update focus immediately.
:param focusType: The follow mode to toggle (mouse, system focus, review cursor, navigator object)
"""
magnifier: Magnifier = getMagnifier()
if magnifierIsActiveVerify(
magnifier,
MagnifierAction.TOGGLE_FOLLOW_SETTINGS,
):
state = not getFollowState(focusType)
setFollowState(focusType, state)

magnifier._focusManager.updateFollowedFocus()

ui.message(
pgettext(
"magnifier",
# Translators: Message announced when toggling a follow setting with {setting} being the name of the setting and {state} being either "enabled" or "disabled".
"{setting} {state}",
).format(
setting=focusType.displayString,
state=pgettext(
"magnifier",
# Translators: State of the follow setting being toggled enabled.
"enabled",
)
if state
else pgettext(
"magnifier",
# Translators: State of the follow setting being toggled disabled.
"disabled",
),
),
)


def toggleAllFollow() -> None:
"""Toggle all follow settings at once and update focus immediately"""
magnifier: Magnifier = getMagnifier()
if magnifierIsActiveVerify(
magnifier,
MagnifierAction.TOGGLE_FOLLOW_SETTINGS,
):
isActiveNow = toggleAllFollowStates()
magnifier._focusManager.updateFollowedFocus()
if not isActiveNow:
stateMessage = pgettext(
"magnifier",
# Translators: State of all follow settings being toggled disabled.
"All follow settings disabled",
)
else:
stateMessage = pgettext(
"magnifier",
# Translators: State of all follow settings being toggled enabled.
"All follow settings enabled",
)
ui.message(stateMessage)


def toggleFullscreenMode() -> None:
"""Cycle through full-screen focus modes (center, border, relative)"""
magnifier: Magnifier = getMagnifier()
Expand Down
75 changes: 68 additions & 7 deletions source/_magnifier/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""

import config
from .utils.types import Filter, FullScreenMode
from .utils.types import Filter, FullScreenMode, MagnifierFollowFocusType


class ZoomLevel:
Expand Down Expand Up @@ -78,9 +78,6 @@ def setDefaultZoomLevel(zoomLevel: float) -> None:

:param zoomLevel: The zoom level to set.
"""

if "magnifier" not in config.conf:
config.conf["magnifier"] = {}
config.conf["magnifier"]["defaultZoomLevel"] = zoomLevel


Expand All @@ -99,9 +96,6 @@ def setDefaultPanStep(panStep: int) -> None:

:param panStep: The pan value to set.
"""

if "magnifier" not in config.conf:
config.conf["magnifier"] = {}
config.conf["magnifier"]["defaultPanStep"] = panStep


Expand All @@ -123,6 +117,73 @@ def setDefaultFilter(filter: Filter) -> None:
config.conf["magnifier"]["defaultFilter"] = filter.value


_FOLLOW_CONFIG_KEYS: dict[MagnifierFollowFocusType, str] = {
MagnifierFollowFocusType.MOUSE: "followMouse",
MagnifierFollowFocusType.SYSTEM_FOCUS: "followSystemFocus",
MagnifierFollowFocusType.REVIEW: "followReviewCursor",
MagnifierFollowFocusType.NAVIGATOR_OBJECT: "followNavigatorObject",
}

_savedFollowStates: dict[MagnifierFollowFocusType, bool] = {}

_allFollowStatesForcedActive = False


def _ensureSavedStatesInitialized() -> None:
"""
Populate _savedFollowStates from current config if not yet done.
Called lazily to avoid reading config.conf at module import time.
"""
if not _savedFollowStates:
saveFollowStates()


def getFollowState(focusType: MagnifierFollowFocusType) -> bool:
"""
Get the current follow state for a given focus type.

:param focusType: The focus type to query.
:return: True if the magnifier follows the given focus type, False otherwise.
"""
return config.conf["magnifier"][_FOLLOW_CONFIG_KEYS[focusType]]


def setFollowState(focusType: MagnifierFollowFocusType, state: bool) -> None:
"""
Set the follow state for a given focus type.

:param focusType: The focus type to update.
:param state: True to enable following, False to disable.
"""
config.conf["magnifier"][_FOLLOW_CONFIG_KEYS[focusType]] = state


def saveFollowStates() -> None:
"""Save current follow states so they can be restored later."""
for focusType in _FOLLOW_CONFIG_KEYS:
_savedFollowStates[focusType] = getFollowState(focusType)


def toggleAllFollowStates() -> bool:
"""
Toggle all follow states between forced-active and previously saved states.
Comment thread
seanbudd marked this conversation as resolved.
Outdated

:return: True when all follow states are forced active after the call, False when restored.
"""
global _allFollowStatesForcedActive
_ensureSavedStatesInitialized()
if _allFollowStatesForcedActive:
for focusType, state in _savedFollowStates.items():
setFollowState(focusType, state)
_allFollowStatesForcedActive = False
else:
saveFollowStates()
for focusType in _FOLLOW_CONFIG_KEYS:
setFollowState(focusType, True)
_allFollowStatesForcedActive = True
return _allFollowStatesForcedActive


def getDefaultFullscreenMode() -> FullScreenMode:
"""
Get default full-screen mode from config.
Expand Down
Loading
Loading