diff options
author | Joffrey Bion <joffrey.bion@booking.com> | 2020-03-28 13:50:35 +0100 |
---|---|---|
committer | Joffrey Bion <joffrey.bion@booking.com> | 2020-03-28 13:50:35 +0100 |
commit | 856dbcba2abb78d889045e96f47b6727b230359e (patch) | |
tree | bf4cfd236082bd0af7e75c7de050f832f9a6017c | |
parent | Add board components (diff) | |
download | seven-wonders-856dbcba2abb78d889045e96f47b6727b230359e.tar.gz seven-wonders-856dbcba2abb78d889045e96f47b6727b230359e.tar.bz2 seven-wonders-856dbcba2abb78d889045e96f47b6727b230359e.zip |
Add hand components
6 files changed, 251 insertions, 23 deletions
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt index c538b3bf..24c640b2 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt @@ -5,17 +5,27 @@ import org.luxons.sevenwonders.model.api.PlayerDTO import org.luxons.sevenwonders.model.boards.Requirements import org.luxons.sevenwonders.model.resources.ResourceTransactions +interface Card { + val name: String + val color: Color + val requirements: Requirements + val chainParent: String? + val chainChildren: List<String> + val image: String + val back: CardBack +} + @Serializable data class TableCard( - val name: String, - val color: Color, - val requirements: Requirements, - val chainParent: String?, - val chainChildren: List<String>, - val image: String, - val back: CardBack, + override val name: String, + override val color: Color, + override val requirements: Requirements, + override val chainParent: String?, + override val chainChildren: List<String>, + override val image: String, + override val back: CardBack, val playedDuringLastMove: Boolean -) +) : Card /** * A card with contextual information relative to the hand it is sitting in. The extra information is especially useful @@ -23,15 +33,15 @@ data class TableCard( */ @Serializable data class HandCard( - val name: String, - val color: Color, - val requirements: Requirements, - val chainParent: String?, - val chainChildren: List<String>, - val image: String, - val back: CardBack, + override val name: String, + override val color: Color, + override val requirements: Requirements, + override val chainParent: String?, + override val chainChildren: List<String>, + override val image: String, + override val back: CardBack, val playability: CardPlayability -) +) : Card @Serializable data class PreparedCard( diff --git a/sw-ui-kt/src/main/kotlin/blueprintjs.kt b/sw-ui-kt/src/main/kotlin/blueprintjs.kt index 2a2bfdce..eaf36618 100644 --- a/sw-ui-kt/src/main/kotlin/blueprintjs.kt +++ b/sw-ui-kt/src/main/kotlin/blueprintjs.kt @@ -213,6 +213,45 @@ external class Button : AbstractButton { external class AnchorButton : AbstractButton { override fun render(): ReactElement } + +external interface IButtonGroupProps : IProps { + /** + * Text alignment within button. By default, icons and text will be centered + * within the button. Passing `"left"` or `"right"` will align the button + * text to that side and push `icon` and `rightIcon` to either edge. Passing + * `"center"` will center the text and icons together. + */ + var alignText: Alignment? + + /** + * Whether the button group should take up the full width of its container. + * @default false + */ + var fill: Boolean? + + /** + * Whether the child buttons should appear with minimal styling. + * @default false + */ + var minimal: Boolean? + + /** + * Whether the child buttons should appear with large styling. + * @default false + */ + var large: Boolean? + + /** + * Whether the button group should appear with vertical styling. + * @default false + */ + var vertical: Boolean? +} + +external class ButtonGroup : PureComponent<IButtonGroupProps, RState> { + override fun render(): ReactElement? +} + external interface IInputGroupProps : IControlledProps, IIntentProps, IProps { /** * Whether the input is non-interactive. diff --git a/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt b/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt index 1b20423c..22489c86 100644 --- a/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt +++ b/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt @@ -52,6 +52,12 @@ fun RBuilder.bpButton( block() } +fun RBuilder.bpButtonGroup( + block: RHandler<IButtonGroupProps> = {} +): ReactElement = child(ButtonGroup::class) { + block() +} + fun RBuilder.bpInputGroup( large: Boolean = false, placeholder: String = "", diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/CardImage.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/CardImage.kt index b7abbeff..38afe028 100644 --- a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/CardImage.kt +++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/CardImage.kt @@ -2,20 +2,24 @@ package org.luxons.sevenwonders.ui.components.game import kotlinx.css.CSSBuilder import kotlinx.css.Color +import kotlinx.css.borderRadius +import kotlinx.css.pct import kotlinx.css.properties.boxShadow import kotlinx.css.px import kotlinx.css.rem import kotlinx.html.IMG import kotlinx.html.title -import org.luxons.sevenwonders.model.cards.TableCard +import org.luxons.sevenwonders.model.cards.Card import react.RBuilder import styled.StyledDOMBuilder import styled.css import styled.styledImg -fun RBuilder.cardImage(card: TableCard, highlightColor: Color? = null, block: StyledDOMBuilder<IMG>.() -> Unit = {}) { +fun RBuilder.cardImage(card: Card, highlightColor: Color? = null, block: StyledDOMBuilder<IMG>.() -> Unit = {}) { styledImg(src = "/images/cards/${card.image}") { css { + borderRadius = 5.pct + boxShadow(offsetX = 2.px, offsetY = 2.px, blurRadius = 5.px, color = Color.black) highlightStyle(highlightColor) } attrs { diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt index 2b6136af..11ce09c1 100644 --- a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt +++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt @@ -3,6 +3,7 @@ package org.luxons.sevenwonders.ui.components.game import com.palantir.blueprintjs.Intent import com.palantir.blueprintjs.bpButton import com.palantir.blueprintjs.bpNonIdealState +import com.palantir.blueprintjs.org.luxons.sevenwonders.ui.components.game.handComponent import kotlinx.css.CSSBuilder import kotlinx.css.Overflow import kotlinx.css.Position @@ -84,11 +85,11 @@ private class GameScene(props: GameSceneProps) : RComponent<GameSceneProps, RSta div { p { + turnInfo.message } boardComponent(board = board) -// handComponent( -// cards = turnInfo.hand, -// wonderUpgradable = turnInfo.wonderBuildability.isBuildable, -// prepareMove = props.prepareMove -// ) + handComponent( + cards = turnInfo.hand, + wonderUpgradable = turnInfo.wonderBuildability.isBuildable, + prepareMove = props.prepareMove + ) productionBar( gold = board.gold, production = board.production diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt new file mode 100644 index 00000000..9aac310a --- /dev/null +++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt @@ -0,0 +1,168 @@ +package com.palantir.blueprintjs.org.luxons.sevenwonders.ui.components.game + +import com.palantir.blueprintjs.Intent +import com.palantir.blueprintjs.bpButton +import com.palantir.blueprintjs.bpButtonGroup +import kotlinx.css.Align +import kotlinx.css.CSSBuilder +import kotlinx.css.Color +import kotlinx.css.Display +import kotlinx.css.GridColumn +import kotlinx.css.GridRow +import kotlinx.css.Position +import kotlinx.css.alignItems +import kotlinx.css.bottom +import kotlinx.css.display +import kotlinx.css.filter +import kotlinx.css.gridColumn +import kotlinx.css.gridRow +import kotlinx.css.height +import kotlinx.css.left +import kotlinx.css.margin +import kotlinx.css.maxHeight +import kotlinx.css.maxWidth +import kotlinx.css.pct +import kotlinx.css.position +import kotlinx.css.properties.boxShadow +import kotlinx.css.properties.s +import kotlinx.css.properties.transform +import kotlinx.css.properties.transition +import kotlinx.css.properties.translate +import kotlinx.css.px +import kotlinx.css.rem +import kotlinx.css.vh +import kotlinx.css.vw +import kotlinx.css.width +import kotlinx.css.zIndex +import kotlinx.html.DIV +import org.luxons.sevenwonders.model.MoveType +import org.luxons.sevenwonders.model.PlayerMove +import org.luxons.sevenwonders.model.cards.HandCard +import org.luxons.sevenwonders.ui.components.game.cardImage +import react.RBuilder +import styled.StyledDOMBuilder +import styled.css +import styled.styledDiv + +fun RBuilder.handComponent( + cards: List<HandCard>, + wonderUpgradable: Boolean, + prepareMove: (PlayerMove) -> Unit +) { + styledDiv { + css { + handStyle() + } + cards.forEachIndexed { index, c -> + handCard(card = c, wonderUpgradable = wonderUpgradable, prepareMove = prepareMove) { + attrs { + key = index.toString() + } + } + } + } +} + +private fun RBuilder.handCard( + card: HandCard, + wonderUpgradable: Boolean, + prepareMove: (PlayerMove) -> Unit, + block: StyledDOMBuilder<DIV>.() -> Unit +) { + styledDiv { + css { + handCardStyle() + } + block() + cardImage(card) { + css { + handCardImgStyle(card.playability.isPlayable) + } + } + actionButtons(card, wonderUpgradable, prepareMove) + } +} + +private fun RBuilder.actionButtons(card: HandCard, wonderUpgradable: Boolean, prepareMove: (PlayerMove) -> Unit) { + // class: action-buttons + styledDiv { + css { + alignItems = Align.flexEnd + display = Display.none + gridRow = GridRow("1") + gridColumn = GridColumn("1") + + ancestorHover(".hand-card") { + display = Display.flex + } + } + bpButtonGroup { + bpButton(title = "PLAY", + large = true, + intent = Intent.SUCCESS, + icon = "play", + disabled = !card.playability.isPlayable, + onClick = { prepareMove(PlayerMove(MoveType.PLAY, card.name)) }) + bpButton(title = "UPGRADE WONDER", + large = true, + intent = Intent.PRIMARY, + icon = "key-shift", + disabled = !wonderUpgradable, + onClick = { prepareMove(PlayerMove(MoveType.UPGRADE_WONDER, card.name)) }) + bpButton(title = "DISCARD", + large = true, + intent = Intent.DANGER, + icon = "cross", + onClick = { prepareMove(PlayerMove(MoveType.DISCARD, card.name)) }) + } + } +} + +private fun CSSBuilder.handStyle() { + alignItems = Align.center + bottom = 0.px + display = Display.flex + height = 345.px + left = 50.pct + maxHeight = 25.vw + position = Position.absolute + transform { + translate(tx = (-50).pct, ty = 55.pct) + } + transition(duration = 0.5.s) + zIndex = 30 + + hover { + bottom = 4.rem + transform { + translate(tx = (-50).pct, ty = 0.pct) + } + } +} + +private fun CSSBuilder.handCardStyle() { + classes.add("hand-card") + alignItems = Align.flexEnd + display = Display.grid + margin(all = 0.2.rem) +} + +private fun CSSBuilder.handCardImgStyle(isPlayable: Boolean) { + gridRow = GridRow("1") + gridColumn = GridColumn("1") + maxWidth = 13.vw + maxHeight = 60.vh + transition(duration = 0.1.s) + width = 11.rem + + ancestorHover(".hand-card") { + boxShadow(offsetX = 0.px, offsetY = 10.px, blurRadius = 40.px, color = Color.black) + width = 14.rem + maxWidth = 15.vw + maxHeight = 90.vh + } + + if (!isPlayable) { + filter = "grayscale(50%) contrast(50%)" + } +} |