1 // Copyright 2020-2021 Ian Jackson and contributors to Otter
2 // SPDX-License-Identifier: AGPL-3.0-or-later
3 // There is NO WARRANTY.
7 pub const HELD_SURROUND_COLOUR: &str = "black";
9 const MONOSPACE: HtmlLit = Html::lit(
10 r#"font-family="Latin Modern Mono, monospace" font-weight="700""#);
12 pub const DEFAULT_TABLE_SIZE: Pos = PosC::new( 300, 200 );
13 pub const DEFAULT_TABLE_COLOUR: &str = "green";
15 pub const SELECT_SCALE: f64 = 1.1;
17 // also in script.ts:redisplay_ancillaries ("halo")
18 // nelem.setAttributeNS(null,'stroke-width','2px');
19 pub const SELECT_STROKE_WIDTH: f64 = 2.0;
21 pub const DEFAULT_EDGE_WIDTH: f64 = 0.2;
22 pub const INVISIBLE_EDGE_SENSITIVE: f64 = 2.;
24 pub const LABEL_FONT_SIZE: f64 = 4.0;
26 pub const HTML_TEXT_LABEL_ELEM_START: HtmlLit =
27 Html::lit(r##"text pointer-events="none""##);
29 #[derive(Debug,Serialize,Deserialize,Clone)]
30 pub struct TextOptions {
37 /// When trying to centre text, we use text-align and/or text-anchor
38 /// to do the horizontal positioning, but vertical positioning is
39 /// troublesome. We bodge it. Multiple the font size (in pixels)
40 /// by this, and add it to the SVG y coordinate (ie, shufting the text
42 pub const SVG_FONT_Y_ADJUST_OF_FONT_SIZE: f64 =
43 include!("SVG_FONT_Y_ADJUST_OF_FONT_SIZE.txt");
45 pub fn default_edge_width() -> f64 { DEFAULT_EDGE_WIDTH }
47 pub fn monospace_font(size: u32) -> Html {
48 hformat!(r##"{} font-size="{}""##, MONOSPACE, size)
51 #[derive(Clone,Copy,Debug,Eq,PartialEq,Serialize,Deserialize,EnumString)]
52 pub enum PresentationLayout {
57 type PL = PresentationLayout;
59 pub fn player_num_dasharray(player_num: NonZeroUsize) -> Html {
60 let n: usize = player_num.into();
61 let mut dasharray = String::with_capacity(n*3 + 4);
62 for dash in iter::once("3").chain(
63 iter::repeat("1").take(n-1))
65 write!(&mut dasharray, "{} 1 ", &dash).unwrap();
67 let spc = dasharray.pop();
68 assert_eq!(spc,Some(' '));
69 Html::from_html_string(dasharray)
72 pub fn player_dasharray(gplayers: &GPlayers, player: PlayerId) -> Html {
73 let kd: slotmap::KeyData = player.into();
74 let n: usize = kd.get_idx_version().0.try_into().unwrap();
75 let n: NonZeroUsize = n.try_into()
76 .unwrap_or_else(|_| gplayers.capacity().try_into().unwrap());
77 player_num_dasharray(n)
80 pub fn occultation_notify_update_image(piece: PieceId)
81 -> UnpreparedUpdates {
83 move |updates: &mut PrepareUpdatesBuffer| {
84 updates.piece_update_image(piece, &None)
85 .unwrap_or_else(|e| error!("unable to send update! {:?}", e))
90 impl PresentationLayout {
91 pub fn template(self) -> &'static str {
93 PL::Portrait => "session",
94 PL::Landscape => "landscape",
97 pub fn abbreviate_timestamps(self) -> bool {
99 PL::Portrait => false,
100 PL::Landscape => true,
105 impl Default for PresentationLayout {
106 fn default() -> Self { PL::Portrait }
110 pub struct AbbrevPresentationLayout(pub PresentationLayout);
112 #[derive(Error,Debug,Clone,Copy)]
113 #[error("Invalid presentation layout character")]
114 pub struct InvalidAbbrevPresentationLayout;
116 impl FromStr for AbbrevPresentationLayout {
117 type Err = InvalidAbbrevPresentationLayout;
119 fn from_str(s: &str) -> Self {
120 AbbrevPresentationLayout(match s {
122 "l" => PL::Landscape,
123 _ => throw!(InvalidAbbrevPresentationLayout)
128 impl Display for AbbrevPresentationLayout {
129 #[throws(fmt::Error)]
130 fn fmt(&self, f: &mut fmt::Formatter) {
131 f.write_str(match self.0 {
133 PL::Landscape => "l",
139 pub fn y_adjust(&self) -> f64 {
140 self.size * SVG_FONT_Y_ADJUST_OF_FONT_SIZE
143 pub fn start_element(&self) -> Html {
145 r##"{} text-align="center" text-anchor="middle" x="0" y="{}" fill="{}" font-size="{}px""##,
146 HTML_TEXT_LABEL_ELEM_START,
147 self.y_adjust(), &self.colour, self.size,