Skip to content

Commit

Permalink
Rendering a nice window
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Oct 24, 2023
1 parent 4670649 commit 4778611
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 8 deletions.
2 changes: 2 additions & 0 deletions paint/src/main/scala/roguepaint/PaintGame.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package roguepaint

import indigo.*
import indigo.scenes.*
import indigoextras.subsystems.FPSCounter
import io.indigoengine.roguelike.starterkit.*

import scala.scalajs.js.annotation.JSExportTopLevel
Expand Down Expand Up @@ -30,6 +31,7 @@ object PaintGame extends IndigoGame[Unit, Unit, Model, ViewModel]:
.withShaders(
TerminalText.standardShader
)
// .withSubSystems(FPSCounter(Point.zero))
)

def initialModel(startupData: Unit): Outcome[Model] =
Expand Down
65 changes: 57 additions & 8 deletions paint/src/main/scala/roguepaint/components/Window.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object Window:
viewModel: WindowViewModel
): GlobalEvent => Outcome[WindowViewModel] =
case FrameTick if model.bounds.size != viewModel.terminal.screenSize =>
Outcome(viewModel.resize(model.bounds.size))
Outcome(viewModel.resize(model))

case _ =>
Outcome(viewModel)
Expand All @@ -39,7 +39,8 @@ object Window:

final case class WindowModel(
id: String,
bounds: Rectangle
bounds: Rectangle,
title: Option[String]
):

def update(frameContext: FrameContext[Unit], event: GlobalEvent): Outcome[WindowModel] =
Expand All @@ -50,7 +51,8 @@ object WindowModel:
def apply(id: String): WindowModel =
WindowModel(
id,
Rectangle(Point(10, 10), Size(10, 5))
Rectangle(Point(15, 15), Size(15, 10)),
Some("Inventory")
)

final case class WindowViewModel(terminal: TerminalEmulator):
Expand All @@ -62,8 +64,8 @@ final case class WindowViewModel(terminal: TerminalEmulator):
): Outcome[WindowViewModel] =
Window.updateViewModel(frameContext, model, this)(event)

def resize(newSize: Size): WindowViewModel =
this.copy(terminal = WindowViewModel.makeWindowTerminal(newSize, terminal))
def resize(model: WindowModel): WindowViewModel =
this.copy(terminal = WindowViewModel.makeWindowTerminal(model, terminal))

object WindowViewModel:

Expand All @@ -72,13 +74,14 @@ object WindowViewModel:
TerminalEmulator(Size.zero)
)

def makeWindowTerminal(newSize: Size, current: TerminalEmulator): TerminalEmulator =
val validSize = newSize.max(Size(2))
def makeWindowTerminal(model: WindowModel, current: TerminalEmulator): TerminalEmulator =
val validSize = model.bounds.size.max(if model.title.isDefined then Size(3) else Size(2))

if validSize == current.screenSize then current
else
val tiles: Batch[(Point, MapTile)] =
val grey = RGBA.White.mix(RGBA.Black, 0.5)
val grey = RGBA.White.mix(RGBA.Black, 0.5)
val title = model.title.getOrElse("").toCharArray()

(0 to validSize.height).toBatch.flatMap { _y =>
(0 to validSize.width).toBatch.map { _x =>
Expand All @@ -87,6 +90,48 @@ object WindowViewModel:
val coords = Point(_x, _y)

coords match
// When there is a title
case Point(0, 1) if model.title.isDefined =>
// Title bar left
coords -> MapTile(Tile.`│`, RGBA.White, RGBA.Zero)

case Point(x, 1) if model.title.isDefined && x == maxX =>
// Title bar right
coords -> MapTile(Tile.`│`, RGBA.White, RGBA.Zero)

case Point(1, 1) if model.title.isDefined =>
// Title bar left padding
coords -> MapTile(Tile.SPACE, RGBA.White, RGBA.Zero)

case Point(x, 1) if model.title.isDefined =>
// Title text, x starts at 2
val idx = x - 2
val tile =
if idx >= 0 && idx < title.length then
val c = title(idx)
Tile.charCodes.get(if c == '\\' then "\\" else c.toString) match
case None => Tile.SPACE
case Some(char) => Tile(char)
else Tile.SPACE

coords -> MapTile(tile, RGBA.White, RGBA.Zero)

case Point(0, 2) if model.title.isDefined =>
// Title bar line left
val tile = if maxY > 2 then Tile.`├` else Tile.`└`
coords -> MapTile(Tile.`│`, RGBA.White, RGBA.Zero)

case Point(x, 2) if model.title.isDefined && x == maxX =>
// Title bar line right
val tile = if maxY > 2 then Tile.`┤` else Tile.`┘`
coords -> MapTile(tile, RGBA.White, RGBA.Zero)

case Point(x, 2) if model.title.isDefined =>
// Title bar line
coords -> MapTile(Tile.`─`, RGBA.White, RGBA.Zero)

// Normal window frame

case Point(0, 0) =>
// top left
coords -> MapTile(Tile.`┌`, RGBA.White, RGBA.Zero)
Expand Down Expand Up @@ -119,6 +164,10 @@ object WindowViewModel:
// Middle right
coords -> MapTile(Tile.`│`, RGBA.White, RGBA.Zero)

case Point(x, y) if x == maxX - 1 && y == maxY - 1 =>
// Resize corner
coords -> MapTile(Tile.`/`, grey, RGBA.Zero)

case Point(x, y) =>
// Window background
coords -> MapTile(Tile.`░`, grey, RGBA.Zero)
Expand Down

0 comments on commit 4778611

Please sign in to comment.