Skip to content

Commit

Permalink
Title bars blend into window, border tiles can be modified
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Oct 2, 2024
1 parent 90fb7e6 commit fdf23b5
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 53 deletions.
4 changes: 4 additions & 0 deletions demo/src/main/scala/demo/ColourWindow.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ object ColourWindow:
RGBA.Black
)
.addBorder
.modifyBorderTiles(
_.withBottomLeft(Tile.`├`)
.withBottomRight(Tile.`┤`)
)
).onDrag { (_: Unit, dragData) =>
Batch(
WindowEvent
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package roguelikestarterkit.ui.components

import roguelikestarterkit.tiles.Tile

final case class TerminalBorderTiles(
fill: Tile,
topLeft: Tile,
topRight: Tile,
bottomLeft: Tile,
bottomRight: Tile,
horizontal: Tile,
vertical: Tile
):
def withFill(value: Tile): TerminalBorderTiles =
this.copy(fill = value)
def withTopLeft(value: Tile): TerminalBorderTiles =
this.copy(topLeft = value)
def withTopRight(value: Tile): TerminalBorderTiles =
this.copy(topRight = value)
def withBottomLeft(value: Tile): TerminalBorderTiles =
this.copy(bottomLeft = value)
def withBottomRight(value: Tile): TerminalBorderTiles =
this.copy(bottomRight = value)
def withHorizontal(value: Tile): TerminalBorderTiles =
this.copy(horizontal = value)
def withVertical(value: Tile): TerminalBorderTiles =
this.copy(vertical = value)

object TerminalBorderTiles:
val default: TerminalBorderTiles =
TerminalBorderTiles(Tile.` `, Tile.`┌`, Tile.`┐`, Tile.`└`, Tile.`┘`, Tile.`─`, Tile.`│`)
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ object TerminalButton:
fgColor: RGBA,
bgColor: RGBA,
charSheet: CharSheet,
hasBorder: Boolean
hasBorder: Boolean,
borderTiles: TerminalBorderTiles
): (Coords, Bounds, ReferenceData) => Outcome[Layer] =
if hasBorder then presentButtonWithBorder(label, fgColor, bgColor, charSheet)
if hasBorder then presentButtonWithBorder(label, fgColor, bgColor, charSheet, borderTiles)
else presentButtonNoBorder(label, fgColor, bgColor, charSheet)

private def presentButtonNoBorder[ReferenceData](
Expand Down Expand Up @@ -53,25 +54,26 @@ object TerminalButton:
label: ReferenceData => Batch[Tile],
fgColor: RGBA,
bgColor: RGBA,
charSheet: CharSheet
charSheet: CharSheet,
borderTiles: TerminalBorderTiles
): (Coords, Bounds, ReferenceData) => Outcome[Layer] =
(offset, bounds, ref) =>
val txt = label(ref).take(bounds.width - 2)
val hBar = Batch.fill(bounds.width - 2)("").mkString
val hBar = Batch.fill(bounds.width - 2)(borderTiles.horizontal)
val size = bounds.dimensions.unsafeToSize

val terminal =
RogueTerminalEmulator(size)
.fill(Tile.` `, fgColor, bgColor)
.put(Point(0, 0), Tile.`┌`, fgColor, bgColor)
.put(Point(size.width - 1, 0), Tile.`┐`, fgColor, bgColor)
.put(Point(0, size.height - 1), Tile.`└`, fgColor, bgColor)
.put(Point(size.width - 1, size.height - 1), Tile.`┘`, fgColor, bgColor)
.put(Point(0, 1), Tile.`│`, fgColor, bgColor)
.put(Point(size.width - 1, 1), Tile.`│`, fgColor, bgColor)
.putLine(Point(1, 0), hBar, fgColor, bgColor)
.fill(borderTiles.fill, fgColor, bgColor)
.put(Point(0, 0), borderTiles.topLeft, fgColor, bgColor)
.put(Point(size.width - 1, 0), borderTiles.topRight, fgColor, bgColor)
.put(Point(0, size.height - 1), borderTiles.bottomLeft, fgColor, bgColor)
.put(Point(size.width - 1, size.height - 1), borderTiles.bottomRight, fgColor, bgColor)
.put(Point(0, 1), borderTiles.vertical, fgColor, bgColor)
.put(Point(size.width - 1, 1), borderTiles.vertical, fgColor, bgColor)
.putTileLine(Point(1, 0), hBar, fgColor, bgColor)
.putTileLine(Point(1, 1), txt, fgColor, bgColor)
.putLine(Point(1, 2), hBar, fgColor, bgColor)
.putTileLine(Point(1, 2), hBar, fgColor, bgColor)

val terminalClones =
terminal
Expand Down Expand Up @@ -151,7 +153,8 @@ object TerminalButton:
theme.up.foreground,
theme.up.background,
theme.charSheet,
theme.hasBorder
theme.hasBorder,
theme.borderTiles
)
}
.presentOver(
Expand All @@ -160,7 +163,8 @@ object TerminalButton:
theme.over.foreground,
theme.over.background,
theme.charSheet,
theme.hasBorder
theme.hasBorder,
theme.borderTiles
)
)
.presentDown(
Expand All @@ -169,7 +173,8 @@ object TerminalButton:
theme.down.foreground,
theme.down.background,
theme.charSheet,
theme.hasBorder
theme.hasBorder,
theme.borderTiles
)
)

