96 lines
3.2 KiB
Rust
96 lines
3.2 KiB
Rust
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)
|
|
}
|
|
}
|