project panel: Always show paste in context menu (and grey it out when it's disabled) (#17262)
 Release Notes: - "Paste" is now always shown in project panel context menu.
This commit is contained in:
parent
b578be5c77
commit
b6cf576d66
2 changed files with 53 additions and 8 deletions
|
@ -499,8 +499,12 @@ impl ProjectPanel {
|
||||||
.action("Copy", Box::new(Copy))
|
.action("Copy", Box::new(Copy))
|
||||||
.action("Duplicate", Box::new(Duplicate))
|
.action("Duplicate", Box::new(Duplicate))
|
||||||
// TODO: Paste should always be visible, cbut disabled when clipboard is empty
|
// TODO: Paste should always be visible, cbut disabled when clipboard is empty
|
||||||
.when(self.clipboard.as_ref().is_some(), |menu| {
|
.map(|menu| {
|
||||||
|
if self.clipboard.as_ref().is_some() {
|
||||||
menu.action("Paste", Box::new(Paste))
|
menu.action("Paste", Box::new(Paste))
|
||||||
|
} else {
|
||||||
|
menu.disabled_action("Paste", Box::new(Paste))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.separator()
|
.separator()
|
||||||
.action("Copy Path", Box::new(CopyPath))
|
.action("Copy Path", Box::new(CopyPath))
|
||||||
|
|
|
@ -21,6 +21,7 @@ enum ContextMenuItem {
|
||||||
icon: Option<IconName>,
|
icon: Option<IconName>,
|
||||||
handler: Rc<dyn Fn(Option<&FocusHandle>, &mut WindowContext)>,
|
handler: Rc<dyn Fn(Option<&FocusHandle>, &mut WindowContext)>,
|
||||||
action: Option<Box<dyn Action>>,
|
action: Option<Box<dyn Action>>,
|
||||||
|
disabled: bool,
|
||||||
},
|
},
|
||||||
CustomEntry {
|
CustomEntry {
|
||||||
entry_render: Box<dyn Fn(&mut WindowContext) -> AnyElement>,
|
entry_render: Box<dyn Fn(&mut WindowContext) -> AnyElement>,
|
||||||
|
@ -102,6 +103,7 @@ impl ContextMenu {
|
||||||
handler: Rc::new(move |_, cx| handler(cx)),
|
handler: Rc::new(move |_, cx| handler(cx)),
|
||||||
icon: None,
|
icon: None,
|
||||||
action,
|
action,
|
||||||
|
disabled: false,
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -120,6 +122,7 @@ impl ContextMenu {
|
||||||
handler: Rc::new(move |_, cx| handler(cx)),
|
handler: Rc::new(move |_, cx| handler(cx)),
|
||||||
icon: None,
|
icon: None,
|
||||||
action,
|
action,
|
||||||
|
disabled: false,
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -167,6 +170,29 @@ impl ContextMenu {
|
||||||
cx.dispatch_action(action.boxed_clone());
|
cx.dispatch_action(action.boxed_clone());
|
||||||
}),
|
}),
|
||||||
icon: None,
|
icon: None,
|
||||||
|
disabled: false,
|
||||||
|
});
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disabled_action(
|
||||||
|
mut self,
|
||||||
|
label: impl Into<SharedString>,
|
||||||
|
action: Box<dyn Action>,
|
||||||
|
) -> Self {
|
||||||
|
self.items.push(ContextMenuItem::Entry {
|
||||||
|
toggle: None,
|
||||||
|
label: label.into(),
|
||||||
|
action: Some(action.boxed_clone()),
|
||||||
|
|
||||||
|
handler: Rc::new(move |context, cx| {
|
||||||
|
if let Some(context) = &context {
|
||||||
|
cx.focus(context);
|
||||||
|
}
|
||||||
|
cx.dispatch_action(action.boxed_clone());
|
||||||
|
}),
|
||||||
|
icon: None,
|
||||||
|
disabled: true,
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -179,6 +205,7 @@ impl ContextMenu {
|
||||||
action: Some(action.boxed_clone()),
|
action: Some(action.boxed_clone()),
|
||||||
handler: Rc::new(move |_, cx| cx.dispatch_action(action.boxed_clone())),
|
handler: Rc::new(move |_, cx| cx.dispatch_action(action.boxed_clone())),
|
||||||
icon: Some(IconName::ArrowUpRight),
|
icon: Some(IconName::ArrowUpRight),
|
||||||
|
disabled: false,
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -187,7 +214,11 @@ impl ContextMenu {
|
||||||
let context = self.action_context.as_ref();
|
let context = self.action_context.as_ref();
|
||||||
match self.selected_index.and_then(|ix| self.items.get(ix)) {
|
match self.selected_index.and_then(|ix| self.items.get(ix)) {
|
||||||
Some(
|
Some(
|
||||||
ContextMenuItem::Entry { handler, .. }
|
ContextMenuItem::Entry {
|
||||||
|
handler,
|
||||||
|
disabled: false,
|
||||||
|
..
|
||||||
|
}
|
||||||
| ContextMenuItem::CustomEntry { handler, .. },
|
| ContextMenuItem::CustomEntry { handler, .. },
|
||||||
) => (handler)(context, cx),
|
) => (handler)(context, cx),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -259,6 +290,7 @@ impl ContextMenu {
|
||||||
if let Some(ix) = self.items.iter().position(|item| {
|
if let Some(ix) = self.items.iter().position(|item| {
|
||||||
if let ContextMenuItem::Entry {
|
if let ContextMenuItem::Entry {
|
||||||
action: Some(action),
|
action: Some(action),
|
||||||
|
disabled: false,
|
||||||
..
|
..
|
||||||
} = item
|
} = item
|
||||||
{
|
{
|
||||||
|
@ -298,7 +330,7 @@ impl ContextMenuItem {
|
||||||
ContextMenuItem::Header(_)
|
ContextMenuItem::Header(_)
|
||||||
| ContextMenuItem::Separator
|
| ContextMenuItem::Separator
|
||||||
| ContextMenuItem::Label { .. } => false,
|
| ContextMenuItem::Label { .. } => false,
|
||||||
ContextMenuItem::Entry { .. } => true,
|
ContextMenuItem::Entry { disabled, .. } => !disabled,
|
||||||
ContextMenuItem::CustomEntry { selectable, .. } => *selectable,
|
ContextMenuItem::CustomEntry { selectable, .. } => *selectable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,6 +360,7 @@ impl Render for ContextMenu {
|
||||||
for item in self.items.iter() {
|
for item in self.items.iter() {
|
||||||
if let ContextMenuItem::Entry {
|
if let ContextMenuItem::Entry {
|
||||||
action: Some(action),
|
action: Some(action),
|
||||||
|
disabled: false,
|
||||||
..
|
..
|
||||||
} = item
|
} = item
|
||||||
{
|
{
|
||||||
|
@ -360,22 +393,30 @@ impl Render for ContextMenu {
|
||||||
handler,
|
handler,
|
||||||
icon,
|
icon,
|
||||||
action,
|
action,
|
||||||
|
disabled,
|
||||||
} => {
|
} => {
|
||||||
let handler = handler.clone();
|
let handler = handler.clone();
|
||||||
let menu = cx.view().downgrade();
|
let menu = cx.view().downgrade();
|
||||||
|
let color = if *disabled {
|
||||||
|
Color::Muted
|
||||||
|
} else {
|
||||||
|
Color::Default
|
||||||
|
};
|
||||||
let label_element = if let Some(icon) = icon {
|
let label_element = if let Some(icon) = icon {
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(Label::new(label.clone()))
|
.child(Label::new(label.clone()).color(color))
|
||||||
.child(Icon::new(*icon).size(IconSize::Small))
|
.child(
|
||||||
|
Icon::new(*icon).size(IconSize::Small).color(color),
|
||||||
|
)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
} else {
|
} else {
|
||||||
Label::new(label.clone()).into_any_element()
|
Label::new(label.clone()).color(color).into_any_element()
|
||||||
};
|
};
|
||||||
|
|
||||||
ListItem::new(ix)
|
ListItem::new(ix)
|
||||||
.inset(true)
|
.inset(true)
|
||||||
|
.disabled(*disabled)
|
||||||
.selected(Some(ix) == self.selected_index)
|
.selected(Some(ix) == self.selected_index)
|
||||||
.when_some(*toggle, |list_item, (position, toggled)| {
|
.when_some(*toggle, |list_item, (position, toggled)| {
|
||||||
let contents = if toggled {
|
let contents = if toggled {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue