zsui 0.3.0-alpha.2

Rust-first feature-gated native UI framework for Win32, AppKit, and Linux.
Documentation
fn windows_palette_for_draw_plan(draw_plan: Option<&NativeDrawPlan>) -> WindowsGdiPalette {
    match resolved_windows_theme_mode(
        draw_plan
            .map(|plan| plan.theme_mode)
            .unwrap_or(crate::ZsuiThemeMode::System),
    ) {
        crate::ZsuiThemeMode::HighContrast => windows_high_contrast_palette(),
        crate::ZsuiThemeMode::Dark => WindowsGdiPalette::from_theme(&crate::ZsuiTheme::dark()),
        _ => WindowsGdiPalette::default(),
    }
}

fn resolved_windows_theme_mode(theme_mode: crate::ZsuiThemeMode) -> crate::ZsuiThemeMode {
    resolved_windows_theme_mode_for_system(theme_mode, windows_system_theme_mode())
}

fn resolved_windows_theme_mode_for_system(
    theme_mode: crate::ZsuiThemeMode,
    system_mode: crate::ZsuiThemeMode,
) -> crate::ZsuiThemeMode {
    if system_mode == crate::ZsuiThemeMode::HighContrast {
        crate::ZsuiThemeMode::HighContrast
    } else if theme_mode == crate::ZsuiThemeMode::System {
        system_mode
    } else {
        theme_mode
    }
}

pub fn windows_system_theme_mode() -> crate::ZsuiThemeMode {
    if windows_system_high_contrast() {
        return crate::ZsuiThemeMode::HighContrast;
    }
    let subkey = wide_null("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
    let value_name = wide_null("AppsUseLightTheme");
    let mut value = 1u32;
    let mut value_size = size_of::<u32>() as u32;
    let status = unsafe {
        RegGetValueW(
            HKEY_CURRENT_USER,
            subkey.as_ptr(),
            value_name.as_ptr(),
            RRF_RT_REG_DWORD,
            null_mut(),
            &mut value as *mut u32 as _,
            &mut value_size,
        )
    };
    if status == 0 && value == 0 {
        crate::ZsuiThemeMode::Dark
    } else {
        crate::ZsuiThemeMode::Light
    }
}

pub fn windows_system_high_contrast() -> bool {
    let mut high_contrast = HIGHCONTRASTW {
        cbSize: size_of::<HIGHCONTRASTW>() as u32,
        dwFlags: 0,
        lpszDefaultScheme: null_mut(),
    };
    unsafe {
        SystemParametersInfoW(
            SPI_GETHIGHCONTRAST,
            high_contrast.cbSize,
            &mut high_contrast as *mut HIGHCONTRASTW as _,
            0,
        ) != 0
            && high_contrast.dwFlags & HCF_HIGHCONTRASTON != 0
    }
}

fn windows_high_contrast_palette() -> WindowsGdiPalette {
    let surface = windows_system_color(COLOR_WINDOW);
    let primary_text = windows_system_color(COLOR_WINDOWTEXT);
    WindowsGdiPalette {
        primary_text,
        secondary_text: primary_text,
        disabled_text: primary_text,
        accent: windows_system_color(COLOR_HIGHLIGHT),
        accent_text: windows_system_color(COLOR_HIGHLIGHTTEXT),
        surface,
        surface_raised: surface,
        control: surface,
        border: primary_text,
        strong_stroke: primary_text,
        success: primary_text,
        warning: primary_text,
        danger: primary_text,
    }
}

fn windows_system_color(index: i32) -> Color {
    let color = unsafe { GetSysColor(index) };
    Color::rgb(
        (color & 0xff) as u8,
        ((color >> 8) & 0xff) as u8,
        ((color >> 16) & 0xff) as u8,
    )
}

fn apply_windows_win32_window_theme(hwnd: HWND, theme_mode: crate::ZsuiThemeMode) {
    if hwnd.is_null() {
        return;
    }
    let dark = i32::from(matches!(
        resolved_windows_theme_mode(theme_mode),
        crate::ZsuiThemeMode::Dark
    ));
    unsafe {
        DwmSetWindowAttribute(
            hwnd,
            DWMWA_USE_IMMERSIVE_DARK_MODE as u32,
            &dark as *const i32 as _,
            size_of::<i32>() as u32,
        );
    }
}