def test_layout_with_insets(self): layout = StackLayout() container = Frame(self.context, layout) container.bounds = Bounds(0, 0, 100, 100) child1 = Panel(self.context) child1.bounds = Bounds(10, 10, 20, 20) child1.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) child2 = Panel(self.context) child2.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) child2.preferred_size_override = Some(Dimension(80, 60)) container.add(child1) container.add(child2, fill=False) def test(padding: Insets): layout.padding = padding self.assertEqual(True, container.layout_pending) self.context.process() self.assertEqual(False, container.layout_pending) name = f"stack-{padding.top},{padding.right},{padding.bottom},{padding.left}" self.assertImage(name, self.context) for p in [ Insets(10, 10, 10, 10), Insets(15, 0, 15, 0), Insets(0, 10, 20, 0) ]: test(p)
def handle_button(button: str): if len(button) > 0: label.text = f"{button} is pressed" panel.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) else: label.text = "" panel.set_color(StyleKeys.Background, RGBA(0.1, 0.1, 0.1, 0.8))
def test_drag_overlapping(self): bottom = Frame(self.context) bottom.draggable = True bottom.bounds = Bounds(10, 10, 50, 50) bottom.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) top = Frame(self.context) top.draggable = True top.bounds = Bounds(20, 20, 50, 50) top.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) self.mouse.move_to(Point(30, 30)) self.mouse.press(MouseButton.LEFT) self.mouse.move_to(Point(50, 50)) self.mouse.release(MouseButton.LEFT) self.context.process() self.assertImage("drag_overlapping_top", self.context) self.mouse.move_to(Point(20, 20)) self.mouse.press(MouseButton.LEFT) self.mouse.move_to(Point(40, 40)) self.mouse.release(MouseButton.LEFT) self.context.process() self.assertImage("drag_overlapping_bottom", self.context)
def test_hbox_layout(self): layout = HBoxLayout() container = Frame(self.context, layout) container.bounds = Bounds(5, 5, 90, 90) child1 = Panel(self.context) child1.preferred_size_override = Some(Dimension(20, 50)) child1.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) container.add(child1) child2 = Panel(self.context) child2.preferred_size_override = Some(Dimension(15, 60)) child2.minimum_size_override = Some(Dimension(15, 60)) child2.set_color(StyleKeys.Background, RGBA(0, 1, 0, 1)) container.add(child2) child3 = Panel(self.context) child3.preferred_size_override = Some(Dimension(30, 40)) child3.minimum_size_override = Some(Dimension(10, 20)) child3.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) container.add(child3) def test(direction: BoxDirection, spacing: float, padding: Insets, align: BoxAlign): container.bounds = Bounds(5, 5, 90, 90) layout.spacing = spacing layout.padding = padding layout.align = align self.assertEqual(True, container.layout_pending) self.context.process() self.assertEqual(False, container.layout_pending) (top, right, bottom, left) = padding.tuple prefix = f"hbox-{direction.name}-{spacing}-{top},{right},{bottom},{left}-{align.name}-" self.assertImage(prefix + "full-size", self.context) container.bounds = Bounds(5, 5, 45, 45) self.assertEqual(True, container.layout_pending) self.context.process() self.assertEqual(False, container.layout_pending) self.assertImage(prefix + "half-size", self.context) for d in BoxDirection: for s in [0, 10]: for p in [Insets(0, 0, 0, 0), Insets(15, 20, 10, 5)]: for a in BoxAlign: test(d, s, p, a)
def start(self, args: dict): from alleycat.ui.blender import UI self.context = UI().create_context() window = Frame(self.context, BorderLayout()) window.bounds = Bounds(160, 70, 280, 200) panel = Panel(self.context, HBoxLayout()) panel.set_color(StyleKeys.Background, RGBA(0.3, 0.3, 0.3, 0.8)) window.add(panel, padding=Insets(10, 10, 10, 10)) icon = Canvas(self.context, self.context.toolkit.images["cat.png"]) icon.minimum_size_override = Some(Dimension(64, 64)) panel.add(icon) label = Label(self.context, text_size=18) label.set_color(StyleKeys.Text, RGBA(1, 1, 1, 1)) panel.add(label) button1 = LabelButton(self.context, text_size=16, text="Button 1") button2 = LabelButton(self.context, text_size=16, text="Button 2") buttons = Panel(self.context, HBoxLayout(spacing=10, direction=BoxDirection.Reverse)) buttons.add(button2) buttons.add(button1) window.add(buttons, Border.Bottom, Insets(0, 10, 10, 10)) def handle_button(button: str): if len(button) > 0: label.text = f"{button} is pressed" panel.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) else: label.text = "" panel.set_color(StyleKeys.Background, RGBA(0.1, 0.1, 0.1, 0.8)) button1_active = button1.observe("active").pipe( ops.map(lambda v: "Button 1" if v else "")) button2_active = button2.observe("active").pipe( ops.map(lambda v: "Button 2" if v else "")) button_active = rx.combine_latest(button1_active, button2_active).pipe( ops.map(lambda v: v[0] + v[1])) button_active.subscribe(handle_button, on_error=self.context.error_handler) window.draggable = True window.resizable = True
def test_draw_with_padding(self): image = self.context.toolkit.images[FixturePath] window = Frame(self.context) window.bounds = Bounds(0, 0, 100, 100) canvas = Canvas(self.context, image) canvas.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) window.add(canvas) def assert_padding(size: Dimension, padding: Insets): (w, h) = size.tuple (top, right, bottom, left) = padding.tuple canvas.bounds = Bounds(0, 0, w, h) canvas.padding = padding self.context.process() self.assertImage( f"draw_with_padding-{top},{right},{bottom},{left}-{w}x{h}", self.context, tolerance=Tolerance) assert_padding(Dimension(100, 100), Insets(0, 0, 0, 0)) assert_padding(Dimension(100, 100), Insets(10, 5, 3, 15)) assert_padding(Dimension(64, 64), Insets(0, 0, 0, 0)) assert_padding(Dimension(64, 64), Insets(10, 5, 3, 15))
def test_rgba_unpack(self): (r, g, b, a) = RGBA(0.1, 0.2, 0.8, 1.0) self.assertEqual(0.1, r) self.assertEqual(0.2, g) self.assertEqual(0.8, b) self.assertEqual(1.0, a)
def test_rgba_copy(self): self.assertEqual(RGBA(0.4, 0.2, 0.8, 0.3), RGBA(0.1, 0.2, 0.8, 1.0).copy(r=0.4, a=0.3)) self.assertEqual(RGBA(0.1, 0.5, 0.1, 1.0), RGBA(0.1, 0.2, 0.8, 1.0).copy(g=0.5, b=0.1)) self.assertEqual( RGBA(0.3, 0.1, 0.4, 0.4), RGBA(0.1, 0.2, 0.8, 1.0).copy(r=0.3, g=0.1, b=0.4, a=0.4)) self.assertEqual(RGBA(0.1, 0.2, 0.8, 1.0), RGBA(0.1, 0.2, 0.8, 1.0).copy())
def test_rgba_init(self): self.assertEqual(0.5, RGBA(0.5, 0.12, 0.2, 1).r) self.assertEqual(0.12, RGBA(0.5, 0.12, 0.2, 1).g) self.assertEqual(0.2, RGBA(0.5, 0.12, 0.2, 1).b) self.assertEqual(1, RGBA(0.5, 0.12, 0.2, 1).a) base = {"r": 0.5, "g": 0.5, "b": 0.5, "a": 0.5} for attr in ["r", "g", "b", "a"]: for value in [-0.1, 1.1]: args = base.copy() args[attr] = value with self.assertRaises(ValueError) as cm: RGBA(**args) self.assertEqual(f"Argument '{attr}' must be between 0 and 1.", cm.exception.args[0])
def setUp(self) -> None: super().setUp() self.container = Frame(self.context, AnchorLayout()) self.container.bounds = Bounds(0, 0, 100, 100) self.child = Panel(self.context) self.child.preferred_size_override = Some(Dimension(40, 30)) self.child.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1))
def test_lookup_color(self): lookup = StyleLookup() red = RGBA(1, 0, 0, 1) blue = RGBA(0, 0, 1, 1) red_key = "red" blue_key = "blue" lookup.set_color(red_key, red) lookup.set_color(blue_key, blue) self.assertEqual(Nothing, lookup.get_color("green")) self.assertEqual(red, lookup.get_color(red_key).unwrap()) self.assertEqual(blue, lookup.get_color(blue_key).unwrap()) lookup.clear_color(blue_key) self.assertEqual(Nothing, lookup.get_color(blue_key))
def test_draw(self): self.context.look_and_feel.set_color("Panel.background", RGBA(0, 0, 1, 0.5)) window = Window(self.context) window.bounds = Bounds(0, 0, 100, 100) panel1 = Panel(self.context) panel1.bounds = Bounds(20, 20, 40, 60) panel2 = Panel(self.context) panel2.bounds = Bounds(50, 40, 40, 40) panel2.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) window.add(panel1) window.add(panel2) self.context.process() self.assertImage("draw", self.context)
def test_on_style_change(self): lookup = StyleLookup() changes = [] lookup.on_style_change.subscribe(changes.append) self.assertEqual([], changes) lookup.set_color("color1", RGBA(1, 0, 0, 1)) lookup.set_color("color1", RGBA(1, 0, 0, 1)) # Should ignore duplicated requests. self.assertEqual( [ColorChangeEvent(lookup, "color1", Some(RGBA(1, 0, 0, 1)))], changes) lookup.set_color("color2", RGBA(0, 1, 0, 1)) self.assertEqual( [ColorChangeEvent(lookup, "color2", Some(RGBA(0, 1, 0, 1)))], changes[1:]) lookup.set_color("color2", RGBA(0, 1, 1, 1)) self.assertEqual( [ColorChangeEvent(lookup, "color2", Some(RGBA(0, 1, 1, 1)))], changes[2:]) font = ToyFontFace("Sans") lookup.set_font("font1", font) self.assertEqual([FontChangeEvent(lookup, "font1", Some(font))], changes[3:]) lookup.clear_color("color1") lookup.clear_font("font1") self.assertEqual([ColorChangeEvent(lookup, "color1", Nothing)], changes[4:5]) self.assertEqual([FontChangeEvent(lookup, "font1", Nothing)], changes[5:]) padding = Insets(5, 5, 5, 5) lookup.set_insets("padding", padding) self.assertEqual([InsetsChangeEvent(lookup, "padding", Some(padding))], changes[6:]) lookup.clear_insets("padding") self.assertEqual([InsetsChangeEvent(lookup, "padding", Nothing)], changes[7:])
def test_hbox_hide_child(self): container = Frame(self.context, HBoxLayout()) container.bounds = Bounds(0, 0, 100, 100) child1 = Panel(self.context) child1.preferred_size_override = Some(Dimension(20, 50)) child1.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) container.add(child1) child2 = Panel(self.context) child2.preferred_size_override = Some(Dimension(15, 60)) child2.minimum_size_override = Some(Dimension(15, 60)) child2.set_color(StyleKeys.Background, RGBA(0, 1, 0, 1)) container.add(child2) child3 = Panel(self.context) child3.preferred_size_override = Some(Dimension(30, 40)) child3.minimum_size_override = Some(Dimension(10, 20)) child3.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) container.add(child3) def test(visibility: Sequence[bool]): child1.visible = visibility[0] child2.visible = visibility[1] child3.visible = visibility[2] self.assertEqual(True, container.layout_pending) self.context.process() self.assertEqual(False, container.layout_pending) name = f"hbox-visibility-{'-'.join(map(str, visibility))}" self.assertImage(name, self.context) for v1 in [True, False]: for v2 in [True, False]: for v3 in [True, False]: test((v1, v2, v3))
def test_draw(self): window1 = Frame(self.context) window1.bounds = Bounds(10, 20, 80, 60) window2 = Frame(self.context) window2.bounds = Bounds(50, 40, 50, 50) window2.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) self.context.process() self.assertImage("draw", self.context)
def create_container(self, areas: Set[Border]) -> Container: container = Frame(self.context, BorderLayout()) container.bounds = Bounds(5, 5, 90, 90) if Border.Top in areas: top = Panel(self.context) top.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) top.preferred_size_override = Some(Dimension(0, 20)) container.add(top, Border.Top) if Border.Right in areas: right = Panel(self.context) right.set_color(StyleKeys.Background, RGBA(0, 1, 0, 1)) right.preferred_size_override = Some(Dimension(15, 0)) container.add(right, Border.Right) if Border.Bottom in areas: bottom = Panel(self.context) bottom.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) bottom.preferred_size_override = Some(Dimension(0, 20)) container.add(bottom, Border.Bottom) if Border.Left in areas: left = Panel(self.context) left.set_color(StyleKeys.Background, RGBA(1, 1, 1, 1)) left.preferred_size_override = Some(Dimension(5, 0)) container.add(left, Border.Left) if Border.Center in areas: center = Panel(self.context) center.set_color(StyleKeys.Background, RGBA(0, 0, 0, 1)) container.add(center, Border.Center) return container
def test_draw_children(self): window = Frame(self.context) window.bounds = Bounds(10, 20, 80, 60) window.set_color(StyleKeys.Background, RGBA(0.5, 0.5, 0.5, 1)) child1 = Panel(self.context) child1.bounds = Bounds(10, 10, 40, 40) child1.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) child2 = Panel(self.context) child2.bounds = Bounds(30, 30, 40, 40) child2.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) window.add(child1) window.add(child2) self.context.process() self.assertImage("draw_children", self.context)
def test_layout(self): container = Frame(self.context, StackLayout()) container.bounds = Bounds(0, 0, 100, 100) child1 = Panel(self.context) child1.bounds = Bounds(10, 10, 20, 20) child1.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) child2 = Panel(self.context) child2.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) child2.preferred_size_override = Some(Dimension(80, 60)) child3 = Panel(self.context) child3.set_color(StyleKeys.Background, RGBA(0, 1, 0, 1)) child3.preferred_size_override = Some(Dimension(60, 40)) container.add(child1) container.add(child2, fill=False) container.add(child3, False) self.context.process() self.assertImage("stack", self.context) child4 = Panel(self.context) child4.set_color(StyleKeys.Background, RGBA(0, 1, 1, 1)) container.add(child4, fill=True) self.context.process() self.assertImage("stack-fill", self.context) container.add(child3, True) self.context.process() self.assertImage("stack-fill2", self.context)
def test_draw(self): image = self.context.toolkit.images[FixturePath] window = Frame(self.context) window.bounds = Bounds(0, 0, 100, 100) canvas1 = Canvas(self.context) canvas1.bounds = Bounds(30, 40, 80, 30) canvas1.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) canvas2 = Canvas(self.context, image) canvas2.bounds = Bounds(0, 10, 64, 64) canvas3 = Canvas(self.context, image) canvas3.bounds = Bounds(10, 70, 80, 20) canvas3.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) window.add(canvas1) window.add(canvas2) window.add(canvas3) self.context.process() self.assertImage("draw", self.context, tolerance=Tolerance)
def __init__(self, toolkit: Toolkit) -> None: super().__init__(toolkit) def with_prefix(key: str, prefix: str) -> str: return str.join(".", [prefix, key]) active_color = RGBA(0.3, 0.7, 0.3, 1) highlight_color = RGBA(0.9, 0.8, 0.5, 1) self.set_font("text", toolkit.fonts.fallback_font) self.set_color(with_prefix(StyleKeys.Background, "Window"), RGBA(0, 0, 0, 0.8)) self.set_color(with_prefix(StyleKeys.Border, "Window"), active_color) self.set_color(with_prefix(StyleKeys.Background, "Overlay"), RGBA(0, 0, 0, 0)) self.set_color(with_prefix(StyleKeys.Border, "Overlay"), RGBA(0, 0, 0, 0)) self.set_color(with_prefix(StyleKeys.Border, "Button"), active_color) self.set_color(with_prefix(StyleKeys.BorderHover, "Button"), highlight_color) self.set_color(with_prefix(StyleKeys.BackgroundActive, "Button"), active_color) self.set_color(with_prefix(StyleKeys.BorderActive, "Button"), active_color) self.set_color(StyleKeys.Text, RGBA(0.8, 0.8, 0.8, 1)) self.set_color(with_prefix(StyleKeys.TextHover, "Button"), highlight_color) self.set_color(with_prefix(StyleKeys.TextActive, "Button"), RGBA(0, 0, 0, 1)) self.set_insets(StyleKeys.Padding, Insets(10, 10, 10, 10)) self.set_insets(with_prefix(StyleKeys.Padding, "Overlay"), Insets(0, 0, 0, 0)) self.register_ui(Window, GlassWindowUI) self.register_ui(Frame, GlassFrameUI) self.register_ui(Panel, GlassPanelUI) self.register_ui(LabelButton, GlassLabelButtonUI) self.register_ui(Button, GlassButtonUI) self.register_ui(Label, GlassLabelUI) self.register_ui(Canvas, GlassCanvasUI)
def test_draw(self): window = Window(self.context) window.bounds = Bounds(0, 0, 100, 100) button1 = LabelButton(self.context) button1.text = "Text" button1.bounds = Bounds(20, 10, 40, 20) button2 = LabelButton(self.context) button2.text = "AlleyCat" button2.text_size = 16 button2.set_color(StyleKeys.Text, RGBA(1, 0, 0, 1)) button2.bounds = Bounds(10, 50, 80, 30) window.add(button1) window.add(button2) self.context.process() self.assertImage("draw", self.context, tolerance=Tolerance)
def test_draw(self): window = Frame(self.context) window.bounds = Bounds(0, 0, 100, 60) label = Label(self.context) label.text = "Text" label.bounds = Bounds(0, 30, 60, 30) label2 = Label(self.context) label2.text = "AlleyCat" label2.text_size = 18 label2.set_color(StyleKeys.Text, RGBA(1, 0, 0, 1)) label2.bounds = Bounds(20, 0, 80, 60) window.add(label) window.add(label2) self.context.process() self.assertImage("draw", self.context, tolerance=Tolerance)
def test_rgba_from_tuple(self): self.assertEqual(RGBA(0.1, 0.2, 0.8, 1.0), RGBA.from_tuple((0.1, 0.2, 0.8, 1.0)))
def test_nested_layout(self): box = Frame(self.context, VBoxLayout()) box.bounds = Bounds(0, 0, 100, 100) child1 = Panel(self.context) child1.preferred_size_override = Some(Dimension(50, 20)) child1.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) box.add(child1) child2 = Panel(self.context, BorderLayout()) top = Panel(self.context) top.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) top.preferred_size_override = Some(Dimension(0, 20)) child2.add(top, Border.Top) right = Panel(self.context) right.set_color(StyleKeys.Background, RGBA(0, 1, 0, 1)) right.preferred_size_override = Some(Dimension(15, 0)) child2.add(right, Border.Right) bottom = Panel(self.context) bottom.set_color(StyleKeys.Background, RGBA(1, 0, 0, 1)) bottom.preferred_size_override = Some(Dimension(0, 15)) child2.add(bottom, Border.Bottom) left = Panel(self.context) left.set_color(StyleKeys.Background, RGBA(1, 1, 1, 1)) left.preferred_size_override = Some(Dimension(5, 0)) child2.add(left, Border.Left) center = Panel(self.context) center.set_color(StyleKeys.Background, RGBA(0, 0, 0, 1)) center.preferred_size_override = Some(Dimension(60, 20)) child2.add(center, Border.Center) box.add(child2) child3 = Panel(self.context) child3.preferred_size_override = Some(Dimension(40, 20)) child3.minimum_size_override = Some(Dimension(20, 10)) child3.set_color(StyleKeys.Background, RGBA(0, 0, 1, 1)) box.add(child3) self.assertEqual(True, box.layout_pending) self.context.process() self.assertEqual(False, box.layout_pending) self.assertImage("nested_layout", self.context) left.minimum_size_override = Some(Dimension(40, 0)) top.preferred_size_override = Some(Dimension(0, 10)) self.assertEqual(True, box.layout_pending) self.context.process() self.assertEqual(False, box.layout_pending) self.assertImage("nested_layout_resize_nested_child", self.context) bottom.visible = False self.assertEqual(True, box.layout_pending) self.context.process() self.assertEqual(False, box.layout_pending) self.assertImage("nested_layout_hide_nested_child", self.context)
def test_rgba_to_tuple(self): self.assertEqual((0.1, 0.2, 0.8, 1.0), RGBA(0.1, 0.2, 0.8, 1.0).tuple)