feat: improve tooltips in preferences

This commit is contained in:
lwouis committed 2024-12-03 21:46:26 +01:00
1 parent 3c58c6bf5f
commit f97e9f9333
7 files changed
+37 -57

No files matched your search

-12
View File
@@ -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

+1 -1
View File
@@ -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
+13 -30
View File
@@ -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