summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@booking.com>2020-03-28 13:50:35 +0100
committerJoffrey Bion <joffrey.bion@booking.com>2020-03-28 13:50:35 +0100
commit856dbcba2abb78d889045e96f47b6727b230359e (patch)
treebf4cfd236082bd0af7e75c7de050f832f9a6017c
parentAdd board components (diff)
downloadseven-wonders-856dbcba2abb78d889045e96f47b6727b230359e.tar.gz
seven-wonders-856dbcba2abb78d889045e96f47b6727b230359e.tar.bz2
seven-wonders-856dbcba2abb78d889045e96f47b6727b230359e.zip
Add hand components
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt42
-rw-r--r--sw-ui-kt/src/main/kotlin/blueprintjs.kt39
-rw-r--r--sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt6
-rw-r--r--sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/CardImage.kt8
-rw-r--r--sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt11
-rw-r--r--sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt168
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%)"
+ }
+}
bgstack15