Cooler tooltips
This commit is contained in:
parent
43adaee243
commit
a5d3adadeb
202
src/gui.rs
202
src/gui.rs
@ -185,17 +185,65 @@ fn draw_attribute(name: &str, attribute: &Attribute, y: i32, ctx: &mut Rltk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Tooltip {
|
||||||
|
lines: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tooltip {
|
||||||
|
fn new() -> Tooltip {
|
||||||
|
Tooltip { lines: Vec::new() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add<S: ToString>(&mut self, line: S) {
|
||||||
|
self.lines.push(line.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn width(&self) -> i32 {
|
||||||
|
let mut max = 0;
|
||||||
|
for s in self.lines.iter() {
|
||||||
|
if s.len() > max {
|
||||||
|
max = s.len();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
max as i32 + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn height(&self) -> i32 {
|
||||||
|
self.lines.len() as i32 + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self, ctx: &mut Rltk, x: i32, y: i32) {
|
||||||
|
let box_gray = RGB::from_hex("#999999").expect("Oops");
|
||||||
|
let light_gray = RGB::from_hex("#DDDDDD").expect("Oops");
|
||||||
|
let white = RGB::named(rltk::WHITE);
|
||||||
|
let black = RGB::named(rltk::BLACK);
|
||||||
|
|
||||||
|
ctx.draw_box(x, y, self.width() - 1, self.height() - 1, white, box_gray);
|
||||||
|
|
||||||
|
for (i, s) in self.lines.iter().enumerate() {
|
||||||
|
let col = if i == 0 { white } else { light_gray };
|
||||||
|
ctx.print_color(x + 1, y + i as i32 + 1, col, black, &s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
||||||
|
use rltk::to_cp437;
|
||||||
|
|
||||||
let (min_x, _max_x, min_y, _max_y) = camera::get_screen_bounds(ecs, ctx);
|
let (min_x, _max_x, min_y, _max_y) = camera::get_screen_bounds(ecs, ctx);
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
let names = ecs.read_storage::<Name>();
|
let names = ecs.read_storage::<Name>();
|
||||||
let positions = ecs.read_storage::<Position>();
|
let positions = ecs.read_storage::<Position>();
|
||||||
let hidden = ecs.read_storage::<Hidden>();
|
let hidden = ecs.read_storage::<Hidden>();
|
||||||
|
let attributes = ecs.read_storage::<Attributes>();
|
||||||
|
let pools = ecs.read_storage::<Pools>();
|
||||||
|
let entities = ecs.entities();
|
||||||
let mouse_pos = ctx.mouse_pos();
|
let mouse_pos = ctx.mouse_pos();
|
||||||
let mut mouse_map_pos = mouse_pos;
|
let mut mouse_map_pos = mouse_pos.clone();
|
||||||
mouse_map_pos.0 += min_x - 1;
|
mouse_map_pos.0 += min_x - 1;
|
||||||
mouse_map_pos.1 += min_y - 1;
|
mouse_map_pos.1 += min_y - 1;
|
||||||
|
|
||||||
if mouse_map_pos.0 >= map.width - 1
|
if mouse_map_pos.0 >= map.width - 1
|
||||||
|| mouse_map_pos.1 >= map.height - 1
|
|| mouse_map_pos.1 >= map.height - 1
|
||||||
|| mouse_map_pos.0 < 1
|
|| mouse_map_pos.0 < 1
|
||||||
@ -208,92 +256,94 @@ fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tooltip: Vec<String> = Vec::new();
|
let mut tip_boxes: Vec<Tooltip> = Vec::new();
|
||||||
|
for (entity, name, position, _hidden) in (&entities, &names, &positions, !&hidden).join() {
|
||||||
for (name, position, _hidden) in (&names, &positions, !&hidden).join() {
|
|
||||||
if position.x == mouse_map_pos.0 && position.y == mouse_map_pos.1 {
|
if position.x == mouse_map_pos.0 && position.y == mouse_map_pos.1 {
|
||||||
tooltip.push(name.name.to_string());
|
let mut tip = Tooltip::new();
|
||||||
|
tip.add(name.name.to_string());
|
||||||
|
|
||||||
|
// Comment on attributes
|
||||||
|
if let Some(attr) = attributes.get(entity) {
|
||||||
|
let mut s = String::new();
|
||||||
|
if attr.might.bonus < 0 {
|
||||||
|
s += "Weak. "
|
||||||
|
} else if attr.might.bonus > 0 {
|
||||||
|
s += "String. "
|
||||||
|
}
|
||||||
|
|
||||||
|
if attr.quickness.bonus < 0 {
|
||||||
|
s += "Clumsy. "
|
||||||
|
} else if attr.quickness.bonus > 0 {
|
||||||
|
s += "Agile. "
|
||||||
|
}
|
||||||
|
|
||||||
|
if attr.fitness.bonus < 0 {
|
||||||
|
s += "Unhealthy. "
|
||||||
|
} else if attr.fitness.bonus > 0 {
|
||||||
|
s += "Healthy. "
|
||||||
|
}
|
||||||
|
|
||||||
|
if attr.intelligence.bonus < 0 {
|
||||||
|
s += "Unintelligent. "
|
||||||
|
} else if attr.intelligence.bonus > 0 {
|
||||||
|
s += "Smart. "
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.is_empty() {
|
||||||
|
s = "Quite Average".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
tip.add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment on pools
|
||||||
|
if let Some(stat) = pools.get(entity) {
|
||||||
|
tip.add(format!("Level: {}", stat.level));
|
||||||
|
}
|
||||||
|
|
||||||
|
tip_boxes.push(tip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tooltip.is_empty() {
|
if tip_boxes.is_empty() {
|
||||||
let mut width: i32 = 0;
|
return;
|
||||||
for s in tooltip.iter() {
|
|
||||||
if width < s.len() as i32 {
|
|
||||||
width = s.len() as i32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
width += 3;
|
|
||||||
|
|
||||||
if mouse_pos.0 > 40 {
|
|
||||||
let arrow_pos = Point::new(mouse_pos.0 - 2, mouse_pos.1);
|
|
||||||
let left_x = mouse_pos.0 - width;
|
|
||||||
let mut y = mouse_pos.1;
|
|
||||||
|
|
||||||
for s in tooltip.iter() {
|
|
||||||
ctx.print_color(
|
|
||||||
left_x,
|
|
||||||
y,
|
|
||||||
RGB::named(rltk::WHITE),
|
|
||||||
RGB::named(rltk::GREY),
|
|
||||||
s,
|
|
||||||
);
|
|
||||||
let padding = (width - s.len() as i32) - 1;
|
|
||||||
for i in 0..padding {
|
|
||||||
ctx.print_color(
|
|
||||||
arrow_pos.x - i,
|
|
||||||
y,
|
|
||||||
RGB::named(rltk::WHITE),
|
|
||||||
RGB::named(rltk::GREY),
|
|
||||||
&" ".to_string(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
y += 1;
|
let box_gray = RGB::from_hex("#999999").expect("Oops");
|
||||||
}
|
let white = RGB::named(rltk::WHITE);
|
||||||
|
|
||||||
ctx.print_color(
|
let arrow;
|
||||||
arrow_pos.x,
|
let arrow_x;
|
||||||
arrow_pos.y,
|
let arrow_y = mouse_pos.1;
|
||||||
RGB::named(rltk::WHITE),
|
if mouse_pos.0 < 40 {
|
||||||
RGB::named(rltk::GREY),
|
// Render to the left
|
||||||
&"->".to_string(),
|
arrow = to_cp437('→');
|
||||||
);
|
arrow_x = mouse_pos.0 - 1;
|
||||||
} else {
|
} else {
|
||||||
let arrow_pos = Point::new(mouse_pos.0 + 1, mouse_pos.1);
|
// Render to the right
|
||||||
let left_x = mouse_pos.0 + 3;
|
arrow = to_cp437('←');
|
||||||
let mut y = mouse_pos.1;
|
arrow_x = mouse_pos.0 + 1;
|
||||||
|
|
||||||
for s in tooltip.iter() {
|
|
||||||
ctx.print_color(
|
|
||||||
left_x + 1,
|
|
||||||
y,
|
|
||||||
RGB::named(rltk::WHITE),
|
|
||||||
RGB::named(rltk::GREY),
|
|
||||||
s,
|
|
||||||
);
|
|
||||||
|
|
||||||
let padding = (width - s.len() as i32) - 1;
|
|
||||||
for i in 0..padding {
|
|
||||||
ctx.print_color(
|
|
||||||
arrow_pos.x + 1 + i,
|
|
||||||
y,
|
|
||||||
RGB::named(rltk::WHITE),
|
|
||||||
RGB::named(rltk::GREY),
|
|
||||||
&" ".to_string(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
y += 1;
|
ctx.set(arrow_x, arrow_y, white, box_gray, arrow);
|
||||||
|
|
||||||
|
let mut total_height = 0;
|
||||||
|
for tt in tip_boxes.iter() {
|
||||||
|
total_height += tt.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.print_color(
|
let mut y = mouse_pos.1 - (total_height / 2);
|
||||||
arrow_pos.x,
|
while y + (total_height / 2) > 50 {
|
||||||
arrow_pos.y,
|
y -= 1;
|
||||||
RGB::named(rltk::WHITE),
|
|
||||||
RGB::named(rltk::GREY),
|
|
||||||
&"<-".to_string(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for tt in tip_boxes.iter() {
|
||||||
|
let x = if mouse_pos.0 < 40 {
|
||||||
|
mouse_pos.0 - (1 + tt.width())
|
||||||
|
} else {
|
||||||
|
mouse_pos.0 + (1 + tt.width())
|
||||||
|
};
|
||||||
|
tt.render(ctx, x, y);
|
||||||
|
y += tt.height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user