From 8b05ed526d29f9636075ae0674de848e0fb9b9ac Mon Sep 17 00:00:00 2001
From: Jake Stanger <mail@jstanger.dev>
Date: Fri, 28 Jun 2024 23:27:52 +0100
Subject: [PATCH] refactor: move label truncate function to ext trait

 Conflicts:
	src/gtk_helpers.rs
	src/modules/music/mod.rs
---
 Cargo.lock                    | 16 ++++++++--------
 src/config/truncate.rs        | 29 ++++++++++-------------------
 src/gtk_helpers.rs            | 20 ++++++++++++++++++--
 src/modules/clipboard.rs      |  3 ++-
 src/modules/focused.rs        |  3 ++-
 src/modules/music/mod.rs      |  2 +-
 src/modules/networkmanager.rs |  4 ++--
 src/modules/sway/mode.rs      |  2 +-
 8 files changed, 44 insertions(+), 35 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index ae8bf35..d981825 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3200,7 +3200,7 @@ dependencies = [
  "dbusmenu-gtk3-sys",
  "gtk",
  "serde",
- "thiserror 2.0.0",
+ "thiserror 2.0.3",
  "tokio",
  "tracing",
  "zbus",
@@ -3230,11 +3230,11 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "2.0.0"
+version = "2.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15291287e9bff1bc6f9ff3409ed9af665bec7a5fc8ac079ea96be07bca0e2668"
+checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
 dependencies = [
- "thiserror-impl 2.0.0",
+ "thiserror-impl 2.0.3",
 ]
 
 [[package]]
@@ -3250,9 +3250,9 @@ dependencies = [
 
 [[package]]
 name = "thiserror-impl"
-version = "2.0.0"
+version = "2.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22efd00f33f93fa62848a7cab956c3d38c8d43095efda1decfc2b3a5dc0b8972"
+checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
 dependencies = [
  "proc-macro2",
  "quote 1.0.35",
@@ -3681,9 +3681,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
 
 [[package]]
 name = "uuid"
-version = "1.8.0"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
+checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
 dependencies = [
  "getrandom",
 ]
diff --git a/src/config/truncate.rs b/src/config/truncate.rs
index 14222ad..69fde92 100644
--- a/src/config/truncate.rs
+++ b/src/config/truncate.rs
@@ -1,5 +1,4 @@
 use gtk::pango::EllipsizeMode as GtkEllipsizeMode;
-use gtk::prelude::*;
 use serde::Deserialize;
 
 #[derive(Debug, Deserialize, Clone, Copy)]
@@ -102,35 +101,27 @@ pub enum TruncateMode {
 }
 
 impl TruncateMode {
-    const fn mode(&self) -> EllipsizeMode {
-        match self {
-            Self::Length { mode, .. } | Self::Auto(mode) => *mode,
-        }
-    }
-
-    const fn length(&self) -> Option<i32> {
+    pub const fn length(&self) -> Option<i32> {
         match self {
             Self::Auto(_) | Self::Off => None,
             Self::Length { length, .. } => *length,
         }
     }
 
-    const fn max_length(&self) -> Option<i32> {
+    pub const fn max_length(&self) -> Option<i32> {
         match self {
             Self::Auto(_) | Self::Off => None,
             Self::Length { max_length, .. } => *max_length,
         }
     }
+}
 
-    pub fn truncate_label(&self, label: &gtk::Label) {
-        label.set_ellipsize(self.mode().into());
-
-        if let Some(length) = self.length() {
-            label.set_width_chars(length);
-        }
-
-        if let Some(length) = self.max_length() {
-            label.set_max_width_chars(length);
-        }
+impl From<TruncateMode> for GtkEllipsizeMode {
+    fn from(value: TruncateMode) -> Self {
+        let mode = match value {
+            TruncateMode::Off => EllipsizeMode::None,
+            TruncateMode::Length { mode, .. } | TruncateMode::Auto(mode) => mode,
+        };
+        mode.into()
     }
 }
diff --git a/src/gtk_helpers.rs b/src/gtk_helpers.rs
index 628ac3a..1b5052b 100644
--- a/src/gtk_helpers.rs
+++ b/src/gtk_helpers.rs
@@ -1,6 +1,8 @@
+use crate::config::TruncateMode;
 use glib::{markup_escape_text, IsA};
+use gtk::pango::EllipsizeMode;
 use gtk::prelude::*;
-use gtk::{Orientation, Widget};
+use gtk::{Label, Orientation, Widget};
 
 /// Represents a widget's size
 /// and location relative to the bar's start edge.
@@ -83,9 +85,11 @@ pub trait IronbarLabelExt {
     /// the text is escaped to avoid issues with special characters (ie `&`).
     /// Otherwise, the text is used verbatim, and it is up to the user to escape.
     fn set_label_escaped(&self, label: &str);
+
+    fn truncate(&self, mode: TruncateMode);
 }
 
-impl IronbarLabelExt for gtk::Label {
+impl IronbarLabelExt for Label {
     fn set_label_escaped(&self, label: &str) {
         if !label.contains("<span") {
             self.set_label(&markup_escape_text(label));
@@ -93,4 +97,16 @@ impl IronbarLabelExt for gtk::Label {
             self.set_label(label);
         }
     }
+
+    fn truncate(&self, mode: TruncateMode) {
+        self.set_ellipsize(<TruncateMode as Into<EllipsizeMode>>::into(mode));
+
+        if let Some(length) = mode.length() {
+            self.set_width_chars(length);
+        }
+
+        if let Some(length) = mode.max_length() {
+            self.set_max_width_chars(length);
+        }
+    }
 }
diff --git a/src/modules/clipboard.rs b/src/modules/clipboard.rs
index aea0c32..9dbd68c 100644
--- a/src/modules/clipboard.rs
+++ b/src/modules/clipboard.rs
@@ -1,6 +1,7 @@
 use crate::clients::clipboard::{self, ClipboardEvent};
 use crate::clients::wayland::{ClipboardItem, ClipboardValue};
 use crate::config::{CommonConfig, TruncateMode};
+use crate::gtk_helpers::IronbarLabelExt;
 use crate::image::new_icon_button;
 use crate::modules::{
     Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
@@ -195,7 +196,7 @@ impl Module<Button> for ClipboardModule {
                                 button.add(&label);
 
                                 if let Some(truncate) = self.truncate {
-                                    truncate.truncate_label(&label);
+                                    label.truncate(truncate);
                                 }
 
                                 button.style_context().add_class("text");
diff --git a/src/modules/focused.rs b/src/modules/focused.rs
index 2fde9bf..250493e 100644
--- a/src/modules/focused.rs
+++ b/src/modules/focused.rs
@@ -1,6 +1,7 @@
 use crate::clients::wayland::{self, ToplevelEvent};
 use crate::config::{CommonConfig, TruncateMode};
 use crate::gtk_helpers::IronbarGtkExt;
+use crate::gtk_helpers::IronbarLabelExt;
 use crate::image::ImageProvider;
 use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
 use crate::{glib_recv, module_impl, send_async, spawn, try_send};
@@ -145,7 +146,7 @@ impl Module<gtk::Box> for FocusedModule {
         label.add_class("label");
 
         if let Some(truncate) = self.truncate {
-            truncate.truncate_label(&label);
+            label.truncate(truncate);
         }
 
         container.add(&label);
diff --git a/src/modules/music/mod.rs b/src/modules/music/mod.rs
index 1e02de4..53b6baa 100644
--- a/src/modules/music/mod.rs
+++ b/src/modules/music/mod.rs
@@ -196,7 +196,7 @@ impl Module<Button> for MusicModule {
             .build();
 
         if let Some(truncate) = self.truncate {
-            truncate.truncate_label(&label);
+            label.truncate(truncate);
         }
 
         button_contents.add(&icon_pause);
diff --git a/src/modules/networkmanager.rs b/src/modules/networkmanager.rs
index 6235b51..55668ec 100644
--- a/src/modules/networkmanager.rs
+++ b/src/modules/networkmanager.rs
@@ -66,7 +66,7 @@ impl Module<GtkBox> for NetworkManagerModule {
 
         let initial_icon_name = "content-loading-symbolic";
         ImageProvider::parse(initial_icon_name, &icon_theme, false, self.icon_size)
-            .map(|provider| provider.load_into_image(icon.clone()));
+            .map(|provider| provider.load_into_image(&icon));
 
         let widget_receiver = context.subscribe();
         glib_recv!(widget_receiver, state => {
@@ -80,7 +80,7 @@ impl Module<GtkBox> for NetworkManagerModule {
                 ClientState::Unknown => "dialog-question-symbolic",
             };
             ImageProvider::parse(icon_name, &icon_theme, false, self.icon_size)
-                .map(|provider| provider.load_into_image(icon.clone()));
+                .map(|provider| provider.load_into_image(&icon));
         });
 
         Ok(ModuleParts::new(container, None))
diff --git a/src/modules/sway/mode.rs b/src/modules/sway/mode.rs
index eb544d9..b9bcbaa 100644
--- a/src/modules/sway/mode.rs
+++ b/src/modules/sway/mode.rs
@@ -66,7 +66,7 @@ impl Module<Label> for SwayModeModule {
             let label = label.clone();
 
             if let Some(truncate) = self.truncate {
-                truncate.truncate_label(&label);
+                label.truncate(truncate);
             }
 
             let on_mode = move |mode: ModeEvent| {
