mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Rebase !1447 Chat input color and icon reflect channel message is sent to.
This commit is contained in:
parent
f2660ef5f9
commit
63952875d9
@ -23,8 +23,8 @@ use common::{
|
|||||||
group,
|
group,
|
||||||
skills::Skill,
|
skills::Skill,
|
||||||
slot::Slot,
|
slot::Slot,
|
||||||
ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, InventoryManip,
|
ChatMode, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip,
|
||||||
InventoryUpdateEvent, LoadoutManip,
|
InventoryManip, InventoryUpdateEvent, LoadoutManip,
|
||||||
},
|
},
|
||||||
event::{EventBus, LocalEvent},
|
event::{EventBus, LocalEvent},
|
||||||
grid::Grid,
|
grid::Grid,
|
||||||
@ -124,6 +124,7 @@ pub struct Client {
|
|||||||
player_list: HashMap<Uid, PlayerInfo>,
|
player_list: HashMap<Uid, PlayerInfo>,
|
||||||
character_list: CharacterList,
|
character_list: CharacterList,
|
||||||
sites: Vec<SiteInfo>,
|
sites: Vec<SiteInfo>,
|
||||||
|
pub chat_mode: ChatMode,
|
||||||
recipe_book: RecipeBook,
|
recipe_book: RecipeBook,
|
||||||
available_recipes: HashSet<String>,
|
available_recipes: HashSet<String>,
|
||||||
|
|
||||||
@ -416,6 +417,7 @@ impl Client {
|
|||||||
sites,
|
sites,
|
||||||
recipe_book,
|
recipe_book,
|
||||||
available_recipes: HashSet::default(),
|
available_recipes: HashSet::default(),
|
||||||
|
chat_mode: ChatMode::default(),
|
||||||
|
|
||||||
max_group_size,
|
max_group_size,
|
||||||
group_invite: None,
|
group_invite: None,
|
||||||
@ -1346,6 +1348,9 @@ impl Client {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
ServerGeneral::ChatMsg(m) => frontend_events.push(Event::Chat(m)),
|
ServerGeneral::ChatMsg(m) => frontend_events.push(Event::Chat(m)),
|
||||||
|
ServerGeneral::ChatMode(m) => {
|
||||||
|
self.chat_mode = m;
|
||||||
|
},
|
||||||
ServerGeneral::SetPlayerEntity(uid) => {
|
ServerGeneral::SetPlayerEntity(uid) => {
|
||||||
if let Some(entity) = self.state.ecs().entity_from_uid(uid.0) {
|
if let Some(entity) = self.state.ecs().entity_from_uid(uid.0) {
|
||||||
self.entity = entity;
|
self.entity = entity;
|
||||||
|
@ -110,6 +110,7 @@ pub enum ServerGeneral {
|
|||||||
/// A message to go into the client chat box. The client is responsible for
|
/// A message to go into the client chat box. The client is responsible for
|
||||||
/// formatting the message and turning it into a speech bubble.
|
/// formatting the message and turning it into a speech bubble.
|
||||||
ChatMsg(comp::ChatMsg),
|
ChatMsg(comp::ChatMsg),
|
||||||
|
ChatMode(comp::ChatMode),
|
||||||
SetPlayerEntity(Uid),
|
SetPlayerEntity(Uid),
|
||||||
TimeOfDay(TimeOfDay),
|
TimeOfDay(TimeOfDay),
|
||||||
EntitySync(sync::EntitySyncPackage),
|
EntitySync(sync::EntitySyncPackage),
|
||||||
@ -230,6 +231,7 @@ impl ServerMsg {
|
|||||||
// Always possible
|
// Always possible
|
||||||
ServerGeneral::PlayerListUpdate(_)
|
ServerGeneral::PlayerListUpdate(_)
|
||||||
| ServerGeneral::ChatMsg(_)
|
| ServerGeneral::ChatMsg(_)
|
||||||
|
| ServerGeneral::ChatMode(_)
|
||||||
| ServerGeneral::SetPlayerEntity(_)
|
| ServerGeneral::SetPlayerEntity(_)
|
||||||
| ServerGeneral::TimeOfDay(_)
|
| ServerGeneral::TimeOfDay(_)
|
||||||
| ServerGeneral::EntitySync(_)
|
| ServerGeneral::EntitySync(_)
|
||||||
|
@ -9,7 +9,7 @@ use std::time::{Duration, Instant};
|
|||||||
|
|
||||||
/// A player's current chat mode. These are chat types that can only be sent by
|
/// A player's current chat mode. These are chat types that can only be sent by
|
||||||
/// the player.
|
/// the player.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub enum ChatMode {
|
pub enum ChatMode {
|
||||||
/// Private message to another player (by uuid)
|
/// Private message to another player (by uuid)
|
||||||
Tell(Uid),
|
Tell(Uid),
|
||||||
|
@ -94,6 +94,7 @@ impl Client {
|
|||||||
// Always possible
|
// Always possible
|
||||||
ServerGeneral::PlayerListUpdate(_)
|
ServerGeneral::PlayerListUpdate(_)
|
||||||
| ServerGeneral::ChatMsg(_)
|
| ServerGeneral::ChatMsg(_)
|
||||||
|
| ServerGeneral::ChatMode(_)
|
||||||
| ServerGeneral::SetPlayerEntity(_)
|
| ServerGeneral::SetPlayerEntity(_)
|
||||||
| ServerGeneral::TimeOfDay(_)
|
| ServerGeneral::TimeOfDay(_)
|
||||||
| ServerGeneral::EntitySync(_)
|
| ServerGeneral::EntitySync(_)
|
||||||
@ -169,6 +170,7 @@ impl Client {
|
|||||||
// Always possible
|
// Always possible
|
||||||
ServerGeneral::PlayerListUpdate(_)
|
ServerGeneral::PlayerListUpdate(_)
|
||||||
| ServerGeneral::ChatMsg(_)
|
| ServerGeneral::ChatMsg(_)
|
||||||
|
| ServerGeneral::ChatMode(_)
|
||||||
| ServerGeneral::SetPlayerEntity(_)
|
| ServerGeneral::SetPlayerEntity(_)
|
||||||
| ServerGeneral::TimeOfDay(_)
|
| ServerGeneral::TimeOfDay(_)
|
||||||
| ServerGeneral::EntitySync(_)
|
| ServerGeneral::EntitySync(_)
|
||||||
|
@ -1510,6 +1510,7 @@ fn handle_tell(
|
|||||||
.insert(client, mode.clone());
|
.insert(client, mode.clone());
|
||||||
let msg = message_opt.unwrap_or_else(|| format!("{} wants to talk to you.", alias));
|
let msg = message_opt.unwrap_or_else(|| format!("{} wants to talk to you.", alias));
|
||||||
server.state.send_chat(mode.new_message(client_uid, msg));
|
server.state.send_chat(mode.new_message(client_uid, msg));
|
||||||
|
server.notify_client(client, ServerGeneral::ChatMode(mode));
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
@ -1551,6 +1552,7 @@ fn handle_faction(
|
|||||||
server.state.send_chat(mode.new_message(*uid, msg));
|
server.state.send_chat(mode.new_message(*uid, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
server.notify_client(client, ServerGeneral::ChatMode(mode));
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
@ -1586,6 +1588,7 @@ fn handle_group(
|
|||||||
server.state.send_chat(mode.new_message(*uid, msg));
|
server.state.send_chat(mode.new_message(*uid, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
server.notify_client(client, ServerGeneral::ChatMode(mode));
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
@ -1767,6 +1770,7 @@ fn handle_region(
|
|||||||
server.state.send_chat(mode.new_message(*uid, msg));
|
server.state.send_chat(mode.new_message(*uid, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
server.notify_client(client, ServerGeneral::ChatMode(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_say(
|
fn handle_say(
|
||||||
@ -1795,6 +1799,7 @@ fn handle_say(
|
|||||||
server.state.send_chat(mode.new_message(*uid, msg));
|
server.state.send_chat(mode.new_message(*uid, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
server.notify_client(client, ServerGeneral::ChatMode(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_world(
|
fn handle_world(
|
||||||
@ -1823,6 +1828,7 @@ fn handle_world(
|
|||||||
server.state.send_chat(mode.new_message(*uid, msg));
|
server.state.send_chat(mode.new_message(*uid, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
server.notify_client(client, ServerGeneral::ChatMode(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_join_faction(
|
fn handle_join_faction(
|
||||||
@ -1847,9 +1853,14 @@ fn handle_join_faction(
|
|||||||
.get(target)
|
.get(target)
|
||||||
.map(|player| player.alias.clone())
|
.map(|player| player.alias.clone())
|
||||||
{
|
{
|
||||||
let faction_leave = if let Ok(faction) = scan_fmt!(&args, &action.arg_fmt(), String) {
|
let (faction_leave, mode) = if let Ok(faction) = scan_fmt!(&args, &action.arg_fmt(), String)
|
||||||
|
{
|
||||||
let mode = comp::ChatMode::Faction(faction.clone());
|
let mode = comp::ChatMode::Faction(faction.clone());
|
||||||
let _ = server.state.ecs().write_storage().insert(client, mode);
|
let _ = server
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.write_storage()
|
||||||
|
.insert(client, mode.clone());
|
||||||
let faction_leave = server
|
let faction_leave = server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
@ -1862,16 +1873,21 @@ fn handle_join_faction(
|
|||||||
ChatType::FactionMeta(faction.clone())
|
ChatType::FactionMeta(faction.clone())
|
||||||
.chat_msg(format!("[{}] joined faction ({})", alias, faction)),
|
.chat_msg(format!("[{}] joined faction ({})", alias, faction)),
|
||||||
);
|
);
|
||||||
faction_leave
|
(faction_leave, mode)
|
||||||
} else {
|
} else {
|
||||||
let mode = comp::ChatMode::default();
|
let mode = comp::ChatMode::default();
|
||||||
let _ = server.state.ecs().write_storage().insert(client, mode);
|
let _ = server
|
||||||
server
|
.state
|
||||||
|
.ecs()
|
||||||
|
.write_storage()
|
||||||
|
.insert(client, mode.clone());
|
||||||
|
let faction_leave = server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage()
|
.write_storage()
|
||||||
.remove(client)
|
.remove(client)
|
||||||
.map(|comp::Faction(f)| f)
|
.map(|comp::Faction(f)| f);
|
||||||
|
(faction_leave, mode)
|
||||||
};
|
};
|
||||||
if let Some(faction) = faction_leave {
|
if let Some(faction) = faction_leave {
|
||||||
server.state.send_chat(
|
server.state.send_chat(
|
||||||
@ -1879,6 +1895,7 @@ fn handle_join_faction(
|
|||||||
.chat_msg(format!("[{}] left faction ({})", alias, faction)),
|
.chat_msg(format!("[{}] left faction ({})", alias, faction)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
server.notify_client(client, ServerGeneral::ChatMode(mode));
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use super::{
|
use super::{
|
||||||
img_ids::Imgs, ERROR_COLOR, FACTION_COLOR, GROUP_COLOR, INFO_COLOR, KILL_COLOR, LOOT_COLOR,
|
img_ids::Imgs, ERROR_COLOR, FACTION_COLOR, GROUP_COLOR, INFO_COLOR, KILL_COLOR, LOOT_COLOR,
|
||||||
OFFLINE_COLOR, ONLINE_COLOR, REGION_COLOR, SAY_COLOR, TELL_COLOR, TEXT_COLOR, WORLD_COLOR,
|
OFFLINE_COLOR, ONLINE_COLOR, REGION_COLOR, SAY_COLOR, TELL_COLOR, WORLD_COLOR,
|
||||||
};
|
};
|
||||||
use crate::{i18n::Localization, ui::fonts::Fonts, GlobalState};
|
use crate::{i18n::Localization, ui::fonts::Fonts, GlobalState};
|
||||||
use client::{cmd, Client};
|
use client::{cmd, Client};
|
||||||
use common::comp::{
|
use common::comp::{
|
||||||
chat::{KillSource, KillType},
|
chat::{KillSource, KillType},
|
||||||
ChatMsg, ChatType,
|
ChatMode, ChatMsg, ChatType,
|
||||||
};
|
};
|
||||||
use common_net::msg::validate_chat_msg;
|
use common_net::msg::validate_chat_msg;
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
@ -27,6 +27,7 @@ widget_ids! {
|
|||||||
message_box_bg,
|
message_box_bg,
|
||||||
chat_input,
|
chat_input,
|
||||||
chat_input_bg,
|
chat_input_bg,
|
||||||
|
chat_input_icon,
|
||||||
chat_arrow,
|
chat_arrow,
|
||||||
chat_icons[],
|
chat_icons[],
|
||||||
}
|
}
|
||||||
@ -36,8 +37,10 @@ const X: f64 = 18.0;*/
|
|||||||
|
|
||||||
const MAX_MESSAGES: usize = 100;
|
const MAX_MESSAGES: usize = 100;
|
||||||
|
|
||||||
|
const CHAT_ICON_WIDTH: 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;
|
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 = 174.0;
|
||||||
|
|
||||||
#[derive(WidgetCommon)]
|
#[derive(WidgetCommon)]
|
||||||
@ -121,9 +124,14 @@ impl<'a> Chat<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct InputState {
|
||||||
|
message: String,
|
||||||
|
mode: ChatMode,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
messages: VecDeque<ChatMsg>,
|
messages: VecDeque<ChatMsg>,
|
||||||
input: String,
|
input: InputState,
|
||||||
ids: Ids,
|
ids: Ids,
|
||||||
history: VecDeque<String>,
|
history: VecDeque<String>,
|
||||||
// Index into the history Vec, history_pos == 0 is history not in use
|
// Index into the history Vec, history_pos == 0 is history not in use
|
||||||
@ -149,7 +157,10 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
|
|
||||||
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
|
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
|
||||||
State {
|
State {
|
||||||
input: "".to_owned(),
|
input: InputState {
|
||||||
|
message: "".to_owned(),
|
||||||
|
mode: ChatMode::default(),
|
||||||
|
},
|
||||||
messages: VecDeque::new(),
|
messages: VecDeque::new(),
|
||||||
history: VecDeque::new(),
|
history: VecDeque::new(),
|
||||||
history_pos: 0,
|
history_pos: 0,
|
||||||
@ -212,8 +223,8 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
false
|
false
|
||||||
} else if let Some(cursor) = state.completion_cursor {
|
} else if let Some(cursor) = state.completion_cursor {
|
||||||
// Cycle through tab completions of the current word
|
// Cycle through tab completions of the current word
|
||||||
if state.input.contains('\t') {
|
if state.input.message.contains('\t') {
|
||||||
state.update(|s| s.input.retain(|c| c != '\t'));
|
state.update(|s| s.input.message.retain(|c| c != '\t'));
|
||||||
//tab_dir + 1
|
//tab_dir + 1
|
||||||
}
|
}
|
||||||
if !state.completions.is_empty() && (tab_dir != 0 || state.completions_index.is_none())
|
if !state.completions.is_empty() && (tab_dir != 0 || state.completions_index.is_none())
|
||||||
@ -225,14 +236,15 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
% len,
|
% len,
|
||||||
);
|
);
|
||||||
if let Some(replacement) = &s.completions.get(s.completions_index.unwrap()) {
|
if let Some(replacement) = &s.completions.get(s.completions_index.unwrap()) {
|
||||||
let (completed, offset) = do_tab_completion(cursor, &s.input, replacement);
|
let (completed, offset) =
|
||||||
|
do_tab_completion(cursor, &s.input.message, replacement);
|
||||||
force_cursor = cursor_offset_to_index(offset, &completed, &ui, &self.fonts);
|
force_cursor = cursor_offset_to_index(offset, &completed, &ui, &self.fonts);
|
||||||
s.input = completed;
|
s.input.message = completed;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
} else if let Some(cursor) = state.input.find('\t') {
|
} else if let Some(cursor) = state.input.message.find('\t') {
|
||||||
// Begin tab completion
|
// Begin tab completion
|
||||||
state.update(|s| s.completion_cursor = Some(cursor));
|
state.update(|s| s.completion_cursor = Some(cursor));
|
||||||
true
|
true
|
||||||
@ -252,11 +264,15 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
s.history_pos -= 1;
|
s.history_pos -= 1;
|
||||||
}
|
}
|
||||||
if s.history_pos > 0 {
|
if s.history_pos > 0 {
|
||||||
s.input = s.history.get(s.history_pos - 1).unwrap().to_owned();
|
s.input.message = s.history.get(s.history_pos - 1).unwrap().to_owned();
|
||||||
force_cursor =
|
force_cursor = cursor_offset_to_index(
|
||||||
cursor_offset_to_index(s.input.len(), &s.input, &ui, &self.fonts);
|
s.input.message.len(),
|
||||||
|
&s.input.message,
|
||||||
|
&ui,
|
||||||
|
&self.fonts,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
s.input.clear();
|
s.input.message.clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -264,7 +280,7 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
let keyboard_capturer = ui.global_input().current.widget_capturing_keyboard;
|
let keyboard_capturer = ui.global_input().current.widget_capturing_keyboard;
|
||||||
|
|
||||||
if let Some(input) = &self.force_input {
|
if let Some(input) = &self.force_input {
|
||||||
state.update(|s| s.input = input.to_string());
|
state.update(|s| s.input.message = input.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let input_focused =
|
let input_focused =
|
||||||
@ -273,12 +289,26 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
// Only show if it has the keyboard captured.
|
// Only show if it has the keyboard captured.
|
||||||
// Chat input uses a rectangle as its background.
|
// Chat input uses a rectangle as its background.
|
||||||
if input_focused {
|
if input_focused {
|
||||||
|
// Shallow comparison of ChatMode.
|
||||||
|
let discrim = |x| std::mem::discriminant(x);
|
||||||
|
if discrim(&state.input.mode) != discrim(&self.client.chat_mode) {
|
||||||
|
state.update(|s| {
|
||||||
|
s.input.mode = self.client.chat_mode.clone();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let (color, icon) = render_chat_mode(&state.input.mode, &self.imgs);
|
||||||
|
Image::new(icon)
|
||||||
|
.w_h(CHAT_ICON_WIDTH, CHAT_ICON_HEIGHT)
|
||||||
|
.top_left_with_margin_on(state.ids.chat_input_bg, 2.0)
|
||||||
|
.set(state.ids.chat_input_icon, ui);
|
||||||
|
|
||||||
// Any changes to this TextEdit's width and font size must be reflected in
|
// Any changes to this TextEdit's width and font size must be reflected in
|
||||||
// `cursor_offset_to_index` below.
|
// `cursor_offset_to_index` below.
|
||||||
let mut text_edit = TextEdit::new(&state.input)
|
let mut text_edit = TextEdit::new(&state.input.message)
|
||||||
.w(CHAT_BOX_INPUT_WIDTH)
|
.w(CHAT_BOX_INPUT_WIDTH)
|
||||||
.restrict_to_height(false)
|
.restrict_to_height(false)
|
||||||
.color(TEXT_COLOR)
|
.color(color)
|
||||||
.line_spacing(2.0)
|
.line_spacing(2.0)
|
||||||
.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);
|
||||||
@ -298,13 +328,13 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
.set(state.ids.chat_input_bg, ui);
|
.set(state.ids.chat_input_bg, ui);
|
||||||
|
|
||||||
if let Some(str) = text_edit
|
if let Some(str) = text_edit
|
||||||
.top_left_with_margins_on(state.ids.chat_input_bg, 1.0, 1.0)
|
.right_from(state.ids.chat_input_icon, 1.0)
|
||||||
.set(state.ids.chat_input, ui)
|
.set(state.ids.chat_input, ui)
|
||||||
{
|
{
|
||||||
let mut input = str.to_owned();
|
let mut input = str.to_owned();
|
||||||
input.retain(|c| c != '\n');
|
input.retain(|c| c != '\n');
|
||||||
if let Ok(()) = validate_chat_msg(&input) {
|
if let Ok(()) = validate_chat_msg(&input) {
|
||||||
state.update(|s| s.input = input);
|
state.update(|s| s.input.message = input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,8 +471,8 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
item.set(text.h(y), ui);
|
item.set(text.h(y), ui);
|
||||||
let icon_id = state.ids.chat_icons[item.i];
|
let icon_id = state.ids.chat_icons[item.i];
|
||||||
Image::new(icon)
|
Image::new(icon)
|
||||||
.w_h(16.0, 16.0)
|
.w_h(CHAT_ICON_WIDTH, CHAT_ICON_HEIGHT)
|
||||||
.top_left_with_margins_on(item.widget_id, 2.0, -16.0)
|
.top_left_with_margins_on(item.widget_id, 2.0, -CHAT_ICON_WIDTH)
|
||||||
.parent(state.ids.message_box_bg)
|
.parent(state.ids.message_box_bg)
|
||||||
.set(icon_id, ui);
|
.set(icon_id, ui);
|
||||||
} else {
|
} else {
|
||||||
@ -475,22 +505,19 @@ 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.to_string()))
|
Some(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))
|
Some(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
|
else if ui.widget_input(state.ids.chat_input).presses().key().any(
|
||||||
.widget_input(state.ids.chat_input)
|
|key_press| matches!(key_press.key, Key::Return if !state.input.message.is_empty()),
|
||||||
.presses()
|
) {
|
||||||
.key()
|
let msg = state.input.message.clone();
|
||||||
.any(|key_press| matches!(key_press.key, Key::Return if !state.input.is_empty()))
|
|
||||||
{
|
|
||||||
let msg = state.input.clone();
|
|
||||||
state.update(|s| {
|
state.update(|s| {
|
||||||
s.input.clear();
|
s.input.message.clear();
|
||||||
// Update the history
|
// Update the history
|
||||||
// Don't add if this is identical to the last message in the history
|
// Don't add if this is identical to the last message in the history
|
||||||
s.history_pos = 0;
|
s.history_pos = 0;
|
||||||
@ -557,6 +584,18 @@ fn cursor_offset_to_index(offset: usize, text: &str, ui: &Ui, fonts: &Fonts) ->
|
|||||||
cursor::index_before_char(infos, offset)
|
cursor::index_before_char(infos, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the color and icon for a client's ChatMode.
|
||||||
|
fn render_chat_mode(chat_mode: &ChatMode, imgs: &Imgs) -> (Color, conrod_core::image::Id) {
|
||||||
|
match chat_mode {
|
||||||
|
ChatMode::World => (WORLD_COLOR, imgs.chat_world_small),
|
||||||
|
ChatMode::Say => (SAY_COLOR, imgs.chat_say_small),
|
||||||
|
ChatMode::Region => (REGION_COLOR, imgs.chat_region_small),
|
||||||
|
ChatMode::Faction(_) => (FACTION_COLOR, imgs.chat_faction_small),
|
||||||
|
ChatMode::Group(_) => (GROUP_COLOR, imgs.chat_group_small),
|
||||||
|
ChatMode::Tell(_) => (TELL_COLOR, imgs.chat_tell_small),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the color and icon for the current line in the chat box
|
/// Get the color and icon for the current line in the chat box
|
||||||
fn render_chat_line(chat_type: &ChatType<String>, imgs: &Imgs) -> (Color, conrod_core::image::Id) {
|
fn render_chat_line(chat_type: &ChatType<String>, imgs: &Imgs) -> (Color, conrod_core::image::Id) {
|
||||||
match chat_type {
|
match chat_type {
|
||||||
|
Loading…
Reference in New Issue
Block a user