Skip to main content

atmos/kernel/
mouse_tracker.rs

1#![allow(dead_code)]
2
3/// 画面サイズとマウス座標の厳格な管理を行うトラッカー
4pub struct MouseTracker {
5    pub x: u32,
6    pub y: u32,
7    pub screen_width: u32,
8    pub screen_height: u32,
9    pub learned_max_x: u32,
10    pub learned_max_y: u32,
11}
12
13impl MouseTracker {
14    /// 新しいトラッカーを初期化します
15    pub fn new(initial_x: u32, initial_y: u32, screen_width: u32, screen_height: u32) -> Self {
16        let mut tracker = Self {
17            x: initial_x,
18            y: initial_y,
19            screen_width,
20            screen_height,
21            learned_max_x: 28000, // 初期値を小さめにし、徐々に学習させる
22            learned_max_y: 28000,
23        };
24        tracker.clamp();
25        tracker
26    }
27
28    /// 画面のリサイズなどで解像度が変更された場合に呼び出します
29    pub fn update_screen_size(&mut self, width: u32, height: u32) {
30        self.screen_width = width;
31        self.screen_height = height;
32        self.clamp();
33    }
34
35    /// 相対的な移動量 (dx, dy) を適用し、画面内にクランプします
36    pub fn move_relative(&mut self, dx: i32, dy: i32) {
37        let new_x = (self.x as i32).saturating_add(dx);
38        let new_y = (self.y as i32).saturating_add(dy);
39
40        self.x = new_x.max(0) as u32;
41        self.y = new_y.max(0) as u32;
42        self.clamp();
43    }
44
45    /// タブレット等の絶対座標入力を解像度にマッピングして移動します
46    pub fn move_absolute_tablet(
47        &mut self,
48        abs_x: u32,
49        abs_y: u32,
50        _max_abs_x: u32,
51        _max_abs_y: u32,
52    ) {
53        if self.screen_width == 0 || self.screen_height == 0 {
54            return;
55        }
56
57        // 送られてきた座標が学習済みの最大値を超えていれば更新 (自動キャリブレーション)
58        if abs_x > self.learned_max_x {
59            self.learned_max_x = abs_x;
60        }
61        if abs_y > self.learned_max_y {
62            self.learned_max_y = abs_y;
63        }
64
65        let mapped_x = (abs_x as u64 * self.screen_width as u64) / self.learned_max_x as u64;
66        let mapped_y = (abs_y as u64 * self.screen_height as u64) / self.learned_max_y as u64;
67
68        self.x = mapped_x as u32;
69        self.y = mapped_y as u32;
70        self.clamp();
71    }
72
73    /// 現在の座標が画面内に収まるようにクランプします
74    fn clamp(&mut self) {
75        if self.screen_width > 0 {
76            self.x = self.x.min(self.screen_width - 1);
77        } else {
78            self.x = 0;
79        }
80
81        if self.screen_height > 0 {
82            self.y = self.y.min(self.screen_height - 1);
83        } else {
84            self.y = 0;
85        }
86    }
87}
88
89