[go: up one dir, main page]

Selector

Struct Selector 

Source
pub struct Selector<T = ()>(/* private fields */);
Expand description

An identifier for a particular command.

This should be a unique string identifier. Having multiple selectors with the same identifier but different payload types is not allowed and can cause Command::get and get_unchecked to panic.

The type parameter T specifies the command’s payload type. See Command for more information.

Certain Selectors are defined by Druid, and have special meaning to the framework; these are listed in the druid::commands module.

Implementations§

Source§

impl Selector<()>

Source

pub const NOOP: Selector

A selector that does nothing.

Source

pub fn to(self, target: impl Into<Target>) -> Command

Turns this into a command with the specified Target.

Examples found in repository?
examples/multiwin.rs (line 60)
51fn ui_builder() -> impl Widget<State> {
52    let text = LocalizedString::new("hello-counter")
53        .with_arg("count", |data: &State, _env| data.menu_count.into());
54    let label = Label::new(text);
55    let inc_button =
56        Button::<State>::new("Add menu item").on_click(|_ctx, data, _env| data.menu_count += 1);
57    let dec_button = Button::<State>::new("Remove menu item")
58        .on_click(|_ctx, data, _env| data.menu_count = data.menu_count.saturating_sub(1));
59    let new_button = Button::<State>::new("New window").on_click(|ctx, _data, _env| {
60        ctx.submit_command(sys_cmds::NEW_FILE.to(Global));
61    });
62    let quit_button = Button::<State>::new("Quit app").on_click(|_ctx, _data, _env| {
63        Application::global().quit();
64    });
65
66    let mut col = Flex::column();
67    col.add_flex_child(Align::centered(Padding::new(5.0, label)), 1.0);
68    let mut row = Flex::row();
69    row.add_child(Padding::new(5.0, inc_button));
70    row.add_child(Padding::new(5.0, dec_button));
71    col.add_flex_child(Align::centered(row), 1.0);
72    let mut row = Flex::row();
73    row.add_child(Padding::new(5.0, new_button));
74    row.add_child(Padding::new(5.0, quit_button));
75    col.add_flex_child(Align::centered(row), 1.0);
76    let content = ControllerHost::new(col, ContextMenuController);
77    Glow::new(content)
78}
More examples
Hide additional examples
examples/identity.rs (line 88)
62fn make_ui() -> impl Widget<OurData> {
63    // We can also generate these dynamically whenever we need it.
64    let id_two = WidgetId::next();
65    // We have a column with 2 labels and 2 buttons.
66    // Each of the 2 labels only has access to its own counter and is given a `WidgetId`.
67    // Both labels have a controller, this handles commands send to children.
68    // The 2 buttons send a command when clicked. Both send the exact same command.
69    // The key diference is that they both give a different `WidgetId` as target.
70    // This means that only the corresponding controller gets the command, and increments their counter.
71    Flex::column()
72        .with_child(
73            Label::dynamic(|data, _| format!("One: {data}"))
74                .controller(LabelControler)
75                .with_id(ID_ONE)
76                .lens(OurData::counter_one)
77                .padding(2.0),
78        )
79        .with_child(
80            Label::dynamic(|data, _| format!("Two: {data}"))
81                .controller(LabelControler)
82                .with_id(id_two)
83                .lens(OurData::counter_two)
84                .padding(2.0),
85        )
86        .with_child(
87            Button::<OurData>::new("Increment one")
88                .on_click(|ctx, _data, _env| ctx.submit_command(INCREMENT.to(ID_ONE)))
89                .padding(2.0),
90        )
91        .with_child(
92            Button::<OurData>::new("Increment two")
93                .on_click(move |ctx, _data, _env| ctx.submit_command(INCREMENT.to(id_two)))
94                .padding(2.0),
95        )
96        .padding(10.0)
97}
examples/sub_window.rs (line 169)
99    fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
100        let wait_duration = Duration::from_millis(500);
101        let resched_dur = Duration::from_millis(50);
102        let cursor_size = Size::new(15., 15.);
103        let now = Instant::now();
104        let new_state = match &self.state {
105            TooltipState::Fresh => match event {
106                Event::MouseMove(me) if ctx.is_hot() => Some(TooltipState::Waiting {
107                    last_move: now,
108                    timer_expire: now + wait_duration,
109                    token: ctx.request_timer(wait_duration),
110                    position_in_window_coordinates: me.window_pos,
111                }),
112                _ => None,
113            },
114            TooltipState::Waiting {
115                last_move,
116                timer_expire,
117                token,
118                position_in_window_coordinates,
119            } => match event {
120                Event::MouseMove(me) if ctx.is_hot() => {
121                    let (cur_token, cur_expire) = if *timer_expire - now < resched_dur {
122                        (ctx.request_timer(wait_duration), now + wait_duration)
123                    } else {
124                        (*token, *timer_expire)
125                    };
126                    Some(TooltipState::Waiting {
127                        last_move: now,
128                        timer_expire: cur_expire,
129                        token: cur_token,
130                        position_in_window_coordinates: me.window_pos,
131                    })
132                }
133                Event::Timer(tok) if tok == token => {
134                    let deadline = *last_move + wait_duration;
135                    ctx.set_handled();
136                    if deadline > now {
137                        let wait_for = deadline - now;
138                        tracing::info!("Waiting another {:?}", wait_for);
139                        Some(TooltipState::Waiting {
140                            last_move: *last_move,
141                            timer_expire: deadline,
142                            token: ctx.request_timer(wait_for),
143                            position_in_window_coordinates: *position_in_window_coordinates,
144                        })
145                    } else {
146                        let tooltip_position_in_window_coordinates =
147                            (position_in_window_coordinates.to_vec2() + cursor_size.to_vec2())
148                                .to_point();
149                        let win_id = ctx.new_sub_window(
150                            WindowConfig::default()
151                                .show_titlebar(false)
152                                .window_size_policy(WindowSizePolicy::Content)
153                                .set_level(WindowLevel::Tooltip(ctx.window().clone()))
154                                .set_position(tooltip_position_in_window_coordinates),
155                            Label::<()>::new(self.tip.clone()),
156                            (),
157                            env.clone(),
158                        );
159                        Some(TooltipState::Showing(win_id))
160                    }
161                }
162                _ => None,
163            },
164            TooltipState::Showing(win_id) => {
165                match event {
166                    Event::MouseMove(me) if !ctx.is_hot() => {
167                        // TODO another timer on leaving
168                        tracing::info!("Sending close window for {:?}", win_id);
169                        ctx.submit_command(CLOSE_WINDOW.to(*win_id));
170                        Some(TooltipState::Waiting {
171                            last_move: now,
172                            timer_expire: now + wait_duration,
173                            token: ctx.request_timer(wait_duration),
174                            position_in_window_coordinates: me.window_pos,
175                        })
176                    }
177                    _ => None,
178                }
179            }
180        };
181
182        if let Some(state) = new_state {
183            self.state = state;
184        }
185
186        if !ctx.is_handled() {
187            child.event(ctx, event, data, env);
188        }
189    }
190
191    fn lifecycle(
192        &mut self,
193        child: &mut W,
194        ctx: &mut LifeCycleCtx,
195        event: &LifeCycle,
196        data: &T,
197        env: &Env,
198    ) {
199        if let LifeCycle::HotChanged(false) = event {
200            if let TooltipState::Showing(win_id) = self.state {
201                ctx.submit_command(CLOSE_WINDOW.to(win_id));
202            }
203            self.state = TooltipState::Fresh;
204        }
205        child.lifecycle(ctx, event, data, env)
206    }
Source§

