fix: capture mouse motion and mouse interactions in overlay
This commit is contained in:
parent
1810bedfa5
commit
1970499459
4 changed files with 417 additions and 407 deletions
|
|
@ -135,7 +135,7 @@ impl<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>
|
||||||
self.on_selected.as_ref(),
|
self.on_selected.as_ref(),
|
||||||
self.selections,
|
self.selections,
|
||||||
|| tree.state.downcast_mut::<State<Item>>(),
|
|| tree.state.downcast_mut::<State<Item>>(),
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
|
|
|
||||||
|
|
@ -585,9 +585,9 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
Cow::Borrowed(_) => panic!(),
|
Cow::Borrowed(_) => panic!(),
|
||||||
Cow::Owned(o) => o.as_mut_slice(),
|
Cow::Owned(o) => o.as_mut_slice(),
|
||||||
};
|
};
|
||||||
let menu_status = process_menu_events(
|
process_menu_events(
|
||||||
self,
|
self,
|
||||||
&event,
|
event,
|
||||||
view_cursor,
|
view_cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
|
|
@ -629,8 +629,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
if !self.is_overlay && !view_cursor.is_over(viewport) {
|
if !self.is_overlay && !view_cursor.is_over(viewport) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
let new_root = process_overlay_events(
|
||||||
let (new_root, status) = process_overlay_events(
|
|
||||||
self,
|
self,
|
||||||
renderer,
|
renderer,
|
||||||
viewport_size,
|
viewport_size,
|
||||||
|
|
@ -641,6 +640,10 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
shell,
|
shell,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if self.is_overlay && view_cursor.is_over(viewport) {
|
||||||
|
shell.capture_event();
|
||||||
|
}
|
||||||
|
|
||||||
return new_root;
|
return new_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -680,8 +683,9 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
feature = "winit",
|
feature = "winit",
|
||||||
feature = "surface-message"
|
feature = "surface-message"
|
||||||
))]
|
))]
|
||||||
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) {
|
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland))
|
||||||
if let Some(handler) = self.on_surface_action.as_ref() {
|
&& let Some(handler) = self.on_surface_action.as_ref()
|
||||||
|
{
|
||||||
let mut root = self.window_id;
|
let mut root = self.window_id;
|
||||||
let mut depth = self.depth;
|
let mut depth = self.depth;
|
||||||
while let Some(parent) =
|
while let Some(parent) =
|
||||||
|
|
@ -694,10 +698,8 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
root = *parent.0;
|
root = *parent.0;
|
||||||
depth = depth.saturating_sub(1);
|
depth = depth.saturating_sub(1);
|
||||||
}
|
}
|
||||||
shell.publish((handler)(crate::surface::Action::DestroyPopup(
|
shell
|
||||||
root,
|
.publish((handler)(crate::surface::Action::DestroyPopup(root)));
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.reset();
|
state.reset();
|
||||||
|
|
@ -708,7 +710,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
if self.bar_bounds.contains(overlay_cursor) {
|
if self.bar_bounds.contains(overlay_cursor) {
|
||||||
state.reset();
|
state.reset();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -804,8 +806,8 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
let menu_color = styling.background;
|
let menu_color = styling.background;
|
||||||
r.fill_quad(menu_quad, menu_color);
|
r.fill_quad(menu_quad, menu_color);
|
||||||
// draw path hightlight
|
// draw path hightlight
|
||||||
if let (true, Some(active)) = (draw_path, ms.index) {
|
if let (true, Some(active)) = (draw_path, ms.index)
|
||||||
if let Some(active_layout) = children_layout
|
&& let Some(active_layout) = children_layout
|
||||||
.children()
|
.children()
|
||||||
.nth(active.saturating_sub(start_index))
|
.nth(active.saturating_sub(start_index))
|
||||||
{
|
{
|
||||||
|
|
@ -824,7 +826,6 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
|
|
||||||
r.fill_quad(path_quad, styling.path);
|
r.fill_quad(path_quad, styling.path);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if start_index < menu_roots.len() {
|
if start_index < menu_roots.len() {
|
||||||
// draw item
|
// draw item
|
||||||
menu_roots[start_index..=end_index]
|
menu_roots[start_index..=end_index]
|
||||||
|
|
@ -894,6 +895,19 @@ impl<Message: Clone + 'static> overlay::Overlay<Message, crate::Theme, crate::Re
|
||||||
) {
|
) {
|
||||||
self.draw(renderer, theme, style, layout, cursor);
|
self.draw(renderer, theme, style, layout, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mouse_interaction(
|
||||||
|
&self,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
_renderer: &crate::Renderer,
|
||||||
|
) -> mouse::Interaction {
|
||||||
|
if cursor.is_over(layout.bounds()) {
|
||||||
|
mouse::Interaction::Idle
|
||||||
|
} else {
|
||||||
|
mouse::Interaction::None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, crate::Renderer>
|
impl<Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, crate::Renderer>
|
||||||
|
|
@ -948,8 +962,9 @@ impl<Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, crate::
|
||||||
feature = "winit",
|
feature = "winit",
|
||||||
feature = "surface-message"
|
feature = "surface-message"
|
||||||
))]
|
))]
|
||||||
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) {
|
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland))
|
||||||
if let Some((new_root, new_ms)) = new_root {
|
&& let Some((new_root, new_ms)) = new_root
|
||||||
|
{
|
||||||
use iced_runtime::platform_specific::wayland::popup::{
|
use iced_runtime::platform_specific::wayland::popup::{
|
||||||
SctkPopupSettings, SctkPositioner,
|
SctkPopupSettings, SctkPositioner,
|
||||||
};
|
};
|
||||||
|
|
@ -1085,10 +1100,22 @@ impl<Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, crate::
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mouse_interaction(
|
||||||
|
&self,
|
||||||
|
_tree: &Tree,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
_viewport: &Rectangle,
|
||||||
|
_renderer: &crate::Renderer,
|
||||||
|
) -> mouse::Interaction {
|
||||||
|
if cursor.is_over(layout.bounds()) {
|
||||||
|
mouse::Interaction::Idle
|
||||||
|
} else {
|
||||||
|
mouse::Interaction::None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1331,7 +1358,7 @@ fn process_menu_events<Message: std::clone::Clone>(
|
||||||
shell,
|
shell,
|
||||||
&Rectangle::default(),
|
&Rectangle::default(),
|
||||||
);
|
);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_results, clippy::too_many_lines, clippy::too_many_arguments)]
|
#[allow(unused_results, clippy::too_many_lines, clippy::too_many_arguments)]
|
||||||
|
|
@ -1343,12 +1370,11 @@ fn process_overlay_events<Message>(
|
||||||
view_cursor: Cursor,
|
view_cursor: Cursor,
|
||||||
overlay_cursor: Point,
|
overlay_cursor: Point,
|
||||||
cross_offset: f32,
|
cross_offset: f32,
|
||||||
_shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> (Option<(usize, MenuState)>, event::Status)
|
) -> Option<(usize, MenuState)>
|
||||||
where
|
where
|
||||||
Message: std::clone::Clone,
|
Message: std::clone::Clone,
|
||||||
{
|
{
|
||||||
use event::Status::{Captured, Ignored};
|
|
||||||
/*
|
/*
|
||||||
if no active root || pressed:
|
if no active root || pressed:
|
||||||
return
|
return
|
||||||
|
|
@ -1431,8 +1457,8 @@ where
|
||||||
state.open = false;
|
state.open = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
shell.capture_event();
|
||||||
return (new_menu_root, Captured);
|
return new_menu_root;
|
||||||
};
|
};
|
||||||
|
|
||||||
let last_menu_bounds = &last_menu_state.menu_bounds;
|
let last_menu_bounds = &last_menu_state.menu_bounds;
|
||||||
|
|
@ -1446,7 +1472,8 @@ where
|
||||||
{
|
{
|
||||||
|
|
||||||
last_menu_state.index = None;
|
last_menu_state.index = None;
|
||||||
return (new_menu_root, Captured);
|
shell.capture_event();
|
||||||
|
return new_menu_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calc new index
|
// calc new index
|
||||||
|
|
@ -1461,7 +1488,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if state.pressed {
|
if state.pressed {
|
||||||
return (new_menu_root, Ignored);
|
return new_menu_root;
|
||||||
}
|
}
|
||||||
let roots = active_root.iter().skip(1).fold(
|
let roots = active_root.iter().skip(1).fold(
|
||||||
&menu.menu_roots[active_root[0]].children,
|
&menu.menu_roots[active_root[0]].children,
|
||||||
|
|
@ -1494,7 +1521,7 @@ where
|
||||||
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) && remove {
|
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) && remove {
|
||||||
if let Some(id) = state.popup_id.remove(&menu.window_id) {
|
if let Some(id) = state.popup_id.remove(&menu.window_id) {
|
||||||
state.active_root.truncate(menu.depth + 1);
|
state.active_root.truncate(menu.depth + 1);
|
||||||
_shell.publish((menu.on_surface_action.as_ref().unwrap())({
|
shell.publish((menu.on_surface_action.as_ref().unwrap())({
|
||||||
crate::surface::action::destroy_popup(id)
|
crate::surface::action::destroy_popup(id)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
@ -1555,7 +1582,8 @@ where
|
||||||
state.menu_states.truncate(menu.depth + 1);
|
state.menu_states.truncate(menu.depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
(new_menu_root, Captured)
|
shell.capture_event();
|
||||||
|
new_menu_root
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use iced::clipboard::mime::AllowedMimeTypes;
|
||||||
use iced::touch::Finger;
|
use iced::touch::Finger;
|
||||||
use iced::{
|
use iced::{
|
||||||
Alignment, Background, Color, Event, Length, Padding, Rectangle, Size, Task, Vector, alignment,
|
Alignment, Background, Color, Event, Length, Padding, Rectangle, Size, Task, Vector, alignment,
|
||||||
event, keyboard, mouse, touch, window,
|
keyboard, mouse, touch, window,
|
||||||
};
|
};
|
||||||
use iced_core::mouse::ScrollDelta;
|
use iced_core::mouse::ScrollDelta;
|
||||||
use iced_core::text::{self, Ellipsize, LineHeight, Renderer as TextRenderer, Shaping, Wrapping};
|
use iced_core::text::{self, Ellipsize, LineHeight, Renderer as TextRenderer, Shaping, Wrapping};
|
||||||
|
|
@ -36,7 +36,6 @@ use std::collections::HashSet;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
|
@ -609,8 +608,8 @@ where
|
||||||
.text
|
.text
|
||||||
.get(button)
|
.get(button)
|
||||||
.zip(state.paragraphs.entry(button))
|
.zip(state.paragraphs.entry(button))
|
||||||
|
&& !text.is_empty()
|
||||||
{
|
{
|
||||||
if !text.is_empty() {
|
|
||||||
icon_spacing = f32::from(self.button_spacing);
|
icon_spacing = f32::from(self.button_spacing);
|
||||||
let paragraph = entry.or_insert_with(|| {
|
let paragraph = entry.or_insert_with(|| {
|
||||||
crate::Plain::new(Text {
|
crate::Plain::new(Text {
|
||||||
|
|
@ -630,7 +629,6 @@ where
|
||||||
let size = paragraph.min_bounds();
|
let size = paragraph.min_bounds();
|
||||||
width += size.width;
|
width += size.width;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Add indent to measurement if found.
|
// Add indent to measurement if found.
|
||||||
if let Some(indent) = self.model.indent(button) {
|
if let Some(indent) = self.model.indent(button) {
|
||||||
|
|
@ -895,12 +893,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unfocus if another segmented control was focused.
|
// Unfocus if another segmented control was focused.
|
||||||
if let Some(f) = state.focused.as_ref() {
|
if let Some(f) = state.focused.as_ref()
|
||||||
if f.updated_at != LAST_FOCUS_UPDATE.with(|f| f.get()) {
|
&& f.updated_at != LAST_FOCUS_UPDATE.with(|f| f.get())
|
||||||
|
{
|
||||||
state.unfocus();
|
state.unfocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
Size::new(self.width, self.height)
|
Size::new(self.width, self.height)
|
||||||
|
|
@ -1162,6 +1160,9 @@ where
|
||||||
None::<fn(_, _) -> Message>,
|
None::<fn(_, _) -> Message>,
|
||||||
on_drop,
|
on_drop,
|
||||||
);
|
);
|
||||||
|
if matches!(ret, iced::event::Status::Captured) {
|
||||||
|
shell.capture_event();
|
||||||
|
}
|
||||||
if let Some(msg) = maybe_msg {
|
if let Some(msg) = maybe_msg {
|
||||||
log::trace!(
|
log::trace!(
|
||||||
target: TAB_REORDER_LOG_TARGET,
|
target: TAB_REORDER_LOG_TARGET,
|
||||||
|
|
@ -1200,9 +1201,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::Touch(touch::Event::FingerLifted { id, .. }) => {
|
Event::Touch(touch::Event::FingerLifted { id, .. }) => {
|
||||||
state.fingers_pressed.remove(&id);
|
state.fingers_pressed.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1301,8 +1301,8 @@ where
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
||||||
)
|
)
|
||||||
&& !over_close_button
|
&& !over_close_button
|
||||||
|
&& let Some(position) = cursor_position.position()
|
||||||
{
|
{
|
||||||
if let Some(position) = cursor_position.position() {
|
|
||||||
state.tab_drag_candidate = Some(TabDragCandidate {
|
state.tab_drag_candidate = Some(TabDragCandidate {
|
||||||
entity: key,
|
entity: key,
|
||||||
bounds,
|
bounds,
|
||||||
|
|
@ -1323,17 +1323,15 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if is_lifted(&event) {
|
if is_lifted(&event) {
|
||||||
state.unfocus();
|
state.unfocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(on_activate) = self.on_activate.as_ref() {
|
if let Some(on_activate) = self.on_activate.as_ref() {
|
||||||
if is_pressed(&event) {
|
if is_pressed(event) {
|
||||||
state.pressed_item = Some(Item::Tab(key));
|
state.pressed_item = Some(Item::Tab(key));
|
||||||
} else if is_lifted(&event) {
|
} else if is_lifted(&event) && self.button_is_pressed(state, key) {
|
||||||
if self.button_is_pressed(state, key) {
|
|
||||||
shell.publish(on_activate(key));
|
shell.publish(on_activate(key));
|
||||||
state.set_focused();
|
state.set_focused();
|
||||||
state.focused_item = Item::Tab(key);
|
state.focused_item = Item::Tab(key);
|
||||||
|
|
@ -1342,17 +1340,15 @@ where
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Present a context menu on a right click event.
|
// Present a context menu on a right click event.
|
||||||
if self.context_menu.is_some() {
|
if self.context_menu.is_some()
|
||||||
if let Some(on_context) = self.on_context.as_ref() {
|
&& let Some(on_context) = self.on_context.as_ref()
|
||||||
if right_button_released(&event)
|
&& (right_button_released(&event)
|
||||||
|| (touch_lifted(&event) && fingers_pressed == 2)
|
|| (touch_lifted(&event) && fingers_pressed == 2))
|
||||||
{
|
{
|
||||||
state.show_context = Some(key);
|
state.show_context = Some(key);
|
||||||
state.context_cursor =
|
state.context_cursor = cursor_position.position().unwrap_or_default();
|
||||||
cursor_position.position().unwrap_or_default();
|
|
||||||
|
|
||||||
state.menu_state.inner.with_data_mut(|data| {
|
state.menu_state.inner.with_data_mut(|data| {
|
||||||
data.open = true;
|
data.open = true;
|
||||||
|
|
@ -1363,8 +1359,6 @@ where
|
||||||
shell.capture_event();
|
shell.capture_event();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Middle)) =
|
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Middle)) =
|
||||||
event
|
event
|
||||||
|
|
@ -1385,9 +1379,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.scrollable_focus {
|
if self.scrollable_focus
|
||||||
if let Some(on_activate) = self.on_activate.as_ref() {
|
&& let Some(on_activate) = self.on_activate.as_ref()
|
||||||
if let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event {
|
&& let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event
|
||||||
|
{
|
||||||
let current = Instant::now();
|
let current = Instant::now();
|
||||||
|
|
||||||
// Permit successive scroll wheel events only after a given delay.
|
// Permit successive scroll wheel events only after a given delay.
|
||||||
|
|
@ -1438,8 +1433,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if let Item::Tab(key) = std::mem::replace(&mut state.hovered, Item::None) {
|
if let Item::Tab(key) = std::mem::replace(&mut state.hovered, Item::None) {
|
||||||
for key in self.model.order.iter().copied() {
|
for key in self.model.order.iter().copied() {
|
||||||
|
|
@ -1460,11 +1453,11 @@ where
|
||||||
|
|
||||||
if let (Some(tab_drag), Some(candidate)) =
|
if let (Some(tab_drag), Some(candidate)) =
|
||||||
(self.tab_drag.as_ref(), state.tab_drag_candidate)
|
(self.tab_drag.as_ref(), state.tab_drag_candidate)
|
||||||
|
&& let Event::Mouse(mouse::Event::CursorMoved { .. }) = event
|
||||||
|
&& let Some(position) = cursor_position.position()
|
||||||
|
&& position.distance(candidate.origin) >= tab_drag.threshold
|
||||||
|
&& let Some(candidate) = state.tab_drag_candidate.take()
|
||||||
{
|
{
|
||||||
if let Event::Mouse(mouse::Event::CursorMoved { .. }) = event {
|
|
||||||
if let Some(position) = cursor_position.position() {
|
|
||||||
if position.distance(candidate.origin) >= tab_drag.threshold {
|
|
||||||
if let Some(candidate) = state.tab_drag_candidate.take() {
|
|
||||||
log::trace!(
|
log::trace!(
|
||||||
target: TAB_REORDER_LOG_TARGET,
|
target: TAB_REORDER_LOG_TARGET,
|
||||||
"tab drag threshold met entity={:?} distance={:.2} threshold={}",
|
"tab drag threshold met entity={:?} distance={:.2} threshold={}",
|
||||||
|
|
@ -1483,10 +1476,6 @@ where
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches!(
|
if matches!(
|
||||||
event,
|
event,
|
||||||
|
|
@ -1504,14 +1493,14 @@ where
|
||||||
{
|
{
|
||||||
state.focused_visible = true;
|
state.focused_visible = true;
|
||||||
return if *modifiers == keyboard::Modifiers::SHIFT {
|
return if *modifiers == keyboard::Modifiers::SHIFT {
|
||||||
self.focus_previous(state, shell)
|
self.focus_previous(state, shell);
|
||||||
} else if modifiers.is_empty() {
|
} else if modifiers.is_empty() {
|
||||||
self.focus_next(state, shell)
|
self.focus_next(state, shell);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(on_activate) = self.on_activate.as_ref() {
|
if let Some(on_activate) = self.on_activate.as_ref()
|
||||||
if let Event::Keyboard(keyboard::Event::KeyReleased {
|
&& let Event::Keyboard(keyboard::Event::KeyReleased {
|
||||||
key: keyboard::Key::Named(keyboard::key::Named::Enter),
|
key: keyboard::Key::Named(keyboard::key::Named::Enter),
|
||||||
..
|
..
|
||||||
}) = event
|
}) = event
|
||||||
|
|
@ -1526,33 +1515,31 @@ where
|
||||||
state.buttons_offset -= 1;
|
state.buttons_offset -= 1;
|
||||||
|
|
||||||
// If the change would cause it to be insensitive, focus the first tab.
|
// If the change would cause it to be insensitive, focus the first tab.
|
||||||
if !self.prev_tab_sensitive(state) {
|
if !self.prev_tab_sensitive(state)
|
||||||
if let Some(first) = self.first_tab(state) {
|
&& let Some(first) = self.first_tab(state)
|
||||||
|
{
|
||||||
state.focused_item = Item::Tab(first);
|
state.focused_item = Item::Tab(first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Item::NextButton => {
|
Item::NextButton => {
|
||||||
if self.next_tab_sensitive(state) {
|
if self.next_tab_sensitive(state) {
|
||||||
state.buttons_offset += 1;
|
state.buttons_offset += 1;
|
||||||
|
|
||||||
// If the change would cause it to be insensitive, focus the last tab.
|
// If the change would cause it to be insensitive, focus the last tab.
|
||||||
if !self.next_tab_sensitive(state) {
|
if !self.next_tab_sensitive(state)
|
||||||
if let Some(last) = self.last_tab(state) {
|
&& let Some(last) = self.last_tab(state)
|
||||||
|
{
|
||||||
state.focused_item = Item::Tab(last);
|
state.focused_item = Item::Tab(last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Item::None | Item::Set => (),
|
Item::None | Item::Set => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
shell.capture_event();
|
shell.capture_event();
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1794,14 +1781,15 @@ where
|
||||||
let original_bounds = bounds;
|
let original_bounds = bounds;
|
||||||
let center_y = bounds.center_y();
|
let center_y = bounds.center_y();
|
||||||
|
|
||||||
if show_drop_hint_marker {
|
if show_drop_hint_marker
|
||||||
if matches!(
|
&& matches!(
|
||||||
drop_hint_marker,
|
drop_hint_marker,
|
||||||
Some(DropHint {
|
Some(DropHint {
|
||||||
entity,
|
entity,
|
||||||
side: DropSide::Before
|
side: DropSide::Before
|
||||||
}) if entity == key
|
}) if entity == key
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
draw_drop_indicator(
|
draw_drop_indicator(
|
||||||
renderer,
|
renderer,
|
||||||
original_bounds,
|
original_bounds,
|
||||||
|
|
@ -1810,7 +1798,6 @@ where
|
||||||
appearance.active.text_color,
|
appearance.active.text_color,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let menu_open = || {
|
let menu_open = || {
|
||||||
state.show_context == Some(key)
|
state.show_context == Some(key)
|
||||||
|
|
@ -1882,15 +1869,17 @@ where
|
||||||
let mut indent_padding = 0.0;
|
let mut indent_padding = 0.0;
|
||||||
|
|
||||||
// Adjust bounds by indent
|
// Adjust bounds by indent
|
||||||
if let Some(indent) = self.model.indent(key) {
|
if let Some(indent) = self.model.indent(key)
|
||||||
if indent > 0 {
|
&& indent > 0
|
||||||
|
{
|
||||||
let adjustment = f32::from(indent) * f32::from(self.indent_spacing);
|
let adjustment = f32::from(indent) * f32::from(self.indent_spacing);
|
||||||
bounds.x += adjustment;
|
bounds.x += adjustment;
|
||||||
bounds.width -= adjustment;
|
bounds.width -= adjustment;
|
||||||
|
|
||||||
// Draw indent line
|
// Draw indent line
|
||||||
if let crate::theme::SegmentedButton::FileNav = self.style {
|
if let crate::theme::SegmentedButton::FileNav = self.style
|
||||||
if indent > 1 {
|
&& indent > 1
|
||||||
|
{
|
||||||
indent_padding = 7.0;
|
indent_padding = 7.0;
|
||||||
|
|
||||||
for level in 1..indent {
|
for level in 1..indent {
|
||||||
|
|
@ -1917,8 +1906,6 @@ where
|
||||||
indent_padding += 4.0;
|
indent_padding += 4.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the background of the button.
|
// Render the background of the button.
|
||||||
if key_is_focused || status_appearance.background.is_some() {
|
if key_is_focused || status_appearance.background.is_some() {
|
||||||
|
|
@ -1990,8 +1977,7 @@ where
|
||||||
bounds.x += offset;
|
bounds.x += offset;
|
||||||
} else {
|
} else {
|
||||||
// Draw the selection indicator if widget is a segmented selection, and the item is selected.
|
// Draw the selection indicator if widget is a segmented selection, and the item is selected.
|
||||||
if key_is_active {
|
if key_is_active && let crate::theme::SegmentedButton::Control = self.style {
|
||||||
if let crate::theme::SegmentedButton::Control = self.style {
|
|
||||||
let mut image_bounds = bounds;
|
let mut image_bounds = bounds;
|
||||||
image_bounds.y = center_y - 8.0;
|
image_bounds.y = center_y - 8.0;
|
||||||
|
|
||||||
|
|
@ -2007,17 +1993,14 @@ where
|
||||||
height: 16.0,
|
height: 16.0,
|
||||||
..image_bounds
|
..image_bounds
|
||||||
},
|
},
|
||||||
crate::widget::icon(
|
crate::widget::icon(match crate::widget::common::object_select().data() {
|
||||||
match crate::widget::common::object_select().data() {
|
|
||||||
crate::iced_core::svg::Data::Bytes(bytes) => {
|
crate::iced_core::svg::Data::Bytes(bytes) => {
|
||||||
crate::widget::icon::from_svg_bytes(bytes.as_ref())
|
crate::widget::icon::from_svg_bytes(bytes.as_ref()).symbolic(true)
|
||||||
.symbolic(true)
|
|
||||||
}
|
}
|
||||||
crate::iced_core::svg::Data::Path(path) => {
|
crate::iced_core::svg::Data::Path(path) => {
|
||||||
crate::widget::icon::from_path(path.clone())
|
crate::widget::icon::from_path(path.clone())
|
||||||
}
|
}
|
||||||
},
|
}),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let offset = 16.0 + f32::from(self.button_spacing);
|
let offset = 16.0 + f32::from(self.button_spacing);
|
||||||
|
|
@ -2025,7 +2008,6 @@ where
|
||||||
bounds.x += offset;
|
bounds.x += offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Whether to show the close button on this tab.
|
// Whether to show the close button on this tab.
|
||||||
let show_close_button =
|
let show_close_button =
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ where
|
||||||
clipboard,
|
clipboard,
|
||||||
shell,
|
shell,
|
||||||
&layout.bounds(),
|
&layout.bounds(),
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue