diff --git a/Telegram/SourceFiles/platform/mac/mac_touchbar.h b/Telegram/SourceFiles/platform/mac/mac_touchbar.h index 11f61db91..f9e75832c 100644 --- a/Telegram/SourceFiles/platform/mac/mac_touchbar.h +++ b/Telegram/SourceFiles/platform/mac/mac_touchbar.h @@ -27,5 +27,6 @@ enum class TouchBarType { - (id _Nonnull) init:(NSView * _Nonnull)view; - (void) handleTrackStateChange:(Media::Player::TrackState)state; - (void) setTouchBar:(Platform::TouchBarType)type; +- (void) showInputFieldItems:(bool)show; @end diff --git a/Telegram/SourceFiles/platform/mac/mac_touchbar.mm b/Telegram/SourceFiles/platform/mac/mac_touchbar.mm index 7487cb46a..6b51d34a0 100644 --- a/Telegram/SourceFiles/platform/mac/mac_touchbar.mm +++ b/Telegram/SourceFiles/platform/mac/mac_touchbar.mm @@ -16,6 +16,7 @@ #include "data/data_session.h" #include "dialogs/dialogs_layout.h" #include "history/history.h" +#include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" #include "observer_peer.h" @@ -37,6 +38,14 @@ constexpr auto kCommandPlaylistPrevious = 0x003; constexpr auto kCommandPlaylistNext = 0x004; constexpr auto kCommandClosePlayer = 0x005; +constexpr auto kCommandBold = 0x010; +constexpr auto kCommandItalic = 0x011; +constexpr auto kCommandMonospace = 0x012; +constexpr auto kCommandClear = 0x013; +constexpr auto kCommandLink = 0x014; + +constexpr auto kCommandPopoverInput = 0x020; + constexpr auto kMs = 1000; constexpr auto kSongType = AudioMsgId::Type::Song; @@ -57,6 +66,13 @@ const NSTouchBarItemIdentifier kPreviousItemIdentifier = [NSString stringWithFor const NSTouchBarItemIdentifier kCommandClosePlayerItemIdentifier = [NSString stringWithFormat:@"%@.closePlayer", kCustomizationIdPlayer]; const NSTouchBarItemIdentifier kCurrentPositionItemIdentifier = [NSString stringWithFormat:@"%@.currentPosition", kCustomizationIdPlayer]; +const NSTouchBarItemIdentifier kPopoverInputItemIdentifier = [NSString stringWithFormat:@"%@.popoverInput", kCustomizationIdMain]; +const NSTouchBarItemIdentifier kBoldItemIdentifier = [NSString stringWithFormat:@"%@.bold", kCustomizationIdMain]; +const NSTouchBarItemIdentifier kItalicItemIdentifier = [NSString stringWithFormat:@"%@.italic", kCustomizationIdMain]; +const NSTouchBarItemIdentifier kMonospaceItemIdentifier = [NSString stringWithFormat:@"%@.monospace", kCustomizationIdMain]; +const NSTouchBarItemIdentifier kClearItemIdentifier = [NSString stringWithFormat:@"%@.clear", kCustomizationIdMain]; +const NSTouchBarItemIdentifier kLinkItemIdentifier = [NSString stringWithFormat:@"%@.link", kCustomizationIdMain]; + NSImage *CreateNSImageFromStyleIcon(const style::icon &icon, int size = kIdealIconSize) { const auto instance = icon.instance(QColor(255, 255, 255, 255), 100); auto pixmap = QPixmap::fromImage(instance); @@ -66,6 +82,10 @@ NSImage *CreateNSImageFromStyleIcon(const style::icon &icon, int size = kIdealIc return image; } +NSString *NSStringFromLang(LangKey key) { + return [NSString stringWithUTF8String:lang(key).toUtf8().constData()]; +} + inline bool CurrentSongExists() { return Media::Player::instance()->current(kSongType).audio() != nullptr; } @@ -124,6 +144,36 @@ void PaintUnreadBadge(Painter &p, PeerData *peer) { Dialogs::Layout::paintUnreadCount(p, unread, kIdealIconSize, kIdealIconSize - unreadSt.size, unreadSt, nullptr, 2); } +void SendKeyEvent(int command) { + QWidget *focused = QApplication::focusWidget(); + if (!qobject_cast(focused)) { + return; + } + auto key = 0; + auto modifier = Qt::KeyboardModifiers(0) | Qt::ControlModifier; + switch (command) { + case kCommandBold: + key = Qt::Key_B; + break; + case kCommandItalic: + key = Qt::Key_I; + break; + case kCommandMonospace: + key = Qt::Key_M; + modifier |= Qt::ShiftModifier; + break; + case kCommandClear: + key = Qt::Key_N; + modifier |= Qt::ShiftModifier; + break; + case kCommandLink: + key = Qt::Key_K; + break; + } + QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyPress, key, modifier)); + QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifier)); +} + } // namespace @interface PinnedDialogButton : NSCustomTouchBarItem @@ -363,6 +413,37 @@ void PaintUnreadBadge(Painter &p, PeerData *peer) { kCurrentPositionItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{ @"type": @"text", @"name": @"Current Position" + }], + kBoldItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{ + @"type": @"textButton", + @"name": NSStringFromLang(lng_menu_formatting_bold), + @"cmd": [NSNumber numberWithInt:kCommandBold], + }], + kItalicItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{ + @"type": @"textButton", + @"name": NSStringFromLang(lng_menu_formatting_italic), + @"cmd": [NSNumber numberWithInt:kCommandItalic], + }], + kMonospaceItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{ + @"type": @"textButton", + @"name": NSStringFromLang(lng_menu_formatting_monospace), + @"cmd": [NSNumber numberWithInt:kCommandMonospace], + }], + kClearItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{ + @"type": @"textButton", + @"name": NSStringFromLang(lng_menu_formatting_clear), + @"cmd": [NSNumber numberWithInt:kCommandClear], + }], + kLinkItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{ + @"type": @"textButton", + @"name": NSStringFromLang(lng_info_link_label), + @"cmd": [NSNumber numberWithInt:kCommandLink], + }], + kPopoverInputItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{ + @"type": @"popover", + @"name": @"Input Field", + @"cmd": [NSNumber numberWithInt:kCommandPopoverInput], + @"image": [NSImage imageNamed:NSImageNameTouchBarTextItalicTemplate], }] }; @@ -434,6 +515,14 @@ void PaintUnreadBadge(Painter &p, PeerData *peer) { item.customizationLabel = dictionaryItem[@"name"]; [dictionaryItem setObject:button forKey:@"view"]; return item; + } else if ([type isEqualToString:@"textButton"]) { + NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; + NSButton *button = [NSButton buttonWithTitle:dictionaryItem[@"name"] target:self action:@selector(buttonAction:)]; + button.tag = [dictionaryItem[@"cmd"] intValue]; + item.view = button; + item.customizationLabel = dictionaryItem[@"name"]; + [dictionaryItem setObject:button forKey:@"view"]; + return item; } else if ([type isEqualToString:@"text"]) { NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; NSTextField *text = [NSTextField labelWithString:@"00:00 / 00:00"]; @@ -442,6 +531,24 @@ void PaintUnreadBadge(Painter &p, PeerData *peer) { item.customizationLabel = dictionaryItem[@"name"]; [dictionaryItem setObject:text forKey:@"view"]; return item; + } else if ([type isEqualToString:@"popover"]) { + NSPopoverTouchBarItem *item = [[NSPopoverTouchBarItem alloc] initWithIdentifier:identifier]; + item.collapsedRepresentationImage = dictionaryItem[@"image"]; + + NSTouchBar *secondaryTouchBar = [[NSTouchBar alloc] init]; + secondaryTouchBar.delegate = self; + if ([dictionaryItem[@"cmd"] intValue] == kCommandPopoverInput) { + secondaryTouchBar.defaultItemIdentifiers = @[ + kBoldItemIdentifier, + kItalicItemIdentifier, + kMonospaceItemIdentifier, + kLinkItemIdentifier, + kClearItemIdentifier]; + } + + item.pressAndHoldTouchBar = secondaryTouchBar; + item.popoverTouchBar = secondaryTouchBar; + return item; } else if ([type isEqualToString:@"pinned"]) { NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; _mainPinnedButtons = [[NSMutableArray alloc] init]; @@ -512,6 +619,15 @@ void PaintUnreadBadge(Painter &p, PeerData *peer) { _touchBarType = type; } +- (void) showInputFieldItems:(bool)show { + NSMutableArray *items = [NSMutableArray arrayWithObject:kPinnedPanelItemIdentifier]; + if (show) { + [items addObject:kPopoverInputItemIdentifier]; + _touchBarMain.principalItemIdentifier = kPopoverInputItemIdentifier; + } + _touchBarMain.defaultItemIdentifiers = items; +} + // Main Touchbar. - (void) toggleArchiveButton:(bool)hide { @@ -670,6 +786,14 @@ void PaintUnreadBadge(Painter &p, PeerData *peer) { case kCommandClosePlayer: App::main()->closeBothPlayers(); break; + // Input Field. + case kCommandBold: + case kCommandItalic: + case kCommandMonospace: + case kCommandClear: + case kCommandLink: + SendKeyEvent(command); + break; } }); } diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 788d3b3ef..868b4de75 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "platform/mac/main_window_mac.h" +#include "data/data_session.h" #include "styles/style_window.h" #include "mainwindow.h" #include "mainwidget.h" @@ -16,15 +17,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_widget.h" #include "history/history_inner_widget.h" #include "main/main_account.h" // Account::sessionChanges. +#include "media/player/media_player_instance.h" +#include "media/audio/media_audio.h" #include "storage/localstorage.h" #include "window/notifications_manager_default.h" #include "window/themes/window_theme.h" +#include "platform/mac/mac_touchbar.h" #include "platform/platform_notifications_manager.h" #include "platform/platform_info.h" #include "boxes/peer_list_controllers.h" #include "boxes/about_box.h" #include "lang/lang_keys.h" #include "platform/mac/mac_utilities.h" +#include "ui/widgets/input_fields.h" #include #include @@ -32,11 +37,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include -#include "media/player/media_player_instance.h" -#include "media/audio/media_audio.h" -#include "platform/mac/mac_touchbar.h" -#include "data/data_session.h" - @interface MainWindowObserver : NSObject { } @@ -745,6 +745,7 @@ void MainWindow::updateGlobalMenuHook() { auto focused = QApplication::focusWidget(); bool canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false; auto clipboardHasText = _private->clipboardHasText(); + auto showTouchBarItem = false; if (auto edit = qobject_cast(focused)) { canCut = canCopy = canDelete = edit->hasSelectedText(); canSelectAll = !edit->text().isEmpty(); @@ -757,10 +758,18 @@ void MainWindow::updateGlobalMenuHook() { canUndo = edit->document()->isUndoAvailable(); canRedo = edit->document()->isRedoAvailable(); canPaste = clipboardHasText; + if (canCopy) { + if (const auto inputField = qobject_cast(focused->parentWidget())) { + showTouchBarItem = inputField->isMarkdownEnabled(); + } + } } else if (auto list = qobject_cast(focused)) { canCopy = list->canCopySelected(); canDelete = list->canDeleteSelected(); } + if (_private->_touchBar) { + [_private->_touchBar showInputFieldItems:showTouchBarItem]; + } App::wnd()->updateIsActive(0); const auto logged = account().sessionExists(); const auto locked = Core::App().locked(); diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.h b/Telegram/SourceFiles/ui/widgets/input_fields.h index 72b872358..ad397e070 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.h +++ b/Telegram/SourceFiles/ui/widgets/input_fields.h @@ -259,6 +259,10 @@ public: bool isUndoAvailable() const; bool isRedoAvailable() const; + bool isMarkdownEnabled() const { + return _markdownEnabled; + } + using SubmitSettings = InputSubmitSettings; void setSubmitSettings(SubmitSettings settings); static bool ShouldSubmit(