Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions Textream/Textream/NotchOverlayController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ class NotchOverlayController: NSObject {
content: overlayContent,
speechRecognizer: speechRecognizer,
baseHeight: panelHeight,
followingCursor: true
followingCursor: true,
mirrorAxis: settings.floatingMirrorDisplay ? settings.floatingMirrorAxis : nil
)
let contentView = NSHostingView(rootView: floatingView)

Expand Down Expand Up @@ -312,7 +313,7 @@ class NotchOverlayController: NSObject {
let fullscreenView = ExternalDisplayView(
content: overlayContent,
speechRecognizer: speechRecognizer,
mirrorAxis: nil
mirrorAxis: settings.fullscreenMirrorDisplay ? settings.fullscreenMirrorAxis : nil
)
let contentView = NSHostingView(rootView: fullscreenView)

Expand Down Expand Up @@ -347,7 +348,8 @@ class NotchOverlayController: NSObject {
let floatingView = FloatingOverlayView(
content: overlayContent,
speechRecognizer: speechRecognizer,
baseHeight: panelHeight
baseHeight: panelHeight,
mirrorAxis: settings.floatingMirrorDisplay ? settings.floatingMirrorAxis : nil
)
let contentView = NSHostingView(rootView: floatingView)

Expand Down Expand Up @@ -1186,6 +1188,7 @@ struct FloatingOverlayView: View {
@Bindable var speechRecognizer: SpeechRecognizer
let baseHeight: CGFloat
var followingCursor: Bool = false
var mirrorAxis: MirrorAxis? = nil

private var words: [String] { content.words }
private var totalCharCount: Int { content.totalCharCount }
Expand Down Expand Up @@ -1292,7 +1295,10 @@ struct FloatingOverlayView: View {
)
.clipShape(RoundedRectangle(cornerRadius: 16))
.opacity(appeared ? 1 : 0)
.scaleEffect(appeared ? 1 : 0.9)
.scaleEffect(
x: (mirrorAxis?.scaleX ?? 1) * (appeared ? 1 : 0.9),
y: (mirrorAxis?.scaleY ?? 1) * (appeared ? 1 : 0.9)
)
.onAppear {
withAnimation(.easeOut(duration: 0.3)) {
appeared = true
Expand Down
20 changes: 20 additions & 0 deletions Textream/Textream/NotchSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,14 @@ class NotchSettings {
didSet { UserDefaults.standard.set(followCursorWhenUndocked, forKey: "followCursorWhenUndocked") }
}

var floatingMirrorDisplay: Bool {
didSet { UserDefaults.standard.set(floatingMirrorDisplay, forKey: "floatingMirrorDisplay") }
}

var floatingMirrorAxis: MirrorAxis {
didSet { UserDefaults.standard.set(floatingMirrorAxis.rawValue, forKey: "floatingMirrorAxis") }
}

var externalDisplayMode: ExternalDisplayMode {
didSet { UserDefaults.standard.set(externalDisplayMode.rawValue, forKey: "externalDisplayMode") }
}
Expand Down Expand Up @@ -427,6 +435,14 @@ class NotchSettings {
didSet { UserDefaults.standard.set(Int(fullscreenScreenID), forKey: "fullscreenScreenID") }
}

var fullscreenMirrorDisplay: Bool {
didSet { UserDefaults.standard.set(fullscreenMirrorDisplay, forKey: "fullscreenMirrorDisplay") }
}

var fullscreenMirrorAxis: MirrorAxis {
didSet { UserDefaults.standard.set(fullscreenMirrorAxis.rawValue, forKey: "fullscreenMirrorAxis") }
}

var browserServerEnabled: Bool {
didSet {
UserDefaults.standard.set(browserServerEnabled, forKey: "browserServerEnabled")
Expand Down Expand Up @@ -484,6 +500,8 @@ class NotchSettings {
let savedTransparencyOpacity = UserDefaults.standard.double(forKey: "overlayTransparencyOpacity")
self.overlayTransparencyOpacity = savedTransparencyOpacity > 0 ? savedTransparencyOpacity : 0.85
self.followCursorWhenUndocked = UserDefaults.standard.object(forKey: "followCursorWhenUndocked") as? Bool ?? false
self.floatingMirrorDisplay = UserDefaults.standard.object(forKey: "floatingMirrorDisplay") as? Bool ?? false
self.floatingMirrorAxis = MirrorAxis(rawValue: UserDefaults.standard.string(forKey: "floatingMirrorAxis") ?? "") ?? .horizontal
self.externalDisplayMode = ExternalDisplayMode(rawValue: UserDefaults.standard.string(forKey: "externalDisplayMode") ?? "") ?? .off
let savedScreenID = UserDefaults.standard.integer(forKey: "externalScreenID")
self.externalScreenID = UInt32(savedScreenID)
Expand All @@ -499,6 +517,8 @@ class NotchSettings {
self.autoNextPageDelay = savedDelay > 0 ? savedDelay : 3
let savedFullscreenScreenID = UserDefaults.standard.integer(forKey: "fullscreenScreenID")
self.fullscreenScreenID = UInt32(savedFullscreenScreenID)
self.fullscreenMirrorDisplay = UserDefaults.standard.object(forKey: "fullscreenMirrorDisplay") as? Bool ?? false
self.fullscreenMirrorAxis = MirrorAxis(rawValue: UserDefaults.standard.string(forKey: "fullscreenMirrorAxis") ?? "") ?? .horizontal
self.browserServerEnabled = UserDefaults.standard.object(forKey: "browserServerEnabled") as? Bool ?? false
let savedPort = UserDefaults.standard.integer(forKey: "browserServerPort")
self.browserServerPort = savedPort > 0 ? UInt16(savedPort) : 7373
Expand Down
47 changes: 47 additions & 0 deletions Textream/Textream/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,13 @@ struct SettingsView: View {

Divider()

mirrorDisplayPicker(
isEnabled: $settings.floatingMirrorDisplay,
axis: $settings.floatingMirrorAxis
)

Divider()

Toggle(isOn: $settings.floatingGlassEffect) {
Text("Glass Effect")
.font(.system(size: 13, weight: .medium))
Expand Down Expand Up @@ -913,6 +920,13 @@ struct SettingsView: View {
onRefresh: { refreshOverlayScreens() }
)

Divider()

mirrorDisplayPicker(
isEnabled: $settings.fullscreenMirrorDisplay,
axis: $settings.fullscreenMirrorAxis
)

HStack(spacing: 6) {
Image(systemName: "escape")
.font(.system(size: 11, weight: .semibold))
Expand Down Expand Up @@ -990,6 +1004,35 @@ struct SettingsView: View {
.onAppear { refreshOverlayScreens() }
}

private func mirrorDisplayPicker(isEnabled: Binding<Bool>, axis: Binding<MirrorAxis>) -> some View {
VStack(alignment: .leading, spacing: 8) {
Toggle(isOn: isEnabled) {
Text("Mirror Display")
.font(.system(size: 13, weight: .medium))
}
.toggleStyle(.switch)
.controlSize(.small)

Text("Flip the teleprompter for use with a mirror rig.")
.font(.system(size: 11))
.foregroundStyle(.secondary)

if isEnabled.wrappedValue {
Picker("", selection: axis) {
ForEach(MirrorAxis.allCases) { mirrorAxis in
Text(mirrorAxis.label).tag(mirrorAxis)
}
}
.pickerStyle(.segmented)
.labelsHidden()

Text(axis.wrappedValue.description)
.font(.system(size: 11))
.foregroundStyle(.secondary)
}
}
}

// MARK: - External Tab

@State private var availableScreens: [NSScreen] = []
Expand Down Expand Up @@ -1391,7 +1434,11 @@ struct SettingsView: View {
settings.overlayTransparency = false
settings.overlayTransparencyOpacity = 0.85
settings.followCursorWhenUndocked = false
settings.floatingMirrorDisplay = false
settings.floatingMirrorAxis = .horizontal
settings.fullscreenScreenID = 0
settings.fullscreenMirrorDisplay = false
settings.fullscreenMirrorAxis = .horizontal
settings.externalDisplayMode = .off
settings.externalScreenID = 0
settings.mirrorAxis = .horizontal
Expand Down