diff --git a/assets/voxygen/i18n/en/gameinput.ron b/assets/voxygen/i18n/en/gameinput.ron index 92c7adb51d..231740d70b 100644 --- a/assets/voxygen/i18n/en/gameinput.ron +++ b/assets/voxygen/i18n/en/gameinput.ron @@ -40,6 +40,7 @@ "gameinput.escape": "Escape", "gameinput.map": "Map", "gameinput.bag": "Bag", + "gameinput.trade": "Trade", "gameinput.social": "Social", "gameinput.sit": "Sit", "gameinput.spellbook": "Spells", diff --git a/assets/voxygen/i18n/en/hud/trade.ron b/assets/voxygen/i18n/en/hud/trade.ron new file mode 100644 index 0000000000..b199a27a7f --- /dev/null +++ b/assets/voxygen/i18n/en/hud/trade.ron @@ -0,0 +1,13 @@ +/// WARNING: Localization files shall be saved in UTF-8 format without BOM + +/// Localization for "global" English +( + string_map: { + "hud.trade.trade_window": "Trade window", + }, + + + vector_map: { + } +) + diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index fb61cd4a7b..8c15f9f750 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -19,6 +19,7 @@ mod settings_window; mod skillbar; mod slots; mod social; +mod trade; mod util; pub use hotbar::{SlotContents as HotbarSlotContents, State as HotbarState}; @@ -44,6 +45,7 @@ use serde::{Deserialize, Serialize}; use settings_window::{SettingsTab, SettingsWindow}; use skillbar::Skillbar; use social::{Social, SocialTab}; +use trade::Trade; use crate::{ ecs::{comp as vcomp, comp::HpFloaterList}, @@ -257,6 +259,7 @@ widget_ids! { minimap, prompt_dialog, bag, + trade, social, quest, diary, @@ -480,6 +483,7 @@ pub struct Show { debug: bool, bag: bool, bag_inv: bool, + trade: bool, social: bool, diary: bool, group: bool, @@ -509,6 +513,17 @@ impl Show { fn toggle_bag(&mut self) { self.bag(!self.bag); } + fn trade(&mut self, open: bool) { + if !self.esc_menu { + self.bag = open; + self.trade = open; + self.map = false; + self.want_grab = !open; + } + } + + fn toggle_trade(&mut self) { self.trade(!self.trade); } + fn map(&mut self, open: bool) { if !self.esc_menu { self.map = open; @@ -590,6 +605,7 @@ impl Show { fn toggle_windows(&mut self, global_state: &mut GlobalState) { if self.bag + || self.trade || self.esc_menu || self.map || self.social @@ -600,6 +616,7 @@ impl Show { || !matches!(self.open_windows, Windows::None) { self.bag = false; + self.trade = false; self.esc_menu = false; self.help = false; self.intro = false; @@ -774,6 +791,7 @@ impl Hud { debug: false, bag: false, bag_inv: false, + trade: false, esc_menu: false, open_windows: Windows::None, map: false, @@ -2089,6 +2107,35 @@ impl Hud { } } } + // Trade window + if self.show.trade { + match Trade::new( + client, + &self.imgs, + &self.item_imgs, + &self.fonts, + &self.rot_imgs, + tooltip_manager, + &mut self.slot_manager, + i18n, + &self.show, + ) + .set(self.ids.trade, ui_widgets) + { + Some(trade::Event::Close) => { + self.show.stats = false; + self.show.trade(false); + if !self.show.social { + self.show.want_grab = true; + self.force_ungrab = false; + } else { + self.force_ungrab = true + }; + }, + None => {}, + } + } + // Buffs let ecs = client.state().ecs(); let entity = client.entity(); @@ -2763,6 +2810,10 @@ impl Hud { self.show.toggle_bag(); true }, + GameInput::Trade if state => { + self.show.toggle_trade(); + true + }, GameInput::Social if state => { self.show.toggle_social(); true diff --git a/voxygen/src/hud/trade.rs b/voxygen/src/hud/trade.rs new file mode 100644 index 0000000000..345cde15f4 --- /dev/null +++ b/voxygen/src/hud/trade.rs @@ -0,0 +1,165 @@ +use super::{ + cr_color, + img_ids::{Imgs, ImgsRot}, + item_imgs::ItemImgs, + slots::{InventorySlot, SlotManager}, + util::loadout_slot_text, + Show, CRITICAL_HP_COLOR, LOW_HP_COLOR, QUALITY_COMMON, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, +}; +use common::{ + comp::{item::Quality,}, +}; +use crate::{ + hud::get_quality_col, + i18n::Localization, + ui::{ + fonts::Fonts, + slot::{ContentSize, SlotMaker}, + ImageFrame, Tooltip, TooltipManager, Tooltipable, + }, +}; +use client::Client; +use conrod_core::{ + color, + widget::{self, Button, Image, Rectangle, Scrollbar, Text}, + widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, +}; + +pub struct State { + ids: Ids, +} + +pub enum Event { + Close, +} + +widget_ids! { + pub struct Ids { + trade_close, + bg, + bg_frame, + trade_title_bg, + trade_title, + } +} + +#[derive(WidgetCommon)] +pub struct Trade<'a> { + client: &'a Client, + imgs: &'a Imgs, + item_imgs: &'a ItemImgs, + fonts: &'a Fonts, + #[conrod(common_builder)] + common: widget::CommonBuilder, + rot_imgs: &'a ImgsRot, + tooltip_manager: &'a mut TooltipManager, + slot_manager: &'a mut SlotManager, + localized_strings: &'a Localization, + show: &'a Show, +} + +impl<'a> Trade<'a> { + pub fn new( + client: &'a Client, + imgs: &'a Imgs, + item_imgs: &'a ItemImgs, + fonts: &'a Fonts, + rot_imgs: &'a ImgsRot, + tooltip_manager: &'a mut TooltipManager, + slot_manager: &'a mut SlotManager, + localized_strings: &'a Localization, + show: &'a Show, + ) -> Self { + Self { + client, + imgs, + item_imgs, + fonts, + common: widget::CommonBuilder::default(), + rot_imgs, + tooltip_manager, + slot_manager, + localized_strings, + show, + } + } +} + +impl<'a> Widget for Trade<'a> { + type Event = Option; + type State = State; + type Style = (); + + fn init_state(&self, id_gen: widget::id::Generator) -> Self::State { + State { + ids: Ids::new(id_gen), + } + } + + fn style(&self) -> Self::Style {} + + fn update(self, args: widget::UpdateArgs) -> Self::Event { + let widget::UpdateArgs { state, ui, .. } = args; + + let mut event = None; + + let inventories = self.client.inventories(); + let inventory = match inventories.get(self.client.entity()) { + Some(l) => l, + None => return None, + }; + + let trade_tooltip = Tooltip::new({ + // Edge images [t, b, r, l] + // Corner images [tr, tl, br, bl] + let edge = &self.rot_imgs.tt_side; + let corner = &self.rot_imgs.tt_corner; + ImageFrame::new( + [edge.cw180, edge.none, edge.cw270, edge.cw90], + [corner.none, corner.cw270, corner.cw90, corner.cw180], + Color::Rgba(0.08, 0.07, 0.04, 1.0), + 5.0, + ) + }) + .title_font_size(self.fonts.cyri.scale(15)) + .parent(ui.window) + .desc_font_size(self.fonts.cyri.scale(12)) + .font_id(self.fonts.cyri.conrod_id) + .desc_text_color(TEXT_COLOR); + + // BG + Image::new(self.imgs.inv_bg_bag) + .w_h(424.0, 708.0) + .middle() + .color(Some(UI_MAIN)) + .set(state.ids.bg, ui); + Image::new(self.imgs.inv_frame_bag) + .w_h(424.0, 708.0) + .middle_of(state.ids.bg) + .color(Some(UI_HIGHLIGHT_0)) + .set(state.ids.bg_frame, ui); + // Title + Text::new( + &self + .localized_strings + .get("hud.trade.trade_window") + ) + .mid_top_with_margin_on(state.ids.bg_frame, 9.0) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(20)) + .color(Color::Rgba(0.0, 0.0, 0.0, 1.0)) + .set(state.ids.trade_title_bg, ui); + Text::new( + &self + .localized_strings + .get("hud.trade.trade_window") + ) + .top_left_with_margins_on(state.ids.trade_title_bg, 2.0, 2.0) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(20)) + .color(TEXT_COLOR) + .set(state.ids.trade_title, ui); + + event + } +} diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index b5192d0b9a..be468b76d6 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -142,7 +142,8 @@ impl ControlSettings { GameInput::ToggleLantern => KeyMouse::Key(VirtualKeyCode::G), GameInput::Mount => KeyMouse::Key(VirtualKeyCode::F), GameInput::Map => KeyMouse::Key(VirtualKeyCode::M), - GameInput::Bag => KeyMouse::Key(VirtualKeyCode::B), + GameInput::Bag => KeyMouse::Key(VirtualKeyCode::R), + GameInput::Trade => KeyMouse::Key(VirtualKeyCode::B), GameInput::Social => KeyMouse::Key(VirtualKeyCode::O), GameInput::Crafting => KeyMouse::Key(VirtualKeyCode::C), GameInput::Spellbook => KeyMouse::Key(VirtualKeyCode::P), diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 0f09c0bee5..9b49993dce 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -54,6 +54,7 @@ pub enum GameInput { Escape, Map, Bag, + Trade, Social, Crafting, Spellbook, @@ -107,6 +108,7 @@ impl GameInput { GameInput::Escape => "gameinput.escape", GameInput::Map => "gameinput.map", GameInput::Bag => "gameinput.bag", + GameInput::Trade => "gameinput.trade", GameInput::Social => "gameinput.social", GameInput::Crafting => "gameinput.crafting", GameInput::Spellbook => "gameinput.spellbook", @@ -167,6 +169,7 @@ impl GameInput { GameInput::Escape, GameInput::Map, GameInput::Bag, + GameInput::Trade, GameInput::Social, GameInput::Crafting, GameInput::Spellbook,