From 615a167d401b49c5a8139a1eeb99780523187753 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Sun, 9 Jun 2024 13:31:33 +0100 Subject: [PATCH] Fixed #102: The top window under the mouse is considered active --- .../main/scala/demo/ComponentsWindow.scala | 2 +- .../main/scala/demo/ComponentsWindow2.scala | 2 +- demo/src/main/scala/demo/MenuWindow.scala | 46 +++++++++++++++++++ demo/src/main/scala/demo/UIScene.scala | 6 +++ .../ui/window/WindowManager.scala | 21 +++++++-- .../ui/window/WindowManagerModel.scala | 4 +- 6 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 demo/src/main/scala/demo/MenuWindow.scala diff --git a/demo/src/main/scala/demo/ComponentsWindow.scala b/demo/src/main/scala/demo/ComponentsWindow.scala index 09d06cbc..67237055 100644 --- a/demo/src/main/scala/demo/ComponentsWindow.scala +++ b/demo/src/main/scala/demo/ComponentsWindow.scala @@ -86,7 +86,7 @@ object ComponentsWindow: ) ) .withTitle("Components example") - .moveTo(0, 0) + .moveTo(0, 3) .resizeTo(25, 25) .isDraggable .isResizable diff --git a/demo/src/main/scala/demo/ComponentsWindow2.scala b/demo/src/main/scala/demo/ComponentsWindow2.scala index 4d960b4f..0efae42c 100644 --- a/demo/src/main/scala/demo/ComponentsWindow2.scala +++ b/demo/src/main/scala/demo/ComponentsWindow2.scala @@ -59,7 +59,7 @@ object ComponentsWindow2: ) ) .withTitle("More component examples") - .moveTo(2, 2) + .moveTo(2, 5) .resizeTo(25, 25) .isDraggable .isResizable diff --git a/demo/src/main/scala/demo/MenuWindow.scala b/demo/src/main/scala/demo/MenuWindow.scala new file mode 100644 index 00000000..59ca9f3d --- /dev/null +++ b/demo/src/main/scala/demo/MenuWindow.scala @@ -0,0 +1,46 @@ +package demo + +import indigo.* +import roguelikestarterkit.* + +object MenuWindow: + + private val graphic = Graphic(0, 0, TerminalMaterial(AssetName(""), RGBA.White, RGBA.Black)) + + val windowId: WindowId = WindowId("MenuWindow") + + def window( + charSheet: CharSheet + ): WindowModel[ComponentList[Int], Int] = + WindowModel( + windowId, + charSheet, + ComponentList(Dimensions(20, 3)) { (_: Int) => + Batch( + Button[Int]( + "Window 1", + Button.Theme( + charSheet, + RGBA.Silver -> RGBA.Black, + RGBA.White -> RGBA.Black, + RGBA.Black -> RGBA.White, + hasBorder = false + ) + ).onClick(Log("Window 1"), WindowEvent.Open(ComponentsWindow.windowId)), + Button[Int]( + "Window 2", + Button.Theme( + charSheet, + RGBA.Silver -> RGBA.Black, + RGBA.Green -> RGBA.Black, + RGBA.Black -> RGBA.Yellow, + hasBorder = false + ) + ).onClick(Log("Window 2"), WindowEvent.Open(ComponentsWindow2.windowId)) + ) + } + .withLayout(ComponentLayout.Horizontal(Padding(0, 1, 0, 0))) + ) + .moveTo(0, 0) + .resizeTo(20, 3) + .isStatic diff --git a/demo/src/main/scala/demo/UIScene.scala b/demo/src/main/scala/demo/UIScene.scala index 5dde3062..9e1df66c 100644 --- a/demo/src/main/scala/demo/UIScene.scala +++ b/demo/src/main/scala/demo/UIScene.scala @@ -39,7 +39,13 @@ object UIScene extends Scene[Size, Model, ViewModel]: Model.defaultCharSheet ) ) + .register( + MenuWindow.window( + Model.defaultCharSheet + ) + ) .open( + MenuWindow.windowId, ComponentsWindow.windowId, ComponentsWindow2.windowId ) diff --git a/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManager.scala b/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManager.scala index aea055c8..23ff8322 100644 --- a/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManager.scala +++ b/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManager.scala @@ -144,10 +144,15 @@ object WindowManager: model: WindowManagerModel[ReferenceData] ): GlobalEvent => Outcome[WindowManagerModel[ReferenceData]] = e => + val windowUnderMouse = model.windowAt(context.mouseCoords) + model.windows .map { w => Window.updateModel( - context.copy(state = if w.hasFocus then UIState.Active else UIState.InActive), + context.copy(state = + if w.hasFocus || windowUnderMouse.exists(_ == w.id) then UIState.Active + else UIState.InActive + ), w )(e) } @@ -213,6 +218,8 @@ object WindowManager: Outcome(viewModel.changeMagnification(next)) case e => + val windowUnderMouse = model.windowAt(context.mouseCoords) + val updated = val prunedVM = viewModel.prune(model) model.windows.flatMap { m => @@ -225,7 +232,10 @@ object WindowManager: case Some(vm) => Batch( vm.update( - context.copy(state = if m.hasFocus then UIState.Active else UIState.InActive), + context.copy(state = + if m.hasFocus || windowUnderMouse.exists(_ == m.id) then UIState.Active + else UIState.InActive + ), m, e ) @@ -240,6 +250,8 @@ object WindowManager: model: WindowManagerModel[ReferenceData], viewModel: WindowManagerViewModel[ReferenceData] ): Outcome[SceneUpdateFragment] = + val windowUnderMouse = model.windowAt(context.mouseCoords) + val windowLayers: Outcome[Batch[Layer]] = model.windows .filter(_.isOpen) @@ -253,7 +265,10 @@ object WindowManager: Batch( Window .present( - context.copy(state = if m.hasFocus then UIState.Active else UIState.InActive), + context.copy(state = + if m.hasFocus || windowUnderMouse.exists(_ == m.id) then UIState.Active + else UIState.InActive + ), m, vm ) diff --git a/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManagerModel.scala b/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManagerModel.scala index 0af8b175..294a63ed 100644 --- a/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManagerModel.scala +++ b/roguelike-starterkit/src/main/scala/roguelikestarterkit/ui/window/WindowManagerModel.scala @@ -56,8 +56,8 @@ final case class WindowManagerModel[ReferenceData](windows: Batch[WindowModel[?, this.copy(windows = reordered) - def giveWindowAt(coords: Coords): Option[WindowId] = - windows.reverse.find(w => !w.static && w.bounds.contains(coords)).map(_.id) + def windowAt(coords: Coords): Option[WindowId] = + windows.reverse.find(_.bounds.contains(coords)).map(_.id) def moveTo(id: WindowId, position: Coords): WindowManagerModel[ReferenceData] = this.copy(windows = windows.map(w => if w.id == id then w.moveTo(position) else w))