diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f9a333ec0..bb3f61ff9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Eyebrows and shapes can now be selected - Character name and level information to chat, social tab and `/players` command. - Added inventory, armour and weapon saving +- Show where screenshots are saved to in the chat ### Changed diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index 983e244d86..9feb900171 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -7,11 +7,11 @@ use crate::{ window::Event as WinEvent, Direction, GlobalState, PlayState, PlayStateResult, }; -use client::{self, Client}; +use client::{self, Client, Event as ClientEvent}; use common::{assets, clock::Clock, comp, msg::ClientState, state::DeltaTime}; use log::error; use specs::WorldExt; -use std::{cell::RefCell, rc::Rc, time::Duration}; +use std::{cell::RefCell, rc::Rc, time::Duration, sync::mpsc}; use ui::CharSelectionUi; pub struct CharSelectionState { @@ -42,10 +42,12 @@ impl PlayState for CharSelectionState { // Load the player's character list self.client.borrow_mut().load_character_list(); + let (message_sender, _message_receiver): (mpsc::Sender, mpsc::Receiver) = mpsc::channel(); + let mut current_client_state = self.client.borrow().get_client_state(); while let ClientState::Pending | ClientState::Registered = current_client_state { // Handle window events - for event in global_state.window.fetch_events(&mut global_state.settings) { + for event in global_state.window.fetch_events(&mut global_state.settings, &message_sender) { if self.char_selection_ui.handle_event(event.clone()) { continue; } diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index 27382c26ea..e46d492a45 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -11,6 +11,8 @@ use log::{error, warn}; #[cfg(feature = "singleplayer")] use std::time::Duration; use ui::{Event as MainMenuEvent, MainMenuUi}; +use std::sync::mpsc; +use client::{self, Event as ClientEvent}; pub struct MainMenuState { main_menu_ui: MainMenuUi, @@ -47,9 +49,11 @@ impl PlayState for MainMenuState { &crate::i18n::i18n_asset_key(&global_state.settings.language.selected_language), ); + let (message_sender, _message_receiver): (mpsc::Sender, mpsc::Receiver) = mpsc::channel(); + loop { // Handle window events. - for event in global_state.window.fetch_events(&mut global_state.settings) { + for event in global_state.window.fetch_events(&mut global_state.settings, &message_sender) { match event { Event::Close => return PlayStateResult::Shutdown, // Pass events to ui. diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index e785de0d9c..2722547c98 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -9,7 +9,7 @@ use crate::{ window::{AnalogGameInput, Event, GameInput}, Direction, Error, GlobalState, PlayState, PlayStateResult, }; -use client::{self, Client, Event::Chat}; +use client::{self, Client, Event::Chat, Event as ClientEvent}; use common::{ assets::{load_watched, watch}, clock::Clock, @@ -23,7 +23,7 @@ use common::{ }; use log::error; use specs::{Join, WorldExt}; -use std::{cell::RefCell, rc::Rc, time::Duration}; +use std::{cell::RefCell, rc::Rc, time::Duration, sync::mpsc}; use vek::*; /// The action to perform after a tick @@ -143,6 +143,8 @@ impl PlayState for SessionState { let mut ori = self.scene.camera().get_orientation(); let mut free_look = false; + let (message_sender, message_receiver): (mpsc::Sender, mpsc::Receiver) = mpsc::channel(); + // Game loop let mut current_client_state = self.client.borrow().get_client_state(); while let ClientState::Pending | ClientState::Character = current_client_state { @@ -224,8 +226,14 @@ impl PlayState for SessionState { .unwrap_or(false) })); + // Receive any ClientEvents sent through the message channel + match message_receiver.try_recv() { + Ok(message_event) => self.hud.new_message(message_event), + Err(_x) => {}, + }; + // Handle window events. - for event in global_state.window.fetch_events(&mut global_state.settings) { + for event in global_state.window.fetch_events(&mut global_state.settings, &message_sender) { // Pass all events to the ui first. if self.hud.handle_event(event.clone(), global_state) { continue; diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 667b352d5b..1ef15d6895 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -10,6 +10,11 @@ use hashbrown::HashMap; use log::{error, warn}; use serde_derive::{Deserialize, Serialize}; use std::fmt; +use std::sync::mpsc::Sender; +use client::{self, Event as ClientEvent}; +use common::{ + ChatType, +}; use vek::*; /// Represents a key that the game recognises after input mapping. @@ -483,7 +488,7 @@ impl Window { pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer } - pub fn fetch_events(&mut self, settings: &mut Settings) -> Vec { + pub fn fetch_events(&mut self, settings: &mut Settings, message_sender: &Sender) -> Vec { let mut events = vec![]; events.append(&mut self.supplement_events); // Refresh ui size (used when changing playstates) @@ -651,7 +656,7 @@ impl Window { } if take_screenshot { - self.take_screenshot(&settings); + self.take_screenshot(&settings, &message_sender); } if toggle_fullscreen { @@ -924,10 +929,11 @@ impl Window { pub fn send_supplement_event(&mut self, event: Event) { self.supplement_events.push(event) } - pub fn take_screenshot(&mut self, settings: &Settings) { + pub fn take_screenshot(&mut self, settings: &Settings, message_sender: &Sender) { match self.renderer.create_screenshot() { Ok(img) => { let mut path = settings.screenshots_path.clone(); + let sender = message_sender.clone(); std::thread::spawn(move || { use std::time::SystemTime; @@ -935,6 +941,10 @@ impl Window { if !path.exists() { if let Err(err) = std::fs::create_dir_all(&path) { warn!("Couldn't create folder for screenshot: {:?}", err); + let _result = sender.send(ClientEvent::Chat { + chat_type: ChatType::Meta, + message: String::from("Couldn't create folder for screenshot"), + }); } } path.push(format!( @@ -946,6 +956,20 @@ impl Window { )); if let Err(err) = img.save(&path) { warn!("Couldn't save screenshot: {:?}", err); + let _result = sender.send(ClientEvent::Chat { + chat_type: ChatType::Meta, + message: String::from("Couldn't save screenshot"), + }); + } else { + match path.to_str() { + Some(x) => { + let _result = sender.send(ClientEvent::Chat { + chat_type: ChatType::Meta, + message: format!("Screenshot saved to {}", x), + }); + }, + None => {} + } } }); },