Work on card settings UI
This commit is contained in:
parent
235d3c3600
commit
e322c4084c
51
src/card.rs
51
src/card.rs
@ -1,36 +1,11 @@
|
||||
use anyhow::anyhow;
|
||||
use eframe::egui::Ui;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Config<'a> {
|
||||
#[serde(rename = "type")]
|
||||
typ: &'a str,
|
||||
#[serde(flatten)]
|
||||
settings: ron::Value,
|
||||
}
|
||||
|
||||
impl Config<'_> {
|
||||
pub fn to_card(&self) -> anyhow::Result<Box<dyn Card>> {
|
||||
inventory::iter::<Type>
|
||||
.into_iter()
|
||||
.find(|card_type| card_type.name == self.typ)
|
||||
.ok_or_else(|| anyhow!("Invalid card type {}", self.typ))?
|
||||
.new_card(self.settings.clone())
|
||||
}
|
||||
pub fn to_settings_ui(&self) -> anyhow::Result<Box<dyn SettingsUi>> {
|
||||
inventory::iter::<Type>
|
||||
.into_iter()
|
||||
.find(|card_type| card_type.name == self.typ)
|
||||
.ok_or_else(|| anyhow!("Invalid card type {}", self.typ))?
|
||||
.settings_ui(self.settings.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Type {
|
||||
name: &'static str,
|
||||
new: fn(settings: ron::Value) -> anyhow::Result<Box<dyn Card>>,
|
||||
settings_ui: fn(settings: ron::Value) -> anyhow::Result<Box<dyn SettingsUi>>,
|
||||
default_settings: fn() -> String,
|
||||
}
|
||||
|
||||
impl Type {
|
||||
@ -39,16 +14,32 @@ impl Type {
|
||||
name,
|
||||
new: T::new_dyn,
|
||||
settings_ui: T::settings_ui_dyn,
|
||||
default_settings: T::default_settings,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_card(&self, settings: ron::Value) -> anyhow::Result<Box<dyn Card>> {
|
||||
pub fn new_card(&self, settings: ron::Value) -> anyhow::Result<Box<dyn Card>> {
|
||||
(self.new)(settings)
|
||||
}
|
||||
|
||||
fn settings_ui(&self, settings: ron::Value) -> anyhow::Result<Box<dyn SettingsUi>> {
|
||||
pub fn settings_ui(&self, settings: ron::Value) -> anyhow::Result<Box<dyn SettingsUi>> {
|
||||
(self.settings_ui)(settings)
|
||||
}
|
||||
|
||||
pub fn default_settings(&self) -> String {
|
||||
(self.default_settings)()
|
||||
}
|
||||
|
||||
pub fn get(name: &str) -> anyhow::Result<&'static Self> {
|
||||
inventory::iter::<Type>
|
||||
.into_iter()
|
||||
.find(|card_type| card_type.name == name)
|
||||
.ok_or_else(|| anyhow!("Invalid card type {}", name))
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &'static str {
|
||||
self.name
|
||||
}
|
||||
}
|
||||
|
||||
inventory::collect!(Type);
|
||||
@ -66,6 +57,10 @@ pub trait Card {
|
||||
Ok(Box::new(card))
|
||||
}
|
||||
|
||||
fn default_settings() -> String
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn read_mem(&mut self, _address: u16) -> Option<u8> {
|
||||
None
|
||||
}
|
||||
|
@ -1,11 +1,23 @@
|
||||
use eframe::egui::{self, Slider};
|
||||
use eframe::{
|
||||
egui::{
|
||||
self, CentralPanel, DragValue, Layout, Margin, SidePanel, Slider, Style, TopBottomPanel,
|
||||
},
|
||||
emath::Align,
|
||||
};
|
||||
use egui_modal::Modal;
|
||||
|
||||
use crate::{state::EmuState, window::Window, Options};
|
||||
use crate::{
|
||||
card::{SettingsUi, Type},
|
||||
state::EmuState,
|
||||
window::Window,
|
||||
Options,
|
||||
};
|
||||
|
||||
pub struct OptionWindow {
|
||||
options: Options,
|
||||
category: OptionsCategory,
|
||||
card_options: Vec<(&'static str, Box<dyn SettingsUi>)>,
|
||||
select_idx: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
@ -17,9 +29,17 @@ enum OptionsCategory {
|
||||
impl OptionWindow {
|
||||
pub fn new(ctx: &egui::Context, state: &EmuState) -> Self {
|
||||
Modal::new(ctx, "options_modal").open();
|
||||
let ramcard_type = Type::get("RAM card").unwrap();
|
||||
let def_opts = ramcard_type.default_settings();
|
||||
let settings_ui = ramcard_type
|
||||
.settings_ui(ron::from_str(&def_opts).unwrap())
|
||||
.unwrap();
|
||||
let card_options = vec![(ramcard_type.name(), settings_ui)];
|
||||
Self {
|
||||
options: state.options(),
|
||||
category: OptionsCategory::General,
|
||||
card_options,
|
||||
select_idx: Some(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,12 +58,37 @@ impl Window for OptionWindow {
|
||||
ui.checkbox(&mut self.options.mute, "Mute");
|
||||
ui.checkbox(&mut self.options.fan_enabled, "Fan enabled");
|
||||
ui.add(Slider::new(&mut self.options.volume, 0.0..=100.0).text("Volume"));
|
||||
ui.separator();
|
||||
}
|
||||
OptionsCategory::Cards => {
|
||||
ui.heading("TODO");
|
||||
TopBottomPanel::top("card_opts").show_inside(ui, |ui| {
|
||||
SidePanel::left("card_opts_left")
|
||||
.show_separator_line(false)
|
||||
.show_inside(ui, |ui| {
|
||||
let frame =
|
||||
egui::Frame::canvas(&Style::default()).outer_margin(Margin {
|
||||
left: 0.0,
|
||||
right: 0.0,
|
||||
top: 0.0,
|
||||
bottom: 10.0,
|
||||
});
|
||||
frame.show(ui, |ui| {
|
||||
for (i, (name, _settings_ui)) in
|
||||
self.card_options.iter().enumerate()
|
||||
{
|
||||
ui.selectable_value(&mut self.select_idx, Some(i), *name);
|
||||
}
|
||||
});
|
||||
});
|
||||
CentralPanel::default().show_inside(ui, |ui| {
|
||||
if let Some(select_idx) = self.select_idx {
|
||||
self.card_options[select_idx].1.draw_ui(ui);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
modal.buttons(ui, |ui| {
|
||||
ui.with_layout(Layout::right_to_left(Align::Min), |ui| {
|
||||
if ui.button("Apply").clicked() {
|
||||
state.update_options(self.options);
|
||||
}
|
||||
|
13
src/ram.rs
13
src/ram.rs
@ -1,7 +1,10 @@
|
||||
use eframe::egui::{DragValue, Ui};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{card::{Card, SettingsUi}, register};
|
||||
use crate::{
|
||||
card::{Card, SettingsUi},
|
||||
register,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct RamCardSettings {
|
||||
@ -47,6 +50,14 @@ impl Card for RamCard {
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn default_settings() -> String {
|
||||
ron::to_string(&RamCardSettings {
|
||||
size: 4096,
|
||||
start_addr: 0,
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn settings_ui(settings: ron::Value) -> anyhow::Result<impl SettingsUi>
|
||||
where
|
||||
Self: Sized,
|
||||
|
Loading…
Reference in New Issue
Block a user