176 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
/*
 | 
						|
This file is part of Telegram Desktop,
 | 
						|
the official desktop application for the Telegram messaging service.
 | 
						|
 | 
						|
For license and copyright information please follow this link:
 | 
						|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
						|
*/
 | 
						|
#include "platform/mac/touchbar/mac_touchbar_audio.h"
 | 
						|
 | 
						|
#include "media/audio/media_audio.h"
 | 
						|
#include "media/player/media_player_instance.h"
 | 
						|
#include "platform/mac/touchbar/mac_touchbar_common.h"
 | 
						|
#include "platform/mac/touchbar/mac_touchbar_controls.h"
 | 
						|
#include "styles/style_media_player.h"
 | 
						|
 | 
						|
#import <AppKit/NSButton.h>
 | 
						|
#import <AppKit/NSCustomTouchBarItem.h>
 | 
						|
#import <AppKit/NSSlider.h>
 | 
						|
#import <AppKit/NSSliderTouchBarItem.h>
 | 
						|
 | 
						|
using TouchBar::kCircleDiameter;
 | 
						|
using TouchBar::CreateNSImageFromStyleIcon;
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
constexpr auto kSongType = AudioMsgId::Type::Song;
 | 
						|
 | 
						|
const auto *kCustomizationIdPlayer = @"telegram.touchbar";
 | 
						|
 | 
						|
inline NSTouchBarItemIdentifier Format(NSString *s) {
 | 
						|
	return [NSString stringWithFormat:@"%@.%@", kCustomizationIdPlayer, s];
 | 
						|
}
 | 
						|
const auto kSeekBarItemIdentifier = Format(@"seekbar");
 | 
						|
const auto kPlayItemIdentifier = Format(@"play");
 | 
						|
const auto kNextItemIdentifier = Format(@"nextItem");
 | 
						|
const auto kPreviousItemIdentifier = Format(@"previousItem");
 | 
						|
const auto kClosePlayerItemIdentifier = Format(@"closePlayer");
 | 
						|
const auto kCurrentPositionItemIdentifier = Format(@"currentPosition");
 | 
						|
 | 
						|
} // namespace
 | 
						|
 | 
						|
#pragma mark - TouchBarAudioPlayer
 | 
						|
 | 
						|
@interface TouchBarAudioPlayer()
 | 
						|
@end // @interface TouchBarAudioPlayer
 | 
						|
 | 
						|
@implementation TouchBarAudioPlayer {
 | 
						|
	rpl::event_stream<> _closeRequests;
 | 
						|
	rpl::producer< Media::Player::TrackState> _trackState;
 | 
						|
 | 
						|
	rpl::lifetime _lifetime;
 | 
						|
}
 | 
						|
 | 
						|
- (id)init {
 | 
						|
	self = [super init];
 | 
						|
	if (!self) {
 | 
						|
		return self;
 | 
						|
	}
 | 
						|
	self.delegate = self;
 | 
						|
	self.customizationIdentifier = kCustomizationIdPlayer.lowercaseString;
 | 
						|
	self.defaultItemIdentifiers = @[
 | 
						|
		kPlayItemIdentifier,
 | 
						|
		kPreviousItemIdentifier,
 | 
						|
		kNextItemIdentifier,
 | 
						|
		kSeekBarItemIdentifier,
 | 
						|
		kClosePlayerItemIdentifier];
 | 
						|
	self.customizationAllowedItemIdentifiers = @[
 | 
						|
		kPlayItemIdentifier,
 | 
						|
		kPreviousItemIdentifier,
 | 
						|
		kNextItemIdentifier,
 | 
						|
		kCurrentPositionItemIdentifier,
 | 
						|
		kSeekBarItemIdentifier,
 | 
						|
		kClosePlayerItemIdentifier];
 | 
						|
 | 
						|
	_trackState = Media::Player::instance()->updatedNotifier(
 | 
						|
	) | rpl::filter([=](const Media::Player::TrackState &state) {
 | 
						|
		return state.id.type() == kSongType;
 | 
						|
	});
 | 
						|
 | 
						|
	return self;
 | 
						|
}
 | 
						|
 | 
						|
