Merge b192e08064fbc05e3d58dd60e3d40247fea322b0 into 35f945daa9938d684dca2a5ff9dc0286993622e5

This commit is contained in:
Will Ahlswede 2026-04-22 19:56:01 +08:00 committed by GitHub
commit e9914f59be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 62 additions and 9 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
# Visual Studio
*.vs/
# Rust build artifacts
/target/

View File

@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
fifteen_minutes: "15 Minutes",
one_hour: "1 Hour",
settings: "Settings",
show_decimals: "Show Decimals",
start_with_windows: "Start with Windows",
reset_position: "Reset Position",
language: "Language",

View File

@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
fifteen_minutes: "15 minutes",
one_hour: "1 heure",
settings: "Paramètres",
show_decimals: "Afficher les décimales",
start_with_windows: "Démarrer avec Windows",
reset_position: "Réinitialiser la position",
language: "Langue",

View File

@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
fifteen_minutes: "15 Minuten",
one_hour: "1 Stunde",
settings: "Einstellungen",
show_decimals: "Dezimalstellen anzeigen",
start_with_windows: "Mit Windows starten",
reset_position: "Position zurücksetzen",
language: "Sprache",

View File

@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
fifteen_minutes: "15分",
one_hour: "1時間",
settings: "設定",
show_decimals: "小数点を表示",
start_with_windows: "Windows と同時に開始",
reset_position: "位置をリセット",
language: "言語",

View File

