// 自定义形状命中:对象原始矩形宽 160,但 paint 只画左侧直径 80 的圆,hitTest 也只接受圆内。 // 圆外部分可落到父容器监听器;按下与释放须经相同合法目标复核。 // 扩展矩形的绘制、命中和事件方法,用同一个 hits 状态观察交互结果。 class CircleTarget: RectBlock { hits: Object // point 已转换到该出现位置局部坐标;使用圆心(40,40)、半径40,而不是整个 160x80 外框。 function hitTest(self: CircleTarget, mount: Mount, point: Point): Bool { return point.inCircle(40, 40, 40) } // 把原生命令宽度缩为 80、圆角半径设为 40,得到与 hitTest 对应的圆形区域。 function paint(self: CircleTarget, mount: Mount, geometry: Bounds): DisplayList { drawing = RectBlock.paint(self, mount, geometry) drawing.commands.at(0).width = 80 drawing.commands.at(0).radius = 40 return drawing } // 圆内点击递增自身计数并停止向祖先传播;父容器不会为同一次点击再递增。 function onEvent(self: CircleTarget, event: Event): Unit { self.hits.increment() event.stopPropagation() } } hits = ui.state(0) // 父监听器单独计数;它和圆形目标显示在同页,便于比较穿过透明区的输入。 background = ui.state(0) circle = CircleTarget(160, 80, 0, "#237A45", hits) root = Column(24, 16, circle, TextBlock("点击圆内计入圆;透明右半区域交给父容器"), TextBlock("圆内点击"), ui.textOf(hits, "value"), TextBlock("父容器点击"), ui.textOf(background, "value")) // 订阅在父 Column 上,圆外有效区域可回退到父目标;源命中只读检查不执行这些业务回调。 connection = root.on("click", background.increment) page = Page() page.render(root)