mirror of
https://gitlab.com/cleanflash/installer.git
synced 2026-08-13 02:41:38 +08:00
Implement HiDPI scaling
This commit is contained in:
@@ -5,6 +5,20 @@ pub mod widgets;
|
||||
pub use font::FontManager;
|
||||
pub use renderer::Renderer;
|
||||
|
||||
/// Query the system DPI scale factor (1.0 = 100%, 1.5 = 150%, 2.0 = 200%).
|
||||
/// The process must already be DPI-aware (declared in the manifest) for this
|
||||
/// to return the true hardware DPI rather than the virtualised 96.
|
||||
pub fn get_dpi_scale() -> f32 {
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe {
|
||||
use windows_sys::Win32::UI::HiDpi::GetDpiForSystem;
|
||||
let dpi = GetDpiForSystem();
|
||||
if dpi == 0 { 1.0 } else { dpi as f32 / 96.0 }
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{ 1.0 }
|
||||
}
|
||||
|
||||
/// Set the window icon from the icon resource already embedded in the binary
|
||||
/// by `winresource` (resource ID 1). No-op on non-Windows platforms.
|
||||
pub fn set_window_icon(window: &minifb::Window) {
|
||||
|
||||
@@ -109,6 +109,29 @@ impl Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw an RGBA image scaled to (w, h) at (x, y) using nearest-neighbor interpolation.
|
||||
pub fn draw_image_scaled(&mut self, x: i32, y: i32, w: i32, h: i32, img: &RgbaImage) {
|
||||
if w <= 0 || h <= 0 || img.width == 0 || img.height == 0 {
|
||||
return;
|
||||
}
|
||||
for dy in 0..h {
|
||||
for dx in 0..w {
|
||||
let src_x = (dx as f32 * img.width as f32 / w as f32) as usize;
|
||||
let src_y = (dy as f32 * img.height as f32 / h as f32) as usize;
|
||||
let idx = (src_y * img.width + src_x) * 4;
|
||||
let r = img.data[idx];
|
||||
let g = img.data[idx + 1];
|
||||
let b = img.data[idx + 2];
|
||||
let a = img.data[idx + 3];
|
||||
if a == 255 {
|
||||
self.set_pixel(x + dx, y + dy, Self::rgb(r, g, b));
|
||||
} else if a > 0 {
|
||||
self.blend_pixel(x + dx, y + dy, Self::rgb(r, g, b), a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw an RGBA image onto the framebuffer at (x, y).
|
||||
pub fn draw_image(&mut self, x: i32, y: i32, img: &RgbaImage) {
|
||||
for iy in 0..img.height as i32 {
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::renderer::Renderer;
|
||||
pub struct GradientButton {
|
||||
pub rect: Rect,
|
||||
pub text: String,
|
||||
pub font_size: f32,
|
||||
pub color1: u32,
|
||||
pub color2: u32,
|
||||
pub back_color: u32,
|
||||
@@ -23,6 +24,7 @@ impl GradientButton {
|
||||
Self {
|
||||
rect: Rect::new(x, y, w, h),
|
||||
text: text.to_string(),
|
||||
font_size: 13.0,
|
||||
color1: Renderer::rgb(118, 118, 118),
|
||||
color2: Renderer::rgb(81, 81, 81),
|
||||
back_color: Renderer::rgb(0, 0, 0),
|
||||
@@ -77,7 +79,7 @@ impl GradientButton {
|
||||
renderer.draw_rect(r.x, r.y, r.w, r.h, bg);
|
||||
|
||||
// Measure text to centre it.
|
||||
let font_size = 13.0;
|
||||
let font_size = self.font_size;
|
||||
let (tw, th) = fonts.measure_text(&self.text, font_size);
|
||||
let tx = r.x + ((r.w as f32 - tw) / 2.0) as i32;
|
||||
let ty = r.y + ((r.h as f32 - th) / 2.0) as i32;
|
||||
|
||||
@@ -11,8 +11,12 @@ pub struct ImageCheckBox {
|
||||
|
||||
impl ImageCheckBox {
|
||||
pub fn new(x: i32, y: i32) -> Self {
|
||||
Self::with_size(x, y, 21)
|
||||
}
|
||||
|
||||
pub fn with_size(x: i32, y: i32, size: i32) -> Self {
|
||||
Self {
|
||||
rect: Rect::new(x, y, 21, 21),
|
||||
rect: Rect::new(x, y, size, size),
|
||||
checked: true,
|
||||
enabled: true,
|
||||
visible: true,
|
||||
@@ -43,7 +47,7 @@ impl ImageCheckBox {
|
||||
unchecked_img
|
||||
};
|
||||
if img.width > 0 && img.height > 0 {
|
||||
renderer.draw_image(self.rect.x, self.rect.y, img);
|
||||
renderer.draw_image_scaled(self.rect.x, self.rect.y, self.rect.w, self.rect.h, img);
|
||||
} else {
|
||||
// Fallback: draw a simple square.
|
||||
let bg = if self.checked {
|
||||
|
||||
@@ -8,6 +8,7 @@ pub struct Label {
|
||||
pub text: String,
|
||||
pub color: u32,
|
||||
pub font_size: f32,
|
||||
pub line_spacing: f32,
|
||||
pub visible: bool,
|
||||
}
|
||||
|
||||
@@ -18,6 +19,7 @@ impl Label {
|
||||
text: text.to_string(),
|
||||
color: Renderer::rgb(245, 245, 245),
|
||||
font_size,
|
||||
line_spacing: 2.0,
|
||||
visible: true,
|
||||
}
|
||||
}
|
||||
@@ -33,7 +35,7 @@ impl Label {
|
||||
&self.text,
|
||||
self.font_size,
|
||||
self.color,
|
||||
2.0,
|
||||
self.line_spacing,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user