forked from pisilinux-rs/yali-rs
update
This commit is contained in:
+140
-59
@@ -3,9 +3,10 @@ mod steps;
|
||||
mod jobs;
|
||||
mod ui;
|
||||
mod autoinstall;
|
||||
mod branding;
|
||||
|
||||
use installer::{GlobalState, InstallerStep, WelcomeStep, LocationStep};
|
||||
use steps::{KeyboardStep, UsersStep, SummaryStep, ExecutionStep, FinishStep, PartitionStep};
|
||||
use steps::{KeyboardStep, UsersStep, SummaryStep, ExecutionStep, FinishStep, PartitionStep, BootloaderStep, LicenseStep, NetworkStep, DisplayManagerStep};
|
||||
use eframe::egui;
|
||||
use rust_i18n::t;
|
||||
|
||||
@@ -32,14 +33,14 @@ fn main() -> eframe::Result<()> {
|
||||
fn run_gui(demo_mode: bool) -> eframe::Result<()> {
|
||||
let options = eframe::NativeOptions {
|
||||
viewport: egui::ViewportBuilder::default()
|
||||
.with_inner_size([1100.0, 760.0])
|
||||
.with_min_inner_size([900.0, 650.0])
|
||||
.with_title(t!("installer").to_string()),
|
||||
.with_inner_size([1200.0, 900.0])
|
||||
.with_min_inner_size([1080.0, 720.0])
|
||||
.with_title(t!("installer")),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
eframe::run_native(
|
||||
&t!("installer").to_string(),
|
||||
t!("installer").as_ref(),
|
||||
options,
|
||||
Box::new(move |cc| {
|
||||
// Görsel yükleyicileri etkinleştir (PNG desteği)
|
||||
@@ -88,17 +89,19 @@ fn run_auto_install(path: &str, demo_mode: bool) -> eframe::Result<()> {
|
||||
}
|
||||
|
||||
if !autoinstall::checker::all_passed(&checks) {
|
||||
eprintln!("{}: {}", t!("error"), "Critical check error. Installation stopped.");
|
||||
eprintln!("{}: Critical check error. Installation stopped.", t!("error"));
|
||||
std::process::exit(2);
|
||||
}
|
||||
|
||||
// State'i hazırla
|
||||
let mut state = GlobalState::default();
|
||||
state.demo_mode = demo_mode;
|
||||
let mut state = GlobalState {
|
||||
demo_mode,
|
||||
..Default::default()
|
||||
};
|
||||
apply_to_state(&af, &mut state);
|
||||
|
||||
if state.partition_plan.is_none() {
|
||||
eprintln!("{}: {}", t!("error"), format!("{}: {}", t!("partition_plan_could_not_be_created"), af.install.disk));
|
||||
eprintln!("{}: {}: {}", t!("error"), t!("partition_plan_could_not_be_created"), af.install.disk);
|
||||
std::process::exit(3);
|
||||
}
|
||||
|
||||
@@ -122,13 +125,9 @@ fn run_auto_install(path: &str, demo_mode: bool) -> eframe::Result<()> {
|
||||
use jobs::{InstallMessage, UiSender};
|
||||
|
||||
// CLI modunda egui Context yok; basit bir mpsc kanal kullanıyoruz.
|
||||
// UiSender'a dummy bir context gerekeceğinden terminal çıktısı için
|
||||
// doğrudan kanalı dinliyoruz.
|
||||
let (tx, rx) = mpsc::channel::<InstallMessage>();
|
||||
|
||||
// Arka plan iş parçacığı — gerçek job kuyruğunu çalıştırır.
|
||||
// egui::Context::default() CLI modunda request_repaint()'i no-op yapar;
|
||||
// mesajlar mpsc kanalı üzerinden terminale aktarılır.
|
||||
let cli_ctx = eframe::egui::Context::default();
|
||||
let ui_sender = UiSender::new(tx, cli_ctx);
|
||||
|
||||
@@ -147,16 +146,33 @@ fn run_auto_install(path: &str, demo_mode: bool) -> eframe::Result<()> {
|
||||
let rt = tokio::runtime::Runtime::new().expect("tokio runtime");
|
||||
let mut queue = jobs::build_full_job_queue(
|
||||
plan_c,
|
||||
&mount_c,
|
||||
&source_c,
|
||||
&locale_c,
|
||||
&timezone_c,
|
||||
&username_c,
|
||||
&password_c,
|
||||
&hostname_c,
|
||||
&kb_layout_c,
|
||||
&kb_variant_c,
|
||||
demo_mode,
|
||||
jobs::JobQueueConfig {
|
||||
mount: mount_c,
|
||||
source: source_c,
|
||||
locale: locale_c,
|
||||
timezone: timezone_c,
|
||||
username: username_c,
|
||||
password: password_c,
|
||||
hostname: hostname_c,
|
||||
kb_layout: kb_layout_c,
|
||||
kb_variant: kb_variant_c,
|
||||
demo_mode,
|
||||
boot_device: String::new(),
|
||||
bootloader_timeout: 5,
|
||||
bootloader_password: String::new(),
|
||||
kernel_options: String::new(),
|
||||
use_ntp: true,
|
||||
root_password: String::new(),
|
||||
display_manager: "sddm".to_string(),
|
||||
autologin: true,
|
||||
desktop_environment: "plasma".to_string(),
|
||||
selected_package_groups: Vec::new(),
|
||||
manual_year: 2026,
|
||||
manual_month: 5,
|
||||
manual_day: 26,
|
||||
manual_hour: 12,
|
||||
manual_minute: 0,
|
||||
},
|
||||
);
|
||||
rt.block_on(queue.run_all(ui_sender));
|
||||
});
|
||||
@@ -182,32 +198,69 @@ fn run_auto_install(path: &str, demo_mode: bool) -> eframe::Result<()> {
|
||||
}
|
||||
});
|
||||
|
||||
// eframe::Result döndürmek için Ok
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct YaliApp {
|
||||
state: GlobalState,
|
||||
steps: Vec<Box<dyn InstallerStep>>,
|
||||
last_step: usize,
|
||||
state: GlobalState,
|
||||
steps: Vec<Box<dyn InstallerStep>>,
|
||||
rescue_step: Option<Box<dyn InstallerStep>>,
|
||||
last_step: usize,
|
||||
branding: branding::BrandingConfig,
|
||||
loaded_language: String,
|
||||
}
|
||||
|
||||
impl Default for YaliApp {
|
||||
fn default() -> Self {
|
||||
let default_lang = "tr".to_string();
|
||||
let branding = branding::BrandingConfig::load_for_lang(&default_lang);
|
||||
let mut app = Self {
|
||||
state: GlobalState::default(),
|
||||
steps: vec![
|
||||
Box::new(WelcomeStep::default()),
|
||||
Box::new(LocationStep::default()),
|
||||
Box::new(LicenseStep),
|
||||
Box::new(KeyboardStep::default()),
|
||||
Box::new(NetworkStep::default()),
|
||||
Box::new(PartitionStep::default()),
|
||||
Box::new(UsersStep::default()),
|
||||
Box::new(BootloaderStep::default()),
|
||||
Box::new(DisplayManagerStep::default()),
|
||||
Box::new(SummaryStep),
|
||||
Box::new(ExecutionStep::default()),
|
||||
Box::new(FinishStep),
|
||||
],
|
||||
rescue_step: Some(Box::new(steps::RescueStep::default())),
|
||||
last_step: usize::MAX,
|
||||
branding: branding.clone(),
|
||||
loaded_language: String::new(),
|
||||
};
|
||||
|
||||
// OEM modu: varsayılan değerleri ata ve step engelleme
|
||||
if branding.oem.enabled {
|
||||
app.state.oem_mode = true;
|
||||
if !branding.oem.default_username.is_empty() {
|
||||
app.state.username = branding.oem.default_username.clone();
|
||||
app.state.hostname = branding.oem.default_hostname.clone();
|
||||
}
|
||||
if !branding.oem.default_password.is_empty() {
|
||||
app.state.password = branding.oem.default_password.clone();
|
||||
app.state.password_confirm = branding.oem.default_password.clone();
|
||||
}
|
||||
// OEM ön tanımlı disk planı varsa?
|
||||
}
|
||||
|
||||
// Branding görsel verilerini GlobalState'e enjekte et
|
||||
app.state.branding_yali_dark = branding.yali_logo_uri();
|
||||
app.state.branding_yali_light = branding.yali_logo_uri();
|
||||
app.state.branding_pisi_dark = branding.pisi_logo_dark_uri();
|
||||
app.state.branding_pisi_light = branding.pisi_logo_light_uri();
|
||||
app.state.branding_icons = branding.slides.icons
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), branding::path_to_file_uri(v)))
|
||||
.collect();
|
||||
app.state.branding_slides = branding.slides.items.clone();
|
||||
|
||||
app.steps[0].on_enter(&mut app.state);
|
||||
app.last_step = 0;
|
||||
app
|
||||
@@ -218,6 +271,45 @@ impl eframe::App for YaliApp {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
rust_i18n::set_locale(&self.state.language);
|
||||
|
||||
// Dil değişimi kontrolü -> branding dosyasını dinamik olarak yeniden yükle
|
||||
if self.loaded_language != self.state.language {
|
||||
self.loaded_language = self.state.language.clone();
|
||||
let branding = branding::BrandingConfig::load_for_lang(&self.loaded_language);
|
||||
self.branding = branding.clone();
|
||||
self.state.branding_yali_dark = branding.yali_logo_uri();
|
||||
self.state.branding_yali_light = branding.yali_logo_uri();
|
||||
self.state.branding_pisi_dark = branding.pisi_logo_dark_uri();
|
||||
self.state.branding_pisi_light = branding.pisi_logo_light_uri();
|
||||
self.state.branding_icons = branding.slides.icons
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), branding::path_to_file_uri(v)))
|
||||
.collect();
|
||||
self.state.branding_slides = branding.slides.items.clone();
|
||||
|
||||
// Pencere başlığını dinamik olarak güncelle
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Title(self.branding.general.title.clone()));
|
||||
}
|
||||
|
||||
// Rescue modu: tam ekran, sidebar yok, navigasyon yok
|
||||
if self.state.rescue_mode {
|
||||
if let Some(rescue) = &mut self.rescue_step {
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame::none()
|
||||
.fill(ui::theme::c_bg_dark())
|
||||
.inner_margin(egui::Margin::same(20.0)))
|
||||
.show(ctx, |ui| {
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
rescue.show(ui, &mut self.state);
|
||||
});
|
||||
ui.add_space(12.0);
|
||||
if ui.button(t!("rescue_return")).clicked() {
|
||||
self.state.rescue_mode = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let cur = self.state.current_step;
|
||||
let n_steps = self.steps.len();
|
||||
let is_exec = cur == n_steps - 2;
|
||||
@@ -238,31 +330,31 @@ impl eframe::App for YaliApp {
|
||||
.show(ctx, |ui| {
|
||||
ui.add_space(20.0);
|
||||
|
||||
// PisiLinux logo
|
||||
// Dağıtım logosu — branding.toml'dan dinamik yüklenir
|
||||
ui.vertical_centered(|ui| {
|
||||
let logo = if self.state.is_dark {
|
||||
egui::include_image!("../assets/pisi-logo-dark.png")
|
||||
let logo_uri = if self.state.is_dark {
|
||||
&self.state.branding_yali_dark
|
||||
} else {
|
||||
egui::include_image!("../assets/pisi-logo-light.png")
|
||||
&self.state.branding_yali_light
|
||||
};
|
||||
ui.add(
|
||||
egui::Image::new(logo)
|
||||
.max_width(120.0)
|
||||
.rounding(egui::Rounding::same(8.0)),
|
||||
);
|
||||
if !logo_uri.is_empty() {
|
||||
ui.add(
|
||||
egui::Image::from_uri(logo_uri.as_str())
|
||||
.max_width(120.0)
|
||||
.rounding(egui::Rounding::same(8.0)),
|
||||
);
|
||||
}
|
||||
ui.add_space(8.0);
|
||||
ui.label(
|
||||
egui::RichText::new(t!("os_name"))
|
||||
egui::RichText::new(t!("app_name"))
|
||||
.strong()
|
||||
.size(16.0)
|
||||
.color(ui::theme::c_text_dim()),
|
||||
);
|
||||
// get desktop environment
|
||||
let desktop = std::env::var("XDG_CURRENT_DESKTOP").unwrap_or_default();
|
||||
ui.label(
|
||||
egui::RichText::new(&format!("{} Desktop", desktop))
|
||||
.size(14.0)
|
||||
.color(ui::theme::c_text_dim()),
|
||||
|
||||
ui.colored_label(
|
||||
egui::Color32::from_rgb(60, 60, 90),
|
||||
format!("{}: {}", t!("version"), env!("CARGO_PKG_VERSION")),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -305,15 +397,10 @@ impl eframe::App for YaliApp {
|
||||
ui.add_space(2.0);
|
||||
}
|
||||
|
||||
// Alt kısım: tema değiştirme + sürüm bilgisi
|
||||
// Alt kısım: tema değiştirme
|
||||
ui.with_layout(egui::Layout::bottom_up(egui::Align::Center), |ui| {
|
||||
ui.add_space(12.0);
|
||||
ui.colored_label(
|
||||
egui::Color32::from_rgb(60, 60, 90),
|
||||
format!("YALI (v{})", env!("CARGO_PKG_VERSION")),
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
// Tema değiştirme butonu
|
||||
|
||||
let theme_icon = if self.state.is_dark { "☀" } else { "🌙" };
|
||||
let theme_label = if self.state.is_dark { "Light" } else { "Dark" };
|
||||
if ui.add(
|
||||
@@ -341,11 +428,8 @@ impl eframe::App for YaliApp {
|
||||
ui.horizontal(|ui| {
|
||||
ui.add_space(8.0);
|
||||
|
||||
// İptal — kurulum ve bitiş ekranında gizle
|
||||
if !is_exec && !is_finish {
|
||||
if ui.add(ui::theme::secondary_button(&t!("cancel"))).clicked() {
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||
}
|
||||
if !is_exec && !is_finish && ui.add(ui::theme::secondary_button(&t!("cancel"))).clicked() {
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||
}
|
||||
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
@@ -357,7 +441,6 @@ impl eframe::App for YaliApp {
|
||||
.unwrap_or(false);
|
||||
|
||||
if !is_finish {
|
||||
// İleri / Tamamlandı butonu
|
||||
if !is_exec || is_valid {
|
||||
let next_label = if is_exec {
|
||||
t!("finish_next")
|
||||
@@ -367,7 +450,6 @@ impl eframe::App for YaliApp {
|
||||
let btn = if is_valid {
|
||||
ui::theme::primary_button(&next_label)
|
||||
} else {
|
||||
// Devre dışı görünüm için secondary kullan
|
||||
ui::theme::secondary_button(&next_label)
|
||||
};
|
||||
if ui.add_enabled(is_valid, btn).clicked() {
|
||||
@@ -375,7 +457,6 @@ impl eframe::App for YaliApp {
|
||||
}
|
||||
}
|
||||
|
||||
// Geri — kurulum ekranında gizle
|
||||
if cur > 0 && !is_exec {
|
||||
ui.add_space(8.0);
|
||||
if ui.add(ui::theme::secondary_button(&t!("back"))).clicked() {
|
||||
@@ -403,4 +484,4 @@ impl eframe::App for YaliApp {
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user