chiark / gitweb /
Add centring as an option to Paragraph.
authorSimon Tatham <anakin@pobox.com>
Fri, 19 Jan 2024 06:14:06 +0000 (06:14 +0000)
committerSimon Tatham <anakin@pobox.com>
Fri, 19 Jan 2024 08:20:16 +0000 (08:20 +0000)
src/text.rs

index 44dd7b9fc7dcad3a429562dca23832e7e588c911..95733a96cf9a35956047447102436b3bd92281f1 100644 (file)
@@ -471,6 +471,7 @@ pub struct Paragraph {
     firstindent: usize,
     laterindent: usize,
     wrap: bool,
+    centred: bool,
 }
 
 impl ColouredString {
@@ -504,6 +505,7 @@ impl Paragraph {
             firstindent: 0,
             laterindent: 0,
             wrap: true,
+            centred: false,
         }
     }
 
@@ -512,6 +514,11 @@ impl Paragraph {
         self
     }
 
+    pub fn set_centred(mut self, centred: bool) -> Self {
+        self.centred = centred;
+        self
+    }
+
     pub fn set_indent(
         mut self,
         firstindent: usize,
@@ -591,6 +598,7 @@ fn test_para_build() {
             words: Vec::new(),
             firstindent: 0,
             laterindent: 0,
+            centred: false,
             wrap: true,
         }
     );
@@ -600,6 +608,7 @@ fn test_para_build() {
             words: Vec::new(),
             firstindent: 0,
             laterindent: 0,
+            centred: false,
             wrap: false,
         }
     );
@@ -609,6 +618,7 @@ fn test_para_build() {
             words: Vec::new(),
             firstindent: 3,
             laterindent: 4,
+            centred: false,
             wrap: true,
         }
     );
@@ -624,6 +634,7 @@ fn test_para_build() {
             },
             firstindent: 0,
             laterindent: 0,
+            centred: false,
             wrap: true,
         }
     );
@@ -641,6 +652,7 @@ fn test_para_build() {
             },
             firstindent: 0,
             laterindent: 0,
+            centred: false,
             wrap: true,
         }
     );
@@ -661,6 +673,7 @@ fn test_para_build() {
             },
             firstindent: 0,
             laterindent: 0,
+            centred: false,
             wrap: true,
         }
     );
@@ -683,6 +696,23 @@ impl TextFragment for Paragraph {
         let mut break_width = 0;
         let mut curr_indent = self.firstindent;
 
+        let twidth = width.saturating_sub(1);
+        let mut push_line = |line: ColouredString| {
+            let line = if self.centred {
+                let tspace = twidth.saturating_sub(line.width());
+                let tleft = tspace / 2;
+                ColouredString::plain(" ").repeat(tleft) + line
+            } else {
+                let indent = if lines.len() > 0 {
+                    self.laterindent
+                } else {
+                    self.firstindent
+                };
+                ColouredString::plain(" ").repeat(indent) + line
+            };
+            lines.push(line);
+        };
+
         for (i, word) in self.words.iter().enumerate() {
             curr_width += word.width();
             curr_pos = i + 1;
@@ -692,12 +722,11 @@ impl TextFragment for Paragraph {
                     && break_pos > start_pos
                     && curr_width - start_width + curr_indent >= width
                 {
-                    let mut line =
-                        ColouredString::plain(" ").repeat(curr_indent);
+                    let mut line = ColouredString::plain("");
                     for i in start_pos..break_pos {
                         line.push_str(&self.words[i]);
                     }
-                    lines.push(line);
+                    push_line(line);
                     start_pos = break_pos;
                     start_width = break_width;
                     if self.words[start_pos].is_space() {
@@ -712,11 +741,11 @@ impl TextFragment for Paragraph {
             }
         }
 
-        let mut line = ColouredString::plain(" ").repeat(curr_indent);
+        let mut line = ColouredString::plain("");
         for i in start_pos..break_pos {
             line.push_str(&self.words[i]);
         }
-        lines.push(line);
+        push_line(line);
 
         lines
     }