mouse.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. from __future__ import annotations
  2. from typing import Any
  3. from ... import windows_automation
  4. from ..context import WorkflowContext
  5. from ..registry import control_ports, field_def, register_node
  6. def _number(value: Any, default: float = 0) -> float:
  7. try:
  8. return float(value)
  9. except (TypeError, ValueError):
  10. return default
  11. def click_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  12. params = node.get("params", {})
  13. result = windows_automation.mouse_action(
  14. "click",
  15. x=int(_number(inputs.get("x", params.get("x")))),
  16. y=int(_number(inputs.get("y", params.get("y")))),
  17. duration=_number(params.get("duration"), 0),
  18. button=params.get("button") or "left",
  19. clicks=int(_number(params.get("clicks"), 1)),
  20. )
  21. return {"x": result.get("x"), "y": result.get("y"), "action": result.get("action")}
  22. def double_click_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  23. params = node.get("params", {})
  24. result = windows_automation.mouse_action(
  25. "double_click",
  26. x=int(_number(inputs.get("x", params.get("x")))),
  27. y=int(_number(inputs.get("y", params.get("y")))),
  28. button=params.get("button") or "left",
  29. )
  30. return {"x": result.get("x"), "y": result.get("y"), "action": result.get("action")}
  31. def right_click_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  32. params = node.get("params", {})
  33. result = windows_automation.mouse_action(
  34. "right_click",
  35. x=int(_number(inputs.get("x", params.get("x")))),
  36. y=int(_number(inputs.get("y", params.get("y")))),
  37. )
  38. return {"x": result.get("x"), "y": result.get("y"), "action": result.get("action")}
  39. def move_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  40. params = node.get("params", {})
  41. result = windows_automation.mouse_action(
  42. "move_to",
  43. x=int(_number(inputs.get("x", params.get("x")))),
  44. y=int(_number(inputs.get("y", params.get("y")))),
  45. duration=_number(params.get("duration"), 0),
  46. )
  47. return {"x": result.get("x"), "y": result.get("y"), "action": result.get("action")}
  48. def scroll_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  49. amount = int(_number(inputs.get("amount", node.get("params", {}).get("amount")), 0))
  50. result = windows_automation.mouse_action("scroll", amount=amount)
  51. return {"x": result.get("x"), "y": result.get("y"), "amount": amount, "action": result.get("action")}
  52. COORD_INPUTS = {
  53. "x": field_def("number", "X 坐标", required=True),
  54. "y": field_def("number", "Y 坐标", required=True),
  55. }
  56. MOUSE_OUTPUTS = {
  57. "x": {"type": "number", "label": "鼠标 X 坐标"},
  58. "y": {"type": "number", "label": "鼠标 Y 坐标"},
  59. "action": {"type": "string", "label": "动作名称"},
  60. }
  61. for node_type, label, executor, params in [
  62. (
  63. "mouse.click",
  64. "鼠标点击",
  65. click_node,
  66. {
  67. "button": field_def("select", "按键", "left", options=["left", "middle", "right"]),
  68. "clicks": field_def("number", "点击次数", 1, minimum=1, maximum=20),
  69. "duration": field_def("number", "移动耗时", 0, minimum=0, maximum=60),
  70. },
  71. ),
  72. (
  73. "mouse.double_click",
  74. "鼠标双击",
  75. double_click_node,
  76. {"button": field_def("select", "按键", "left", options=["left", "middle", "right"])},
  77. ),
  78. ("mouse.right_click", "鼠标右键", right_click_node, {}),
  79. ("mouse.move", "鼠标移动", move_node, {"duration": field_def("number", "移动耗时", 0, minimum=0, maximum=60)}),
  80. ]:
  81. register_node(
  82. {
  83. "type": node_type,
  84. "category": "mouse",
  85. "label": label,
  86. "params": params,
  87. "inputs": COORD_INPUTS,
  88. "outputs": MOUSE_OUTPUTS,
  89. "control_ports": control_ports(),
  90. },
  91. executor,
  92. )
  93. register_node(
  94. {
  95. "type": "mouse.scroll",
  96. "category": "mouse",
  97. "label": "鼠标滚动",
  98. "params": {"amount": field_def("number", "滚动量", 0)},
  99. "inputs": {"amount": field_def("number", "滚动量")},
  100. "outputs": MOUSE_OUTPUTS | {"amount": {"type": "number", "label": "滚动量"}},
  101. "control_ports": control_ports(),
  102. },
  103. scroll_node,
  104. )