Skip to main content

veloren_voxygen/hud/
controller_icons.rs

1use super::img_ids::Imgs;
2use crate::{
3    Settings,
4    game_input::GameInput,
5    settings::Button,
6    window::{ControllerType, MenuInput},
7};
8use conrod_core::image::Id as ConrodImageId;
9use gilrs::Button as GilButton;
10
11/// Returns the left trigger (dark) icon based on controller type
12pub fn fetch_skillbar_gamepad_left(ctrl_type: ControllerType, imgs: &Imgs) -> ConrodImageId {
13    match ctrl_type {
14        ControllerType::Xbox => imgs.left_trigger_xbox_dark,
15        ControllerType::Nintendo => imgs.left_trigger_nin_dark,
16        ControllerType::Playstation => imgs.left_trigger_ps_dark,
17        _ => imgs.m1_ico,
18    }
19}
20
21/// Returns the right trigger (dark) icon based on controller type
22pub fn fetch_skillbar_gamepad_right(ctrl_type: ControllerType, imgs: &Imgs) -> ConrodImageId {
23    match ctrl_type {
24        ControllerType::Xbox => imgs.right_trigger_xbox_dark,
25        ControllerType::Nintendo => imgs.right_trigger_nin_dark,
26        ControllerType::Playstation => imgs.right_trigger_ps_dark,
27        _ => imgs.m2_ico,
28    }
29}
30
31/// Represents an input that has no binding
32pub const UNBOUND_KEY: &str = ":none:";
33
34/// Gets a string output for the controller input based on GameInput data
35///
36/// a multi-input action will return like ":mod2: + :mod1: + :main:"
37pub fn get_controller_input_string(
38    input: GameInput,
39    settings: &Settings,
40    ctrl: ControllerType,
41) -> Option<String> {
42    let mut icon_tags = Vec::new();
43    let unknown = Button::Simple(GilButton::Unknown);
44
45    // extract just the button name
46    let get_tag = |b: Button| {
47        let mut name = match b {
48            Button::Simple(inner) => format!("{:?}", inner),
49            _ => format!("{:?}", b),
50        };
51        match ctrl {
52            ControllerType::Xbox => name.push_str("_x"),
53            ControllerType::Nintendo => name.push_str("_n"),
54            ControllerType::Playstation => name.push_str("_p"),
55            _ => {},
56        }
57        format!(":{}:", name)
58    };
59
60    // prioritize game layers over game buttons
61    if let Some(layer) = settings.controller.get_layer_button_binding(input) {
62        // add modifiers if they aren't Unknown
63        if layer.mod2 != unknown {
64            icon_tags.push(get_tag(layer.mod2));
65        }
66        if layer.mod1 != unknown {
67            icon_tags.push(get_tag(layer.mod1));
68        }
69
70        // add the main layer button
71        icon_tags.push(get_tag(layer.button));
72    } else if let Some(button) = settings.controller.get_game_button_binding(input) {
73        icon_tags.push(get_tag(button));
74    }
75
76    if icon_tags.is_empty() {
77        None
78    } else {
79        Some(icon_tags.join(" + ").to_lowercase())
80    }
81}
82
83/// Gets a string output for the controller input based on MenuInput data
84pub fn get_controller_input_string_menu(
85    input: MenuInput,
86    settings: &Settings,
87    ctrl: ControllerType,
88) -> Option<String> {
89    // Extract just the button name
90    let get_tag = |b: Button| {
91        let mut name = match b {
92            Button::Simple(inner) => format!("{:?}", inner),
93            _ => format!("{:?}", b),
94        };
95        match ctrl {
96            ControllerType::Xbox => name.push_str("_x"),
97            ControllerType::Nintendo => name.push_str("_n"),
98            ControllerType::Playstation => name.push_str("_p"),
99            _ => {},
100        }
101        format!(":{}:", name).to_lowercase()
102    };
103
104    settings
105        .controller
106        .get_menu_button_binding(input)
107        .map(get_tag)
108}
109
110/// Returns a ConrodImageId for valid strings
111pub fn get_controller_icon_id_from_string(name: &str, imgs: &Imgs) -> ConrodImageId {
112    // TODO: either gilrs or we have to swap nintendo buttons to be accurate. Figure
113    // it out when controller type detection is working.
114    match name {
115        "south" | "south_x" | "south_n" => imgs.south_button_a,
116        "south_p" => imgs.south_button_ps_cross,
117        "east" | "east_x" | "east_n" => imgs.east_button_b,
118        "east_p" => imgs.east_button_ps_circle,
119        "west" | "west_x" | "west_n" => imgs.west_button_x,
120        "west_p" => imgs.west_button_ps_square,
121        "north" | "north_x" | "north_n" => imgs.north_button_y,
122        "north_p" => imgs.north_button_ps_triangle,
123        "leftaxis" | "leftaxis_x" | "leftaxis_n" | "leftaxis_p" => imgs.left_axis,
124        "rightaxis" | "rightaxis_x" | "rightaxis_n" | "rightaxis_p" => imgs.right_axis,
125        "leftthumb" | "leftthumb_x" | "leftthumb_n" | "leftthumb_p" => imgs.left_axis_button,
126        "rightthumb" | "rightthumb_x" | "rightthumb_n" | "rightthumb_p" => imgs.right_axis_button,
127        // trigger is shoulder
128        "lefttrigger" | "lefttrigger_x" => imgs.left_shoulder_xbox_lb,
129        "lefttrigger_n" => imgs.left_shoulder_nin_l,
130        "lefttrigger_p" => imgs.left_shoulder_ps_l1,
131        "righttrigger" | "righttrigger_x" => imgs.right_shoulder_xbox_rb,
132        "righttrigger_n" => imgs.right_shoulder_nin_r,
133        "righttrigger_p" => imgs.right_shoulder_ps_r1,
134        // trigger2 is trigger
135        "lefttrigger2" | "lefttrigger2_x" => imgs.left_trigger_xbox_lt,
136        "lefttrigger2_n" => imgs.left_trigger_nin_zl,
137        "lefttrigger2_p" => imgs.left_trigger_ps_l2,
138        "righttrigger2" | "righttrigger2_x" => imgs.right_trigger_xbox_rt,
139        "righttrigger2_n" => imgs.right_trigger_nin_zr,
140        "righttrigger2_p" => imgs.right_trigger_ps_r2,
141        "dpaddown" | "dpaddown_x" | "dpaddown_n" => imgs.dpad_down,
142        "dpaddown_p" => imgs.dpad_down_ps,
143        "dpadleft" | "dpadleft_x" | "dpadleft_n" => imgs.dpad_left,
144        "dpadleft_p" => imgs.dpad_left_ps,
145        "dpadright" | "dpadright_x" | "dpadright_n" => imgs.dpad_right,
146        "dpadright_p" => imgs.dpad_right_ps,
147        "dpadup" | "dpadup_x" | "dpadup_n" => imgs.dpad_up,
148        "dpadup_p" => imgs.dpad_up_ps,
149        "start" | "start_x" => imgs.start_button_xbox,
150        "start_n" => imgs.start_button_nin,
151        "start_p" => imgs.start_button_ps,
152        "select" | "select_x" => imgs.select_button_xbox,
153        "select_n" => imgs.select_button_nin,
154        "select_p" => imgs.select_button_ps,
155        "mode" => imgs.start_button_xbox, // TODO: add `mode` button for xbox, nin, ps
156        // gilrs supports c and z buttons, so here they are (no custom icons though)
157        "c" => imgs.south_button_a,
158        "z" => imgs.east_button_b,
159        // Mouse
160        "middleclick" => imgs.m_click_ico,
161        _ => imgs.no_button,
162    }
163}