Ajoute une propriété "Ombre portée" (box-shadow), disponible sur tout widget
Nouveau groupe "Ombre" dans le panneau de propriétés, à côté de "Bordure" (même universalité — voir UNIVERSAL_CONTROLS) : décalage X/Y, flou, étendue, couleur et opacité, combinés en une seule valeur CSS box-shadow (couleur+opacité fusionnées en rgba(), un <input type="color"> seul ne portant pas de canal alpha). Décalages/flou/étendue tous à 0 = pas d'ombre, même convention que border-width à 0 = pas de bordure. Nouveau ctype "shadow" (c_shadow.py), suit exactement le même principe que le ctype "size" déjà existant (size_override_controls.py) : plusieurs entrées de formulaire pour un seul réglage, composées/décomposées dans save_element_controls.py et control_value.py plutôt que passées par le chemin générique clé->valeur. Ajoute tests/test_shadow_controls.py (présence dans le panneau, composition de la valeur CSS, aller-retour dans le formulaire, remise à zéro qui retire l'ombre). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9c9e3c5379
commit
bda082bffd
@@ -0,0 +1,56 @@
|
||||
"""Ombre portée (panneau de propriétés, tout widget) : 6 sous-réglages
|
||||
(décalage X/Y, flou, étendue, couleur, opacité) combinés en une seule
|
||||
valeur CSS box-shadow."""
|
||||
import re
|
||||
|
||||
import screens
|
||||
|
||||
|
||||
def _create_element(client, slug, widget="conteneur"):
|
||||
resp = client.post(f"/game/{slug}/screens/new", data={"name": "Accueil"}, follow_redirects=False)
|
||||
screen_id = int(re.search(r"/screens/(\d+)/edit", resp.headers["Location"]).group(1))
|
||||
resp = client.post(f"/game/{slug}/screens/{screen_id}/elements/add", data={"widget": widget}, follow_redirects=False)
|
||||
element_id = int(re.search(r"selected=(\d+)", resp.headers["Location"]).group(1))
|
||||
return screen_id, element_id
|
||||
|
||||
|
||||
def test_shadow_controls_appear_in_the_properties_panel(client, game):
|
||||
screen_id, element_id = _create_element(client, game)
|
||||
html = client.get(f"/game/{game}/screens/{screen_id}/edit?selected={element_id}").data.decode()
|
||||
assert "ctrl_box-shadow_x" in html
|
||||
assert "ctrl_box-shadow_color" in html
|
||||
|
||||
|
||||
def test_saving_a_shadow_composes_box_shadow_css(client, game):
|
||||
screen_id, element_id = _create_element(client, game)
|
||||
client.post(f"/game/{game}/elements/{element_id}/save", data={
|
||||
"ctrl_box-shadow_x": "2", "ctrl_box-shadow_y": "6", "ctrl_box-shadow_blur": "20",
|
||||
"ctrl_box-shadow_spread": "3", "ctrl_box-shadow_color": "#ff0000", "ctrl_box-shadow_opacity": "0.5",
|
||||
})
|
||||
el = screens.get_element(game, element_id)
|
||||
assert el["style"]["box-shadow"] == "2px 6px 20px 3px rgba(255, 0, 0, 0.5)"
|
||||
|
||||
|
||||
def test_shadow_value_round_trips_back_into_the_form(client, game):
|
||||
screen_id, element_id = _create_element(client, game)
|
||||
client.post(f"/game/{game}/elements/{element_id}/save", data={
|
||||
"ctrl_box-shadow_x": "2", "ctrl_box-shadow_y": "6", "ctrl_box-shadow_blur": "20",
|
||||
"ctrl_box-shadow_spread": "3", "ctrl_box-shadow_color": "#ff0000", "ctrl_box-shadow_opacity": "0.5",
|
||||
})
|
||||
html = client.get(f"/game/{game}/screens/{screen_id}/edit?selected={element_id}").data.decode()
|
||||
assert 'name="ctrl_box-shadow_x" value="2.0"' in html or 'name="ctrl_box-shadow_x" value="2"' in html
|
||||
assert 'name="ctrl_box-shadow_color" value="#ff0000"' in html
|
||||
|
||||
|
||||
def test_all_zero_offsets_remove_the_shadow(client, game):
|
||||
screen_id, element_id = _create_element(client, game)
|
||||
client.post(f"/game/{game}/elements/{element_id}/save", data={
|
||||
"ctrl_box-shadow_x": "2", "ctrl_box-shadow_y": "6", "ctrl_box-shadow_blur": "20",
|
||||
"ctrl_box-shadow_spread": "3", "ctrl_box-shadow_color": "#ff0000", "ctrl_box-shadow_opacity": "0.5",
|
||||
})
|
||||
client.post(f"/game/{game}/elements/{element_id}/save", data={
|
||||
"ctrl_box-shadow_x": "0", "ctrl_box-shadow_y": "0", "ctrl_box-shadow_blur": "0",
|
||||
"ctrl_box-shadow_spread": "0", "ctrl_box-shadow_color": "#ff0000", "ctrl_box-shadow_opacity": "0.5",
|
||||
})
|
||||
el = screens.get_element(game, element_id)
|
||||
assert "box-shadow" not in el["style"]
|
||||
Reference in New Issue
Block a user