impl<T> Selector<T>

Source

pub const fn new(s: &'static str) -> Selector<T>

Create a new Selector with the given string.

Examples found in repository?
examples/identity.rs (line 37)
37const INCREMENT: Selector = Selector::new("identity-example.increment");
More examples
Hide additional examples
examples/markdown_preview.rs (line 44)
44const OPEN_LINK: Selector<String> = Selector::new("druid-example.open-link");
examples/blocking_function.rs (line 31)
31const FINISH_SLOW_FUNCTION: Selector<u32> = Selector::new("finish_slow_function");
Source§

impl<T: Any> Selector<T>

Source

pub fn with(self, payload: T) -> Command

Convenience method for Command::new with this selector.

If the payload is () there is no need to call this, as Selector<()> implements Into<Command>.

By default, the command will have Target::Auto. The Selector::to method can be used to override this.

Examples found in repository?
examples/markdown_preview.rs (line 228)
196fn add_attribute_for_tag(tag: &Tag, mut attrs: AttributesAdder) {
197    match tag {
198        Tag::Heading(lvl) => {
199            let font_size = match lvl {
200                1 => 38.,
201                2 => 32.0,
202                3 => 26.0,
203                4 => 20.0,
204                5 => 16.0,
205                _ => 12.0,
206            };
207            attrs.size(font_size).weight(FontWeight::BOLD);
208        }
209        Tag::BlockQuote => {
210            attrs.style(FontStyle::Italic).text_color(BLOCKQUOTE_COLOR);
211        }
212        Tag::CodeBlock(_) => {
213            attrs.font_family(FontFamily::MONOSPACE);
214        }
215        Tag::Emphasis => {
216            attrs.style(FontStyle::Italic);
217        }
218        Tag::Strong => {
219            attrs.weight(FontWeight::BOLD);
220        }
221        Tag::Strikethrough => {
222            attrs.strikethrough(true);
223        }
224        Tag::Link(_link_ty, target, _title) => {
225            attrs
226                .underline(true)
227                .text_color(LINK_COLOR)
228                .link(OPEN_LINK.with(target.to_string()));
229        }
230        // ignore other tags for now
231        _ => (),
232    }
233}
More examples
Hide additional examples
examples/open_save.rs (line 62)
39fn ui_builder() -> impl Widget<String> {
40    let rs = FileSpec::new("Rust source", &["rs"]);
41    let txt = FileSpec::new("Text file", &["txt"]);
42    let other = FileSpec::new("Bogus file", &["foo", "bar", "baz"]);
43    // The options can also be generated at runtime,
44    // so to show that off we create a String for the default save name.
45    let default_save_name = String::from("MyFile.txt");
46    let save_dialog_options = FileDialogOptions::new()
47        .allowed_types(vec![rs, txt, other])
48        .default_type(txt)
49        .default_name(default_save_name)
50        .name_label("Target")
51        .title("Choose a target for this lovely file")
52        .button_text("Export");
53    let open_dialog_options = save_dialog_options
54        .clone()
55        .default_name("MySavedFile.txt")
56        .name_label("Source")
57        .title("Where did you put that file?")
58        .button_text("Import");
59
60    let input = TextBox::new();
61    let save = Button::new("Save").on_click(move |ctx, _, _| {
62        ctx.submit_command(druid::commands::SHOW_SAVE_PANEL.with(save_dialog_options.clone()))
63    });
64    let open = Button::new("Open").on_click(move |ctx, _, _| {
65        ctx.submit_command(druid::commands::SHOW_OPEN_PANEL.with(open_dialog_options.clone()))
66    });
67
68    let mut col = Flex::column();
69    col.add_child(input);
70    col.add_spacer(8.0);
71    col.add_child(save);
72    col.add_child(open);
73    Align::centered(col)
74}

Trait Implementations§

Source§

impl<T> Clone for Selector<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for Selector<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Display for Selector<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<Selector> for Command

Source§

fn from(selector: Selector) -> Command

Converts to this type from the input type.
Source§

impl<T: PartialEq> PartialEq for Selector<T>

Source§

fn eq(&self, other: &Selector<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T> Copy for Selector<T>

Source§

impl<T: Eq> Eq for Selector<T>

Source§

impl<T> StructuralPartialEq for Selector<T>

Auto Trait Implementations§

§

impl<T> Freeze for Selector<T>

§

impl<T> RefUnwindSafe for Selector<T>
where T: RefUnwindSafe,

§

impl<T> Send for Selector<T>
where T: Send,

§

impl<T> Sync for Selector<T>
where T: Sync,

§

impl<T> Unpin for Selector<T>
where T: Unpin,

§

impl<T> UnwindSafe for Selector<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AnyEq for T
where T: Any + PartialEq,

Source§

fn equals(&self, other: &(dyn Any + 'static)) -> bool

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> RoundFrom<T> for T

Source§

fn round_from(x: T) -> T

Performs the conversion.
Source§

impl<T, U> RoundInto<U> for T
where U: RoundFrom<T>,

Source§

fn round_into(self) -> U

Performs the conversion.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more