From 87aa8a249f03bbae821b07a6f52803a7dee2fa45 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 12 Jul 2020 00:48:42 +0300 Subject: [PATCH] Reimplemented track position item for audio touchbar. --- .../mac/touchbar/mac_touchbar_audio.mm | 8 +- .../mac/touchbar/mac_touchbar_controls.h | 6 + .../mac/touchbar/mac_touchbar_controls.mm | 116 +++++++++++++++++- 3 files changed, 127 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_audio.mm b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_audio.mm index 89e934ca96..8dfa3d1336 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_audio.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_audio.mm @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "platform/mac/touchbar/mac_touchbar_audio.h" -#include "core/sandbox.h" #include "media/audio/media_audio.h" #include "media/player/media_player_instance.h" #include "platform/mac/touchbar/mac_touchbar_common.h" @@ -72,7 +71,7 @@ const auto kCurrentPositionItemIdentifier = Format(@"currentPosition"); kPlayItemIdentifier, kPreviousItemIdentifier, kNextItemIdentifier, - // kCurrentPositionItemIdentifier, // TODO. + kCurrentPositionItemIdentifier, kSeekBarItemIdentifier, kClosePlayerItemIdentifier]; @@ -164,6 +163,11 @@ const auto kCurrentPositionItemIdentifier = Format(@"currentPosition"); item.view = button; item.customizationLabel = @"Close Player"; return [item autorelease]; + } else if (isEqual(kCurrentPositionItemIdentifier)) { + auto *item = TouchBar::CreateTouchBarTrackPosition( + itemId, + rpl::duplicate(_trackState)); + return [item autorelease]; } return nil; } diff --git a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.h b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.h index 62c36c66f1..1cc8c832f4 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.h +++ b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.h @@ -14,6 +14,7 @@ struct TrackState; } // namespace Media @class NSButton; +@class NSCustomTouchBarItem; @class NSImage; @class NSSliderTouchBarItem; @@ -56,4 +57,9 @@ NSSliderTouchBarItem *CreateTouchBarSlider( Fn callback, rpl::producer stateChanged); +[[nodiscard]] API_AVAILABLE(macos(10.12.2)) +NSCustomTouchBarItem *CreateTouchBarTrackPosition( + NSString *itemId, + rpl::producer stateChanged); + } // namespace TouchBar diff --git a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.mm b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.mm index 8d75429d2a..a72072660d 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_controls.mm @@ -7,24 +7,126 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "platform/mac/touchbar/mac_touchbar_controls.h" +#include "base/platform/mac/base_utilities_mac.h" // Q2NSString() #include "core/sandbox.h" // Sandbox::customEnterFromEventLoop() +#include "layout.h" // formatDurationText() #include "media/audio/media_audio.h" #include "platform/mac/touchbar/mac_touchbar_common.h" #import +#import #import +#import #import #import +using namespace TouchBar; + namespace { +constexpr auto kPadding = 7; + inline NSImage *Icon(const style::icon &icon) { - using namespace TouchBar; return CreateNSImageFromStyleIcon(icon, kCircleDiameter / 2); } +inline NSDictionary *Attributes() { + return @{ + NSFontAttributeName: [NSFont systemFontOfSize:14], + NSParagraphStyleAttributeName: + [NSMutableParagraphStyle defaultParagraphStyle], + NSForegroundColorAttributeName: [NSColor whiteColor] + }; +} + +inline NSString *FormatTime(TimeId time) { + return Platform::Q2NSString(formatDurationText(time)); +} + } // namespace +#pragma mark - TrackPosition + +@interface TrackPosition : NSImageView +@end // @interface TrackPosition + +@implementation TrackPosition { + NSMutableString *_text; + + double _width; + double _height; + + rpl::lifetime _lifetime; +} + +- (id)init:(rpl::producer< Media::Player::TrackState>)trackState { + self = [super init]; + const auto textLength = _lifetime.make_state>(0); + _width = _height = 0; + _text = [[NSMutableString alloc] initWithCapacity:13]; + + rpl::combine( + rpl::duplicate( + trackState + ) | rpl::map([](const auto &state) { + return state.position / 1000; + }) | rpl::distinct_until_changed(), + std::move( + trackState + ) | rpl::map([](const auto &state) { + return state.length / 1000; + }) | rpl::distinct_until_changed() + ) | rpl::start_with_next([=](int position, int length) { + [_text setString:[NSString stringWithFormat:@"%@ / %@", + FormatTime(position), + FormatTime(length)]]; + *textLength = _text.length; + + [self display]; + }, _lifetime); + + textLength->changes( + ) | rpl::start_with_next([=] { + const auto size = [_text sizeWithAttributes:Attributes()]; + _width = size.width + kPadding * 2; + _height = size.height; + + if (self.image) { + [self.image release]; + } + self.image = [[NSImage alloc] initWithSize:NSMakeSize( + _width, + kCircleDiameter)]; + }, _lifetime); + + return self; +} + +- (void)drawRect:(NSRect)dirtyRect { + if (!(_text && _text.length && _width && _height)) { + return; + } + const auto size = [_text sizeWithAttributes:Attributes()]; + const auto rect = CGRectMake( + (_width - size.width) / 2, + -(kCircleDiameter - _height) / 2, + _width, + kCircleDiameter); + [_text drawInRect:rect withAttributes:Attributes()]; +} + +- (void)dealloc { + if (self.image) { + [self.image release]; + } + if (_text) { + [_text release]; + } + [super dealloc]; +} + +@end // @implementation TrackPosition + namespace TouchBar { NSButton *CreateTouchBarButton( @@ -159,4 +261,16 @@ NSSliderTouchBarItem *CreateTouchBarSlider( return seekBar; } +NSCustomTouchBarItem *CreateTouchBarTrackPosition( + NSString *itemId, + rpl::producer stateChanged) { + auto *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:itemId]; + auto *trackPosition = [[[TrackPosition alloc] + init:std::move(stateChanged)] autorelease]; + + item.view = trackPosition; + item.customizationLabel = @"Track Position"; + return item; +} + } // namespace TouchBar