Fix front panel not allocating size correctly

This commit is contained in:
pjht 2024-01-27 18:47:54 -06:00
parent a3b0bdbf7b
commit 9e0073df41
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
3 changed files with 76 additions and 75 deletions

View File

@ -1,7 +1,7 @@
use std::{path::Path, sync::mpsc::Sender}; use std::{path::Path, sync::mpsc::Sender};
use eframe::{ use eframe::{
egui::{self, Id, Painter, Sense, TextureOptions, Ui, Widget}, egui::{self, Id, Painter, Response, Sense, TextureOptions, Ui, Widget},
epaint::{pos2, vec2, Color32, Pos2, Rect, TextureHandle}, epaint::{pos2, vec2, Color32, Pos2, Rect, TextureHandle},
}; };
@ -55,87 +55,83 @@ impl Widget for Frontpanel<'_> {
); );
let led_textures = let led_textures =
led::Textures::new(self.textures.led_on.clone(), self.textures.led_off.clone()); led::Textures::new(self.textures.led_on.clone(), self.textures.led_off.clone());
let (resp, painter) = ui.allocate_painter( let resp = ui.allocate_response(
(800.0, 333.0).into(), vec2(800.0, 333.0),
Sense { Sense {
click: false, click: false,
drag: false, drag: false,
focusable: false, focusable: false,
}, },
); );
let fp_rect = painter.clip_rect(); let fp_rect = resp.rect;
painter.image( ui.allocate_ui_at_rect(fp_rect, |ui| {
self.textures.fp.id(), ui.image(&self.textures.fp);
painter.clip_rect(), for led in &LEDS {
NULL_UV, let pos = led.pos + fp_rect.left_top().to_vec2();
NULL_TINT, let led_data = 0xAAAA;
); let led_on = (led_data & led.mask) > 0;
let scale_vec = painter.clip_rect().size() / vec2(800.0, 333.0); ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(16.0, 16.0)), |ui| {
for led in &LEDS { ui.add(led::Led::new(led_on, &led_textures));
let pos = (led.pos.to_vec2() * scale_vec).to_pos2() + fp_rect.left_top().to_vec2();
let led_data = 0xAAAA;
let led_on = (led_data & led.mask) > 0;
ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(16.0, 16.0)), |ui| {
ui.add(led::Led::new(led_on, &led_textures));
});
}
// 0: Power
// 1..17: A/D left to right
// 17..25: Action left to right
for (i, switch) in SWITCHES.iter().enumerate() {
let pos = (switch.pos.to_vec2() * scale_vec).to_pos2() + fp_rect.left_top().to_vec2();
if i == 0 {
ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(11.0, 25.0)), |ui| {
let mut power_inv = !state.power;
if ui
.add(switch::ToggleSwitch::new(&mut power_inv, &sw_textures))
.drag_started()
{
if !power_inv {
self.audio_tx.send(AudioMessage::FanOn).unwrap();
} else {
self.audio_tx.send(AudioMessage::FanOff).unwrap();
}
self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap();
};
state.power = !power_inv;
}); });
} }
if (1..17).contains(&i) { // 0: Power
let bit_mask = 1 << (16 - i); // 1..17: A/D left to right
let mut sw_state = state.ad_sws & bit_mask > 0; // 17..25: Action left to right
ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(11.0, 25.0)), |ui| { for (i, switch) in SWITCHES.iter().enumerate() {
if ui let pos = switch.pos + fp_rect.left_top().to_vec2();
.add(switch::ToggleSwitch::new(&mut sw_state, &sw_textures)) if i == 0 {
.drag_started() ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(11.0, 25.0)), |ui| {
{ let mut power_inv = !state.power;
self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap(); if ui
.add(switch::ToggleSwitch::new(&mut power_inv, &sw_textures))
.drag_started()
{
if !power_inv {
self.audio_tx.send(AudioMessage::FanOn).unwrap();
} else {
self.audio_tx.send(AudioMessage::FanOff).unwrap();
}
self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap();
};
state.power = !power_inv;
});
}
if (1..17).contains(&i) {
let bit_mask = 1 << (16 - i);
let mut sw_state = state.ad_sws & bit_mask > 0;
ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(11.0, 25.0)), |ui| {
if ui
.add(switch::ToggleSwitch::new(&mut sw_state, &sw_textures))
.drag_started()
{
self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap();
};
});
state.ad_sws = (state.ad_sws & !(bit_mask)) | ((sw_state as u16) << (16 - i));
}
if (17..25).contains(&i) {
let state = match i {
17 => &mut state.runstop,
18 => &mut state.single_step,
19 => &mut state.exam,
20 => &mut state.dep,
21 => &mut state.reset,
22 => &mut state.prot,
23 => &mut state.aux1,
24 => &mut state.aux2,
_ => unreachable!(),
}; };
}); ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(11.0, 25.0)), |ui| {
state.ad_sws = (state.ad_sws & !(bit_mask)) | ((sw_state as u16) << (16 - i)); if ui
.add(switch::ThreePosSwitch::new(state, &sw_textures))
.drag_started()
{
self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap();
};
});
}
} }
if (17..25).contains(&i) { });
let state = match i {
17 => &mut state.runstop,
18 => &mut state.single_step,
19 => &mut state.exam,
20 => &mut state.dep,
21 => &mut state.reset,
22 => &mut state.prot,
23 => &mut state.aux1,
24 => &mut state.aux2,
_ => unreachable!(),
};
ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(11.0, 25.0)), |ui| {
if ui
.add(switch::ThreePosSwitch::new(state, &sw_textures))
.drag_started()
{
self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap();
};
});
}
}
ui.data_mut(|data| data.insert_temp(self.id, state)); ui.data_mut(|data| data.insert_temp(self.id, state));
resp resp
} }

