From 42ed93b8f03e3a2c9df329016af1ab1cedef8df5 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 17 Apr 2022 23:05:30 +0100 Subject: [PATCH] currency: Initial skeleton Can render, but no special behaviours. Signed-off-by: Ian Jackson --- src/currency.rs | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/spec.rs | 2 + 3 files changed, 118 insertions(+) create mode 100644 src/currency.rs diff --git a/src/currency.rs b/src/currency.rs new file mode 100644 index 00000000..e39cfc2b --- /dev/null +++ b/src/currency.rs @@ -0,0 +1,115 @@ +// Copyright 2020-2021 Ian Jackson and contributors to Otter +// SPDX-License-Identifier: AGPL-3.0-or-later +// There is NO WARRANTY. + +//! Currency +//! +//! A "Currency" piece +//! - has an image, which is another piece which it displays +//! - has special counting behaviour on drag and drop +//! - represents a *quanity* + +// Future plans +// - occultable, to hide the quantity +// - can have a back face which is less manipulable (if image has 2 faces) + +use crate::prelude::*; + +const QTY_FONT_SIZE: f64 = 6.; + +type Qty = u32; + +#[derive(Debug,Serialize,Deserialize)] +pub struct Spec { + image: Box, + qty: Qty, + currency: String, + #[serde(default="default_min_unit")] min_unit: Qty, +} + +fn default_min_unit() -> Qty { 1 } + +#[derive(Debug,Serialize,Deserialize)] +pub struct Banknote { + itemname: String, + image: Arc, + qty: Qty, + currency: String, + min_unit: Qty, +} + +#[typetag::serde(name="Currency")] +impl PieceSpec for Spec { + #[throws(SpecError)] + fn load(&self, _: usize, gpc: &mut GPiece, ig: &Instance, depth: SpecDepth) + -> PieceSpecLoaded { + gpc.rotateable = false; + + let Spec { ref image, ref currency, qty, min_unit } = *self; + + let SpecLoaded { p: image, occultable:_ } = + image.load_inert(ig, depth)?; + + let itemname = format!("currency-{}", image.itemname()); + + if image.nfaces() != 1 { + throw!(SpecError::WrongNumberOfFaces { + got: image.nfaces(), got_why: "image".into(), + exp: 1, exp_why: "needed".into(), + }); + } + + if (qty % min_unit) != 0 { + throw!(SpecError::CurrencyQtyNotMultipleOfUnit) + } + + let bnote = Banknote { + image: image.into(), + currency: currency.clone(), + itemname, qty, min_unit, + }; + + SpecLoaded { p: Box::new(bnote) as _, occultable: None } + } +} + +#[dyn_upcast] +impl OutlineTrait for Banknote { + delegate!{ + to self.image { + fn outline_path(&self, scale: f64) -> Result; + fn thresh_dragraise(&self) -> Result, IE>; + fn bbox_approx(&self) -> Result; + } + } +} + +#[dyn_upcast] +impl PieceBaseTrait for Banknote { + fn nfaces(&self) -> RawFaceId { self.image.nfaces() } + fn itemname(&self) -> &str { &self.itemname } +} + +#[typetag::serde(name="Currency")] +impl PieceTrait for Banknote { + #[throws(IE)] + fn describe_html(&self, gpc: &GPiece, _: &GameOccults) -> Html { + hformat!("{}, {} {}", + self.image.describe_html(gpc.face)?, + self.qty, Html::from_txt(&self.currency)) + } + + #[throws(IE)] + fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _gs: &GameState, + vpid: VisiblePieceId) { + self.image.svg(f, vpid, gpc.face, &gpc.xdata)?; + + let label_font_size = QTY_FONT_SIZE; + let label_y_adj = label_font_size * SVG_FONT_Y_ADJUST_OF_FONT_SIZE; + + hwrite!(f, + r##"{} {}"##, + label_y_adj, label_font_size, + self.qty, &self.currency)?; + } +} diff --git a/src/lib.rs b/src/lib.rs index 4cc863f4..7394bd94 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ pub mod childio; pub mod clock; pub mod commands; pub mod config; +pub mod currency; pub mod deck; pub mod dice; pub mod debugmutex; diff --git a/src/spec.rs b/src/spec.rs index d429c715..47e211ec 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -87,6 +87,8 @@ pub enum SpecError { #[error("invalid size scale")] InvalidSizeScale, #[error("multiple faces required")] MultipleFacesRequired, #[error("far too many faces ({0})")] FarTooManyFaces(usize), + #[error("currency quantity not multiple of minimum unit")] + CurrencyQtyNotMultipleOfUnit, #[error("coordinate overflow")] CoordinateOverflow(#[from] CoordinateOverflow), #[error("image for supposedly-occultable piece \ -- 2.30.2