T26c Media: video
Scrubber shows what has loaded, what has played and its chapters, names the time under the pointer, seeks by press and gpui's drag, and steps by the slider's keys; over_media lights it for a dark layer. VideoPlayer shows the host's frame in its shape with a caption and a control bar over it: the scrubber, play, the time, speed, captions, picture in picture and full screen, each only with its handler; the bar rests after a still pointer while it plays, on one wake from the executor's timer. Keys: Space and K, J and L, the arrows, C and F. VideoThumbnailStrip lays frames along the length under a playhead with a trim whose handles drag and whose ends I and O set. SubtitleEditor edits cues in place: times as mm:ss.mmm, kept in order, a time that does not read kept out with the reason shown. InlineEdit is a Tab stop with the ring; it hands focus back after Enter or Escape and keeps its text on Enter's release. overlays::media_button is shared by the lightbox and the player's bar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f7f20b5146
commit
d0175edb7b
22 files changed
+2232
-25
No files matched your search
@@ -7,10 +7,11 @@ use gpui::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
buttons::label_size,
|
||||
forms::Run,
|
||||
motion,
|
||||
primitives::{FocusRing, FocusScope, Icon, IconName, Image, give_back, take_focus},
|
||||
theme::{ActiveTheme, ControlSize, IconSize, TextSize},
|
||||
theme::{ActiveTheme, ControlSize, TextSize},
|
||||
};
|
||||
|
||||
/// One picture in a lightbox, and the line under it.
|
||||
@@ -31,10 +32,11 @@ impl Slide {
|
||||
|
||||
type OnStep = Rc<dyn Fn(usize, &mut Window, &mut App)>;
|
||||
|
||||
/// A round button drawn for the dark layer: light icon, a faint fill on hover, dim when it has nowhere to go.
|
||||
fn media_button(
|
||||
/// A round button drawn for a dark layer over pictures: light icon, a faint fill on hover, dim when it has nowhere to go.
|
||||
pub(crate) fn media_button(
|
||||
id: (ElementId, &'static str),
|
||||
icon: IconName,
|
||||
size: ControlSize,
|
||||
enabled: bool,
|
||||
run: impl Fn(&mut Window, &mut App) + 'static,
|
||||
cx: &App,
|
||||
@@ -47,11 +49,11 @@ fn media_button(
|
||||
.flex_none()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.size(theme.control_height(ControlSize::Lg))
|
||||
.size(theme.control_height(size))
|
||||
.rounded_full()
|
||||
.border_1()
|
||||
.border_color(gpui::transparent_black())
|
||||
.child(Icon::new(icon).size(IconSize::Md).color(if enabled {
|
||||
.child(Icon::new(icon).size(label_size(size).1).color(if enabled {
|
||||
light
|
||||
} else {
|
||||
light.opacity(0.3)
|
||||
@@ -147,6 +149,7 @@ impl RenderOnce for Lightbox {
|
||||
media_button(
|
||||
(self.id.clone(), name),
|
||||
icon,
|
||||
ControlSize::Lg,
|
||||
to.is_some(),
|
||||
move |window, cx| {
|
||||
if let Some(to) = to {
|
||||
@@ -206,6 +209,7 @@ impl RenderOnce for Lightbox {
|
||||
.child(div().flex().justify_end().p_3().child(media_button(
|
||||
(self.id.clone(), "close"),
|
||||
IconName::X,
|
||||
ControlSize::Lg,
|
||||
true,
|
||||
move |window, cx| button(window, cx),
|
||||
cx,
|
||||
|
||||
@@ -12,6 +12,7 @@ pub use dialog::{Close, Dialog};
|
||||
pub use dialogs::{AlertDialog, ConfirmDialog, PromptDialog};
|
||||
pub use floats::{FloatingToolbar, Peek};
|
||||
pub use hover::HoverCard;
|
||||
pub(crate) use lightbox::media_button;
|
||||
pub use lightbox::{Lightbox, Slide};
|
||||
pub use popover::Popover;
|
||||
pub use spotlight::{Spotlight, Tour, TourStep};
|
||||
Reference in new issue
Block a user