feat: 大规模扩充至212个模块/175K行代码 — 覆盖android/java/javax/org/dalvik全包
- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
This commit is contained in:
1 parent
506f9ac725
commit
a51854455b
128 files changed
+100571
-3
No files matched your search
@@ -0,0 +1,545 @@
|
||||
"""
|
||||
Android gesture 包 — Gesture, GestureOverlayView, GesturePoint, GestureStroke,
|
||||
GestureLibrary, GestureStore, Prediction, OrientedBoundingBox, GestureUtils
|
||||
方法签名完全对齐 Android SDK
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
import sys
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
from ..java.lang import RuntimeException
|
||||
|
||||
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
|
||||
|
||||
__all__ = [
|
||||
"Gesture",
|
||||
"GestureOverlayView",
|
||||
"GesturePoint",
|
||||
"GestureStroke",
|
||||
"GestureLibrary",
|
||||
"GestureStore",
|
||||
"Prediction",
|
||||
"OrientedBoundingBox",
|
||||
"GestureUtils",
|
||||
]
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# GesturePoint
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class GesturePoint(Stub):
|
||||
"""GesturePoint — 手势点"""
|
||||
|
||||
def __init__(self, x: float = 0.0, y: float = 0.0, timestamp: int = 0):
|
||||
super().__init__()
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.timestamp = timestamp
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"GesturePoint({self.x}, {self.y})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# OrientedBoundingBox
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class OrientedBoundingBox(Stub):
|
||||
"""OrientedBoundingBox — 有向包围盒"""
|
||||
|
||||
def __init__(self, center_x: float = 0.0, center_y: float = 0.0,
|
||||
width: float = 0.0, height: float = 0.0, orientation: float = 0.0):
|
||||
super().__init__()
|
||||
self.centerX = center_x
|
||||
self.centerY = center_y
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.orientation = orientation
|
||||
|
||||
def toRect(self) -> Tuple[float, float, float, float]:
|
||||
"""转换为矩形"""
|
||||
hw = self.width / 2.0
|
||||
hh = self.height / 2.0
|
||||
return (self.centerX - hw, self.centerY - hh,
|
||||
self.centerX + hw, self.centerY + hh)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Prediction
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Prediction(Stub):
|
||||
"""Prediction — 预测结果"""
|
||||
|
||||
def __init__(self, name: str = "", score: float = 0.0):
|
||||
super().__init__()
|
||||
self.name = name
|
||||
self.score = score
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Prediction(name={self.name}, score={self.score})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# GestureStroke
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class GestureStroke(Stub):
|
||||
"""GestureStroke — 手势笔划"""
|
||||
|
||||
def __init__(self, points: Optional[List[GesturePoint]] = None):
|
||||
super().__init__()
|
||||
self._points = points or []
|
||||
self._path: Optional[Any] = None
|
||||
self._length = self._compute_length()
|
||||
self._bounding_box = OrientedBoundingBox()
|
||||
|
||||
def _compute_length(self) -> float:
|
||||
length = 0.0
|
||||
for i in range(1, len(self._points)):
|
||||
dx = self._points[i].x - self._points[i - 1].x
|
||||
dy = self._points[i].y - self._points[i - 1].y
|
||||
length += math.sqrt(dx * dx + dy * dy)
|
||||
return length
|
||||
|
||||
def getLength(self) -> float:
|
||||
"""获取长度"""
|
||||
return self._length
|
||||
|
||||
def getPoints(self) -> List[GesturePoint]:
|
||||
"""获取点列表"""
|
||||
return self._points.copy()
|
||||
|
||||
def getPath(self) -> Optional[Any]:
|
||||
"""获取路径"""
|
||||
return self._path
|
||||
|
||||
def toPath(self, width: float = 1.0, height: float = 1.0, num_sample: int = 0) -> Any:
|
||||
"""转换为路径"""
|
||||
return self._path
|
||||
|
||||
def clearPath(self) -> None:
|
||||
"""清除路径"""
|
||||
self._path = None
|
||||
|
||||
def computeOrientedBoundingBox(self) -> OrientedBoundingBox:
|
||||
"""计算有向包围盒"""
|
||||
return self._bounding_box
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Gesture
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Gesture(Stub):
|
||||
"""Gesture — 手势"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._strokes: List[GestureStroke] = []
|
||||
self._id = 0
|
||||
self._bounding_box: Optional[Tuple[float, float, float, float]] = None
|
||||
self._length = 0.0
|
||||
|
||||
def getStrokes(self) -> List[GestureStroke]:
|
||||
"""获取笔划列表"""
|
||||
return self._strokes.copy()
|
||||
|
||||
def getLength(self) -> float:
|
||||
"""获取手势长度"""
|
||||
return sum(s.getLength() for s in self._strokes)
|
||||
|
||||
def getBoundingBox(self) -> Tuple[float, float, float, float]:
|
||||
"""获取包围盒"""
|
||||
if self._bounding_box:
|
||||
return self._bounding_box
|
||||
if not self._strokes:
|
||||
return (0.0, 0.0, 0.0, 0.0)
|
||||
min_x = min(p.x for s in self._strokes for p in s._points) if self._strokes else 0
|
||||
min_y = min(p.y for s in self._strokes for p in s._points) if self._strokes else 0
|
||||
max_x = max(p.x for s in self._strokes for p in s._points) if self._strokes else 0
|
||||
max_y = max(p.y for s in self._strokes for p in s._points) if self._strokes else 0
|
||||
return (min_x, min_y, max_x, max_y)
|
||||
|
||||
def getID(self) -> int:
|
||||
"""获取 ID"""
|
||||
return self._id
|
||||
|
||||
def setID(self, id_: int) -> None:
|
||||
"""设置 ID"""
|
||||
self._id = id_
|
||||
|
||||
def toPath(self) -> Optional[Any]:
|
||||
"""转换为路径"""
|
||||
return None
|
||||
|
||||
def toTempPath(self) -> Optional[Any]:
|
||||
"""转换为临时路径"""
|
||||
return None
|
||||
|
||||
def toBitmap(self) -> Optional[Any]:
|
||||
"""转换为位图"""
|
||||
return None
|
||||
|
||||
def getStrokesCount(self) -> int:
|
||||
"""获取笔划数量"""
|
||||
return len(self._strokes)
|
||||
|
||||
def getGestureStroke(self, index: int) -> Optional[GestureStroke]:
|
||||
"""获取指定索引的笔划"""
|
||||
if 0 <= index < len(self._strokes):
|
||||
return self._strokes[index]
|
||||
return None
|
||||
|
||||
def addStroke(self, stroke: GestureStroke) -> None:
|
||||
"""添加笔划"""
|
||||
self._strokes.append(stroke)
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Gesture(id={self._id}, strokes={len(self._strokes)})"
|
||||
|
||||
def equals(self, other: Any) -> bool:
|
||||
if not isinstance(other, Gesture):
|
||||
return False
|
||||
return self._id == other._id
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._id) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# GestureOverlayView
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class GestureOverlayView(Stub):
|
||||
"""GestureOverlayView — 手势覆盖视图 (桌面存根)"""
|
||||
|
||||
GESTURE_STROKE_TYPE_SINGLE = 0
|
||||
GESTURE_STROKE_TYPE_MULTIPLE = 1
|
||||
ORIENTATION_HORIZONTAL = 0
|
||||
ORIENTATION_VERTICAL = 1
|
||||
|
||||
def __init__(self, context: Any = None):
|
||||
super().__init__()
|
||||
self._context = context
|
||||
self._gesture: Optional[Gesture] = None
|
||||
self._gesture_color = 0xFFFFFF00
|
||||
self._uncertain_gesture_color = 0xFFFF0000
|
||||
self._gesture_stroke_width = 4.0
|
||||
self._gesture_stroke_type = GestureOverlayView.GESTURE_STROKE_TYPE_SINGLE
|
||||
self._gesture_stroke_length_threshold = 50.0
|
||||
self._gesture_stroke_squareness_threshold = 0.5
|
||||
self._fade_enabled = True
|
||||
self._fade_offset = 0
|
||||
self._fade_duration = 150
|
||||
self._events_interception_enabled = True
|
||||
self._gesture_visible = True
|
||||
self._gesture_listeners: List[Any] = []
|
||||
self._gesture_performed_listeners: List[Any] = []
|
||||
self._gesturing_listeners: List[Any] = []
|
||||
|
||||
def getGesture(self) -> Optional[Gesture]:
|
||||
return self._gesture
|
||||
|
||||
def setGesture(self, gesture: Gesture) -> None:
|
||||
self._gesture = gesture
|
||||
|
||||
def setGestureColor(self, color: int) -> None:
|
||||
self._gesture_color = color
|
||||
|
||||
def getGestureColor(self) -> int:
|
||||
return self._gesture_color
|
||||
|
||||
def setUncertainGestureColor(self, color: int) -> None:
|
||||
self._uncertain_gesture_color = color
|
||||
|
||||
def getUncertainGestureColor(self) -> int:
|
||||
return self._uncertain_gesture_color
|
||||
|
||||
def setGestureStrokeWidth(self, width: float) -> None:
|
||||
self._gesture_stroke_width = width
|
||||
|
||||
def getGestureStrokeWidth(self) -> float:
|
||||
return self._gesture_stroke_width
|
||||
|
||||
def setGestureStrokeType(self, type_: int) -> None:
|
||||
self._gesture_stroke_type = type_
|
||||
|
||||
def getGestureStrokeType(self) -> int:
|
||||
return self._gesture_stroke_type
|
||||
|
||||
def setGestureStrokeLengthThreshold(self, threshold: float) -> None:
|
||||
self._gesture_stroke_length_threshold = threshold
|
||||
|
||||
def getGestureStrokeLengthThreshold(self) -> float:
|
||||
return self._gesture_stroke_length_threshold
|
||||
|
||||
def setGestureStrokeSquarenessThreshold(self, threshold: float) -> None:
|
||||
self._gesture_stroke_squareness_threshold = threshold
|
||||
|
||||
def getGestureStrokeSquarenessThreshold(self) -> float:
|
||||
return self._gesture_stroke_squareness_threshold
|
||||
|
||||
def setFadeEnabled(self, enabled: bool) -> None:
|
||||
self._fade_enabled = enabled
|
||||
|
||||
def isFadeEnabled(self) -> bool:
|
||||
return self._fade_enabled
|
||||
|
||||
def setFadeOffset(self, offset: int) -> None:
|
||||
self._fade_offset = offset
|
||||
|
||||
def getFadeOffset(self) -> int:
|
||||
return self._fade_offset
|
||||
|
||||
def setFadeDuration(self, duration: int) -> None:
|
||||
self._fade_duration = duration
|
||||
|
||||
def getFadeDuration(self) -> int:
|
||||
return self._fade_duration
|
||||
|
||||
def setEventsInterceptionEnabled(self, enabled: bool) -> None:
|
||||
self._events_interception_enabled = enabled
|
||||
|
||||
def isEventsInterceptionEnabled(self) -> bool:
|
||||
return self._events_interception_enabled
|
||||
|
||||
def setGestureVisible(self, visible: bool) -> None:
|
||||
self._gesture_visible = visible
|
||||
|
||||
def isGestureVisible(self) -> bool:
|
||||
return self._gesture_visible
|
||||
|
||||
def addOnGestureListener(self, listener: Any) -> None:
|
||||
self._gesture_listeners.append(listener)
|
||||
|
||||
def removeOnGestureListener(self, listener: Any) -> None:
|
||||
if listener in self._gesture_listeners:
|
||||
self._gesture_listeners.remove(listener)
|
||||
|
||||
def removeAllOnGestureListeners(self) -> None:
|
||||
self._gesture_listeners.clear()
|
||||
|
||||
def addOnGesturePerformedListener(self, listener: Any) -> None:
|
||||
self._gesture_performed_listeners.append(listener)
|
||||
|
||||
def removeOnGesturePerformedListener(self, listener: Any) -> None:
|
||||
if listener in self._gesture_performed_listeners:
|
||||
self._gesture_performed_listeners.remove(listener)
|
||||
|
||||
def removeAllOnGesturePerformedListeners(self) -> None:
|
||||
self._gesture_performed_listeners.clear()
|
||||
|
||||
def addOnGesturingListener(self, listener: Any) -> None:
|
||||
self._gesturing_listeners.append(listener)
|
||||
|
||||
def removeOnGesturingListener(self, listener: Any) -> None:
|
||||
if listener in self._gesturing_listeners:
|
||||
self._gesturing_listeners.remove(listener)
|
||||
|
||||
def removeAllOnGesturingListeners(self) -> None:
|
||||
self._gesturing_listeners.clear()
|
||||
|
||||
def cancelGesture(self) -> None:
|
||||
self._gesture = None
|
||||
|
||||
def clear(self) -> None:
|
||||
self._gesture = None
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# GestureLibrary
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class GestureLibrary(Stub):
|
||||
"""GestureLibrary — 手势库 (桌面存根)"""
|
||||
|
||||
ORIENTATION_INVARIANT = 0
|
||||
ORIENTATION_SENSITIVE = 1
|
||||
ORIENTATION_SEQUENTIAL_SENSITIVE = 2
|
||||
SEQUENCE_INVARIANT = 0
|
||||
SEQUENCE_SENSITIVE = 1
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._gestures: Dict[str, List[Gesture]] = {}
|
||||
self._read_only = False
|
||||
self._orientation_style = GestureLibrary.ORIENTATION_SENSITIVE
|
||||
self._sequence_type = GestureLibrary.SEQUENCE_SENSITIVE
|
||||
|
||||
def store(self) -> bool:
|
||||
"""存储手势库"""
|
||||
return True
|
||||
|
||||
def load(self) -> bool:
|
||||
"""加载手势库"""
|
||||
return True
|
||||
|
||||
def getGestureEntries(self) -> List[str]:
|
||||
"""获取手势条目"""
|
||||
return list(self._gestures.keys())
|
||||
|
||||
def getGestures(self, entry_name: str) -> List[Gesture]:
|
||||
"""获取手势列表"""
|
||||
return self._gestures.get(entry_name, [])
|
||||
|
||||
def recognize(self, gesture: Gesture) -> List[Prediction]:
|
||||
"""识别手势"""
|
||||
return []
|
||||
|
||||
def removeGesture(self, entry_name: str, gesture: Gesture) -> None:
|
||||
"""移除手势"""
|
||||
if entry_name in self._gestures and gesture in self._gestures[entry_name]:
|
||||
self._gestures[entry_name].remove(gesture)
|
||||
|
||||
def removeEntry(self, entry_name: str) -> None:
|
||||
"""移除条目"""
|
||||
self._gestures.pop(entry_name, None)
|
||||
|
||||
def addGesture(self, entry_name: str, gesture: Gesture) -> None:
|
||||
"""添加手势"""
|
||||
if entry_name not in self._gestures:
|
||||
self._gestures[entry_name] = []
|
||||
self._gestures[entry_name].append(gesture)
|
||||
|
||||
def isReadOnly(self) -> bool:
|
||||
"""检查是否只读"""
|
||||
return self._read_only
|
||||
|
||||
def setOrientationStyle(self, style: int) -> None:
|
||||
self._orientation_style = style
|
||||
|
||||
def getOrientationStyle(self) -> int:
|
||||
return self._orientation_style
|
||||
|
||||
def setSequenceType(self, type_: int) -> None:
|
||||
self._sequence_type = type_
|
||||
|
||||
def getSequenceType(self) -> int:
|
||||
return self._sequence_type
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# GestureStore
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class GestureStore(Stub):
|
||||
"""GestureStore — 手势存储 (桌面存根)"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._gestures: Dict[str, List[Gesture]] = {}
|
||||
self._orientation_style = GestureLibrary.ORIENTATION_SENSITIVE
|
||||
self._sequence_type = GestureLibrary.SEQUENCE_SENSITIVE
|
||||
self._change_listener: Optional[Any] = None
|
||||
|
||||
def addGesture(self, entry_name: str, gesture: Gesture) -> None:
|
||||
if entry_name not in self._gestures:
|
||||
self._gestures[entry_name] = []
|
||||
self._gestures[entry_name].append(gesture)
|
||||
|
||||
def removeGesture(self, entry_name: str, gesture: Gesture) -> None:
|
||||
if entry_name in self._gestures and gesture in self._gestures[entry_name]:
|
||||
self._gestures[entry_name].remove(gesture)
|
||||
|
||||
def removeEntry(self, entry_name: str) -> None:
|
||||
self._gestures.pop(entry_name, None)
|
||||
|
||||
def getGestureEntries(self) -> List[str]:
|
||||
return list(self._gestures.keys())
|
||||
|
||||
def getGestures(self, entry_name: str) -> List[Gesture]:
|
||||
return self._gestures.get(entry_name, [])
|
||||
|
||||
def recognize(self, gesture: Gesture) -> List[Prediction]:
|
||||
return []
|
||||
|
||||
def recognizeAsync(self, gesture: Gesture) -> None:
|
||||
pass
|
||||
|
||||
def setOrientationStyle(self, style: int) -> None:
|
||||
self._orientation_style = style
|
||||
|
||||
def getOrientationStyle(self) -> int:
|
||||
return self._orientation_style
|
||||
|
||||
def setSequenceType(self, type_: int) -> None:
|
||||
self._sequence_type = type_
|
||||
|
||||
def getSequenceType(self) -> int:
|
||||
return self._sequence_type
|
||||
|
||||
def load(self, store_file: Any) -> None:
|
||||
pass
|
||||
|
||||
def save(self, store_file: Any) -> None:
|
||||
pass
|
||||
|
||||
def setChangeListener(self, listener: Any) -> None:
|
||||
self._change_listener = listener
|
||||
|
||||
def getChangeListener(self) -> Any:
|
||||
return self._change_listener
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# GestureUtils
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class GestureUtils(Stub):
|
||||
"""GestureUtils — 手势工具类"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@staticmethod
|
||||
def copy(gesture: Gesture) -> Gesture:
|
||||
"""复制手势"""
|
||||
new_gesture = Gesture()
|
||||
for stroke in gesture.getStrokes():
|
||||
new_stroke = GestureStroke(stroke.getPoints())
|
||||
new_gesture.addStroke(new_stroke)
|
||||
return new_gesture
|
||||
|
||||
@staticmethod
|
||||
def boundingBox(gesture: Gesture) -> OrientedBoundingBox:
|
||||
"""计算手势包围盒"""
|
||||
bbox = gesture.getBoundingBox()
|
||||
cx = (bbox[0] + bbox[2]) / 2.0 if bbox[2] != bbox[0] else 0.0
|
||||
cy = (bbox[1] + bbox[3]) / 2.0 if bbox[3] != bbox[1] else 0.0
|
||||
w = bbox[2] - bbox[0]
|
||||
h = bbox[3] - bbox[1]
|
||||
return OrientedBoundingBox(cx, cy, w, h, 0.0)
|
||||
|
||||
@staticmethod
|
||||
def boundingBox_stroke(stroke: GestureStroke) -> OrientedBoundingBox:
|
||||
"""计算笔划包围盒"""
|
||||
return stroke.computeOrientedBoundingBox()
|
||||
|
||||
@staticmethod
|
||||
def spatialSampling(gesture: Gesture, num_samples: int) -> List[float]:
|
||||
"""空间采样"""
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def temporalSampling(gesture: Gesture, num_samples: int) -> List[float]:
|
||||
"""时间采样"""
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def computeOrientedBoundingBox(points: List[GesturePoint]) -> OrientedBoundingBox:
|
||||
"""计算有向包围盒"""
|
||||
if not points:
|
||||
return OrientedBoundingBox()
|
||||
xs = [p.x for p in points]
|
||||
ys = [p.y for p in points]
|
||||
cx = sum(xs) / len(xs)
|
||||
cy = sum(ys) / len(ys)
|
||||
w = max(xs) - min(xs)
|
||||
h = max(ys) - min(ys)
|
||||
return OrientedBoundingBox(cx, cy, w, h, 0.0)
|
||||
Reference in new issue
Block a user