mirror of
https://gitlab.com/erkanisik/yali-rs.git
synced 2026-07-31 03:09:00 +00:00
feat: form input styling, root password toggle, partition UI fixes
- form_input_text: Frame wrapper with stroke/fill/rounding, .frame(false) - form_input_password: SVG eye icons instead of emoji, Frame wrapper - Partition disk grid: hardcoded colors, left-aligned headers - Users: root password show/hide toggle, colored form frames - Add c_root_bg() theme function
This commit is contained in:
@@ -43,6 +43,27 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [4.0.1] — 2026-06-19
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `c_root_bg()` tema fonksiyonu
|
||||||
|
- `show_root_password`, `show_root_password_confirm` alanları (`UsersStep`)
|
||||||
|
- `form_input_text` / `form_input_password`'a `Frame` sarmalı ve `.frame(false)`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- `form_input_text`: Frame içine alındı, stroke/fill/rounding eklendi, yükseklik 32→10
|
||||||
|
- `form_input_password`: SVG göz ikonları (emoji yerine), Frame sarmalı, `override_text_color`
|
||||||
|
- Disk grid seçim renkleri `theme::c_*()` → sabit `(237,237,224,1)`
|
||||||
|
- Disk listesi header ve sütun başlıkları: `Align::Center` → `Align::LEFT`, `vertical_centered` kaldırıldı
|
||||||
|
- Root şifre alanları raw `TextEdit` → `form_input_password` (göz ikonu + frame ile)
|
||||||
|
- Kullanıcı formu Frame rengi `theme::c_bg_widget()` → `(240,243,198)`
|
||||||
|
- Manuel disk listesinde marka/model etiketi sıralaması değiştirildi
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `users.rs:154` — `Color32` import hatası (missing `egui::` prefix)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [4.0.0] — 2026-06-06
|
## [4.0.0] — 2026-06-06
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
+61
-21
@@ -18,18 +18,27 @@ pub fn form_input_text(
|
|||||||
)-> eframe::egui::Response {
|
)-> eframe::egui::Response {
|
||||||
|
|
||||||
let width_percent = 0.90; // Mevcut genişliğin %90'ı
|
let width_percent = 0.90; // Mevcut genişliğin %90'ı
|
||||||
let height = 32.0; // Standart yükseklik
|
let height = 10.0; // Standart yükseklik
|
||||||
let hesaplanan_genislik = ui.available_width() * width_percent;
|
let hesaplanan_genislik = ui.available_width() * width_percent;
|
||||||
let boyut = eframe::egui::vec2(hesaplanan_genislik, height);
|
let boyut = eframe::egui::vec2(hesaplanan_genislik, height);
|
||||||
|
|
||||||
ui.spacing_mut().button_padding = eframe::egui::vec2(10.0, 10.0);
|
ui.spacing_mut().button_padding = eframe::egui::vec2(10.0, 10.0);
|
||||||
|
egui::Frame::none()
|
||||||
|
.fill(egui::Color32::from_rgb(255, 255, 255))
|
||||||
|
.stroke(egui::Stroke::new(1.0, egui::Color32::from_gray(200)))
|
||||||
|
.rounding(4.0)
|
||||||
|
.inner_margin(eframe::egui::Margin::symmetric(2.0, 2.0))
|
||||||
|
.show(ui, |ui| {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
boyut,
|
boyut,
|
||||||
eframe::egui::TextEdit::singleline(text)
|
eframe::egui::TextEdit::singleline(text)
|
||||||
.vertical_align(eframe::egui::Align::Center)
|
.vertical_align(eframe::egui::Align::Center)
|
||||||
|
.frame(false),
|
||||||
)
|
)
|
||||||
|
}).inner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn form_input_password(
|
pub fn form_input_password(
|
||||||
ui: &mut eframe::egui::Ui,
|
ui: &mut eframe::egui::Ui,
|
||||||
text: &mut String,
|
text: &mut String,
|
||||||
@@ -38,28 +47,59 @@ pub fn form_input_password(
|
|||||||
let width_percent = 0.90;
|
let width_percent = 0.90;
|
||||||
let height = 32.0;
|
let height = 32.0;
|
||||||
let toplam_genislik = ui.available_width() * width_percent;
|
let toplam_genislik = ui.available_width() * width_percent;
|
||||||
let dugme_genislik = 40.0;
|
|
||||||
let alan_genislik = toplam_genislik - dugme_genislik - 4.0;
|
let buton_genislik = 32.0;
|
||||||
let boyut = eframe::egui::vec2(alan_genislik, height);
|
let alan_genislik = toplam_genislik - buton_genislik - 4.0;
|
||||||
|
|
||||||
ui.spacing_mut().button_padding = eframe::egui::vec2(10.0, 10.0);
|
let mut response: Option<eframe::egui::Response> = None;
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.visuals_mut().override_text_color = Some(eframe::egui::Color32::from_rgb(30, 30, 30));
|
||||||
let r = ui.add_sized(
|
|
||||||
boyut,
|
// SVG içeriklerini string olarak tanımlıyoruz
|
||||||
eframe::egui::TextEdit::singleline(text)
|
let goz_acik_svg = r#"<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" /><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /></svg>"#;
|
||||||
.password(!*show_password)
|
let goz_kapali_svg = r#"<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88" /></svg>"#;
|
||||||
.vertical_align(eframe::egui::Align::Center),
|
|
||||||
);
|
eframe::egui::Frame::none()
|
||||||
let göz = if *show_password { "🙈" } else { "👁" };
|
.fill(eframe::egui::Color32::WHITE)
|
||||||
if ui.add(
|
.stroke(eframe::egui::Stroke::new(1.0, eframe::egui::Color32::from_rgb(200, 200, 200)))
|
||||||
eframe::egui::Button::new(göz)
|
.rounding(6.0)
|
||||||
.min_size(eframe::egui::vec2(dugme_genislik, height))
|
.inner_margin(eframe::egui::Margin::symmetric(2.0, 2.0))
|
||||||
).clicked() {
|
.show(ui, |ui| {
|
||||||
*show_password = !*show_password;
|
ui.horizontal(|ui| {
|
||||||
}
|
// 1. Şifre Metin Alanı
|
||||||
r
|
let r = ui.add_sized(
|
||||||
}).inner
|
eframe::egui::vec2(alan_genislik, height),
|
||||||
|
eframe::egui::TextEdit::singleline(text)
|
||||||
|
.password(!*show_password)
|
||||||
|
.frame(false)
|
||||||
|
);
|
||||||
|
response = Some(r);
|
||||||
|
|
||||||
|
// Duruma göre ilgili SVG string'ini seçip byte dizisine (&[u8]) çeviriyoruz
|
||||||
|
let (uri, svg_bytes) = if *show_password {
|
||||||
|
("bytes://goz_acik.svg", goz_acik_svg.as_bytes())
|
||||||
|
} else {
|
||||||
|
("bytes://goz_kapali.svg", goz_kapali_svg.as_bytes())
|
||||||
|
};
|
||||||
|
|
||||||
|
// Image::from_bytes kullanarak imajı güvenli bir şekilde yüklüyoruz
|
||||||
|
let svg_gosterici = eframe::egui::Image::from_bytes(uri, svg_bytes)
|
||||||
|
.tint(eframe::egui::Color32::from_rgb(120, 120, 120))
|
||||||
|
.max_width(18.0)
|
||||||
|
.max_height(18.0);
|
||||||
|
|
||||||
|
// 2. SVG İkonlu Buton
|
||||||
|
let btn = eframe::egui::Button::image(svg_gosterici)
|
||||||
|
.frame(false)
|
||||||
|
.min_size(eframe::egui::vec2(buton_genislik, height));
|
||||||
|
|
||||||
|
if ui.add(btn).on_hover_cursor(eframe::egui::CursorIcon::PointingHand).clicked() {
|
||||||
|
*show_password = !*show_password;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
response.expect("Metin alanı yüklenemedi")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn form_label(ui: &mut eframe::egui::Ui, text: &str) {
|
pub fn form_label(ui: &mut eframe::egui::Ui, text: &str) {
|
||||||
|
|||||||
+22
-18
@@ -415,13 +415,13 @@ impl PartitionStep {
|
|||||||
// arka plan
|
// arka plan
|
||||||
egui::Frame::none()
|
egui::Frame::none()
|
||||||
.fill(if selected {
|
.fill(if selected {
|
||||||
crate::ui::theme::c_accent_dim()
|
//crate::ui::theme::c_accent_dim()
|
||||||
|
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||||
} else if response.hovered() {
|
} else if response.hovered() {
|
||||||
egui::Color32::from_rgba_unmultiplied(60, 60, 80, 180)
|
egui::Color32::from_rgba_unmultiplied(60, 60, 80, 180)
|
||||||
} else if too_small {
|
|
||||||
egui::Color32::from_rgba_unmultiplied(60, 30, 30, 180)
|
|
||||||
} else {
|
} else {
|
||||||
crate::ui::theme::c_bg_widget()
|
//crate::ui::theme::c_bg_widget()
|
||||||
|
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||||
})
|
})
|
||||||
.stroke(egui::Stroke::new(
|
.stroke(egui::Stroke::new(
|
||||||
if selected { 2.0 } else { 1.0 },
|
if selected { 2.0 } else { 1.0 },
|
||||||
@@ -509,15 +509,16 @@ impl PartitionStep {
|
|||||||
egui::vec2(tam_genislik * col_widths[j], 30.0),
|
egui::vec2(tam_genislik * col_widths[j], 30.0),
|
||||||
egui::Sense::hover(),
|
egui::Sense::hover(),
|
||||||
);
|
);
|
||||||
let child_ui = &mut ui.child_ui(rect, egui::Layout::top_down(egui::Align::Center));
|
let child_ui = &mut ui.child_ui(rect, egui::Layout::top_down(egui::Align::LEFT));
|
||||||
egui::Frame::none()
|
egui::Frame::none()
|
||||||
.fill(header_color)
|
.fill(header_color)
|
||||||
.stroke(egui::Stroke::new(1.0, header_color))
|
.stroke(egui::Stroke::new(1.0, header_color))
|
||||||
.inner_margin(egui::Margin::symmetric(8.0, 4.0))
|
.inner_margin(egui::Margin::symmetric(8.0, 4.0))
|
||||||
.show(child_ui, |ui| {
|
.show(child_ui, |ui| {
|
||||||
ui.vertical_centered(|ui| {
|
ui.label(egui::RichText::new(h)
|
||||||
ui.label(egui::RichText::new(h).strong().color(header_text).size(13.0));
|
.strong()
|
||||||
});
|
.color(header_text)
|
||||||
|
.size(13.0));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
@@ -653,11 +654,13 @@ impl PartitionStep {
|
|||||||
|
|
||||||
egui::Frame::none()
|
egui::Frame::none()
|
||||||
.fill(if selected {
|
.fill(if selected {
|
||||||
crate::ui::theme::c_accent_dim()
|
//crate::ui::theme::c_accent_dim()
|
||||||
|
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||||
} else if response.hovered() {
|
} else if response.hovered() {
|
||||||
egui::Color32::from_rgba_unmultiplied(60, 60, 80, 180)
|
egui::Color32::from_rgba_unmultiplied(60, 60, 80, 180)
|
||||||
} else {
|
} else {
|
||||||
crate::ui::theme::c_bg_widget()
|
//crate::ui::theme::c_bg_widget()
|
||||||
|
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||||
})
|
})
|
||||||
.stroke(egui::Stroke::new(
|
.stroke(egui::Stroke::new(
|
||||||
if selected { 2.0 } else { 1.0 },
|
if selected { 2.0 } else { 1.0 },
|
||||||
@@ -680,17 +683,20 @@ impl PartitionStep {
|
|||||||
} else {
|
} else {
|
||||||
&disk.vendor
|
&disk.vendor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ui.label(
|
||||||
|
egui::RichText::new(marka)
|
||||||
|
.size(11.0)
|
||||||
|
.color(crate::ui::theme::c_text_dim()),
|
||||||
|
);
|
||||||
|
|
||||||
ui.label(
|
ui.label(
|
||||||
egui::RichText::new(format!("{} GB", disk.size_gb))
|
egui::RichText::new(format!("{} GB", disk.size_gb))
|
||||||
.size(14.0)
|
.size(14.0)
|
||||||
.strong()
|
.strong()
|
||||||
.color(crate::ui::theme::c_text()),
|
.color(crate::ui::theme::c_text()),
|
||||||
);
|
);
|
||||||
ui.label(
|
|
||||||
egui::RichText::new(marka)
|
|
||||||
.size(11.0)
|
|
||||||
.color(crate::ui::theme::c_text_dim()),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if response.clicked() {
|
if response.clicked() {
|
||||||
@@ -753,9 +759,7 @@ impl PartitionStep {
|
|||||||
.stroke(egui::Stroke::new(1.0, header_color))
|
.stroke(egui::Stroke::new(1.0, header_color))
|
||||||
.inner_margin(egui::Margin::symmetric(8.0, 4.0))
|
.inner_margin(egui::Margin::symmetric(8.0, 4.0))
|
||||||
.show(child_ui, |ui| {
|
.show(child_ui, |ui| {
|
||||||
ui.vertical_centered(|ui| {
|
ui.label(egui::RichText::new(h).strong().color(header_text).size(13.0));
|
||||||
ui.label(egui::RichText::new(h).strong().color(header_text).size(13.0));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|||||||
+16
-23
@@ -8,6 +8,8 @@ pub struct UsersStep {
|
|||||||
use_same_for_admin: bool,
|
use_same_for_admin: bool,
|
||||||
show_password: bool,
|
show_password: bool,
|
||||||
show_password_confirm: bool,
|
show_password_confirm: bool,
|
||||||
|
show_root_password: bool, // <-- Eklendi
|
||||||
|
show_root_password_confirm: bool, // <-- Eklendi
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for UsersStep {
|
impl Default for UsersStep {
|
||||||
@@ -16,6 +18,8 @@ impl Default for UsersStep {
|
|||||||
use_same_for_admin: true,
|
use_same_for_admin: true,
|
||||||
show_password: false,
|
show_password: false,
|
||||||
show_password_confirm: false,
|
show_password_confirm: false,
|
||||||
|
show_root_password: false,
|
||||||
|
show_root_password_confirm: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,7 +155,7 @@ impl InstallerStep for UsersStep {
|
|||||||
|
|
||||||
// ─── Kullanıcı Bilgileri Formu ──────────────────────────────────
|
// ─── Kullanıcı Bilgileri Formu ──────────────────────────────────
|
||||||
egui::Frame::group(ui.style())
|
egui::Frame::group(ui.style())
|
||||||
.fill(theme::c_bg_widget())
|
.fill(egui::Color32::from_rgb(240, 243, 198))
|
||||||
.rounding(6.0)
|
.rounding(6.0)
|
||||||
.inner_margin(egui::Margin::symmetric(10.0, 10.0))
|
.inner_margin(egui::Margin::symmetric(10.0, 10.0))
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
@@ -200,6 +204,7 @@ impl InstallerStep for UsersStep {
|
|||||||
{
|
{
|
||||||
let show_pwd = &mut self.show_password;
|
let show_pwd = &mut self.show_password;
|
||||||
let before = state.password.clone();
|
let before = state.password.clone();
|
||||||
|
|
||||||
form_input_password(ui, &mut state.password, show_pwd);
|
form_input_password(ui, &mut state.password, show_pwd);
|
||||||
// Kullanıcı şifreyi değiştirdiyse OEM bayrağını kaldır
|
// Kullanıcı şifreyi değiştirdiyse OEM bayrağını kaldır
|
||||||
if state.oem_mode && state.password != before {
|
if state.oem_mode && state.password != before {
|
||||||
@@ -254,7 +259,7 @@ impl InstallerStep for UsersStep {
|
|||||||
} else {
|
} else {
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
egui::Frame::group(ui.style())
|
egui::Frame::group(ui.style())
|
||||||
.fill(theme::c_bg_widget())
|
.fill(theme::c_root_bg())
|
||||||
.rounding(6.0)
|
.rounding(6.0)
|
||||||
.inner_margin(egui::Margin::same(12.0))
|
.inner_margin(egui::Margin::same(12.0))
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
@@ -263,33 +268,21 @@ impl InstallerStep for UsersStep {
|
|||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
// Root şifresi
|
// Root şifresi
|
||||||
|
|
||||||
ui.label(egui::RichText::new(t!("admin_password_label")).strong().color(theme::c_text()));
|
ui.label(egui::RichText::new(t!("admin_password_label")).strong().color(theme::c_text()));
|
||||||
ui.horizontal(|ui| {
|
|
||||||
ui.add(
|
// DÜZELTME: 3. parametre olarak show_root_password eklendi
|
||||||
eframe::egui::TextEdit::singleline(&mut state.root_password)
|
let show_root_pwd = &mut self.show_root_password;
|
||||||
.password(true)
|
form_input_password(ui, &mut state.root_password, show_root_pwd);
|
||||||
.desired_width(f32::INFINITY)
|
|
||||||
.min_size(eframe::egui::vec2(0.0, 32.0))
|
|
||||||
);
|
|
||||||
|
|
||||||
if !state.root_password.is_empty() && state.root_password.len() < 8 {
|
|
||||||
ui.colored_label(theme::c_error(), t!("admin_password_short"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
// Şifre doğrulama
|
// Şifre doğrulama
|
||||||
ui.label(egui::RichText::new(t!("admin_password_confirm_label")).strong().color(theme::c_text()));
|
ui.label(egui::RichText::new(t!("admin_password_confirm_label")).strong().color(theme::c_text()));
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
// DÜZELTME: 3. parametre olarak show_root_password_confirm eklendi
|
||||||
ui.add(
|
let show_root_pwd_conf = &mut self.show_root_password_confirm;
|
||||||
eframe::egui::TextEdit::singleline(&mut state.root_password_confirm)
|
form_input_password(ui, &mut state.root_password_confirm, show_root_pwd_conf);
|
||||||
.password(true)
|
|
||||||
.desired_width(f32::INFINITY)
|
|
||||||
.min_size(eframe::egui::vec2(0.0, 32.0))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
if state.root_password == state.root_password_confirm {
|
if state.root_password == state.root_password_confirm {
|
||||||
ui.colored_label(theme::c_success(), "✅");
|
ui.colored_label(theme::c_success(), "✅");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ pub fn c_error() -> Color32 { color_from_hex(ERROR.load(Ordering::Relaxed))
|
|||||||
pub fn c_sidebar() -> Color32 { color_from_hex(SIDEBAR.load(Ordering::Relaxed)) }
|
pub fn c_sidebar() -> Color32 { color_from_hex(SIDEBAR.load(Ordering::Relaxed)) }
|
||||||
pub fn c_sidebar_text() -> Color32 { color_from_hex(SIDEBAR_TEXT.load(Ordering::Relaxed)) }
|
pub fn c_sidebar_text() -> Color32 { color_from_hex(SIDEBAR_TEXT.load(Ordering::Relaxed)) }
|
||||||
pub fn c_footer_bg() -> Color32 { color_from_hex(0xf7f7f7) }
|
pub fn c_footer_bg() -> Color32 { color_from_hex(0xf7f7f7) }
|
||||||
|
pub fn c_root_bg() -> Color32 { color_from_hex(0xf7f7f7) }
|
||||||
|
|
||||||
pub fn set_theme_mode(is_dark: bool) {
|
pub fn set_theme_mode(is_dark: bool) {
|
||||||
if is_dark {
|
if is_dark {
|
||||||
|
|||||||
Reference in New Issue
Block a user