- (NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
 | 
						|
		makeItemForIdentifier:(NSTouchBarItemIdentifier)itemId {
 | 
						|
	if (!touchBar) {
 | 
						|
		return nil;
 | 
						|
	}
 | 
						|
	const auto mediaPlayer = Media::Player::instance();
 | 
						|
	const auto isEqual = [&](NSString *string) {
 | 
						|
		return [itemId isEqualToString:string];
 | 
						|
	};
 | 
						|
 | 
						|
	if (isEqual(kSeekBarItemIdentifier)) {
 | 
						|
		auto *item = TouchBar::CreateTouchBarSlider(
 | 
						|
			itemId,
 | 
						|
			_lifetime,
 | 
						|
			[=](bool touchUp, double value, double duration) {
 | 
						|
				if (touchUp) {
 | 
						|
					mediaPlayer->finishSeeking(kSongType, value);
 | 
						|
				} else {
 | 
						|
					mediaPlayer->startSeeking(kSongType);
 | 
						|
				}
 | 
						|
			},
 | 
						|
			rpl::duplicate(_trackState));
 | 
						|
		return [item autorelease];
 | 
						|
	} else if (isEqual(kNextItemIdentifier)
 | 
						|
			|| isEqual(kPreviousItemIdentifier)) {
 | 
						|
		const auto isNext = isEqual(kNextItemIdentifier);
 | 
						|
		auto *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:itemId];
 | 
						|
 | 
						|
		auto *button = TouchBar::CreateTouchBarButton(
 | 
						|
			isNext
 | 
						|
				? st::touchBarIconPlayerNext
 | 
						|
				: st::touchBarIconPlayerPrevious,
 | 
						|
			_lifetime,
 | 
						|
			[=] { isNext // TODO
 | 
						|
				? mediaPlayer->next(kSongType)
 | 
						|
				: mediaPlayer->previous(kSongType); });
 | 
						|
		rpl::duplicate(
 | 
						|
			_trackState
 | 
						|
		) | rpl::start_with_next([=] {
 | 
						|
			const auto newValue = isNext
 | 
						|
				? mediaPlayer->nextAvailable(kSongType)
 | 
						|
				: mediaPlayer->previousAvailable(kSongType);
 | 
						|
			if (button.enabled != newValue) {
 | 
						|
				button.enabled = newValue;
 | 
						|
			}
 | 
						|
		}, _lifetime);
 | 
						|
 | 
						|
		item.view = button;
 | 
						|
		item.customizationLabel = [NSString
 | 
						|
			stringWithFormat:@"%@ Playlist Item",
 | 
						|
			isNext ? @"Next" : @"Previous"];
 | 
						|
		return [item autorelease];
 | 
						|
	} else if (isEqual(kPlayItemIdentifier)) {
 | 
						|
		auto *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:itemId];
 | 
						|
 | 
						|
		auto *button = TouchBar::CreateTouchBarButtonWithTwoStates(
 | 
						|
			st::touchBarIconPlayerPause,
 | 
						|
			st::touchBarIconPlayerPlay,
 | 
						|
			_lifetime,
 | 
						|
			[=](bool value) { mediaPlayer->playPause(kSongType); },
 | 
						|
			false,
 | 
						|
			rpl::duplicate(
 | 
						|
				_trackState
 | 
						|
			) | rpl::map([](const auto &state) {
 | 
						|
				return (state.state == Media::Player::State::Playing);
 | 
						|
			}) | rpl::distinct_until_changed());
 | 
						|
 | 
						|
		item.view = button;
 | 
						|
		item.customizationLabel = @"Play/Pause";
 | 
						|
		return [item autorelease];
 | 
						|
	} else if (isEqual(kClosePlayerItemIdentifier)) {
 | 
						|
		auto *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:itemId];
 | 
						|
		auto *button = TouchBar::CreateTouchBarButton(
 | 
						|
			st::touchBarIconPlayerClose,
 | 
						|
			_lifetime,
 | 
						|
			[=] { _closeRequests.fire({}); });
 | 
						|
 | 
						|
		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;
 | 
						|
}
 | 
						|
 | 
						|
- (rpl::producer<>)closeRequests {
 | 
						|
	return _closeRequests.events();
 | 
						|
}
 | 
						|
 | 
						|
@end // @implementation TouchBarAudioPlayer
 |