use zng_txt::Txt;
use zng_view_api::access::AccessCmd;
pub use zng_view_api::access::ScrollCmd;
use crate::{
event::{event, event_args},
widget::{WidgetId, info::WidgetPath},
window::{WINDOWS_APP, WindowId},
};
pub(super) fn on_access_init(window_id: WindowId) {
let args = AccessInitedArgs::now(window_id);
ACCESS_INITED_EVENT.notify(args)
}
pub(super) fn on_access_deinit(window_id: WindowId) {
let args = AccessDeinitedArgs::now(window_id);
ACCESS_DEINITED_EVENT.notify(args)
}
fn find_wgt(window_id: WindowId, widget_id: WidgetId) -> Option<WidgetPath> {
WINDOWS_APP.widget_tree(window_id)?.get(widget_id).map(|w| w.path())
}
pub(super) fn on_access_command(window_id: WindowId, widget_id: WidgetId, command: AccessCmd) {
let widget = match find_wgt(window_id, widget_id) {
Some(w) => w,
None => return,
};
match command {
AccessCmd::Click(primary) => {
let args = AccessClickArgs::now(widget, primary);
ACCESS_CLICK_EVENT.notify(args)
}
AccessCmd::Focus(focus) => {
let args = AccessFocusArgs::now(widget, focus);
ACCESS_FOCUS_EVENT.notify(args)
}
AccessCmd::FocusNavOrigin => {
let args = AccessFocusNavOriginArgs::now(widget);
ACCESS_FOCUS_NAV_ORIGIN_EVENT.notify(args)
}
AccessCmd::SetExpanded(expanded) => {
let args = AccessExpanderArgs::now(widget, expanded);
ACCESS_EXPANDER_EVENT.notify(args)
}
AccessCmd::Increment(inc) => {
let args = AccessIncrementArgs::now(widget, inc);
ACCESS_INCREMENT_EVENT.notify(args)
}
AccessCmd::SetToolTipVis(vis) => {
let args = AccessToolTipArgs::now(widget, vis);
ACCESS_TOOLTIP_EVENT.notify(args)
}
AccessCmd::ReplaceSelectedText(s) => {
let args = AccessTextArgs::now(widget, s, true);
ACCESS_TEXT_EVENT.notify(args)
}
AccessCmd::Scroll(s) => {
let args = AccessScrollArgs::now(widget, s);
ACCESS_SCROLL_EVENT.notify(args)
}
AccessCmd::SelectText {
start: (start_wgt, start_idx),
caret: (caret_wgt, caret_idx),
} => {
let start_wgt = match find_wgt(window_id, WidgetId::from_raw(start_wgt.0)) {
Some(w) => w,
None => return,
};
let caret_wgt = match find_wgt(window_id, WidgetId::from_raw(caret_wgt.0)) {
Some(w) => w,
None => return,
};
let args = AccessSelectionArgs::now((start_wgt, start_idx), (caret_wgt, caret_idx));
ACCESS_SELECTION_EVENT.notify(args)
}
AccessCmd::SetString(s) => {
let args = AccessTextArgs::now(widget, s, false);
ACCESS_TEXT_EVENT.notify(args)
}
AccessCmd::SetNumber(n) => {
let args = AccessNumberArgs::now(widget, n);
ACCESS_NUMBER_EVENT.notify(args)
}
a => {
tracing::warn!("access command `{a:?}` not implemented");
}
}
}
event_args! {
pub struct AccessInitedArgs {
pub window_id: WindowId,
..
fn is_in_target(&self, _id: WidgetId) -> bool {
true
}
}
pub struct AccessDeinitedArgs {
pub window_id: WindowId,
..
fn is_in_target(&self, _id: WidgetId) -> bool {
true
}
}
pub struct AccessClickArgs {
pub target: WidgetPath,
pub is_primary: bool,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessFocusArgs {
pub target: WidgetPath,
pub focus: bool,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessFocusNavOriginArgs {
pub target: WidgetPath,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessExpanderArgs {
pub target: WidgetPath,
pub expanded: bool,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessIncrementArgs {
pub target: WidgetPath,
pub delta: i32,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessToolTipArgs {
pub target: WidgetPath,
pub visible: bool,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessScrollArgs {
pub target: WidgetPath,
pub command: ScrollCmd,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessTextArgs {
pub target: WidgetPath,
pub txt: Txt,
pub selection_only: bool,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessNumberArgs {
pub target: WidgetPath,
pub num: f64,
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.target.contains(id)
}
}
pub struct AccessSelectionArgs {
pub start: (WidgetPath, usize),
pub caret: (WidgetPath, usize),
..
fn is_in_target(&self, id: WidgetId) -> bool {
self.start.0.contains(id) || self.caret.0.contains(id)
}
}
}
impl AccessClickArgs {
pub fn is_context(&self) -> bool {
!self.is_primary
}
}
event! {
pub static ACCESS_INITED_EVENT: AccessInitedArgs;
pub static ACCESS_DEINITED_EVENT: AccessDeinitedArgs;
pub static ACCESS_CLICK_EVENT: AccessClickArgs;
pub static ACCESS_FOCUS_EVENT: AccessFocusArgs;
pub static ACCESS_FOCUS_NAV_ORIGIN_EVENT: AccessFocusNavOriginArgs;
pub static ACCESS_EXPANDER_EVENT: AccessExpanderArgs;
pub static ACCESS_INCREMENT_EVENT: AccessIncrementArgs;
pub static ACCESS_TOOLTIP_EVENT: AccessToolTipArgs;
pub static ACCESS_SCROLL_EVENT: AccessScrollArgs;
pub static ACCESS_TEXT_EVENT: AccessTextArgs;
pub static ACCESS_NUMBER_EVENT: AccessNumberArgs;
pub static ACCESS_SELECTION_EVENT: AccessSelectionArgs;
}
pub struct ACCESS;
impl ACCESS {
pub fn click(&self, widget: WidgetPath, is_primary: bool) {
ACCESS_CLICK_EVENT.notify(AccessClickArgs::now(widget, is_primary));
}
pub fn show_tooltip(&self, widget: WidgetPath) {
ACCESS_TOOLTIP_EVENT.notify(AccessToolTipArgs::now(widget, true));
}
pub fn hide_tooltip(&self, widget: WidgetPath) {
ACCESS_TOOLTIP_EVENT.notify(AccessToolTipArgs::now(widget, false));
}
}