group button and menu logic changes

group member panels

health bar text

text shadows and scaling

cleanup, don't show the player panel

social window assets
This commit is contained in:
Monty Marz 2020-07-26 01:21:15 +02:00
parent 3a22b3694d
commit f2ed7efced
16 changed files with 529 additions and 199 deletions

BIN
assets/voxygen/element/frames/enemybar_1.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/frames/enemybar_bg_1.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/frames/group_member_bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/frames/group_member_frame.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/misc_bg/social_bg.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/misc_bg/social_frame.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/misc_bg/social_tab_active.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/misc_bg/social_tab_inactive.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -326,6 +326,8 @@ magically infused items?"#,
"hud.group.kick": "Kick",
"hud.group.assign_leader": "Assign Leader",
"hud.group.leave": "Leave Group",
"hud.group.dead" : "Dead",
"hud.group.out_of_range": "Out of range",
"hud.spell": "Spells",

View File

@ -34,7 +34,7 @@ use common::{
use futures_executor::block_on;
use futures_timer::Delay;
use futures_util::{select, FutureExt};
use hashbrown::HashMap;
use hashbrown::{HashMap, HashSet};
use image::DynamicImage;
use network::{
Network, Participant, Pid, ProtocolAddr, Stream, PROMISES_CONSISTENCY, PROMISES_ORDERED,

View File

@ -98,7 +98,6 @@ pub enum Event {
ToggleSocial,
ToggleSpell,
ToggleCrafting,
ToggleGroup,
}
impl<'a> Widget for Buttons<'a> {
@ -399,25 +398,6 @@ impl<'a> Widget for Buttons<'a> {
.set(state.ids.crafting_text, ui);
}
// Group
if Button::image(self.imgs.group_icon)
.w_h(49.0, 26.0)
.bottom_left_with_margins_on(ui.window, 190.0, 10.0)
.hover_image(self.imgs.group_icon_hover)
.press_image(self.imgs.group_icon_press)
.with_tooltip(
self.tooltip_manager,
&localized_strings.get("hud.group"),
"",
&button_tooltip,
)
.bottom_offset(TOOLTIP_UPSHIFT)
.set(state.ids.group_button, ui)
.was_clicked()
{
return Some(Event::ToggleGroup);
}
None
}
}

View File

@ -1,7 +1,15 @@
use super::{img_ids::Imgs, Show, TEXT_COLOR, TEXT_COLOR_3, TEXT_COLOR_GREY, UI_MAIN};
use super::{
img_ids::{Imgs, ImgsRot},
Show, BLACK, GROUP_COLOR, HP_COLOR, KILL_COLOR, LOW_HP_COLOR, MANA_COLOR, TEXT_COLOR,
TEXT_COLOR_GREY, TRANSPARENT, UI_HIGHLIGHT_0,
};
use crate::{
i18n::VoxygenLocalization, settings::Settings, ui::fonts::ConrodVoxygenFonts, window::GameInput,
i18n::VoxygenLocalization,
settings::Settings,
ui::{fonts::ConrodVoxygenFonts, ImageFrame, Tooltip, TooltipManager, Tooltipable},
window::GameInput,
GlobalState,
};
use client::{self, Client};
use common::{
@ -12,13 +20,13 @@ use conrod_core::{
color,
position::{Place, Relative},
widget::{self, Button, Image, Rectangle, Scrollbar, Text},
widget_ids, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
};
use specs::WorldExt;
use std::time::Instant;
use specs::{saveload::MarkerAllocator, WorldExt};
widget_ids! {
pub struct Ids {
group_button,
bg,
title,
close,
@ -35,6 +43,14 @@ widget_ids! {
bubble_frame,
btn_accept,
btn_decline,
member_panels_bg[],
member_panels_frame[],
member_panels_txt_bg[],
member_panels_txt[],
member_health[],
member_stam[],
dead_txt[],
health_txt[],
}
}
@ -44,6 +60,7 @@ pub struct State {
selected_member: Option<Uid>,
}
const TOOLTIP_UPSHIFT: f64 = 40.0;
#[derive(WidgetCommon)]
pub struct Group<'a> {
show: &'a mut Show,
@ -52,6 +69,10 @@ pub struct Group<'a> {
imgs: &'a Imgs,
fonts: &'a ConrodVoxygenFonts,
localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
tooltip_manager: &'a mut TooltipManager,
rot_imgs: &'a ImgsRot,
pulse: f32,
global_state: &'a GlobalState,
#[conrod(common_builder)]
common: widget::CommonBuilder,
@ -65,21 +86,28 @@ impl<'a> Group<'a> {
imgs: &'a Imgs,
fonts: &'a ConrodVoxygenFonts,
localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
tooltip_manager: &'a mut TooltipManager,
rot_imgs: &'a ImgsRot,
pulse: f32,
global_state: &'a GlobalState,
) -> Self {
Self {
show,
client,
settings,
imgs,
rot_imgs,
tooltip_manager,
fonts,
localized_strings,
pulse,
global_state,
common: widget::CommonBuilder::default(),
}
}
}
pub enum Event {
Close,
Accept,
Decline,
Kick(Uid),
@ -102,10 +130,34 @@ impl<'a> Widget for Group<'a> {
#[allow(clippy::unused_unit)] // TODO: Pending review in #587
fn style(&self) -> Self::Style { () }
//TODO: Disband groups when there's only one member in them
//TODO: Always send health, energy, level and position of group members to the
// client
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
let widget::UpdateArgs { state, ui, .. } = args;
let mut events = Vec::new();
let localized_strings = self.localized_strings;
let button_tooltip = Tooltip::new({
// Edge images [t, b, r, l]
// Corner images [tr, tl, br, bl]
let edge = &self.rot_imgs.tt_side;
let corner = &self.rot_imgs.tt_corner;
ImageFrame::new(
[edge.cw180, edge.none, edge.cw270, edge.cw90],
[corner.none, corner.cw270, corner.cw90, corner.cw180],
Color::Rgba(0.08, 0.07, 0.04, 1.0),
5.0,
)
})
.title_font_size(self.fonts.cyri.scale(15))
.parent(ui.window)
.desc_font_size(self.fonts.cyri.scale(12))
.title_text_color(TEXT_COLOR)
.font_id(self.fonts.cyri.conrod_id)
.desc_text_color(TEXT_COLOR);
// Don't show pets
let group_members = self
@ -117,7 +169,6 @@ impl<'a> Widget for Group<'a> {
Role::Pet => None,
})
.collect::<Vec<_>>();
// Not considered in group for ui purposes if it is just pets
let in_group = !group_members.is_empty();
@ -149,27 +200,295 @@ impl<'a> Widget for Group<'a> {
// TODO show something to the player when they click on the group button while
// they are not in a group so that it doesn't look like the button is
// broken
if in_group || open_invite.is_some() {
if self.show.group_menu || open_invite.is_some() {
// Frame
Rectangle::fill_with([220.0, 230.0], color::Color::Rgba(0.0, 0.0, 0.0, 0.8))
.bottom_left_with_margins_on(ui.window, 220.0, 10.0)
.set(state.ids.bg, ui);
if open_invite.is_some() {
// yellow animated border
}
}
if open_invite.is_some() {
// Group Menu button
Button::image(self.imgs.group_icon)
.w_h(49.0, 26.0)
.bottom_left_with_margins_on(ui.window, 190.0, 10.0)
.set(state.ids.group_button, ui);
}
// Buttons
if let Some((group_name, leader)) = self.client.group_info().filter(|_| in_group) {
let selected = state.selected_member;
Text::new(&group_name)
.mid_top_with_margin_on(state.ids.bg, 2.0)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.title, ui);
if Button::image(self.imgs.button)
// Group Menu Button
if Button::image(if self.show.group_menu {
self.imgs.group_icon_press
} else {
self.imgs.group_icon
})
.w_h(49.0, 26.0)
.bottom_left_with_margins_on(ui.window, 190.0, 10.0)
.hover_image(self.imgs.group_icon_hover)
.press_image(self.imgs.group_icon_press)
.with_tooltip(
self.tooltip_manager,
&localized_strings.get("hud.group"),
"",
&button_tooltip,
)
.bottom_offset(TOOLTIP_UPSHIFT)
.set(state.ids.group_button, ui)
.was_clicked()
{
self.show.group_menu = !self.show.group_menu;
};
// Member panels
let group_size = group_members.len() + 1;
if state.ids.member_panels_bg.len() < group_size {
state.update(|s| {
s.ids
.member_panels_bg
.resize(group_size, &mut ui.widget_id_generator())
})
};
if state.ids.member_health.len() < group_size {
state.update(|s| {
s.ids
.member_health
.resize(group_size, &mut ui.widget_id_generator())
})
};
if state.ids.member_stam.len() < group_size {
state.update(|s| {
s.ids
.member_stam
.resize(group_size, &mut ui.widget_id_generator())
})
};
if state.ids.member_panels_frame.len() < group_size {
state.update(|s| {
s.ids
.member_panels_frame
.resize(group_size, &mut ui.widget_id_generator())
})
};
if state.ids.member_panels_txt.len() < group_size {
state.update(|s| {
s.ids
.member_panels_txt
.resize(group_size, &mut ui.widget_id_generator())
})
};
if state.ids.dead_txt.len() < group_size {
state.update(|s| {
s.ids
.dead_txt
.resize(group_size, &mut ui.widget_id_generator())
})
};
if state.ids.health_txt.len() < group_size {
state.update(|s| {
s.ids
.health_txt
.resize(group_size, &mut ui.widget_id_generator())
})
};
if state.ids.member_panels_txt_bg.len() < group_size {
state.update(|s| {
s.ids
.member_panels_txt_bg
.resize(group_size, &mut ui.widget_id_generator())
})
};
let client_state = self.client.state();
let stats = client_state.ecs().read_storage::<common::comp::Stats>();
let energy = client_state.ecs().read_storage::<common::comp::Energy>();
let uid_allocator = client_state
.ecs()
.read_resource::<common::sync::UidAllocator>();
for (i, &uid) in self
.client
.uid()
.iter()
.chain(group_members.iter().copied())
.enumerate()
{
self.show.group = true;
let entity = uid_allocator.retrieve_entity_internal(uid.into());
let stats = entity.and_then(|entity| stats.get(entity));
let energy = entity.and_then(|entity| energy.get(entity));
if let Some(stats) = stats {
let char_name = stats.name.to_string();
let health_perc = stats.health.current() as f64 / stats.health.maximum() as f64;
// change panel positions when debug info is shown
let offset = if self.global_state.settings.gameplay.toggle_debug {
210.0
} else {
110.0
};
let pos = if i == 0 {
Image::new(self.imgs.member_bg)
.top_left_with_margins_on(ui.window, offset, 20.0)
} else {
Image::new(self.imgs.member_bg)
.down_from(state.ids.member_panels_bg[i - 1], 40.0)
};
let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8; //Animation timer
let crit_hp_color: Color = Color::Rgba(0.79, 0.19, 0.17, hp_ani);
let health_col = match (health_perc * 100.0) as u8 {
0..=20 => crit_hp_color,
21..=40 => LOW_HP_COLOR,
_ => HP_COLOR,
};
// Don't show panel for the player!
// Panel BG
pos.w_h(152.0, 36.0)
.color(if i == 0 {
Some(TRANSPARENT)
} else {
Some(TEXT_COLOR)
})
.set(state.ids.member_panels_bg[i], ui);
// Health
Image::new(self.imgs.bar_content)
.w_h(148.0 * health_perc, 22.0)
.color(if i == 0 {
Some(TRANSPARENT)
} else {
Some(health_col)
})
.top_left_with_margins_on(state.ids.member_panels_bg[i], 2.0, 2.0)
.set(state.ids.member_health[i], ui);
if stats.is_dead {
// Death Text
Text::new(&self.localized_strings.get("hud.group.dead"))
.mid_top_with_margin_on(state.ids.member_panels_bg[i], 1.0)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(if i == 0 { TRANSPARENT } else { KILL_COLOR })
.set(state.ids.dead_txt[i], ui);
} else {
// Health Text
let txt = format!(
"{}/{}",
stats.health.current() as u32,
stats.health.maximum() as u32,
);
let font_size = match stats.health.maximum() {
0..=999 => 14,
1000..=9999 => 13,
10000..=99999 => 12,
_ => 11,
};
let txt_offset = match stats.health.maximum() {
0..=999 => 4.0,
1000..=9999 => 4.5,
10000..=99999 => 5.0,
_ => 5.5,
};
Text::new(&txt)
.mid_top_with_margin_on(state.ids.member_panels_bg[i], txt_offset)
.font_size(font_size)
.font_id(self.fonts.cyri.conrod_id)
.color(if i == 0 {
TRANSPARENT
} else {
Color::Rgba(1.0, 1.0, 1.0, 0.5)
})
.set(state.ids.health_txt[i], ui);
};
// Panel Frame
Image::new(self.imgs.member_frame)
.w_h(152.0, 36.0)
.middle_of(state.ids.member_panels_bg[i])
.color(if i == 0 {
Some(TRANSPARENT)
} else {
Some(UI_HIGHLIGHT_0)
})
.set(state.ids.member_panels_frame[i], ui);
// Panel Text
Text::new(&char_name)
.top_left_with_margins_on(state.ids.member_panels_frame[i], -22.0, 0.0)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(if i == 0 { TRANSPARENT } else { BLACK })
.set(state.ids.member_panels_txt_bg[i], ui);
Text::new(&char_name)
.bottom_left_with_margins_on(state.ids.member_panels_txt_bg[i], 2.0, 2.0)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(if i == 0 { TRANSPARENT } else { GROUP_COLOR })
.set(state.ids.member_panels_txt[i], ui);
if let Some(energy) = energy {
let stam_perc = energy.current() as f64 / energy.maximum() as f64;
// Stamina
Image::new(self.imgs.bar_content)
.w_h(100.0 * stam_perc, 8.0)
.color(if i == 0 {
Some(TRANSPARENT)
} else {
Some(MANA_COLOR)
})
.top_left_with_margins_on(state.ids.member_panels_bg[i], 26.0, 2.0)
.set(state.ids.member_stam[i], ui);
}
} else {
// Values N.A.
if let Some(stats) = stats {
Text::new(&stats.name.to_string())
.top_left_with_margins_on(state.ids.member_panels_frame[i], -22.0, 0.0)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(GROUP_COLOR)
.set(state.ids.member_panels_txt[i], ui);
};
let offset = if self.global_state.settings.gameplay.toggle_debug {
210.0
} else {
110.0
};
let pos = if i == 0 {
Image::new(self.imgs.member_bg)
.top_left_with_margins_on(ui.window, offset, 20.0)
} else {
Image::new(self.imgs.member_bg)
.down_from(state.ids.member_panels_bg[i - 1], 40.0)
};
pos.w_h(152.0, 36.0)
.color(if i == 0 {
Some(TRANSPARENT)
} else {
Some(TEXT_COLOR)
})
.set(state.ids.member_panels_bg[i], ui);
// Panel Frame
Image::new(self.imgs.member_frame)
.w_h(152.0, 36.0)
.middle_of(state.ids.member_panels_bg[i])
.color(if i == 0 {
Some(TRANSPARENT)
} else {
Some(UI_HIGHLIGHT_0)
})
.set(state.ids.member_panels_frame[i], ui);
// Panel Text
Text::new(&self.localized_strings.get("hud.group.out_of_range"))
.mid_top_with_margin_on(state.ids.member_panels_bg[i], 3.0)
.font_size(16)
.font_id(self.fonts.cyri.conrod_id)
.color(if i == 0 { TRANSPARENT } else { TEXT_COLOR })
.set(state.ids.dead_txt[i], ui);
}
}
if self.show.group_menu {
let selected = state.selected_member;
Text::new(&group_name)
.mid_top_with_margin_on(state.ids.bg, 2.0)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.title, ui);
if Button::image(self.imgs.button)
.w_h(90.0, 22.0)
.top_right_with_margins_on(state.ids.bg, 30.0, 5.0)
.hover_image(self.imgs.button)
@ -180,47 +499,48 @@ impl<'a> Widget for Group<'a> {
.label_font_size(self.fonts.cyri.scale(10))
.set(state.ids.btn_friend, ui)
.was_clicked()
{};
if Button::image(self.imgs.button)
.w_h(90.0, 22.0)
.bottom_right_with_margins_on(state.ids.bg, 5.0, 5.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label(&self.localized_strings.get("hud.group.leave"))
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.cyri.conrod_id)
.label_font_size(self.fonts.cyri.scale(10))
.set(state.ids.btn_leave, ui)
.was_clicked()
{
events.push(Event::LeaveGroup);
};
// Group leader functions
if my_uid == Some(leader) {
{};
if Button::image(self.imgs.button)
.w_h(90.0, 22.0)
.mid_bottom_with_margin_on(state.ids.btn_friend, -27.0)
.bottom_right_with_margins_on(state.ids.bg, 5.0, 5.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label(&self.localized_strings.get("hud.group.assign_leader"))
.label_color(if state.selected_member.is_some() {
TEXT_COLOR
} else {
TEXT_COLOR_GREY
})
.label(&self.localized_strings.get("hud.group.leave"))
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.cyri.conrod_id)
.label_font_size(self.fonts.cyri.scale(10))
.set(state.ids.btn_leader, ui)
.set(state.ids.btn_leave, ui)
.was_clicked()
{
if let Some(uid) = selected {
events.push(Event::AssignLeader(uid));
state.update(|s| {
s.selected_member = None;
});
}
self.show.group_menu = false;
events.push(Event::LeaveGroup);
};
if Button::image(self.imgs.button)
// Group leader functions
if my_uid == Some(leader) {
if Button::image(self.imgs.button)
.w_h(90.0, 22.0)
.mid_bottom_with_margin_on(state.ids.btn_friend, -27.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label(&self.localized_strings.get("hud.group.assign_leader"))
.label_color(if state.selected_member.is_some() {
TEXT_COLOR
} else {
TEXT_COLOR_GREY
})
.label_font_id(self.fonts.cyri.conrod_id)
.label_font_size(self.fonts.cyri.scale(10))
.set(state.ids.btn_leader, ui)
.was_clicked()
{
if let Some(uid) = selected {
events.push(Event::AssignLeader(uid));
state.update(|s| {
s.selected_member = None;
});
}
};
if Button::image(self.imgs.button)
.w_h(90.0, 22.0)
.mid_bottom_with_margin_on(state.ids.btn_leader, -27.0)
.hover_image(self.imgs.button)
@ -231,105 +551,107 @@ impl<'a> Widget for Group<'a> {
.label_font_size(self.fonts.cyri.scale(10))
.set(state.ids.btn_link, ui)
.was_clicked()
{};
if Button::image(self.imgs.button)
.w_h(90.0, 22.0)
.mid_bottom_with_margin_on(state.ids.btn_link, -27.0)
.down_from(state.ids.btn_link, 5.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label(&self.localized_strings.get("hud.group.kick"))
.label_color(if state.selected_member.is_some() {
TEXT_COLOR
} else {
TEXT_COLOR_GREY
{};
if Button::image(self.imgs.button)
.w_h(90.0, 22.0)
.mid_bottom_with_margin_on(state.ids.btn_link, -27.0)
.down_from(state.ids.btn_link, 5.0)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.label(&self.localized_strings.get("hud.group.kick"))
.label_color(if state.selected_member.is_some() {
TEXT_COLOR
} else {
TEXT_COLOR_GREY
})
.label_font_id(self.fonts.cyri.conrod_id)
.label_font_size(self.fonts.cyri.scale(10))
.set(state.ids.btn_kick, ui)
.was_clicked()
{
if let Some(uid) = selected {
events.push(Event::Kick(uid));
state.update(|s| {
s.selected_member = None;
});
}
};
}
// Group Members, only character names, cut long names when they exceed the
// button size
let group_size = group_members.len() + 1;
if state.ids.members.len() < group_size {
state.update(|s| {
s.ids
.members
.resize(group_size, &mut ui.widget_id_generator())
})
.label_font_id(self.fonts.cyri.conrod_id)
.label_font_size(self.fonts.cyri.scale(10))
.set(state.ids.btn_kick, ui)
.was_clicked()
}
// Scrollable area for group member names
Rectangle::fill_with([110.0, 192.0], color::TRANSPARENT)
.top_left_with_margins_on(state.ids.bg, 30.0, 5.0)
.scroll_kids()
.scroll_kids_vertically()
.set(state.ids.scroll_area, ui);
Scrollbar::y_axis(state.ids.scroll_area)
.thickness(5.0)
.rgba(0.33, 0.33, 0.33, 1.0)
.set(state.ids.scrollbar, ui);
// List member names
for (i, &uid) in self
.client
.uid()
.iter()
.chain(group_members.iter().copied())
.enumerate()
{
if let Some(uid) = selected {
events.push(Event::Kick(uid));
state.update(|s| {
s.selected_member = None;
});
}
};
}
// Group Members, only character names, cut long names when they exceed the
// button size
let group_size = group_members.len() + 1;
if state.ids.members.len() < group_size {
state.update(|s| {
s.ids
.members
.resize(group_size, &mut ui.widget_id_generator())
})
}
// Scrollable area for group member names
Rectangle::fill_with([110.0, 192.0], color::TRANSPARENT)
.top_left_with_margins_on(state.ids.bg, 30.0, 5.0)
.scroll_kids()
.scroll_kids_vertically()
.set(state.ids.scroll_area, ui);
Scrollbar::y_axis(state.ids.scroll_area)
.thickness(5.0)
.rgba(0.33, 0.33, 0.33, 1.0)
.set(state.ids.scrollbar, ui);
// List member names
for (i, &uid) in self
.client
.uid()
.iter()
.chain(group_members.iter().copied())
.enumerate()
{
let selected = state.selected_member.map_or(false, |u| u == uid);
let char_name = uid_to_name_text(uid, &self.client);
let selected = state.selected_member.map_or(false, |u| u == uid);
let char_name = uid_to_name_text(uid, &self.client);
// TODO: Do something special visually if uid == leader
if Button::image(if selected {
self.imgs.selection
} else {
self.imgs.nothing
})
.w_h(100.0, 22.0)
.and(|w| {
if i == 0 {
w.top_left_with_margins_on(state.ids.scroll_area, 5.0, 0.0)
// TODO: Do something special visually if uid == leader
if Button::image(if selected {
self.imgs.selection
} else {
w.down_from(state.ids.members[i - 1], 10.0)
}
})
.hover_image(self.imgs.selection_hover)
.press_image(self.imgs.selection_press)
.crop_kids()
.label_x(Relative::Place(Place::Start(Some(4.0))))
.label(&char_name)
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.cyri.conrod_id)
.label_font_size(self.fonts.cyri.scale(12))
.set(state.ids.members[i], ui)
.was_clicked()
{
// Do nothing when clicking yourself
if Some(uid) != my_uid {
// Select the group member
state.update(|s| {
s.selected_member = if selected { None } else { Some(uid) }
});
}
};
self.imgs.nothing
})
.w_h(100.0, 22.0)
.and(|w| {
if i == 0 {
w.top_left_with_margins_on(state.ids.scroll_area, 5.0, 0.0)
} else {
w.down_from(state.ids.members[i - 1], 10.0)
}
})
.hover_image(self.imgs.selection_hover)
.press_image(self.imgs.selection_press)
.crop_kids()
.label_x(Relative::Place(Place::Start(Some(4.0))))
.label(&char_name)
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.cyri.conrod_id)
.label_font_size(self.fonts.cyri.scale(12))
.set(state.ids.members[i], ui)
.was_clicked()
{
// Do nothing when clicking yourself
if Some(uid) != my_uid {
// Select the group member
state.update(|s| {
s.selected_member = if selected { None } else { Some(uid) }
});
}
};
}
// Maximum of 6 Players/Npcs per Group
// Player pets count as group members, too. They are not counted
// into the maximum group size.
}
// Maximum of 6 Players/Npcs per Group
// Player pets count as group members, too. They are not counted
// into the maximum group size.
}
if let Some(invite_uid) = open_invite {
self.show.group = true; // Auto open group menu
// TODO: add group name here too
// Invite text
let name = uid_to_name_text(invite_uid, &self.client);
let invite_text = self
.localized_strings
@ -337,7 +659,7 @@ impl<'a> Widget for Group<'a> {
.replace("{name}", &name);
Text::new(&invite_text)
.mid_top_with_margin_on(state.ids.bg, 20.0)
.font_size(20)
.font_size(12)
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.title, ui);
@ -364,6 +686,7 @@ impl<'a> Widget for Group<'a> {
.was_clicked()
{
events.push(Event::Accept);
self.show.group_menu = true;
};
// Decline button
let decline_key = self
@ -390,6 +713,7 @@ impl<'a> Widget for Group<'a> {
events.push(Event::Decline);
};
}
events
}
}

View File

@ -76,6 +76,8 @@ image_ids! {
// Group Window
member_frame: "voxygen.element.frames.group_member_frame",
member_bg: "voxygen.element.frames.group_member_bg",
// Chat-Arrows
chat_arrow: "voxygen.element.buttons.arrow_down",

View File

@ -82,6 +82,7 @@ const HP_COLOR: Color = Color::Rgba(0.33, 0.63, 0.0, 1.0);
const LOW_HP_COLOR: Color = Color::Rgba(0.93, 0.59, 0.03, 1.0);
const CRITICAL_HP_COLOR: Color = Color::Rgba(0.79, 0.19, 0.17, 1.0);
const MANA_COLOR: Color = Color::Rgba(0.29, 0.62, 0.75, 0.9);
const TRANSPARENT: Color = Color::Rgba(0.0, 0.0, 0.0, 0.0);
//const FOCUS_COLOR: Color = Color::Rgba(1.0, 0.56, 0.04, 1.0);
//const RAGE_COLOR: Color = Color::Rgba(0.5, 0.04, 0.13, 1.0);
@ -370,6 +371,7 @@ pub struct Show {
social: bool,
spell: bool,
group: bool,
group_menu: bool,
esc_menu: bool,
open_windows: Windows,
map: bool,
@ -404,11 +406,6 @@ impl Show {
}
}
fn group(&mut self, open: bool) {
self.group = open;
self.want_grab = !open;
}
fn social(&mut self, open: bool) {
if !self.esc_menu {
self.social = open;
@ -437,8 +434,6 @@ impl Show {
fn toggle_map(&mut self) { self.map(!self.map) }
fn toggle_group(&mut self) { self.group(!self.group) }
fn toggle_mini_map(&mut self) { self.mini_map = !self.mini_map; }
fn settings(&mut self, open: bool) {
@ -624,6 +619,7 @@ impl Hud {
social: false,
spell: false,
group: false,
group_menu: false,
mini_map: true,
settings_tab: SettingsTab::Interface,
social_tab: SocialTab::Online,
@ -1610,7 +1606,6 @@ impl Hud {
Some(buttons::Event::ToggleSpell) => self.show.toggle_spell(),
Some(buttons::Event::ToggleMap) => self.show.toggle_map(),
Some(buttons::Event::ToggleCrafting) => self.show.toggle_crafting(),
Some(buttons::Event::ToggleGroup) => self.show.toggle_group(),
None => {},
}
}
@ -1949,25 +1944,27 @@ impl Hud {
}
}
// Group Window
if self.show.group {
for event in Group::new(
&mut self.show,
client,
&global_state.settings,
&self.imgs,
&self.fonts,
&self.voxygen_i18n,
)
.set(self.ids.group_window, ui_widgets)
{
match event {
group::Event::Close => self.show.social(false),
group::Event::Accept => events.push(Event::AcceptInvite),
group::Event::Decline => events.push(Event::DeclineInvite),
group::Event::Kick(uid) => events.push(Event::KickMember(uid)),
group::Event::LeaveGroup => events.push(Event::LeaveGroup),
group::Event::AssignLeader(uid) => events.push(Event::AssignLeader(uid)),
}
for event in Group::new(
&mut self.show,
client,
&global_state.settings,
&self.imgs,
&self.fonts,
&self.voxygen_i18n,
tooltip_manager,
&self.rot_imgs,
self.pulse,
&global_state,
)
.set(self.ids.group_window, ui_widgets)
{
match event {
group::Event::Accept => events.push(Event::AcceptInvite),
group::Event::Decline => events.push(Event::DeclineInvite),
group::Event::Kick(uid) => events.push(Event::KickMember(uid)),
group::Event::LeaveGroup => events.push(Event::LeaveGroup),
group::Event::AssignLeader(uid) => events.push(Event::AssignLeader(uid)),
}
}

View File

@ -1153,15 +1153,14 @@ impl<'a> Widget for Skillbar<'a> {
.w_h(100.0 * scale, 20.0 * scale)
.top_left_with_margins_on(state.ids.m1_slot, 0.0, -100.0 * scale)
.set(state.ids.healthbar_bg, ui);
let health_col = match hp_percentage as u8 {
0..=20 => crit_hp_color,
21..=40 => LOW_HP_COLOR,
_ => HP_COLOR,
};
Image::new(self.imgs.bar_content)
.w_h(97.0 * scale * hp_percentage / 100.0, 16.0 * scale)
.color(Some(if hp_percentage <= 20.0 {
crit_hp_color
} else if hp_percentage <= 40.0 {
LOW_HP_COLOR
} else {
HP_COLOR
}))
.color(Some(health_col))
.top_right_with_margins_on(state.ids.healthbar_bg, 2.0 * scale, 1.0 * scale)
.set(state.ids.healthbar_filling, ui);
// Energybar

View File

@ -105,8 +105,10 @@ impl<'a> Widget for Social<'a> {
let mut events = Vec::new();
let pos = if self.show.group { 180.0 } else { 25.0 };
Image::new(self.imgs.window_3)
.top_left_with_margins_on(ui.window, 200.0, 25.0)
.top_left_with_margins_on(ui.window, 200.0, pos)
.color(Some(UI_MAIN))
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(state.ids.social_frame, ui);