Make item tooltip accept multiple items for salvage

This commit is contained in:
Snowram 2021-10-14 02:00:45 +02:00 committed by Sam
parent e28ca15059
commit 2bf16aab63
7 changed files with 92 additions and 66 deletions

View File

@ -21,7 +21,7 @@ use common::{
combat::{combat_rating, Damage}, combat::{combat_rating, Damage},
comp::{ comp::{
inventory::InventorySortOrder, inventory::InventorySortOrder,
item::{ItemDef, MaterialStatManifest, Quality}, item::{Item, ItemDef, ItemDesc, MaterialStatManifest, Quality},
Body, Energy, Health, Inventory, Poise, SkillSet, Stats, Body, Energy, Health, Inventory, Poise, SkillSet, Stats,
}, },
}; };
@ -383,6 +383,20 @@ impl<'a> InventoryScroller<'a> {
.as_ref() .as_ref()
.and_then(|(_, _, prices)| prices.clone()); .and_then(|(_, _, prices)| prices.clone());
let salvage_result: Vec<Item> = item
.salvage_output()
.map(|asset| Item::new_from_asset_expect(asset))
.collect();
let item: Vec<&dyn ItemDesc> = if self.show_salvage {
salvage_result
.iter()
.map(|item| item as &dyn ItemDesc)
.collect()
} else {
vec![item]
};
slot_widget slot_widget
.filled_slot(quality_col_img) .filled_slot(quality_col_img)
.with_item_tooltip( .with_item_tooltip(
@ -851,7 +865,7 @@ impl<'a> Widget for Bag<'a> {
if let Some(item) = inventory.equipped($slot) { if let Some(item) = inventory.equipped($slot) {
let manager = &mut *self.item_tooltip_manager; let manager = &mut *self.item_tooltip_manager;
$slot_maker $slot_maker
.with_item_tooltip(manager, item, &None, &item_tooltip) .with_item_tooltip(manager, vec![item], &None, &item_tooltip)
.set($slot_id, ui) .set($slot_id, ui)
} else { } else {
let manager = &mut *self.tooltip_manager; let manager = &mut *self.tooltip_manager;

View File

@ -724,7 +724,7 @@ impl<'a> Widget for Crafting<'a> {
.middle_of(state.ids.output_img_frame) .middle_of(state.ids.output_img_frame)
.with_item_tooltip( .with_item_tooltip(
self.item_tooltip_manager, self.item_tooltip_manager,
&*recipe.output.0, vec![&*recipe.output.0],
&None, &None,
&item_tooltip, &item_tooltip,
) )
@ -953,7 +953,7 @@ impl<'a> Widget for Crafting<'a> {
.w_h(22.0, 22.0) .w_h(22.0, 22.0)
.middle_of(state.ids.ingredient_frame[i]) .middle_of(state.ids.ingredient_frame[i])
.hover_image(self.imgs.wpn_icon_border_mo) .hover_image(self.imgs.wpn_icon_border_mo)
.with_item_tooltip(self.item_tooltip_manager, &*item_def, &None, &item_tooltip) .with_item_tooltip(self.item_tooltip_manager, vec![&*item_def], &None, &item_tooltip)
.set(state.ids.ingredient_btn[i], ui) .set(state.ids.ingredient_btn[i], ui)
.was_clicked() .was_clicked()
{ {
@ -968,6 +968,12 @@ impl<'a> Widget for Crafting<'a> {
.middle_of(state.ids.ingredient_btn[i]) .middle_of(state.ids.ingredient_btn[i])
.w_h(20.0, 20.0) .w_h(20.0, 20.0)
.graphics_for(state.ids.ingredient_btn[i]) .graphics_for(state.ids.ingredient_btn[i])
.with_item_tooltip(
self.item_tooltip_manager,
vec![&*item_def],
&None,
&item_tooltip,
)
.set(state.ids.ingredient_img[i], ui); .set(state.ids.ingredient_img[i], ui);
// Ingredients text and amount // Ingredients text and amount

View File

@ -333,7 +333,12 @@ impl<'a> Widget for LootScroller<'a> {
.color(Some(shade_color(color::hsla(0.0, 0.0, 1.0, 1.0)))) .color(Some(shade_color(color::hsla(0.0, 0.0, 1.0, 1.0))))
.w_h(ICON_SIZE, ICON_SIZE) .w_h(ICON_SIZE, ICON_SIZE)
.middle_of(state.ids.message_icon_bgs[i]) .middle_of(state.ids.message_icon_bgs[i])
.with_item_tooltip(self.item_tooltip_manager, &**item, &None, &item_tooltip) .with_item_tooltip(
self.item_tooltip_manager,
vec![&**item],
&None,
&item_tooltip,
)
.set(state.ids.message_icons[i], ui); .set(state.ids.message_icons[i], ui);
let label = if *amount == 1 { let label = if *amount == 1 {

View File

@ -645,7 +645,7 @@ impl<'a> Skillbar<'a> {
.position(entry.position); .position(entry.position);
// if there is an item attached, show item tooltip // if there is an item attached, show item tooltip
if let Some(item) = slot_content(entry.slot) { if let Some(item) = slot_content(entry.slot) {
slot.with_item_tooltip(self.item_tooltip_manager, item, &None, &item_tooltip) slot.with_item_tooltip(self.item_tooltip_manager, vec![item], &None, &item_tooltip)
.set(entry.widget_id, ui); .set(entry.widget_id, ui);
// if we can gather some text to display, show it // if we can gather some text to display, show it
} else if let Some((title, desc)) = tooltip_text(entry.slot) { } else if let Some((title, desc)) = tooltip_text(entry.slot) {

View File

@ -393,7 +393,7 @@ impl<'a> Trade<'a> {
slot_widget slot_widget
.filled_slot(quality_col_img) .filled_slot(quality_col_img)
.with_item_tooltip(self.item_tooltip_manager, item, prices, &item_tooltip) .with_item_tooltip(self.item_tooltip_manager, vec![item], prices, &item_tooltip)
.set(slot_id, ui); .set(slot_id, ui);
} else { } else {
slot_widget.set(slot_id, ui); slot_widget.set(slot_id, ui);

View File

@ -157,7 +157,6 @@ impl Ui {
ui.set_num_redraw_frames(1); ui.set_num_redraw_frames(1);
let item_tooltip_manager = ItemTooltipManager::new( let item_tooltip_manager = ItemTooltipManager::new(
ui.widget_id_generator(),
Duration::from_millis(1), Duration::from_millis(1),
Duration::from_millis(0), Duration::from_millis(0),
scale.scale_factor_logical(), scale.scale_factor_logical(),

View File

@ -40,7 +40,6 @@ enum HoverState {
const MOUSE_PAD_Y: f64 = 15.0; const MOUSE_PAD_Y: f64 = 15.0;
pub struct ItemTooltipManager { pub struct ItemTooltipManager {
tooltip_id: widget::Id,
state: HoverState, state: HoverState,
// How long before a tooltip is displayed when hovering // How long before a tooltip is displayed when hovering
hover_dur: Duration, hover_dur: Duration,
@ -51,14 +50,8 @@ pub struct ItemTooltipManager {
} }
impl ItemTooltipManager { impl ItemTooltipManager {
pub fn new( pub fn new(hover_dur: Duration, fade_dur: Duration, logical_scale_factor: f64) -> Self {
mut generator: widget::id::Generator,
hover_dur: Duration,
fade_dur: Duration,
logical_scale_factor: f64,
) -> Self {
Self { Self {
tooltip_id: generator.next(),
state: HoverState::None, state: HoverState::None,
hover_dur, hover_dur,
fade_dur, fade_dur,
@ -115,63 +108,72 @@ impl ItemTooltipManager {
fn set_tooltip( fn set_tooltip(
&mut self, &mut self,
tooltip: &ItemTooltip, tooltip: &ItemTooltip,
item: &dyn ItemDesc, items: Vec<&dyn ItemDesc>,
prices: &Option<SitePrices>, prices: &Option<SitePrices>,
img_id: Option<image::Id>, img_id: Option<image::Id>,
image_dims: Option<(f64, f64)>, image_dims: Option<(f64, f64)>,
src_id: widget::Id, src_id: widget::Id,
ui: &mut UiCell, ui: &mut UiCell,
) { ) {
let tooltip_id = self.tooltip_id; let mut y_offset = 0.0;
let mp_h = MOUSE_PAD_Y / self.logical_scale_factor; let mp_h = MOUSE_PAD_Y / self.logical_scale_factor;
for item in items {
let tooltip_id = ui.widget_id_generator().next();
let tooltip = |transparency, mouse_pos: [f64; 2], ui: &mut UiCell| { let mut tooltip = |transparency, mouse_pos: [f64; 2], ui: &mut UiCell| {
// Fill in text and the potential image beforehand to get an accurate size for // Fill in text and the potential image beforehand to get an accurate size for
// spacing // spacing
let tooltip = tooltip let tooltip = tooltip
.clone() .clone()
.item(item) .item(item)
.prices(prices) .prices(prices)
.image(img_id) .image(img_id)
.image_dims(image_dims); .image_dims(image_dims);
let [t_w, t_h] = tooltip.get_wh(ui).unwrap_or([0.0, 0.0]); let [t_w, t_h] = tooltip.get_wh(ui).unwrap_or([0.0, 0.0]);
let [m_x, m_y] = [mouse_pos[0], mouse_pos[1]]; let [m_x, m_y] = [mouse_pos[0], mouse_pos[1]];
let (w_w, w_h) = (ui.win_w, ui.win_h); let (w_w, w_h) = (ui.win_w, ui.win_h);
// Determine position based on size and mouse position // Determine position based on size and mouse position
// Flow to the top left of the mouse when there is space // Flow to the top left of the mouse when there is space
let x = if (m_x + w_w / 2.0) > t_w { let x = if (m_x + w_w / 2.0) > t_w {
m_x - t_w / 2.0 m_x - t_w / 2.0
} else { } else {
m_x + t_w / 2.0 m_x + t_w / 2.0
};
let y = if w_h - (m_y + w_h / 2.0) > t_h + mp_h {
m_y + mp_h + t_h / 2.0
} else {
m_y - mp_h - t_h / 2.0
};
tooltip
.floating(true)
.transparency(transparency)
.x_y(x, y + y_offset)
.set(tooltip_id, ui);
// Increase the offset to stack the next tooltip on top of the previous one
y_offset += t_h + 5.0;
}; };
let y = if w_h - (m_y + w_h / 2.0) > t_h + mp_h {
m_y + mp_h + t_h / 2.0
} else {
m_y - mp_h - t_h / 2.0
};
tooltip
.floating(true)
.transparency(transparency)
.x_y(x, y)
.set(tooltip_id, ui);
};
match self.state { match self.state {
HoverState::Hovering(Hover(id, xy)) if id == src_id => tooltip(1.0, xy, ui), HoverState::Hovering(Hover(id, xy)) if id == src_id => tooltip(1.0, xy, ui),
HoverState::Fading(start, Hover(id, xy), _) if id == src_id => tooltip( HoverState::Fading(start, Hover(id, xy), _) if id == src_id => tooltip(
(0.1f32 - start.elapsed().as_millis() as f32 / self.hover_dur.as_millis() as f32) (0.1f32
.max(0.0), - start.elapsed().as_millis() as f32 / self.hover_dur.as_millis() as f32)
xy, .max(0.0),
ui, xy,
), ui,
HoverState::Start(start, id) if id == src_id && start.elapsed() > self.hover_dur => { ),
let xy = ui.global_input().current.mouse.xy; HoverState::Start(start, id)
self.state = HoverState::Hovering(Hover(id, xy)); if id == src_id && start.elapsed() > self.hover_dur =>
tooltip(1.0, xy, ui); {
}, let xy = ui.global_input().current.mouse.xy;
_ => (), self.state = HoverState::Hovering(Hover(id, xy));
tooltip(1.0, xy, ui);
}
_ => (),
}
} }
} }
} }
@ -180,7 +182,7 @@ pub struct ItemTooltipped<'a, W> {
inner: W, inner: W,
tooltip_manager: &'a mut ItemTooltipManager, tooltip_manager: &'a mut ItemTooltipManager,
item: &'a dyn ItemDesc, items: Vec<&'a dyn ItemDesc>,
prices: &'a Option<SitePrices>, prices: &'a Option<SitePrices>,
img_id: Option<image::Id>, img_id: Option<image::Id>,
image_dims: Option<(f64, f64)>, image_dims: Option<(f64, f64)>,
@ -201,7 +203,7 @@ impl<'a, W: Widget> ItemTooltipped<'a, W> {
let event = self.inner.set(id, ui); let event = self.inner.set(id, ui);
self.tooltip_manager.set_tooltip( self.tooltip_manager.set_tooltip(
self.tooltip, self.tooltip,
self.item, self.items,
self.prices, self.prices,
self.img_id, self.img_id,
self.image_dims, self.image_dims,
@ -218,7 +220,7 @@ pub trait ItemTooltipable {
self, self,
tooltip_manager: &'a mut ItemTooltipManager, tooltip_manager: &'a mut ItemTooltipManager,
item: &'a dyn ItemDesc, items: Vec<&'a dyn ItemDesc>,
prices: &'a Option<SitePrices>, prices: &'a Option<SitePrices>,
@ -231,14 +233,14 @@ impl<W: Widget> ItemTooltipable for W {
fn with_item_tooltip<'a>( fn with_item_tooltip<'a>(
self, self,
tooltip_manager: &'a mut ItemTooltipManager, tooltip_manager: &'a mut ItemTooltipManager,
item: &'a dyn ItemDesc, items: Vec<&'a dyn ItemDesc>,
prices: &'a Option<SitePrices>, prices: &'a Option<SitePrices>,
tooltip: &'a ItemTooltip<'a>, tooltip: &'a ItemTooltip<'a>,
) -> ItemTooltipped<'a, W> { ) -> ItemTooltipped<'a, W> {
ItemTooltipped { ItemTooltipped {
inner: self, inner: self,
tooltip_manager, tooltip_manager,
item, items,
prices, prices,
img_id: None, img_id: None,
image_dims: None, image_dims: None,