<commit_before>//! User-input events and their effects.
//!
//! * Every user input the application receives is converted to an
//!   [`Event`](./enum.Event.html).
//! * Each event is then given to the root, and descends the view tree down to
//!   the view currently in focus, through the
//!   [`on_event`](../view/trait.View.html#method.on_event) method.
//!     * If the view consumes the event, it may return a callback to be
//!       executed.
//!     * Otherwise, it ignores the event, and the view parent can in turn
//!       choose to consume it or not.
//! * If no view consumes the event, the
//!   [global callback](../struct.Cursive.html#method.add_global_callback)
//!   table is checked.

use std::any::Any;
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;
use vec::Vec2;
use Cursive;

/// Callback is a function that can be triggered by an event.
/// It has a mutable access to the cursive root.
#[derive(Clone)]
pub struct Callback(Rc<Box<Fn(&mut Cursive)>>);
// TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible

/// A boxed callback that can be run on `&mut Any`.
pub type AnyCb<'a> = Box<FnMut(&mut Any) + 'a>;

/// A trigger that only selects some types of events.
pub struct EventTrigger(Box<Fn(&Event) -> bool>);

impl EventTrigger {
    /// Create a new `EventTrigger` using the given function as filter.
    pub fn from_fn<F>(f: F) -> Self
    where
        F: 'static + Fn(&Event) -> bool,
    {
        EventTrigger(Box::new(f))
    }

    /// Checks if this trigger applies to the given `Event`.
    pub fn apply(&self, event: &Event) -> bool {
        (self.0)(event)
    }

    /// Returns an `EventTrigger` that only accepts arrow keys.
    ///
    /// Only bare arrow keys without modifiers (Shift, Ctrl, Alt) will be accepted.
    pub fn arrows() -> Self {
        Self::from_fn(|e| match e {
            Event::Key(Key::Left)
            | Event::Key(Key::Down)
            | Event::Key(Key::Up)
            | Event::Key(Key::Right) => true,
            _ => false,
        })
    }

    /// Returns an `EventTrigger` that only accepts mouse events.
    pub fn mouse() -> Self {
        Self::from_fn(|e| match e {
            Event::Mouse { .. } => true,
            _ => false,
        })
    }

    /// Returns an `EventTrigger` that accepts any event.
    pub fn any() -> Self {
        Self::from_fn(|_| true)
    }

    /// Returns an `EventTrigger` that doesn't accept any event.
    pub fn none() -> Self {
        Self::from_fn(|_| true)
    }

    /// Returns an `EventTrigger` that applies if either `self` or `other` applies.<commit_msg>Fix EventTrigger::none<commit_after>//! User-input events and their effects.
//!
//! * Every user input the application receives is converted to an
//!   [`Event`](./enum.Event.html).
//! * Each event is then given to the root, and descends the view tree down to
//!   the view currently in focus, through the
//!   [`on_event`](../view/trait.View.html#method.on_event) method.
//!     * If the view consumes the event, it may return a callback to be
//!       executed.
//!     * Otherwise, it ignores the event, and the view parent can in turn
//!       choose to consume it or not.
//! * If no view consumes the event, the
//!   [global callback](../struct.Cursive.html#method.add_global_callback)
//!   table is checked.

use std::any::Any;
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;
use vec::Vec2;
use Cursive;

/// Callback is a function that can be triggered by an event.
/// It has a mutable access to the cursive root.
#[derive(Clone)]
pub struct Callback(Rc<Box<Fn(&mut Cursive)>>);
// TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible

/// A boxed callback that can be run on `&mut Any`.
pub type AnyCb<'a> = Box<FnMut(&mut Any) + 'a>;

/// A trigger that only selects some types of events.
pub struct EventTrigger(Box<Fn(&Event) -> bool>);

impl EventTrigger {
    /// Create a new `EventTrigger` using the given function as filter.
    pub fn from_fn<F>(f: F) -> Self
    where
        F: 'static + Fn(&Event) -> bool,
    {
        EventTrigger(Box::new(f))
    }

    /// Checks if this trigger applies to the given `Event`.
    pub fn apply(&self, event: &Event) -> bool {
        (self.0)(event)
    }

    /// Returns an `EventTrigger` that only accepts arrow keys.
    ///
    /// Only bare arrow keys without modifiers (Shift, Ctrl, Alt) will be accepted.
    pub fn arrows() -> Self {
        Self::from_fn(|e| match e {
            Event::Key(Key::Left)
            | Event::Key(Key::Down)
            | Event::Key(Key::Up)
            | Event::Key(Key::Right) => true,
            _ => false,
        })
    }

    /// Returns an `EventTrigger` that only accepts mouse events.
    pub fn mouse() -> Self {
        Self::from_fn(|e| match e {
            Event::Mouse { .. } => true,
            _ => false,
        })
    }

    /// Returns an `EventTrigger` that accepts any event.
    pub fn any() -> Self {
        Self::from_fn(|_| true)
    }

    /// Returns an `EventTrigger` that doesn't accept any event.
    pub fn none() -> Self {
        Self::from_fn(|_| false)
    }

    /// Returns an `EventTrigger` that applies if either `self` or `other` applies.
{'fraction_non_alphanumeric': 0.14695752009184845, 'fraction_numerical': 0.0007654037504783774, 'mean_word_length': 2.4029947916666665, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3982360', 'n_tokens_mistral': 1638, 'n_tokens_neox': 1599, 'n_words': 578}