@ -121,6 +121,7 @@ pub struct Strings {
pub fifteen_minutes: &'static str,
pub one_hour: &'static str,
pub settings: &'static str,
pub show_decimals: &'static str,
pub start_with_windows: &'static str,
pub reset_position: &'static str,
pub language: &'static str,

View File

@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
fifteen_minutes: "15 minutos",
one_hour: "1 hora",
settings: "Configuración",
show_decimals: "Mostrar decimales",
start_with_windows: "Iniciar con Windows",
reset_position: "Restablecer posición",
language: "Idioma",

View File

@ -756,9 +756,9 @@ fn is_leap(y: u64) -> bool {
}
/// Format a usage section as "X% · Yh" style text
pub fn format_line(section: &UsageSection, strings: Strings) -> String {
pub fn format_line(section: &UsageSection, strings: Strings, show_decimals: bool) -> String {
let pct = format!("{:.0}%", section.percentage);
let cd = format_countdown(section.resets_at, strings);
let cd = format_countdown(section.resets_at, strings, show_decimals);
if cd.is_empty() {
pct
} else {
@ -766,7 +766,7 @@ pub fn format_line(section: &UsageSection, strings: Strings) -> String {
}
}
fn format_countdown(resets_at: Option<SystemTime>, strings: Strings) -> String {
fn format_countdown(resets_at: Option<SystemTime>, strings: Strings, show_decimals: bool) -> String {
let reset = match resets_at {
Some(t) => t,
None => return String::new(),
@ -792,11 +792,21 @@ fn format_countdown_from_secs(total_secs: u64, strings: Strings) -> String {
let total_hours = total_secs / 3600;
let total_days = total_secs / 86400;
if total_days >= 1 {
let hours_fraction = total_mins / 60;
let days_fraction = total_hours / 24;
let minute_fraction = total_secs / 60;
if total_days > 0 && show_decimals && days_fraction > 0 {
format!("{total_days}.{days_fraction:01}{}", strings.day_suffix)
} else if total_days > 0 {
format!("{total_days}{}", strings.day_suffix)
} else if total_hours >= 1 {
} else if total_hours > 0 && show_decimals && hours_fraction > 0 {
format!("{total_hours}.{hours_fraction:01}{}", strings.hour_suffix)
} else if total_hours > 0 {
format!("{total_hours}{}", strings.hour_suffix)
} else if total_mins >= 1 {
} else if total_mins > 0 && show_decimals && minute_fraction > 0 {
format!("{total_mins}.{minute_fraction:01}{}", strings.minute_suffix)
} else if total_mins > 0 {
format!("{total_mins}{}", strings.minute_suffix)
} else {
format!("{total_secs}{}", strings.second_suffix)

View File

@ -76,6 +76,7 @@ struct AppState {
dragging: bool,
drag_start_mouse_x: i32,
drag_start_offset: i32,
show_decimals: bool,
widget_visible: bool,
}
@ -110,6 +111,7 @@ const IDM_LANG_SPANISH: u16 = 42;
const IDM_LANG_FRENCH: u16 = 43;
const IDM_LANG_GERMAN: u16 = 44;
const IDM_LANG_JAPANESE: u16 = 45;
const IDM_SHOW_DECIMALS: u16 = 50;
const IDM_LANG_KOREAN: u16 = 46;
const IDM_LANG_TRADITIONAL_CHINESE: u16 = 47;
@ -195,6 +197,8 @@ struct SettingsFile {
language: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
last_update_check_unix: Option<u64>,
#[serde(default)]
show_decimals: bool,
#[serde(default = "default_widget_visible")]
widget_visible: bool,
}
@ -206,6 +210,7 @@ impl Default for SettingsFile {
poll_interval_ms: default_poll_interval(),
language: None,
last_update_check_unix: None,
show_decimals: true,
widget_visible: true,
}
}
@ -247,6 +252,7 @@ fn save_state_settings() {
.language_override
.map(|language| language.code().to_string()),
last_update_check_unix: s.last_update_check_unix,
show_decimals: s.show_decimals,
widget_visible: s.widget_visible,
});
}
@ -336,8 +342,8 @@ fn refresh_usage_texts(state: &mut AppState) {
let strings = state.language.strings();
let Some((session_text, weekly_text)) = state.data.as_ref().map(|data| {
(
poller::format_line(&data.session, strings),
poller::format_line(&data.weekly, strings),
poller::format_line(&data.session, strings, state.show_decimals),
poller::format_line(&data.weekly, strings, state.show_decimals),
)
}) else {
return;
@ -728,7 +734,7 @@ const DIVIDER_RIGHT_MARGIN: i32 = 10;
const LABEL_WIDTH: i32 = 18;
const LABEL_RIGHT_MARGIN: i32 = 10;
const BAR_RIGHT_MARGIN: i32 = 4;
const TEXT_WIDTH: i32 = 62;
const TEXT_WIDTH: i32 = 80;
const RIGHT_MARGIN: i32 = 1;
const WIDGET_HEIGHT: i32 = 46;
@ -870,6 +876,7 @@ pub fn run() {
dragging: false,
drag_start_mouse_x: 0,
drag_start_offset: 0,
show_decimals: settings.show_decimals,
widget_visible: settings.widget_visible,
});
}
@ -1920,6 +1927,16 @@ unsafe extern "system" fn wnd_proc(
IDM_START_WITH_WINDOWS => {
set_startup_enabled(!is_startup_enabled());
}
IDM_SHOW_DECIMALS => {
{
let mut state = lock_state();
if let Some(s) = state.as_mut() {
s.show_decimals = !s.show_decimals;
}
}
save_state_settings();
render_layered();
}
IDM_FREQ_1MIN | IDM_FREQ_5MIN | IDM_FREQ_15MIN | IDM_FREQ_1HOUR => {
let new_interval = match id {
IDM_FREQ_1MIN => POLL_1_MIN,
@ -2100,6 +2117,23 @@ fn show_context_menu(hwnd: HWND) {
PCWSTR::from_raw(reset_pos_str.as_ptr()),
);
// Show Decimals toggle
let show_decimals_str = native_interop::wide_str(strings.show_decimals);
let show_checked_flags = if {
let state = lock_state();
state.as_ref().map(|s| s.show_decimals).unwrap_or(true)
} {
MF_CHECKED
} else {
MENU_ITEM_FLAGS(0)
};
let _ = AppendMenuW(
settings_menu,
show_checked_flags,
IDM_SHOW_DECIMALS as usize,
PCWSTR::from_raw(show_decimals_str.as_ptr()),
);
let language_menu = CreatePopupMenu().unwrap();
let system_label = native_interop::wide_str(strings.system_default);
let system_flags = if language_override.is_none() {