mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
WIP: added backgrounds for quality
This commit is contained in:
parent
0640662e49
commit
d3c1ce27e1
@ -7,8 +7,8 @@ use super::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
i18n::Localization,
|
i18n::Localization,
|
||||||
ui::{
|
ui::{
|
||||||
fonts::Fonts, ImageFrame, ItemTooltip, ItemTooltipManager, ItemTooltipable, OutlinedText,
|
fonts::Fonts, ImageFrame, ItemTooltip, ItemTooltipManager, ItemTooltipable, Tooltip,
|
||||||
Tooltip, TooltipManager, Tooltipable,
|
TooltipManager, Tooltipable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use client::{self, Client};
|
use client::{self, Client};
|
||||||
@ -44,6 +44,9 @@ widget_ids! {
|
|||||||
title_main,
|
title_main,
|
||||||
title_rec,
|
title_rec,
|
||||||
align_rec,
|
align_rec,
|
||||||
|
align_rec_craftable,
|
||||||
|
align_rec_partial,
|
||||||
|
align_rec_uncraftable,
|
||||||
scrollbar_rec,
|
scrollbar_rec,
|
||||||
btn_open_search,
|
btn_open_search,
|
||||||
btn_close_search,
|
btn_close_search,
|
||||||
@ -55,8 +58,9 @@ widget_ids! {
|
|||||||
align_ing,
|
align_ing,
|
||||||
scrollbar_ing,
|
scrollbar_ing,
|
||||||
btn_craft,
|
btn_craft,
|
||||||
recipe_name_btns[],
|
recipe_names_craftable[],
|
||||||
recipe_name_texts[],
|
recipe_names_partial[],
|
||||||
|
recipe_names_uncraftable[],
|
||||||
recipe_img_frame[],
|
recipe_img_frame[],
|
||||||
recipe_img[],
|
recipe_img[],
|
||||||
ingredients[],
|
ingredients[],
|
||||||
@ -203,13 +207,6 @@ impl CraftingTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// First available recipes, then unavailable ones, each alphabetically
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
enum RecipeIngredientQuantity {
|
|
||||||
All,
|
|
||||||
Some,
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
ids: Ids,
|
ids: Ids,
|
||||||
@ -287,16 +284,6 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
.color(Some(UI_MAIN))
|
.color(Some(UI_MAIN))
|
||||||
.w_h(422.0, 460.0)
|
.w_h(422.0, 460.0)
|
||||||
.set(state.ids.window, ui);
|
.set(state.ids.window, ui);
|
||||||
// Search Background
|
|
||||||
// I couldn't find a way to manually set they layer of a widget
|
|
||||||
// If it is possible, please move this code (for rectangle) down to the code for
|
|
||||||
// search input
|
|
||||||
if self.show.crafting_search_key.is_some() {
|
|
||||||
Rectangle::fill([114.0, 20.0])
|
|
||||||
.top_left_with_margins_on(state.ids.window, 52.0, 26.0)
|
|
||||||
.hsla(0.0, 0.0, 0.0, 0.7)
|
|
||||||
.set(state.ids.input_bg_search, ui);
|
|
||||||
}
|
|
||||||
// Window
|
// Window
|
||||||
Image::new(self.imgs.crafting_frame)
|
Image::new(self.imgs.crafting_frame)
|
||||||
.middle_of(state.ids.window)
|
.middle_of(state.ids.window)
|
||||||
@ -416,7 +403,16 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
.set(state.ids.category_imgs[i], ui);
|
.set(state.ids.category_imgs[i], ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ordered_recipes: Vec<_> = self
|
// First available recipes, then unavailable ones, then by quality, then
|
||||||
|
// alphabetically In the pairs, "name" is the recipe book key, and
|
||||||
|
// "recipe.output.0.name()" is the display name (as stored in the item
|
||||||
|
// descriptors)
|
||||||
|
|
||||||
|
let mut craftable_recipes = Vec::new();
|
||||||
|
let mut partial_recipes = Vec::new();
|
||||||
|
let mut uncraftable_recipes = Vec::new();
|
||||||
|
|
||||||
|
for (name, recipe) in self
|
||||||
.client
|
.client
|
||||||
.recipe_book()
|
.recipe_book()
|
||||||
.iter()
|
.iter()
|
||||||
@ -431,7 +427,8 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|(name, recipe)| {
|
.filter(|(_, recipe)| self.show.crafting_tab.satisfies(recipe.output.0.as_ref()))
|
||||||
|
{
|
||||||
let at_least_some_ingredients = recipe.inputs.iter().any(|(input, amount)| {
|
let at_least_some_ingredients = recipe.inputs.iter().any(|(input, amount)| {
|
||||||
*amount > 0
|
*amount > 0
|
||||||
&& self.inventory.slots().any(|slot| {
|
&& self.inventory.slots().any(|slot| {
|
||||||
@ -449,102 +446,180 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
Some(cs) == self.show.craft_sprite.map(|(_, s)| s)
|
Some(cs) == self.show.craft_sprite.map(|(_, s)| s)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
let state = if show_craft_sprite {
|
|
||||||
RecipeIngredientQuantity::All
|
if show_craft_sprite {
|
||||||
|
craftable_recipes.push((name, recipe));
|
||||||
} else if at_least_some_ingredients {
|
} else if at_least_some_ingredients {
|
||||||
RecipeIngredientQuantity::Some
|
partial_recipes.push((name, recipe));
|
||||||
} else {
|
} else {
|
||||||
RecipeIngredientQuantity::None
|
uncraftable_recipes.push((name, recipe));
|
||||||
};
|
}
|
||||||
// (name, recipe, state)
|
}
|
||||||
(name, recipe, match tweak!(1) {
|
|
||||||
0 => RecipeIngredientQuantity::All,
|
craftable_recipes
|
||||||
1 => RecipeIngredientQuantity::Some,
|
.sort_by_key(|(_, recipe)| (recipe.output.0.quality, recipe.output.0.name()));
|
||||||
_ => RecipeIngredientQuantity::None,
|
partial_recipes
|
||||||
})
|
.sort_by_key(|(_, recipe)| (recipe.output.0.quality, recipe.output.0.name()));
|
||||||
})
|
uncraftable_recipes
|
||||||
.collect();
|
.sort_by_key(|(_, recipe)| (recipe.output.0.quality, recipe.output.0.name()));
|
||||||
ordered_recipes.sort_by_key(|(_, recipe, state)| {
|
|
||||||
(*state, recipe.output.0.quality, recipe.output.0.name())
|
// let n_craftable_recipies = ordered_recipes.into_iter(||)
|
||||||
});
|
// let (craftable_recipes, _uncraftable_recipes) =
|
||||||
|
// ordered_recipes.into_iter().partition( |(_, _, quantity)|
|
||||||
|
// quantity == &RecipeIngredientQuantity::All );
|
||||||
|
// let (partial_recipes, uncraftable_recipes) = _uncraftable_recipes.partition(
|
||||||
|
// |(_, _, quantity)| quantity == &RecipeIngredientQuantity::Some
|
||||||
|
// );
|
||||||
|
|
||||||
|
// let craftable_recipes: Vec<_> = craftable_recipes.collect();
|
||||||
|
// let partial_recipes: Vec<_> = partial_recipes.collect();
|
||||||
|
// let uncraftable_recipes: Vec<_> = uncraftable_recipes.collect();
|
||||||
|
// let partial_recipes: Vec<_> =
|
||||||
|
// ordered_recipes.into_iter().filter(|(_, _, quantity)| quantity ==
|
||||||
|
// &RecipeIngredientQuantity::Some).collect(); let uncraftable_recipes:
|
||||||
|
// Vec<_> = ordered_recipes.into_iter().filter(|(_, _, quantity)|
|
||||||
|
// quantity == &RecipeIngredientQuantity::None).collect();
|
||||||
|
|
||||||
// Recipe list
|
// Recipe list
|
||||||
if state.ids.recipe_name_btns.len() < self.client.recipe_book().iter().len() {
|
if state.ids.recipe_names_craftable.len() < craftable_recipes.len() {
|
||||||
state.update(|state| {
|
state.update(|state| {
|
||||||
state.ids.recipe_name_btns.resize(
|
state
|
||||||
self.client.recipe_book().iter().len(),
|
.ids
|
||||||
&mut ui.widget_id_generator(),
|
.recipe_names_craftable
|
||||||
)
|
.resize(craftable_recipes.len(), &mut ui.widget_id_generator())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if state.ids.recipe_name_texts.len() < self.client.recipe_book().iter().len() {
|
if state.ids.recipe_names_partial.len() < partial_recipes.len() {
|
||||||
state.update(|state| {
|
state.update(|state| {
|
||||||
state.ids.recipe_name_texts.resize(
|
state
|
||||||
self.client.recipe_book().iter().len(),
|
.ids
|
||||||
&mut ui.widget_id_generator(),
|
.recipe_names_partial
|
||||||
)
|
.resize(partial_recipes.len(), &mut ui.widget_id_generator())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (i, (name, recipe, quantity)) in ordered_recipes
|
if state.ids.recipe_names_uncraftable.len() < uncraftable_recipes.len() {
|
||||||
.into_iter()
|
state.update(|state| {
|
||||||
.filter(|(_, recipe, _)| self.show.crafting_tab.satisfies(recipe.output.0.as_ref()))
|
state
|
||||||
.enumerate()
|
.ids
|
||||||
{
|
.recipe_names_uncraftable
|
||||||
let button = Button::image(
|
.resize(uncraftable_recipes.len(), &mut ui.widget_id_generator())
|
||||||
if state
|
});
|
||||||
.selected_recipe
|
}
|
||||||
.as_ref()
|
|
||||||
.map(|s| s != name)
|
//create alignments
|
||||||
.unwrap_or(false)
|
Rectangle::fill_with(
|
||||||
{
|
[130.0, 25.0 * craftable_recipes.len() as f64],
|
||||||
|
color::hsla(0.0, 0.0, 0.0, 0.0),
|
||||||
|
)
|
||||||
|
.mid_top_with_margin_on(state.ids.align_rec, 0.0)
|
||||||
|
.set(state.ids.align_rec_craftable, ui);
|
||||||
|
Rectangle::fill_with(
|
||||||
|
[130.0, 25.0 * partial_recipes.len() as f64],
|
||||||
|
TEXT_GRAY_COLOR.alpha(tweak!(0.1)),
|
||||||
|
)
|
||||||
|
.down_from(state.ids.align_rec_craftable, 0.0)
|
||||||
|
.set(state.ids.align_rec_partial, ui);
|
||||||
|
Rectangle::fill_with(
|
||||||
|
[130.0, 25.0 * uncraftable_recipes.len() as f64],
|
||||||
|
TEXT_DULL_RED_COLOR.alpha(tweak!(0.1)),
|
||||||
|
)
|
||||||
|
.down_from(state.ids.align_rec_partial, 0.0)
|
||||||
|
.set(state.ids.align_rec_uncraftable, ui);
|
||||||
|
|
||||||
|
for (i, (name, recipe)) in craftable_recipes.into_iter().enumerate() {
|
||||||
|
let button = Button::image(if state.selected_recipe.as_ref() == Some(name) {
|
||||||
|
self.imgs.selection
|
||||||
|
} else {
|
||||||
self.imgs.nothing
|
self.imgs.nothing
|
||||||
|
})
|
||||||
|
.and(|button| {
|
||||||
|
if i == 0 {
|
||||||
|
button.mid_top_with_margin_on(state.ids.align_rec_craftable, 2.0)
|
||||||
} else {
|
} else {
|
||||||
match state.selected_recipe {
|
button.down_from(state.ids.recipe_names_craftable[i - 1], 5.0)
|
||||||
None => self.imgs.nothing,
|
|
||||||
Some(_) => self.imgs.selection,
|
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
);
|
.label(recipe.output.0.name())
|
||||||
// Recipe Button
|
|
||||||
let button = if i == 0 {
|
|
||||||
button.mid_top_with_margin_on(state.ids.align_rec, 2.0)
|
|
||||||
} else {
|
|
||||||
button.mid_bottom_with_margin_on(state.ids.recipe_name_btns[i - 1], -25.0)
|
|
||||||
};
|
|
||||||
let text_color = get_quality_col(&*recipe.output.0);
|
|
||||||
let outline_color = match quantity {
|
|
||||||
RecipeIngredientQuantity::All => TEXT_COLOR,
|
|
||||||
RecipeIngredientQuantity::Some => TEXT_GRAY_COLOR,
|
|
||||||
RecipeIngredientQuantity::None => TEXT_DULL_RED_COLOR,
|
|
||||||
};
|
|
||||||
if button
|
|
||||||
.w_h(130.0, 20.0)
|
.w_h(130.0, 20.0)
|
||||||
.hover_image(self.imgs.selection_hover)
|
.hover_image(self.imgs.selection_hover)
|
||||||
.press_image(self.imgs.selection_press)
|
.press_image(self.imgs.selection_press)
|
||||||
.set(state.ids.recipe_name_btns[i], ui)
|
.label_color(get_quality_col(recipe.output.0.as_ref()))
|
||||||
.was_clicked()
|
.label_font_size(self.fonts.cyri.scale(12))
|
||||||
{
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
if state
|
.label_y(conrod_core::position::Relative::Scalar(2.0))
|
||||||
.selected_recipe
|
.set(state.ids.recipe_names_craftable[i], ui);
|
||||||
.as_ref()
|
|
||||||
.map(|s| s == name)
|
if button.was_clicked() {
|
||||||
.unwrap_or(false)
|
if state.selected_recipe.as_ref() == Some(name) {
|
||||||
{
|
state.update(|s| s.selected_recipe = None);
|
||||||
|
} else {
|
||||||
|
state.update(|s| s.selected_recipe = Some(name.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i, (name, recipe)) in partial_recipes.into_iter().enumerate() {
|
||||||
|
let button = Button::image(if state.selected_recipe.as_ref() == Some(name) {
|
||||||
|
self.imgs.selection
|
||||||
|
} else {
|
||||||
|
self.imgs.nothing
|
||||||
|
})
|
||||||
|
.and(|button| {
|
||||||
|
if i == 0 {
|
||||||
|
button.mid_top_with_margin_on(state.ids.align_rec_partial, 2.0)
|
||||||
|
} else {
|
||||||
|
button.down_from(state.ids.recipe_names_partial[i - 1], 5.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// .image_color(TEXT_GRAY_COLOR)
|
||||||
|
.label(recipe.output.0.name())
|
||||||
|
.w_h(130.0, 20.0)
|
||||||
|
.hover_image(self.imgs.selection_hover)
|
||||||
|
.press_image(self.imgs.selection_press)
|
||||||
|
.label_color(get_quality_col(recipe.output.0.as_ref()))
|
||||||
|
.label_font_size(self.fonts.cyri.scale(12))
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_y(conrod_core::position::Relative::Scalar(2.0))
|
||||||
|
.set(state.ids.recipe_names_partial[i], ui);
|
||||||
|
|
||||||
|
if button.was_clicked() {
|
||||||
|
if state.selected_recipe.as_ref() == Some(name) {
|
||||||
|
state.update(|s| s.selected_recipe = None);
|
||||||
|
} else {
|
||||||
|
state.update(|s| s.selected_recipe = Some(name.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i, (name, recipe)) in uncraftable_recipes.into_iter().enumerate() {
|
||||||
|
let button = Button::image(if state.selected_recipe.as_ref() == Some(name) {
|
||||||
|
self.imgs.selection
|
||||||
|
} else {
|
||||||
|
self.imgs.nothing
|
||||||
|
})
|
||||||
|
.and(|button| {
|
||||||
|
if i == 0 {
|
||||||
|
button.mid_top_with_margin_on(state.ids.align_rec_uncraftable, 2.0)
|
||||||
|
} else {
|
||||||
|
button.down_from(state.ids.recipe_names_uncraftable[i - 1], 5.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// .image_color(TEXT_DULL_RED_COLOR)
|
||||||
|
.label(recipe.output.0.name())
|
||||||
|
.w_h(130.0, 20.0)
|
||||||
|
.hover_image(self.imgs.selection_hover)
|
||||||
|
.press_image(self.imgs.selection_press)
|
||||||
|
.label_color(get_quality_col(recipe.output.0.as_ref()))
|
||||||
|
.label_font_size(self.fonts.cyri.scale(12))
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_y(conrod_core::position::Relative::Scalar(2.0))
|
||||||
|
.set(state.ids.recipe_names_uncraftable[i], ui);
|
||||||
|
|
||||||
|
if button.was_clicked() {
|
||||||
|
if state.selected_recipe.as_ref() == Some(name) {
|
||||||
state.update(|s| s.selected_recipe = None);
|
state.update(|s| s.selected_recipe = None);
|
||||||
} else {
|
} else {
|
||||||
state.update(|s| s.selected_recipe = Some(name.clone()));
|
state.update(|s| s.selected_recipe = Some(name.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OutlinedText::new(recipe.output.0.name())
|
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
|
||||||
.font_size(self.fonts.cyri.scale(12))
|
|
||||||
.color(text_color)
|
|
||||||
.outline_width(tweak!(0.5))
|
|
||||||
.outline_color(outline_color)
|
|
||||||
.w_h(tweak!(100.0), tweak!(20.0))
|
|
||||||
.mid_top_with_margin_on(state.ids.recipe_name_btns[i], tweak!(1.0))
|
|
||||||
.graphics_for(state.ids.recipe_name_btns[i])
|
|
||||||
.set(state.ids.recipe_name_texts[i], ui);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selected Recipe
|
// Selected Recipe
|
||||||
@ -910,6 +985,12 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
{
|
{
|
||||||
events.push(Event::SearchRecipe(None));
|
events.push(Event::SearchRecipe(None));
|
||||||
}
|
}
|
||||||
|
Rectangle::fill([114.0, 20.0])
|
||||||
|
.top_left_with_margins_on(state.ids.btn_close_search, -2.0, 16.0)
|
||||||
|
.hsla(0.0, 0.0, 0.0, 0.7)
|
||||||
|
.depth(1.0)
|
||||||
|
.parent(state.ids.window)
|
||||||
|
.set(state.ids.input_bg_search, ui);
|
||||||
if let Some(string) = TextEdit::new(key.as_str())
|
if let Some(string) = TextEdit::new(key.as_str())
|
||||||
.top_left_with_margins_on(state.ids.btn_close_search, -2.0, 18.0)
|
.top_left_with_margins_on(state.ids.btn_close_search, -2.0, 18.0)
|
||||||
.w_h(90.0, 20.0)
|
.w_h(90.0, 20.0)
|
||||||
@ -959,44 +1040,3 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
events
|
events
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tint_color_with_quantity(color: Color, quantity: RecipeIngredientQuantity) -> Color {
|
|
||||||
// let color::Hsla(h, s, l, a) = color.to_hsl();
|
|
||||||
// match quantity{
|
|
||||||
// RecipeIngredientQuantity::All => color,
|
|
||||||
// RecipeIngredientQuantity::Some =>
|
|
||||||
// Color::Hsla(h * tweak!(1.0) + tweak!(0.0), s * tweak!(0.05) +
|
|
||||||
// tweak!(0.05), l * tweak!(0.2) + tweak!(0.3), a),
|
|
||||||
// RecipeIngredientQuantity::None =>
|
|
||||||
// Color::Hsla(h * tweak!(0.0) + tweak!(0.0), s * tweak!(0.05) +
|
|
||||||
// tweak!(0.2), l * tweak!(0.2) + tweak!(0.3), a), }
|
|
||||||
// new_color = (color - mean_color) * potency + base_color
|
|
||||||
let mean_color = Color::Rgba(tweak!(0.5), tweak!(0.5), tweak!(0.5), tweak!(1.0));
|
|
||||||
let (potency, base_color) = match quantity {
|
|
||||||
RecipeIngredientQuantity::All => (
|
|
||||||
tweak!(0.3),
|
|
||||||
Color::Rgba(tweak!(0.8), tweak!(0.8), tweak!(0.8), tweak!(0.8)),
|
|
||||||
), //preserve color
|
|
||||||
RecipeIngredientQuantity::Some => (tweak!(0.15), TEXT_GRAY_COLOR),
|
|
||||||
RecipeIngredientQuantity::None => (tweak!(0.1), TEXT_DULL_RED_COLOR),
|
|
||||||
};
|
|
||||||
|
|
||||||
let color::Rgba(r, g, b, a) = color.to_rgb();
|
|
||||||
let color::Rgba(r1, g1, b1, a1) = mean_color.to_rgb();
|
|
||||||
let color::Rgba(r2, g2, b2, a2) = base_color.to_rgb();
|
|
||||||
Color::Rgba(
|
|
||||||
(r - r1) * potency + r2,
|
|
||||||
(g - g1) * potency + g2,
|
|
||||||
(b - b1) * potency + b2,
|
|
||||||
// (a - a1) * potency + a2,
|
|
||||||
1.0,
|
|
||||||
)
|
|
||||||
// match quantity{
|
|
||||||
// RecipeIngredientQuantity::All => color,
|
|
||||||
// RecipeIngredientQuantity::Some =>
|
|
||||||
// Color::Rgba(r * tweak!(0.15) + tweak!(0.45), g * tweak!(0.15) +
|
|
||||||
// tweak!(0.45), b * tweak!(0.15) + tweak!(0.45), a),
|
|
||||||
// RecipeIngredientQuantity::None =>
|
|
||||||
// Color::Rgba(r * tweak!(0.1) + tweak!(0.46), g * tweak!(0.1) +
|
|
||||||
// tweak!(0.1), b * tweak!(0.1) + tweak!(0.1), a), }
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user