feat: improve tooltips in preferences
This commit is contained in:
1 parent
3c58c6bf5f
commit
f97e9f9333
7 files changed
+37
-57
No files matched your search
@@ -53,7 +53,6 @@
|
||||
1C961BD37A4652E7A692ED8A /* thumbnails_show_running_applications_light@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 1C961484E5164C1BFF3B78FF /* thumbnails_show_running_applications_light@2x.jpg */; };
|
||||
1C961C3245C17EC408B798DE /* app_icons_hide_preview_focused_window_light@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 1C961A9B3F8ABA1ECFDF7C9F /* app_icons_hide_preview_focused_window_light@2x.jpg */; };
|
||||
1C961C7FC66CEEE4223C57A2 /* thumbnails_hide_space_number_labels_light@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 1C9611334B667767A4514B57 /* thumbnails_hide_space_number_labels_light@2x.jpg */; };
|
||||
1C961CB7E9B170E1CD99881F /* info_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C9616ABADF052D54E9375C2 /* info_button@2x.png */; };
|
||||
1C961D268F3911907129C96A /* titles_show_windowless_apps_light@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 1C9618877FB96FD51E89A597 /* titles_show_windowless_apps_light@2x.jpg */; };
|
||||
1C961DD2AB893820F334BBA4 /* thumbnails_hide_preview_focused_window_light@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 1C961802AB937EC23AADBBFA /* thumbnails_hide_preview_focused_window_light@2x.jpg */; };
|
||||
1C961DE40FF784E02A044D35 /* thumbnails_hide_status_icons_light@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 1C9616C88A2EED5DFF4E83D8 /* thumbnails_hide_status_icons_light@2x.jpg */; };
|
||||
@@ -291,7 +290,6 @@
|
||||
1C9616522F4E58860385E090 /* .swiftformat */ = {isa = PBXFileReference; lastKnownFileType = file.swiftformat; path = .swiftformat; sourceTree = "<group>"; };
|
||||
1C9616610337AE2361694C63 /* titles_hide_preview_focused_window_light@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "titles_hide_preview_focused_window_light@2x.jpg"; sourceTree = "<group>"; };
|
||||
1C96168DC0D8707F8EC6B442 /* titles_show_running_applications_windows_light@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "titles_show_running_applications_windows_light@2x.jpg"; sourceTree = "<group>"; };
|
||||
1C9616ABADF052D54E9375C2 /* info_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info_button@2x.png"; sourceTree = "<group>"; };
|
||||
1C9616C88A2EED5DFF4E83D8 /* thumbnails_hide_status_icons_light@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "thumbnails_hide_status_icons_light@2x.jpg"; sourceTree = "<group>"; };
|
||||
1C9617A90991E963760F7475 /* thumbnails_show_app_badges_light@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "thumbnails_show_app_badges_light@2x.jpg"; sourceTree = "<group>"; };
|
||||
1C9617C5839903D752070CF2 /* ImageTextButtonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageTextButtonView.swift; sourceTree = "<group>"; };
|
||||
@@ -716,14 +714,6 @@
|
||||
path = illustrations;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1C961A5CDC3134CCB0811D78 /* preferences */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1C9616ABADF052D54E9375C2 /* info_button@2x.png */,
|
||||
);
|
||||
path = preferences;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1C961B4542D84D5B6E937B15 /* workflows */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1484,7 +1474,6 @@
|
||||
BF0C86C288D4FD8F92D3C7DB /* app */,
|
||||
BF0C80536B40523C5DB23BE2 /* menubar */,
|
||||
BF0C8060939B50725E1C3392 /* permission-window */,
|
||||
1C961A5CDC3134CCB0811D78 /* preferences */,
|
||||
);
|
||||
path = icons;
|
||||
sourceTree = "<group>";
|
||||
@@ -2004,7 +1993,6 @@
|
||||
BF0C816911CAD3F1B5865BFA /* Localizable.strings in Resources */,
|
||||
BF0C863526C260F4155F9D2C /* Localizable.strings in Resources */,
|
||||
BF0C8C0EDECEA32BBCE5B27D /* Localizable.strings in Resources */,
|
||||
1C961CB7E9B170E1CD99881F /* info_button@2x.png in Resources */,
|
||||
1C96150A9E75C3D69638C481 /* app_icons_light@2x.jpg in Resources */,
|
||||
1C9617DCCF162B8F8CBF2C1D /* app_icons_align_thumbnails_center_light@2x.jpg in Resources */,
|
||||
1C961F211FCEFE8A725563DD /* app_icons_align_thumbnails_leading_light@2x.jpg in Resources */,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB |
@@ -4,4 +4,4 @@ set -exu
|
||||
|
||||
"$(pipenv --venv)"/bin/pyftsubset resources/SF-Pro-Text-Regular-Full.otf \
|
||||
--output-file=resources/SF-Pro-Text-Regular.otf \
|
||||
--text=""
|
||||
--text=""
|
||||
@@ -11,6 +11,7 @@ enum Symbols: String {
|
||||
case filledCircled = ""
|
||||
case filledCircledNumber0 = ""
|
||||
case filledCircledNumber10 = ""
|
||||
case circledInfo = ""
|
||||
}
|
||||
|
||||
// Font icon using SF Symbols from the SF Pro font from Apple
|
||||
|
||||
@@ -32,13 +32,13 @@ class MouseHoverView: NSView {
|
||||
}
|
||||
|
||||
class ClickHoverImageView: MouseHoverView {
|
||||
var imageView: NSImageView!
|
||||
var infoCircle: NSView!
|
||||
var onClick: EventClosure?
|
||||
|
||||
init(imageView: NSImageView) {
|
||||
init(infoCircle: NSView) {
|
||||
super.init(frame: .zero)
|
||||
self.imageView = imageView
|
||||
addSubview(imageView)
|
||||
self.infoCircle = infoCircle
|
||||
addSubview(infoCircle)
|
||||
|
||||
let clickGesture = NSClickGestureRecognizer(target: self, action: #selector(handleClick(_:)))
|
||||
addGestureRecognizer(clickGesture)
|
||||
@@ -130,37 +130,21 @@ class LabelAndControl: NSObject {
|
||||
return checkbox
|
||||
}
|
||||
|
||||
static func makeInfoButton(width: CGFloat = 15,
|
||||
height: CGFloat = 15,
|
||||
padding: CGFloat = 2,
|
||||
static func makeInfoButton(size: CGFloat = 18,
|
||||
onClick: EventClosure? = nil,
|
||||
onMouseEntered: EventClosure? = nil,
|
||||
onMouseExited: EventClosure? = nil) -> ClickHoverImageView {
|
||||
let imageView = NSImageView(image: NSImage(named: "info_button")!)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.imageScaling = .scaleProportionallyUpOrDown
|
||||
|
||||
// Enable layer-backed view to improve rendering quality
|
||||
imageView.wantsLayer = true
|
||||
imageView.layer?.contentsGravity = .resizeAspect
|
||||
imageView.layer?.shouldRasterize = true
|
||||
imageView.layer?.rasterizationScale = NSScreen.main?.backingScaleFactor ?? 1.0
|
||||
|
||||
let view = ClickHoverImageView(imageView: imageView)
|
||||
let imageView = ThumbnailFontIconView(symbol: .circledInfo, size: size, color: .labelColor, shadow: nil)
|
||||
let view = ClickHoverImageView(infoCircle: imageView)
|
||||
view.onClick = onClick
|
||||
view.onMouseEntered = onMouseEntered
|
||||
view.onMouseExited = onMouseExited
|
||||
|
||||
// Set constraints to add equal padding around the image
|
||||
NSLayoutConstraint.activate([
|
||||
imageView.widthAnchor.constraint(equalToConstant: width),
|
||||
imageView.heightAnchor.constraint(equalToConstant: height),
|
||||
imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: padding),
|
||||
imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -padding),
|
||||
imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
|
||||
imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
|
||||
imageView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||
imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
])
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
@@ -172,10 +156,9 @@ class LabelAndControl: NSObject {
|
||||
onClick: EventClosure? = nil,
|
||||
onMouseEntered: EventClosure? = nil,
|
||||
onMouseExited: EventClosure? = nil,
|
||||
width: CGFloat = 15,
|
||||
height: CGFloat = 15) -> [NSView] {
|
||||
size: CGFloat = 15) -> [NSView] {
|
||||
let labelCheckboxViews = makeLabelWithCheckbox(labelText, rawName, extraAction: extraAction, labelPosition: labelPosition)
|
||||
let infoButtonView = makeInfoButton(width: width, height: height, onClick: onClick, onMouseEntered: onMouseEntered, onMouseExited: onMouseExited)
|
||||
let infoButtonView = makeInfoButton(size: size, onClick: onClick, onMouseEntered: onMouseEntered, onMouseExited: onMouseExited)
|
||||
|
||||
var views: [NSView] = []
|
||||
labelCheckboxViews.forEach { view in
|
||||
|
||||
@@ -30,7 +30,7 @@ class IllustratedImageThemeView: ClickHoverImageView {
|
||||
imageView.layer?.masksToBounds = true
|
||||
imageView.layer?.cornerRadius = TableGroupView.cornerRadius
|
||||
|
||||
super.init(imageView: imageView)
|
||||
super.init(infoCircle: imageView)
|
||||
self.style = style
|
||||
self.theme = theme
|
||||
self.imageName = imageName
|
||||
@@ -77,12 +77,12 @@ class IllustratedImageThemeView: ClickHoverImageView {
|
||||
if highlighted {
|
||||
updateImage(imageName)
|
||||
} else {
|
||||
self.imageView.image = NSImage(named: self.imageName)
|
||||
(infoCircle as! NSImageView).image = NSImage(named: self.imageName)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateImage(_ imageName: String) {
|
||||
imageView.image = NSImage(named: self.getStyleThemeImageName(imageName))
|
||||
(infoCircle as! NSImageView).image = NSImage(named: getStyleThemeImageName(imageName))
|
||||
}
|
||||
|
||||
static func getConcatenatedImageName(_ style: AppearanceStylePreference,
|
||||
@@ -214,7 +214,7 @@ class ShowHideIllustratedView {
|
||||
showTabsAsWindows.supportedStyles = [.thumbnails, .appIcons, .titles]
|
||||
showTabsAsWindows.leftViews = [TableGroupView.makeText(NSLocalizedString("Show standard tabs as windows", comment: ""))]
|
||||
showTabsAsWindows.subTitle = NSLocalizedString("Some apps like Finder or Preview use standard tabs which act like independent windows. Some other apps like web browsers use custom tabs which act in unique ways and are not actual windows. AltTab can't list those separately.", comment: "")
|
||||
showTabsAsWindows.rightViews.append(LabelAndControl.makeInfoButton(width: 15, height: 15, onMouseEntered: { event, view in
|
||||
showTabsAsWindows.rightViews.append(LabelAndControl.makeInfoButton(onMouseEntered: { event, view in
|
||||
if ShowHideIllustratedView.isDisabledOnApplications(showTabsAsWindows) {
|
||||
Popover.shared.show(event: event, positioningView: view, message: featureUnavailable)
|
||||
} else {
|
||||
@@ -237,7 +237,7 @@ class ShowHideIllustratedView {
|
||||
previewFocusedWindow.supportedStyles = [.thumbnails, .appIcons, .titles]
|
||||
previewFocusedWindow.leftViews = [TableGroupView.makeText(NSLocalizedString("Preview selected window", comment: ""))]
|
||||
previewFocusedWindow.subTitle = NSLocalizedString("Preview the selected window.", comment: "")
|
||||
previewFocusedWindow.rightViews.append(LabelAndControl.makeInfoButton(width: 15, height: 15, onMouseEntered: { event, view in
|
||||
previewFocusedWindow.rightViews.append(LabelAndControl.makeInfoButton(onMouseEntered: { event, view in
|
||||
if ShowHideIllustratedView.isDisabledOnApplications(previewFocusedWindow) {
|
||||
Popover.shared.show(event: event, positioningView: view, message: featureUnavailable)
|
||||
} else {
|
||||
@@ -329,11 +329,13 @@ class ShowHideIllustratedView {
|
||||
}
|
||||
}
|
||||
|
||||
class Popover: NSPopover {
|
||||
class Popover: NSPopover, NSPopoverDelegate {
|
||||
static let shared = Popover()
|
||||
private var hidingInitiated = true
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
delegate = self
|
||||
contentViewController = NSViewController()
|
||||
behavior = .semitransient
|
||||
}
|
||||
@@ -342,12 +344,18 @@ class Popover: NSPopover {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func popoverWillClose(_ notification: Notification) {
|
||||
hidingInitiated = true
|
||||
}
|
||||
|
||||
func hide() {
|
||||
performClose(nil)
|
||||
}
|
||||
|
||||
func show(event: NSEvent, positioningView: NSView, message: String) {
|
||||
hide()
|
||||
func show(event: NSEvent, positioningView: NSView, message: String, extraView: NSView? = nil) {
|
||||
if !hidingInitiated { return }
|
||||
hidingInitiated = false
|
||||
|
||||
let view = NSView()
|
||||
|
||||
let label = NSTextField(labelWithString: message)
|
||||
@@ -356,16 +364,16 @@ class Popover: NSPopover {
|
||||
label.maximumNumberOfLines = 0
|
||||
label.isEditable = false
|
||||
label.isSelectable = true
|
||||
label.textColor = NSColor.gray
|
||||
label.font = NSFont.systemFont(ofSize: 12)
|
||||
view.addSubview(label)
|
||||
var actualView: NSView = extraView == nil ? label : StackView([label, extraView!], .vertical)
|
||||
view.addSubview(actualView)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
view.widthAnchor.constraint(lessThanOrEqualToConstant: 400),
|
||||
label.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
|
||||
label.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10),
|
||||
label.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
|
||||
label.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
|
||||
actualView.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
|
||||
actualView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10),
|
||||
actualView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
|
||||
actualView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
|
||||
])
|
||||
contentViewController?.view = view
|
||||
|
||||
|
||||
Reference in new issue
Block a user