mirror of
https://github.com/gopher64/gopher64.git
synced 2026-09-23 12:56:24 +02:00
Slint fixes (#433)
* Slint fixes * more * more * more * more * more * more * more * more * more
This commit is contained in:
@@ -227,6 +227,7 @@ pub fn init(device: &mut device::Device) {
|
||||
device.cpu.clock_rate = if !device.cpu.overclock {
|
||||
93750000
|
||||
} else {
|
||||
println!("Overclocking enabled, setting clock rate to 125 MHz");
|
||||
125000000
|
||||
};
|
||||
|
||||
|
||||
+46
-14
@@ -108,7 +108,7 @@ fn local_game_window(app: &AppWindow, controller_paths: &[Option<String>]) {
|
||||
});
|
||||
}
|
||||
|
||||
fn get_input_profiles(config: &ui::config::Config) -> Vec<String> {
|
||||
fn input_profiles(config: &ui::config::Config) -> Vec<String> {
|
||||
let mut profiles = vec![];
|
||||
for key in config.input.input_profiles.keys() {
|
||||
profiles.push(key.clone())
|
||||
@@ -122,12 +122,33 @@ fn settings_window(app: &AppWindow, config: &ui::config::Config) {
|
||||
app.set_widescreen(config.video.widescreen);
|
||||
app.set_apply_crt_shader(config.video.crt);
|
||||
app.set_overclock_n64_cpu(config.emulation.overclock);
|
||||
app.set_resolution(format!("{}x", config.video.upscale).into());
|
||||
let combobox_value = match config.video.upscale {
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
4 => 2,
|
||||
_ => 0,
|
||||
};
|
||||
app.set_resolution(combobox_value);
|
||||
}
|
||||
|
||||
fn update_input_profiles(weak: &slint::Weak<AppWindow>, config: &ui::config::Config) {
|
||||
let profiles = get_input_profiles(config);
|
||||
let profiles = input_profiles(config);
|
||||
let config_bindings = config.input.input_profile_binding.clone();
|
||||
let weak2 = weak.clone();
|
||||
weak.upgrade_in_event_loop(move |handle| {
|
||||
let profile_bindings = slint::VecModel::default();
|
||||
for (i, input_profile_binding) in handle.get_selected_profile_binding().iter().enumerate() {
|
||||
let currently_selected = handle
|
||||
.get_input_profiles()
|
||||
.row_data(input_profile_binding as usize)
|
||||
.unwrap_or(config_bindings[i].clone().into())
|
||||
.to_string();
|
||||
let position = profiles
|
||||
.iter()
|
||||
.position(|profile| *profile == currently_selected);
|
||||
profile_bindings.push(position.unwrap() as i32);
|
||||
}
|
||||
|
||||
let input_profiles = slint::VecModel::default();
|
||||
for profile in profiles {
|
||||
input_profiles.push(profile.into());
|
||||
@@ -135,6 +156,20 @@ fn update_input_profiles(weak: &slint::Weak<AppWindow>, config: &ui::config::Con
|
||||
let input_profiles_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
|
||||
std::rc::Rc::new(input_profiles);
|
||||
handle.set_input_profiles(slint::ModelRc::from(input_profiles_model));
|
||||
|
||||
let input_profile_binding_model: std::rc::Rc<slint::VecModel<i32>> =
|
||||
std::rc::Rc::new(profile_bindings);
|
||||
handle.set_selected_profile_binding(slint::ModelRc::from(input_profile_binding_model));
|
||||
|
||||
// this is a workaround to make the input profile combobox update
|
||||
handle.set_blank_profiles(true);
|
||||
slint::Timer::single_shot(std::time::Duration::from_millis(200), move || {
|
||||
weak2
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
handle.set_blank_profiles(false);
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
@@ -156,14 +191,6 @@ fn controller_window(
|
||||
std::rc::Rc::new(slint::VecModel::from(config.input.transfer_pak.to_vec()));
|
||||
app.set_transferpak(slint::ModelRc::from(transferpak_enabled_model));
|
||||
|
||||
let profile_bindings = slint::VecModel::default();
|
||||
for binding in config.input.input_profile_binding.iter() {
|
||||
profile_bindings.push(binding.into());
|
||||
}
|
||||
let input_profile_binding_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
|
||||
std::rc::Rc::new(profile_bindings);
|
||||
app.set_input_profile_binding(slint::ModelRc::from(input_profile_binding_model));
|
||||
|
||||
update_input_profiles(&app.as_weak(), config);
|
||||
|
||||
let controllers = slint::VecModel::default();
|
||||
@@ -224,7 +251,8 @@ fn save_settings(app: &AppWindow, controller_paths: &[Option<String>]) {
|
||||
config.video.widescreen = app.get_widescreen();
|
||||
config.video.crt = app.get_apply_crt_shader();
|
||||
config.emulation.overclock = app.get_overclock_n64_cpu();
|
||||
config.video.upscale = app.get_resolution().trim_end_matches('x').parse().unwrap();
|
||||
let upscale_values = [1, 2, 4];
|
||||
config.video.upscale = upscale_values[app.get_resolution() as usize];
|
||||
|
||||
config.input.emulate_vru = app.get_emulate_vru();
|
||||
for (i, controller_enabled) in app.get_controller_enabled().iter().enumerate() {
|
||||
@@ -233,8 +261,12 @@ fn save_settings(app: &AppWindow, controller_paths: &[Option<String>]) {
|
||||
for (i, transferpak_enabled) in app.get_transferpak().iter().enumerate() {
|
||||
config.input.transfer_pak[i] = transferpak_enabled;
|
||||
}
|
||||
for (i, input_profile_binding) in app.get_input_profile_binding().iter().enumerate() {
|
||||
config.input.input_profile_binding[i] = input_profile_binding.into();
|
||||
for (i, input_profile_binding) in app.get_selected_profile_binding().iter().enumerate() {
|
||||
config.input.input_profile_binding[i] = app
|
||||
.get_input_profiles()
|
||||
.row_data(input_profile_binding as usize)
|
||||
.unwrap()
|
||||
.to_string();
|
||||
}
|
||||
|
||||
for (i, selected_controller) in app.get_selected_controller().iter().enumerate() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { LocalGame, ControllerConfig,Netplay,Settings,About } from "pages.slint";
|
||||
import { LocalGame, ControllerConfig, Netplay, Settings, About } from "pages.slint";
|
||||
import { SideBar } from "side_bar.slint";
|
||||
import { SettingsData } from "settings_page.slint";
|
||||
import { AboutData } from "about_page.slint";
|
||||
@@ -34,11 +34,12 @@ export component AppWindow inherits Window {
|
||||
in-out property emulate_vru <=> ControllerData.emulate_vru;
|
||||
in-out property controller_enabled <=> ControllerData.controller_enabled;
|
||||
in-out property transferpak <=> ControllerData.transferpak;
|
||||
in-out property input_profile_binding <=> ControllerData.input_profile_binding;
|
||||
in-out property selected_profile_binding <=> ControllerData.selected_profile_binding;
|
||||
in-out property input_profiles <=> ControllerData.input_profiles;
|
||||
in-out property controller_names <=> ControllerData.controller_names;
|
||||
in-out property selected_controller <=> ControllerData.selected_controller;
|
||||
in-out property game_running <=> State.game_running;
|
||||
in-out property blank_profiles <=> ControllerData.blank_profiles;
|
||||
preferred-width: 700px;
|
||||
preferred-height: 500px;
|
||||
title: @tr("Gopher64");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { CheckBox, ComboBox, Button, HorizontalBox, VerticalBox, GridBox } from "std-widgets.slint";
|
||||
import { CheckBox, ComboBox, Button, HorizontalBox, VerticalBox, GroupBox } from "std-widgets.slint";
|
||||
import { Page } from "page.slint";
|
||||
import { State } from "localgame_page.slint";
|
||||
|
||||
@@ -9,20 +9,14 @@ export global ControllerData {
|
||||
in-out property <bool> emulate_vru;
|
||||
in-out property <[bool]> controller_enabled;
|
||||
in-out property <[bool]> transferpak;
|
||||
in-out property <[string]> input_profile_binding;
|
||||
in-out property <[int]> selected_profile_binding: [-1, -1, -1, -1];
|
||||
in-out property <[string]> input_profiles;
|
||||
in-out property <[string]> controller_names;
|
||||
in-out property <[int]> selected_controller;
|
||||
in-out property <bool> blank_profiles;
|
||||
}
|
||||
|
||||
export component ControllerConfig inherits Page {
|
||||
property <[{name: string, vru-enabled: bool}]> rows: [
|
||||
{ name: "1", vru-enabled: false },
|
||||
{ name: "2", vru-enabled: false },
|
||||
{ name: "3", vru-enabled: false },
|
||||
{ name: "4", vru-enabled: true }
|
||||
];
|
||||
|
||||
callback input_profile_button_clicked;
|
||||
title: @tr("Controller Configuration");
|
||||
|
||||
@@ -41,213 +35,83 @@ export component ControllerConfig inherits Page {
|
||||
|
||||
Rectangle { }
|
||||
|
||||
Text {
|
||||
text: @tr("Controller Settings:");
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
GridBox {
|
||||
Row {
|
||||
Text {
|
||||
text: @tr("Port");
|
||||
}
|
||||
|
||||
Text {
|
||||
text: @tr("Enabled");
|
||||
}
|
||||
|
||||
Text {
|
||||
text: @tr("Emulate VRU");
|
||||
}
|
||||
|
||||
Text {
|
||||
text: @tr("Transfer Pak");
|
||||
}
|
||||
|
||||
Text {
|
||||
text: @tr("Profile");
|
||||
}
|
||||
|
||||
Text {
|
||||
text: @tr("Controller");
|
||||
}
|
||||
}
|
||||
|
||||
Row { // 0
|
||||
property <int> number: 0;
|
||||
Text { // Port
|
||||
text: rows[number].name;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
CheckBox { // Enabled
|
||||
checked: ControllerData.controller_enabled[number];
|
||||
toggled => {
|
||||
ControllerData.controller_enabled[number] = self.checked;
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox { // Emulate VRU
|
||||
enabled: rows[number].vru-enabled;
|
||||
checked: false;
|
||||
}
|
||||
|
||||
CheckBox { // Transfer Pak
|
||||
checked: ControllerData.transferpak[number];
|
||||
toggled => {
|
||||
ControllerData.transferpak[number] = self.checked;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Profile
|
||||
model: ControllerData.input_profiles;
|
||||
current-value: ControllerData.input_profile_binding[number];
|
||||
selected => {
|
||||
ControllerData.input_profile_binding[number] = self.current-value;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Controller
|
||||
model: ControllerData.controller_names;
|
||||
width: self.preferred-width;
|
||||
current-value: ControllerData.controller_names[ControllerData.selected_controller[number]];
|
||||
selected => {
|
||||
ControllerData.selected_controller[number] = self.current-index;
|
||||
HorizontalBox {
|
||||
GroupBox {
|
||||
title: @tr("Port");
|
||||
VerticalLayout {
|
||||
alignment: space-between;
|
||||
for player in [0, 1, 2, 3]: Text {
|
||||
text: player + 1;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row { // 1
|
||||
property <int> number: 1;
|
||||
Text { // Port
|
||||
text: rows[number].name;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
CheckBox { // Enabled
|
||||
checked: ControllerData.controller_enabled[number];
|
||||
toggled => {
|
||||
ControllerData.controller_enabled[number] = self.checked;
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox { // Emulate VRU
|
||||
enabled: rows[number].vru-enabled;
|
||||
checked: false;
|
||||
}
|
||||
|
||||
CheckBox { // Transfer Pak
|
||||
checked: ControllerData.transferpak[number];
|
||||
toggled => {
|
||||
ControllerData.transferpak[number] = self.checked;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Profile
|
||||
model: ControllerData.input_profiles;
|
||||
current-value: ControllerData.input_profile_binding[number];
|
||||
selected => {
|
||||
ControllerData.input_profile_binding[number] = self.current-value;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Controller
|
||||
model: ControllerData.controller_names;
|
||||
width: self.preferred-width;
|
||||
current-value: ControllerData.controller_names[ControllerData.selected_controller[number]];
|
||||
selected => {
|
||||
ControllerData.selected_controller[number] = self.current-index;
|
||||
GroupBox {
|
||||
title: @tr("Enabled");
|
||||
VerticalLayout {
|
||||
alignment: space-between;
|
||||
for player in [0, 1, 2, 3]: CheckBox {
|
||||
checked: ControllerData.controller_enabled[player];
|
||||
toggled => {
|
||||
ControllerData.controller_enabled[player] = self.checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row { // 2
|
||||
property <int> number: 2;
|
||||
Text { // Port
|
||||
text: rows[number].name;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
CheckBox { // Enabled
|
||||
checked: ControllerData.controller_enabled[number];
|
||||
toggled => {
|
||||
ControllerData.controller_enabled[number] = self.checked;
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox { // Emulate VRU
|
||||
enabled: rows[number].vru-enabled;
|
||||
checked: false;
|
||||
}
|
||||
|
||||
CheckBox { // Transfer Pak
|
||||
checked: ControllerData.transferpak[number];
|
||||
toggled => {
|
||||
ControllerData.transferpak[number] = self.checked;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Profile
|
||||
model: ControllerData.input_profiles;
|
||||
current-value: ControllerData.input_profile_binding[number];
|
||||
selected => {
|
||||
ControllerData.input_profile_binding[number] = self.current-value;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Controller
|
||||
model: ControllerData.controller_names;
|
||||
width: self.preferred-width;
|
||||
current-value: ControllerData.controller_names[ControllerData.selected_controller[number]];
|
||||
selected => {
|
||||
ControllerData.selected_controller[number] = self.current-index;
|
||||
GroupBox {
|
||||
title: @tr("Emulate VRU");
|
||||
VerticalLayout {
|
||||
alignment: space-between;
|
||||
for valid in [false, false, false, true]: CheckBox {
|
||||
enabled: valid;
|
||||
checked: valid && ControllerData.emulate_vru;
|
||||
toggled => {
|
||||
ControllerData.emulate_vru = self.checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row { // 3
|
||||
property <int> number: 3;
|
||||
Text { // Port
|
||||
text: rows[number].name;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
CheckBox { // Enabled
|
||||
checked: ControllerData.controller_enabled[number];
|
||||
toggled => {
|
||||
ControllerData.controller_enabled[number] = self.checked;
|
||||
GroupBox {
|
||||
title: @tr("Transfer Pak");
|
||||
VerticalLayout {
|
||||
alignment: space-between;
|
||||
for player in [0, 1, 2, 3]: CheckBox {
|
||||
checked: ControllerData.transferpak[player];
|
||||
toggled => {
|
||||
ControllerData.transferpak[player] = self.checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox { // Emulate VRU
|
||||
enabled: rows[number].vru-enabled;
|
||||
checked: ControllerData.emulate_vru;
|
||||
toggled => {
|
||||
ControllerData.emulate_vru = self.checked;
|
||||
if !ControllerData.blank_profiles: GroupBox {
|
||||
title: @tr("Profile");
|
||||
VerticalLayout {
|
||||
alignment: space-between;
|
||||
for player in [0, 1, 2, 3]: ComboBox {
|
||||
model: ControllerData.input_profiles;
|
||||
current-index: ControllerData.selected_profile_binding[player];
|
||||
selected => {
|
||||
ControllerData.selected_profile_binding[player] = self.current-index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox { // Transfer Pak
|
||||
checked: ControllerData.transferpak[number];
|
||||
toggled => {
|
||||
ControllerData.transferpak[number] = self.checked;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Profile
|
||||
model: ControllerData.input_profiles;
|
||||
current-value: ControllerData.input_profile_binding[number];
|
||||
selected => {
|
||||
ControllerData.input_profile_binding[number] = self.current-value;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // Controller
|
||||
model: ControllerData.controller_names;
|
||||
width: self.preferred-width;
|
||||
current-value: ControllerData.controller_names[ControllerData.selected_controller[number]];
|
||||
selected => {
|
||||
ControllerData.selected_controller[number] = self.current-index;
|
||||
GroupBox {
|
||||
title: @tr("Controller");
|
||||
VerticalLayout {
|
||||
alignment: space-between;
|
||||
for player in [0, 1, 2, 3]: ComboBox {
|
||||
model: ControllerData.controller_names;
|
||||
width: self.preferred-width;
|
||||
current-index: ControllerData.selected_controller[player];
|
||||
selected => {
|
||||
ControllerData.selected_controller[player] = self.current-index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ export component NetplayCreate inherits Window {
|
||||
HorizontalBox {
|
||||
server := ComboBox {
|
||||
model: NetplayData.server_names;
|
||||
selected(current-value) => {
|
||||
selected => {
|
||||
if (self.current-index >= 0) {
|
||||
get_ping(NetplayData.server_urls[self.current-index]);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ export component NetplayJoin inherits Window {
|
||||
HorizontalBox {
|
||||
server := ComboBox {
|
||||
model: NetplayData.server_names;
|
||||
selected(current-value) => {
|
||||
selected => {
|
||||
if (self.current-index >= 0) {
|
||||
get_ping(NetplayData.server_urls[self.current-index]);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export global SettingsData {
|
||||
in-out property <bool> widescreen;
|
||||
in-out property <bool> apply_crt_shader;
|
||||
in-out property <bool> overclock_n64_cpu;
|
||||
in-out property <string> resolution;
|
||||
in-out property <int> resolution;
|
||||
}
|
||||
|
||||
export component Settings inherits Page {
|
||||
@@ -27,9 +27,9 @@ export component Settings inherits Page {
|
||||
|
||||
ComboBox {
|
||||
model: ["1x", "2x", "4x"];
|
||||
current-value: SettingsData.resolution;
|
||||
current-index: SettingsData.resolution;
|
||||
selected => {
|
||||
SettingsData.resolution = self.current-value;
|
||||
SettingsData.resolution = self.current-index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ impl NetplayPages for NetplayJoin {
|
||||
}
|
||||
|
||||
fn populate_server_names<T: ComponentHandle + NetplayPages + 'static>(weak: slint::Weak<T>) {
|
||||
let task = reqwest::get("https://m64p.s3.amazonaws.com/servers.json");
|
||||
let task = reqwest::get("https://m64p.s3.amazonaws.com/serverstest.json");
|
||||
tokio::spawn(async move {
|
||||
let mut local_servers: Vec<(String, String)> = vec![];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user