refactor: sensor configuration fields
Automatically round decimal values for sensor.x and .y to an integer. Make fields optional which are not used in every sensor.
This commit is contained in:
@@ -53,7 +53,6 @@ The background image and sensor definitions are taken from the default system pa
|
||||
"sensor": [
|
||||
{
|
||||
"mode": 1,
|
||||
"type": 1,
|
||||
"name": "CPU temp",
|
||||
"label": "cpu_temperature",
|
||||
"x": 195,
|
||||
@@ -67,7 +66,6 @@ The background image and sensor definitions are taken from the default system pa
|
||||
},
|
||||
{
|
||||
"mode": 1,
|
||||
"type": 1,
|
||||
"name": "CPU usage",
|
||||
"label": "cpu_percent",
|
||||
"unit": "%",
|
||||
|
||||
@@ -31,7 +31,6 @@ Example `panel.json` with a single "fan" indicator sensor and the following (par
|
||||
"id": "29d9ef2d-30b4-459d-b2b0-43cb6d4d6b41",
|
||||
"itemName": "CPU usage",
|
||||
"mode": 2,
|
||||
"type": 1,
|
||||
"direction": 1,
|
||||
"label": "cpu_percent",
|
||||
"value": "47.7",
|
||||
@@ -39,10 +38,6 @@ Example `panel.json` with a single "fan" indicator sensor and the following (par
|
||||
"y": 184,
|
||||
"width": 237,
|
||||
"height": 237,
|
||||
"fontColor": "#ffffff",
|
||||
"fontSize": 14,
|
||||
"fontFamily": "default_font",
|
||||
"textAlign": "left",
|
||||
"minAngle": -160,
|
||||
"maxAngle": 30,
|
||||
"minValue": 0,
|
||||
|
||||
@@ -25,41 +25,30 @@ The background image and sensor definitions are taken from the default system pa
|
||||
"sensor": [
|
||||
{
|
||||
"mode": 3,
|
||||
"type": 2,
|
||||
"name": "SSD 4 usage",
|
||||
"label": "storage_ssd4_usage",
|
||||
"x": 400,
|
||||
"y": 45,
|
||||
"direction": 1,
|
||||
"value": "35",
|
||||
"fontFamily": "HarmonyOS_Sans_SC_Bold",
|
||||
"fontSize": 24,
|
||||
"fontColor": -1,
|
||||
"textAlign": "center",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"pic": "progress.png"
|
||||
},
|
||||
{
|
||||
"mode": 3,
|
||||
"type": 2,
|
||||
"name": "SSD 5 usage",
|
||||
"label": "storage_ssd5_usage",
|
||||
"x": 400,
|
||||
"y": 106,
|
||||
"direction": 1,
|
||||
"value": "80",
|
||||
"fontFamily": "HarmonyOS_Sans_SC_Bold",
|
||||
"fontSize": 24,
|
||||
"fontColor": -1,
|
||||
"textAlign": "center",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"pic": "progress.png"
|
||||
},
|
||||
{
|
||||
"mode": 1,
|
||||
"type": 2,
|
||||
"name": "SSD 4 temp",
|
||||
"label": "storage_ssd4_temperature",
|
||||
"x": 580,
|
||||
@@ -68,7 +57,6 @@ The background image and sensor definitions are taken from the default system pa
|
||||
"value": "34",
|
||||
"fontFamily": "HarmonyOS_Sans_SC_Bold",
|
||||
"fontSize": 24,
|
||||
"fontColor": -1,
|
||||
"textAlign": "center",
|
||||
"integerDigits": -1,
|
||||
"decimalDigits": 0,
|
||||
@@ -76,7 +64,6 @@ The background image and sensor definitions are taken from the default system pa
|
||||
},
|
||||
{
|
||||
"mode": 1,
|
||||
"type": 2,
|
||||
"name": "SSD 5 temp",
|
||||
"label": "storage_ssd5_temperature",
|
||||
"x": 580,
|
||||
@@ -85,7 +72,6 @@ The background image and sensor definitions are taken from the default system pa
|
||||
"value": "35",
|
||||
"fontFamily": "HarmonyOS_Sans_SC_Bold",
|
||||
"fontSize": 24,
|
||||
"fontColor": -1,
|
||||
"textAlign": "center",
|
||||
"integerDigits": -1,
|
||||
"decimalDigits": 0,
|
||||
|
||||
@@ -31,7 +31,6 @@ Example `panel.json` with a single "pointer" indicator sensor and the following
|
||||
"id": "a9d4acac-2af9-4fe0-9f69-86cd09f25696",
|
||||
"itemName": "CPU dial",
|
||||
"mode": 4,
|
||||
"type": 1,
|
||||
"direction": 1,
|
||||
"label": "cpu_percent",
|
||||
"value": "47.7",
|
||||
@@ -39,11 +38,6 @@ Example `panel.json` with a single "pointer" indicator sensor and the following
|
||||
"y": 208,
|
||||
"width": 302,
|
||||
"height": 302,
|
||||
"fontColor": "#ffffff",
|
||||
"fontSize": 14,
|
||||
"fontFamily": "",
|
||||
"fontWeight": "normal",
|
||||
"textAlign": "left",
|
||||
"minAngle": -110,
|
||||
"maxAngle": 110,
|
||||
"minValue": 0,
|
||||
|
||||
+30
-17
@@ -91,8 +91,11 @@ pub fn load_custom_panel<P: AsRef<Path>>(path: P) -> anyhow::Result<Panel> {
|
||||
{
|
||||
sensor.pic = Some(img_path.join(pic).display().to_string());
|
||||
}
|
||||
if !sensor.font_family.is_empty() && !Path::new(&sensor.font_family).is_absolute() {
|
||||
sensor.font_family = font_path.join(&sensor.font_family).display().to_string();
|
||||
if let Some(font_family) = &sensor.font_family
|
||||
&& !font_family.is_empty()
|
||||
&& !Path::new(&font_family).is_absolute()
|
||||
{
|
||||
sensor.font_family = Some(font_path.join(font_family).display().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +286,7 @@ impl Panel {
|
||||
pub struct Sensor {
|
||||
/// Sensor mode: text, fan, progress, pointer
|
||||
pub mode: SensorMode,
|
||||
/// Sensor type. TODO verify sensor type values
|
||||
/// Sensor type, _not used_.
|
||||
/// - 1 Time / Date Labels
|
||||
/// - 2 Windows-specific system info
|
||||
/// - 3 Hardware value
|
||||
@@ -293,7 +296,7 @@ pub struct Sensor {
|
||||
/// - 7 system info ?
|
||||
/// - 8 lm-sensor ?
|
||||
#[serde(rename = "type")]
|
||||
pub sensor_type: i32,
|
||||
pub sensor_type: Option<i32>,
|
||||
/// Label name for internal panels.
|
||||
pub name: Option<String>,
|
||||
/// Label name for custom panels.
|
||||
@@ -312,12 +315,12 @@ pub struct Sensor {
|
||||
/// Optional unit text to print after the value
|
||||
#[serde(deserialize_with = "empty_string_as_none")]
|
||||
pub unit: Option<String>,
|
||||
/// x-position. Custom panel coordinates are stored as float!
|
||||
// TODO use i32 and round from f32 in deserialization
|
||||
pub x: f32,
|
||||
/// y-position.
|
||||
// TODO use i32 and round from f32 in deserialization
|
||||
pub y: f32,
|
||||
/// Rounded x-position. Custom panel coordinates are stored as float!
|
||||
#[serde(deserialize_with = "f32_as_rounded_i32")]
|
||||
pub x: i32,
|
||||
/// Rounded y-position. Custom panel coordinates are stored as float!
|
||||
#[serde(deserialize_with = "f32_as_rounded_i32")]
|
||||
pub y: i32,
|
||||
/// Used for pointer type
|
||||
pub width: Option<i32>,
|
||||
/// Used for pointer type
|
||||
@@ -326,14 +329,14 @@ pub struct Sensor {
|
||||
pub direction: Option<SensorDirection>,
|
||||
|
||||
/// Font name matching font filename without file extension.
|
||||
pub font_family: String,
|
||||
pub font_family: Option<String>,
|
||||
/// TODO font size unit: points or pixels?
|
||||
pub font_size: i32,
|
||||
pub font_size: Option<i32>,
|
||||
/// Font color in `#RRGGBB` notation, or -1 if not set. #ffffff = white, #ff0000 = red
|
||||
pub font_color: FontColor,
|
||||
pub font_color: Option<FontColor>,
|
||||
/// _Not (yet) used_
|
||||
pub font_weight: FontWeight,
|
||||
pub text_align: TextAlign,
|
||||
pub font_weight: Option<FontWeight>,
|
||||
pub text_align: Option<TextAlign>,
|
||||
|
||||
/// Number of integer places for the sensor value.
|
||||
// -1 ≈ unset ⇒ Option<i32>
|
||||
@@ -429,16 +432,18 @@ pub enum TimeDateLabel {
|
||||
HM3,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum FontWeight {
|
||||
#[default]
|
||||
Normal,
|
||||
Bold,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum TextAlign {
|
||||
#[default]
|
||||
Left,
|
||||
Center,
|
||||
Right,
|
||||
@@ -569,3 +574,11 @@ where
|
||||
let option = Option::<String>::deserialize(deserializer)?;
|
||||
Ok(option.and_then(|s| if s.trim().is_empty() { None } else { Some(s) }))
|
||||
}
|
||||
|
||||
fn f32_as_rounded_i32<'de, D>(deserializer: D) -> Result<i32, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let rounded = f32::deserialize(deserializer).map(f32::round)?;
|
||||
Ok(rounded as i32)
|
||||
}
|
||||
|
||||
+20
-18
@@ -205,15 +205,16 @@ impl PanelRenderer {
|
||||
value: &str,
|
||||
unit: &str,
|
||||
) -> Result<(), ImageProcessingError> {
|
||||
let font = self
|
||||
.font_handler
|
||||
.get_ttf_font_or_default(&sensor.font_family);
|
||||
let font = if let Some(font_family) = &sensor.font_family {
|
||||
self.font_handler.get_ttf_font_or_default(font_family)
|
||||
} else {
|
||||
FontHandler::default_font()
|
||||
};
|
||||
let font_size = sensor.font_size.unwrap_or(14) as f32;
|
||||
// TODO verify pixel scaling! Is font_size point size or pixel size?
|
||||
// This is still a bit off compared to the original AOOSTAR-X. Only tested with HarmonyOS_Sans_SC_Bold!
|
||||
let adjustment_hack = 0.7;
|
||||
let scale = font
|
||||
.pt_to_px_scale(sensor.font_size as f32 * adjustment_hack)
|
||||
.unwrap();
|
||||
let scale = font.pt_to_px_scale(font_size * adjustment_hack).unwrap();
|
||||
|
||||
let text = format_value(
|
||||
value,
|
||||
@@ -223,12 +224,12 @@ impl PanelRenderer {
|
||||
);
|
||||
let size = text_size(scale, &font, &text);
|
||||
// TODO verify x & y-coordinate handling
|
||||
let x = match sensor.text_align {
|
||||
TextAlign::Left => sensor.x as i32,
|
||||
TextAlign::Center => sensor.x as i32 - (size.0 / 2) as i32,
|
||||
TextAlign::Right => sensor.x as i32 - size.0 as i32,
|
||||
let x = match sensor.text_align.unwrap_or_default() {
|
||||
TextAlign::Left => sensor.x,
|
||||
TextAlign::Center => sensor.x - (size.0 / 2) as i32,
|
||||
TextAlign::Right => sensor.x - size.0 as i32,
|
||||
};
|
||||
let y = (sensor.y - scale.y / 2f32) as i32;
|
||||
let y = (sensor.y as f32 - scale.y / 2f32) as i32;
|
||||
// let y = sensor.y as i32 - (size.1 / 2) as i32;
|
||||
|
||||
debug!(
|
||||
@@ -236,7 +237,7 @@ impl PanelRenderer {
|
||||
sensor.x, sensor.y
|
||||
);
|
||||
|
||||
let font_color = sensor.font_color.into();
|
||||
let font_color = sensor.font_color.unwrap_or_default().into();
|
||||
draw_text_mut(background, font_color, x, y, scale, &font, &text);
|
||||
|
||||
Ok(())
|
||||
@@ -257,8 +258,8 @@ impl PanelRenderer {
|
||||
return Err(ImageProcessingError::InvalidDirection(direction));
|
||||
}
|
||||
|
||||
let pos_x = sensor.x as i32;
|
||||
let pos_y = sensor.y as i32;
|
||||
let pos_x = sensor.x;
|
||||
let pos_y = sensor.y;
|
||||
|
||||
let pic_path = sensor.pic.as_ref().ok_or_else(|| {
|
||||
ImageProcessingError::ImageLoadError("No picture specified".to_string())
|
||||
@@ -385,8 +386,8 @@ impl PanelRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
let pos_x = sensor.x as i32;
|
||||
let pos_y = sensor.y as i32;
|
||||
let pos_x = sensor.x;
|
||||
let pos_y = sensor.y;
|
||||
|
||||
if let Some(progress_layer) = self.get_layer(SensorMode::Progress) {
|
||||
PanelRenderer::paste_image(progress_layer, &processed_img, pos_x, pos_y);
|
||||
@@ -420,8 +421,8 @@ impl PanelRenderer {
|
||||
return Err(ImageProcessingError::InvalidDirection(direction));
|
||||
}
|
||||
|
||||
let x_center = sensor.x as i32;
|
||||
let y_center = sensor.y as i32;
|
||||
let x_center = sensor.x;
|
||||
let y_center = sensor.y;
|
||||
let xz_x = sensor.xz_x.unwrap_or(0);
|
||||
let xz_y = sensor.xz_y.unwrap_or(0);
|
||||
|
||||
@@ -429,6 +430,7 @@ impl PanelRenderer {
|
||||
ImageProcessingError::ImageLoadError("No picture specified".to_string())
|
||||
})?;
|
||||
|
||||
// TODO combine get image with resize
|
||||
let mut pic = self
|
||||
.image_cache
|
||||
.get(pic_path, None)
|
||||
|
||||
Reference in New Issue
Block a user