modal: refactoring to allow modification of global state from opened modal
This commit is contained in:
parent
11ac0ea84b
commit
df6fafd256
2 changed files with 39 additions and 37 deletions
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::RwLock;
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use egui::{Align2, Rect, RichText, Rounding, Stroke, Vec2};
|
use egui::{Align2, Rect, RichText, Rounding, Stroke, Vec2};
|
||||||
use egui::epaint::RectShape;
|
use egui::epaint::RectShape;
|
||||||
|
@ -25,19 +25,18 @@ use crate::gui::views::types::{ModalPosition, ModalState};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Showing [`Modal`] state to be accessible from different ui parts.
|
/// Showing [`Modal`] state to be accessible from different ui parts.
|
||||||
static ref MODAL_STATE: RwLock<ModalState> = RwLock::new(ModalState::default());
|
static ref MODAL_STATE: Arc<RwLock<ModalState>> = Arc::new(RwLock::new(ModalState::default()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores data to draw modal [`egui::Window`] at ui.
|
/// Stores data to draw modal [`egui::Window`] at ui.
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Modal {
|
pub struct Modal {
|
||||||
/// Identifier for modal.
|
/// Identifier for modal.
|
||||||
pub(crate) id: &'static str,
|
pub(crate) id: &'static str,
|
||||||
/// Position on the screen.
|
/// Position on the screen.
|
||||||
position: ModalPosition,
|
position: ModalPosition,
|
||||||
/// Flag to show the content.
|
|
||||||
open: AtomicBool,
|
|
||||||
/// To check if it can be closed.
|
/// To check if it can be closed.
|
||||||
closeable: AtomicBool,
|
closeable: Arc<AtomicBool>,
|
||||||
/// Title text
|
/// Title text
|
||||||
title: Option<String>
|
title: Option<String>
|
||||||
}
|
}
|
||||||
|
@ -48,13 +47,12 @@ impl Modal {
|
||||||
/// Maximum width of the content.
|
/// Maximum width of the content.
|
||||||
const DEFAULT_WIDTH: f32 = Root::SIDE_PANEL_WIDTH - (2.0 * Self::DEFAULT_MARGIN);
|
const DEFAULT_WIDTH: f32 = Root::SIDE_PANEL_WIDTH - (2.0 * Self::DEFAULT_MARGIN);
|
||||||
|
|
||||||
/// Create opened and closeable [`Modal`] with center position.
|
/// Create closeable [`Modal`] with center position.
|
||||||
pub fn new(id: &'static str) -> Self {
|
pub fn new(id: &'static str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
position: ModalPosition::Center,
|
position: ModalPosition::Center,
|
||||||
open: AtomicBool::new(true),
|
closeable: Arc::new(AtomicBool::new(true)),
|
||||||
closeable: AtomicBool::new(true),
|
|
||||||
title: None
|
title: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,14 +63,10 @@ impl Modal {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if [`Modal`] is open.
|
|
||||||
pub fn is_open(&self) -> bool {
|
|
||||||
self.open.load(Ordering::Relaxed)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mark [`Modal`] closed.
|
/// Mark [`Modal`] closed.
|
||||||
pub fn close(&self) {
|
pub fn close(&self) {
|
||||||
self.open.store(false, Ordering::Relaxed);
|
let mut w_nav = MODAL_STATE.write().unwrap();
|
||||||
|
w_nav.modal = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Setup possibility to close [`Modal`].
|
/// Setup possibility to close [`Modal`].
|
||||||
|
@ -119,37 +113,32 @@ impl Modal {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return id of opened [`Modal`] or remove its instance from [`ModalState`] if it was closed.
|
/// Return id of opened [`Modal`].
|
||||||
pub fn opened() -> Option<&'static str> {
|
pub fn opened() -> Option<&'static str> {
|
||||||
// Check if Modal is showing.
|
// Check if modal is showing.
|
||||||
{
|
{
|
||||||
if MODAL_STATE.read().unwrap().modal.is_none() {
|
if MODAL_STATE.read().unwrap().modal.is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if Modal is open.
|
// Get identifier of opened modal.
|
||||||
let (is_open, id) = {
|
let r_state = MODAL_STATE.read().unwrap();
|
||||||
let r_state = MODAL_STATE.read().unwrap();
|
let modal = r_state.modal.as_ref().unwrap();
|
||||||
let modal = r_state.modal.as_ref().unwrap();
|
Some(modal.id)
|
||||||
(modal.is_open(), modal.id)
|
|
||||||
};
|
|
||||||
|
|
||||||
// If Modal is not open, remove it from navigator state.
|
|
||||||
if !is_open {
|
|
||||||
let mut w_state = MODAL_STATE.write().unwrap();
|
|
||||||
w_state.modal = None;
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw opened [`Modal`] content.
|
/// Draw opened [`Modal`] content.
|
||||||
pub fn ui(ctx: &egui::Context, add_content: impl FnOnce(&mut egui::Ui, &Modal)) {
|
pub fn ui(ctx: &egui::Context, add_content: impl FnOnce(&mut egui::Ui, &Modal)) {
|
||||||
if let Some(modal) = &MODAL_STATE.read().unwrap().modal {
|
let has_modal = {
|
||||||
if modal.is_open() {
|
MODAL_STATE.read().unwrap().modal.is_some()
|
||||||
modal.window_ui(ctx, add_content);
|
};
|
||||||
}
|
if has_modal {
|
||||||
|
let modal = {
|
||||||
|
let r_state = MODAL_STATE.read().unwrap();
|
||||||
|
r_state.modal.clone().unwrap()
|
||||||
|
};
|
||||||
|
modal.window_ui(ctx, add_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ pub enum TitleContentType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Position of [`Modal`] on the screen.
|
/// Position of [`Modal`] on the screen.
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum ModalPosition {
|
pub enum ModalPosition {
|
||||||
CenterTop,
|
CenterTop,
|
||||||
Center
|
Center
|
||||||
|
@ -40,7 +41,8 @@ pub enum ModalPosition {
|
||||||
/// Global [`Modal`] state.
|
/// Global [`Modal`] state.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ModalState {
|
pub struct ModalState {
|
||||||
pub modal: Option<Modal>
|
/// Opened [`Modal`].
|
||||||
|
pub modal: Option<Modal>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains identifiers to draw opened [`Modal`] content for current ui container.
|
/// Contains identifiers to draw opened [`Modal`] content for current ui container.
|
||||||
|
@ -138,12 +140,23 @@ impl TextEditOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// QR code scanning state.
|
/// QR code scan result.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum QrScanResult {
|
||||||
|
/// Slatepack message.
|
||||||
|
Slatepack(String),
|
||||||
|
/// Slatepack address.
|
||||||
|
Address(String),
|
||||||
|
/// Parsed text.
|
||||||
|
Text(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// QR code scan state.
|
||||||
pub struct QrScanState {
|
pub struct QrScanState {
|
||||||
// Flag to check if image is processing to find QR code.
|
// Flag to check if image is processing to find QR code.
|
||||||
pub(crate) image_processing: bool,
|
pub(crate) image_processing: bool,
|
||||||
// Found QR code content.
|
// Found QR code content.
|
||||||
pub qr_scan_result: Option<String>
|
pub qr_scan_result: Option<QrScanResult>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for QrScanState {
|
impl Default for QrScanState {
|
||||||
|
|
Loading…
Reference in a new issue