druid/text/
input_methods.rs

1// Copyright 2021 The Druid Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Types related to input method editing.
16//!
17//! Most IME-related code is in `druid-shell`; these are helper types used
18//! exclusively in `druid`.
19
20use std::rc::Rc;
21
22use crate::shell::text::InputHandler;
23use crate::WidgetId;
24
25/// A trait for input handlers registered by widgets.
26///
27/// A widget registers itself as accepting text input by calling
28/// [`LifeCycleCtx::register_text_input`] while handling the
29/// [`LifeCycle::WidgetAdded`] event.
30///
31/// The widget does not explicitly *deregister* afterwards; rather anytime
32/// the widget tree changes, `druid` will call [`is_alive`] on each registered
33/// `ImeHandlerRef`, and deregister those that return `false`.
34///
35/// [`LifeCycle::WidgetAdded`]: crate::LifeCycle::WidgetAdded
36/// [`LifeCycleCtx::register_text_input`]: crate::LifeCycleCtx::register_text_input
37/// [`is_alive`]: ImeHandlerRef::is_alive
38pub trait ImeHandlerRef {
39    /// Returns `true` if this handler is still active.
40    fn is_alive(&self) -> bool;
41    /// Mark the session as locked, and return a handle.
42    ///
43    /// The lock can be read-write or read-only, indicated by the `mutable` flag.
44    ///
45    /// if [`is_alive`] is `true`, this should always return `Some(_)`.
46    ///
47    /// [`is_alive`]: ImeHandlerRef::is_alive
48    fn acquire(&self, mutable: bool) -> Option<Box<dyn InputHandler + 'static>>;
49    /// Mark the session as released.
50    fn release(&self) -> bool;
51}
52
53/// A type we use to keep track of which widgets are responsible for which
54/// ime sessions.
55#[derive(Clone)]
56pub(crate) struct TextFieldRegistration {
57    pub widget_id: WidgetId,
58    pub document: Rc<dyn ImeHandlerRef>,
59}
60
61impl TextFieldRegistration {
62    pub fn is_alive(&self) -> bool {
63        self.document.is_alive()
64    }
65}
66
67impl std::fmt::Debug for TextFieldRegistration {
68    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
69        f.debug_struct("TextFieldRegistration")
70            .field("widget_id", &self.widget_id)
71            .field("is_alive", &self.document.is_alive())
72            .finish()
73    }
74}