use egui::Ui; use crate::constants::chinese_hero_name; use crate::state::{HeroState, Recommendations}; /// Render the in-game view with item build recommendations. pub fn render(ui: &mut Ui, hero: &HeroState, recommendations: &Recommendations) { // ---- Header ---- ui.horizontal(|ui| { ui.heading( egui::RichText::new("出装推荐") .color(egui::Color32::from_rgb(255, 200, 50)) .size(18.0), ); if recommendations.is_loading { ui.spinner(); } }); // Hero name (Chinese preferred) if let Some(name) = &hero.hero_name { let display = hero .hero_id .and_then(chinese_hero_name) .unwrap_or_else(|| name.strip_prefix("npc_dota_hero_").unwrap_or(name)); ui.horizontal(|ui| { ui.colored_label(egui::Color32::LIGHT_GRAY, "英雄: "); ui.label( egui::RichText::new(display) .color(egui::Color32::WHITE) .strong(), ); ui.colored_label(egui::Color32::GRAY, format!("Lv.{}", hero.level)); if !hero.alive { ui.colored_label(egui::Color32::RED, " [阵亡]"); } }); } ui.separator(); // ---- Error ---- if let Some(err) = &recommendations.last_error { ui.colored_label(egui::Color32::RED, format!("⚠ {}", err)); return; } if recommendations.item_builds.is_empty() { if recommendations.is_loading { ui.colored_label(egui::Color32::GRAY, "正在加载出装数据..."); } else if hero.hero_id.is_none() { ui.colored_label(egui::Color32::GRAY, "等待英雄信息..."); } else { ui.colored_label(egui::Color32::GRAY, "暂无出装数据"); } return; } // ---- Item phases ---- for phase in &recommendations.item_builds { ui.collapsing( egui::RichText::new(&phase.phase_name) .color(egui::Color32::from_rgb(255, 210, 80)) .size(13.0), |ui| { egui::Grid::new(format!("items_{}", &phase.phase_name)) .num_columns(2) .striped(true) .min_col_width(100.0) .show(ui, |ui| { ui.colored_label(egui::Color32::GRAY, "物品"); ui.colored_label(egui::Color32::GRAY, "流行度"); ui.end_row(); for item in &phase.items { ui.label(&item.display_name); let color = popularity_color(item.popularity_pct); ui.colored_label(color, format!("{:.0}%", item.popularity_pct)); ui.end_row(); } }); }, ); ui.add_space(2.0); } } fn popularity_color(pct: f32) -> egui::Color32 { if pct >= 40.0 { egui::Color32::from_rgb(100, 230, 100) } else if pct >= 20.0 { egui::Color32::from_rgb(220, 220, 80) } else { egui::Color32::from_rgb(180, 180, 180) } }