Publish showcase_catalog.py from marimo
Browse files- showcase_catalog.py +61 -2
showcase_catalog.py
CHANGED
|
@@ -675,7 +675,7 @@ for rows, cols in [(2, 3), (8, 12)]:
|
|
| 675 |
|
| 676 |
term("auto-detector", "Perception",
|
| 677 |
"OCR when there is text, a grid when there is none",
|
| 678 |
-
["AutoDetector", "AutoDetector.detect"],
|
| 679 |
note="The default: useful with nothing installed, better the moment OCR appears.",
|
| 680 |
code="""
|
| 681 |
from PIL import Image
|
|
@@ -1622,7 +1622,8 @@ def _with_gtk(tmp=None):
|
|
| 1622 |
|
| 1623 |
term("atspi-index", "Perception",
|
| 1624 |
"The accessibility tree: elements the OS already knows about",
|
| 1625 |
-
["AtspiDetector", "AtspiDetector.detect", "AtspiDetector.text",
|
|
|
|
| 1626 |
"AtspiReader.read", "AccessibleNode", "TreeReader", "TreeReader.read",
|
| 1627 |
"accessibility_available",
|
| 1628 |
"INTERACTIVE_ROLES", "TEXT_ROLES"],
|
|
@@ -1720,3 +1721,61 @@ desk("desk-atspi", "Real desktop",
|
|
| 1720 |
"PyAutoGuiExecutor", "PlannerBrain"],
|
| 1721 |
note="Roles and extents come from GTK itself; the click is a real one and the app reacts.",
|
| 1722 |
scene_name="gtk", make=make_atspi_click)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 675 |
|
| 676 |
term("auto-detector", "Perception",
|
| 677 |
"OCR when there is text, a grid when there is none",
|
| 678 |
+
["AutoDetector", "AutoDetector.detect", "AutoDetector.coordinates_of_last_detect"],
|
| 679 |
note="The default: useful with nothing installed, better the moment OCR appears.",
|
| 680 |
code="""
|
| 681 |
from PIL import Image
|
|
|
|
| 1622 |
|
| 1623 |
term("atspi-index", "Perception",
|
| 1624 |
"The accessibility tree: elements the OS already knows about",
|
| 1625 |
+
["AtspiDetector", "AtspiDetector.detect", "AtspiDetector.text",
|
| 1626 |
+
"AtspiDetector.coordinates_of_last_detect", "AtspiReader",
|
| 1627 |
"AtspiReader.read", "AccessibleNode", "TreeReader", "TreeReader.read",
|
| 1628 |
"accessibility_available",
|
| 1629 |
"INTERACTIVE_ROLES", "TEXT_ROLES"],
|
|
|
|
| 1721 |
"PyAutoGuiExecutor", "PlannerBrain"],
|
| 1722 |
note="Roles and extents come from GTK itself; the click is a real one and the app reacts.",
|
| 1723 |
scene_name="gtk", make=make_atspi_click)
|
| 1724 |
+
|
| 1725 |
+
term("uia-mapping", "Perception",
|
| 1726 |
+
"The Windows backend: the same index, from UI Automation",
|
| 1727 |
+
["UiaReader", "UiaReader.read", "UiaDetector", "UiaDetector.detect", "UiaDetector.text",
|
| 1728 |
+
"UiaDetector.coordinates_of_last_detect"],
|
| 1729 |
+
note="Windows-only, so the mapping is exercised here against a synthetic control tree.",
|
| 1730 |
+
code="""
|
| 1731 |
+
from tiny_computer_agent import UiaDetector, UiaReader, accessibility_available
|
| 1732 |
+
|
| 1733 |
+
print("on this machine:", accessibility_available("uia"))
|
| 1734 |
+
print()
|
| 1735 |
+
|
| 1736 |
+
|
| 1737 |
+
class FakeBox:
|
| 1738 |
+
def __init__(self, left, top, right, bottom):
|
| 1739 |
+
self.left, self.top, self.right, self.bottom = left, top, right, bottom
|
| 1740 |
+
|
| 1741 |
+
|
| 1742 |
+
class FakeControl:
|
| 1743 |
+
\"\"\"The slice of a UI Automation element the reader actually uses.\"\"\"
|
| 1744 |
+
|
| 1745 |
+
def __init__(self, name, control_type, box=None, children=()):
|
| 1746 |
+
self.Name = name
|
| 1747 |
+
self.ControlTypeName = control_type
|
| 1748 |
+
self.BoundingRectangle = box
|
| 1749 |
+
self._children = list(children)
|
| 1750 |
+
|
| 1751 |
+
def GetChildren(self):
|
| 1752 |
+
return self._children
|
| 1753 |
+
|
| 1754 |
+
|
| 1755 |
+
def tree():
|
| 1756 |
+
return FakeControl("Accessible desktop", "WindowControl", FakeBox(160, 160, 620, 380), [
|
| 1757 |
+
FakeControl("", "PaneControl", FakeBox(174, 174, 606, 366), [
|
| 1758 |
+
FakeControl("Files", "ButtonControl", FakeBox(174, 201, 274, 237)),
|
| 1759 |
+
FakeControl("Terminal", "ButtonControl", FakeBox(282, 201, 382, 237)),
|
| 1760 |
+
FakeControl("Save", "ButtonControl", FakeBox(390, 201, 490, 237)),
|
| 1761 |
+
FakeControl("Cancel", "ButtonControl", FakeBox(498, 201, 598, 237)),
|
| 1762 |
+
FakeControl("Choose an action", "TextControl", FakeBox(174, 245, 598, 264)),
|
| 1763 |
+
]),
|
| 1764 |
+
])
|
| 1765 |
+
|
| 1766 |
+
|
| 1767 |
+
reader = UiaReader(provider=tree)
|
| 1768 |
+
print(f"UiaReader().read() -> {len(reader.read())} AccessibleNode(s), "
|
| 1769 |
+
f"control types mapped to roles")
|
| 1770 |
+
print()
|
| 1771 |
+
detector = UiaDetector(reader=reader)
|
| 1772 |
+
print("UiaDetector().detect() -> only the things worth clicking:")
|
| 1773 |
+
for element in detector.detect():
|
| 1774 |
+
print(f" {element.label!r:12} kind={element.kind:8} centre={str(element.center):12} "
|
| 1775 |
+
f"box={element.width}x{element.height}")
|
| 1776 |
+
print()
|
| 1777 |
+
print("the window and the (unnamed) pane are read, and deliberately not offered:")
|
| 1778 |
+
print(" ", [node.role for node in reader.read()])
|
| 1779 |
+
print()
|
| 1780 |
+
print("UiaDetector().text() ->", detector.text()[:80])
|
| 1781 |
+
""")
|