View File

@ -64,7 +64,7 @@ impl<'a> ThreePosSwitch<'a> {
impl Widget for ThreePosSwitch<'_> { impl Widget for ThreePosSwitch<'_> {
fn ui(self, ui: &mut eframe::egui::Ui) -> eframe::egui::Response { fn ui(self, ui: &mut eframe::egui::Ui) -> eframe::egui::Response {
let (resp, painter) = ui.allocate_painter((11.0, 25.0).into(), Sense::drag()); let (mut resp, painter) = ui.allocate_painter((11.0, 25.0).into(), Sense::drag());
painter.image( painter.image(
self.textures.get_for_state(*self.state), self.textures.get_for_state(*self.state),
Rect::from_min_size(painter.clip_rect().left_top(), vec2(11.0, 25.0)), Rect::from_min_size(painter.clip_rect().left_top(), vec2(11.0, 25.0)),
@ -79,8 +79,10 @@ impl Widget for ThreePosSwitch<'_> {
} else { } else {
*self.state = SwitchState::Up; *self.state = SwitchState::Up;
}; };
resp.mark_changed();
} else if resp.drag_released() { } else if resp.drag_released() {
*self.state = SwitchState::Neut; *self.state = SwitchState::Neut;
resp.mark_changed();
} }
resp resp
} }
@ -99,7 +101,7 @@ impl<'a> ToggleSwitch<'a> {
impl Widget for ToggleSwitch<'_> { impl Widget for ToggleSwitch<'_> {
fn ui(self, ui: &mut eframe::egui::Ui) -> eframe::egui::Response { fn ui(self, ui: &mut eframe::egui::Ui) -> eframe::egui::Response {
let (resp, painter) = ui.allocate_painter((11.0, 25.0).into(), Sense::drag()); let (mut resp, painter) = ui.allocate_painter((11.0, 25.0).into(), Sense::drag());
painter.image( painter.image(
self.textures.get_for_bool(*self.state), self.textures.get_for_bool(*self.state),
Rect::from_min_size(painter.clip_rect().left_top(), vec2(11.0, 25.0)), Rect::from_min_size(painter.clip_rect().left_top(), vec2(11.0, 25.0)),
@ -108,6 +110,7 @@ impl Widget for ToggleSwitch<'_> {
); );
if resp.drag_started() { if resp.drag_started() {
*self.state = !*self.state; *self.state = !*self.state;
resp.mark_changed();
} }
resp resp
} }

View File

@ -226,7 +226,7 @@ impl eframe::App for AltairEmulator {
}); });
}); });
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.add(Label::new("Hello")); ui.style_mut().debug.debug_on_hover = true;
ui.add(Frontpanel::new( ui.add(Frontpanel::new(
Id::new("frontpanel"), Id::new("frontpanel"),
&self.textures, &self.textures,
@ -589,6 +589,8 @@ impl eframe::App for AltairEmulator {
// self.cpu.finish_m_cycle(data); // self.cpu.finish_m_cycle(data);
// self.update_fp(); // self.update_fp();
// } // }
//
ui.add(Label::new("Hello"));
}); });
// let old_fan_enabled = self.options.fan_enabled; // let old_fan_enabled = self.options.fan_enabled;