import { Injectable, Inject, NgZone } from '@angular/core' import { TouchBarSegmentedControl, SegmentedControlSegment } from 'electron' import { AppService } from './app.service' import { ConfigService } from './config.service' import { ElectronService } from './electron.service' import { HostAppService, Platform } from './hostApp.service' import { ToolbarButton, ToolbarButtonProvider } from '../api' /** @hidden */ @Injectable({ providedIn: 'root' }) export class TouchbarService { private tabsSegmentedControl: TouchBarSegmentedControl private buttonsSegmentedControl: TouchBarSegmentedControl private tabSegments: SegmentedControlSegment[] = [] private nsImageCache: {[id: string]: Electron.NativeImage} = {} constructor ( private app: AppService, private hostApp: HostAppService, @Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[], private config: ConfigService, private electron: ElectronService, private zone: NgZone, ) { if (this.hostApp.platform !== Platform.macOS) { return } app.tabsChanged$.subscribe(() => this.updateTabs()) app.activeTabChange$.subscribe(() => this.updateTabs()) const activityIconPath = `${electron.app.getAppPath()}/assets/activity.png` const activityIcon = this.electron.nativeImage.createFromPath(activityIconPath) app.tabOpened$.subscribe(tab => { tab.titleChange$.subscribe(title => { const segment = this.tabSegments[app.tabs.indexOf(tab)] if (segment) { segment.label = this.shortenTitle(title) this.tabsSegmentedControl.segments = this.tabSegments } }) tab.activity$.subscribe(hasActivity => { const showIcon = this.app.activeTab !== tab && hasActivity const segment = this.tabSegments[app.tabs.indexOf(tab)] if (segment) { segment.icon = showIcon ? activityIcon : undefined } }) }) } updateTabs () { this.tabSegments = this.app.tabs.map(tab => ({ label: this.shortenTitle(tab.title), })) this.tabsSegmentedControl.segments = this.tabSegments this.tabsSegmentedControl.selectedIndex = this.app.tabs.indexOf(this.app.activeTab) } update () { if (this.hostApp.platform !== Platform.macOS) { return } let buttons: ToolbarButton[] = [] this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => { buttons = buttons.concat(provider.provide()) }) buttons = buttons.filter(x => !!x.touchBarNSImage) buttons.sort((a, b) => (a.weight || 0) - (b.weight || 0)) this.tabSegments = this.app.tabs.map(tab => ({ label: this.shortenTitle(tab.title), })) this.tabsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({ segments: this.tabSegments, selectedIndex: this.app.tabs.indexOf(this.app.activeTab), change: (selectedIndex) => this.zone.run(() => { this.app.selectTab(this.app.tabs[selectedIndex]) }), }) this.buttonsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({ segments: buttons.map(button => this.getButton(button)), mode: 'buttons', change: (selectedIndex) => this.zone.run(() => { if (buttons[selectedIndex].click) { buttons[selectedIndex].click!() } }), }) const touchBar = new this.electron.TouchBar({ items: [ this.tabsSegmentedControl, new this.electron.TouchBar.TouchBarSpacer({ size: 'flexible' }), new this.electron.TouchBar.TouchBarSpacer({ size: 'small' }), this.buttonsSegmentedControl, ], }) this.hostApp.setTouchBar(touchBar) } private getButton (button: ToolbarButton): Electron.SegmentedControlSegment { return { label: button.touchBarNSImage ? undefined : this.shortenTitle(button.touchBarTitle || button.title), icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : undefined, // click: () => this.zone.run(() => button.click()), } } private getCachedNSImage (name: string) { if (!this.nsImageCache[name]) { this.nsImageCache[name] = this.electron.nativeImage.createFromNamedImage(name, [0, 0, 1]) } return this.nsImageCache[name] } private shortenTitle (title: string): string { if (title.length > 15) { title = title.substring(0, 15) + '...' } return title } }