More redesign changes.

This commit is contained in:
2025-01-11 19:05:08 -08:00
parent bfd7b14db7
commit 606d2b1828
5 changed files with 57 additions and 61 deletions

10
src/Grapp.entitlements Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>

View File

@@ -19,7 +19,11 @@ enum ViewConstants {
static let spacing2: CGFloat = 2 static let spacing2: CGFloat = 2
static let spacing5: CGFloat = 2 static let spacing5: CGFloat = 2
static let spacing10: CGFloat = 10 static let spacing10: CGFloat = 10
static let spacing15: CGFloat = 15
static let spacing20: CGFloat = 20 static let spacing20: CGFloat = 20
static let spacing25: CGFloat = 25
static let spacing30: CGFloat = 30
static let spacing35: CGFloat = 35
static let spacing40: CGFloat = 40 static let spacing40: CGFloat = 40
} }

View File

@@ -74,6 +74,7 @@ $(EXEC): ./arm64/$(EXEC)
@lipo -create -output $(EXEC) $^ @lipo -create -output $(EXEC) $^
endif endif
$(EXEC).app: $(EXEC) $(EXEC).app: $(EXEC)
@rm -rf $@ @rm -rf $@
@mkdir -p $@/Contents/MacOS/ && \ @mkdir -p $@/Contents/MacOS/ && \
@@ -81,7 +82,11 @@ $(EXEC).app: $(EXEC)
cp Info.plist $@/Contents/ && \ cp Info.plist $@/Contents/ && \
cp resources/AppIcon.icns $@/Contents/Resources/ && \ cp resources/AppIcon.icns $@/Contents/Resources/ && \
cp $(EXEC) $@/Contents/MacOS/ && \ cp $(EXEC) $@/Contents/MacOS/ && \
codesign -s ${DEVELOPER_ID} -f --timestamp -o runtime $(EXEC).app $(if $(DEBUG), \
codesign --entitlements Grapp.entitlements \
-s ${APPLE_DEVELOPMENT} -f --timestamp -o runtime $(EXEC).app, \
codesign -s ${APPLE_DEVELOPER_ID_APPLICATION} -f --timestamp \
-o runtime $(EXEC).app)
all: $(EXEC).app all: $(EXEC).app

View File

