Implement color picker
This commit is contained in:
parent
761b434108
commit
1bac3dedab
|
@ -3,8 +3,9 @@ use crate::{
|
||||||
emulator::{EmulatorClient, EmulatorCommand, SimId},
|
emulator::{EmulatorClient, EmulatorCommand, SimId},
|
||||||
};
|
};
|
||||||
use egui::{
|
use egui::{
|
||||||
menu, Button, CentralPanel, Color32, Context, Frame, Response, Sense, TopBottomPanel, Ui, Vec2,
|
ecolor::HexColor, menu, Align2, Button, CentralPanel, Color32, Context, Frame, Layout,
|
||||||
ViewportBuilder, ViewportCommand, ViewportId, WidgetText,
|
Response, Sense, TopBottomPanel, Ui, Vec2, ViewportBuilder, ViewportCommand, ViewportId,
|
||||||
|
WidgetText, Window,
|
||||||
};
|
};
|
||||||
use winit::event_loop::EventLoopProxy;
|
use winit::event_loop::EventLoopProxy;
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ pub struct GameWindow {
|
||||||
display_mode: DisplayMode,
|
display_mode: DisplayMode,
|
||||||
colors: [Color32; 2],
|
colors: [Color32; 2],
|
||||||
screen: Option<GameScreen>,
|
screen: Option<GameScreen>,
|
||||||
|
color_picker: Option<ColorPickerState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameWindow {
|
impl GameWindow {
|
||||||
|
@ -46,6 +48,7 @@ impl GameWindow {
|
||||||
display_mode: DisplayMode::Anaglyph,
|
display_mode: DisplayMode::Anaglyph,
|
||||||
colors: COLOR_PRESETS[0],
|
colors: COLOR_PRESETS[0],
|
||||||
screen: None,
|
screen: None,
|
||||||
|
color_picker: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,8 +151,26 @@ impl GameWindow {
|
||||||
for preset in COLOR_PRESETS {
|
for preset in COLOR_PRESETS {
|
||||||
if ui.color_pair_button(preset[0], preset[1]).clicked() {
|
if ui.color_pair_button(preset[0], preset[1]).clicked() {
|
||||||
self.colors = preset;
|
self.colors = preset;
|
||||||
|
ui.close_menu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ui.with_layout(ui.layout().with_cross_align(egui::Align::Center), |ui| {
|
||||||
|
if ui.button("Custom").clicked() {
|
||||||
|
let color_str = |color: Color32| {
|
||||||
|
format!("{:02x}{:02x}{:02x}", color.r(), color.g(), color.b())
|
||||||
|
};
|
||||||
|
let is_running = self.client.is_running(self.sim_id);
|
||||||
|
if is_running {
|
||||||
|
self.client.send_command(EmulatorCommand::Pause);
|
||||||
|
}
|
||||||
|
self.color_picker = Some(ColorPickerState {
|
||||||
|
color_codes: [color_str(self.colors[0]), color_str(self.colors[1])],
|
||||||
|
just_opened: true,
|
||||||
|
unpause_on_close: is_running,
|
||||||
|
});
|
||||||
|
ui.close_menu();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
ui.menu_button("Audio", |ui| {
|
ui.menu_button("Audio", |ui| {
|
||||||
|
@ -195,6 +216,29 @@ impl GameWindow {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_color_picker(&mut self, ui: &mut Ui) {
|
||||||
|
let Some(state) = self.color_picker.as_mut() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let open = ui
|
||||||
|
.horizontal(|ui| {
|
||||||
|
let left_color = ui.color_picker(&mut self.colors[0], &mut state.color_codes[0]);
|
||||||
|
if state.just_opened {
|
||||||
|
left_color.request_focus();
|
||||||
|
state.just_opened = false;
|
||||||
|
}
|
||||||
|
let right_color = ui.color_picker(&mut self.colors[1], &mut state.color_codes[1]);
|
||||||
|
left_color.has_focus() || right_color.has_focus()
|
||||||
|
})
|
||||||
|
.inner;
|
||||||
|
if !open {
|
||||||
|
if state.unpause_on_close {
|
||||||
|
self.client.send_command(EmulatorCommand::Resume);
|
||||||
|
}
|
||||||
|
self.color_picker = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWindow for GameWindow {
|
impl AppWindow for GameWindow {
|
||||||
|
@ -220,6 +264,15 @@ impl AppWindow for GameWindow {
|
||||||
self.show_menu(ctx, ui);
|
self.show_menu(ctx, ui);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
if self.color_picker.is_some() {
|
||||||
|
Window::new("Color Picker")
|
||||||
|
.title_bar(false)
|
||||||
|
.resizable(false)
|
||||||
|
.anchor(Align2::CENTER_CENTER, Vec2::ZERO)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
self.show_color_picker(ui);
|
||||||
|
});
|
||||||
|
}
|
||||||
let frame = Frame::central_panel(&ctx.style()).fill(Color32::BLACK);
|
let frame = Frame::central_panel(&ctx.style()).fill(Color32::BLACK);
|
||||||
CentralPanel::default().frame(frame).show(ctx, |ui| {
|
CentralPanel::default().frame(frame).show(ctx, |ui| {
|
||||||
if let Some(screen) = self.screen.as_mut() {
|
if let Some(screen) = self.screen.as_mut() {
|
||||||
|
@ -259,6 +312,8 @@ trait UiExt {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_pair_button(&mut self, left: Color32, right: Color32) -> Response;
|
fn color_pair_button(&mut self, left: Color32, right: Color32) -> Response;
|
||||||
|
|
||||||
|
fn color_picker(&mut self, color: &mut Color32, hex: &mut String) -> Response;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UiExt for Ui {
|
impl UiExt for Ui {
|
||||||
|
@ -283,4 +338,29 @@ impl UiExt for Ui {
|
||||||
self.painter().rect_stroke(rect, 0.0, style.fg_stroke);
|
self.painter().rect_stroke(rect, 0.0, style.fg_stroke);
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn color_picker(&mut self, color: &mut Color32, hex: &mut String) -> Response {
|
||||||
|
self.allocate_ui_with_layout(
|
||||||
|
Vec2::new(100.0, 130.0),
|
||||||
|
Layout::top_down_justified(egui::Align::Center),
|
||||||
|
|ui| {
|
||||||
|
let (rect, _) = ui.allocate_at_least(Vec2::new(100.0, 100.0), Sense::hover());
|
||||||
|
ui.painter().rect_filled(rect, 0.0, *color);
|
||||||
|
let resp = ui.text_edit_singleline(hex);
|
||||||
|
if resp.changed() {
|
||||||
|
if let Ok(new_color) = HexColor::from_str_without_hash(hex) {
|
||||||
|
*color = new_color.color();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ColorPickerState {
|
||||||
|
color_codes: [String; 2],
|
||||||
|
just_opened: bool,
|
||||||
|
unpause_on_close: bool,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue