mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added chat tabs
This commit is contained in:
parent
e66a2079ce
commit
95a6e35a3a
@ -59,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- /skill_preset command which allows you to apply skill presets
|
- /skill_preset command which allows you to apply skill presets
|
||||||
- Added timed bans and ban history.
|
- Added timed bans and ban history.
|
||||||
- Added non-admin moderators with limit privileges and updated the security model to reflect this.
|
- Added non-admin moderators with limit privileges and updated the security model to reflect this.
|
||||||
|
- Chat tabs
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
BIN
assets/voxygen/element/ui/settings/buttons/settings_button_plus.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/settings/buttons/settings_button_plus.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/settings/buttons/settings_button_plus_hover.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/settings/buttons/settings_button_plus_hover.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/settings/buttons/settings_button_plus_press.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/settings/buttons/settings_button_plus_press.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/settings/chat_tab_settings_bg.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/settings/chat_tab_settings_bg.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/settings/chat_tab_settings_frame.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/settings/chat_tab_settings_frame.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -16,6 +16,7 @@
|
|||||||
"common.controls": "Controls",
|
"common.controls": "Controls",
|
||||||
"common.video": "Graphics",
|
"common.video": "Graphics",
|
||||||
"common.sound": "Sound",
|
"common.sound": "Sound",
|
||||||
|
"common.chat": "Chat",
|
||||||
"common.resume": "Resume",
|
"common.resume": "Resume",
|
||||||
"common.characters": "Characters",
|
"common.characters": "Characters",
|
||||||
"common.close": "Close",
|
"common.close": "Close",
|
||||||
@ -44,6 +45,7 @@
|
|||||||
"common.video_settings": "Graphics Settings",
|
"common.video_settings": "Graphics Settings",
|
||||||
"common.sound_settings": "Sound Settings",
|
"common.sound_settings": "Sound Settings",
|
||||||
"common.language_settings": "Language Settings",
|
"common.language_settings": "Language Settings",
|
||||||
|
"common.chat_settings": "Chat Settings",
|
||||||
|
|
||||||
// Message when connection to the server is lost
|
// Message when connection to the server is lost
|
||||||
"common.connection_lost": r#"Connection lost!
|
"common.connection_lost": r#"Connection lost!
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
/// Localization for "global" English
|
/// Localization for "global" English
|
||||||
(
|
(
|
||||||
string_map: {
|
string_map: {
|
||||||
|
"hud.chat.all": "All",
|
||||||
|
"hud.chat.chat_tab_hover_tooltip": "Right click for settings",
|
||||||
|
|
||||||
// Debuff outcomes
|
// Debuff outcomes
|
||||||
"hud.outcome.burning": "died of: burning",
|
"hud.outcome.burning": "died of: burning",
|
||||||
"hud.outcome.curse": "died of: curse",
|
"hud.outcome.curse": "died of: curse",
|
||||||
|
@ -107,6 +107,23 @@
|
|||||||
"hud.settings.awaitingkey": "Press a key...",
|
"hud.settings.awaitingkey": "Press a key...",
|
||||||
"hud.settings.unbound": "None",
|
"hud.settings.unbound": "None",
|
||||||
"hud.settings.reset_keybinds": "Reset to Defaults",
|
"hud.settings.reset_keybinds": "Reset to Defaults",
|
||||||
|
|
||||||
|
"hud.settings.chat_tabs": "Chat Tabs",
|
||||||
|
"hud.settings.label": "Label:",
|
||||||
|
"hud.settings.delete": "Delete",
|
||||||
|
"hud.settings.show_all": "Show all",
|
||||||
|
"hud.settings.messages": "Messages",
|
||||||
|
"hud.settings.activity": "Activity",
|
||||||
|
"hud.settings.death": "Death",
|
||||||
|
"hud.settings.group": "Group",
|
||||||
|
"hud.settings.faction": "Faction",
|
||||||
|
"hud.settings.world": "World",
|
||||||
|
"hud.settings.region": "Region",
|
||||||
|
"hud.settings.say": "Say",
|
||||||
|
"hud.settings.none": "None",
|
||||||
|
"hud.settings.all": "All",
|
||||||
|
"hud.settings.group_only": "Group only",
|
||||||
|
"hud.settings.reset_chat" : "Reset to Defaults",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
use super::{
|
use super::{
|
||||||
img_ids::Imgs, ERROR_COLOR, FACTION_COLOR, GROUP_COLOR, INFO_COLOR, KILL_COLOR, LOOT_COLOR,
|
img_ids::Imgs, ChatTab, ERROR_COLOR, FACTION_COLOR, GROUP_COLOR, INFO_COLOR, KILL_COLOR,
|
||||||
OFFLINE_COLOR, ONLINE_COLOR, REGION_COLOR, SAY_COLOR, TELL_COLOR, WORLD_COLOR,
|
LOOT_COLOR, OFFLINE_COLOR, ONLINE_COLOR, REGION_COLOR, SAY_COLOR, TELL_COLOR, TEXT_COLOR,
|
||||||
|
WORLD_COLOR,
|
||||||
};
|
};
|
||||||
use crate::{i18n::Localization, ui::fonts::Fonts, GlobalState};
|
use crate::{i18n::Localization, settings::chat::MAX_CHAT_TABS, ui::fonts::Fonts, GlobalState};
|
||||||
use client::{cmd, Client};
|
use client::{cmd, Client};
|
||||||
use common::comp::{
|
use common::comp::{
|
||||||
chat::{KillSource, KillType},
|
chat::{KillSource, KillType},
|
||||||
|
group::Role,
|
||||||
BuffKind, ChatMode, ChatMsg, ChatType,
|
BuffKind, ChatMode, ChatMsg, ChatType,
|
||||||
};
|
};
|
||||||
use common_net::msg::validate_chat_msg;
|
use common_net::msg::validate_chat_msg;
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
|
color,
|
||||||
input::Key,
|
input::Key,
|
||||||
position::Dimension,
|
position::Dimension,
|
||||||
text::{
|
text::{
|
||||||
@ -17,9 +20,10 @@ use conrod_core::{
|
|||||||
cursor::{self, Index},
|
cursor::{self, Index},
|
||||||
},
|
},
|
||||||
widget::{self, Button, Id, Image, List, Rectangle, Text, TextEdit},
|
widget::{self, Button, Id, Image, List, Rectangle, Text, TextEdit},
|
||||||
widget_ids, Color, Colorable, Positionable, Sizeable, Ui, UiCell, Widget, WidgetCommon,
|
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Ui, UiCell, Widget,
|
||||||
|
WidgetCommon,
|
||||||
};
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::{HashSet, VecDeque};
|
||||||
|
|
||||||
widget_ids! {
|
widget_ids! {
|
||||||
struct Ids {
|
struct Ids {
|
||||||
@ -29,7 +33,15 @@ widget_ids! {
|
|||||||
chat_input_bg,
|
chat_input_bg,
|
||||||
chat_input_icon,
|
chat_input_icon,
|
||||||
chat_arrow,
|
chat_arrow,
|
||||||
|
chat_icon_align,
|
||||||
chat_icons[],
|
chat_icons[],
|
||||||
|
|
||||||
|
chat_tab_align,
|
||||||
|
chat_tab_all,
|
||||||
|
chat_tab_selected,
|
||||||
|
chat_tabs[],
|
||||||
|
chat_tab_tooltip_bg,
|
||||||
|
chat_tab_tooltip_text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*#[const_tweaker::tweak(min = 0.0, max = 60.0, step = 1.0)]
|
/*#[const_tweaker::tweak(min = 0.0, max = 60.0, step = 1.0)]
|
||||||
@ -41,10 +53,14 @@ const CHAT_ICON_WIDTH: f64 = 16.0;
|
|||||||
const CHAT_ICON_HEIGHT: f64 = 16.0;
|
const CHAT_ICON_HEIGHT: f64 = 16.0;
|
||||||
const CHAT_BOX_WIDTH: f64 = 470.0;
|
const CHAT_BOX_WIDTH: f64 = 470.0;
|
||||||
const CHAT_BOX_INPUT_WIDTH: f64 = 460.0 - CHAT_ICON_WIDTH - 1.0;
|
const CHAT_BOX_INPUT_WIDTH: f64 = 460.0 - CHAT_ICON_WIDTH - 1.0;
|
||||||
const CHAT_BOX_HEIGHT: f64 = 174.0;
|
const CHAT_BOX_HEIGHT: f64 = 154.0;
|
||||||
|
|
||||||
|
const CHAT_TAB_HEIGHT: f64 = 20.0;
|
||||||
|
const CHAT_TAB_ALL_WIDTH: f64 = 40.0;
|
||||||
|
|
||||||
#[derive(WidgetCommon)]
|
#[derive(WidgetCommon)]
|
||||||
pub struct Chat<'a> {
|
pub struct Chat<'a> {
|
||||||
|
pulse: f32,
|
||||||
new_messages: &'a mut VecDeque<ChatMsg>,
|
new_messages: &'a mut VecDeque<ChatMsg>,
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
force_input: Option<String>,
|
force_input: Option<String>,
|
||||||
@ -69,11 +85,13 @@ impl<'a> Chat<'a> {
|
|||||||
new_messages: &'a mut VecDeque<ChatMsg>,
|
new_messages: &'a mut VecDeque<ChatMsg>,
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
|
pulse: f32,
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
localized_strings: &'a Localization,
|
localized_strings: &'a Localization,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
pulse,
|
||||||
new_messages,
|
new_messages,
|
||||||
client,
|
client,
|
||||||
force_input: None,
|
force_input: None,
|
||||||
@ -142,16 +160,22 @@ pub struct State {
|
|||||||
completions_index: Option<usize>,
|
completions_index: Option<usize>,
|
||||||
// At which character is tab completion happening
|
// At which character is tab completion happening
|
||||||
completion_cursor: Option<usize>,
|
completion_cursor: Option<usize>,
|
||||||
|
// last time mouse has been hovered
|
||||||
|
tabs_last_hover_pulse: Option<f32>,
|
||||||
|
// last chat_tab (used to see if chat tab has been changed)
|
||||||
|
prev_chat_tab: Option<ChatTab>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
TabCompletionStart(String),
|
TabCompletionStart(String),
|
||||||
SendMessage(String),
|
SendMessage(String),
|
||||||
Focus(Id),
|
Focus(Id),
|
||||||
|
ChangeChatTab(Option<usize>),
|
||||||
|
ShowChatTabSettings(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget for Chat<'a> {
|
impl<'a> Widget for Chat<'a> {
|
||||||
type Event = Option<Event>;
|
type Event = Vec<Event>;
|
||||||
type State = State;
|
type State = State;
|
||||||
type Style = ();
|
type Style = ();
|
||||||
|
|
||||||
@ -168,6 +192,8 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
completions_index: None,
|
completions_index: None,
|
||||||
completion_cursor: None,
|
completion_cursor: None,
|
||||||
ids: Ids::new(id_gen),
|
ids: Ids::new(id_gen),
|
||||||
|
tabs_last_hover_pulse: None,
|
||||||
|
prev_chat_tab: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,12 +204,23 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
#[allow(clippy::single_match)] // TODO: Pending review in #587
|
#[allow(clippy::single_match)] // TODO: Pending review in #587
|
||||||
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
|
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
|
||||||
let widget::UpdateArgs { id, state, ui, .. } = args;
|
let widget::UpdateArgs { id, state, ui, .. } = args;
|
||||||
let transp = self.global_state.settings.interface.chat_transp;
|
|
||||||
|
let mut events = Vec::new();
|
||||||
|
|
||||||
|
let chat_settings = &self.global_state.settings.chat;
|
||||||
|
|
||||||
|
let chat_tabs = &chat_settings.chat_tabs;
|
||||||
|
let current_chat_tab = chat_settings.chat_tab_index.and_then(|i| chat_tabs.get(i));
|
||||||
|
|
||||||
// Maintain scrolling.
|
// Maintain scrolling.
|
||||||
if !self.new_messages.is_empty() {
|
if !self.new_messages.is_empty() {
|
||||||
state.update(|s| s.messages.extend(self.new_messages.drain(..)));
|
state.update(|s| s.messages.extend(self.new_messages.drain(..)));
|
||||||
ui.scroll_widget(state.ids.message_box, [0.0, std::f64::MAX]);
|
ui.scroll_widget(state.ids.message_box, [0.0, std::f64::MAX]);
|
||||||
}
|
}
|
||||||
|
if current_chat_tab != state.prev_chat_tab.as_ref() {
|
||||||
|
state.update(|s| s.prev_chat_tab = current_chat_tab.cloned());
|
||||||
|
ui.scroll_widget(state.ids.message_box, [0.0, std::f64::MAX]);
|
||||||
|
}
|
||||||
|
|
||||||
// Empty old messages
|
// Empty old messages
|
||||||
state.update(|s| {
|
state.update(|s| {
|
||||||
@ -322,7 +359,7 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
_ => 0.0,
|
_ => 0.0,
|
||||||
};
|
};
|
||||||
Rectangle::fill([CHAT_BOX_WIDTH, y])
|
Rectangle::fill([CHAT_BOX_WIDTH, y])
|
||||||
.rgba(0.0, 0.0, 0.0, transp + 0.1)
|
.rgba(0.0, 0.0, 0.0, chat_settings.chat_transp + 0.1)
|
||||||
.bottom_left_with_margins_on(ui.window, 10.0, 10.0)
|
.bottom_left_with_margins_on(ui.window, 10.0, 10.0)
|
||||||
.w(CHAT_BOX_WIDTH)
|
.w(CHAT_BOX_WIDTH)
|
||||||
.set(state.ids.chat_input_bg, ui);
|
.set(state.ids.chat_input_bg, ui);
|
||||||
@ -341,7 +378,7 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
|
|
||||||
// Message box
|
// Message box
|
||||||
Rectangle::fill([CHAT_BOX_WIDTH, CHAT_BOX_HEIGHT])
|
Rectangle::fill([CHAT_BOX_WIDTH, CHAT_BOX_HEIGHT])
|
||||||
.rgba(0.0, 0.0, 0.0, transp)
|
.rgba(0.0, 0.0, 0.0, chat_settings.chat_transp)
|
||||||
.and(|r| {
|
.and(|r| {
|
||||||
if input_focused {
|
if input_focused {
|
||||||
r.up_from(state.ids.chat_input_bg, 0.0)
|
r.up_from(state.ids.chat_input_bg, 0.0)
|
||||||
@ -351,11 +388,6 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
})
|
})
|
||||||
.crop_kids()
|
.crop_kids()
|
||||||
.set(state.ids.message_box_bg, ui);
|
.set(state.ids.message_box_bg, ui);
|
||||||
let (mut items, _) = List::flow_down(state.messages.len() + 1)
|
|
||||||
.top_left_with_margins_on(state.ids.message_box_bg, 0.0, 16.0)
|
|
||||||
.w_h(CHAT_BOX_WIDTH - 16.0, CHAT_BOX_HEIGHT)
|
|
||||||
.scroll_kids_vertically()
|
|
||||||
.set(state.ids.message_box, ui);
|
|
||||||
if state.ids.chat_icons.len() < state.messages.len() {
|
if state.ids.chat_icons.len() < state.messages.len() {
|
||||||
state.update(|s| {
|
state.update(|s| {
|
||||||
s.ids
|
s.ids
|
||||||
@ -363,105 +395,70 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
.resize(s.messages.len(), &mut ui.widget_id_generator())
|
.resize(s.messages.len(), &mut ui.widget_id_generator())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let group_members = self
|
||||||
|
.client
|
||||||
|
.group_members()
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(u, r)| match r {
|
||||||
|
Role::Member => Some(u),
|
||||||
|
Role::Pet => None,
|
||||||
|
})
|
||||||
|
.collect::<HashSet<_>>();
|
||||||
|
let show_char_name = chat_settings.chat_character_name;
|
||||||
|
let messages = &state
|
||||||
|
.messages
|
||||||
|
.iter()
|
||||||
|
.map(|m| {
|
||||||
|
let mut message = m.clone();
|
||||||
|
if let Some(template_key) = get_chat_template_key(&message.chat_type) {
|
||||||
|
message.message = self.localized_strings.get(template_key).to_string();
|
||||||
|
if let ChatType::Kill(kill_source, _) = &message.chat_type {
|
||||||
|
match kill_source {
|
||||||
|
KillSource::Player(_, KillType::Buff(buffkind))
|
||||||
|
| KillSource::NonExistent(KillType::Buff(buffkind))
|
||||||
|
| KillSource::NonPlayer(_, KillType::Buff(buffkind)) => {
|
||||||
|
message.message = insert_killing_buff(
|
||||||
|
*buffkind,
|
||||||
|
self.localized_strings,
|
||||||
|
&message.message,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message.message = self.client.format_message(&message, show_char_name);
|
||||||
|
message
|
||||||
|
})
|
||||||
|
.filter(|m| {
|
||||||
|
if let Some(chat_tab) = current_chat_tab {
|
||||||
|
chat_tab.filter.satisfies(&m, &group_members)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
Rectangle::fill_with([CHAT_ICON_WIDTH, CHAT_BOX_HEIGHT], color::TRANSPARENT)
|
||||||
|
.top_left_with_margins_on(state.ids.message_box_bg, 0.0, 0.0)
|
||||||
|
.crop_kids()
|
||||||
|
.set(state.ids.chat_icon_align, ui);
|
||||||
|
let (mut items, _) = List::flow_down(messages.len() + 1)
|
||||||
|
.top_left_with_margins_on(state.ids.message_box_bg, 0.0, CHAT_ICON_WIDTH)
|
||||||
|
.w_h(CHAT_BOX_WIDTH - CHAT_ICON_WIDTH, CHAT_BOX_HEIGHT)
|
||||||
|
.scroll_kids_vertically()
|
||||||
|
.set(state.ids.message_box, ui);
|
||||||
|
|
||||||
let show_char_name = self.global_state.settings.interface.chat_character_name;
|
|
||||||
while let Some(item) = items.next(ui) {
|
while let Some(item) = items.next(ui) {
|
||||||
// This would be easier if conrod used the v-metrics from rusttype.
|
// This would be easier if conrod used the v-metrics from rusttype.
|
||||||
if item.i < state.messages.len() {
|
if item.i < messages.len() {
|
||||||
let mut message = state.messages[item.i].clone();
|
let message = &messages[item.i];
|
||||||
let (color, icon) = render_chat_line(&message.chat_type, &self.imgs);
|
let (color, icon) = render_chat_line(&message.chat_type, &self.imgs);
|
||||||
let ChatMsg { chat_type, .. } = &message;
|
|
||||||
// For each ChatType needing localization get/set matching pre-formatted
|
// For each ChatType needing localization get/set matching pre-formatted
|
||||||
// localized string. This string will be formatted with the data
|
// localized string. This string will be formatted with the data
|
||||||
// provided in ChatType in the client/src/mod.rs
|
// provided in ChatType in the client/src/mod.rs
|
||||||
// fn format_message called below
|
// fn format_message called below
|
||||||
message.message = match chat_type {
|
|
||||||
ChatType::Online(_) => self
|
let text = Text::new(&message.message)
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.online_msg")
|
|
||||||
.to_string(),
|
|
||||||
ChatType::Offline(_) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.offline_msg")
|
|
||||||
.to_string(),
|
|
||||||
ChatType::Kill(kill_source, _) => match kill_source {
|
|
||||||
KillSource::Player(_, KillType::Buff(buffkind)) => insert_killing_buff(
|
|
||||||
*buffkind,
|
|
||||||
self.localized_strings,
|
|
||||||
self.localized_strings.get("hud.chat.died_of_pvp_buff_msg"),
|
|
||||||
),
|
|
||||||
KillSource::Player(_, KillType::Melee) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.pvp_melee_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::Player(_, KillType::Projectile) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.pvp_ranged_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::Player(_, KillType::Explosion) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.pvp_explosion_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::Player(_, KillType::Energy) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.pvp_energy_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::Player(_, KillType::Other) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.pvp_other_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::NonExistent(KillType::Buff(buffkind)) => insert_killing_buff(
|
|
||||||
*buffkind,
|
|
||||||
self.localized_strings,
|
|
||||||
self.localized_strings
|
|
||||||
.get("hud.chat.died_of_buff_nonexistent_msg"),
|
|
||||||
),
|
|
||||||
KillSource::NonPlayer(_, KillType::Buff(buffkind)) => insert_killing_buff(
|
|
||||||
*buffkind,
|
|
||||||
self.localized_strings,
|
|
||||||
self.localized_strings.get("hud.chat.died_of_npc_buff_msg"),
|
|
||||||
),
|
|
||||||
KillSource::NonPlayer(_, KillType::Melee) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.npc_melee_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::NonPlayer(_, KillType::Projectile) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.npc_ranged_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::NonPlayer(_, KillType::Explosion) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.npc_explosion_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::NonPlayer(_, KillType::Energy) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.npc_energy_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::NonPlayer(_, KillType::Other) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.npc_other_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::Environment(_) => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.environmental_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::FallDamage => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.fall_kill_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::Suicide => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.suicide_msg")
|
|
||||||
.to_string(),
|
|
||||||
KillSource::NonExistent(_) | KillSource::Other => self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.chat.default_death_msg")
|
|
||||||
.to_string(),
|
|
||||||
},
|
|
||||||
_ => message.message,
|
|
||||||
};
|
|
||||||
let msg = self.client.format_message(&message, show_char_name);
|
|
||||||
let text = Text::new(&msg)
|
|
||||||
.font_size(self.fonts.opensans.scale(15))
|
.font_size(self.fonts.opensans.scale(15))
|
||||||
.font_id(self.fonts.opensans.conrod_id)
|
.font_id(self.fonts.opensans.conrod_id)
|
||||||
.w(CHAT_BOX_WIDTH - 17.0)
|
.w(CHAT_BOX_WIDTH - 17.0)
|
||||||
@ -477,7 +474,7 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
Image::new(icon)
|
Image::new(icon)
|
||||||
.w_h(CHAT_ICON_WIDTH, CHAT_ICON_HEIGHT)
|
.w_h(CHAT_ICON_WIDTH, CHAT_ICON_HEIGHT)
|
||||||
.top_left_with_margins_on(item.widget_id, 2.0, -CHAT_ICON_WIDTH)
|
.top_left_with_margins_on(item.widget_id, 2.0, -CHAT_ICON_WIDTH)
|
||||||
.parent(state.ids.message_box_bg)
|
.parent(state.ids.chat_icon_align)
|
||||||
.set(icon_id, ui);
|
.set(icon_id, ui);
|
||||||
} else {
|
} else {
|
||||||
// Spacer at bottom of the last message so that it is not cut off.
|
// Spacer at bottom of the last message so that it is not cut off.
|
||||||
@ -492,6 +489,125 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Chat tabs
|
||||||
|
if ui
|
||||||
|
.rect_of(state.ids.message_box_bg)
|
||||||
|
.map_or(false, |r| r.is_over(ui.global_input().current.mouse.xy))
|
||||||
|
{
|
||||||
|
state.update(|s| s.tabs_last_hover_pulse = Some(self.pulse));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(time_since_hover) = state
|
||||||
|
.tabs_last_hover_pulse
|
||||||
|
.map(|t| self.pulse - t)
|
||||||
|
.filter(|t| t <= &1.5)
|
||||||
|
{
|
||||||
|
let alpha = 1.0 - (time_since_hover / 1.5).powi(4);
|
||||||
|
let shading = color::rgba(1.0, 1.0, 1.0, (chat_settings.chat_transp + 0.1) * alpha);
|
||||||
|
|
||||||
|
Rectangle::fill([CHAT_BOX_WIDTH, CHAT_TAB_HEIGHT])
|
||||||
|
.rgba(0.0, 0.0, 0.0, (chat_settings.chat_transp + 0.1) * alpha)
|
||||||
|
.up_from(state.ids.message_box_bg, 0.0)
|
||||||
|
.set(state.ids.chat_tab_align, ui);
|
||||||
|
if ui
|
||||||
|
.rect_of(state.ids.chat_tab_align)
|
||||||
|
.map_or(false, |r| r.is_over(ui.global_input().current.mouse.xy))
|
||||||
|
{
|
||||||
|
state.update(|s| s.tabs_last_hover_pulse = Some(self.pulse));
|
||||||
|
}
|
||||||
|
|
||||||
|
if Button::image(if chat_settings.chat_tab_index.is_none() {
|
||||||
|
self.imgs.selection
|
||||||
|
} else {
|
||||||
|
self.imgs.nothing
|
||||||
|
})
|
||||||
|
.top_left_with_margins_on(state.ids.chat_tab_align, 0.0, 0.0)
|
||||||
|
.w_h(CHAT_TAB_ALL_WIDTH, CHAT_TAB_HEIGHT)
|
||||||
|
.hover_image(self.imgs.selection_hover)
|
||||||
|
.hover_image(self.imgs.selection_press)
|
||||||
|
.image_color(shading)
|
||||||
|
.label(&self.localized_strings.get("hud.chat.all"))
|
||||||
|
.label_font_size(self.fonts.cyri.scale(14))
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_color(TEXT_COLOR.alpha(alpha))
|
||||||
|
.set(state.ids.chat_tab_all, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::ChangeChatTab(None));
|
||||||
|
}
|
||||||
|
|
||||||
|
let chat_tab_width = (CHAT_BOX_WIDTH - CHAT_TAB_ALL_WIDTH) / (MAX_CHAT_TABS as f64);
|
||||||
|
|
||||||
|
if state.ids.chat_tabs.len() < chat_tabs.len() {
|
||||||
|
state.update(|s| {
|
||||||
|
s.ids
|
||||||
|
.chat_tabs
|
||||||
|
.resize(chat_tabs.len(), &mut ui.widget_id_generator())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (i, chat_tab) in chat_tabs.iter().enumerate() {
|
||||||
|
if Button::image(if chat_settings.chat_tab_index == Some(i) {
|
||||||
|
self.imgs.selection
|
||||||
|
} else {
|
||||||
|
self.imgs.nothing
|
||||||
|
})
|
||||||
|
.w_h(chat_tab_width, CHAT_TAB_HEIGHT)
|
||||||
|
.hover_image(self.imgs.selection_hover)
|
||||||
|
.press_image(self.imgs.selection_press)
|
||||||
|
.image_color(shading)
|
||||||
|
.label(chat_tab.label.as_str())
|
||||||
|
.label_font_size(self.fonts.cyri.scale(14))
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_color(TEXT_COLOR.alpha(alpha))
|
||||||
|
.right_from(
|
||||||
|
if i == 0 {
|
||||||
|
state.ids.chat_tab_all
|
||||||
|
} else {
|
||||||
|
state.ids.chat_tabs[i - 1]
|
||||||
|
},
|
||||||
|
0.0,
|
||||||
|
)
|
||||||
|
.set(state.ids.chat_tabs[i], ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::ChangeChatTab(Some(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui
|
||||||
|
.widget_input(state.ids.chat_tabs[i])
|
||||||
|
.mouse()
|
||||||
|
.map_or(false, |m| m.is_over())
|
||||||
|
{
|
||||||
|
Rectangle::fill([120.0, 20.0])
|
||||||
|
.rgba(0.0, 0.0, 0.0, 0.9)
|
||||||
|
.top_left_with_margins_on(state.ids.chat_tabs[i], -20.0, 5.0)
|
||||||
|
.parent(id)
|
||||||
|
.set(state.ids.chat_tab_tooltip_bg, ui);
|
||||||
|
|
||||||
|
Text::new(
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.chat.chat_tab_hover_tooltip"),
|
||||||
|
)
|
||||||
|
.mid_top_with_margin_on(state.ids.chat_tab_tooltip_bg, 3.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(10))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.chat_tab_tooltip_text, ui);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui
|
||||||
|
.widget_input(state.ids.chat_tabs[i])
|
||||||
|
.clicks()
|
||||||
|
.right()
|
||||||
|
.next()
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
events.push(Event::ShowChatTabSettings(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Chat Arrow
|
// Chat Arrow
|
||||||
// Check if already at bottom.
|
// Check if already at bottom.
|
||||||
if !Self::scrolled_to_bottom(state, ui)
|
if !Self::scrolled_to_bottom(state, ui)
|
||||||
@ -509,11 +625,11 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
|
|
||||||
// We've started a new tab completion. Populate tab completion suggestions.
|
// We've started a new tab completion. Populate tab completion suggestions.
|
||||||
if request_tab_completions {
|
if request_tab_completions {
|
||||||
Some(Event::TabCompletionStart(state.input.message.to_string()))
|
events.push(Event::TabCompletionStart(state.input.message.to_string()));
|
||||||
// If the chat widget is focused, return a focus event to pass the focus
|
// If the chat widget is focused, return a focus event to pass the focus
|
||||||
// to the input box.
|
// to the input box.
|
||||||
} else if keyboard_capturer == Some(id) {
|
} else if keyboard_capturer == Some(id) {
|
||||||
Some(Event::Focus(state.ids.chat_input))
|
events.push(Event::Focus(state.ids.chat_input));
|
||||||
}
|
}
|
||||||
// If enter is pressed and the input box is not empty, send the current message.
|
// If enter is pressed and the input box is not empty, send the current message.
|
||||||
else if ui.widget_input(state.ids.chat_input).presses().key().any(
|
else if ui.widget_input(state.ids.chat_input).presses().key().any(
|
||||||
@ -530,10 +646,9 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
s.history.truncate(self.history_max);
|
s.history.truncate(self.history_max);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Some(Event::SendMessage(msg))
|
events.push(Event::SendMessage(msg));
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
events
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,3 +761,30 @@ fn insert_killing_buff(buff: BuffKind, localized_strings: &Localization, templat
|
|||||||
|
|
||||||
template.replace("{died_of_buff}", buff_outcome)
|
template.replace("{died_of_buff}", buff_outcome)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_chat_template_key(chat_type: &ChatType<String>) -> Option<&str> {
|
||||||
|
Some(match chat_type {
|
||||||
|
ChatType::Online(_) => "hud.chat.online_msg",
|
||||||
|
ChatType::Offline(_) => "hud.chat.offline_msg",
|
||||||
|
ChatType::Kill(kill_source, _) => match kill_source {
|
||||||
|
KillSource::Player(_, KillType::Buff(_)) => "hud.chat.died_of_pvp_buff_msg",
|
||||||
|
KillSource::Player(_, KillType::Melee) => "hud.chat.pvp_melee_kill_msg",
|
||||||
|
KillSource::Player(_, KillType::Projectile) => "hud.chat.pvp_ranged_kill_msg",
|
||||||
|
KillSource::Player(_, KillType::Explosion) => "hud.chat.pvp_explosion_kill_msg",
|
||||||
|
KillSource::Player(_, KillType::Energy) => "hud.chat.pvp_energy_kill_msg",
|
||||||
|
KillSource::Player(_, KillType::Other) => "hud.chat.pvp_other_kill_msg",
|
||||||
|
KillSource::NonExistent(KillType::Buff(_)) => "hud.chat.died_of_buff_nonexistent_msg",
|
||||||
|
KillSource::NonPlayer(_, KillType::Buff(_)) => "hud.chat.died_of_npc_buff_msg",
|
||||||
|
KillSource::NonPlayer(_, KillType::Melee) => "hud.chat.npc_melee_kill_msg",
|
||||||
|
KillSource::NonPlayer(_, KillType::Projectile) => "hud.chat.npc_ranged_kill_msg",
|
||||||
|
KillSource::NonPlayer(_, KillType::Explosion) => "hud.chat.npc_explosion_kill_msg",
|
||||||
|
KillSource::NonPlayer(_, KillType::Energy) => "hud.chat.npc_energy_kill_msg",
|
||||||
|
KillSource::NonPlayer(_, KillType::Other) => "hud.chat.npc_other_kill_msg",
|
||||||
|
KillSource::Environment(_) => "hud.chat.environmental_kill_msg",
|
||||||
|
KillSource::FallDamage => "hud.chat.fall_kill_msg",
|
||||||
|
KillSource::Suicide => "hud.chat.suicide_msg",
|
||||||
|
KillSource::NonExistent(_) | KillSource::Other => "hud.chat.default_death_msg",
|
||||||
|
},
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -122,6 +122,13 @@ image_ids! {
|
|||||||
settings_button_hover: "voxygen.element.ui.settings.buttons.settings_button_hover",
|
settings_button_hover: "voxygen.element.ui.settings.buttons.settings_button_hover",
|
||||||
settings_button_press: "voxygen.element.ui.settings.buttons.settings_button_press",
|
settings_button_press: "voxygen.element.ui.settings.buttons.settings_button_press",
|
||||||
|
|
||||||
|
settings_plus: "voxygen.element.ui.settings.buttons.settings_button_plus",
|
||||||
|
settings_plus_hover: "voxygen.element.ui.settings.buttons.settings_button_plus_hover",
|
||||||
|
settings_plus_press: "voxygen.element.ui.settings.buttons.settings_button_plus_press",
|
||||||
|
|
||||||
|
chat_tab_settings_bg: "voxygen.element.ui.settings.chat_tab_settings_bg",
|
||||||
|
chat_tab_settings_frame: "voxygen.element.ui.settings.chat_tab_settings_frame",
|
||||||
|
|
||||||
quest_bg: "voxygen.element.ui.quests.temp_quest_bg",
|
quest_bg: "voxygen.element.ui.quests.temp_quest_bg",
|
||||||
|
|
||||||
// Slider
|
// Slider
|
||||||
|
@ -55,9 +55,10 @@ use crate::{
|
|||||||
render::{Consts, Globals, Renderer},
|
render::{Consts, Globals, Renderer},
|
||||||
scene::camera::{self, Camera},
|
scene::camera::{self, Camera},
|
||||||
session::{
|
session::{
|
||||||
settings_change::{Interface as InterfaceChange, SettingsChange},
|
settings_change::{Chat as ChatChange, Interface as InterfaceChange, SettingsChange},
|
||||||
Interactable,
|
Interactable,
|
||||||
},
|
},
|
||||||
|
settings::chat::ChatFilter,
|
||||||
ui::{
|
ui::{
|
||||||
fonts::Fonts, img_ids::Rotations, slot, slot::SlotKey, Graphic, Ingameable, ScaleMode, Ui,
|
fonts::Fonts, img_ids::Rotations, slot, slot::SlotKey, Graphic, Ingameable, ScaleMode, Ui,
|
||||||
},
|
},
|
||||||
@ -466,6 +467,19 @@ pub enum PressBehavior {
|
|||||||
#[serde(other)]
|
#[serde(other)]
|
||||||
Toggle = 0,
|
Toggle = 0,
|
||||||
}
|
}
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct ChatTab {
|
||||||
|
pub label: String,
|
||||||
|
pub filter: ChatFilter,
|
||||||
|
}
|
||||||
|
impl Default for ChatTab {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
label: String::from("Chat"),
|
||||||
|
filter: ChatFilter::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PressBehavior {
|
impl PressBehavior {
|
||||||
pub fn update(&self, keystate: bool, setting: &mut bool, f: impl FnOnce(bool)) {
|
pub fn update(&self, keystate: bool, setting: &mut bool, f: impl FnOnce(bool)) {
|
||||||
@ -503,6 +517,7 @@ pub struct Show {
|
|||||||
open_windows: Windows,
|
open_windows: Windows,
|
||||||
map: bool,
|
map: bool,
|
||||||
ingame: bool,
|
ingame: bool,
|
||||||
|
chat_tab_settings_index: Option<usize>,
|
||||||
settings_tab: SettingsTab,
|
settings_tab: SettingsTab,
|
||||||
skilltreetab: SelectedSkillTree,
|
skilltreetab: SelectedSkillTree,
|
||||||
crafting_tab: CraftingTab,
|
crafting_tab: CraftingTab,
|
||||||
@ -869,6 +884,7 @@ impl Hud {
|
|||||||
diary: false,
|
diary: false,
|
||||||
group: false,
|
group: false,
|
||||||
group_menu: false,
|
group_menu: false,
|
||||||
|
chat_tab_settings_index: None,
|
||||||
settings_tab: SettingsTab::Interface,
|
settings_tab: SettingsTab::Interface,
|
||||||
skilltreetab: SelectedSkillTree::General,
|
skilltreetab: SelectedSkillTree::General,
|
||||||
crafting_tab: CraftingTab::All,
|
crafting_tab: CraftingTab::All,
|
||||||
@ -2585,10 +2601,11 @@ impl Hud {
|
|||||||
.retain(|m| !matches!(m.chat_type, comp::ChatType::Npc(_, _)));
|
.retain(|m| !matches!(m.chat_type, comp::ChatType::Npc(_, _)));
|
||||||
|
|
||||||
// Chat box
|
// Chat box
|
||||||
match Chat::new(
|
for event in Chat::new(
|
||||||
&mut self.new_messages,
|
&mut self.new_messages,
|
||||||
&client,
|
&client,
|
||||||
global_state,
|
global_state,
|
||||||
|
self.pulse,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
i18n,
|
i18n,
|
||||||
@ -2600,16 +2617,25 @@ impl Hud {
|
|||||||
.and_then(self.force_chat_cursor.take(), |c, pos| c.cursor_pos(pos))
|
.and_then(self.force_chat_cursor.take(), |c, pos| c.cursor_pos(pos))
|
||||||
.set(self.ids.chat, ui_widgets)
|
.set(self.ids.chat, ui_widgets)
|
||||||
{
|
{
|
||||||
Some(chat::Event::TabCompletionStart(input)) => {
|
match event {
|
||||||
self.tab_complete = Some(input);
|
chat::Event::TabCompletionStart(input) => {
|
||||||
},
|
self.tab_complete = Some(input);
|
||||||
Some(chat::Event::SendMessage(message)) => {
|
},
|
||||||
events.push(Event::SendMessage(message));
|
chat::Event::SendMessage(message) => {
|
||||||
},
|
events.push(Event::SendMessage(message));
|
||||||
Some(chat::Event::Focus(focus_id)) => {
|
},
|
||||||
self.to_focus = Some(Some(focus_id));
|
chat::Event::Focus(focus_id) => {
|
||||||
},
|
self.to_focus = Some(Some(focus_id));
|
||||||
None => {},
|
},
|
||||||
|
chat::Event::ChangeChatTab(tab) => {
|
||||||
|
events.push(Event::SettingsChange(ChatChange::ChangeChatTab(tab).into()));
|
||||||
|
},
|
||||||
|
chat::Event::ShowChatTabSettings(tab) => {
|
||||||
|
self.show.chat_tab_settings_index = Some(tab);
|
||||||
|
self.show.settings_tab = SettingsTab::Chat;
|
||||||
|
self.show.settings(true);
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.new_messages = VecDeque::new();
|
self.new_messages = VecDeque::new();
|
||||||
@ -2644,6 +2670,9 @@ impl Hud {
|
|||||||
|
|
||||||
self.show.settings(false)
|
self.show.settings(false)
|
||||||
},
|
},
|
||||||
|
settings_window::Event::ChangeChatSettingsTab(tab) => {
|
||||||
|
self.show.chat_tab_settings_index = tab;
|
||||||
|
},
|
||||||
settings_window::Event::SettingsChange(settings_change) => {
|
settings_window::Event::SettingsChange(settings_change) => {
|
||||||
match &settings_change {
|
match &settings_change {
|
||||||
SettingsChange::Interface(interface_change) => match interface_change {
|
SettingsChange::Interface(interface_change) => match interface_change {
|
||||||
|
658
voxygen/src/hud/settings_window/chat.rs
Normal file
658
voxygen/src/hud/settings_window/chat.rs
Normal file
@ -0,0 +1,658 @@
|
|||||||
|
use super::{RESET_BUTTONS_HEIGHT, RESET_BUTTONS_WIDTH};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
hud::{img_ids::Imgs, ChatTab, Show, TEXT_COLOR, TEXT_GRAY_COLOR, UI_HIGHLIGHT_0, UI_MAIN},
|
||||||
|
i18n::Localization,
|
||||||
|
session::settings_change::{Chat as ChatChange, Chat::*},
|
||||||
|
settings::chat::MAX_CHAT_TABS,
|
||||||
|
ui::{fonts::Fonts, ImageSlider, ToggleButton},
|
||||||
|
GlobalState,
|
||||||
|
};
|
||||||
|
use conrod_core::{
|
||||||
|
color,
|
||||||
|
position::Relative,
|
||||||
|
widget::{self, Button, DropDownList, Image, Rectangle, Text, TextEdit},
|
||||||
|
widget_ids, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
|
||||||
|
};
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
widget_ids! {
|
||||||
|
struct Ids {
|
||||||
|
window,
|
||||||
|
window_r,
|
||||||
|
general_txt,
|
||||||
|
transp_text,
|
||||||
|
transp_slider,
|
||||||
|
char_name_text,
|
||||||
|
char_name_button,
|
||||||
|
reset_chat_button,
|
||||||
|
|
||||||
|
//Tabs
|
||||||
|
tabs_frame,
|
||||||
|
tabs_bg,
|
||||||
|
tabs_text,
|
||||||
|
tab_align,
|
||||||
|
tab_add,
|
||||||
|
tabs[],
|
||||||
|
|
||||||
|
//tab content
|
||||||
|
tab_content_align,
|
||||||
|
tab_content_align_r,
|
||||||
|
tab_label_text,
|
||||||
|
tab_label_input,
|
||||||
|
tab_label_bg,
|
||||||
|
btn_tab_delete,
|
||||||
|
|
||||||
|
text_messages,
|
||||||
|
btn_messages_all,
|
||||||
|
text_messages_all,
|
||||||
|
btn_messages_world,
|
||||||
|
text_messages_world,
|
||||||
|
icon_messages_world,
|
||||||
|
btn_messages_region,
|
||||||
|
text_messages_region,
|
||||||
|
icon_messages_region,
|
||||||
|
btn_messages_faction,
|
||||||
|
text_messages_faction,
|
||||||
|
icon_messages_faction,
|
||||||
|
btn_messages_group,
|
||||||
|
text_messages_group,
|
||||||
|
icon_messages_group,
|
||||||
|
btn_messages_say,
|
||||||
|
text_messages_say,
|
||||||
|
icon_messages_say,
|
||||||
|
|
||||||
|
text_activity,
|
||||||
|
list_activity,
|
||||||
|
|
||||||
|
text_death,
|
||||||
|
list_death,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(WidgetCommon)]
|
||||||
|
pub struct Chat<'a> {
|
||||||
|
global_state: &'a GlobalState,
|
||||||
|
show: &'a Show,
|
||||||
|
imgs: &'a Imgs,
|
||||||
|
fonts: &'a Fonts,
|
||||||
|
localized_strings: &'a Localization,
|
||||||
|
#[conrod(common_builder)]
|
||||||
|
common: widget::CommonBuilder,
|
||||||
|
}
|
||||||
|
impl<'a> Chat<'a> {
|
||||||
|
pub fn new(
|
||||||
|
global_state: &'a GlobalState,
|
||||||
|
show: &'a Show,
|
||||||
|
imgs: &'a Imgs,
|
||||||
|
fonts: &'a Fonts,
|
||||||
|
localized_strings: &'a Localization,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
global_state,
|
||||||
|
show,
|
||||||
|
imgs,
|
||||||
|
fonts,
|
||||||
|
localized_strings,
|
||||||
|
common: widget::CommonBuilder::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct State {
|
||||||
|
ids: Ids,
|
||||||
|
}
|
||||||
|
pub enum Event {
|
||||||
|
ChangeChatSettingsTab(Option<usize>),
|
||||||
|
ChatChange(ChatChange),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Widget for Chat<'a> {
|
||||||
|
type Event = Vec<Event>;
|
||||||
|
type State = State;
|
||||||
|
type Style = ();
|
||||||
|
|
||||||
|
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
|
||||||
|
State {
|
||||||
|
ids: Ids::new(id_gen),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unused_unit)] // TODO: Pending review in #587
|
||||||
|
fn style(&self) -> Self::Style { () }
|
||||||
|
|
||||||
|
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
|
||||||
|
let widget::UpdateArgs { state, ui, .. } = args;
|
||||||
|
|
||||||
|
let mut events = Vec::new();
|
||||||
|
let chat_settings = &self.global_state.settings.chat;
|
||||||
|
// Alignment
|
||||||
|
// Settings Window
|
||||||
|
Rectangle::fill_with(args.rect.dim(), color::TRANSPARENT)
|
||||||
|
.xy(args.rect.xy())
|
||||||
|
.graphics_for(args.id)
|
||||||
|
.scroll_kids()
|
||||||
|
.scroll_kids_vertically()
|
||||||
|
.set(state.ids.window, ui);
|
||||||
|
// Right Side
|
||||||
|
Rectangle::fill_with([args.rect.w() / 2.0, args.rect.h()], color::TRANSPARENT)
|
||||||
|
.top_right_of(state.ids.window)
|
||||||
|
.set(state.ids.window_r, ui);
|
||||||
|
|
||||||
|
// General Title
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.general"))
|
||||||
|
.top_left_with_margins_on(state.ids.window, 5.0, 5.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(18))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.general_txt, ui);
|
||||||
|
|
||||||
|
// Chat Transp
|
||||||
|
Text::new(
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.background_transparency"),
|
||||||
|
)
|
||||||
|
.down_from(state.ids.general_txt, 20.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.transp_text, ui);
|
||||||
|
if let Some(new_val) = ImageSlider::continuous(
|
||||||
|
chat_settings.chat_transp,
|
||||||
|
0.0,
|
||||||
|
0.9,
|
||||||
|
self.imgs.slider_indicator,
|
||||||
|
self.imgs.slider,
|
||||||
|
)
|
||||||
|
.w_h(104.0, 22.0)
|
||||||
|
.down_from(state.ids.transp_text, 10.0)
|
||||||
|
.track_breadth(12.0)
|
||||||
|
.slider_length(10.0)
|
||||||
|
.pad_track((5.0, 5.0))
|
||||||
|
.set(state.ids.transp_slider, ui)
|
||||||
|
{
|
||||||
|
events.push(Event::ChatChange(Transp(new_val)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Show character names in chat" toggle button
|
||||||
|
Text::new(
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.chat_character_name"),
|
||||||
|
)
|
||||||
|
.down_from(state.ids.transp_slider, 10.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.char_name_text, ui);
|
||||||
|
|
||||||
|
if chat_settings.chat_character_name
|
||||||
|
!= ToggleButton::new(
|
||||||
|
chat_settings.chat_character_name,
|
||||||
|
self.imgs.checkbox,
|
||||||
|
self.imgs.checkbox_checked,
|
||||||
|
)
|
||||||
|
.w_h(18.0, 18.0)
|
||||||
|
.right_from(state.ids.char_name_text, 10.0)
|
||||||
|
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||||
|
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||||
|
.set(state.ids.char_name_button, ui)
|
||||||
|
{
|
||||||
|
events.push(Event::ChatChange(CharName(
|
||||||
|
!chat_settings.chat_character_name,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the chat settings to the default settings
|
||||||
|
if Button::image(self.imgs.button)
|
||||||
|
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
|
||||||
|
.hover_image(self.imgs.button_hover)
|
||||||
|
.press_image(self.imgs.button_press)
|
||||||
|
.down_from(state.ids.char_name_text, 20.0)
|
||||||
|
.label(&self.localized_strings.get("hud.settings.reset_chat"))
|
||||||
|
.label_font_size(self.fonts.cyri.scale(14))
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_y(Relative::Scalar(2.0))
|
||||||
|
.set(state.ids.reset_chat_button, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::ChatChange(ResetChatSettings));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tabs Title
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.chat_tabs"))
|
||||||
|
.top_left_with_margins_on(state.ids.window_r, 5.0, 5.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(18))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.tabs_text, ui);
|
||||||
|
|
||||||
|
// bg and frame
|
||||||
|
Image::new(self.imgs.chat_tab_settings_bg)
|
||||||
|
.w_h(390.0, 270.0)
|
||||||
|
.color(Some(UI_MAIN))
|
||||||
|
.down_from(state.ids.tabs_text, 20.0)
|
||||||
|
.set(state.ids.tabs_bg, ui);
|
||||||
|
|
||||||
|
Image::new(self.imgs.chat_tab_settings_frame)
|
||||||
|
.w_h(390.0, 270.0)
|
||||||
|
.color(Some(UI_HIGHLIGHT_0))
|
||||||
|
.down_from(state.ids.tabs_text, 20.0)
|
||||||
|
.set(state.ids.tabs_frame, ui);
|
||||||
|
|
||||||
|
// Tabs Alignment
|
||||||
|
Rectangle::fill_with([390.0, 20.0], color::TRANSPARENT)
|
||||||
|
.down_from(state.ids.tabs_text, 20.0)
|
||||||
|
.set(state.ids.tab_align, ui);
|
||||||
|
|
||||||
|
// Tabs Settings Alignment
|
||||||
|
Rectangle::fill_with([390.0, 250.0], color::TRANSPARENT)
|
||||||
|
.down_from(state.ids.tab_align, 0.0)
|
||||||
|
.set(state.ids.tab_content_align, ui);
|
||||||
|
Rectangle::fill_with([195.0, 250.0], color::TRANSPARENT)
|
||||||
|
.top_right_of(state.ids.tab_content_align)
|
||||||
|
.set(state.ids.tab_content_align_r, ui);
|
||||||
|
|
||||||
|
let chat_tabs = &chat_settings.chat_tabs;
|
||||||
|
if state.ids.tabs.len() < chat_tabs.len() {
|
||||||
|
state.update(|s| {
|
||||||
|
s.ids
|
||||||
|
.tabs
|
||||||
|
.resize(chat_tabs.len(), &mut ui.widget_id_generator())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (i, chat_tab) in chat_tabs.iter().enumerate() {
|
||||||
|
let is_selected = self
|
||||||
|
.show
|
||||||
|
.chat_tab_settings_index
|
||||||
|
.map(|index| index == i)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
let button = Button::image(if is_selected {
|
||||||
|
self.imgs.selection
|
||||||
|
} else {
|
||||||
|
self.imgs.nothing
|
||||||
|
})
|
||||||
|
.w_h(390.0 / (MAX_CHAT_TABS as f64), 19.0)
|
||||||
|
.hover_image(self.imgs.selection_hover)
|
||||||
|
.press_image(self.imgs.selection_press)
|
||||||
|
.label(chat_tab.label.as_str())
|
||||||
|
.label_font_size(self.fonts.cyri.scale(12))
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_y(Relative::Scalar(1.0));
|
||||||
|
|
||||||
|
let button = if i == 0 {
|
||||||
|
button.top_left_with_margins_on(state.ids.tab_align, 1.0, 1.0)
|
||||||
|
} else {
|
||||||
|
button.right_from(state.ids.tabs[i - 1], 0.0)
|
||||||
|
};
|
||||||
|
if button.set(state.ids.tabs[i], ui).was_clicked() {
|
||||||
|
events.push(Event::ChangeChatSettingsTab(if is_selected {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(i)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Add button
|
||||||
|
if chat_tabs.len() < MAX_CHAT_TABS {
|
||||||
|
let add_tab_button = Button::image(self.imgs.settings_plus)
|
||||||
|
.hover_image(self.imgs.settings_plus_hover)
|
||||||
|
.press_image(self.imgs.settings_plus_press)
|
||||||
|
.w_h(19.0, 19.0);
|
||||||
|
|
||||||
|
let add_tab_button = if chat_tabs.is_empty() {
|
||||||
|
add_tab_button.top_left_with_margins_on(state.ids.tab_align, 1.0, 1.0)
|
||||||
|
} else {
|
||||||
|
add_tab_button.right_from(state.ids.tabs[chat_tabs.len() - 1], 0.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
if add_tab_button.set(state.ids.tab_add, ui).was_clicked() {
|
||||||
|
let index = chat_tabs.len();
|
||||||
|
events.push(Event::ChatChange(ChatTabInsert(index, ChatTab::default())));
|
||||||
|
events.push(Event::ChangeChatSettingsTab(Some(index)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Content
|
||||||
|
if let Some((index, chat_tab)) = self
|
||||||
|
.show
|
||||||
|
.chat_tab_settings_index
|
||||||
|
.and_then(|i| chat_tabs.get(i).map(|ct| (i, ct)))
|
||||||
|
{
|
||||||
|
let mut updated_chat_tab = chat_tab.clone();
|
||||||
|
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.label"))
|
||||||
|
.top_left_with_margins_on(state.ids.tab_content_align, 5.0, 25.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(16))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.tab_label_text, ui);
|
||||||
|
|
||||||
|
Rectangle::fill([90.0, 20.0])
|
||||||
|
.right_from(state.ids.tab_label_text, 5.0)
|
||||||
|
.color(color::rgba(0.0, 0.0, 0.0, 0.7))
|
||||||
|
.set(state.ids.tab_label_bg, ui);
|
||||||
|
|
||||||
|
if let Some(label) = TextEdit::new(chat_tab.label.as_str())
|
||||||
|
.right_from(state.ids.tab_label_text, 10.0)
|
||||||
|
.y_relative_to(state.ids.tab_label_text, -3.0)
|
||||||
|
.w_h(75.0, 20.0)
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.tab_label_input, ui)
|
||||||
|
{
|
||||||
|
updated_chat_tab.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
if Button::image(self.imgs.button)
|
||||||
|
.hover_image(self.imgs.button_hover)
|
||||||
|
.press_image(self.imgs.button_press)
|
||||||
|
.w_h(100.0, 30.0)
|
||||||
|
.label(&self.localized_strings.get("hud.settings.delete"))
|
||||||
|
.label_font_size(self.fonts.cyri.scale(14))
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_y(Relative::Scalar(1.0))
|
||||||
|
.bottom_right_with_margins_on(state.ids.tab_content_align, 10.0, 10.0)
|
||||||
|
.set(state.ids.btn_tab_delete, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::ChatChange(ChatTabRemove(index)));
|
||||||
|
events.push(Event::ChangeChatSettingsTab(None));
|
||||||
|
|
||||||
|
if let Some(chat_tab_index) = chat_settings.chat_tab_index {
|
||||||
|
match chat_tab_index.cmp(&index) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
events.push(Event::ChatChange(ChangeChatTab(None)));
|
||||||
|
},
|
||||||
|
Ordering::Greater => {
|
||||||
|
events.push(Event::ChatChange(ChangeChatTab(Some(index - 1))));
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//helper methods to reduce on repeated code
|
||||||
|
//(TODO: perhaps introduce a checkbox with label widget)
|
||||||
|
let create_toggle = |selected, enabled| {
|
||||||
|
ToggleButton::new(selected, self.imgs.checkbox, self.imgs.checkbox_checked)
|
||||||
|
.and(|button| {
|
||||||
|
if enabled {
|
||||||
|
button
|
||||||
|
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||||
|
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||||
|
} else {
|
||||||
|
button.image_colors(TEXT_GRAY_COLOR, TEXT_GRAY_COLOR)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.w_h(16.0, 16.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
let create_toggle_text = |text, enabled| {
|
||||||
|
Text::new(text)
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.color(if enabled { TEXT_COLOR } else { TEXT_GRAY_COLOR })
|
||||||
|
};
|
||||||
|
|
||||||
|
let create_toggle_icon = |img, enabled: bool| {
|
||||||
|
Image::new(img)
|
||||||
|
.and_if(!enabled, |image| image.color(Some(TEXT_GRAY_COLOR)))
|
||||||
|
.w_h(18.0, 18.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
//Messages
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.messages"))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.font_size(self.fonts.cyri.scale(16))
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.top_left_with_margins_on(state.ids.tab_content_align, 35.0, 15.0)
|
||||||
|
.set(state.ids.text_messages, ui);
|
||||||
|
|
||||||
|
// Toggle all options
|
||||||
|
if chat_tab.filter.message_all
|
||||||
|
!= ToggleButton::new(
|
||||||
|
chat_tab.filter.message_all,
|
||||||
|
self.imgs.checkbox,
|
||||||
|
self.imgs.checkbox_checked,
|
||||||
|
)
|
||||||
|
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||||
|
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||||
|
.w_h(18.0, 18.0)
|
||||||
|
.down_from(state.ids.text_messages, 10.0)
|
||||||
|
.set(state.ids.btn_messages_all, ui)
|
||||||
|
{
|
||||||
|
updated_chat_tab.filter.message_all = !chat_tab.filter.message_all;
|
||||||
|
};
|
||||||
|
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.show_all"))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.font_size(self.fonts.cyri.scale(16))
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.right_from(state.ids.btn_messages_all, 5.0)
|
||||||
|
.set(state.ids.text_messages_all, ui);
|
||||||
|
|
||||||
|
//Messages - group
|
||||||
|
if chat_tab.filter.message_group
|
||||||
|
!= create_toggle(chat_tab.filter.message_group, !chat_tab.filter.message_all)
|
||||||
|
.down_from(state.ids.btn_messages_all, 10.0)
|
||||||
|
.set(state.ids.btn_messages_group, ui)
|
||||||
|
&& !chat_tab.filter.message_all
|
||||||
|
{
|
||||||
|
updated_chat_tab.filter.message_group = !chat_tab.filter.message_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_toggle_text(
|
||||||
|
&self.localized_strings.get("hud.settings.group"),
|
||||||
|
!chat_tab.filter.message_all,
|
||||||
|
)
|
||||||
|
.right_from(state.ids.btn_messages_group, 5.0)
|
||||||
|
.set(state.ids.text_messages_group, ui);
|
||||||
|
|
||||||
|
create_toggle_icon(self.imgs.chat_group_small, !chat_tab.filter.message_all)
|
||||||
|
.right_from(state.ids.text_messages_group, 5.0)
|
||||||
|
.set(state.ids.icon_messages_group, ui);
|
||||||
|
|
||||||
|
//Messages - faction
|
||||||
|
if chat_tab.filter.message_faction
|
||||||
|
!= create_toggle(
|
||||||
|
chat_tab.filter.message_faction,
|
||||||
|
!chat_tab.filter.message_all,
|
||||||
|
)
|
||||||
|
.down_from(state.ids.btn_messages_group, 10.0)
|
||||||
|
.set(state.ids.btn_messages_faction, ui)
|
||||||
|
&& !chat_tab.filter.message_all
|
||||||
|
{
|
||||||
|
updated_chat_tab.filter.message_faction = !chat_tab.filter.message_faction;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_toggle_text(
|
||||||
|
&self.localized_strings.get("hud.settings.faction"),
|
||||||
|
!chat_tab.filter.message_all,
|
||||||
|
)
|
||||||
|
.right_from(state.ids.btn_messages_faction, 5.0)
|
||||||
|
.set(state.ids.text_messages_faction, ui);
|
||||||
|
|
||||||
|
create_toggle_icon(self.imgs.chat_faction_small, !chat_tab.filter.message_all)
|
||||||
|
.right_from(state.ids.text_messages_faction, 5.0)
|
||||||
|
.set(state.ids.icon_messages_faction, ui);
|
||||||
|
|
||||||
|
//Messages - world
|
||||||
|
if chat_tab.filter.message_world
|
||||||
|
!= create_toggle(chat_tab.filter.message_world, !chat_tab.filter.message_all)
|
||||||
|
.down_from(state.ids.btn_messages_faction, 10.0)
|
||||||
|
.set(state.ids.btn_messages_world, ui)
|
||||||
|
&& !chat_tab.filter.message_all
|
||||||
|
{
|
||||||
|
updated_chat_tab.filter.message_world = !chat_tab.filter.message_world;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_toggle_text(
|
||||||
|
&self.localized_strings.get("hud.settings.world"),
|
||||||
|
!chat_tab.filter.message_all,
|
||||||
|
)
|
||||||
|
.right_from(state.ids.btn_messages_world, 5.0)
|
||||||
|
.set(state.ids.text_messages_world, ui);
|
||||||
|
|
||||||
|
create_toggle_icon(self.imgs.chat_world_small, !chat_tab.filter.message_all)
|
||||||
|
.right_from(state.ids.text_messages_world, 5.0)
|
||||||
|
.set(state.ids.icon_messages_world, ui);
|
||||||
|
|
||||||
|
//Messages - region
|
||||||
|
if chat_tab.filter.message_region
|
||||||
|
!= create_toggle(chat_tab.filter.message_region, !chat_tab.filter.message_all)
|
||||||
|
.down_from(state.ids.btn_messages_world, 10.0)
|
||||||
|
.set(state.ids.btn_messages_region, ui)
|
||||||
|
&& !chat_tab.filter.message_all
|
||||||
|
{
|
||||||
|
updated_chat_tab.filter.message_region = !chat_tab.filter.message_region;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_toggle_text(
|
||||||
|
&self.localized_strings.get("hud.settings.region"),
|
||||||
|
!chat_tab.filter.message_all,
|
||||||
|
)
|
||||||
|
.right_from(state.ids.btn_messages_region, 5.0)
|
||||||
|
.set(state.ids.text_messages_region, ui);
|
||||||
|
|
||||||
|
create_toggle_icon(self.imgs.chat_region_small, !chat_tab.filter.message_all)
|
||||||
|
.right_from(state.ids.text_messages_region, 5.0)
|
||||||
|
.set(state.ids.icon_messages_region, ui);
|
||||||
|
|
||||||
|
//Messages - say
|
||||||
|
if chat_tab.filter.message_say
|
||||||
|
!= create_toggle(chat_tab.filter.message_say, !chat_tab.filter.message_all)
|
||||||
|
.down_from(state.ids.btn_messages_region, 10.0)
|
||||||
|
.set(state.ids.btn_messages_say, ui)
|
||||||
|
&& !chat_tab.filter.message_all
|
||||||
|
{
|
||||||
|
updated_chat_tab.filter.message_say = !chat_tab.filter.message_say;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_toggle_text(
|
||||||
|
&self.localized_strings.get("hud.settings.say"),
|
||||||
|
!chat_tab.filter.message_all,
|
||||||
|
)
|
||||||
|
.right_from(state.ids.btn_messages_say, 5.0)
|
||||||
|
.set(state.ids.text_messages_say, ui);
|
||||||
|
|
||||||
|
create_toggle_icon(self.imgs.chat_say_small, !chat_tab.filter.message_all)
|
||||||
|
.right_from(state.ids.text_messages_say, 5.0)
|
||||||
|
.set(state.ids.icon_messages_say, ui);
|
||||||
|
|
||||||
|
//Activity
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.activity"))
|
||||||
|
.top_left_with_margins_on(state.ids.tab_content_align_r, 0.0, 5.0)
|
||||||
|
.align_middle_y_of(state.ids.text_messages)
|
||||||
|
.font_size(self.fonts.cyri.scale(16))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.text_activity, ui);
|
||||||
|
|
||||||
|
if let Some(clicked) = DropDownList::new(
|
||||||
|
&[
|
||||||
|
&self.localized_strings.get("hud.settings.none"),
|
||||||
|
&self.localized_strings.get("hud.settings.all"),
|
||||||
|
&self.localized_strings.get("hud.settings.group_only"),
|
||||||
|
],
|
||||||
|
Some(if chat_tab.filter.activity_all {
|
||||||
|
//all
|
||||||
|
1
|
||||||
|
} else if chat_tab.filter.activity_group {
|
||||||
|
//group only
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
//none
|
||||||
|
0
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.w_h(100.0, 20.0)
|
||||||
|
.color(color::hsl(0.0, 0.0, 0.1))
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_font_size(self.fonts.cyri.scale(14))
|
||||||
|
.label_y(Relative::Scalar(1.0))
|
||||||
|
.down_from(state.ids.text_activity, 10.0)
|
||||||
|
.set(state.ids.list_activity, ui)
|
||||||
|
{
|
||||||
|
match clicked {
|
||||||
|
0 => {
|
||||||
|
updated_chat_tab.filter.activity_all = false;
|
||||||
|
updated_chat_tab.filter.activity_group = false;
|
||||||
|
},
|
||||||
|
1 => {
|
||||||
|
updated_chat_tab.filter.activity_all = true;
|
||||||
|
},
|
||||||
|
2 => {
|
||||||
|
updated_chat_tab.filter.activity_all = false;
|
||||||
|
updated_chat_tab.filter.activity_group = true;
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Death
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.death"))
|
||||||
|
.down_from(state.ids.list_activity, 20.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(16))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.text_death, ui);
|
||||||
|
|
||||||
|
if let Some(clicked) = DropDownList::new(
|
||||||
|
&[
|
||||||
|
&self.localized_strings.get("hud.settings.none"),
|
||||||
|
&self.localized_strings.get("hud.settings.all"),
|
||||||
|
&self.localized_strings.get("hud.settings.group_only"),
|
||||||
|
],
|
||||||
|
Some(if chat_tab.filter.death_all {
|
||||||
|
//all
|
||||||
|
1
|
||||||
|
} else if chat_tab.filter.death_group {
|
||||||
|
//group only
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
//none
|
||||||
|
0
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.w_h(100.0, 20.0)
|
||||||
|
.color(color::hsl(0.0, 0.0, 0.1))
|
||||||
|
.label_color(TEXT_COLOR)
|
||||||
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.label_font_size(self.fonts.cyri.scale(14))
|
||||||
|
.label_y(Relative::Scalar(1.0))
|
||||||
|
.down_from(state.ids.text_death, 10.0)
|
||||||
|
.set(state.ids.list_death, ui)
|
||||||
|
{
|
||||||
|
match clicked {
|
||||||
|
0 => {
|
||||||
|
updated_chat_tab.filter.death_all = false;
|
||||||
|
updated_chat_tab.filter.death_group = false;
|
||||||
|
},
|
||||||
|
1 => {
|
||||||
|
updated_chat_tab.filter.death_all = true;
|
||||||
|
},
|
||||||
|
2 => {
|
||||||
|
updated_chat_tab.filter.death_all = false;
|
||||||
|
updated_chat_tab.filter.death_group = true;
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if chat_tab != &updated_chat_tab {
|
||||||
|
//insert to front to avoid errors where the tab is moved or removed
|
||||||
|
events.insert(0, Event::ChatChange(ChatTabUpdate(index, updated_chat_tab)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
events
|
||||||
|
}
|
||||||
|
}
|
@ -66,12 +66,6 @@ widget_ids! {
|
|||||||
buff_pos_map_button,
|
buff_pos_map_button,
|
||||||
buff_pos_map_text,
|
buff_pos_map_text,
|
||||||
//
|
//
|
||||||
chat_transp_title,
|
|
||||||
chat_transp_text,
|
|
||||||
chat_transp_slider,
|
|
||||||
chat_char_name_text,
|
|
||||||
chat_char_name_button,
|
|
||||||
//
|
|
||||||
sct_title,
|
sct_title,
|
||||||
sct_show_text,
|
sct_show_text,
|
||||||
sct_show_radio,
|
sct_show_radio,
|
||||||
@ -164,7 +158,6 @@ impl<'a> Widget for Interface<'a> {
|
|||||||
let crosshair_transp = self.global_state.settings.interface.crosshair_transp;
|
let crosshair_transp = self.global_state.settings.interface.crosshair_transp;
|
||||||
let crosshair_type = self.global_state.settings.interface.crosshair_type;
|
let crosshair_type = self.global_state.settings.interface.crosshair_type;
|
||||||
let ui_scale = self.global_state.settings.interface.ui_scale;
|
let ui_scale = self.global_state.settings.interface.ui_scale;
|
||||||
let chat_transp = self.global_state.settings.interface.chat_transp;
|
|
||||||
|
|
||||||
Text::new(&self.localized_strings.get("hud.settings.general"))
|
Text::new(&self.localized_strings.get("hud.settings.general"))
|
||||||
.top_left_with_margins_on(state.ids.window, 5.0, 5.0)
|
.top_left_with_margins_on(state.ids.window, 5.0, 5.0)
|
||||||
@ -942,70 +935,6 @@ impl<'a> Widget for Interface<'a> {
|
|||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.set(state.ids.show_bar_numbers_percentage_text, ui);
|
.set(state.ids.show_bar_numbers_percentage_text, ui);
|
||||||
|
|
||||||
// Chat Transp
|
|
||||||
Text::new(&self.localized_strings.get("hud.settings.chat"))
|
|
||||||
.down_from(state.ids.show_bar_numbers_percentage_button, 20.0)
|
|
||||||
.font_size(self.fonts.cyri.scale(18))
|
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
|
||||||
.color(TEXT_COLOR)
|
|
||||||
.set(state.ids.chat_transp_title, ui);
|
|
||||||
Text::new(
|
|
||||||
&self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.settings.background_transparency"),
|
|
||||||
)
|
|
||||||
.right_from(state.ids.chat_transp_slider, 20.0)
|
|
||||||
.font_size(self.fonts.cyri.scale(14))
|
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
|
||||||
.color(TEXT_COLOR)
|
|
||||||
.set(state.ids.chat_transp_text, ui);
|
|
||||||
|
|
||||||
if let Some(new_val) = ImageSlider::continuous(
|
|
||||||
chat_transp,
|
|
||||||
0.0,
|
|
||||||
0.9,
|
|
||||||
self.imgs.slider_indicator,
|
|
||||||
self.imgs.slider,
|
|
||||||
)
|
|
||||||
.w_h(104.0, 22.0)
|
|
||||||
.down_from(state.ids.chat_transp_title, 8.0)
|
|
||||||
.track_breadth(12.0)
|
|
||||||
.slider_length(10.0)
|
|
||||||
.pad_track((5.0, 5.0))
|
|
||||||
.set(state.ids.chat_transp_slider, ui)
|
|
||||||
{
|
|
||||||
events.push(ChatTransp(new_val));
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Show character names in chat" toggle button
|
|
||||||
let chat_char_name = ToggleButton::new(
|
|
||||||
self.global_state.settings.interface.chat_character_name,
|
|
||||||
self.imgs.checkbox,
|
|
||||||
self.imgs.checkbox_checked,
|
|
||||||
)
|
|
||||||
.w_h(18.0, 18.0)
|
|
||||||
.down_from(state.ids.chat_transp_slider, 20.0)
|
|
||||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
|
||||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
|
||||||
.set(state.ids.chat_char_name_button, ui);
|
|
||||||
if self.global_state.settings.interface.chat_character_name != chat_char_name {
|
|
||||||
events.push(ChatCharName(
|
|
||||||
!self.global_state.settings.interface.chat_character_name,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Text::new(
|
|
||||||
&self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.settings.chat_character_name"),
|
|
||||||
)
|
|
||||||
.right_from(state.ids.chat_char_name_button, 20.0)
|
|
||||||
.font_size(self.fonts.cyri.scale(14))
|
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
|
||||||
.color(TEXT_COLOR)
|
|
||||||
.set(state.ids.chat_char_name_text, ui);
|
|
||||||
|
|
||||||
// TODO Show account name in chat
|
|
||||||
|
|
||||||
// Reset the interface settings to the default settings
|
// Reset the interface settings to the default settings
|
||||||
if Button::image(self.imgs.button)
|
if Button::image(self.imgs.button)
|
||||||
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
|
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mod chat;
|
||||||
mod controls;
|
mod controls;
|
||||||
mod gameplay;
|
mod gameplay;
|
||||||
mod interface;
|
mod interface;
|
||||||
@ -38,6 +39,7 @@ widget_ids! {
|
|||||||
video,
|
video,
|
||||||
sound,
|
sound,
|
||||||
language,
|
language,
|
||||||
|
chat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ const RESET_BUTTONS_WIDTH: f64 = 155.0;
|
|||||||
#[derive(Debug, EnumIter, PartialEq)]
|
#[derive(Debug, EnumIter, PartialEq)]
|
||||||
pub enum SettingsTab {
|
pub enum SettingsTab {
|
||||||
Interface,
|
Interface,
|
||||||
|
Chat,
|
||||||
Video,
|
Video,
|
||||||
Sound,
|
Sound,
|
||||||
Gameplay,
|
Gameplay,
|
||||||
@ -57,6 +60,7 @@ impl SettingsTab {
|
|||||||
fn name_key(&self) -> &str {
|
fn name_key(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
SettingsTab::Interface => "common.interface",
|
SettingsTab::Interface => "common.interface",
|
||||||
|
SettingsTab::Chat => "common.chat",
|
||||||
SettingsTab::Gameplay => "common.gameplay",
|
SettingsTab::Gameplay => "common.gameplay",
|
||||||
SettingsTab::Controls => "common.controls",
|
SettingsTab::Controls => "common.controls",
|
||||||
SettingsTab::Video => "common.video",
|
SettingsTab::Video => "common.video",
|
||||||
@ -68,6 +72,7 @@ impl SettingsTab {
|
|||||||
fn title_key(&self) -> &str {
|
fn title_key(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
SettingsTab::Interface => "common.interface_settings",
|
SettingsTab::Interface => "common.interface_settings",
|
||||||
|
SettingsTab::Chat => "common.chat_settings",
|
||||||
SettingsTab::Gameplay => "common.gameplay_settings",
|
SettingsTab::Gameplay => "common.gameplay_settings",
|
||||||
SettingsTab::Controls => "common.controls_settings",
|
SettingsTab::Controls => "common.controls_settings",
|
||||||
SettingsTab::Video => "common.video_settings",
|
SettingsTab::Video => "common.video_settings",
|
||||||
@ -118,6 +123,7 @@ pub enum Event {
|
|||||||
ChangeTab(SettingsTab),
|
ChangeTab(SettingsTab),
|
||||||
Close,
|
Close,
|
||||||
SettingsChange(SettingsChange),
|
SettingsChange(SettingsChange),
|
||||||
|
ChangeChatSettingsTab(Option<usize>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -250,6 +256,23 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
events.push(Event::SettingsChange(change.into()));
|
events.push(Event::SettingsChange(change.into()));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
SettingsTab::Chat => {
|
||||||
|
for event in
|
||||||
|
chat::Chat::new(global_state, self.show, imgs, fonts, localized_strings)
|
||||||
|
.top_left_with_margins_on(state.ids.settings_content_align, 0.0, 0.0)
|
||||||
|
.wh_of(state.ids.settings_content_align)
|
||||||
|
.set(state.ids.chat, ui)
|
||||||
|
{
|
||||||
|
match event {
|
||||||
|
chat::Event::ChatChange(change) => {
|
||||||
|
events.push(Event::SettingsChange(change.into()));
|
||||||
|
},
|
||||||
|
chat::Event::ChangeChatSettingsTab(index) => {
|
||||||
|
events.push(Event::ChangeChatSettingsTab(index));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
SettingsTab::Gameplay => {
|
SettingsTab::Gameplay => {
|
||||||
for change in gameplay::Gameplay::new(global_state, imgs, fonts, localized_strings)
|
for change in gameplay::Gameplay::new(global_state, imgs, fonts, localized_strings)
|
||||||
.top_left_with_margins_on(state.ids.settings_content_align, 0.0, 0.0)
|
.top_left_with_margins_on(state.ids.settings_content_align, 0.0, 0.0)
|
||||||
|
@ -2,14 +2,14 @@ use super::SessionState;
|
|||||||
use crate::{
|
use crate::{
|
||||||
controller::ControllerSettings,
|
controller::ControllerSettings,
|
||||||
hud::{
|
hud::{
|
||||||
BarNumbers, BuffPosition, CrosshairType, Intro, PressBehavior, ScaleChange,
|
BarNumbers, BuffPosition, ChatTab, CrosshairType, Intro, PressBehavior, ScaleChange,
|
||||||
ShortcutNumbers, XpBar,
|
ShortcutNumbers, XpBar,
|
||||||
},
|
},
|
||||||
i18n::{LanguageMetadata, LocalizationHandle},
|
i18n::{LanguageMetadata, LocalizationHandle},
|
||||||
render::RenderMode,
|
render::RenderMode,
|
||||||
settings::{
|
settings::{
|
||||||
AudioSettings, ControlSettings, Fps, GamepadSettings, GameplaySettings, GraphicsSettings,
|
AudioSettings, ChatSettings, ControlSettings, Fps, GamepadSettings, GameplaySettings,
|
||||||
InterfaceSettings,
|
GraphicsSettings, InterfaceSettings,
|
||||||
},
|
},
|
||||||
window::{FullScreenSettings, GameInput},
|
window::{FullScreenSettings, GameInput},
|
||||||
GlobalState,
|
GlobalState,
|
||||||
@ -26,6 +26,17 @@ pub enum Audio {
|
|||||||
ResetAudioSettings,
|
ResetAudioSettings,
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
pub enum Chat {
|
||||||
|
Transp(f32),
|
||||||
|
CharName(bool),
|
||||||
|
ChangeChatTab(Option<usize>),
|
||||||
|
ChatTabUpdate(usize, ChatTab),
|
||||||
|
ChatTabInsert(usize, ChatTab),
|
||||||
|
ChatTabMove(usize, usize), //(i, j) move item from position i, and insert into position j
|
||||||
|
ChatTabRemove(usize),
|
||||||
|
ResetChatSettings,
|
||||||
|
}
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum Control {
|
pub enum Control {
|
||||||
ChangeBinding(GameInput),
|
ChangeBinding(GameInput),
|
||||||
ResetKeyBindings,
|
ResetKeyBindings,
|
||||||
@ -88,8 +99,6 @@ pub enum Interface {
|
|||||||
ToggleTips(bool),
|
ToggleTips(bool),
|
||||||
|
|
||||||
CrosshairTransp(f32),
|
CrosshairTransp(f32),
|
||||||
ChatTransp(f32),
|
|
||||||
ChatCharName(bool),
|
|
||||||
CrosshairType(CrosshairType),
|
CrosshairType(CrosshairType),
|
||||||
Intro(Intro),
|
Intro(Intro),
|
||||||
ToggleXpBar(XpBar),
|
ToggleXpBar(XpBar),
|
||||||
@ -127,6 +136,7 @@ pub enum Networking {}
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum SettingsChange {
|
pub enum SettingsChange {
|
||||||
Audio(Audio),
|
Audio(Audio),
|
||||||
|
Chat(Chat),
|
||||||
Control(Control),
|
Control(Control),
|
||||||
Gamepad(Gamepad),
|
Gamepad(Gamepad),
|
||||||
Gameplay(Gameplay),
|
Gameplay(Gameplay),
|
||||||
@ -144,6 +154,7 @@ macro_rules! settings_change_from {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
settings_change_from!(Audio);
|
settings_change_from!(Audio);
|
||||||
|
settings_change_from!(Chat);
|
||||||
settings_change_from!(Control);
|
settings_change_from!(Control);
|
||||||
settings_change_from!(Gamepad);
|
settings_change_from!(Gamepad);
|
||||||
settings_change_from!(Gameplay);
|
settings_change_from!(Gameplay);
|
||||||
@ -190,6 +201,46 @@ impl SettingsChange {
|
|||||||
}
|
}
|
||||||
settings.save_to_file_warn();
|
settings.save_to_file_warn();
|
||||||
},
|
},
|
||||||
|
SettingsChange::Chat(chat_change) => {
|
||||||
|
let chat_tabs = &mut settings.chat.chat_tabs;
|
||||||
|
match chat_change {
|
||||||
|
Chat::Transp(chat_transp) => {
|
||||||
|
settings.chat.chat_transp = chat_transp;
|
||||||
|
},
|
||||||
|
Chat::CharName(chat_char_name) => {
|
||||||
|
settings.chat.chat_character_name = chat_char_name;
|
||||||
|
},
|
||||||
|
Chat::ChangeChatTab(chat_tab_index) => {
|
||||||
|
settings.chat.chat_tab_index =
|
||||||
|
chat_tab_index.filter(|i| *i < chat_tabs.len());
|
||||||
|
},
|
||||||
|
Chat::ChatTabUpdate(i, chat_tab) => {
|
||||||
|
if i < chat_tabs.len() {
|
||||||
|
chat_tabs[i] = chat_tab;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Chat::ChatTabInsert(i, chat_tab) => {
|
||||||
|
if i <= chat_tabs.len() {
|
||||||
|
settings.chat.chat_tabs.insert(i, chat_tab);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Chat::ChatTabMove(i, j) => {
|
||||||
|
if i < chat_tabs.len() && j < chat_tabs.len() {
|
||||||
|
let chat_tab = settings.chat.chat_tabs.remove(i);
|
||||||
|
settings.chat.chat_tabs.insert(j, chat_tab);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Chat::ChatTabRemove(i) => {
|
||||||
|
if i < chat_tabs.len() {
|
||||||
|
settings.chat.chat_tabs.remove(i);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Chat::ResetChatSettings => {
|
||||||
|
settings.chat = ChatSettings::default();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
settings.save_to_file_warn();
|
||||||
|
},
|
||||||
SettingsChange::Control(control_change) => match control_change {
|
SettingsChange::Control(control_change) => match control_change {
|
||||||
Control::ChangeBinding(game_input) => {
|
Control::ChangeBinding(game_input) => {
|
||||||
global_state.window.set_keybinding_mode(game_input);
|
global_state.window.set_keybinding_mode(game_input);
|
||||||
@ -400,12 +451,6 @@ impl SettingsChange {
|
|||||||
Interface::CrosshairTransp(crosshair_transp) => {
|
Interface::CrosshairTransp(crosshair_transp) => {
|
||||||
settings.interface.crosshair_transp = crosshair_transp;
|
settings.interface.crosshair_transp = crosshair_transp;
|
||||||
},
|
},
|
||||||
Interface::ChatTransp(chat_transp) => {
|
|
||||||
settings.interface.chat_transp = chat_transp;
|
|
||||||
},
|
|
||||||
Interface::ChatCharName(chat_char_name) => {
|
|
||||||
settings.interface.chat_character_name = chat_char_name;
|
|
||||||
},
|
|
||||||
Interface::CrosshairType(crosshair_type) => {
|
Interface::CrosshairType(crosshair_type) => {
|
||||||
settings.interface.crosshair_type = crosshair_type;
|
settings.interface.crosshair_type = crosshair_type;
|
||||||
},
|
},
|
||||||
|
88
voxygen/src/settings/chat.rs
Normal file
88
voxygen/src/settings/chat.rs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
use crate::hud::ChatTab;
|
||||||
|
use common::{
|
||||||
|
comp::{ChatMsg, ChatType},
|
||||||
|
uid::Uid,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
pub const MAX_CHAT_TABS: usize = 5;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct ChatFilter {
|
||||||
|
//messages
|
||||||
|
pub message_all: bool,
|
||||||
|
pub message_world: bool,
|
||||||
|
pub message_region: bool,
|
||||||
|
pub message_say: bool,
|
||||||
|
pub message_group: bool,
|
||||||
|
pub message_faction: bool,
|
||||||
|
//activity (login/logout)
|
||||||
|
pub activity_all: bool,
|
||||||
|
pub activity_group: bool,
|
||||||
|
//deaths
|
||||||
|
pub death_all: bool,
|
||||||
|
pub death_group: bool,
|
||||||
|
}
|
||||||
|
impl ChatFilter {
|
||||||
|
pub fn satisfies(&self, chat_msg: &ChatMsg, group_members: &HashSet<&Uid>) -> bool {
|
||||||
|
match &chat_msg.chat_type {
|
||||||
|
ChatType::Online(u) | ChatType::Offline(u) => {
|
||||||
|
self.activity_all || (self.activity_group && group_members.contains(u))
|
||||||
|
},
|
||||||
|
ChatType::CommandInfo | ChatType::CommandError => true,
|
||||||
|
ChatType::Kill(_, u) => self.death_all || self.death_group && group_members.contains(u),
|
||||||
|
ChatType::GroupMeta(_) => true, //todo
|
||||||
|
ChatType::FactionMeta(_) => true, //todo
|
||||||
|
ChatType::Tell(..) => true,
|
||||||
|
ChatType::Say(_) => self.message_all || self.message_say,
|
||||||
|
ChatType::Group(..) => self.message_all || self.message_group,
|
||||||
|
ChatType::Faction(..) => self.message_all || self.message_faction,
|
||||||
|
ChatType::Region(_) => self.message_all || self.message_region,
|
||||||
|
ChatType::World(_) => self.message_all || self.message_world,
|
||||||
|
ChatType::Npc(..) => true,
|
||||||
|
ChatType::NpcSay(..) => true,
|
||||||
|
ChatType::NpcTell(..) => true,
|
||||||
|
ChatType::Meta => true,
|
||||||
|
ChatType::Loot => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Default for ChatFilter {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
message_all: true,
|
||||||
|
message_world: true,
|
||||||
|
message_region: true,
|
||||||
|
message_say: true,
|
||||||
|
message_group: true,
|
||||||
|
message_faction: true,
|
||||||
|
|
||||||
|
activity_all: false,
|
||||||
|
activity_group: true,
|
||||||
|
|
||||||
|
death_all: false,
|
||||||
|
death_group: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct ChatSettings {
|
||||||
|
pub chat_transp: f32,
|
||||||
|
pub chat_character_name: bool,
|
||||||
|
pub chat_tabs: Vec<ChatTab>,
|
||||||
|
pub chat_tab_index: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ChatSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
chat_transp: 0.4,
|
||||||
|
chat_character_name: true,
|
||||||
|
chat_tabs: vec![ChatTab::default()],
|
||||||
|
chat_tab_index: Some(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,8 +16,6 @@ pub struct InterfaceSettings {
|
|||||||
pub speech_bubble_dark_mode: bool,
|
pub speech_bubble_dark_mode: bool,
|
||||||
pub speech_bubble_icon: bool,
|
pub speech_bubble_icon: bool,
|
||||||
pub crosshair_transp: f32,
|
pub crosshair_transp: f32,
|
||||||
pub chat_transp: f32,
|
|
||||||
pub chat_character_name: bool,
|
|
||||||
pub crosshair_type: CrosshairType,
|
pub crosshair_type: CrosshairType,
|
||||||
pub intro_show: Intro,
|
pub intro_show: Intro,
|
||||||
pub xp_bar: XpBar,
|
pub xp_bar: XpBar,
|
||||||
@ -51,8 +49,6 @@ impl Default for InterfaceSettings {
|
|||||||
speech_bubble_dark_mode: false,
|
speech_bubble_dark_mode: false,
|
||||||
speech_bubble_icon: true,
|
speech_bubble_icon: true,
|
||||||
crosshair_transp: 0.6,
|
crosshair_transp: 0.6,
|
||||||
chat_transp: 0.4,
|
|
||||||
chat_character_name: true,
|
|
||||||
crosshair_type: CrosshairType::Round,
|
crosshair_type: CrosshairType::Round,
|
||||||
intro_show: Intro::Show,
|
intro_show: Intro::Show,
|
||||||
xp_bar: XpBar::Always,
|
xp_bar: XpBar::Always,
|
||||||
|
@ -3,16 +3,18 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
mod audio;
|
pub mod audio;
|
||||||
mod control;
|
pub mod chat;
|
||||||
mod gamepad;
|
pub mod control;
|
||||||
mod gameplay;
|
pub mod gamepad;
|
||||||
mod graphics;
|
pub mod gameplay;
|
||||||
mod interface;
|
pub mod graphics;
|
||||||
mod language;
|
pub mod interface;
|
||||||
mod networking;
|
pub mod language;
|
||||||
|
pub mod networking;
|
||||||
|
|
||||||
pub use audio::{AudioOutput, AudioSettings};
|
pub use audio::{AudioOutput, AudioSettings};
|
||||||
|
pub use chat::ChatSettings;
|
||||||
pub use control::ControlSettings;
|
pub use control::ControlSettings;
|
||||||
pub use gamepad::GamepadSettings;
|
pub use gamepad::GamepadSettings;
|
||||||
pub use gameplay::GameplaySettings;
|
pub use gameplay::GameplaySettings;
|
||||||
@ -60,6 +62,7 @@ impl Default for Log {
|
|||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
pub chat: ChatSettings,
|
||||||
pub controls: ControlSettings,
|
pub controls: ControlSettings,
|
||||||
pub interface: InterfaceSettings,
|
pub interface: InterfaceSettings,
|
||||||
pub gameplay: GameplaySettings,
|
pub gameplay: GameplaySettings,
|
||||||
@ -96,6 +99,7 @@ impl Default for Settings {
|
|||||||
.expect("Couldn't choose a place to store the screenshots");
|
.expect("Couldn't choose a place to store the screenshots");
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
|
chat: ChatSettings::default(),
|
||||||
controls: ControlSettings::default(),
|
controls: ControlSettings::default(),
|
||||||
interface: InterfaceSettings::default(),
|
interface: InterfaceSettings::default(),
|
||||||
gameplay: GameplaySettings::default(),
|
gameplay: GameplaySettings::default(),
|
||||||
|
Loading…
Reference in New Issue
Block a user