Expand Down Expand Up @@ -240,7 +245,8 @@ object TerminalButton:
up: TerminalTileColors,
over: TerminalTileColors,
down: TerminalTileColors,
hasBorder: Boolean
hasBorder: Boolean,
borderTiles: TerminalBorderTiles
):
def withCharSheet(value: CharSheet): Theme =
this.copy(charSheet = value)
Expand All @@ -261,6 +267,11 @@ object TerminalButton:
def noBorder: Theme =
this.copy(hasBorder = false)

def withBorderTiles(value: TerminalBorderTiles): Theme =
this.copy(borderTiles = value)
def modifyBorderTiles(f: TerminalBorderTiles => TerminalBorderTiles): Theme =
this.copy(borderTiles = f(borderTiles))

object Theme:

def apply(charSheet: CharSheet, foreground: RGBA, background: RGBA, hasBorder: Boolean): Theme =
Expand All @@ -269,7 +280,8 @@ object TerminalButton:
TerminalTileColors(foreground, background),
TerminalTileColors(foreground, background),
TerminalTileColors(foreground, background),
hasBorder
hasBorder,
TerminalBorderTiles.default
)
def apply(charSheet: CharSheet, foreground: RGBA, background: RGBA): Theme =
Theme(
Expand All @@ -294,7 +306,8 @@ object TerminalButton:
TerminalTileColors(foregroundUp, backgroundUp),
TerminalTileColors(foregroundOver, backgroundOver),
TerminalTileColors(foregroundDown, backgroundDown),
hasBorder
hasBorder,
TerminalBorderTiles.default
)
def apply(
charSheet: CharSheet,
Expand Down Expand Up @@ -328,7 +341,8 @@ object TerminalButton:
TerminalTileColors(up._1, up._2),
TerminalTileColors(over._1, over._2),
TerminalTileColors(down._1, down._2),
hasBorder
hasBorder,
TerminalBorderTiles.default
)
def apply(
charSheet: CharSheet,
Expand All @@ -351,21 +365,3 @@ object TerminalButton:
RGBA.White -> RGBA.Black,
RGBA.Black -> RGBA.White
)

enum ButtonState:
case Up, Over, Down

def isUp: Boolean =
this match
case Up => true
case _ => false

def is: Boolean =
this match
case Over => true
case _ => false

def isDown: Boolean =
this match
case Down => true
case _ => false
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package roguelikestarterkit.ui.components

import indigo.*
import roguelikestarterkit.Tile
import roguelikestarterkit.syntax.*
import roguelikestarterkit.terminal.RogueTerminalEmulator
import roguelikestarterkit.terminal.TerminalMaterial
Expand Down Expand Up @@ -54,33 +53,34 @@ object TerminalInput:
private def presentInput[ReferenceData](
charSheet: CharSheet,
fgColor: RGBA,
bgColor: RGBA
bgColor: RGBA,
borderTiles: TerminalBorderTiles
): (Coords, Bounds, Input, Seconds) => Outcome[Layer] =
(offset, bounds, input, runningTime) =>
val correctedLabel =
if input.text.length == bounds.width then input.text
else if input.text.length > bounds.width then input.text.take(bounds.width)
else input.text + (List.fill(bounds.width - input.text.length)(" ").mkString)

