Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
80 changes: 73 additions & 7 deletions source/_magnifier/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"""

import config
from .utils.types import Filter, FullScreenMode
from dataclasses import dataclass, field
from .utils.types import Filter, FullScreenMode, MagnifierFollowFocusType


class ZoomLevel:
Expand Down Expand Up @@ -78,9 +79,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 +97,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 +118,77 @@ 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",
}


@dataclass
class _FollowStateOverride:
savedStates: dict[MagnifierFollowFocusType, bool] = field(default_factory=dict)
isActive: bool = False


_followStateOverride = _FollowStateOverride()


def _ensureSavedStatesInitialized() -> None:
"""
Populate _followStateOverride.savedStates from current config if not yet done.
Called lazily to avoid reading config.conf at module import time.
"""
if not _followStateOverride.savedStates:
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:
_followStateOverride.savedStates[focusType] = getFollowState(focusType)


def toggleAllFollowStates() -> bool:
"""
Toggle all follow states between forced-active and previously saved states.

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


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