summaryrefslogtreecommitdiff
path: root/src/blocks_cache.rs
diff options
context:
space:
mode:
authorMaxVerevkin <maxxverrr@gmail.com>2023-04-17 12:26:43 +0300
committerMaxVerevkin <maxxverrr@gmail.com>2023-04-17 12:26:43 +0300
commitd3b488c95817c75ad6ac892e9826da8d9dd189b3 (patch)
treeae7c6b93c89e8bc574446de2e6f4bea349b3cc63 /src/blocks_cache.rs
parenteed0b89aafaee8146688c4ca05146986bbd4dc37 (diff)
downloadi3bar-mango-d3b488c95817c75ad6ac892e9826da8d9dd189b3.tar.gz
refactor cache management
Diffstat (limited to 'src/blocks_cache.rs')
-rw-r--r--src/blocks_cache.rs106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/blocks_cache.rs b/src/blocks_cache.rs
new file mode 100644
index 0000000..890c13f
--- /dev/null
+++ b/src/blocks_cache.rs
@@ -0,0 +1,106 @@
+use crate::config::Config;
+use crate::i3bar_protocol::{Block, MinWidth};
+use crate::text::{self, ComputedText};
+
+#[derive(Default)]
+pub struct BlocksCache {
+ computed: Vec<ComputedBlock>,
+}
+
+pub struct ComputedBlock {
+ pub block: Block,
+ pub full: ComputedText,
+ pub short: Option<ComputedText>,
+ pub min_width: Option<f64>,
+}
+
+impl BlocksCache {
+ pub fn process_new_blocks(&mut self, config: &Config, blocks: &[Block]) {
+ let comp_min_width = |block: &Block| {
+ let markup = block.markup.as_deref() == Some("pango");
+ match &block.min_width {
+ Some(MinWidth::Pixels(p)) => Some(*p as f64),
+ Some(MinWidth::Text(t)) => Some(text::width_of(t, markup, &config.font.0)),
+ None => None,
+ }
+ };
+ let comp_full = |block: &Block, min_width: Option<f64>| {
+ let markup = block.markup.as_deref() == Some("pango");
+ text::ComputedText::new(
+ &block.full_text,
+ text::Attributes {
+ font: &config.font,
+ padding_left: 0.0,
+ padding_right: 0.0,
+ min_width,
+ align: block.align.unwrap_or_default(),
+ markup,
+ },
+ )
+ };
+ let comp_short = |block: &Block, min_width: Option<f64>| {
+ let markup = block.markup.as_deref() == Some("pango");
+ block.short_text.as_ref().map(|short_text| {
+ text::ComputedText::new(
+ short_text,
+ text::Attributes {
+ font: &config.font,
+ padding_left: 0.0,
+ padding_right: 0.0,
+ min_width,
+ align: block.align.unwrap_or_default(),
+ markup,
+ },
+ )
+ })
+ };
+
+ // update cashe
+ if blocks.len() != self.computed.len() {
+ self.computed.clear();
+ for block in blocks {
+ let mw = comp_min_width(block);
+ self.computed.push(ComputedBlock {
+ block: block.clone(),
+ full: comp_full(block, mw),
+ short: comp_short(block, mw),
+ min_width: mw,
+ });
+ }
+ } else {
+ for (block, computed) in blocks.iter().zip(self.computed.iter_mut()) {
+ if block.min_width != computed.block.min_width
+ || block.markup != computed.block.markup
+ {
+ let mw = comp_min_width(block);
+ *computed = ComputedBlock {
+ block: block.clone(),
+ full: comp_full(block, mw),
+ short: comp_short(block, mw),
+ min_width: mw,
+ };
+ } else {
+ if block.full_text != computed.block.full_text {
+ computed.block.full_text = block.full_text.clone();
+ computed.full = comp_full(block, computed.min_width);
+ }
+ if block.short_text != computed.block.short_text {
+ computed.block.full_text = block.full_text.clone();
+ computed.short = comp_short(block, computed.min_width);
+ }
+ computed.block.color = block.color;
+ computed.block.background = block.background;
+ computed.block.align = block.align;
+ computed.block.name = block.name.clone();
+ computed.block.instance = block.instance.clone();
+ computed.block.separator = block.separator;
+ computed.block.separator_block_width = block.separator_block_width;
+ }
+ }
+ }
+ }
+
+ pub fn get_computed(&self) -> &[ComputedBlock] {
+ &self.computed
+ }
+}