Compare commits
No commits in common. "1a2913041979640ab87edacedac77e34bf9cd9c4" and "570944cb774743885bd726db97687d42cc80cd00" have entirely different histories.
1a29130419
...
570944cb77
4
TODO.md
4
TODO.md
|
@ -1,9 +1,5 @@
|
||||||
# Specific projects
|
# Specific projects
|
||||||
|
|
||||||
## Now:
|
|
||||||
- renderer scenes
|
|
||||||
- outfitter
|
|
||||||
|
|
||||||
## Small jobs
|
## Small jobs
|
||||||
- 🌟 Better planet desc formatting
|
- 🌟 Better planet desc formatting
|
||||||
- Procedural suns
|
- Procedural suns
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub struct InputStatus {
|
||||||
key_guns: bool,
|
key_guns: bool,
|
||||||
key_leftclick: bool,
|
key_leftclick: bool,
|
||||||
|
|
||||||
// One-shot keys (automatically released at the end of each frame)
|
// One-shot keys (audomatically released at the end of each frame)
|
||||||
key_land: bool,
|
key_land: bool,
|
||||||
v_scroll: f32,
|
v_scroll: f32,
|
||||||
}
|
}
|
||||||
|
@ -137,11 +137,6 @@ impl InputStatus {
|
||||||
self.key_guns
|
self.key_guns
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is the player pressing the left mouse button?
|
|
||||||
pub fn pressed_leftclick(&self) -> bool {
|
|
||||||
self.key_leftclick
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Has the player pressed the "land" key?
|
/// Has the player pressed the "land" key?
|
||||||
/// (One-shot, reset to false at the start of each frame)
|
/// (One-shot, reset to false at the start of each frame)
|
||||||
pub fn pressed_land(&self) -> bool {
|
pub fn pressed_land(&self) -> bool {
|
||||||
|
|
|
@ -111,7 +111,7 @@ impl<'a> super::GPUState {
|
||||||
0..self.state.get_radialbar_counter(),
|
0..self.state.get_radialbar_counter(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let textareas = self.ui.get_textareas(input, &self.state);
|
let textareas = self.ui.get_textareas_flying(input, &self.state);
|
||||||
self.state
|
self.state
|
||||||
.text_renderer
|
.text_renderer
|
||||||
.prepare(
|
.prepare(
|
||||||
|
@ -219,7 +219,7 @@ impl<'a> super::GPUState {
|
||||||
0..self.state.get_radialbar_counter(),
|
0..self.state.get_radialbar_counter(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let textareas = self.ui.get_textareas(input, &self.state);
|
let textareas = self.ui.get_textareas_landed(input, &self.state);
|
||||||
self.state
|
self.state
|
||||||
.text_renderer
|
.text_renderer
|
||||||
.prepare(
|
.prepare(
|
||||||
|
@ -281,7 +281,6 @@ impl<'a> super::GPUState {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.state.frame_reset();
|
self.state.frame_reset();
|
||||||
self.ui.update_state(&input, &mut self.state);
|
|
||||||
|
|
||||||
match input
|
match input
|
||||||
.phys_img
|
.phys_img
|
||||||
|
|
|
@ -1,121 +1,29 @@
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
use galactica_content::Content;
|
use galactica_content::Content;
|
||||||
use galactica_system::{data::ShipState, phys::PhysSimShipHandle};
|
use galactica_system::{data::ShipState, phys::PhysSimShipHandle};
|
||||||
use glyphon::TextArea;
|
use glyphon::TextArea;
|
||||||
use log::info;
|
|
||||||
|
|
||||||
use super::scenes::{FlyingScene, LandedScene, OutfitterScene};
|
use super::{fpsindicator::FpsIndicator, planet::Planet, radar::Radar, status::Status};
|
||||||
use crate::{RenderInput, RenderState};
|
use crate::{RenderInput, RenderState};
|
||||||
|
|
||||||
/// Output from a ui scene step
|
|
||||||
pub struct UiSceneStepResult {
|
|
||||||
/// If Some, switch to this scene
|
|
||||||
pub new_scene: Option<UiScenes>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait UiScene<'this>
|
|
||||||
where
|
|
||||||
Self: 'this,
|
|
||||||
{
|
|
||||||
/// Draw this scene
|
|
||||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState);
|
|
||||||
|
|
||||||
/// Update this scene's state for this frame.
|
|
||||||
/// Handles clicks, keys, etc.
|
|
||||||
fn step(&mut self, input: &RenderInput, state: &mut RenderState) -> UiSceneStepResult;
|
|
||||||
|
|
||||||
fn get_textareas(
|
|
||||||
&'this self,
|
|
||||||
v: &mut Vec<TextArea<'this>>,
|
|
||||||
input: &RenderInput,
|
|
||||||
state: &RenderState,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) enum UiScenes {
|
|
||||||
Landed(LandedScene),
|
|
||||||
Flying(FlyingScene),
|
|
||||||
Outfitter(OutfitterScene),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for UiScenes {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Flying(_) => write!(f, "UiScenes::Flying"),
|
|
||||||
Self::Landed(_) => write!(f, "UiScenes::Landed"),
|
|
||||||
Self::Outfitter(_) => write!(f, "UiScenes::Outfitter"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UiScenes {
|
|
||||||
fn is_flying(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::Flying(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_landed(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::Landed(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_outfitter(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::Outfitter(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> UiScene<'a> for UiScenes {
|
|
||||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
|
||||||
match self {
|
|
||||||
Self::Flying(s) => s.draw(input, state),
|
|
||||||
Self::Landed(s) => s.draw(input, state),
|
|
||||||
Self::Outfitter(s) => s.draw(input, state),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn step(&mut self, input: &RenderInput, state: &mut RenderState) -> UiSceneStepResult {
|
|
||||||
match self {
|
|
||||||
Self::Flying(s) => s.step(input, state),
|
|
||||||
Self::Landed(s) => s.step(input, state),
|
|
||||||
Self::Outfitter(s) => s.step(input, state),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_textareas(
|
|
||||||
&'a self,
|
|
||||||
v: &mut Vec<TextArea<'a>>,
|
|
||||||
input: &RenderInput,
|
|
||||||
state: &RenderState,
|
|
||||||
) {
|
|
||||||
match self {
|
|
||||||
Self::Flying(s) => s.get_textareas(v, input, state),
|
|
||||||
Self::Landed(s) => s.get_textareas(v, input, state),
|
|
||||||
Self::Outfitter(s) => s.get_textareas(v, input, state),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UiManager {
|
pub struct UiManager {
|
||||||
current_scene: UiScenes,
|
radar: Radar,
|
||||||
|
status: Status,
|
||||||
|
fps: FpsIndicator,
|
||||||
|
planet: Planet,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UiManager {
|
impl UiManager {
|
||||||
pub fn new(ct: &Content, state: &mut RenderState) -> Self {
|
pub fn new(ct: &Content, state: &mut RenderState) -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_scene: UiScenes::Flying(FlyingScene::new(ct, state)),
|
planet: Planet::new(ct, state),
|
||||||
|
radar: Radar::new(),
|
||||||
|
status: Status::new(),
|
||||||
|
fps: FpsIndicator::new(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this.
|
/// Draw all ui elements
|
||||||
pub fn update_state(&mut self, input: &RenderInput, state: &mut RenderState) {
|
pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||||
let ship_handle = input.player.ship.unwrap();
|
let ship_handle = input.player.ship.unwrap();
|
||||||
let ship = &input
|
let ship = &input
|
||||||
.phys_img
|
.phys_img
|
||||||
|
@ -123,44 +31,41 @@ impl UiManager {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.ship;
|
.ship;
|
||||||
|
|
||||||
|
self.fps.update(input, state);
|
||||||
|
|
||||||
match ship.get_data().get_state() {
|
match ship.get_data().get_state() {
|
||||||
ShipState::Collapsing
|
ShipState::Collapsing
|
||||||
| ShipState::Dead
|
| ShipState::Dead
|
||||||
| ShipState::Flying { .. }
|
| ShipState::Flying { .. }
|
||||||
| ShipState::Landing { .. }
|
| ShipState::Landing { .. }
|
||||||
| ShipState::UnLanding { .. } => {
|
| ShipState::UnLanding { .. } => {
|
||||||
if !self.current_scene.is_flying() {
|
self.radar.draw(input, state);
|
||||||
self.current_scene = UiScenes::Flying(FlyingScene::new(input.ct, state));
|
self.status.draw(input, state);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShipState::Landed { .. } => {
|
ShipState::Landed { .. } => {
|
||||||
if !self.current_scene.is_landed() && !self.current_scene.is_outfitter() {
|
self.planet.draw(input, state);
|
||||||
self.current_scene = UiScenes::Landed(LandedScene::new(input.ct, state))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw all ui elements
|
|
||||||
pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
|
||||||
loop {
|
|
||||||
let r = self.current_scene.step(input, state);
|
|
||||||
if let Some(new_state) = r.new_scene {
|
|
||||||
info!("switching to {:?}", new_state);
|
|
||||||
self.current_scene = new_state;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.current_scene.draw(input, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Textareas to show while player is flying
|
/// Textareas to show while player is flying
|
||||||
pub fn get_textareas(&self, input: &RenderInput, state: &RenderState) -> Vec<TextArea> {
|
pub fn get_textareas_flying(
|
||||||
|
&self,
|
||||||
|
_input: &RenderInput,
|
||||||
|
_state: &RenderState,
|
||||||
|
) -> Vec<TextArea> {
|
||||||
let mut v = Vec::with_capacity(5);
|
let mut v = Vec::with_capacity(5);
|
||||||
self.current_scene.get_textareas(&mut v, input, state);
|
v.push(self.fps.get_textarea());
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Textareas to show when player is landed
|
||||||
|
pub fn get_textareas_landed(&self, input: &RenderInput, state: &RenderState) -> Vec<TextArea> {
|
||||||
|
let mut v = Vec::with_capacity(5);
|
||||||
|
v.extend(self.planet.get_textarea(input, state));
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
mod fpsindicator;
|
||||||
mod manager;
|
mod manager;
|
||||||
mod scenes;
|
mod planet;
|
||||||
|
mod radar;
|
||||||
|
mod status;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub use manager::UiManager;
|
pub use manager::UiManager;
|
||||||
|
|
|
@ -3,20 +3,13 @@ use galactica_system::{data::ShipState, phys::PhysSimShipHandle};
|
||||||
use glyphon::{cosmic_text::Align, Attrs, Color, Metrics, TextArea, Weight};
|
use glyphon::{cosmic_text::Align, Attrs, Color, Metrics, TextArea, Weight};
|
||||||
use nalgebra::{Point2, Vector2};
|
use nalgebra::{Point2, Vector2};
|
||||||
|
|
||||||
use crate::{
|
use super::util::{SpriteRect, UiSprite, UiTextArea};
|
||||||
ui::{
|
use crate::{RenderInput, RenderState};
|
||||||
manager::{UiScene, UiSceneStepResult, UiScenes},
|
|
||||||
util::{SpriteRect, UiSprite, UiTextArea},
|
|
||||||
},
|
|
||||||
RenderInput, RenderState,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::OutfitterScene;
|
pub(super) struct Planet {
|
||||||
|
|
||||||
pub struct LandedScene {
|
|
||||||
// UI elements
|
// UI elements
|
||||||
description: UiTextArea,
|
planet_desc: UiTextArea,
|
||||||
title: UiTextArea,
|
planet_name: UiTextArea,
|
||||||
frame: UiSprite,
|
frame: UiSprite,
|
||||||
landscape: UiSprite,
|
landscape: UiSprite,
|
||||||
button: UiSprite,
|
button: UiSprite,
|
||||||
|
@ -24,13 +17,11 @@ pub struct LandedScene {
|
||||||
/// What object we're displaying currently.
|
/// What object we're displaying currently.
|
||||||
/// Whenever this changes, we need to reflow text.
|
/// Whenever this changes, we need to reflow text.
|
||||||
current_object: Option<SystemObjectHandle>,
|
current_object: Option<SystemObjectHandle>,
|
||||||
|
|
||||||
/// True if we've caught a left click event.
|
|
||||||
/// Used for edge detection.
|
|
||||||
leftclick_down: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LandedScene {
|
// TODO: animate in/out
|
||||||
|
|
||||||
|
impl Planet {
|
||||||
pub fn new(ct: &Content, state: &mut RenderState) -> Self {
|
pub fn new(ct: &Content, state: &mut RenderState) -> Self {
|
||||||
let frame = UiSprite::from(ct, &ct.get_ui().landed_frame);
|
let frame = UiSprite::from(ct, &ct.get_ui().landed_frame);
|
||||||
let button = UiSprite::from(ct, &ct.get_ui().landed_button);
|
let button = UiSprite::from(ct, &ct.get_ui().landed_button);
|
||||||
|
@ -43,9 +34,8 @@ impl LandedScene {
|
||||||
let s = Self {
|
let s = Self {
|
||||||
// height of element in logical pixels
|
// height of element in logical pixels
|
||||||
current_object: None,
|
current_object: None,
|
||||||
leftclick_down: false,
|
|
||||||
|
|
||||||
description: UiTextArea::new(
|
planet_desc: UiTextArea::new(
|
||||||
ct,
|
ct,
|
||||||
state,
|
state,
|
||||||
frame.get_sprite(),
|
frame.get_sprite(),
|
||||||
|
@ -60,7 +50,7 @@ impl LandedScene {
|
||||||
Align::Left,
|
Align::Left,
|
||||||
),
|
),
|
||||||
|
|
||||||
title: UiTextArea::new(
|
planet_name: UiTextArea::new(
|
||||||
ct,
|
ct,
|
||||||
state,
|
state,
|
||||||
frame.get_sprite(),
|
frame.get_sprite(),
|
||||||
|
@ -82,9 +72,11 @@ impl LandedScene {
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Planet {
|
||||||
fn reflow(&mut self, planet: &SystemObject, state: &mut RenderState) {
|
fn reflow(&mut self, planet: &SystemObject, state: &mut RenderState) {
|
||||||
self.description.set_text(
|
self.planet_desc.set_text(
|
||||||
state,
|
state,
|
||||||
&planet.desc,
|
&planet.desc,
|
||||||
Attrs::new()
|
Attrs::new()
|
||||||
|
@ -92,7 +84,7 @@ impl LandedScene {
|
||||||
.family(glyphon::Family::SansSerif),
|
.family(glyphon::Family::SansSerif),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.title.set_text(
|
self.planet_name.set_text(
|
||||||
state,
|
state,
|
||||||
&planet.name,
|
&planet.name,
|
||||||
Attrs::new()
|
Attrs::new()
|
||||||
|
@ -101,29 +93,8 @@ impl LandedScene {
|
||||||
);
|
);
|
||||||
self.current_object = Some(planet.handle);
|
self.current_object = Some(planet.handle);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'this> UiScene<'this> for LandedScene {
|
pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||||
fn step(&mut self, input: &RenderInput, state: &mut RenderState) -> UiSceneStepResult {
|
|
||||||
let frame_rect = Some(self.frame.get_rect(input));
|
|
||||||
self.button.step(input, state, frame_rect);
|
|
||||||
self.landscape.step(input, state, frame_rect);
|
|
||||||
self.frame.step(input, state, None);
|
|
||||||
|
|
||||||
let mut new_scene = None;
|
|
||||||
if input.player.input.pressed_leftclick() && !self.leftclick_down {
|
|
||||||
self.leftclick_down = true;
|
|
||||||
if self.button.contains_mouse(input, state, frame_rect) {
|
|
||||||
new_scene = Some(UiScenes::Outfitter(OutfitterScene::new(input.ct, state)));
|
|
||||||
}
|
|
||||||
} else if !input.player.input.pressed_leftclick() {
|
|
||||||
self.leftclick_down = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return UiSceneStepResult { new_scene };
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
|
||||||
// Get required data
|
// Get required data
|
||||||
let ship_handle = input.player.ship.unwrap();
|
let ship_handle = input.player.ship.unwrap();
|
||||||
let ship_data = &input
|
let ship_data = &input
|
||||||
|
@ -146,20 +117,24 @@ impl<'this> UiScene<'this> for LandedScene {
|
||||||
self.reflow(planet, state);
|
self.reflow(planet, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.button
|
||||||
|
.step(input, state, Some(self.frame.get_rect(input)));
|
||||||
|
self.landscape
|
||||||
|
.step(input, state, Some(self.frame.get_rect(input)));
|
||||||
|
self.frame.step(input, state, None);
|
||||||
|
|
||||||
// Draw elements
|
// Draw elements
|
||||||
let frame_rect = Some(self.frame.get_rect(input));
|
self.button
|
||||||
self.button.push_to_buffer(input, state, frame_rect);
|
.push_to_buffer(input, state, Some(self.frame.get_rect(input)));
|
||||||
self.landscape.push_to_buffer(input, state, frame_rect);
|
self.landscape
|
||||||
|
.push_to_buffer(input, state, Some(self.frame.get_rect(input)));
|
||||||
self.frame.push_to_buffer(input, state, None);
|
self.frame.push_to_buffer(input, state, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_textareas(
|
pub fn get_textarea(&self, input: &RenderInput, state: &RenderState) -> [TextArea; 2] {
|
||||||
&'this self,
|
[
|
||||||
v: &mut Vec<TextArea<'this>>,
|
self.planet_desc.get_textarea(input, state),
|
||||||
input: &RenderInput,
|
self.planet_name.get_textarea(input, state),
|
||||||
state: &RenderState,
|
]
|
||||||
) {
|
|
||||||
v.push(self.description.get_textarea(input, state));
|
|
||||||
v.push(self.title.get_textarea(input, state));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
mod fpsindicator;
|
|
||||||
mod radar;
|
|
||||||
mod scene;
|
|
||||||
mod status;
|
|
||||||
|
|
||||||
pub use scene::FlyingScene;
|
|
|
@ -1,45 +0,0 @@
|
||||||
use galactica_content::Content;
|
|
||||||
use glyphon::TextArea;
|
|
||||||
|
|
||||||
use super::{fpsindicator::FpsIndicator, radar::Radar, status::Status};
|
|
||||||
use crate::{
|
|
||||||
ui::manager::{UiScene, UiSceneStepResult},
|
|
||||||
RenderInput, RenderState,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct FlyingScene {
|
|
||||||
radar: Radar,
|
|
||||||
status: Status,
|
|
||||||
fps: FpsIndicator,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FlyingScene {
|
|
||||||
pub fn new(_ct: &Content, state: &mut RenderState) -> Self {
|
|
||||||
Self {
|
|
||||||
radar: Radar::new(),
|
|
||||||
status: Status::new(),
|
|
||||||
fps: FpsIndicator::new(state),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'this> UiScene<'this> for FlyingScene {
|
|
||||||
fn step(&mut self, input: &RenderInput, state: &mut RenderState) -> UiSceneStepResult {
|
|
||||||
self.fps.update(input, state);
|
|
||||||
return UiSceneStepResult { new_scene: None };
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
|
||||||
self.radar.draw(input, state);
|
|
||||||
self.status.draw(input, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_textareas(
|
|
||||||
&'this self,
|
|
||||||
v: &mut Vec<TextArea<'this>>,
|
|
||||||
_input: &RenderInput,
|
|
||||||
_state: &RenderState,
|
|
||||||
) {
|
|
||||||
v.push(self.fps.get_textarea());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
mod flying;
|
|
||||||
mod landed;
|
|
||||||
mod outfitter;
|
|
||||||
|
|
||||||
pub use flying::FlyingScene;
|
|
||||||
pub use landed::LandedScene;
|
|
||||||
pub use outfitter::OutfitterScene;
|
|
|
@ -1,145 +0,0 @@
|
||||||
use galactica_content::{Content, SystemObject, SystemObjectHandle};
|
|
||||||
use galactica_system::{data::ShipState, phys::PhysSimShipHandle};
|
|
||||||
use glyphon::{cosmic_text::Align, Attrs, Color, Metrics, TextArea, Weight};
|
|
||||||
use nalgebra::{Point2, Vector2};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ui::{
|
|
||||||
manager::{UiScene, UiSceneStepResult, UiScenes},
|
|
||||||
util::{SpriteRect, UiSprite, UiTextArea},
|
|
||||||
},
|
|
||||||
RenderInput, RenderState,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::LandedScene;
|
|
||||||
|
|
||||||
pub struct OutfitterScene {
|
|
||||||
// UI elements
|
|
||||||
description: UiTextArea,
|
|
||||||
landscape: UiSprite,
|
|
||||||
button: UiSprite,
|
|
||||||
|
|
||||||
/// What object we're displaying currently.
|
|
||||||
/// Whenever this changes, we need to reflow text.
|
|
||||||
current_object: Option<SystemObjectHandle>,
|
|
||||||
|
|
||||||
/// True if we've caught a left click event.
|
|
||||||
/// Used for edge detection.
|
|
||||||
leftclick_down: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OutfitterScene {
|
|
||||||
pub fn new(ct: &Content, state: &mut RenderState) -> Self {
|
|
||||||
let button = UiSprite::new(
|
|
||||||
ct,
|
|
||||||
ct.get_sprite_handle("ui::button"),
|
|
||||||
None,
|
|
||||||
SpriteRect {
|
|
||||||
pos: Point2::new(0.0, 0.0),
|
|
||||||
dim: Vector2::new(200.0, 200.0),
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
let landscape = UiSprite::from_with_sprite(
|
|
||||||
ct,
|
|
||||||
&ct.get_ui().landed_landscape,
|
|
||||||
ct.get_sprite_handle("ui::landscape::test"),
|
|
||||||
);
|
|
||||||
|
|
||||||
let s = Self {
|
|
||||||
// height of element in logical pixels
|
|
||||||
current_object: None,
|
|
||||||
leftclick_down: false,
|
|
||||||
|
|
||||||
description: UiTextArea::new(
|
|
||||||
ct,
|
|
||||||
state,
|
|
||||||
button.get_sprite(),
|
|
||||||
Point2::new(0.0, 0.0),
|
|
||||||
800.0,
|
|
||||||
SpriteRect {
|
|
||||||
pos: Point2::new(25.831, 284.883) / 512.0,
|
|
||||||
dim: Vector2::new(433.140, 97.220) / 512.0,
|
|
||||||
},
|
|
||||||
Metrics::new(16.0, 18.0),
|
|
||||||
Color::rgb(255, 255, 255),
|
|
||||||
Align::Left,
|
|
||||||
),
|
|
||||||
|
|
||||||
landscape,
|
|
||||||
button,
|
|
||||||
};
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reflow(&mut self, planet: &SystemObject, state: &mut RenderState) {
|
|
||||||
self.description.set_text(
|
|
||||||
state,
|
|
||||||
&planet.desc,
|
|
||||||
Attrs::new()
|
|
||||||
.weight(Weight::NORMAL)
|
|
||||||
.family(glyphon::Family::SansSerif),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.current_object = Some(planet.handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'this> UiScene<'this> for OutfitterScene {
|
|
||||||
fn step(&mut self, input: &RenderInput, state: &mut RenderState) -> UiSceneStepResult {
|
|
||||||
self.button.step(input, state, None);
|
|
||||||
self.landscape.step(input, state, None);
|
|
||||||
|
|
||||||
let mut new_scene = None;
|
|
||||||
if input.player.input.pressed_leftclick() && !self.leftclick_down {
|
|
||||||
self.leftclick_down = true;
|
|
||||||
if self.button.contains_mouse(input, state, None) {
|
|
||||||
new_scene = Some(UiScenes::Landed(LandedScene::new(input.ct, state)));
|
|
||||||
}
|
|
||||||
} else if !input.player.input.pressed_leftclick() {
|
|
||||||
self.leftclick_down = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return UiSceneStepResult { new_scene };
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
|
||||||
// Get required data
|
|
||||||
let ship_handle = input.player.ship.unwrap();
|
|
||||||
let ship_data = &input
|
|
||||||
.phys_img
|
|
||||||
.get_ship(&PhysSimShipHandle(ship_handle))
|
|
||||||
.unwrap()
|
|
||||||
.ship;
|
|
||||||
let planet_handle = match ship_data.get_data().get_state() {
|
|
||||||
ShipState::Landed { target } => *target,
|
|
||||||
_ => unreachable!("tried to draw planet interface while not landed!"),
|
|
||||||
};
|
|
||||||
let planet = input.ct.get_system_object(planet_handle);
|
|
||||||
|
|
||||||
// Reconfigure for new planet if necessary
|
|
||||||
if self
|
|
||||||
.current_object
|
|
||||||
.map(|x| x != planet_handle)
|
|
||||||
.unwrap_or(true)
|
|
||||||
{
|
|
||||||
self.reflow(planet, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw elements
|
|
||||||
self.button.push_to_buffer(input, state, None);
|
|
||||||
self.landscape.push_to_buffer(input, state, None);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_textareas(
|
|
||||||
&'this self,
|
|
||||||
v: &mut Vec<TextArea<'this>>,
|
|
||||||
input: &RenderInput,
|
|
||||||
state: &RenderState,
|
|
||||||
) {
|
|
||||||
v.push(self.description.get_textarea(input, state));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,24 +17,6 @@ pub struct UiSprite {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UiSprite {
|
impl UiSprite {
|
||||||
pub fn new(
|
|
||||||
ct: &Content,
|
|
||||||
sprite: SpriteHandle,
|
|
||||||
mask: Option<SpriteHandle>,
|
|
||||||
rect: SpriteRect,
|
|
||||||
on_mouse_enter: Option<SectionEdge>,
|
|
||||||
on_mouse_leave: Option<SectionEdge>,
|
|
||||||
) -> Self {
|
|
||||||
return Self {
|
|
||||||
anim: SpriteAutomaton::new(ct, sprite),
|
|
||||||
mask,
|
|
||||||
rect,
|
|
||||||
has_mouse: false,
|
|
||||||
on_mouse_enter,
|
|
||||||
on_mouse_leave,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from(ct: &Content, ui: &UiSpriteConfig) -> Self {
|
pub fn from(ct: &Content, ui: &UiSpriteConfig) -> Self {
|
||||||
if ui.sprite.is_none() {
|
if ui.sprite.is_none() {
|
||||||
unreachable!("called `UiSprite.from()` on a UiSprite with a None sprite!")
|
unreachable!("called `UiSprite.from()` on a UiSprite with a None sprite!")
|
||||||
|
@ -44,17 +26,17 @@ impl UiSprite {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_with_sprite(ct: &Content, ui: &UiSpriteConfig, sprite: SpriteHandle) -> Self {
|
pub fn from_with_sprite(ct: &Content, ui: &UiSpriteConfig, sprite: SpriteHandle) -> Self {
|
||||||
Self::new(
|
return Self {
|
||||||
ct,
|
anim: SpriteAutomaton::new(ct, sprite),
|
||||||
sprite,
|
mask: ui.mask,
|
||||||
ui.mask,
|
rect: SpriteRect {
|
||||||
SpriteRect {
|
|
||||||
pos: *ui.rect.get_pos(),
|
pos: *ui.rect.get_pos(),
|
||||||
dim: *ui.rect.get_dim(),
|
dim: *ui.rect.get_dim(),
|
||||||
},
|
},
|
||||||
ui.on_mouse_enter,
|
has_mouse: false,
|
||||||
ui.on_mouse_leave,
|
on_mouse_enter: ui.on_mouse_enter,
|
||||||
)
|
on_mouse_leave: ui.on_mouse_leave,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step(&mut self, input: &RenderInput, state: &RenderState, parent: Option<SpriteRect>) {
|
pub fn step(&mut self, input: &RenderInput, state: &RenderState, parent: Option<SpriteRect>) {
|
||||||
|
|
Loading…
Reference in New Issue