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}