9.7 KiB
Dock Sistemi Kararlılık ve Kullanılabilirlik İyileştirmeleri
1. default_dock_state() — Tekrarlanan Layout Kodunun Tekilleştirilmesi
Dosya: crates/hcie-gui-egui/src/app/mod.rs:699-714
Yeni fonksiyon:
fn default_dock_state() -> egui_dock::DockState<dock::HciePane> { ... }
Gerekçe: Dock layout kodu (split_left/split_right/split_below ile aynı panel yapısı) 3 farklı yerde manuel olarak tekrarlanıyordu:
HcieApp::new()— ilk açılışAppEvent::ResetLayouthandler'ıenforce_constraints()fallback
Her kopya arasında ufak farklar vardı (fallback'te Tools/Brushes/ColorBox/Layers farklı oranlardaydı). Bu, bir layout değişikliğinde 3 yerin de güncellenmesini zorunlu kılıyor ve tutarsızlık riski taşıyordu.
Değişen çağrılar:
mod.rs:863→dock_state.unwrap_or_else(default_dock_state)mod.rs:1210→self.dock_state = default_dock_state()mod.rs:2256→*state = default_dock_state()
2. std::mem::replace → swap (CRITICAL)
Dosya: crates/hcie-gui-egui/src/app/mod.rs:1984
Eski kod:
let mut dock_state = std::mem::replace(&mut self.dock_state, egui_dock::DockState::new(vec![]));
Yeni kod:
let mut dock_state = default_dock_state();
std::mem::swap(&mut dock_state, &mut self.dock_state);
Gerekçe: Eski kod self.dock_state'i tamamen boş bir DockState (0 surface, 0 node) ile değiştiriyor, sonra 50+ satır işlem yapıp en sonda geri atıyordu (self.dock_state = dock_state). Bu aralıkta herhangi bir panic olursa self.dock_state permament olarak 0 surface'li boş state'te kalır — sonraki her main_surface_mut() panic üretir. Yeni kod default_dock_state() ile swap yaparak bu riski ortadan kaldırır.
3. dock_safe_remove_tab() — Panic-Safe Tab Silme
Dosya: crates/hcie-gui-egui/src/app/mod.rs:998-1023
İmza:
fn dock_safe_remove_tab(&mut self, pos: (SurfaceIndex, NodeIndex, TabIndex)) -> Option<HciePane>
Gerekçe: egui_dock::DockState::remove_tab() üç index'i de bounds-check'siz kullanır — OOB'de panic. Helper sırasıyla surface → node → tab index'lerini doğrular, geçersizse log::warn + None döndürür.
4. dock_find_tabs() — Enumeration Helper
Dosya: crates/hcie-gui-egui/src/app/mod.rs:1024-1043
İmza:
fn dock_find_tabs<F>(&self, predicate: F) -> Vec<(SurfaceIndex, NodeIndex, TabIndex)>
Gerekçe: AppEvent::DocClosed handler'ında 15 satırlık manuel 3-seviye enumerate kodu 2 satıra indirildi. Aynı desenin birden çok yerde tekrarlanması önlendi.
Kullanım: mod.rs:1153 — DocClosed'ta tab'leri bulmak için.
5. enforce_constraints() — Parametre Temizliği
Dosya: crates/hcie-gui-egui/src/app/mod.rs:2138
Eski imza (9 parametre):
fn enforce_constraints(
_ctx: &egui::Context, state: &mut DockState<HciePane>,
_available_width: f32, _last_window_width: &mut f32,
_left_col1_w: &mut f32, _left_col2_w: &mut f32,
_right_col1_w: &mut f32, _right_col2_w: &mut f32,
_stable_frames: u32,
) -> Option<usize>
Yeni imza:
fn enforce_constraints(state: &mut DockState<HciePane>) -> Option<usize>
Çağrıldığı yer: mod.rs:2036
remove_tab validasyonu (satır 2192-2207):
tab_to_move index'leri scan fazında toplanır, remove_tab öncesi iter_surfaces().nth(node_idx.0).map_or(false, |n| matches!(n, Node::Leaf { tabs, .. } if tab_idx.0 < tabs.len())) ile doğrulanır.
6. sync_active_doc_from_dock() — Stale active_doc Düzeltmesi
Dosya: crates/hcie-gui-egui/src/app/mod.rs:1047-1056
İmza:
pub fn sync_active_doc_from_dock(&mut self) { ... }
Çağrıldığı yerler:
mod.rs:1171—AppEvent::DocClosedhandling sonrasımod.rs:2020—ui_main_assemblyiçinde dock_state swap-back sonrası
Gerekçe: Document kapatıldığında veya dock yeniden düzenlendiğinde self.active_doc eski bir index'i gösterebilir. Fonksiyon dock tree'deki ilk geçerli document index'ini bularak active_doc'u günceller.
7. dock.rs TabViewer title() — Referans Ömrü Güvenliği
Dosya: crates/hcie-gui-egui/src/app/dock.rs:184-196
Eski kod:
if let Some(surface) = self.app.dock_state.iter_surfaces().nth(surf_idx.0) {
if let Some(node) = surface.iter_nodes().nth(node_idx.0) {
Yeni kod:
let surface = self.app.dock_state.iter_surfaces().nth(surf_idx.0);
if let Some(surface) = surface {
let node = surface.iter_nodes().nth(node_idx.0);
if let Some(node) = node {
Gerekçe: Eski zincirleme if let'de borrow checker surface referansının ömrünü gereksiz yere uzatabiliyor. Ayrı let'ler referans ömürlerini netleştirir ve refactor durumunda borrow checker sorunlarını önler.
8. layout_solver.rs — Fraction Manipülasyonu Sadece Resize'da
Dosya: crates/hcie-gui-egui/src/app/layout_solver.rs (tamamen yeniden yazıldı, 336 satır → 188 satır)
Ana problem: Layout solver her stabil frame'de fraction'ları yeniden hesaplıyordu. Kullanıcı splitter'ı bırakır bırakmaz "stable + !pointer_down" branch'i Tools'u grid'e snap'liyor VE tüm column fraction'larını stored width'lere zorluyordu — kullanıcının elle ayarladığı genişlik sıfırlanıyordu.
| Durum | Eski Davranış | Yeni Davranış |
|---|---|---|
| Pencere boyut değişikliği (≥1px) | Her stabil frame'de enforcement | Sadece width_changed ise enforcement |
| Splitter sürükleniyor | Measure + store (3 frame) | Measure + store (3 frame, aynı) |
| Splitter bırakıldı | Snap + enforce → kullanıcıyı ezer | Sadece measure + store (30 frame idle'da) |
| Fraction clamp | 0.03..0.97 |
0.05..0.95 |
| Utility panel yok | Her Horizontal node'a müdahale | (None, None) => return — atla |
Kilit değişiklikler:
width_changed = (*last_window_width - available_width).abs() >= 1.0— enforcement sadece resize'da(None, None) => return— utility panel olmayan split'lere dokunmastable_frames >= 30idle persistence — sürekli ölçmek yerine 30 frame'de bir*f = new_fraction.clamp(0.05, 0.95)— minimum %5 genişlikmeasure_and_store_column()helper'ı ilefind_column_width+ store tek satırda
9. Dock Layout Profile Sistemi
Genel Bakış
Kullanıcılar panel düzenlerini (dock_state, column genişlikleri, pinned_panels) adlandırılmış profil olarak kaydedip geri yükleyebilir.
Veri Yapıları
DockProfile — mod.rs:195-202
pub struct DockProfile {
pub name: String,
pub dock_state_json: String,
pub left_col1_w: f32, pub left_col2_w: f32,
pub right_col1_w: f32, pub right_col2_w: f32,
pub last_window_width: f32,
pub pinned_panels: Vec<String>,
}
Settings.dock_profiles — mod.rs:214
#[serde(default)]
pub dock_profiles: Vec<DockProfile>,
Events (event_bus.rs:107-110)
| Event | Purpose |
|---|---|
DockProfileSave(String) |
Mevcut layout'u adla kaydet |
DockProfileApply(String) |
Kayıtlı profili yükle |
DockProfileDelete(String) |
Profili sil |
DockProfileRename(String, String) |
Profili yeniden adlandır |
HcieApp Alanları (mod.rs:677-680)
pub show_dock_profile_dialog: bool,
pub dock_profile_new_name: String,
pub dock_profile_rename_target: Option<usize>,
pub dock_profile_rename_buf: String,
Dialog UI
Dosya: src/app/dock_profile_dialog.rs (yeni, 130 satır)
Modal dialog (egui::Area + dim_background) ile:
- Profil listesi (scrollable): her satırda ad + Apply / Rename / Delete butonları
- Rename modu: inline text edit + ✓ onay
- "Save Current" bölümü: isim gir + Save (veya Enter)
- Boş profil listesinde "No saved profiles yet." mesajı
Çağrıldığı yer: mod.rs:2067
Event Handlers (mod.rs:1817-1872)
DockProfileSave(satır 1817): DockState JSON'a serialize, width/pinned alınır, aynı isimde profil varsa üzerine yazılır,SaveSettingstetiklenir.DockProfileApply(satır 1837): JSON'dan deserialize, tüm width/pinned değerler atanır,ctx.request_repaint().DockProfileDelete(satır 1854):retainile filtrele +SaveSettings.DockProfileRename(satır 1863): Matching profile'innamefield'ı güncellenir +SaveSettings.
Menu Entries (menus.rs:554-559)
- Window → Dock Layout Profiles…: dialog'u açar
- Window → Save Dock Layout As…: dialog'u açar + name input'u "My Layout" ile ön doldurur
- Window → Reset Layout: mevcut
10. Ölü Kod Temizliği
| Öğe | Dosya | Silinen satırlar |
|---|---|---|
show_filter_dialog() |
filter_dialog.rs:453-466 |
14 satır |
show_filter_dialog() re-export |
dialogs.rs:386-388 |
4 satır |
FilterDialogState struct |
filter_dialog.rs:8-18 |
11 satır |
show_filter, filter_dialog, filter_params_open, filter_preview_active |
mod.rs:615-618 |
4 field |
draw_auto_hide_strips() |
mod.rs eski 2209-2322 |
114 satır |
enforce_constraints doc comment (8 parametre) |
mod.rs eski 2048-2061 |
14 satır |
3× tekrarlanan layout kodu → default_dock_state() |
mod.rs |
~90 satır |
adjust_pixel_widths_rec yeniden yazımı |
layout_solver.rs |
336→188 satır |
Değişiklik İstatistikleri (git diff --stat)
| Dosya | Eklenen | Silinen | Net |
|---|---|---|---|
mod.rs |
— | — | +445 / -445 |
dock_profile_dialog.rs (yeni) |
130 | 0 | +130 |
layout_solver.rs |
— | — | +24 / -336 |
filter_dialog.rs |
0 | 49 | -49 |
dialogs.rs |
0 | 4 | -4 |
dock.rs |
4 | 2 | +2 |
menus.rs |
7 | 0 | +7 |
event_bus.rs |
4 | 0 | +4 |
| Toplam | ~290 | ~560 | ~-270 |
Build: 0 error, 0 new warning (cargo check clean).