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

1"""マウスの 7 つのモードのツール(gui/tools/*.py)と、PlotterApp にツールの名前を出す窓口。 

2 

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 

14 

15__all__ = ["MOUSE_MODES", "MOUSE_MODES_BY_NAME", "MouseMode", "ToolManager", "TOOL_CLASSES", "create_tools", 

16 "expose_tool_names"] 

17 

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} 

28 

29 

30def create_tools(app): 

31 return {key: tool_class(app) for key, tool_class in TOOL_CLASSES.items()} 

32 

33 

34class _ToolName: 

35 """PlotterApp の属性として、ツールの同じ名前の属性を読み書きする。""" 

36 

37 def __init__(self, tool_key, name): 

38 self._tool_key = tool_key 

39 self._name = name 

40 

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) 

46 

47 def __set__(self, app, value): 

48 setattr(app.mouse_tools[self._tool_key], self._name, value) 

49 

50 

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))