1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-27 20:34:03 +00:00

Add icons to the new menu (#482)

* Added test icons to layout,
toggle visibility of icon based on submenu_id

* disable icon container pane when menu is open

* Add icons to 'layout.arc'

* Add remaining icons to 'layout.arc'

* Apply suggestions from code review

Co-authored-by: jugeeya <jugeeya@live.com>

* Incorporate feedback, remove deltas from formatting differences

* Updated some icon textures, updated layout

* Swapped x for check icon on selected toggles

* Moved logic to collect submenu id's to app impl

---------

Co-authored-by: Matthew Edell <edell.matthew@gmail.com>
Co-authored-by: jugeeya <jugeeya@live.com>
This commit is contained in:
Austin Traver 2023-02-15 22:47:36 -08:00 committed by GitHub
parent b20a44ca5c
commit d128b902ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 33 deletions

View file

@ -33,6 +33,7 @@ training_mod_consts = { path = "training_mod_consts" }
training_mod_tui = { path = "training_mod_tui" }
native-tls = { version = "0.2.11", features = ["vendored"] }
log = "0.4.17"
byte-unit = "4.0.18"
[patch.crates-io]
native-tls = { git = "https://github.com/skyline-rs/rust-native-tls", rev = "f202fca" }

View file

@ -180,15 +180,6 @@ pub fn handle_get_npad_state(state: *mut NpadGcState, _controller_id: *const u32
let update_count = (*state).updateCount;
let flags = (*state).Flags;
if QUICK_MENU_ACTIVE {
// TODO: This should make more sense, look into.
// BUTTON_PRESSES.a.is_pressed = (*state).Buttons & (1 << 0) > 0;
// BUTTON_PRESSES.b.is_pressed = (*state).Buttons & (1 << 1) > 0;
// BUTTON_PRESSES.zl.is_pressed = (*state).Buttons & (1 << 8) > 0;
// BUTTON_PRESSES.zr.is_pressed = (*state).Buttons & (1 << 9) > 0;
// BUTTON_PRESSES.left.is_pressed = (*state).Buttons & ((1 << 12) | (1 << 16)) > 0;
// BUTTON_PRESSES.right.is_pressed = (*state).Buttons & ((1 << 14) | (1 << 18)) > 0;
// BUTTON_PRESSES.down.is_pressed = (*state).Buttons & ((1 << 15) | (1 << 19)) > 0;
// BUTTON_PRESSES.up.is_pressed = (*state).Buttons & ((1 << 13) | (1 << 17)) > 0;
if (*state).Buttons & (1 << 0) > 0 {
BUTTON_PRESSES.a.is_pressed = true;

Binary file not shown.

View file

@ -1,9 +1,9 @@
use std::collections::HashMap;
use lazy_static::lazy_static;
use skyline::nn::hid::GetNpadStyleSet;
use skyline::nn::ui2d::*;
use smash::ui2d::{SmashPane, SmashTextBox};
use std::collections::HashMap;
use training_mod_tui::gauge::GaugeState;
use training_mod_tui::{App, AppPage};
@ -69,6 +69,7 @@ lazy_static! {
unsafe fn render_submenu_page(app: &App, root_pane: &mut Pane) {
let tab_selected = app.tab_selected();
let tab = app.menu_items.get(tab_selected).unwrap();
let submenu_ids = app.submenu_ids();
(0..NUM_MENU_TEXT_OPTIONS)
// Valid options in this submenu
@ -78,42 +79,74 @@ unsafe fn render_submenu_page(app: &App, root_pane: &mut Pane) {
.find_pane_by_name_recursive(format!("TrModMenuButtonRow{list_idx}").as_str())
.unwrap();
menu_button_row.set_visible(true);
let menu_button = menu_button_row
.find_pane_by_name_recursive(format!("Button{list_section}").as_str())
.unwrap();
menu_button.set_visible(true);
let title_text = menu_button
.find_pane_by_name_recursive("TitleTxt")
.unwrap()
.as_textbox();
let title_bg = menu_button
.find_pane_by_name_recursive("TitleBg")
.unwrap()
.as_picture();
let title_bg_material = &mut *title_bg.material;
let list = &tab.lists[list_section];
let submenu = &list.items[list_idx];
let is_selected = list.state.selected().filter(|s| *s == list_idx).is_some();
title_text.set_text_string(submenu.submenu_title);
let title_bg_material = &mut *title_bg.material;
// In the actual 'layout.arc' file, every icon image is stacked
// into a single container pane, with each image directly on top of another.
// Hide all icon images, and strategically mark the icon that
// corresponds with a particular button to be visible.
submenu_ids.iter().for_each(|id| {
menu_button
.find_pane_by_name_recursive(id)
.unwrap()
.set_visible(id == &submenu.submenu_id);
});
menu_button
.find_pane_by_name_recursive("check")
.unwrap()
.set_visible(false);
if is_selected {
root_pane
.find_pane_by_name_recursive("FooterTxt")
.unwrap()
.as_textbox()
.set_text_string(submenu.help_text);
title_bg_material.set_white_res_color(BG_LEFT_ON_WHITE_COLOR);
title_bg_material.set_black_res_color(BG_LEFT_ON_BLACK_COLOR);
title_text.text_shadow_enable(true);
title_text.text_outline_enable(true);
title_text.set_color(255, 255, 255, 255);
} else {
title_bg_material.set_white_res_color(BG_LEFT_OFF_WHITE_COLOR);
title_bg_material.set_black_res_color(BG_LEFT_OFF_BLACK_COLOR);
title_text.text_shadow_enable(false);
title_text.text_outline_enable(false);
title_text.set_color(178, 199, 211, 255);
}
menu_button.set_visible(true);
menu_button
.find_pane_by_name_recursive("Icon")
.unwrap()
.set_visible(true);
});
}
@ -130,6 +163,7 @@ unsafe fn render_toggle_page(app: &App, root_pane: &mut Pane) {
.find_pane_by_name_recursive(format!("TrModMenuButtonRow{list_idx}").as_str())
.unwrap();
menu_button_row.set_visible(true);
let menu_button = menu_button_row
.find_pane_by_name_recursive(format!("Button{list_section}").as_str())
.unwrap();
@ -139,43 +173,52 @@ unsafe fn render_toggle_page(app: &App, root_pane: &mut Pane) {
.find_pane_by_name_recursive("TitleTxt")
.unwrap()
.as_textbox();
let title_bg = menu_button
.find_pane_by_name_recursive("TitleBg")
.unwrap()
.as_picture();
let value_text = menu_button
.find_pane_by_name_recursive("ValueTxt")
.unwrap()
.as_textbox();
let is_selected = sub_menu_state
.selected()
.filter(|s| *s == list_idx)
.is_some();
let submenu_ids = app.submenu_ids();
submenu_ids.iter().for_each(|id| {
menu_button
.find_pane_by_name_recursive(id)
.unwrap()
.set_visible(false)
});
title_text.set_text_string(name);
menu_button.find_pane_by_name_recursive("check")
.unwrap()
.set_visible(true);
menu_button.find_pane_by_name_recursive("Icon").unwrap().set_visible(*checked);
let title_bg_material = &mut *title_bg.material;
if is_selected {
title_text.text_shadow_enable(true);
title_text.text_outline_enable(true);
title_text.set_color(255, 255, 255, 255);
} else {
title_text.text_shadow_enable(false);
title_text.text_outline_enable(false);
title_text.set_color(178, 199, 211, 255);
}
let title_bg_material = &mut *title_bg.material;
if is_selected {
title_text.set_color(255, 255, 255, 255);
title_bg_material.set_white_res_color(BG_LEFT_ON_WHITE_COLOR);
title_bg_material.set_black_res_color(BG_LEFT_ON_BLACK_COLOR);
} else {
title_text.text_shadow_enable(false);
title_text.text_outline_enable(false);
title_text.set_color(178, 199, 211, 255);
title_bg_material.set_white_res_color(BG_LEFT_OFF_WHITE_COLOR);
title_bg_material.set_black_res_color(BG_LEFT_OFF_BLACK_COLOR);
}
if *checked {
value_text.set_text_string("X");
value_text.set_visible(true);
}
});
});
}
@ -282,6 +325,9 @@ unsafe fn render_slider_page(app: &App, root_pane: &mut Pane) {
max_title_bg_material.set_white_res_color(max_colors.0);
max_title_bg_material.set_black_res_color(max_colors.1);
min_value_text.set_visible(true);
max_value_text.set_visible(true);
}
pub unsafe fn draw(root_pane: &mut Pane) {
@ -326,6 +372,7 @@ pub unsafe fn draw(root_pane: &mut Pane) {
.find_pane_by_name_recursive(format!("TrModMenuButtonRow{row_idx}").as_str())
.unwrap();
menu_button_row.set_visible(false);
let menu_button = menu_button_row
.find_pane_by_name_recursive(format!("Button{col_idx}").as_str())
.unwrap();

View file

@ -1,3 +1,4 @@
use byte_unit::MEBIBYTE;
use sarc::SarcFile;
use skyline::nn::ui2d::*;
use training_mod_consts::{OnOff, MENU};
@ -33,10 +34,13 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
original!()(layout, draw_info, cmd_buffer);
}
// We'll keep some sane max size here; we shouldn't reach above 600KiB is the idea,
// but we can try higher if we need to.
// Allocate a static amount of memory that Smash isn't allowed to deallocate,
// in order for us to be able to swap the 'layout.arc' with the current
// version of the file in between loads of training mode.
#[cfg(feature = "layout_arc_from_file")]
static mut LAYOUT_ARC: &mut [u8; 600000] = &mut [0u8; 600000];
const LAYOUT_ARC_SIZE: usize = (2 * MEBIBYTE) as usize;
#[cfg(feature = "layout_arc_from_file")]
static mut LAYOUT_ARC: &mut [u8; LAYOUT_ARC_SIZE] = &mut [0u8; LAYOUT_ARC_SIZE];
/// We are editing the info_training/layout.arc and replacing the original file with our
/// modified version from `LAYOUT_ARC_PATH`

View file

@ -578,6 +578,23 @@ impl<'a> App<'a> {
defaults_menu: serde_json::from_str(self.default_menu.1.clone().as_str()).unwrap(),
}).unwrap()
}
pub fn submenu_ids(&self) -> Vec<&str> {
return self.menu_items
.values()
.flat_map(|multi_stateful_list| {
multi_stateful_list
.lists
.iter()
.flat_map(|sub_stateful_list| {
sub_stateful_list
.items
.iter()
.map(|submenu| submenu.submenu_id)
})
})
.collect::<Vec<&str>>();
}
}
fn render_submenu_page<B: Backend>(f: &mut Frame<B>, app: &mut App, list_chunks: Vec<Rect>, help_chunk: Rect) {