forked from pisilinux-rs/yali-rs
Bölümleme tablosu boyut sütunu düzeltmeleri ve disk seçimi UI iyileştirmeleri
- Manuel bölümleme tablosunda boyut sütununun görünmemesi sorunu çözüldü - Disk başlığı kırmızı renk ve kutucuk simge sorunları düzeltildi (c_accent yerine c_text, Unicode ok karakteri) - Disk seçimi için ComboBox bileşeni eklendi (eski Grid tabanlı sistem yerine) - Tablo header hizalamaları düzeltildi (sol/sağ/ortalanmış sütunlar) - Font yüklemesi iyileştirildi (monospace font desteği ve emoji fallback mekanizması) - LVM LV boyut kontrolü sembolik boyutlar için düzeltildi - Disk bölüm numarası formatlama fonksiyonu eklendi (nvme0n1p1 vs sda1 mantığı) Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
+180
-116
@@ -505,11 +505,11 @@ impl PartitionStep {
|
||||
// arka plan
|
||||
egui::Frame::none()
|
||||
.fill(if selected {
|
||||
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 255)
|
||||
} else if response.hovered() {
|
||||
egui::Color32::from_rgba_unmultiplied(60, 60, 80, 180)
|
||||
} else {
|
||||
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 40)
|
||||
})
|
||||
.stroke(egui::Stroke::new(
|
||||
if selected { 2.0_f32 } else { 1.0_f32 },
|
||||
@@ -593,26 +593,25 @@ impl PartitionStep {
|
||||
let mut satirlar = Vec::new();
|
||||
if plan.efi_mb > 0 {
|
||||
satirlar.push(Satir {
|
||||
part: format!("{}1 (EFI)", plan.disk),
|
||||
part: format!("{} (EFI)", format_partition_device(&plan.disk, 1)),
|
||||
fs: "FAT32",
|
||||
size: format!("{} MB", plan.efi_mb),
|
||||
});
|
||||
}
|
||||
let swap_part = if plan.efi_mb > 0 { 2 } else { 1 };
|
||||
satirlar.push(Satir {
|
||||
part: format!("{}{} (swap)", plan.disk, swap_part),
|
||||
part: format!("{} (swap)", format_partition_device(&plan.disk, swap_part)),
|
||||
fs: "swap",
|
||||
size: format!("{} MB", plan.swap_mb),
|
||||
});
|
||||
let root_part = swap_part + 1;
|
||||
satirlar.push(Satir {
|
||||
part: format!("{}{}{}", plan.disk, root_part, t!("plan_root_suffix")),
|
||||
part: format!("{}{}", format_partition_device(&plan.disk, root_part), t!("plan_root_suffix")),
|
||||
fs: "ext4",
|
||||
size: format!("{:.1} GB", plan.root_mb as f64 / 1024.0),
|
||||
});
|
||||
|
||||
egui::Frame::none()
|
||||
.stroke(egui::Stroke::new(1.0_f32, crate::ui::theme::c_border()))
|
||||
egui::Frame::none()
|
||||
.rounding(egui::Rounding::same(6.0))
|
||||
.show(ui, |ui| {
|
||||
let tam = ui.available_width();
|
||||
@@ -716,97 +715,124 @@ impl PartitionStep {
|
||||
|
||||
impl PartitionStep {
|
||||
fn show_manual_mode(&mut self, ui: &mut egui::Ui, state: &mut GlobalState) {
|
||||
let kart_genislik = 180.0;
|
||||
let kart_yukseklik = 160.0;
|
||||
// let kart_genislik = 180.0;
|
||||
// let kart_yukseklik = 160.0;
|
||||
|
||||
// ── Disk seçimi (hedef disk) ────────────────────────────
|
||||
ui.group(|ui| {
|
||||
ui.label(t!("select_disk_label"));
|
||||
ui.add_space(8.0);
|
||||
let disks = state.available_disks.clone();
|
||||
ui.label(egui::RichText::new("Kurulum Yapılacak Diski Seçin:").strong());
|
||||
ui.add_space(6.0);
|
||||
|
||||
egui::Grid::new("manual_disk_grid")
|
||||
.min_col_width(kart_genislik + 12.0)
|
||||
.spacing([12.0, 12.0])
|
||||
.show(ui, |ui| {
|
||||
for (i, disk) in disks.iter().enumerate() {
|
||||
let selected = state.selected_disk.as_deref() == Some(&disk.name);
|
||||
// Seçili disk için etiket
|
||||
let selected_label = state.selected_disk.as_ref()
|
||||
.and_then(|disk_name| state.available_disks.iter().find(|d| d.name == *disk_name))
|
||||
.map(|disk| format!("{} - {} ({:.1} GB)", disk.name, disk.model, disk.size_bytes as f64 / 1_073_741_824.0))
|
||||
.unwrap_or_else(|| "Disk Seçin".to_string());
|
||||
|
||||
let (rect, response) = ui.allocate_exact_size(
|
||||
egui::vec2(kart_genislik, kart_yukseklik),
|
||||
egui::Sense::click(),
|
||||
);
|
||||
let child_ui = &mut ui.child_ui(rect, egui::Layout::top_down(egui::Align::Center));
|
||||
// ComboBox Oluşturma
|
||||
egui::ComboBox::from_id_source("disk_selection_combobox")
|
||||
.selected_text(selected_label)
|
||||
.width(ui.available_width() - 20.0) // Genişliği panele yay
|
||||
.show_ui(ui, |ui| {
|
||||
for disk in &state.available_disks {
|
||||
let label = format!("{} - {} ({:.1} GB)", disk.name, disk.model, disk.size_bytes as f64 / 1_073_741_824.0);
|
||||
|
||||
egui::Frame::none()
|
||||
.fill(if selected {
|
||||
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||
} else if response.hovered() {
|
||||
egui::Color32::from_rgba_unmultiplied(60, 60, 80, 180)
|
||||
} else {
|
||||
egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1)
|
||||
})
|
||||
.stroke(egui::Stroke::new(
|
||||
if selected { 2.0_f32 } else { 1.0_f32 },
|
||||
if selected { crate::ui::theme::c_accent() } else { crate::ui::theme::c_border() },
|
||||
))
|
||||
.rounding(egui::Rounding::same(8.0))
|
||||
.inner_margin(egui::Margin::same(8.0))
|
||||
.show(child_ui, |ui| {
|
||||
ui.set_min_size(egui::vec2(kart_genislik - 16.0, kart_yukseklik - 16.0));
|
||||
ui.add_space(8.0);
|
||||
ui.add(
|
||||
egui::Image::new(egui::include_image!("../../assets/disk.png"))
|
||||
.max_width(64.0)
|
||||
.max_height(64.0)
|
||||
.rounding(egui::Rounding::same(6.0)),
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
let marka = if disk.vendor.is_empty() {
|
||||
&disk.model
|
||||
} else {
|
||||
&disk.vendor
|
||||
};
|
||||
|
||||
ui.label(
|
||||
egui::RichText::new(marka)
|
||||
.size(11.0)
|
||||
.color(crate::ui::theme::c_text_dim()),
|
||||
);
|
||||
|
||||
ui.label(
|
||||
egui::RichText::new(format!("{} GB", disk.size_gb))
|
||||
.size(14.0)
|
||||
.strong()
|
||||
.color(crate::ui::theme::c_text()),
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
if response.clicked() {
|
||||
// Aktif diski değiştir; ancak diğer disklerde yapılmış
|
||||
// bölüm tanımlarını KORU. Seçilen diskin mevcut
|
||||
// bölümlerini listeye ekle (aynı cihaz zaten tanımlıysa
|
||||
// kullanıcının tanımı kazanır).
|
||||
state.selected_disk = Some(disk.name.clone());
|
||||
let fresh = read_existing_partitions(&disk.name);
|
||||
for f in fresh {
|
||||
let known = state.custom_partitions.iter()
|
||||
.any(|p| p.device == f.device || p.orig_device == f.orig_device);
|
||||
if !known {
|
||||
state.custom_partitions.push(f);
|
||||
}
|
||||
}
|
||||
self.manual.error = None;
|
||||
}
|
||||
|
||||
if (i + 1) % 3 == 0 {
|
||||
ui.end_row();
|
||||
}
|
||||
if ui.selectable_value(&mut state.selected_disk, Some(disk.name.clone()), label).changed() {
|
||||
// Disk değiştiğinde tetiklenecek işlemler (örn: disk bölümlerini yeniden okuma)
|
||||
println!("Seçilen Disk Değişti: {}", disk.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// // ── Disk seçimi (hedef disk) ────────────────────────────
|
||||
// ui.group(|ui| {
|
||||
// ui.label(t!("select_disk_label"));
|
||||
// ui.add_space(8.0);
|
||||
// let disks = state.available_disks.clone();
|
||||
|
||||
// egui::Grid::new("manual_disk_grid")
|
||||
// .min_col_width(kart_genislik + 12.0)
|
||||
// .spacing([12.0, 12.0])
|
||||
// .show(ui, |ui| {
|
||||
// for (i, disk) in disks.iter().enumerate() {
|
||||
// let selected = state.selected_disk.as_deref() == Some(&disk.name);
|
||||
|
||||
// let (rect, response) = ui.allocate_exact_size(
|
||||
// egui::vec2(kart_genislik, kart_yukseklik),
|
||||
// egui::Sense::click(),
|
||||
// );
|
||||
// let child_ui = &mut ui.child_ui(rect, egui::Layout::top_down(egui::Align::Center));
|
||||
|
||||
// egui::Frame::none()
|
||||
// .fill(if selected {
|
||||
// egui::Color32::from_rgba_unmultiplied(237, 237, 224, 255)
|
||||
// } else if response.hovered() {
|
||||
// egui::Color32::from_rgba_unmultiplied(60, 60, 80, 180)
|
||||
// } else {
|
||||
// egui::Color32::from_rgba_unmultiplied(237, 237, 224, 40)
|
||||
// })
|
||||
// .stroke(egui::Stroke::new(
|
||||
// if selected { 2.0_f32 } else { 1.0_f32 },
|
||||
// if selected { crate::ui::theme::c_accent() } else { crate::ui::theme::c_border() },
|
||||
// ))
|
||||
// .rounding(egui::Rounding::same(8.0))
|
||||
// .inner_margin(egui::Margin::same(8.0))
|
||||
// .show(child_ui, |ui| {
|
||||
// ui.set_min_size(egui::vec2(kart_genislik - 16.0, kart_yukseklik - 16.0));
|
||||
// ui.add_space(8.0);
|
||||
// ui.add(
|
||||
// egui::Image::new(egui::include_image!("../../assets/disk.png"))
|
||||
// .max_width(64.0)
|
||||
// .max_height(64.0)
|
||||
// .rounding(egui::Rounding::same(6.0)),
|
||||
// );
|
||||
// ui.add_space(6.0);
|
||||
// let marka = if disk.vendor.is_empty() {
|
||||
// &disk.model
|
||||
// } else {
|
||||
// &disk.vendor
|
||||
// };
|
||||
|
||||
// ui.label(
|
||||
// egui::RichText::new(marka)
|
||||
// .size(11.0)
|
||||
// .color(crate::ui::theme::c_text_dim()),
|
||||
// );
|
||||
|
||||
// ui.label(
|
||||
// egui::RichText::new(format!("{} GB", disk.size_gb))
|
||||
// .size(14.0)
|
||||
// .strong()
|
||||
// .color(crate::ui::theme::c_text()),
|
||||
// );
|
||||
|
||||
// });
|
||||
|
||||
// if response.clicked() {
|
||||
// // Aktif diski değiştir; ancak diğer disklerde yapılmış
|
||||
// // bölüm tanımlarını KORU. Seçilen diskin mevcut
|
||||
// // bölümlerini listeye ekle (aynı cihaz zaten tanımlıysa
|
||||
// // kullanıcının tanımı kazanır).
|
||||
// state.selected_disk = Some(disk.name.clone());
|
||||
// let fresh = read_existing_partitions(&disk.name);
|
||||
// for f in fresh {
|
||||
// let known = state.custom_partitions.iter()
|
||||
// .any(|p| p.device == f.device || p.orig_device == f.orig_device);
|
||||
// if !known {
|
||||
// state.custom_partitions.push(f);
|
||||
// }
|
||||
// }
|
||||
// self.manual.error = None;
|
||||
// }
|
||||
|
||||
// if (i + 1) % 3 == 0 {
|
||||
// ui.end_row();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
ui.add_space(8.0);
|
||||
|
||||
let disk = match &state.selected_disk {
|
||||
@@ -822,8 +848,6 @@ impl PartitionStep {
|
||||
ui.label(egui::RichText::new(t!("mp_plan_title")).strong().color(crate::ui::theme::c_text()));
|
||||
ui.add_space(6.0);
|
||||
|
||||
let delete_idx: Option<usize> = None;
|
||||
|
||||
let col_widths = [0.25, 0.12, 0.16, 0.24, 0.23];
|
||||
let tam_genislik = ui.available_width();
|
||||
let _border_stroke = egui::Stroke::new(1.0_f32, crate::ui::theme::c_border());
|
||||
@@ -917,12 +941,12 @@ impl PartitionStep {
|
||||
egui::pos2(hdr_rect.left() + 10.0, hdr_rect.center().y),
|
||||
egui::Align2::LEFT_CENTER,
|
||||
if is_active_disk {
|
||||
format!("\u{EA6B} {} ({})", disk_name, disk_total_str)
|
||||
format!("\u{EA6B} {} ( {} )", disk_name, disk_total_str)
|
||||
} else {
|
||||
format!("{} ({})", disk_name, disk_total_str)
|
||||
},
|
||||
egui::FontId::proportional(12.5),
|
||||
crate::ui::theme::c_accent(),
|
||||
crate::ui::theme::select_disk_label(),
|
||||
);
|
||||
|
||||
// Bu diskin kendi sütun başlıkları
|
||||
@@ -1029,13 +1053,25 @@ impl PartitionStep {
|
||||
egui::pos2(x + 8.0, row_rect.top() + 4.0),
|
||||
egui::vec2(cell_w - 16.0, 26.0),
|
||||
);
|
||||
painter.text(
|
||||
text_rect.center(),
|
||||
egui::Align2::CENTER_CENTER,
|
||||
*text,
|
||||
egui::FontId::proportional(13.0),
|
||||
text_color,
|
||||
);
|
||||
// Tablo okunabilirliği: metin sütunları sola, sayı (Boyut)
|
||||
// sağa yaslı; aygıt adı monospace (/dev/sdb1 vs sdb10 ayrımı).
|
||||
let (anchor, font) = match j {
|
||||
0 => (egui::Align2::LEFT_CENTER, egui::FontId::monospace(12.5)),
|
||||
1 => (egui::Align2::RIGHT_CENTER, egui::FontId::monospace(12.5)),
|
||||
_ => (egui::Align2::LEFT_CENTER, egui::FontId::proportional(13.0)),
|
||||
};
|
||||
// Hizalama noktası anchor'a göre seçilir: LEFT_CENTER için hücrenin
|
||||
// SOL kenarı, RIGHT_CENTER için SAĞ kenarı. Her ikisinde de rect.center()
|
||||
// kullanmak metnin hücre ORTASINDAN başlamasına yol açıyordu; uzun
|
||||
// aygıt adlarında (örn. "/dev/nvme0n1p1") bu, metnin yarısının bir
|
||||
// sonraki sütuna taşıp üstüne binmesine (görsel olarak karakterlerin
|
||||
// kayıp/örtülü görünmesine) sebep oluyordu.
|
||||
let anchor_pos = match anchor {
|
||||
egui::Align2::LEFT_CENTER => text_rect.left_center(),
|
||||
egui::Align2::RIGHT_CENTER => text_rect.right_center(),
|
||||
_ => text_rect.center(),
|
||||
};
|
||||
painter.text(anchor_pos, anchor, *text, font, text_color);
|
||||
x += cell_w;
|
||||
}
|
||||
|
||||
@@ -1065,7 +1101,7 @@ impl PartitionStep {
|
||||
}
|
||||
|
||||
if vis_idx < total_rows - 1 {
|
||||
ui.separator();
|
||||
//ui.separator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1087,9 +1123,6 @@ impl PartitionStep {
|
||||
}
|
||||
|
||||
// Silme onayı
|
||||
if let Some(idx) = delete_idx {
|
||||
self.manual.delete_idx = Some(idx);
|
||||
}
|
||||
if let Some(idx) = self.manual.delete_idx {
|
||||
let dev = state.custom_partitions.get(idx)
|
||||
.map(|p| p.device.clone())
|
||||
@@ -1168,7 +1201,6 @@ impl PartitionStep {
|
||||
self.manual.add_mountpoint = match next_num {
|
||||
1 if self.is_uefi => "/boot/efi".to_string(),
|
||||
1 => "/".to_string(),
|
||||
2 if self.is_uefi => "swap".to_string(),
|
||||
2 => "swap".to_string(),
|
||||
3 => "/".to_string(),
|
||||
_ => String::new(),
|
||||
@@ -1781,7 +1813,13 @@ impl PartitionStep {
|
||||
.filter(|lv| lv.vg_name == vg.name)
|
||||
.map(|lv| lv.size_mb)
|
||||
.sum();
|
||||
if current_sum + size_mb > vg.size_mb && size_mb > 0 {
|
||||
let overflows = if size_mb == 0 {
|
||||
// "Kalan alan" (sembolik): VG'de hiç boş yer kalmamışsa hata.
|
||||
current_sum >= vg.size_mb
|
||||
} else {
|
||||
current_sum + size_mb > vg.size_mb
|
||||
};
|
||||
if overflows {
|
||||
self.manual.error = Some(t!("lvm_lv_error_size").to_string());
|
||||
} else {
|
||||
state.logical_volumes.push(crate::installer::LogicalVolume {
|
||||
@@ -1839,7 +1877,7 @@ impl PartitionStep {
|
||||
/// Bölüm tablosunun sütun başlıklarını çizer.
|
||||
/// Her disk grubu kendi başlık satırıyla ayrı bir "tablo" görünümü verir.
|
||||
fn draw_partition_table_header(ui: &mut egui::Ui, tam_genislik: f32, col_widths: [f32; 5]) {
|
||||
let header_color = egui::Color32::from_rgb(33, 37, 41);
|
||||
let header_color = egui::Color32::from_rgb(0, 0, 0);
|
||||
let header_text = egui::Color32::WHITE;
|
||||
let headers: [String; 5] = [
|
||||
t!("mp_device").to_string(),
|
||||
@@ -1851,19 +1889,33 @@ fn draw_partition_table_header(ui: &mut egui::Ui, tam_genislik: f32, col_widths:
|
||||
ui.horizontal(|ui| {
|
||||
ui.set_height(30.0);
|
||||
ui.spacing_mut().item_spacing.x = 0.0;
|
||||
// Başlık hizası içerikle aynı: Aygıt/Dosya Sistemi/Bağlama sola,
|
||||
// Boyut sağa, Biçim ortalanmış.
|
||||
let header_aligns = [
|
||||
egui::Align2::LEFT_CENTER,
|
||||
egui::Align2::RIGHT_CENTER,
|
||||
egui::Align2::LEFT_CENTER,
|
||||
egui::Align2::LEFT_CENTER,
|
||||
egui::Align2::CENTER_CENTER,
|
||||
];
|
||||
for (j, h) in headers.into_iter().enumerate() {
|
||||
let (rect, _) = ui.allocate_exact_size(
|
||||
egui::vec2(tam_genislik * col_widths[j], 30.0),
|
||||
egui::Sense::hover(),
|
||||
);
|
||||
let child_ui = &mut ui.child_ui(rect, egui::Layout::top_down(egui::Align::Center));
|
||||
egui::Frame::none()
|
||||
.fill(header_color)
|
||||
.stroke(egui::Stroke::new(1.0_f32, header_color))
|
||||
.inner_margin(egui::Margin::symmetric(8.0, 4.0))
|
||||
.show(child_ui, |ui| {
|
||||
ui.label(egui::RichText::new(h).strong().color(header_text).size(13.0));
|
||||
});
|
||||
let painter = ui.painter();
|
||||
// İçerikle aynı 8px iç boşluk
|
||||
let inner = rect.shrink2(egui::vec2(8.0, 0.0));
|
||||
painter.rect_filled(rect, egui::Rounding::ZERO, header_color);
|
||||
// Hizalama noktası anchor'a göre seçilir (bkz. satır çiziminde aynı düzeltme):
|
||||
// rect.center() her anchor için kullanılırsa LEFT_CENTER/RIGHT_CENTER
|
||||
// başlıklar hücre ortasından başlar/biter, uzun başlıklarda taşma olur.
|
||||
let anchor_pos = match header_aligns[j] {
|
||||
egui::Align2::LEFT_CENTER => inner.left_center(),
|
||||
egui::Align2::RIGHT_CENTER => inner.right_center(),
|
||||
_ => inner.center(),
|
||||
};
|
||||
painter.text(anchor_pos, header_aligns[j], h, egui::FontId::proportional(13.0), header_text);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2064,6 +2116,18 @@ fn partition_bar(ui: &mut egui::Ui, plan: &PartitionPlan) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Disk adına bölüm numarasını doğru ekle: `sda`+1 → `sda1`, ama
|
||||
/// `nvme0n1`/`mmcblk0`/`loop0` gibi rakamla biten aygıtlarda araya
|
||||
/// `p` konur → `nvme0n1p1`, `mmcblk0p1`. (bkz. `device_to_disk` — aynı
|
||||
/// kuralın tersini uygular.)
|
||||
fn format_partition_device(disk: &str, num: u64) -> String {
|
||||
if disk.chars().last().map(|c| c.is_ascii_digit()).unwrap_or(false) {
|
||||
format!("{}p{}", disk, num)
|
||||
} else {
|
||||
format!("{}{}", disk, num)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sayıyı nokta ile binlik ayraçlı formata çevirir (örn. 7000000 → 7.000.000).
|
||||
fn format_number_thousands(n: u64) -> String {
|
||||
let s = n.to_string();
|
||||
|
||||
+132
-16
@@ -52,6 +52,7 @@ pub fn c_sidebar_text() -> Color32 { color_from_hex(SIDEBAR_TEXT.load(Ordering::
|
||||
pub fn c_footer_bg() -> Color32 { color_from_hex(BG_FOOTER.load(Ordering::Relaxed)) }
|
||||
pub fn c_root_bg() -> Color32 { color_from_hex(BG_ROOT.load(Ordering::Relaxed)) }
|
||||
pub fn c_keyboard_bg() -> Color32 { color_from_hex(KEYBOARD_BG.load(Ordering::Relaxed)) }
|
||||
pub fn select_disk_label() -> Color32 { color_from_hex(0xFFFFFF) }
|
||||
|
||||
pub fn set_theme_mode(is_dark: bool) {
|
||||
if is_dark {
|
||||
@@ -108,10 +109,85 @@ pub fn apply(ctx: &egui::Context, is_dark: bool) {
|
||||
ctx.set_visuals(build_visuals(is_dark));
|
||||
}
|
||||
|
||||
// fn setup_fonts(ctx: &egui::Context) {
|
||||
// let mut fonts = egui::FontDefinitions::default();
|
||||
|
||||
// // 1. ADIM: Sadece Metin (Text) Fontunu Bul ve Yükle
|
||||
// let text_font_paths = [
|
||||
// "/usr/share/fonts/TTF/OpenSans-Regular.ttf",
|
||||
// "/usr/share/fonts/noto/NotoSans-Regular.ttf",
|
||||
// "/usr/share/fonts/exo-1/Exo-Regular.otf",
|
||||
// "/usr/share/fonts/exo-1/Exo2-Medium.ttf",
|
||||
// "/usr/share/fonts/exo-1/Exo-Medium.otf",
|
||||
// ];
|
||||
|
||||
// for path in text_font_paths {
|
||||
// if let Ok(data) = std::fs::read(path) {
|
||||
// fonts.font_data.insert(
|
||||
// "system_text_font".to_owned(),
|
||||
// egui::FontData::from_owned(data),
|
||||
// );
|
||||
|
||||
// // Metin fontunu en başa (0. indeks) koyuyoruz ki varsayılan olarak bu kullanılsın
|
||||
// fonts
|
||||
// .families
|
||||
// .entry(egui::FontFamily::Proportional)
|
||||
// .or_default()
|
||||
// .insert(0, "system_text_font".to_owned());
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 2. ADIM: Renkli Emoji Fontunu Ara ve "Fallback" (Yedek) Olarak Sona Ekle
|
||||
// // ISO ortamlarında Noto Color Emoji genellikle bu yollardan birinde olur
|
||||
// let emoji_font_paths = [
|
||||
// "/usr/share/fonts/noto/NotoColorEmoji.ttf",
|
||||
// ];
|
||||
|
||||
// for path in emoji_font_paths {
|
||||
// if let Ok(data) = std::fs::read(path) {
|
||||
// fonts.font_data.insert(
|
||||
// "system_emoji_font".to_owned(),
|
||||
// egui::FontData::from_owned(data),
|
||||
// );
|
||||
|
||||
// // ÖNEMLİ: Emojiyi listenin SONUNA (push ile) ekliyoruz.
|
||||
// // Böylece egui normal harfleri sistem fontuyla yazacak,
|
||||
// // harf sistem fontunda yoksa (yani emojiyse) gidip bu fonttan alacak.
|
||||
// fonts
|
||||
// .families
|
||||
// .entry(egui::FontFamily::Proportional)
|
||||
// .or_default()
|
||||
// .push("system_emoji_font".to_owned());
|
||||
|
||||
// fonts
|
||||
// .families
|
||||
// .entry(egui::FontFamily::Monospace)
|
||||
// .or_default()
|
||||
// .insert(0, "system_emoji_font".to_owned());
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 3. ADIM: Remixicon ikon fontunu projeye göm (PUA bölgesindeki karakterler için fallback)
|
||||
// let remixicon_data = include_bytes!("../../assets/remixicon.ttf");
|
||||
// fonts.font_data.insert(
|
||||
// "remixicon".to_owned(),
|
||||
// egui::FontData::from_owned(remixicon_data.to_vec()),
|
||||
// );
|
||||
// fonts
|
||||
// .families
|
||||
// .entry(egui::FontFamily::Proportional)
|
||||
// .or_default()
|
||||
// .push("remixicon".to_owned());
|
||||
|
||||
// ctx.set_fonts(fonts);
|
||||
// }
|
||||
|
||||
fn setup_fonts(ctx: &egui::Context) {
|
||||
let mut fonts = egui::FontDefinitions::default();
|
||||
|
||||
// 1. ADIM: Sadece Metin (Text) Fontunu Bul ve Yükle
|
||||
// 1. ADIM: Metin ve Monospace için Sistem Fontu Yükleme
|
||||
let text_font_paths = [
|
||||
"/usr/share/fonts/TTF/OpenSans-Regular.ttf",
|
||||
"/usr/share/fonts/noto/NotoSans-Regular.ttf",
|
||||
@@ -120,25 +196,59 @@ fn setup_fonts(ctx: &egui::Context) {
|
||||
"/usr/share/fonts/exo-1/Exo-Medium.otf",
|
||||
];
|
||||
|
||||
let mut _text_font_loaded = false;
|
||||
|
||||
for path in text_font_paths {
|
||||
if let Ok(data) = std::fs::read(path) {
|
||||
fonts.font_data.insert(
|
||||
"system_text_font".to_owned(),
|
||||
egui::FontData::from_owned(data),
|
||||
egui::FontData::from_owned(data).into(), // Sürüme göre .into() veya std::sync::Arc::new(...)
|
||||
);
|
||||
|
||||
// Metin fontunu en başa (0. indeks) koyuyoruz ki varsayılan olarak bu kullanılsın
|
||||
|
||||
// Proportional (Orantılı) fontun başına ekle
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Proportional)
|
||||
.or_default()
|
||||
.insert(0, "system_text_font".to_owned());
|
||||
|
||||
// Monospace için de bu fontu varsayılan olarak ekle (özel bir monospace bulunamadıysa)
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Monospace)
|
||||
.or_default()
|
||||
.insert(0, "system_text_font".to_owned());
|
||||
|
||||
_text_font_loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. ADIM: Renkli Emoji Fontunu Ara ve "Fallback" (Yedek) Olarak Sona Ekle
|
||||
// ISO ortamlarında Noto Color Emoji genellikle bu yollardan birinde olur
|
||||
// Ek Güvence: Özel bir Monospace fontu varsa öncelikli olarak onu ara
|
||||
let mono_font_paths = [
|
||||
"/usr/share/fonts/TTF/Hack-Regular.ttf",
|
||||
"/usr/share/fonts/TTF/DejaVuSansMono.ttf",
|
||||
"/usr/share/fonts/noto/NotoSansMono-Regular.ttf",
|
||||
];
|
||||
|
||||
for path in mono_font_paths {
|
||||
if let Ok(data) = std::fs::read(path) {
|
||||
fonts.font_data.insert(
|
||||
"system_mono_font".to_owned(),
|
||||
egui::FontData::from_owned(data).into(),
|
||||
);
|
||||
|
||||
// Monospace ailesinin 0. indeksine yerleştir
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Monospace)
|
||||
.or_default()
|
||||
.insert(0, "system_mono_font".to_owned());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. ADIM: Color Emoji Fontunu Yedek (Fallback) Olarak EKLE
|
||||
let emoji_font_paths = [
|
||||
"/usr/share/fonts/noto/NotoColorEmoji.ttf",
|
||||
];
|
||||
@@ -147,39 +257,44 @@ fn setup_fonts(ctx: &egui::Context) {
|
||||
if let Ok(data) = std::fs::read(path) {
|
||||
fonts.font_data.insert(
|
||||
"system_emoji_font".to_owned(),
|
||||
egui::FontData::from_owned(data),
|
||||
egui::FontData::from_owned(data).into(),
|
||||
);
|
||||
|
||||
// ÖNEMLİ: Emojiyi listenin SONUNA (push ile) ekliyoruz.
|
||||
// Böylece egui normal harfleri sistem fontuyla yazacak,
|
||||
// harf sistem fontunda yoksa (yani emojiyse) gidip bu fonttan alacak.
|
||||
// Her iki aileye de SONA (push) ekle, böylece metinler bozulmaz
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Proportional)
|
||||
.or_default()
|
||||
.push("system_emoji_font".to_owned());
|
||||
|
||||
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Monospace)
|
||||
.or_default()
|
||||
.insert(0, "system_emoji_font".to_owned());
|
||||
.push("system_emoji_font".to_owned()); // insert(0, ...) yerine push yapıldı!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. ADIM: Remixicon ikon fontunu projeye göm (PUA bölgesindeki karakterler için fallback)
|
||||
// 3. ADIM: Remixicon İkon Fontunu Göm (PUA)
|
||||
let remixicon_data = include_bytes!("../../assets/remixicon.ttf");
|
||||
fonts.font_data.insert(
|
||||
"remixicon".to_owned(),
|
||||
egui::FontData::from_owned(remixicon_data.to_vec()),
|
||||
egui::FontData::from_owned(remixicon_data.to_vec()).into(),
|
||||
);
|
||||
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Proportional)
|
||||
.or_default()
|
||||
.push("remixicon".to_owned());
|
||||
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Monospace)
|
||||
.or_default()
|
||||
.push("remixicon".to_owned());
|
||||
|
||||
ctx.set_fonts(fonts);
|
||||
}
|
||||
|
||||
@@ -187,7 +302,7 @@ fn setup_fonts(ctx: &egui::Context) {
|
||||
|
||||
fn build_visuals(is_dark: bool) -> Visuals {
|
||||
let mut v = if is_dark { Visuals::dark() } else { Visuals::light() };
|
||||
|
||||
|
||||
// Genel arka planlar
|
||||
v.window_fill = c_bg_dark();
|
||||
v.panel_fill = c_bg_panel();
|
||||
@@ -243,13 +358,14 @@ fn build_visuals(is_dark: bool) -> Visuals {
|
||||
|
||||
fn build_style() -> egui::Style {
|
||||
let mut style = egui::Style::default();
|
||||
|
||||
|
||||
// Genel boşluk ve boyutlar
|
||||
style.spacing.item_spacing = Vec2::new(8.0, 6.0);
|
||||
style.spacing.button_padding = Vec2::new(12.0, 6.0);
|
||||
style.spacing.indent = 16.0;
|
||||
style.spacing.scroll.bar_width = 14.0;
|
||||
|
||||
|
||||
// Metin boyutları
|
||||
style.text_styles = [
|
||||
(egui::TextStyle::Small, FontId::proportional(11.0)),
|
||||
|
||||
Reference in New Issue
Block a user