Coverage for graphica/gui/tools/__init__.py: 88.9%
28 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
1"""マウスの 7 つのモードのツール(gui/tools/*.py)と、PlotterApp にツールの名前を出す窓口。
3ツールは状態を自分で持つ。PlotterApp は各ツールの EXPOSED_NAMES を同じ名前の属性として出し、読み書きをツールへ回す
4(テスト・メニュー・ほかの mixin が今までの名前で使うため。monkeypatch もツールに届く)。
5"""
6from graphica.gui.tools.annotation import AnnotationTool
7from graphica.gui.tools.cursor import CursorTool
8from graphica.gui.tools.layout_edit import LayoutEditTool
9from graphica.gui.tools.manager import MOUSE_MODES, MOUSE_MODES_BY_NAME, MouseMode, ToolManager
10from graphica.gui.tools.peak_placement import PeakPlacementTool
11from graphica.gui.tools.range_select import RangeSelectTool
12from graphica.gui.tools.region_highlight import RegionHighlightTool
13from graphica.gui.tools.slice_extraction import SliceExtractionTool
15__all__ = ["MOUSE_MODES", "MOUSE_MODES_BY_NAME", "MouseMode", "ToolManager", "TOOL_CLASSES", "create_tools",
16 "expose_tool_names"]
18# キーは MOUSE_MODES の name と同じ
19TOOL_CLASSES = {
20 "cursor": CursorTool,
21 "annotation": AnnotationTool,
22 "layout_edit": LayoutEditTool,
23 "range_select": RangeSelectTool,
24 "peak_placement": PeakPlacementTool,
25 "slice_extraction": SliceExtractionTool,
26 "region_highlight": RegionHighlightTool,
27}
30def create_tools(app):
31 return {key: tool_class(app) for key, tool_class in TOOL_CLASSES.items()}
34class _ToolName:
35 """PlotterApp の属性として、ツールの同じ名前の属性を読み書きする。"""
37 def __init__(self, tool_key, name):
38 self._tool_key = tool_key
39 self._name = name
41 def __get__(self, app, owner=None):
42 if app is None: 42 ↛ 44line 42 didn't jump to line 44 because the condition on line 42 was never true
43 # クラスから引いたとき(メニューの表の検査など)は、ツールのクラスの同じ名前を返す
44 return getattr(TOOL_CLASSES[self._tool_key], self._name, self)
45 return getattr(app.mouse_tools[self._tool_key], self._name)
47 def __set__(self, app, value):
48 setattr(app.mouse_tools[self._tool_key], self._name, value)
51def expose_tool_names(app_class):
52 for key, tool_class in TOOL_CLASSES.items():
53 for name in tool_class.EXPOSED_NAMES:
54 if any(name in klass.__dict__ for klass in app_class.__mro__): 54 ↛ 55line 54 didn't jump to line 55 because the condition on line 54 was never true
55 raise TypeError(f"{app_class.__name__}.{name} はツール {key} の名前とぶつかる")
56 setattr(app_class, name, _ToolName(key, name))