Coverage for graphica/gui/tools/pointer.py: 82.6%
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"""マウスのモードが共通に使う、マウス位置の扱い。"""
4def legend_at(canvas, event):
5 """event の位置にある凡例(どのサブプロットの、主・第2のどちらの軸のものでも)。無ければ None。
7 凡例はモードが無くてもドラッグで動かせるので、凡例の上で押した操作はモードの側で使わない。
8 """
9 if event.x is None or event.y is None: 9 ↛ 10line 9 didn't jump to line 10 because the condition on line 9 was never true
10 return None
11 secondary_axes = getattr(canvas, 'all_secondary_axes', [])
12 for ax in list(getattr(canvas, 'all_axes', [])) + [ax for ax in secondary_axes if ax is not None]:
13 legend = ax.get_legend()
14 if legend is not None and legend.get_visible() and legend.contains(event)[0]:
15 return legend
16 return None
19def clamped_data_point(ax, event):
20 """event の位置を ax の枠の中に寄せて、ax のデータ座標で返す。位置が無ければ None。
22 ドラッグを軸の外で離したり、外へはみ出して動かしたりしたときも、縁で止めた位置として扱う。
23 """
24 # 中ならイベントの値をそのまま使う(ピクセルから計算し直すと誤差が出て、クリックがドラッグに見える)
25 if event.inaxes is ax and event.xdata is not None and event.ydata is not None:
26 return float(event.xdata), float(event.ydata)
27 if event.x is None or event.y is None: 27 ↛ 28line 27 didn't jump to line 28 because the condition on line 27 was never true
28 return None
29 box = ax.bbox
30 x = min(max(event.x, box.x0), box.x1)
31 y = min(max(event.y, box.y0), box.y1)
32 data_x, data_y = ax.transData.inverted().transform((x, y))
33 # 縁で止めた向きは表示範囲の端の値そのものにする(ピクセルから戻すと誤差で端の点が漏れる)。枠の始め側が範囲の始め側
34 xlim, ylim = ax.get_xlim(), ax.get_ylim()
35 if event.x <= box.x0: 35 ↛ 36line 35 didn't jump to line 36 because the condition on line 35 was never true
36 data_x = xlim[0]
37 elif event.x >= box.x1:
38 data_x = xlim[1]
39 if event.y <= box.y0:
40 data_y = ylim[0]
41 elif event.y >= box.y1: 41 ↛ 42line 41 didn't jump to line 42 because the condition on line 41 was never true
42 data_y = ylim[1]
43 return float(data_x), float(data_y)