2020-08-07 00:07:32 +08:00
|
|
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
2022-06-14 01:58:49 +08:00
|
|
|
use zero_ui::core::focus::{FocusChangedEvent, FocusRequest, FocusTarget};
|
2020-08-27 11:51:40 +08:00
|
|
|
use zero_ui::prelude::*;
|
2022-02-01 03:18:23 +08:00
|
|
|
use zero_ui::widgets::window::{LayerIndex, WindowLayers};
|
2020-07-22 12:16:15 +08:00
|
|
|
|
2022-06-13 10:10:21 +08:00
|
|
|
use zero_ui_view_prebuilt as zero_ui_view;
|
2021-11-07 12:15:13 +08:00
|
|
|
|
2020-07-22 12:16:15 +08:00
|
|
|
fn main() {
|
2022-06-13 06:04:09 +08:00
|
|
|
examples_util::print_info();
|
2021-09-29 01:52:56 +08:00
|
|
|
zero_ui_view::init();
|
2021-12-26 12:47:49 +08:00
|
|
|
|
2022-07-27 23:46:40 +08:00
|
|
|
// let rec = examples_util::record_profile("focus");
|
2022-06-03 02:48:47 +08:00
|
|
|
|
2022-06-13 10:10:21 +08:00
|
|
|
// zero_ui_view::run_same_process(app_main);
|
|
|
|
app_main();
|
2022-06-03 02:48:47 +08:00
|
|
|
|
2022-06-13 06:04:09 +08:00
|
|
|
// rec.finish();
|
2021-10-12 09:27:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn app_main() {
|
2021-05-15 04:39:50 +08:00
|
|
|
App::default().run_window(|ctx| {
|
2022-06-13 06:04:09 +08:00
|
|
|
ctx.window_id.set_name("main").unwrap();
|
|
|
|
|
2021-05-15 04:39:50 +08:00
|
|
|
trace_focus(ctx.events);
|
2022-01-30 00:07:50 +08:00
|
|
|
let window_enabled = var(true);
|
2020-07-22 12:16:15 +08:00
|
|
|
window! {
|
2021-03-12 03:40:31 +08:00
|
|
|
title = "Focus Example";
|
2022-01-30 00:07:50 +08:00
|
|
|
enabled = window_enabled.clone();
|
2022-06-20 11:08:38 +08:00
|
|
|
background = commands();
|
2021-03-12 03:40:31 +08:00
|
|
|
content = v_stack! {
|
2021-03-31 06:49:36 +08:00
|
|
|
items = widgets![
|
2020-09-10 02:44:15 +08:00
|
|
|
alt_scope(),
|
2021-05-14 12:12:14 +08:00
|
|
|
h_stack! {
|
|
|
|
margin = (50, 0, 0, 0);
|
2022-02-15 03:19:44 +08:00
|
|
|
align = Align::CENTER;
|
2021-05-14 12:12:14 +08:00
|
|
|
spacing = 10;
|
|
|
|
items = widgets![
|
2021-05-17 02:24:30 +08:00
|
|
|
tab_index(),
|
2022-06-14 01:58:49 +08:00
|
|
|
functions(window_enabled),
|
|
|
|
delayed_focus(),
|
2021-05-14 12:12:14 +08:00
|
|
|
]
|
|
|
|
}
|
2021-03-31 06:49:36 +08:00
|
|
|
];
|
2020-07-22 12:16:15 +08:00
|
|
|
};
|
2022-07-03 09:39:44 +08:00
|
|
|
// zero_ui::properties::inspector::show_center_points = true;
|
|
|
|
// zero_ui::properties::inspector::show_bounds = true;
|
2022-07-24 03:47:36 +08:00
|
|
|
// zero_ui::properties::inspector::show_hit_test = true;
|
2022-07-06 10:11:20 +08:00
|
|
|
// zero_ui::properties::inspector::show_directional_query = Some(zero_ui::core::units::Orientation2D::Below);
|
2020-07-22 12:16:15 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-09-10 02:44:15 +08:00
|
|
|
fn alt_scope() -> impl Widget {
|
|
|
|
h_stack! {
|
2021-03-12 03:40:31 +08:00
|
|
|
alt_focus_scope = true;
|
2022-09-16 11:18:17 +08:00
|
|
|
button::vis::replace_theme = theme_generator!(|_, _| button::vis::default_theme! {
|
|
|
|
border = unset!;
|
|
|
|
corner_radius = unset!;
|
2022-08-15 09:12:20 +08:00
|
|
|
});
|
2021-03-31 06:49:36 +08:00
|
|
|
items = widgets![
|
2020-09-10 02:44:15 +08:00
|
|
|
button("alt", TabIndex::AUTO),
|
|
|
|
button("scope", TabIndex::AUTO),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-17 02:24:30 +08:00
|
|
|
fn tab_index() -> impl Widget {
|
2020-09-10 02:44:15 +08:00
|
|
|
v_stack! {
|
2021-03-12 03:40:31 +08:00
|
|
|
spacing = 5;
|
2021-05-18 02:14:52 +08:00
|
|
|
focus_shortcut = shortcut!(T);
|
2021-03-31 06:49:36 +08:00
|
|
|
items = widgets![
|
2021-05-14 12:12:14 +08:00
|
|
|
title("TabIndex (T)"),
|
2021-05-20 03:35:57 +08:00
|
|
|
button("Button A5", 5),
|
|
|
|
button("Button A4", 3),
|
|
|
|
button("Button A3", 2),
|
|
|
|
button("Button A1", 0),
|
|
|
|
button("Button A2", 0),
|
2021-03-31 06:49:36 +08:00
|
|
|
];
|
2020-09-10 02:44:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-30 00:07:50 +08:00
|
|
|
fn functions(window_enabled: RcVar<bool>) -> impl Widget {
|
2021-05-14 12:12:14 +08:00
|
|
|
v_stack! {
|
|
|
|
spacing = 5;
|
2021-05-17 02:24:30 +08:00
|
|
|
focus_shortcut = shortcut!(F);
|
2021-05-14 12:12:14 +08:00
|
|
|
items = widgets![
|
|
|
|
title("Functions (F)"),
|
2022-01-30 00:07:50 +08:00
|
|
|
// New Window
|
2021-05-14 12:12:14 +08:00
|
|
|
button! {
|
|
|
|
content = text("New Window");
|
2021-06-22 10:00:40 +08:00
|
|
|
on_click = hn!(|ctx, _| {
|
2022-07-30 02:22:05 +08:00
|
|
|
Windows::req(ctx.services).open(|ctx| {
|
2022-06-19 05:13:53 +08:00
|
|
|
let _ = ctx.window_id.set_name("other");
|
2022-06-13 06:04:09 +08:00
|
|
|
window! {
|
|
|
|
title = "Other Window";
|
|
|
|
focus_shortcut = shortcut!(W);
|
|
|
|
content = v_stack! {
|
|
|
|
align = Align::CENTER;
|
|
|
|
spacing = 5;
|
|
|
|
items = widgets![
|
|
|
|
title("Other Window (W)"),
|
|
|
|
button("Button B5", 5),
|
|
|
|
button("Button B4", 3),
|
|
|
|
button("Button B3", 2),
|
|
|
|
button("Button B1", 0),
|
|
|
|
button("Button B2", 0),
|
|
|
|
]
|
|
|
|
};
|
|
|
|
}
|
2021-07-31 11:37:04 +08:00
|
|
|
});
|
2021-06-22 10:00:40 +08:00
|
|
|
});
|
2021-05-18 07:19:01 +08:00
|
|
|
},
|
2022-01-30 00:07:50 +08:00
|
|
|
// Detach Button
|
2021-05-18 02:14:52 +08:00
|
|
|
{
|
2021-05-16 02:31:55 +08:00
|
|
|
let detach_focused = RcNode::new_cyclic(|wk| {
|
2021-05-21 00:01:07 +08:00
|
|
|
let btn = button! {
|
2021-05-16 02:31:55 +08:00
|
|
|
content = text("Detach Button");
|
2022-09-07 05:25:30 +08:00
|
|
|
// focus_on_init = true;
|
2021-06-22 10:00:40 +08:00
|
|
|
on_click = hn!(|ctx, _| {
|
2021-05-16 02:31:55 +08:00
|
|
|
let wwk = wk.clone();
|
2022-07-30 02:22:05 +08:00
|
|
|
Windows::req(ctx.services).open(move |_| {
|
2021-05-16 02:31:55 +08:00
|
|
|
window! {
|
|
|
|
title = "Detached Button";
|
2022-05-21 05:41:56 +08:00
|
|
|
content_align = Align::CENTER;
|
2022-06-05 10:06:22 +08:00
|
|
|
content = slot(wwk.upgrade().unwrap(), slot::take_on_init());
|
2021-05-16 02:31:55 +08:00
|
|
|
}
|
2021-07-31 11:37:04 +08:00
|
|
|
});
|
2021-06-22 10:00:40 +08:00
|
|
|
});
|
2021-05-21 00:01:07 +08:00
|
|
|
};
|
|
|
|
btn.boxed()
|
2021-05-15 09:45:49 +08:00
|
|
|
});
|
2022-06-05 10:06:22 +08:00
|
|
|
slot(detach_focused, slot::take_on_init())
|
2022-01-30 00:07:50 +08:00
|
|
|
},
|
2022-02-02 03:56:09 +08:00
|
|
|
// Disable Window
|
|
|
|
disable_window(window_enabled.clone()),
|
2022-02-01 12:18:58 +08:00
|
|
|
// Overlay Scope
|
2022-01-30 00:07:50 +08:00
|
|
|
button! {
|
2022-01-30 12:37:07 +08:00
|
|
|
content = text("Overlay Scope");
|
2022-01-30 00:07:50 +08:00
|
|
|
on_click = hn!(|ctx, _| {
|
2022-02-02 03:56:09 +08:00
|
|
|
WindowLayers::insert(ctx, LayerIndex::TOP_MOST, overlay(window_enabled.clone()));
|
2022-01-30 00:07:50 +08:00
|
|
|
});
|
2022-06-14 01:58:49 +08:00
|
|
|
},
|
2022-06-22 05:58:53 +08:00
|
|
|
nested_focusables(),
|
2021-05-14 12:12:14 +08:00
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
2022-02-02 03:56:09 +08:00
|
|
|
fn disable_window(window_enabled: RcVar<bool>) -> impl Widget {
|
|
|
|
button! {
|
|
|
|
content = text(window_enabled.map(|&e| if e { "Disable Window" } else { "Enabling in 1s..." }.into()));
|
2022-06-22 05:58:53 +08:00
|
|
|
min_width = 140;
|
2022-02-02 03:56:09 +08:00
|
|
|
on_click = async_hn!(window_enabled, |ctx, _| {
|
|
|
|
window_enabled.set(&ctx, false);
|
2022-08-09 04:50:47 +08:00
|
|
|
task::deadline(1.secs()).await;
|
2022-02-02 03:56:09 +08:00
|
|
|
window_enabled.set(&ctx, true);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn overlay(window_enabled: RcVar<bool>) -> impl Widget {
|
2022-01-30 00:07:50 +08:00
|
|
|
container! {
|
|
|
|
id = "overlay";
|
2022-02-01 10:31:20 +08:00
|
|
|
modal = true;
|
2022-05-24 09:57:04 +08:00
|
|
|
content_align = Align::CENTER;
|
2022-01-30 00:07:50 +08:00
|
|
|
content = container! {
|
|
|
|
focus_scope = true;
|
2022-02-02 11:24:25 +08:00
|
|
|
tab_nav = TabNav::Cycle;
|
|
|
|
directional_nav = DirectionalNav::Cycle;
|
2022-02-04 03:22:44 +08:00
|
|
|
background_color = rgb(0.05, 0.05, 0.05);
|
2022-02-01 12:18:58 +08:00
|
|
|
drop_shadow = (0, 0), 4, colors::BLACK;
|
2022-01-30 00:07:50 +08:00
|
|
|
padding = 2;
|
|
|
|
content = v_stack! {
|
2022-02-15 03:19:44 +08:00
|
|
|
items_align = Align::RIGHT;
|
2022-01-30 00:07:50 +08:00
|
|
|
items = widgets![
|
|
|
|
text! {
|
|
|
|
text = "Window scope is disabled so the overlay scope is the root scope.";
|
|
|
|
margin = 15;
|
|
|
|
},
|
2022-02-02 03:56:09 +08:00
|
|
|
h_stack! {
|
|
|
|
spacing = 2;
|
|
|
|
items = widgets![
|
|
|
|
disable_window(window_enabled),
|
|
|
|
button! {
|
|
|
|
content = text("Close");
|
|
|
|
on_click = hn!(|ctx, _| {
|
|
|
|
WindowLayers::remove(ctx, "overlay");
|
|
|
|
})
|
|
|
|
}
|
|
|
|
]
|
2022-01-30 00:07:50 +08:00
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-05-14 12:12:14 +08:00
|
|
|
|
2022-06-14 01:58:49 +08:00
|
|
|
fn delayed_focus() -> impl Widget {
|
|
|
|
v_stack! {
|
|
|
|
spacing = 5;
|
|
|
|
focus_shortcut = shortcut!(D);
|
|
|
|
items = widgets![
|
|
|
|
title("Delayed 4s (D)"),
|
|
|
|
|
|
|
|
delayed_btn("Force Focus", |ctx| {
|
2022-07-30 02:22:05 +08:00
|
|
|
Focus::req(ctx.services).focus(FocusRequest {
|
2022-06-14 01:58:49 +08:00
|
|
|
target: FocusTarget::Direct(WidgetId::named("target")),
|
|
|
|
highlight: true,
|
|
|
|
force_window_focus: true,
|
|
|
|
window_indicator: None,
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
delayed_btn("Info Indicator", |ctx| {
|
2022-07-30 02:22:05 +08:00
|
|
|
Focus::req(ctx.services).focus(FocusRequest {
|
2022-06-14 01:58:49 +08:00
|
|
|
target: FocusTarget::Direct(WidgetId::named("target")),
|
|
|
|
highlight: true,
|
|
|
|
force_window_focus: false,
|
|
|
|
window_indicator: Some(FocusIndicator::Info),
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
delayed_btn("Critical Indicator", |ctx| {
|
2022-07-30 02:22:05 +08:00
|
|
|
Focus::req(ctx.services).focus(FocusRequest {
|
2022-06-14 01:58:49 +08:00
|
|
|
target: FocusTarget::Direct(WidgetId::named("target")),
|
|
|
|
highlight: true,
|
|
|
|
force_window_focus: false,
|
|
|
|
window_indicator: Some(FocusIndicator::Critical),
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
|
|
|
|
text! {
|
|
|
|
id = "target";
|
2022-08-15 09:12:20 +08:00
|
|
|
padding = (7, 15);
|
|
|
|
corner_radius = 4;
|
2022-06-14 01:58:49 +08:00
|
|
|
text = "delayed target";
|
|
|
|
font_style = FontStyle::Italic;
|
2022-06-14 04:35:00 +08:00
|
|
|
text_align = TextAlign::CENTER_MIDDLE;
|
2022-06-14 01:58:49 +08:00
|
|
|
background_color = rgb(30, 30, 30);
|
|
|
|
|
|
|
|
focusable = true;
|
|
|
|
when self.is_focused {
|
|
|
|
text = "focused";
|
|
|
|
background_color = colors::DARK_GREEN;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn delayed_btn(content: impl Into<Text>, on_timeout: impl FnMut(&mut WidgetContext) + 'static) -> impl Widget {
|
|
|
|
let on_timeout = std::rc::Rc::new(std::cell::RefCell::new(Box::new(on_timeout)));
|
|
|
|
let enabled = var(true);
|
|
|
|
button! {
|
|
|
|
content = text(content.into());
|
|
|
|
on_click = async_hn!(enabled, on_timeout, |ctx, _| {
|
|
|
|
enabled.set(&ctx, false);
|
2022-08-09 04:50:47 +08:00
|
|
|
task::deadline(4.secs()).await;
|
2022-06-14 01:58:49 +08:00
|
|
|
ctx.with(|ctx| {
|
|
|
|
let mut on_timeout = on_timeout.borrow_mut();
|
|
|
|
on_timeout(ctx);
|
|
|
|
});
|
|
|
|
enabled.set(&ctx, true);
|
|
|
|
});
|
|
|
|
enabled;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-14 12:12:14 +08:00
|
|
|
fn title(text: impl IntoVar<Text>) -> impl Widget {
|
2022-02-15 03:19:44 +08:00
|
|
|
text! { text; font_weight = FontWeight::BOLD; align = Align::CENTER; }
|
2021-05-14 12:12:14 +08:00
|
|
|
}
|
|
|
|
|
2021-05-20 03:35:57 +08:00
|
|
|
fn button(content: impl Into<Text>, tab_index: impl Into<TabIndex>) -> impl Widget {
|
2020-08-23 07:15:33 +08:00
|
|
|
let content = content.into();
|
2021-05-20 03:35:57 +08:00
|
|
|
let tab_index = tab_index.into();
|
2020-07-22 12:16:15 +08:00
|
|
|
button! {
|
2021-03-12 03:40:31 +08:00
|
|
|
content = text(content.clone());
|
2020-07-22 12:16:15 +08:00
|
|
|
tab_index;
|
2021-06-22 10:00:40 +08:00
|
|
|
on_click = hn!(|_, _| {
|
2022-01-19 13:07:24 +08:00
|
|
|
println!("Clicked {content} {tab_index:?}")
|
2021-06-22 10:00:40 +08:00
|
|
|
});
|
2020-07-22 12:16:15 +08:00
|
|
|
}
|
|
|
|
}
|
2020-08-27 11:51:40 +08:00
|
|
|
|
2022-06-20 11:08:38 +08:00
|
|
|
fn commands() -> impl Widget {
|
|
|
|
use zero_ui::core::focus::commands::*;
|
|
|
|
|
|
|
|
let cmds = [
|
|
|
|
FocusNextCommand.as_any(),
|
|
|
|
FocusPrevCommand.as_any(),
|
|
|
|
FocusUpCommand.as_any(),
|
|
|
|
FocusRightCommand.as_any(),
|
|
|
|
FocusDownCommand.as_any(),
|
|
|
|
FocusLeftCommand.as_any(),
|
|
|
|
FocusAltCommand.as_any(),
|
2022-06-24 05:17:50 +08:00
|
|
|
FocusEnterCommand.as_any(),
|
|
|
|
FocusExitCommand.as_any(),
|
2022-06-20 11:08:38 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
v_stack! {
|
|
|
|
align = Align::BOTTOM_RIGHT;
|
|
|
|
padding = 10;
|
|
|
|
spacing = 8;
|
|
|
|
items_align = Align::RIGHT;
|
|
|
|
|
|
|
|
font_family = FontName::monospace();
|
|
|
|
text_color = colors::GRAY;
|
|
|
|
|
|
|
|
items = cmds.into_iter().map(|cmd| {
|
|
|
|
text! {
|
|
|
|
text = cmd.name_with_shortcut();
|
|
|
|
|
|
|
|
when *#{cmd.enabled()} {
|
|
|
|
color = colors::WHITE;
|
|
|
|
}
|
|
|
|
}.boxed_wgt()
|
|
|
|
}).collect::<WidgetVec>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-04 05:07:54 +08:00
|
|
|
fn trace_focus(events: &mut Events) {
|
2021-06-08 02:40:32 +08:00
|
|
|
events
|
2021-06-25 07:20:10 +08:00
|
|
|
.on_pre_event(
|
|
|
|
FocusChangedEvent,
|
|
|
|
app_hn!(|ctx, args: &FocusChangedArgs, _| {
|
|
|
|
if args.is_hightlight_changed() {
|
|
|
|
println!("highlight: {}", args.highlight);
|
|
|
|
} else if args.is_widget_move() {
|
|
|
|
println!("focused {:?} moved", args.new_focus.as_ref().unwrap());
|
2022-06-05 12:25:21 +08:00
|
|
|
} else if args.is_enabled_change() {
|
|
|
|
println!("focused {:?} enabled/disabled", args.new_focus.as_ref().unwrap());
|
2021-06-25 07:20:10 +08:00
|
|
|
} else {
|
|
|
|
println!(
|
|
|
|
"{} -> {}",
|
2022-09-04 03:19:06 +08:00
|
|
|
inspect::focus(ctx.vars, ctx.services, &args.prev_focus),
|
|
|
|
inspect::focus(ctx.vars, ctx.services, &args.new_focus)
|
2021-06-25 07:20:10 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
)
|
2022-04-27 10:25:55 +08:00
|
|
|
.perm();
|
2021-05-15 04:39:50 +08:00
|
|
|
}
|
|
|
|
|
2022-06-22 05:58:53 +08:00
|
|
|
fn nested_focusables() -> impl Widget {
|
|
|
|
button! {
|
|
|
|
content = text("Nested Focusables");
|
|
|
|
|
|
|
|
on_click = hn!(|ctx, args: &ClickArgs| {
|
|
|
|
args.propagation().stop();
|
2022-07-30 02:22:05 +08:00
|
|
|
Windows::req(ctx.services).focus_or_open("nested-focusables", |_| {
|
2022-06-22 07:27:33 +08:00
|
|
|
window! {
|
|
|
|
title = "Focus Example - Nested Focusables";
|
2022-07-03 09:39:44 +08:00
|
|
|
// zero_ui::properties::inspector::show_center_points = true;
|
2022-06-22 07:56:41 +08:00
|
|
|
content_align = Align::CENTER;
|
2022-06-22 07:27:33 +08:00
|
|
|
content = v_stack! {
|
|
|
|
spacing = 10;
|
|
|
|
items = widgets![
|
|
|
|
nested_focusables_group('a'),
|
|
|
|
nested_focusables_group('b'),
|
|
|
|
];
|
2022-06-22 05:58:53 +08:00
|
|
|
}
|
2022-06-22 07:27:33 +08:00
|
|
|
}
|
|
|
|
});
|
2022-06-22 05:58:53 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn nested_focusables_group(g: char) -> impl Widget {
|
|
|
|
h_stack! {
|
|
|
|
align = Align::TOP;
|
|
|
|
spacing = 10;
|
|
|
|
items = (0..5).map(|n| nested_focusable(g, n, 0).boxed_wgt()).collect::<WidgetVec>()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn nested_focusable(g: char, column: u8, row: u8) -> impl Widget {
|
|
|
|
let nested = text! {
|
|
|
|
text = format!("Focusable {column}, {row}");
|
|
|
|
margin = 5;
|
|
|
|
};
|
|
|
|
v_stack! {
|
2022-06-22 12:12:02 +08:00
|
|
|
id = formatx!("focusable-{g}-{column}-{row}");
|
2022-06-22 05:58:53 +08:00
|
|
|
padding = 2;
|
|
|
|
|
|
|
|
items = if row == 5 {
|
|
|
|
widget_vec![nested]
|
|
|
|
} else {
|
|
|
|
widget_vec![
|
|
|
|
nested,
|
|
|
|
nested_focusable(g, column, row + 1),
|
|
|
|
]
|
|
|
|
};
|
|
|
|
|
|
|
|
focusable = true;
|
|
|
|
|
|
|
|
corner_radius = 5;
|
2022-06-22 07:56:41 +08:00
|
|
|
border = 1, colors::RED.with_alpha(30.pct());
|
2022-06-22 05:58:53 +08:00
|
|
|
background_color = colors::RED.with_alpha(20.pct());
|
|
|
|
when self.is_focused {
|
|
|
|
background_color = colors::GREEN;
|
|
|
|
}
|
2022-06-23 05:36:46 +08:00
|
|
|
when self.is_return_focus {
|
2022-06-22 07:56:41 +08:00
|
|
|
border = 1, colors::LIME_GREEN;
|
|
|
|
}
|
2022-06-22 05:58:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-27 11:51:40 +08:00
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
mod inspect {
|
2020-08-28 03:10:33 +08:00
|
|
|
use super::*;
|
2020-08-27 11:51:40 +08:00
|
|
|
use zero_ui::core::focus::WidgetInfoFocusExt;
|
2022-09-04 03:19:06 +08:00
|
|
|
use zero_ui::core::inspector::WidgetInfoInspectorExt;
|
2020-08-27 11:51:40 +08:00
|
|
|
|
2022-09-04 03:19:06 +08:00
|
|
|
pub fn focus(vars: &VarsRead, services: &mut Services, path: &Option<InteractionPath>) -> String {
|
2020-08-27 11:51:40 +08:00
|
|
|
path.as_ref()
|
|
|
|
.map(|p| {
|
2022-07-30 02:22:05 +08:00
|
|
|
let frame = if let Ok(w) = Windows::req(services).widget_tree(p.window_id()) {
|
2021-05-15 04:39:50 +08:00
|
|
|
w
|
|
|
|
} else {
|
2022-01-19 13:07:24 +08:00
|
|
|
return format!("<{p}>");
|
2021-05-15 04:39:50 +08:00
|
|
|
};
|
2022-07-09 05:59:32 +08:00
|
|
|
let widget = if let Some(w) = frame.get(p.widget_id()) {
|
2021-05-19 11:17:59 +08:00
|
|
|
w
|
|
|
|
} else {
|
2022-01-19 13:07:24 +08:00
|
|
|
return format!("<{p}>");
|
2021-05-19 11:17:59 +08:00
|
|
|
};
|
2022-09-04 03:19:06 +08:00
|
|
|
let info = widget.instance().expect("expected debug info");
|
2020-08-28 03:10:33 +08:00
|
|
|
|
2022-09-04 03:19:06 +08:00
|
|
|
if info.meta.widget_name == "button" {
|
2020-08-28 03:10:33 +08:00
|
|
|
format!(
|
2022-09-04 03:19:06 +08:00
|
|
|
"button({:?})",
|
2022-04-06 01:26:44 +08:00
|
|
|
widget
|
|
|
|
.descendant_instance("text")
|
|
|
|
.expect("expected text in button")
|
2022-09-04 03:19:06 +08:00
|
|
|
.instance()
|
|
|
|
.unwrap()
|
2022-04-06 01:26:44 +08:00
|
|
|
.property("text")
|
|
|
|
.expect("expected text property")
|
|
|
|
.arg(0)
|
2020-08-28 03:10:33 +08:00
|
|
|
.value
|
2022-09-04 03:19:06 +08:00
|
|
|
.get(vars)
|
2020-08-27 11:51:40 +08:00
|
|
|
)
|
2022-09-04 03:19:06 +08:00
|
|
|
} else if info.meta.widget_name == "window" {
|
|
|
|
let title = info
|
|
|
|
.properties
|
2021-05-15 04:39:50 +08:00
|
|
|
.iter()
|
2022-09-04 03:19:06 +08:00
|
|
|
.find(|p| p.meta.property_name == "title")
|
|
|
|
.map(|p| format!("{:?}", p.args[0].value.get(vars)))
|
2021-05-15 04:39:50 +08:00
|
|
|
.unwrap_or_default();
|
2022-01-19 13:07:24 +08:00
|
|
|
format!("window({title})")
|
2020-08-27 11:51:40 +08:00
|
|
|
} else {
|
2022-07-29 09:30:18 +08:00
|
|
|
let focus_info = widget.as_focus_info(true, true);
|
2020-08-27 11:51:40 +08:00
|
|
|
if focus_info.is_alt_scope() {
|
2022-09-04 03:19:06 +08:00
|
|
|
format!("{}(is_alt_scope)", info.meta.widget_name)
|
2020-08-27 11:51:40 +08:00
|
|
|
} else if focus_info.is_scope() {
|
2022-09-04 03:19:06 +08:00
|
|
|
format!("{}(is_scope)", info.meta.widget_name)
|
2020-08-27 11:51:40 +08:00
|
|
|
} else {
|
2022-09-04 03:19:06 +08:00
|
|
|
format!("{}({})", info.meta.widget_name, p.widget_id())
|
2020-08-28 03:10:33 +08:00
|
|
|
}
|
2020-08-27 11:51:40 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.unwrap_or_else(|| "<none>".to_owned())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(debug_assertions))]
|
|
|
|
mod inspect {
|
|
|
|
use super::*;
|
|
|
|
|
2022-06-30 07:06:01 +08:00
|
|
|
pub fn focus(path: &Option<InteractionPath>, _: &mut Services) -> String {
|
2020-08-28 03:10:33 +08:00
|
|
|
path.as_ref()
|
|
|
|
.map(|p| format!("{:?}", p.widget_id()))
|
|
|
|
.unwrap_or_else(|| "<none>".to_owned())
|
2020-08-27 11:51:40 +08:00
|
|
|
}
|
2020-08-28 03:10:33 +08:00
|
|
|
}
|