val hBar = Batch.fill(correctedLabel.length)("").mkString
val hBar = Batch.fill(correctedLabel.length)(borderTiles.horizontal)
val size = (bounds.dimensions + 2).unsafeToSize

val terminal =
RogueTerminalEmulator(size)
.put(Point(0, 0), Tile.`┌`, fgColor, bgColor)
.put(Point(size.width - 1, 0), Tile.`┐`, fgColor, bgColor)
.put(Point(0, size.height - 1), Tile.`└`, fgColor, bgColor)
.put(Point(size.width - 1, size.height - 1), Tile.`┘`, fgColor, bgColor)
.put(Point(0, 1), Tile.`│`, fgColor, bgColor)
.put(Point(size.width - 1, 1), Tile.`│`, fgColor, bgColor)
.putLine(Point(1, 0), hBar, fgColor, bgColor)
.put(Point(0, 0), borderTiles.topLeft, fgColor, bgColor)
.put(Point(size.width - 1, 0), borderTiles.topRight, fgColor, bgColor)
.put(Point(0, size.height - 1), borderTiles.bottomLeft, fgColor, bgColor)
.put(Point(size.width - 1, size.height - 1), borderTiles.bottomRight, fgColor, bgColor)
.put(Point(0, 1), borderTiles.vertical, fgColor, bgColor)
.put(Point(size.width - 1, 1), borderTiles.vertical, fgColor, bgColor)
.putTileLine(Point(1, 0), hBar, fgColor, bgColor)
.putLine(
Point(1, 1),
correctedLabel,
fgColor,
bgColor
)
.putLine(Point(1, 2), hBar, fgColor, bgColor)
.putTileLine(Point(1, 2), hBar, fgColor, bgColor)

val terminalClones =
terminal
Expand Down Expand Up @@ -123,7 +123,12 @@ object TerminalInput:
Input(
"",
Dimensions(width, 1),
presentInput(theme.charSheet, theme.colors.foreground, theme.colors.background),
presentInput(
theme.charSheet,
theme.colors.foreground,
theme.colors.background,
theme.borderTiles
),
_ => Batch.empty,
//
characterLimit = width,
Expand All @@ -135,19 +140,26 @@ object TerminalInput:

final case class Theme(
charSheet: CharSheet,
colors: TerminalTileColors
colors: TerminalTileColors,
borderTiles: TerminalBorderTiles
):
def withCharSheet(value: CharSheet): Theme =
this.copy(charSheet = value)

def withColors(foreground: RGBA, background: RGBA): Theme =
this.copy(colors = TerminalTileColors(foreground, background))

def withBorderTiles(value: TerminalBorderTiles): Theme =
this.copy(borderTiles = value)
def modifyBorderTiles(f: TerminalBorderTiles => TerminalBorderTiles): Theme =
this.copy(borderTiles = f(borderTiles))

object Theme:
def apply(charSheet: CharSheet, foreground: RGBA, background: RGBA): Theme =
Theme(
charSheet,
TerminalTileColors(foreground, background)
TerminalTileColors(foreground, background),
TerminalBorderTiles.default
)

def apply(charSheet: CharSheet): Theme =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ Missing stuff:
- scroll button size can be adjusted based on the content size.
- horizontal scrolling?
- Possible to disable the rest of the UI while holding down on a button?
- Terminal title bar doesn't blend nicely with the rest of the window.
- Support for Pointer events on components and windows(?). (Once the issues with PointerState are resolved.)
- One problem here is that if you want to use, say, a TextBox, then you need a BoundaryLocator instance.
That comes from UIContext, but we can't have UIContext present as it makes the code untestable currently.
Expand Down

0 comments on commit fdf23b5

Please sign in to comment.