@@ -24,8 +24,8 @@ use std::{
};
use supermaven::{AccountStatus, Supermaven};
use ui::{
- prelude::*, Clickable, ContextMenu, ContextMenuEntry, IconButton, IconButtonShape, PopoverMenu,
- PopoverMenuHandle, Tooltip,
+ prelude::*, Clickable, ContextMenu, ContextMenuEntry, IconButton, IconButtonShape, Indicator,
+ PopoverMenu, PopoverMenuHandle, Tooltip,
};
use workspace::{
create_and_open_local_file, item::ItemHandle, notifications::NotificationId, StatusItemView,
@@ -240,24 +240,20 @@ impl Render for InlineCompletionButton {
let current_user_terms_accepted =
self.user_store.read(cx).current_user_has_accepted_terms();
- let icon_button = || {
- let base = IconButton::new("zed-predict-pending-button", zeta_icon)
- .shape(IconButtonShape::Square);
-
- match (
- current_user_terms_accepted,
- self.popover_menu_handle.is_deployed(),
- enabled,
- ) {
- (Some(false) | None, _, _) => {
- let signed_in = current_user_terms_accepted.is_some();
- let tooltip_meta = if signed_in {
- "Read Terms of Service"
- } else {
- "Sign in to use"
- };
+ if !current_user_terms_accepted.unwrap_or(false) {
+ let signed_in = current_user_terms_accepted.is_some();
+ let tooltip_meta = if signed_in {
+ "Read Terms of Service"
+ } else {
+ "Sign in to use"
+ };
- base.tooltip(move |window, cx| {
+ return div().child(
+ IconButton::new("zed-predict-pending-button", zeta_icon)
+ .shape(IconButtonShape::Square)
+ .indicator(Indicator::dot().color(Color::Error))
+ .indicator_border_color(Some(cx.theme().colors().status_bar_background))
+ .tooltip(move |window, cx| {
Tooltip::with_meta(
"Edit Predictions",
None,
@@ -266,34 +262,38 @@ impl Render for InlineCompletionButton {
cx,
)
})
- .on_click(cx.listener(
- move |_, _, window, cx| {
- telemetry::event!(
- "Pending ToS Clicked",
- source = "Edit Prediction Status Button"
- );
- window.dispatch_action(
- zed_actions::OpenZedPredictOnboarding.boxed_clone(),
- cx,
- );
- },
- ))
+ .on_click(cx.listener(move |_, _, window, cx| {
+ telemetry::event!(
+ "Pending ToS Clicked",
+ source = "Edit Prediction Status Button"
+ );
+ window.dispatch_action(
+ zed_actions::OpenZedPredictOnboarding.boxed_clone(),
+ cx,
+ );
+ })),
+ );
+ }
+
+ let icon_button = IconButton::new("zed-predict-pending-button", zeta_icon)
+ .shape(IconButtonShape::Square)
+ .when(!self.popover_menu_handle.is_deployed(), |element| {
+ if enabled {
+ element.tooltip(|window, cx| {
+ Tooltip::for_action("Edit Prediction", &ToggleMenu, window, cx)
+ })
+ } else {
+ element.tooltip(|window, cx| {
+ Tooltip::with_meta(
+ "Edit Prediction",
+ Some(&ToggleMenu),
+ "Disabled For This File",
+ window,
+ cx,
+ )
+ })
}
- (Some(true), true, _) => base,
- (Some(true), false, true) => base.tooltip(|window, cx| {
- Tooltip::for_action("Edit Prediction", &ToggleMenu, window, cx)
- }),
- (Some(true), false, false) => base.tooltip(|window, cx| {
- Tooltip::with_meta(
- "Edit Prediction",
- Some(&ToggleMenu),
- "Disabled For This File",
- window,
- cx,
- )
- }),
- }
- };
+ });
let this = cx.entity().clone();
@@ -311,7 +311,7 @@ impl Render for InlineCompletionButton {
if is_refreshing {
popover_menu = popover_menu.trigger(
- icon_button().with_animation(
+ icon_button.with_animation(
"pulsating-label",
Animation::new(Duration::from_secs(2))
.repeat()
@@ -320,7 +320,7 @@ impl Render for InlineCompletionButton {
),
);
} else {
- popover_menu = popover_menu.trigger(icon_button());
+ popover_menu = popover_menu.trigger(icon_button);
}
div().child(popover_menu.into_any_element())
@@ -1,5 +1,6 @@
#![allow(missing_docs)]
-use crate::{prelude::*, Icon, IconName, IconSize};
+use crate::{prelude::*, Icon, IconName, IconSize, IconWithIndicator, Indicator};
+use gpui::Hsla;
/// An icon that appears within a button.
///
@@ -15,6 +16,8 @@ pub(super) struct ButtonIcon {
selected_icon: Option<IconName>,
selected_icon_color: Option<Color>,
selected_style: Option<ButtonStyle>,
+ indicator: Option<Indicator>,
+ indicator_border_color: Option<Hsla>,
}
impl ButtonIcon {
@@ -28,6 +31,8 @@ impl ButtonIcon {
selected_icon: None,
selected_icon_color: None,
selected_style: None,
+ indicator: None,
+ indicator_border_color: None,
}
}
@@ -56,6 +61,16 @@ impl ButtonIcon {
self.selected_icon_color = color.into();
self
}
+
+ pub fn indicator(mut self, indicator: Indicator) -> Self {
+ self.indicator = Some(indicator);
+ self
+ }
+
+ pub fn indicator_border_color(mut self, color: Option<Hsla>) -> Self {
+ self.indicator_border_color = color;
+ self
+ }
}
impl Disableable for ButtonIcon {
@@ -96,6 +111,13 @@ impl RenderOnce for ButtonIcon {
self.color
};
- Icon::new(icon).size(self.size).color(icon_color)
+ let icon = Icon::new(icon).size(self.size).color(icon_color);
+
+ match self.indicator {
+ Some(indicator) => IconWithIndicator::new(icon, Some(indicator))
+ .indicator_border_color(self.indicator_border_color)
+ .into_any_element(),
+ None => icon.into_any_element(),
+ }
}
}
@@ -1,8 +1,8 @@
#![allow(missing_docs)]
-use gpui::{AnyView, DefiniteLength};
+use gpui::{AnyView, DefiniteLength, Hsla};
use super::button_like::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle};
-use crate::{prelude::*, ElevationIndex, SelectableButton};
+use crate::{prelude::*, ElevationIndex, Indicator, SelectableButton};
use crate::{IconName, IconSize};
use super::button_icon::ButtonIcon;
@@ -22,6 +22,8 @@ pub struct IconButton {
icon_size: IconSize,
icon_color: Color,
selected_icon: Option<IconName>,
+ indicator: Option<Indicator>,
+ indicator_border_color: Option<Hsla>,
alpha: Option<f32>,
}
@@ -34,6 +36,8 @@ impl IconButton {
icon_size: IconSize::default(),
icon_color: Color::Default,
selected_icon: None,
+ indicator: None,
+ indicator_border_color: None,
alpha: None,
};
this.base.base = this.base.base.debug_selector(|| format!("ICON-{:?}", icon));
@@ -64,6 +68,16 @@ impl IconButton {
self.selected_icon = icon.into();
self
}
+
+ pub fn indicator(mut self, indicator: Indicator) -> Self {
+ self.indicator = Some(indicator);
+ self
+ }
+
+ pub fn indicator_border_color(mut self, color: Option<Hsla>) -> Self {
+ self.indicator_border_color = color;
+ self
+ }
}
impl Disableable for IconButton {
@@ -168,6 +182,10 @@ impl RenderOnce for IconButton {
.toggle_state(is_selected)
.selected_icon(self.selected_icon)
.when_some(selected_style, |this, style| this.selected_style(style))
+ .when_some(self.indicator, |this, indicator| {
+ this.indicator(indicator)
+ .indicator_border_color(self.indicator_border_color)
+ })
.size(self.icon_size)
.color(Color::Custom(color)),
)