136 lines
3.6 KiB
Rust
136 lines
3.6 KiB
Rust
use anyhow::{bail, Result};
|
|
use engine::prelude::*;
|
|
use std::sync::Arc;
|
|
|
|
pub struct FittingResult {
|
|
pub fit: bool,
|
|
pub start: i32,
|
|
pub extent: u32,
|
|
}
|
|
|
|
pub struct Tooltip {
|
|
grid: Arc<Grid>,
|
|
gui: Arc<GuiBuilder>,
|
|
gui_handler: Arc<GuiHandler>,
|
|
}
|
|
|
|
impl Tooltip {
|
|
pub fn new(grid: Arc<Grid>, gui: Arc<GuiBuilder>, gui_handler: Arc<GuiHandler>) -> Self {
|
|
Self {
|
|
grid,
|
|
gui,
|
|
gui_handler,
|
|
}
|
|
}
|
|
|
|
pub fn enable(&self) -> Result<()> {
|
|
self.gui.enable()
|
|
}
|
|
|
|
pub fn check_fitting(&self) -> Result<(FittingResult, FittingResult)> {
|
|
if !self.grid.visible() {
|
|
bail!("enable item tooltip first");
|
|
}
|
|
|
|
let (x, y, w, h) = self.grid.position_extent();
|
|
|
|
Ok((
|
|
FittingResult {
|
|
fit: (x + w as i32) <= self.gui_handler.width() as i32,
|
|
start: x,
|
|
extent: w,
|
|
},
|
|
FittingResult {
|
|
fit: (y + h as i32) <= self.gui_handler.height() as i32,
|
|
start: y,
|
|
extent: h,
|
|
},
|
|
))
|
|
}
|
|
|
|
pub fn move_to(&self, x: i32, y: i32) -> Result<()> {
|
|
self.grid.change_position_unscaled(x, y)
|
|
}
|
|
|
|
pub fn position_extent(&self) -> (i32, i32, u32, u32) {
|
|
self.grid.position_extent()
|
|
}
|
|
|
|
pub fn perform_single_check(&self, x: i32, y: i32) -> Result<()> {
|
|
let (width_fitting, height_fitting) = self.check_fitting()?;
|
|
|
|
let mut width_shift = None;
|
|
let mut height_shift = None;
|
|
|
|
let gui_pos = self.position_extent();
|
|
|
|
if !width_fitting.fit {
|
|
width_shift = Some(x - gui_pos.2 as i32);
|
|
}
|
|
|
|
if !height_fitting.fit {
|
|
height_shift = Some(y - gui_pos.3 as i32);
|
|
}
|
|
|
|
if width_shift.is_some() || height_shift.is_some() {
|
|
self.move_to(
|
|
width_shift.unwrap_or(gui_pos.0),
|
|
height_shift.unwrap_or(gui_pos.1),
|
|
)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn perform_double_check(&self, other: &Self, x: i32, spacing: u32) -> Result<()> {
|
|
let (_left_width_fitting, left_height_fitting) = self.check_fitting()?;
|
|
let (right_width_fitting, right_height_fitting) = other.check_fitting()?;
|
|
|
|
let mut width_shift = None;
|
|
let mut height_shift = None;
|
|
|
|
let left_gui_pos = self.position_extent();
|
|
let right_gui_pos = other.position_extent();
|
|
|
|
if !right_width_fitting.fit {
|
|
width_shift = Some(x - right_gui_pos.2 as i32 - spacing as i32);
|
|
}
|
|
|
|
let window_height = self.gui_handler.height();
|
|
|
|
if !left_height_fitting.fit {
|
|
height_shift = Some(window_height as i32 - left_gui_pos.3 as i32 - spacing as i32);
|
|
}
|
|
|
|
if !right_height_fitting.fit {
|
|
let right = window_height as i32 - right_gui_pos.3 as i32 - spacing as i32;
|
|
|
|
match height_shift {
|
|
Some(current) => {
|
|
if current > right {
|
|
height_shift = Some(right);
|
|
}
|
|
}
|
|
None => {
|
|
height_shift = Some(right);
|
|
}
|
|
}
|
|
}
|
|
|
|
if width_shift.is_some() || height_shift.is_some() {
|
|
let width = width_shift.unwrap_or(right_gui_pos.0);
|
|
let height = height_shift.unwrap_or(right_gui_pos.1);
|
|
|
|
other.move_to(width, height)?;
|
|
self.move_to(width - spacing as i32 - left_gui_pos.2 as i32, height)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Into<Arc<GuiBuilder>> for Tooltip {
|
|
fn into(self) -> Arc<GuiBuilder> {
|
|
self.gui
|
|
}
|
|
}
|