diff --git a/src/ui/panes/pid_drawing_tool/symbols.rs b/src/ui/panes/pid_drawing_tool/symbols.rs
index 6bbbe4c4557b5afeab304c095ef99615ec251021..3cf69bcc8359d7d24f3e5ec911e249aeb35537a1 100644
--- a/src/ui/panes/pid_drawing_tool/symbols.rs
+++ b/src/ui/panes/pid_drawing_tool/symbols.rs
@@ -1,20 +1,24 @@
 pub mod icons;
-mod labels;
+mod label;
+mod value_display;
 
 use egui::{Theme, Ui};
 use enum_dispatch::enum_dispatch;
 use glam::Vec2;
-use icons::Icon;
-use labels::Label;
 use serde::{Deserialize, Serialize};
 use strum_macros::{Display, EnumIter};
 
+use icons::Icon;
+use label::Label;
+use value_display::ValueDisplay;
+
 use crate::mavlink::MavMessage;
 
 #[derive(Clone, Serialize, Deserialize, PartialEq, EnumIter, Display, Debug)]
 #[enum_dispatch]
 pub enum Symbol {
     Icon(Icon),
+    ValueDisplay(ValueDisplay),
     Label(Label),
 }
 
diff --git a/src/ui/panes/pid_drawing_tool/symbols/label.rs b/src/ui/panes/pid_drawing_tool/symbols/label.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0b7191cec1f7c466a92ae263bf2a0f6c75e2b3c6
--- /dev/null
+++ b/src/ui/panes/pid_drawing_tool/symbols/label.rs
@@ -0,0 +1,99 @@
+use serde::{Deserialize, Serialize};
+
+use egui::{
+    Align2, Color32, CornerRadius, FontId, Stroke, StrokeKind, TextEdit, Theme, Ui, Window,
+};
+use glam::Vec2;
+
+use crate::{
+    mavlink::MavMessage,
+    ui::utils::{egui_to_glam, glam_to_egui},
+};
+
+use super::SymbolBehavior;
+
+const FONT_SIZE: f32 = 2.0;
+
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
+pub struct Label {
+    text: String,
+    size: Vec2,
+
+    #[serde(skip)]
+    is_window_visible: bool,
+}
+
+impl Default for Label {
+    fn default() -> Self {
+        Self {
+            text: "Label".to_string(),
+            size: Vec2::new(FONT_SIZE * 0.6 * 4.0, FONT_SIZE),
+            is_window_visible: false,
+        }
+    }
+}
+
+impl SymbolBehavior for Label {
+    fn update(&mut self, _message: &MavMessage, _subscribed_msg_id: u32) {}
+
+    fn reset_subscriptions(&mut self) {}
+
+    fn paint(&mut self, ui: &mut Ui, theme: Theme, pos: Vec2, size: f32, _: f32) {
+        let painter = ui.painter();
+        let color = match theme {
+            Theme::Light => Color32::BLACK,
+            Theme::Dark => Color32::WHITE,
+        };
+
+        let text_rect = painter.text(
+            glam_to_egui(pos).to_pos2(),
+            Align2::LEFT_TOP,
+            &self.text,
+            FontId::monospace(FONT_SIZE * size),
+            color,
+        );
+        self.size = egui_to_glam(text_rect.size()) / size;
+        painter.rect(
+            egui::Rect::from_min_size(
+                glam_to_egui(pos).to_pos2(),
+                glam_to_egui(self.size()) * size,
+            ),
+            CornerRadius::ZERO,
+            Color32::TRANSPARENT,
+            Stroke::NONE,
+            StrokeKind::Middle,
+        );
+    }
+
+    fn subscriptions_ui(&mut self, ui: &mut Ui, _mavlink_id: u32) {
+        Window::new("Label Customization")
+            .id(ui.auto_id_with("customization_settings"))
+            .auto_sized()
+            .collapsible(true)
+            .movable(true)
+            .open(&mut self.is_window_visible)
+            .show(ui.ctx(), |ui| subscription_window(ui, &mut self.text));
+    }
+
+    fn context_menu(&mut self, ui: &mut Ui) {
+        if ui.button("Customize text…").clicked() {
+            self.is_window_visible = true;
+            ui.close_menu();
+        }
+    }
+
+    fn anchor_points(&self) -> Option<Vec<Vec2>> {
+        None
+    }
+
+    fn size(&self) -> Vec2 {
+        self.size
+    }
+}
+
+fn subscription_window(ui: &mut Ui, text: &mut String) {
+    TextEdit::singleline(text)
+        .hint_text("Label text")
+        .desired_width(200.0)
+        .show(ui);
+}
diff --git a/src/ui/panes/pid_drawing_tool/symbols/labels.rs b/src/ui/panes/pid_drawing_tool/symbols/value_display.rs
similarity index 97%
rename from src/ui/panes/pid_drawing_tool/symbols/labels.rs
rename to src/ui/panes/pid_drawing_tool/symbols/value_display.rs
index e20c55140a091fc3146f4d60a542fa33ae01c1d1..21915bde13e13999b4b774ba22c39241d67722b9 100644
--- a/src/ui/panes/pid_drawing_tool/symbols/labels.rs
+++ b/src/ui/panes/pid_drawing_tool/symbols/value_display.rs
@@ -20,7 +20,7 @@ use super::SymbolBehavior;
 const FONT_SIZE: f32 = 2.0;
 
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
-pub struct Label {
+pub struct ValueDisplay {
     subscribed_field: Option<IndexedField>,
     size: Vec2,
 
@@ -30,7 +30,7 @@ pub struct Label {
     is_subs_window_visible: bool,
 }
 
-impl Default for Label {
+impl Default for ValueDisplay {
     fn default() -> Self {
         Self {
             subscribed_field: None,
@@ -41,7 +41,7 @@ impl Default for Label {
     }
 }
 
-impl SymbolBehavior for Label {
+impl SymbolBehavior for ValueDisplay {
     fn update(&mut self, message: &MavMessage, subscribed_msg_id: u32) {
         if let Some(subscribed_field) = &self.subscribed_field {
             if message.message_id() == subscribed_msg_id {