Part 1 of implementing the social window

This commit is contained in:
Monty Marz 2019-08-07 13:14:26 +00:00 committed by Marcel
parent 18f5504efc
commit 2101f27ffb
17 changed files with 695 additions and 212 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -3,7 +3,7 @@ use conrod_core::{
widget_ids, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
};
use super::{img_ids::Imgs, small_window::SmallWindowType, Fonts, Windows, TEXT_COLOR};
use super::{img_ids::Imgs, Fonts, Windows, TEXT_COLOR};
use crate::ui::ToggleButton;
widget_ids! {
@ -63,7 +63,9 @@ pub enum Event {
ToggleBag,
ToggleSettings,
ToggleMap,
ToggleSmall(SmallWindowType),
ToggleSocial,
ToggleSpell,
ToggleQuest,
ToggleCharacter,
}
@ -154,6 +156,13 @@ impl<'a> Widget for Buttons<'a> {
return Some(Event::ToggleMap);
};
// Other Windows can only be accessed when `Settings` is closed.
// Opening `Settings` will close all other Windows, including the `Bag`.
// Opening the `Map` won't close the previously displayed windows.
Image::new(self.imgs.social)
.w_h(25.0, 25.0)
.left_from(state.ids.settings_button, 10.0)
.set(state.ids.social_button_bg, ui);
Image::new(self.imgs.spellbook_button)
.w_h(28.0, 25.0)
.left_from(state.ids.map_button, 10.0)
@ -172,7 +181,7 @@ impl<'a> Widget for Buttons<'a> {
// Opening the `Map` won't close the previously displayed windows.
if !(*self.open_windows == Windows::Settings) && self.show_map == false {
// 1 Social
if Button::image(self.imgs.social_button)
if Button::image(self.imgs.social)
.w_h(25.0, 25.0)
.left_from(state.ids.settings_button, 10.0)
.hover_image(self.imgs.social_hover)
@ -185,7 +194,7 @@ impl<'a> Widget for Buttons<'a> {
.set(state.ids.social_button, ui)
.was_clicked()
{
return Some(Event::ToggleSmall(SmallWindowType::Social));
return Some(Event::ToggleSocial);
}
// 3 Spellbook
@ -202,7 +211,7 @@ impl<'a> Widget for Buttons<'a> {
.set(state.ids.spellbook_button, ui)
.was_clicked()
{
return Some(Event::ToggleSmall(SmallWindowType::Spellbook));
return Some(Event::ToggleSpell);
}
// 4 Char-Window
@ -236,7 +245,7 @@ impl<'a> Widget for Buttons<'a> {
.set(state.ids.qlog_button, ui)
.was_clicked()
{
return Some(Event::ToggleSmall(SmallWindowType::QuestLog));
return Some(Event::ToggleQuest);
}
}

@ -1,4 +1,4 @@
use super::{img_ids::Imgs, Fonts, TEXT_COLOR, XP_COLOR};
use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR, XP_COLOR};
use common::comp::Stats;
use conrod_core::{
color,
@ -68,6 +68,7 @@ widget_ids! {
#[derive(WidgetCommon)]
pub struct CharacterWindow<'a> {
_show: &'a Show,
imgs: &'a Imgs,
fonts: &'a Fonts,
stats: &'a Stats,
@ -77,8 +78,9 @@ pub struct CharacterWindow<'a> {
}
impl<'a> CharacterWindow<'a> {
pub fn new(imgs: &'a Imgs, fonts: &'a Fonts, stats: &'a Stats) -> Self {
pub fn new(_show: &'a Show, stats: &'a Stats, imgs: &'a Imgs, fonts: &'a Fonts) -> Self {
Self {
_show,
imgs,
fonts,
stats,
@ -87,6 +89,10 @@ impl<'a> CharacterWindow<'a> {
}
}
/*pub struct State {
ids: Ids,
}*/
pub enum Event {
Close,
}
@ -114,7 +120,7 @@ impl<'a> Widget for CharacterWindow<'a> {
// Frame
Image::new(self.imgs.window_3)
.middle_of(id)
.top_left_with_margins_on(ui.window, 212.0, 215.0)
.top_left_with_margins_on(ui.window, 200.0, 215.0)
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(state.charwindow_frame, ui);

@ -26,6 +26,14 @@ image_ids! {
// Missing: Buff Frame Animation .gif ?! we could do animation in ui.maintain, or in shader?
window_frame: "voxygen.element.frames.window2",
// Social Window
social_button: "voxygen.element.buttons.social_tab",
social_button_pressed: "voxygen.element.buttons.social_tab_pressed",
social_button_hover: "voxygen.element.buttons.social_tab_hover",
social_button_press: "voxygen.element.buttons.social_tab_press",
social_frame: "voxygen.element.frames.social_frame",
// Settings Window
settings_frame_r: "voxygen.element.frames.settings_r",
settings_frame_l: "voxygen.element.frames.settings_l",
@ -85,7 +93,7 @@ image_ids! {
settings_hover: "voxygen.element.buttons.settings_hover",
settings_press: "voxygen.element.buttons.settings_press",
social_button: "voxygen.element.buttons.social",
social: "voxygen.element.buttons.social",
social_hover: "voxygen.element.buttons.social_hover",
social_press: "voxygen.element.buttons.social_press",

@ -6,9 +6,11 @@ mod esc_menu;
mod img_ids;
mod map;
mod minimap;
mod quest;
mod settings_window;
mod skillbar;
mod small_window;
mod social;
mod spell;
pub use settings_window::ScaleChange;
@ -20,10 +22,12 @@ use esc_menu::EscMenu;
use img_ids::Imgs;
use map::Map;
use minimap::MiniMap;
use quest::Quest;
use serde::{Deserialize, Serialize};
use settings_window::{SettingsTab, SettingsWindow};
use skillbar::Skillbar;
use small_window::{SmallWindow, SmallWindowType};
use social::{Social, SocialTab};
use spell::Spell;
use crate::{
render::{Consts, Globals, Renderer},
@ -50,6 +54,7 @@ use crate::{discord, discord::DiscordUpdate};
const XP_COLOR: Color = Color::Rgba(0.59, 0.41, 0.67, 1.0);
const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
const TEXT_COLOR_2: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0);
const TEXT_COLOR_3: Color = Color::Rgba(1.0, 1.0, 1.0, 0.1);
const HP_COLOR: Color = Color::Rgba(0.33, 0.63, 0.0, 1.0);
const MANA_COLOR: Color = Color::Rgba(0.42, 0.41, 0.66, 1.0);
const META_COLOR: Color = Color::Rgba(1.0, 1.0, 0.0, 1.0);
@ -109,10 +114,14 @@ widget_ids! {
character_window,
minimap,
bag,
social,
quest,
spell,
skillbar,
buttons,
esc_menu,
small_window,
social_window,
settings_window,
}
}
@ -155,9 +164,7 @@ pub enum Event {
// `map` is not here because it currently is displayed over the top of other open windows.
#[derive(PartialEq)]
pub enum Windows {
Settings, // Display settings window.
CharacterAnd(Option<SmallWindowType>), // Show character window + optionally another.
Small(SmallWindowType),
Settings, // Display settings window.
None,
}
@ -173,6 +180,10 @@ pub struct Show {
help: bool,
debug: bool,
bag: bool,
social: bool,
spell: bool,
quest: bool,
character_window: bool,
esc_menu: bool,
open_windows: Windows,
map: bool,
@ -180,6 +191,8 @@ pub struct Show {
mini_map: bool,
ingame: bool,
settings_tab: SettingsTab,
social_tab: SocialTab,
want_grab: bool,
}
impl Show {
@ -195,6 +208,29 @@ impl Show {
self.bag = false;
self.want_grab = !open;
}
fn character_window(&mut self, open: bool) {
self.character_window = open;
self.bag = false;
self.want_grab = !open;
}
fn social(&mut self, open: bool) {
self.social = open;
self.spell = false;
self.quest = false;
self.want_grab = !open;
}
fn spell(&mut self, open: bool) {
self.social = false;
self.spell = open;
self.quest = false;
self.want_grab = !open;
}
fn quest(&mut self, open: bool) {
self.social = false;
self.spell = false;
self.quest = open;
self.want_grab = !open;
}
fn toggle_map(&mut self) {
self.map(!self.map)
}
@ -203,28 +239,8 @@ impl Show {
self.mini_map = !self.mini_map;
}
fn toggle_small(&mut self, target: SmallWindowType) {
self.open_windows = match self.open_windows {
Windows::Small(small) if small == target => Windows::None,
Windows::None | Windows::Small(_) => Windows::Small(target),
Windows::CharacterAnd(small) => match small {
Some(small) if small == target => Windows::CharacterAnd(None),
_ => Windows::CharacterAnd(Some(target)),
},
Windows::Settings => Windows::Settings,
};
}
fn toggle_char_window(&mut self) {
self.open_windows = match self.open_windows {
Windows::CharacterAnd(small) => match small {
Some(small) => Windows::Small(small),
None => Windows::None,
},
Windows::Small(small) => Windows::CharacterAnd(Some(small)),
Windows::None => Windows::CharacterAnd(None),
Windows::Settings => Windows::Settings,
}
self.character_window = !self.character_window
}
fn settings(&mut self, open: bool) {
@ -234,6 +250,9 @@ impl Show {
Windows::None
};
self.bag = false;
self.social = false;
self.spell = false;
self.quest = false;
self.want_grab = !open;
}
fn toggle_settings(&mut self) {
@ -255,6 +274,10 @@ impl Show {
if self.bag
|| self.esc_menu
|| self.map
|| self.social
|| self.quest
|| self.spell
|| self.character_window
|| match self.open_windows {
Windows::None => false,
_ => true,
@ -263,6 +286,10 @@ impl Show {
self.bag = false;
self.esc_menu = false;
self.map = false;
self.social = false;
self.quest = false;
self.spell = false;
self.character_window = false;
self.open_windows = Windows::None;
self.want_grab = true;
} else {
@ -278,6 +305,30 @@ impl Show {
self.bag = false;
self.want_grab = false;
}
fn toggle_social(&mut self) {
self.social = !self.social;
self.spell = false;
self.quest = false;
}
fn open_social_tab(&mut self, social_tab: SocialTab) {
self.social_tab = social_tab;
self.spell = false;
self.quest = false;
}
fn toggle_spell(&mut self) {
self.spell = !self.spell;
self.social = false;
self.quest = false;
}
fn toggle_quest(&mut self) {
self.quest = !self.quest;
self.spell = false;
self.social = false;
}
}
pub struct Hud {
@ -323,9 +374,14 @@ impl Hud {
open_windows: Windows::None,
map: false,
ui: true,
social: false,
quest: false,
spell: false,
character_window: false,
inventory_test_button: false,
mini_map: false,
settings_tab: SettingsTab::Interface,
social_tab: SocialTab::Online,
want_grab: true,
ingame: true,
},
@ -347,27 +403,7 @@ impl Hud {
let version = format!("{}-{}", env!("CARGO_PKG_VERSION"), common::util::GIT_HASH);
// Nametags and healthbars
if self.show.ingame {
let ecs = client.state().ecs();
let pos = ecs.read_storage::<comp::Pos>();
let stats = ecs.read_storage::<comp::Stats>();
let players = ecs.read_storage::<comp::Player>();
let scales = ecs.read_storage::<comp::Scale>();
let entities = ecs.entities();
let me = client.entity();
let view_distance = client.view_distance().unwrap_or(1);
// Get player position.
let player_pos = client
.state()
.ecs()
.read_storage::<comp::Pos>()
.get(client.entity())
.map_or(Vec3::zero(), |pos| pos.0);
let mut name_id_walker = self.ids.name_tags.walk();
let mut health_id_walker = self.ids.health_bars.walk();
let mut health_back_id_walker = self.ids.health_bar_backs.walk();
// Crosshair
Image::new(
// TODO: Do we want to match on this every frame?
@ -392,6 +428,26 @@ impl Hud {
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.6)))
.set(self.ids.crosshair_inner, ui_widgets);
// Nametags and healthbars
let ecs = client.state().ecs();
let pos = ecs.read_storage::<comp::Pos>();
let stats = ecs.read_storage::<comp::Stats>();
let players = ecs.read_storage::<comp::Player>();
let scales = ecs.read_storage::<comp::Scale>();
let entities = ecs.entities();
let me = client.entity();
let view_distance = client.view_distance().unwrap_or(1);
// Get player position.
let player_pos = client
.state()
.ecs()
.read_storage::<comp::Pos>()
.get(client.entity())
.map_or(Vec3::zero(), |pos| pos.0);
let mut name_id_walker = self.ids.name_tags.walk();
let mut health_id_walker = self.ids.health_bars.walk();
let mut health_back_id_walker = self.ids.health_bar_backs.walk();
// Render Name Tags
for (pos, name, scale) in (&entities, &pos, &stats, players.maybe(), scales.maybe())
.join()
@ -592,7 +648,9 @@ impl Hud {
Some(buttons::Event::ToggleBag) => self.show.toggle_bag(),
Some(buttons::Event::ToggleSettings) => self.show.toggle_settings(),
Some(buttons::Event::ToggleCharacter) => self.show.toggle_char_window(),
Some(buttons::Event::ToggleSmall(small)) => self.show.toggle_small(small),
Some(buttons::Event::ToggleSocial) => self.show.toggle_social(),
Some(buttons::Event::ToggleSpell) => self.show.toggle_spell(),
Some(buttons::Event::ToggleQuest) => self.show.toggle_quest(),
Some(buttons::Event::ToggleMap) => self.show.toggle_map(),
None => {}
}
@ -702,40 +760,66 @@ impl Hud {
}
}
// Small Window
if let Windows::Small(small) | Windows::CharacterAnd(Some(small)) = self.show.open_windows {
match SmallWindow::new(small, &self.show, &self.imgs, &self.fonts)
.set(self.ids.small_window, ui_widgets)
// Social Window
if self.show.social {
for event in Social::new(
/*&global_state,*/ &self.show,
client,
&self.imgs,
&self.fonts,
)
.set(self.ids.social_window, ui_widgets)
{
Some(small_window::Event::Close) => {
self.show.open_windows = match self.show.open_windows {
Windows::Small(_) => Windows::None,
Windows::CharacterAnd(_) => Windows::CharacterAnd(None),
_ => Windows::Settings,
match event {
social::Event::Close => self.show.social(false),
social::Event::ChangeSocialTab(social_tab) => {
self.show.open_social_tab(social_tab)
}
}
None => {}
}
}
// Character Window
if let Windows::CharacterAnd(small) = self.show.open_windows {
if self.show.character_window {
let ecs = client.state().ecs();
let stats = ecs.read_storage::<comp::Stats>();
let player_stats = stats.get(client.entity()).unwrap();
match CharacterWindow::new(&self.imgs, &self.fonts, &player_stats)
match CharacterWindow::new(&self.show, &player_stats, &self.imgs, &self.fonts)
.set(self.ids.character_window, ui_widgets)
{
Some(character_window::Event::Close) => {
self.show.open_windows = match small {
Some(small) => Windows::Small(small),
None => Windows::None,
}
self.show.character_window(false);
self.force_ungrab = true;
}
None => {}
}
}
// Spellbook
if self.show.spell {
match Spell::new(&self.show, client, &self.imgs, &self.fonts)
.set(self.ids.spell, ui_widgets)
{
Some(spell::Event::Close) => {
self.show.spell(false);
self.force_ungrab = true;
}
None => {}
}
}
// Quest Log
if self.show.quest {
match Quest::new(&self.show, client, &self.imgs, &self.fonts)
.set(self.ids.quest, ui_widgets)
{
Some(quest::Event::Close) => {
self.show.quest(false);
self.force_ungrab = true;
}
None => {}
}
}
// Map
if self.show.map {
match Map::new(&self.show, client, &self.imgs, &self.fonts)
@ -866,7 +950,7 @@ impl Hud {
true
}
GameInput::QuestLog => {
self.show.toggle_small(SmallWindowType::QuestLog);
self.show.toggle_quest();
true
}
GameInput::CharacterWindow => {
@ -874,11 +958,11 @@ impl Hud {
true
}
GameInput::Social => {
self.show.toggle_small(SmallWindowType::Social);
self.show.toggle_social();
true
}
GameInput::Spellbook => {
self.show.toggle_small(SmallWindowType::Spellbook);
self.show.toggle_spell();
true
}
GameInput::Settings => {

114
voxygen/src/hud/quest.rs Normal file

@ -0,0 +1,114 @@
use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR};
use conrod_core::{
color,
widget::{self, Button, Image, Rectangle, Text},
widget_ids, /*, Color*/
Colorable, Positionable, Sizeable, Widget, WidgetCommon,
};
use client::{self, Client};
widget_ids! {
pub struct Ids {
quest_frame,
quest_close,
quest_title,
frame,
content_align,
}
}
#[derive(WidgetCommon)]
pub struct Quest<'a> {
_show: &'a Show,
_client: &'a Client,
imgs: &'a Imgs,
fonts: &'a Fonts,
#[conrod(common_builder)]
common: widget::CommonBuilder,
}
impl<'a> Quest<'a> {
pub fn new(show: &'a Show, _client: &'a Client, imgs: &'a Imgs, fonts: &'a Fonts) -> Self {
Self {
_show: show,
imgs,
_client,
fonts: fonts,
common: widget::CommonBuilder::default(),
}
}
}
/*pub struct State {
ids: Ids,
}*/
pub enum Event {
Close,
}
impl<'a> Widget for Quest<'a> {
type State = Ids;
type Style = ();
type Event = Option<Event>;
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
Ids::new(id_gen)
}
fn style(&self) -> Self::Style {
()
}
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
let widget::UpdateArgs {
id: _, state, ui, ..
} = args;
if self._show.character_window {
Image::new(self.imgs.window_3)
.top_left_with_margins_on(ui.window, 200.0, 658.0)
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(state.quest_frame, ui);
} else {
Image::new(self.imgs.window_3)
.top_left_with_margins_on(ui.window, 200.0, 25.0)
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(state.quest_frame, ui);
}
// X-Button
if Button::image(self.imgs.close_button)
.w_h(28.0, 28.0)
.hover_image(self.imgs.close_button_hover)
.press_image(self.imgs.close_button_press)
.top_right_with_margins_on(state.quest_frame, 0.0, 0.0)
.set(state.quest_close, ui)
.was_clicked()
{
return Some(Event::Close);
}
// Title
// TODO: Use an actual character name.
Text::new("Quest")
.mid_top_with_margin_on(state.quest_frame, 6.0)
.font_id(self.fonts.metamorph)
.font_size(14)
.color(TEXT_COLOR)
.set(state.quest_title, ui);
// Content Alignment
Rectangle::fill_with([95.0 * 4.0, 108.0 * 4.0], color::TRANSPARENT)
.mid_top_with_margin_on(state.quest_frame, 40.0)
.set(state.content_align, ui);
// Contents
// Frame
None
}
}

@ -1,136 +0,0 @@
use super::{img_ids::Imgs, Fonts, Windows, TEXT_COLOR};
use crate::hud::Show;
use conrod_core::{
color,
widget::{self, Button, Image, Rectangle, Text},
widget_ids, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
};
widget_ids! {
struct Ids {
frame,
bg,
title,
icon,
close,
}
}
#[derive(Clone, Copy, PartialEq)]
pub enum SmallWindowType {
Spellbook,
Social,
QuestLog,
}
#[derive(WidgetCommon)]
pub struct SmallWindow<'a> {
content: SmallWindowType,
show: &'a Show,
imgs: &'a Imgs,
fonts: &'a Fonts,
#[conrod(common_builder)]
common: widget::CommonBuilder,
}
impl<'a> SmallWindow<'a> {
pub fn new(content: SmallWindowType, show: &'a Show, imgs: &'a Imgs, fonts: &'a Fonts) -> Self {
Self {
content,
show,
imgs,
fonts,
common: widget::CommonBuilder::default(),
}
}
}
pub struct State {
ids: Ids,
}
pub enum Event {
Close,
}
impl<'a> Widget for SmallWindow<'a> {
type State = State;
type Style = ();
type Event = Option<Event>;
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
State {
ids: Ids::new(id_gen),
}
}
fn style(&self) -> Self::Style {
()
}
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
let widget::UpdateArgs { state, ui, .. } = args;
let (title, icon) = match self.content {
SmallWindowType::Social => ("Social", self.imgs.social_icon),
SmallWindowType::Spellbook => ("Spellbook", self.imgs.spellbook_icon),
SmallWindowType::QuestLog => ("QuestLog", self.imgs.questlog_icon),
};
// Frame
// TODO: Relative to Char Window?
if let Windows::CharacterAnd(_) = self.show.open_windows {
Image::new(self.imgs.window_frame)
.top_left_with_margins_on(ui.window, 200.0, 658.0)
.w_h(107.0 * 4.0, 125.0 * 4.0)
.set(state.ids.frame, ui);
} else {
Image::new(self.imgs.window_frame)
.top_left_with_margins_on(ui.window, 200.0, 10.0)
.w_h(107.0 * 4.0, 125.0 * 4.0)
.set(state.ids.frame, ui);
}
// Icon
Image::new(icon)
.w_h(40.0, 40.0)
.top_left_with_margins_on(state.ids.frame, 4.0, 4.0)
.set(state.ids.icon, ui);
// Content alignment
Rectangle::fill_with([362.0, 418.0], color::TRANSPARENT)
.bottom_right_with_margins_on(state.ids.frame, 17.0, 17.0)
.scroll_kids()
.scroll_kids_vertically()
.set(state.ids.bg, ui);
// X-Button
if Button::image(self.imgs.close_button)
.w_h(28.0, 28.0)
.hover_image(self.imgs.close_button_hover)
.press_image(self.imgs.close_button_press)
.top_right_with_margins_on(state.ids.frame, 12.0, 0.0)
.set(state.ids.close, ui)
.was_clicked()
{
return Some(Event::Close);
}
// Title
Text::new(title)
.mid_top_with_margin_on(state.ids.frame, 16.0)
.font_id(self.fonts.metamorph)
.font_size(14)
.color(TEXT_COLOR)
.set(state.ids.title, ui);
match self.content {
SmallWindowType::Social => {}
SmallWindowType::Spellbook => {}
SmallWindowType::QuestLog => {}
}
None
}
}

281
voxygen/src/hud/social.rs Normal file

@ -0,0 +1,281 @@
use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR, TEXT_COLOR_3};
use common::comp;
use conrod_core::{
color,
widget::{self, Button, Image, Rectangle, Scrollbar, Text},
widget_ids, /*, Color*/
Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
};
use specs::Join;
use client::{self, Client};
widget_ids! {
pub struct Ids {
social_frame,
social_close,
social_title,
frame,
align,
content_align,
online_tab,
friends_tab,
faction_tab,
online_title,
online_no,
scrollbar,
friends_test,
faction_test,
player_names[],
}
}
pub enum SocialTab {
Online,
Friends,
Faction,
}
#[derive(WidgetCommon)]
pub struct Social<'a> {
show: &'a Show,
client: &'a Client,
imgs: &'a Imgs,
fonts: &'a Fonts,
#[conrod(common_builder)]
common: widget::CommonBuilder,
}
impl<'a> Social<'a> {
pub fn new(show: &'a Show, client: &'a Client, imgs: &'a Imgs, fonts: &'a Fonts) -> Self {
Self {
show: show,
imgs,
client: client,
fonts: fonts,
common: widget::CommonBuilder::default(),
}
}
}
/*pub struct State {
ids: Ids,
}*/
pub enum Event {
Close,
ChangeSocialTab(SocialTab),
}
impl<'a> Widget for Social<'a> {
type State = Ids;
type Style = ();
type Event = Vec<Event>;
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
Ids::new(id_gen)
}
fn style(&self) -> Self::Style {
()
}
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
let widget::UpdateArgs {
/*id,*/ state: ids,
ui,
..
} = args;
let mut events = Vec::new();
if self.show.character_window {
Image::new(self.imgs.window_3)
.top_left_with_margins_on(ui.window, 200.0, 658.0)
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(ids.social_frame, ui);
} else {
Image::new(self.imgs.window_3)
.top_left_with_margins_on(ui.window, 200.0, 25.0)
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(ids.social_frame, ui);
}
// X-Button
if Button::image(self.imgs.close_button)
.w_h(28.0, 28.0)
.hover_image(self.imgs.close_button_hover)
.press_image(self.imgs.close_button_press)
.top_right_with_margins_on(ids.social_frame, 0.0, 0.0)
.set(ids.social_close, ui)
.was_clicked()
{
events.push(Event::Close);
}
// Title
Text::new("Social")
.mid_top_with_margin_on(ids.social_frame, 6.0)
.font_id(self.fonts.metamorph)
.font_size(14)
.color(TEXT_COLOR)
.set(ids.social_title, ui);
// Alignment
Rectangle::fill_with([99.0 * 4.0, 112.0 * 4.0], color::TRANSPARENT)
.mid_top_with_margin_on(ids.social_frame, 8.0 * 4.0)
.set(ids.align, ui);
// Content Alignment
Rectangle::fill_with([94.0 * 4.0, 94.0 * 4.0], color::TRANSPARENT)
.middle_of(ids.frame)
.scroll_kids()
.scroll_kids_vertically()
.set(ids.content_align, ui);
Scrollbar::y_axis(ids.content_align)
.thickness(5.0)
.rgba(0.33, 0.33, 0.33, 1.0)
.set(ids.scrollbar, ui);
// Frame
Image::new(self.imgs.social_frame)
.w_h(99.0 * 4.0, 100.0 * 4.0)
.mid_bottom_of(ids.align)
.set(ids.frame, ui);
// Online Tab
if Button::image(if let SocialTab::Online = self.show.social_tab {
self.imgs.social_button_pressed
} else {
self.imgs.social_button
})
.w_h(30.0 * 4.0, 12.0 * 4.0)
.hover_image(if let SocialTab::Online = self.show.social_tab {
self.imgs.social_button_pressed
} else {
self.imgs.social_button_hover
})
.press_image(if let SocialTab::Online = self.show.social_tab {
self.imgs.social_button_pressed
} else {
self.imgs.social_button_press
})
.top_left_with_margins_on(ids.align, 4.0, 0.0)
.label("Online")
.label_font_size(14)
.parent(ids.frame)
.label_color(TEXT_COLOR)
.set(ids.online_tab, ui)
.was_clicked()
{
events.push(Event::ChangeSocialTab(SocialTab::Online));
}
// Contents
if let SocialTab::Online = self.show.social_tab {
// TODO Needs to be a string sent from the server
// Players list
// TODO: this list changes infrequently enough that it should not have to be recreated every frame
let ecs = self.client.state().ecs();
let players = ecs.read_storage::<comp::Player>();
let mut count = 0;
for player in players.join() {
if ids.player_names.len() <= count {
ids.update(|ids| {
ids.player_names
.resize(count + 1, &mut ui.widget_id_generator())
})
}
Text::new(&player.alias)
.down_from(ids.online_title, count as f64 * (15.0 + 3.0))
.font_size(15)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(ids.player_names[count], ui);
count += 1;
}
Text::new(&format!("{} player(s) online\n", count))
.top_left_with_margins_on(ids.content_align, -2.0, 7.0)
.font_size(14)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR)
.set(ids.online_title, ui);
}
// Friends Tab
if Button::image(if let SocialTab::Friends = self.show.social_tab {
self.imgs.social_button_pressed
} else {
self.imgs.social_button
})
.w_h(30.0 * 4.0, 12.0 * 4.0)
.hover_image(if let SocialTab::Friends = self.show.social_tab {
self.imgs.social_button_pressed
} else {
self.imgs.social_button
})
.press_image(if let SocialTab::Friends = self.show.social_tab {
self.imgs.social_button_pressed
} else {
self.imgs.social_button
})
.right_from(ids.online_tab, 0.0)
.label("Friends")
.label_font_size(14)
.parent(ids.frame)
.label_color(TEXT_COLOR_3)
.set(ids.friends_tab, ui)
.was_clicked()
{
events.push(Event::ChangeSocialTab(SocialTab::Friends));
}
// Contents
if let SocialTab::Friends = self.show.social_tab {
Text::new("Not yet available")
.middle_of(ids.content_align)
.font_size(18)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR_3)
.set(ids.friends_test, ui);
}
// Faction Tab
let button_img = if let SocialTab::Faction = self.show.social_tab {
self.imgs.social_button_pressed
} else {
self.imgs.social_button
};
if Button::image(button_img)
.w_h(30.0 * 4.0, 12.0 * 4.0)
.right_from(ids.friends_tab, 0.0)
.label("Faction")
.parent(ids.frame)
.label_font_size(14)
.label_color(TEXT_COLOR_3)
.set(ids.faction_tab, ui)
.was_clicked()
{
events.push(Event::ChangeSocialTab(SocialTab::Faction));
}
// Contents
if let SocialTab::Faction = self.show.social_tab {
Text::new("Not yet available")
.middle_of(ids.content_align)
.font_size(18)
.font_id(self.fonts.opensans)
.color(TEXT_COLOR_3)
.set(ids.faction_test, ui);
}
events
}
}

117
voxygen/src/hud/spell.rs Normal file

@ -0,0 +1,117 @@
use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR};
use conrod_core::{
color,
widget::{self, Button, Image, Rectangle, Text},
widget_ids, /*, Color*/
Colorable, Positionable, Sizeable, Widget, WidgetCommon,
};
use client::{self, Client};
widget_ids! {
pub struct Ids {
spell_frame,
spell_close,
spell_title,
frame,
content_align,
}
}
#[derive(WidgetCommon)]
pub struct Spell<'a> {
_show: &'a Show,
_client: &'a Client,
imgs: &'a Imgs,
fonts: &'a Fonts,
#[conrod(common_builder)]
common: widget::CommonBuilder,
}
impl<'a> Spell<'a> {
pub fn new(show: &'a Show, _client: &'a Client, imgs: &'a Imgs, fonts: &'a Fonts) -> Self {
Self {
_show: show,
imgs,
_client,
fonts: fonts,
common: widget::CommonBuilder::default(),
}
}
}
/*pub struct State {
ids: Ids,
}*/
pub enum Event {
Close,
}
impl<'a> Widget for Spell<'a> {
type State = Ids;
type Style = ();
type Event = Option<Event>;
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
Ids::new(id_gen)
}
fn style(&self) -> Self::Style {
()
}
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
let widget::UpdateArgs {
id: _, state, ui, ..
} = args;
if self._show.character_window {
Image::new(self.imgs.window_3)
.top_left_with_margins_on(ui.window, 200.0, 658.0)
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(state.spell_frame, ui);
} else {
Image::new(self.imgs.window_3)
.top_left_with_margins_on(ui.window, 200.0, 25.0)
.w_h(103.0 * 4.0, 122.0 * 4.0)
.set(state.spell_frame, ui);
}
// X-Button
if Button::image(self.imgs.close_button)
.w_h(28.0, 28.0)
.hover_image(self.imgs.close_button_hover)
.press_image(self.imgs.close_button_press)
.top_right_with_margins_on(state.spell_frame, 0.0, 0.0)
.set(state.spell_close, ui)
.was_clicked()
{
return Some(Event::Close);
}
// Title
// TODO: Use an actual character name.
Text::new("Spell")
.mid_top_with_margin_on(state.spell_frame, 6.0)
.font_id(self.fonts.metamorph)
.font_size(14)
.color(TEXT_COLOR)
.set(state.spell_title, ui);
// Content Alignment
Rectangle::fill_with([95.0 * 4.0, 108.0 * 4.0], color::TRANSPARENT)
.mid_top_with_margin_on(state.spell_frame, 40.0)
.set(state.content_align, ui);
// Contents
// Frame
None
}
}