From b65cc00b8e2c4488fcca990120f10f800775af7a Mon Sep 17 00:00:00 2001 From: Luca Raddatz Date: Tue, 7 Jan 2025 21:43:09 +0100 Subject: [PATCH] Fixes for scenes not showing --- .../kotlin/tools/aqua/bgw/elements/App.kt | 899 +++++++++--------- .../bgw/elements/uicomponents/RadioButton.kt | 7 +- .../bgw/elements/uicomponents/ToggleButton.kt | 7 +- .../bgw/components/layoutviews/CameraPane.kt | 48 +- .../tools/aqua/bgw/main/view/Application.kt | 10 +- .../aqua/bgw/main/view/HexGridGameScene.kt | 4 +- .../tools/aqua/bgw/main/view/UIScene.kt | 23 +- 7 files changed, 515 insertions(+), 483 deletions(-) diff --git a/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/App.kt b/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/App.kt index 2f98e84d5..017bebbdb 100644 --- a/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/App.kt +++ b/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/App.kt @@ -17,7 +17,6 @@ package tools.aqua.bgw.elements -import ActionProp import AppData import data.event.DragGestureExitedEventData import data.event.KeyEventAction @@ -42,501 +41,501 @@ import web.cssom.* import web.dom.Element internal external interface AppProps : Props { - var data: AppData + var data: AppData } internal val App = FC { props -> - useEffect { webSocket?.send("Hello from Client!") } - - props.data.fonts.forEach { font -> - Global { - styles { - fontFace { - fontFamily = font.second - fontStyle = FontStyle.normal - fontWeight = integer(font.third) - src = "url(static/${font.first})" + useEffect { webSocket?.send("Hello from Client!") } + + props.data.fonts.forEach { font -> + Global { + styles { + fontFace { + fontFamily = font.second + fontStyle = FontStyle.normal + fontWeight = integer(font.third) + src = "url(static/${font.first})" + } + } } - } } - } - - Global { - styles { - ".bgw-root-container" { - width = 100.pct - height = 100.pct - position = Position.absolute - left = 0.px - top = 0.px - display = Display.flex - justifyContent = JustifyContent.center - alignItems = AlignItems.center - backgroundColor = rgb(0, 0, 0, 0.0) - overflow = Overflow.hidden - containerName = bgwContainer() - containerType = ContainerType.size - } - - ".bgw-root *" { - // transformOrigin = TransformOrigin(GeometryPosition.center, GeometryPosition.center) - border = None.none - outline = None.none - } - - // BLUE - "@container bgwContainer (min-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: landscape)" { - ".bgw-root" { - fontSize = (100.0 / props.data.height).cqh - width = 100.cqw - height = 100.cqh - margin = 0.px - overflow = Overflow.hidden - userSelect = None.none - } - "bgw_scenes" { - height = 100.cqh - width = (100.0 / props.data.height * props.data.width).cqh - position = Position.relative - backgroundColor = rgb(0, 0, 0, 0.0) - overflow = Overflow.hidden - display = Display.block - } + Global { + styles { + ".bgw-root-container" { + width = 100.pct + height = 100.pct + position = Position.absolute + left = 0.px + top = 0.px + display = Display.flex + justifyContent = JustifyContent.center + alignItems = AlignItems.center + backgroundColor = rgb(0, 0, 0, 0.0) + overflow = Overflow.hidden + containerName = bgwContainer() + containerType = ContainerType.size + } - "input[type='color']" { fontSize = (100.0 / props.data.height).cqh } + ".bgw-root *" { + // transformOrigin = TransformOrigin(GeometryPosition.center, GeometryPosition.center) + border = None.none + outline = None.none + } - "bgw_togglebutton > input[type='checkbox']" { - fontSize = (100.0 / props.data.height).cqh - } - } - - // RED - "@container bgwContainer (max-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: landscape)" { - ".bgw-root" { - fontSize = (100.0 / props.data.width).cqw - width = 100.cqw - height = 100.cqh - margin = 0.px - overflow = Overflow.hidden - userSelect = None.none - } + // BLUE + "@container bgwContainer (min-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: landscape)" { + ".bgw-root" { + fontSize = (100.0 / props.data.height).cqh + width = 100.cqw + height = 100.cqh + margin = 0.px + overflow = Overflow.hidden + userSelect = None.none + } + + "bgw_scenes" { + height = 100.cqh + width = (100.0 / props.data.height * props.data.width).cqh + position = Position.relative + backgroundColor = rgb(0, 0, 0, 0.0) + overflow = Overflow.hidden + display = Display.block + } + + "input[type='color']" { fontSize = (100.0 / props.data.height).cqh } + + "bgw_togglebutton > input[type='checkbox']" { + fontSize = (100.0 / props.data.height).cqh + } + } - "bgw_scenes" { - width = 100.cqw - height = (100.0 / props.data.width * props.data.height).cqw - position = Position.relative - backgroundColor = rgb(0, 0, 0, 0.0) - overflow = Overflow.hidden - display = Display.block - } + // RED + "@container bgwContainer (max-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: landscape)" { + ".bgw-root" { + fontSize = (100.0 / props.data.width).cqw + width = 100.cqw + height = 100.cqh + margin = 0.px + overflow = Overflow.hidden + userSelect = None.none + } + + "bgw_scenes" { + width = 100.cqw + height = (100.0 / props.data.width * props.data.height).cqw + position = Position.relative + backgroundColor = rgb(0, 0, 0, 0.0) + overflow = Overflow.hidden + display = Display.block + } + + "input[type='color']" { fontSize = (100.0 / props.data.width).cqw } + + "bgw_togglebutton > input[type='checkbox']" { + fontSize = (100.0 / props.data.width).cqw + } + } - "input[type='color']" { fontSize = (100.0 / props.data.width).cqw } + // GREEN + "@container bgwContainer (min-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: portrait)" { + ".bgw-root" { + fontSize = (100.0 / props.data.height).cqh + width = 100.cqw + height = 100.cqh + margin = 0.px + overflow = Overflow.hidden + userSelect = None.none + } + + "bgw_scenes" { + height = 100.cqh + width = (100.0 / props.data.height * props.data.width).cqh + position = Position.relative + backgroundColor = rgb(0, 0, 0, 0.0) + overflow = Overflow.hidden + display = Display.block + } + + "input[type='color']" { fontSize = (100.0 / props.data.height).cqh } + + "bgw_togglebutton > input[type='checkbox']" { + fontSize = (100.0 / props.data.height).cqh + } + } - "bgw_togglebutton > input[type='checkbox']" { - fontSize = (100.0 / props.data.width).cqw - } - } - - // GREEN - "@container bgwContainer (min-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: portrait)" { - ".bgw-root" { - fontSize = (100.0 / props.data.height).cqh - width = 100.cqw - height = 100.cqh - margin = 0.px - overflow = Overflow.hidden - userSelect = None.none - } + // YELLOW + "@container bgwContainer (max-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: portrait)" { + ".bgw-root" { + fontSize = (100.0 / props.data.width).cqw + width = 100.cqw + height = 100.cqh + margin = 0.px + overflow = Overflow.hidden + userSelect = None.none + } + + "bgw_scenes" { + width = 100.cqw + height = (100.0 / props.data.width * props.data.height).cqw + position = Position.relative + backgroundColor = rgb(0, 0, 0, 1.0) + overflow = Overflow.hidden + display = Display.block + } + + "input[type='color']" { fontSize = (100.0 / props.data.width).cqw } + + "bgw_togglebutton > input[type='checkbox']" { + fontSize = (100.0 / props.data.width).cqw + } + } - "bgw_scenes" { - height = 100.cqh - width = (100.0 / props.data.height * props.data.width).cqh - position = Position.relative - backgroundColor = rgb(0, 0, 0, 0.0) - overflow = Overflow.hidden - display = Display.block - } + ".bgw-root" { + backgroundColor = rgb(0, 0, 0, 1.0) + color = rgb(0, 0, 0) + margin = 0.px + } + + ".visuals" { + width = 100.pct + height = 100.pct + position = Position.absolute + left = 0.px + top = 0.px + overflow = Overflow.hidden + } + + "bgw_color_visual, bgw_image_visual, bgw_text_visual" { + width = 100.pct + height = 100.pct + position = Position.absolute + left = 0.px + top = 0.px + display = Display.flex + } + + "bgw_scene" { + height = 100.pct + width = 100.pct + inset = 0.px + position = Position.absolute + display = Display.flex + backgroundColor = rgb(0, 0, 0, 0.0) + overflow = Overflow.hidden + } + "bgw_menu_scene > bgw_scene > bgw_visuals" { + opacity = number(DEFAULT_MENU_SCENE_OPACITY) + } + "bgw_menu_scene > bgw_scene" { + opacity = number(0.0) + backdropFilter = blur(0.px) + } + + "bgw_hexagon_view[aria-details='hex-pointy_top']" { + clipPath = polygonPath("0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%") + } + + "bgw_hexagon_view[aria-details='hex-flat_top']" { + clipPath = polygonPath("25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%") + } + + "bgw_menu_scene.scene--visible > bgw_scene" { + opacity = number(1.0) + backdropFilter = blur(DEFAULT_BLUR_RADIUS.em) + } + + "bgw_camera_pane" { overflow = Overflow.hidden } + + "bgw_camera_target" { + width = fit() + height = fit() + } - "input[type='color']" { fontSize = (100.0 / props.data.height).cqh } + "bgw_camera_target > *" { position = important(Position.relative) } + + "bgw_grid_element > *" { + position = important(Position.relative) + left = important(0.px) + top = important(0.px) + } + + ".text, .components" { position = Position.absolute } + + "bgw_linear_layout > bgw_contents > div > *" { + position = important(Position.relative) + left = important(Globals.unset) + top = important(Globals.unset) + flexGrow = number(0.0) + flexShrink = number(0.0) + } + + "bgw_card_stack > bgw_contents > *" { + position = important(Position.absolute) + left = important(Globals.unset) + top = important(Globals.unset) + flexGrow = number(0.0) + flexShrink = number(0.0) + } + + "bgw_hexagon_grid > bgw_contents > bgw_hexagon_content > *" { + position = important(Position.relative) + left = important(Globals.unset) + top = important(Globals.unset) + flexGrow = number(0.0) + flexShrink = number(0.0) + } + + "textarea::-webkit-scrollbar" { display = None.none } + + "input[type='color']::-webkit-color-swatch" { + borderRadius = 3.em + border = None.none + } - "bgw_togglebutton > input[type='checkbox']" { - fontSize = (100.0 / props.data.height).cqh + "bgw_togglebutton" { + position = Position.relative + display = Display.inlineFlex + width = 30.em + height = 18.em + } + + "bgw_togglebutton > input[type='checkbox']" { + opacity = number(0.0) + position = Position.relative + width = 36.em + minWidth = 36.em + height = 100.pct + } + + ".toggle" { + position = Position.absolute + left = 4.em + width = 30.em + height = 18.em + backgroundColor = rgb(145, 145, 145) + transition = transition(300, "background-color") + borderRadius = 3.em + } + + ".toggle::before" { + content = Content("") + position = Position.absolute + width = 12.em + height = 12.em + left = 3.em + top = 3.em + backgroundColor = rgb(255, 255, 255) + transition = transition(300, "transform") + borderRadius = 3.em + } + + "bgw_togglebutton > input[type='checkbox']:checked + .toggle" { + backgroundColor = rgb(0, 117, 255) + } + + "bgw_togglebutton > input[type='checkbox']:checked + .toggle::before" { + transform = translatex(12.em) + } + + ".bgw-root" { + width = 100.pct + height = 100.pct + position = Position.absolute + left = 0.px + top = 0.px + display = Display.flex + justifyContent = JustifyContent.center + alignItems = AlignItems.center + backgroundColor = rgb(0, 0, 0, 1.0) + overflow = Overflow.hidden + } + + ".bgw-root *[aria-roledescription='draggable'][aria-pressed='true']" { + // position = important(Position.fixed) + opacity = important(number(1.0)) + zIndex = important(integer(1000000)) + } + + ".bgw-root *:has(*[aria-roledescription='draggable'][aria-pressed='true'])" { + zIndex = important(integer(1000000)) + } } - } - - // YELLOW - "@container bgwContainer (max-aspect-ratio: ${props.data.width}/${props.data.height}) and (orientation: portrait)" { - ".bgw-root" { - fontSize = (100.0 / props.data.width).cqw - width = 100.cqw - height = 100.cqh - margin = 0.px - overflow = Overflow.hidden - userSelect = None.none + } + + /* div { + id = "bgw_loading" + css { + position = Position.fixed + width = 100.pct + height = 100.pct + backgroundColor = rgb(20,20,20, 1.0) + overflow = Overflow.hidden + display = Display.flex + justifyContent = JustifyContent.center + alignItems = AlignItems.center + zIndex = integer(5000000) } - "bgw_scenes" { - width = 100.cqw - height = (100.0 / props.data.width * props.data.height).cqw - position = Position.relative - backgroundColor = rgb(0, 0, 0, 1.0) - overflow = Overflow.hidden - display = Display.block + img { + src = "logo_animated.svg" } - "input[type='color']" { fontSize = (100.0 / props.data.width).cqw } + /* useEffect { + val loadingSVG = document.createElement("svg") + loadingSVG.id = "eRjslcmEZrC1" + loadingSVG.setAttribute("xmlns", "http://www.w3.org/2000/svg") + loadingSVG.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink") + loadingSVG.setAttribute("viewBox", "0 0 262.985 228.649") + loadingSVG.setAttribute("shape-rendering", "geometricPrecision") + loadingSVG.setAttribute("text-rendering", "geometricPrecision") + loadingSVG.setAttribute("width", "2560") + loadingSVG.setAttribute("height", "1313") + + loadingSVG.innerHTML = """""".trimIndent() + + document.getElementById("bgw_loading")?.appendChild(loadingSVG) + } */ + } */ - "bgw_togglebutton > input[type='checkbox']" { - fontSize = (100.0 / props.data.width).cqw + val (lastDraggedOver, setLastDraggedOver) = useState(null) + val draggedElementRef = useRef(null) + + val pointerSensor = + useSensor( + PointerSensor, + jsObject { activationConstraint = jsObject { distance = 10 } }) + + val allSensors = useSensors(pointerSensor) + + val measuringConfig = + jsObject { + draggable = + jsObject { + measure = { node -> getClientRect(node, jsObject { ignoreTransform = false }) } + } + droppable = + jsObject { + measure = { node -> getClientRect(node, jsObject { ignoreTransform = true }) } + strategy = MeasuringStrategy.BeforeDragging + frequency = MeasuringFrequency.Optimized + } + dragOverlay = + jsObject { + measure = { node -> getClientRect(node, jsObject { ignoreTransform = false }) } + } } - } - - ".bgw-root" { - backgroundColor = rgb(0, 0, 0, 1.0) - color = rgb(0, 0, 0) - margin = 0.px - } - - ".visuals" { - width = 100.pct - height = 100.pct - position = Position.absolute - left = 0.px - top = 0.px - overflow = Overflow.hidden - } - - "bgw_color_visual, bgw_image_visual, bgw_text_visual" { - width = 100.pct - height = 100.pct - position = Position.absolute - left = 0.px - top = 0.px - display = Display.flex - } - - "bgw_scene" { - height = 100.pct - width = 100.pct - inset = 0.px - position = Position.absolute - display = Display.flex - backgroundColor = rgb(0, 0, 0, 0.0) - overflow = Overflow.hidden - } - "bgw_menu_scene > bgw_scene > bgw_visuals" { - opacity = number(DEFAULT_MENU_SCENE_OPACITY) - } - "bgw_menu_scene > bgw_scene" { - opacity = number(0.0) - backdropFilter = blur(0.px) - } - - "bgw_hexagon_view[aria-details='hex-pointy_top']" { - clipPath = polygonPath("0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%") - } - - "bgw_hexagon_view[aria-details='hex-flat_top']" { - clipPath = polygonPath("25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%") - } - - "bgw_menu_scene.scene--visible > bgw_scene" { - opacity = number(1.0) - backdropFilter = blur(DEFAULT_BLUR_RADIUS.em) - } - - "bgw_camera_pane" { overflow = Overflow.hidden } - - "bgw_camera_target" { - width = fit() - height = fit() - } - - "bgw_camera_target > *" { position = important(Position.relative) } - - "bgw_grid_element > *" { - position = important(Position.relative) - left = important(0.px) - top = important(0.px) - } - - ".text, .components" { position = Position.absolute } - - "bgw_linear_layout > bgw_contents > div > *" { - position = important(Position.relative) - left = important(Globals.unset) - top = important(Globals.unset) - flexGrow = number(0.0) - flexShrink = number(0.0) - } - - "bgw_card_stack > bgw_contents > *" { - position = important(Position.absolute) - left = important(Globals.unset) - top = important(Globals.unset) - flexGrow = number(0.0) - flexShrink = number(0.0) - } - - "bgw_hexagon_grid > bgw_contents > bgw_hexagon_content > *" { - position = important(Position.relative) - left = important(Globals.unset) - top = important(Globals.unset) - flexGrow = number(0.0) - flexShrink = number(0.0) - } - - "textarea::-webkit-scrollbar" { display = None.none } - - "input[type='color']::-webkit-color-swatch" { - borderRadius = 3.em - border = None.none - } - - "bgw_togglebutton" { - position = Position.relative - display = Display.inlineFlex - width = 30.em - height = 18.em - } - - "bgw_togglebutton > input[type='checkbox']" { - opacity = number(0.0) - position = Position.relative - width = 36.em - minWidth = 36.em - height = 100.pct - } - - ".toggle" { - position = Position.absolute - left = 4.em - width = 30.em - height = 18.em - backgroundColor = rgb(145, 145, 145) - transition = transition(300, "background-color") - borderRadius = 3.em - } - - ".toggle::before" { - content = Content("") - position = Position.absolute - width = 12.em - height = 12.em - left = 3.em - top = 3.em - backgroundColor = rgb(255, 255, 255) - transition = transition(300, "transform") - borderRadius = 3.em - } - - "bgw_togglebutton > input[type='checkbox']:checked + .toggle" { - backgroundColor = rgb(0, 117, 255) - } - - "bgw_togglebutton > input[type='checkbox']:checked + .toggle::before" { - transform = translatex(12.em) - } - - ".bgw-root" { - width = 100.pct - height = 100.pct - position = Position.absolute - left = 0.px - top = 0.px - display = Display.flex - justifyContent = JustifyContent.center - alignItems = AlignItems.center - backgroundColor = rgb(0, 0, 0, 1.0) - overflow = Overflow.hidden - } - - ".bgw-root *[aria-roledescription='draggable'][aria-pressed='true']" { - // position = important(Position.fixed) - opacity = important(number(1.0)) - zIndex = important(integer(1000000)) - } - - ".bgw-root *:has(*[aria-roledescription='draggable'][aria-pressed='true'])" { - zIndex = important(integer(1000000)) - } - } - } - - /* div { - id = "bgw_loading" - css { - position = Position.fixed - width = 100.pct - height = 100.pct - backgroundColor = rgb(20,20,20, 1.0) - overflow = Overflow.hidden - display = Display.flex - justifyContent = JustifyContent.center - alignItems = AlignItems.center - zIndex = integer(5000000) - } - - img { - src = "logo_animated.svg" - } - - /* useEffect { - val loadingSVG = document.createElement("svg") - loadingSVG.id = "eRjslcmEZrC1" - loadingSVG.setAttribute("xmlns", "http://www.w3.org/2000/svg") - loadingSVG.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink") - loadingSVG.setAttribute("viewBox", "0 0 262.985 228.649") - loadingSVG.setAttribute("shape-rendering", "geometricPrecision") - loadingSVG.setAttribute("text-rendering", "geometricPrecision") - loadingSVG.setAttribute("width", "2560") - loadingSVG.setAttribute("height", "1313") - - loadingSVG.innerHTML = """""".trimIndent() - - document.getElementById("bgw_loading")?.appendChild(loadingSVG) - } */ - } */ - - val (lastDraggedOver, setLastDraggedOver) = useState(null) - val draggedElementRef = useRef(null) - - val pointerSensor = - useSensor( - PointerSensor, - jsObject { activationConstraint = jsObject { distance = 10 } }) - - val allSensors = useSensors(pointerSensor) - - val measuringConfig = - jsObject { - draggable = - jsObject { - measure = { node -> getClientRect(node, jsObject { ignoreTransform = false }) } - } - droppable = - jsObject { - measure = { node -> getClientRect(node, jsObject { ignoreTransform = true }) } - strategy = MeasuringStrategy.BeforeDragging - frequency = MeasuringFrequency.Optimized - } - dragOverlay = - jsObject { - measure = { node -> getClientRect(node, jsObject { ignoreTransform = false }) } - } - } - - DndContext { - sensors = allSensors - // measuring = measuringConfig - - onDragStart = { event -> - val element = event.active?.id?.let { document.getElementById(it) } - draggedElementRef.current = element - JCEFEventDispatcher.dispatchEvent(event.toDragStartedEventData()) - } - onDragEnd = { event -> - if (event.over != null) { - JCEFEventDispatcher.dispatchEvent(event.toDragEventData()) - } - JCEFEventDispatcher.dispatchEvent(event.toDragEndedEventData()) - if (lastDraggedOver != null) { - JCEFEventDispatcher.dispatchEvent( - DragGestureExitedEventData(lastDraggedOver).apply { this.id = event.active?.id }) - } - setLastDraggedOver(null) - } + DndContext { + sensors = allSensors + // measuring = measuringConfig - onDragMove = { event -> JCEFEventDispatcher.dispatchEvent(event.toDragMoveEventData()) } + onDragStart = { event -> + val element = event.active?.id?.let { document.getElementById(it) } + draggedElementRef.current = element + JCEFEventDispatcher.dispatchEvent(event.toDragStartedEventData()) + } - onDragOver = { event -> - JCEFEventDispatcher.dispatchEvent(event.toDragEnteredEventData()) - if (lastDraggedOver != event.over?.id) { - if (lastDraggedOver != null) { - JCEFEventDispatcher.dispatchEvent( - DragGestureExitedEventData(lastDraggedOver).apply { this.id = event.active?.id }) + onDragEnd = { event -> + if (event.over != null) { + JCEFEventDispatcher.dispatchEvent(event.toDragEventData()) + } + JCEFEventDispatcher.dispatchEvent(event.toDragEndedEventData()) + if (lastDraggedOver != null) { + JCEFEventDispatcher.dispatchEvent( + DragGestureExitedEventData(lastDraggedOver).apply { this.id = event.active?.id }) + } + setLastDraggedOver(null) } - setLastDraggedOver(event.over?.id) - } - } - fun globalKeyDown(e: KeyboardEvent<*>) { - JCEFEventDispatcher.dispatchGlobalEvent(e.toKeyEventData("global", KeyEventAction.PRESS)) - JCEFEventDispatcher.dispatchGlobalEvent(e.toKeyEventData("global", KeyEventAction.TYPE)) - } + onDragMove = { event -> JCEFEventDispatcher.dispatchEvent(event.toDragMoveEventData()) } - fun globalKeyUp(e: KeyboardEvent<*>) { - JCEFEventDispatcher.dispatchGlobalEvent( - e.toKeyEventData("global", KeyEventAction.RELEASE)) - } + onDragOver = { event -> + JCEFEventDispatcher.dispatchEvent(event.toDragEnteredEventData()) + if (lastDraggedOver != event.over?.id) { + if (lastDraggedOver != null) { + JCEFEventDispatcher.dispatchEvent( + DragGestureExitedEventData(lastDraggedOver).apply { this.id = event.active?.id }) + } + setLastDraggedOver(event.over?.id) + } + } - useEffectWithCleanup { - document.addEventListener("keydown", { globalKeyDown(it.unsafeCast>()) }) + fun globalKeyDown(e: KeyboardEvent<*>) { + JCEFEventDispatcher.dispatchGlobalEvent(e.toKeyEventData("global", KeyEventAction.PRESS)) + JCEFEventDispatcher.dispatchGlobalEvent(e.toKeyEventData("global", KeyEventAction.TYPE)) + } - document.addEventListener("keyup", { globalKeyUp(it.unsafeCast>()) }) + fun globalKeyUp(e: KeyboardEvent<*>) { + JCEFEventDispatcher.dispatchGlobalEvent( + e.toKeyEventData("global", KeyEventAction.RELEASE) + ) + } - onCleanup { - document.removeEventListener( - "keydown", { globalKeyDown(it.unsafeCast>()) }) + useEffectWithCleanup { + document.addEventListener("keydown", { globalKeyDown(it.unsafeCast>()) }) - document.removeEventListener( - "keyup", { globalKeyUp(it.unsafeCast>()) }) - } - } + document.addEventListener("keyup", { globalKeyUp(it.unsafeCast>()) }) - bgwScenes { - val gameScene = props.data.gameScene - if (gameScene != null) { - bgwGameScene { - id = "boardGameScene" - +SceneBuilder.build(gameScene) - } - } - val menuScene = props.data.menuScene - if (menuScene != null) { - bgwMenuScene { - id = "menuScene" - if (props.data.action !== ActionProp.HIDE_MENU_SCENE && - props.data.action !== ActionProp.SHOW_MENU_SCENE) { - className = ClassName("scene--visible") - } - +SceneBuilder.build(menuScene) + onCleanup { + document.removeEventListener( + "keydown", { globalKeyDown(it.unsafeCast>()) }) + + document.removeEventListener( + "keyup", { globalKeyUp(it.unsafeCast>()) }) + } } - } - } - DragOverlay { className = ClassName("bgw_drag_overlay") } + bgwScenes { + val gameScene = props.data.gameScene + bgwGameScene { + id = "boardGameScene" - /* DragOverlay { - if (draggedElementRef.current != null) { - createPortal( - draggedElementRef.current!!.unsafeCast(), - document.body.unsafeCast() - ) + if (gameScene != null) { + +SceneBuilder.build(gameScene) + } + } + val menuScene = props.data.menuScene + bgwMenuScene { + id = "menuScene" + if (menuScene != null) { + className = ClassName("scene--visible") + + +SceneBuilder.build(menuScene) + } + } } - } */ - } + + DragOverlay { className = ClassName("bgw_drag_overlay") } + + /* DragOverlay { + if (draggedElementRef.current != null) { + createPortal( + draggedElementRef.current!!.unsafeCast(), + document.body.unsafeCast() + ) + } + } */ + } } internal inline val bgwScenes: IntrinsicType> - get() = "bgw_scenes".unsafeCast>>() + get() = "bgw_scenes".unsafeCast>>() internal inline val bgwMenuScene: IntrinsicType> - get() = "bgw_menu_scene".unsafeCast>>() + get() = "bgw_menu_scene".unsafeCast>>() internal inline val bgwGameScene: IntrinsicType> - get() = "bgw_game_scene".unsafeCast>>() + get() = "bgw_game_scene".unsafeCast>>() internal inline val bgwVisuals: IntrinsicType> - get() = "bgw_visuals".unsafeCast>>() + get() = "bgw_visuals".unsafeCast>>() internal inline val bgwContents: IntrinsicType> - get() = "bgw_contents".unsafeCast>>() + get() = "bgw_contents".unsafeCast>>() internal inline val bgwText: IntrinsicType> - get() = "bgw_text".unsafeCast>>() + get() = "bgw_text".unsafeCast>>() internal fun polygonPath( value: String, @@ -557,7 +556,7 @@ internal fun transition(duration: Int, property: String): Transition = internal fun transitionAll(duration: Int): Transition = "${duration}ms".unsafeCast() internal inline fun jsObject(builder: T.() -> Unit): T { - val obj = js("{}") - builder(obj.unsafeCast()) - return obj.unsafeCast() + val obj = js("{}") + builder(obj.unsafeCast()) + return obj.unsafeCast() } diff --git a/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/RadioButton.kt b/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/RadioButton.kt index 1bf33e62b..4c76c0700 100644 --- a/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/RadioButton.kt +++ b/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/RadioButton.kt @@ -40,8 +40,8 @@ internal external interface RadioButtonProps : Props { } internal fun PropertiesBuilder.cssBuilderIntern(componentViewData: RadioButtonData) { - cssBuilder(componentViewData) display = Display.flex + cssBuilder(componentViewData) alignItems = AlignItems.center justifyItems = JustifyItems.flexStart gap = 10.em @@ -61,7 +61,10 @@ internal val RadioButton = bgwRadioButton { id = props.data.id className = ClassName("textField") - css { cssBuilderIntern(props.data) } + css { + cssBuilderIntern(props.data) + cursor = Cursor.pointer + } ref = elementRef useEffect { elementRef.current?.let { droppable.setNodeRef(it) } } diff --git a/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/ToggleButton.kt b/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/ToggleButton.kt index 2ba4dd558..7f93476f2 100644 --- a/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/ToggleButton.kt +++ b/bgw-gui/src/jsMain/kotlin/tools/aqua/bgw/elements/uicomponents/ToggleButton.kt @@ -41,8 +41,8 @@ internal external interface ToggleButtonProps : Props { } internal fun PropertiesBuilder.cssBuilderIntern(componentViewData: ToggleButtonData) { - cssBuilder(componentViewData) display = Display.flex + cssBuilder(componentViewData) alignItems = AlignItems.center justifyItems = JustifyItems.flexStart gap = 10.em @@ -62,7 +62,10 @@ internal val ToggleButton = bgwToggleButton { id = props.data.id className = ClassName("textField") - css { cssBuilderIntern(props.data) } + css { + cssBuilderIntern(props.data) + cursor = Cursor.pointer + } ref = elementRef useEffect { elementRef.current?.let { droppable.setNodeRef(it) } } diff --git a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/components/layoutviews/CameraPane.kt b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/components/layoutviews/CameraPane.kt index ca108a1d5..7ba8fa30c 100644 --- a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/components/layoutviews/CameraPane.kt +++ b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/components/layoutviews/CameraPane.kt @@ -29,15 +29,21 @@ import tools.aqua.bgw.visual.Visual /** * A pane representing a camera view that can be used to display and manipulate a target layout * view. + * + * @param T The type of the [target] [LayoutView]. Must extend the [LayoutView] class. * @param posX The x-coordinate of the camera pane's position on the screen. Default is 0. * @param posY The y-coordinate of the camera pane's position on the screen. Default is 0. * @param width The width of the camera pane. * @param height The height of the camera pane. * @param visual The visual representation of the camera pane. Default is an empty visual. - * @param target The target layout view that this camera pane will display. + * @param target The target [LayoutView] that this camera pane will display. * @param limitBounds Whether the target layout view should be limited to the bounds of the camera * pane. Default is true. - * @param T The type of the target layout view. Must extend the LayoutView class. + * + * @see GridPane + * @see Pane + * + * @since 0.8 */ open class CameraPane>( posX: Number = 0, @@ -50,14 +56,13 @@ open class CameraPane>( ) : ComponentView(posX = posX, posY = posY, width = width, height = height, visual = visual) { /** * [Property] for the [zoom] state of the [CameraPane]. - * - * @see zoom */ internal val zoomProperty: DoubleProperty = DoubleProperty(1) internal var internalData: InternalCameraPanData = InternalCameraPanData() - /** Zoom factor of the camera starting from 1. */ + /** Zoom factor of the camera starting from 1. + */ var zoom: Double get() = zoomProperty.value set(value) { @@ -66,14 +71,14 @@ open class CameraPane>( /** * [Property] for the [interactive] state of the [CameraPane]. - * - * @see zoom */ internal val interactiveProperty: BooleanProperty = BooleanProperty(false) /** * Determines if the camera pane is interactive, which means that you can scroll to zoom and drag - * to move around. + * to pan around. + * + * @see panMouseButton */ var interactive: Boolean get() = interactiveProperty.value @@ -84,7 +89,11 @@ open class CameraPane>( /** [Property] for the [limitBounds] state of the [CameraPane]. */ internal val limitBoundsProperty = BooleanProperty(limitBounds) - /** Determines if the target layout view should be limited to the bounds of the camera pane. */ + /** Determines if the target layout view should be limited to the bounds of the camera pane. + * This will also affect the panning of the camera pane with [pan] and [panBy] as well as zooming. + * + * @since 1.0 + */ var limitBounds: Boolean get() = limitBoundsProperty.value set(value) { @@ -117,7 +126,12 @@ open class CameraPane>( internal val panMouseButtonProperty: Property = Property(MouseButtonType.LEFT_BUTTON) - /** The mouse button that is used to pan the camera pane. */ + /** The mouse button that is used to pan the camera pane. + * + * @see interactive + * + * @since 0.9 + */ var panMouseButton: MouseButtonType get() = panMouseButtonProperty.value set(value) { @@ -132,6 +146,8 @@ open class CameraPane>( * Gets invoked whenever the camera pane is zoomed. * * @see zoom + * + * @since 1.0 */ var onZoomed: ((Number) -> Unit)? = null @@ -146,6 +162,10 @@ open class CameraPane>( * @param smooth Whether the pan should be smooth or instant. * * @see limitBounds + * @see pan + * @see panBy + * + * @since 1.0 */ fun pan(x: Number, y: Number, zoom: Double, smooth: Boolean = true) { panData = @@ -166,6 +186,8 @@ open class CameraPane>( * @param smooth Whether the pan should be smooth or instant. * * @see limitBounds + * @see pan + * @see panBy */ fun pan(x: Number, y: Number, smooth: Boolean = true) { if (panData.zoomOnly) { @@ -188,6 +210,10 @@ open class CameraPane>( * @param smooth Whether the pan should be smooth or instant. * * @see limitBounds + * @see pan + * @see panBy + * + * @since 1.0 */ fun panBy(xOffset: Number, yOffset: Number, zoom: Double, smooth: Boolean = true) { panData = @@ -207,6 +233,8 @@ open class CameraPane>( * @param smooth Whether the pan should be smooth or instant. * * @see limitBounds + * @see pan + * @see panBy */ fun panBy(xOffset: Number, yOffset: Number, smooth: Boolean = true) { if (panData.zoomOnly) { diff --git a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/Application.kt b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/Application.kt index 945f1558f..678153062 100644 --- a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/Application.kt +++ b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/Application.kt @@ -25,19 +25,19 @@ internal object Application : BoardGameApplication(aspectRatio = AspectRatio.of( private val hexGrid = HexGridGameScene() private val animation = AnimationScene() val menuScene = MyMenuScene() - private val uiScene = UIScene() + val uiScene = UIScene() private val dragDropScene = DragDropScene() private val visualScene = VisualScene() - private val cardLayoutScene = CardLayoutScene() + val cardLayoutScene = CardLayoutScene() init { loadFont("Rubik.ttf") - showGameScene(cardLayoutScene) - // showGameScene(hexGrid) + // showGameScene(cardLayoutScene) + showGameScene(hexGrid) // showGameScene(animation) // showGameScene(grid) // showGameScene(dragDropScene) - // showMenuScene(uiScene) + showMenuScene(uiScene) // showGameScene(visualScene) } } diff --git a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/HexGridGameScene.kt b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/HexGridGameScene.kt index 22d816141..8ebf7819d 100644 --- a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/HexGridGameScene.kt +++ b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/HexGridGameScene.kt @@ -141,7 +141,9 @@ internal class HexGridGameScene : BoardGameScene() { height = 50, text = "Zoom", visual = ColorVisual(Color(0, 255, 0))) - .apply { onMouseClicked = { cameraPane.limitBounds = !cameraPane.limitBounds } } + .apply { onMouseClicked = { + Application.showGameScene(Application.cardLayoutScene) + } } private val hexPointy = HexagonView( diff --git a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/UIScene.kt b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/UIScene.kt index 36e330026..7de0237eb 100644 --- a/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/UIScene.kt +++ b/bgw-gui/src/jvmMain/kotlin/tools/aqua/bgw/main/view/UIScene.kt @@ -43,8 +43,8 @@ internal class UIScene : MenuScene() { private val toggleGroup = ToggleGroup().apply { - onSelected = { button -> println("Selected: ${button.text}") } - onDeselected = { button -> println("Deselected: ${button.text}") } + //onSelected = { button -> println("Selected: ${button.text}") } + //onDeselected = { button -> println("Deselected: ${button.text}") } } private val toggle = @@ -56,10 +56,13 @@ internal class UIScene : MenuScene() { text = "Toggle", font = Font(20.0, Color.BLACK, "JetBrainsMono", Font.FontWeight.EXTRA_BOLD), visual = ColorVisual(Color.GREEN), - toggleGroup = toggleGroup, alignment = Alignment.CENTER, ) - .apply { onMouseClicked = { textfield.text = "Toggled" } } + .apply { + onMouseClicked = { + Application.hideMenuScene() + } + } private val toggle2 = ToggleButton( @@ -69,16 +72,10 @@ internal class UIScene : MenuScene() { height = 100, text = "Indeterminate", font = Font(20.0, Color.BLACK, "JetBrainsMono", Font.FontWeight.EXTRA_BOLD), - visual = ColorVisual(Color.ORANGE), - toggleGroup = toggleGroup) + visual = ColorVisual(Color.ORANGE)) .apply { - onSelected = { - println("Setting to indeterminate") - checkBox.isIndeterminate = true - } - onDeselected = { - println("Setting to not indeterminate") - checkBox.isIndeterminate = false + onMouseClicked = { + Application.showGameScene(Application.cardLayoutScene) } }