@@ -55,7 +55,8 @@ class ProgramTableViewCell: NSTableCellView {
appIconImage.heightAnchor.constraint(equalToConstant: 40), appIconImage.heightAnchor.constraint(equalToConstant: 40),
appIconImage.topAnchor.constraint(equalTo: topAnchor), appIconImage.topAnchor.constraint(equalTo: topAnchor),
appIconImage.bottomAnchor.constraint(equalTo: bottomAnchor), appIconImage.bottomAnchor.constraint(equalTo: bottomAnchor),
appIconImage.leadingAnchor.constraint(equalTo: leadingAnchor), appIconImage.leadingAnchor.constraint(equalTo: leadingAnchor,
constant: ViewConstants.spacing5),
titleField.topAnchor.constraint( titleField.topAnchor.constraint(
equalTo: appIconImage.topAnchor, equalTo: appIconImage.topAnchor,

View File

@@ -4,7 +4,7 @@ import Carbon
// NOTE: This is the corner radius of the backgrounView view that acts as // NOTE: This is the corner radius of the backgrounView view that acts as
// a window frame and an NSViewController's view that clips all // a window frame and an NSViewController's view that clips all
// elements inside of it. // elements inside of it.
fileprivate let windowCornerRadius = 20.0 fileprivate let windowCornerRadius = 15.0
class SearchViewController: NSViewController, NSTextFieldDelegate, class SearchViewController: NSViewController, NSTextFieldDelegate,
NSPopoverDelegate, NSTableViewDataSource, NSTableViewDelegate NSPopoverDelegate, NSTableViewDataSource, NSTableViewDelegate
@@ -48,7 +48,6 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
private var contentView: NSView = { private var contentView: NSView = {
let view = NSView() let view = NSView()
// Clip all content to window's rounded frame emulated by // Clip all content to window's rounded frame emulated by
// backgroundView. // backgroundView.
view.wantsLayer = true view.wantsLayer = true
@@ -59,31 +58,26 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
return view return view
}() }()
private var appIconImage: NSImageView = {
let image = NSImageView()
image.image =
NSWorkspace.shared.icon(forFile: Bundle.main.bundlePath)
image.imageScaling = .scaleAxesIndependently
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
private var searchInput: EditableNSTextField = { private var searchInput: EditableNSTextField = {
let textField = EditableNSTextField() let textField = EditableNSTextField()
textField.placeholderString = "Search programs . . ." textField.isBezeled = false
textField.usesSingleLineMode = false textField.maximumNumberOfLines = 1
textField.usesSingleLineMode = true
textField.lineBreakMode = .byTruncatingHead
textField.focusRingType = .none
textField.placeholderString = "Program Search"
textField.bezelStyle = .roundedBezel textField.bezelStyle = .roundedBezel
textField.font = NSFont.systemFont( textField.font = NSFont.systemFont(
ofSize: NSFontDescriptor.preferredFontDescriptor( ofSize: NSFontDescriptor.preferredFontDescriptor(
forTextStyle: .title3).pointSize, weight: .medium) forTextStyle: .largeTitle).pointSize, weight: .medium)
textField.translatesAutoresizingMaskIntoConstraints = false textField.translatesAutoresizingMaskIntoConstraints = false
return textField return textField
}() }()
private var settingsButton: NSButton = { private var settingsButton: NSButton = {
let button = NSButton() let button = NSButton()
button.image = systemImage("gearshape.fill", .title2, .large, button.image = systemImage("gear.circle.fill", .title1, .large,
.init(paletteColors: [.labelColor, .systemRed])) .init(paletteColors: [.labelColor, .systemGray]))
button.isBordered = false button.isBordered = false
button.action = #selector(openSettings) button.action = #selector(openSettings)
button.sizeToFit() button.sizeToFit()
@@ -127,25 +121,16 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
view.addSubview(backgroundView) view.addSubview(backgroundView)
view.addSubview(contentView) view.addSubview(contentView)
contentView.addSubview(appIconImage)
contentView.addSubview(searchInput) contentView.addSubview(searchInput)
contentView.addSubview(settingsButton) contentView.addSubview(settingsButton)
contentView.addSubview(tableScrollView) contentView.addSubview(tableScrollView)
} }
var viewBottomAnchorTable: NSLayoutConstraint? var tableViewHeightAnchor: NSLayoutConstraint?
var viewBottomAnchorImage: NSLayoutConstraint?
private func setConstraints() { private func setConstraints() {
viewBottomAnchorTable = tableScrollView.bottomAnchor.constraint( tableViewHeightAnchor = tableScrollView.heightAnchor.constraint(equalToConstant: 0)
equalTo: contentView.bottomAnchor, tableViewHeightAnchor?.isActive = true
constant: -ViewConstants.spacing10)
viewBottomAnchorImage = appIconImage.bottomAnchor.constraint(
equalTo: contentView.bottomAnchor,
constant: -ViewConstants.spacing10)
viewBottomAnchorTable?.isActive = false
viewBottomAnchorImage?.isActive = true
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: contentView.topAnchor, view.topAnchor.constraint(equalTo: contentView.topAnchor,
@@ -175,37 +160,29 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
backgroundView.trailingAnchor.constraint( backgroundView.trailingAnchor.constraint(
equalTo: contentView.trailingAnchor), equalTo: contentView.trailingAnchor),
appIconImage.widthAnchor.constraint(equalToConstant: 60), searchInput.widthAnchor.constraint(equalToConstant: 350),
appIconImage.heightAnchor.constraint( searchInput.topAnchor.constraint(
equalTo: appIconImage.widthAnchor, multiplier: 1),
appIconImage.topAnchor.constraint(
equalTo: contentView.topAnchor, equalTo: contentView.topAnchor,
constant: ViewConstants.spacing10), constant: ViewConstants.spacing10),
appIconImage.leadingAnchor.constraint(
equalTo: contentView.leadingAnchor,
constant: ViewConstants.spacing10),
searchInput.widthAnchor.constraint(equalToConstant: 300),
searchInput.centerYAnchor.constraint(
equalTo: appIconImage.centerYAnchor),
searchInput.leadingAnchor.constraint( searchInput.leadingAnchor.constraint(
equalTo: appIconImage.trailingAnchor, equalTo: contentView.leadingAnchor,
constant: ViewConstants.spacing10), constant: ViewConstants.spacing15),
settingsButton.firstBaselineAnchor.constraint( settingsButton.centerYAnchor.constraint(
equalTo: searchInput.firstBaselineAnchor), equalTo: searchInput.centerYAnchor),
settingsButton.leadingAnchor.constraint( settingsButton.leadingAnchor.constraint(
equalTo: searchInput.trailingAnchor, equalTo: searchInput.trailingAnchor,
constant: ViewConstants.spacing10), constant: ViewConstants.spacing5),
settingsButton.trailingAnchor.constraint( settingsButton.trailingAnchor.constraint(
equalTo: contentView.trailingAnchor, equalTo: contentView.trailingAnchor,
constant: -ViewConstants.spacing10), constant: -ViewConstants.spacing10),
tableScrollView.heightAnchor.constraint(equalToConstant: 210), // tableScrollView.heightAnchor.constraint(equalToConstant: 210),
tableScrollView.topAnchor.constraint( tableScrollView.topAnchor.constraint(
equalTo: appIconImage.bottomAnchor, equalTo: searchInput.bottomAnchor,
constant: ViewConstants.spacing10), constant: ViewConstants.spacing10),
tableScrollView.bottomAnchor.constraint(
equalTo: contentView.bottomAnchor),
tableScrollView.leadingAnchor.constraint( tableScrollView.leadingAnchor.constraint(
equalTo: contentView.leadingAnchor), equalTo: contentView.leadingAnchor),
tableScrollView.trailingAnchor.constraint( tableScrollView.trailingAnchor.constraint(
@@ -232,7 +209,6 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
key == kVK_UpArrow key == kVK_UpArrow
{ {
controller.programsTableViewSelection -= 1 controller.programsTableViewSelection -= 1
} else if modsContains(keys: OSCtrl, in: modifiers) && } else if modsContains(keys: OSCtrl, in: modifiers) &&
key == kVK_ANSI_N || key == kVK_ANSI_N ||
modsContainsNone(in: modifiers) && modsContainsNone(in: modifiers) &&
@@ -277,6 +253,9 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
keyboardEvents?.start() keyboardEvents?.start()
// TODO: This doesn't play well when the window is expanded with
// search results, causing it to reappear in a slightly
// above usual position.
view.window?.center() view.window?.center()
view.window?.makeFirstResponder(searchInput) view.window?.makeFirstResponder(searchInput)
@@ -297,11 +276,9 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
private func reloadProgramsTableViewData() { private func reloadProgramsTableViewData() {
if programsList.count > 0 { if programsList.count > 0 {
viewBottomAnchorTable?.isActive = true tableViewHeightAnchor?.constant = 210
viewBottomAnchorImage?.isActive = false
} else { } else {
viewBottomAnchorTable?.isActive = false tableViewHeightAnchor?.constant = 0
viewBottomAnchorImage?.isActive = true
} }
programsTableView.reloadData() programsTableView.reloadData()
} }
@@ -376,13 +353,6 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
IndexSet(integer: programsTableViewSelection), IndexSet(integer: programsTableViewSelection),
byExtendingSelection: false) byExtendingSelection: false)
programsTableView.scrollRowToVisible(programsTableViewSelection) programsTableView.scrollRowToVisible(programsTableViewSelection)
if programsList.count > 0 {
appIconImage.image = programsList[0].img
} else {
appIconImage.image =
NSWorkspace.shared.icon(forFile: Bundle.main.bundlePath)
}
} }
func control(_ control: NSControl, textView: NSTextView, func control(_ control: NSControl, textView: NSTextView,
@@ -454,4 +424,10 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
return cell return cell
} }
func tableViewSelectionDidChange(_ notification: Notification) {
if programsTableView.selectedRow != programsTableViewSelection {
programsTableViewSelection = programsTableView.selectedRow
}
}
} }