Skip to content

Commit

Permalink
Create ImageButton with some bells and whistles ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
pakerwreah committed Nov 24, 2022
1 parent 4858036 commit 2da90dd
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 27 deletions.
4 changes: 4 additions & 0 deletions Calendr.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
34D19FC0262299D300B2732C /* NSEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D19FBF262299D300B2732C /* NSEdgeInsets.swift */; };
34D19FC62622A02C00B2732C /* EventDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D19FC52622A02C00B2732C /* EventDetailsViewModelTests.swift */; };
34D19FCC2622B9CD00B2732C /* EventMeta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D19FCB2622B9CC00B2732C /* EventMeta.swift */; };
34D25E4A292F9E2100557E70 /* ImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D25E49292F9E2100557E70 /* ImageButton.swift */; };
34D55FE325F06669007F5C81 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D55FE225F06669007F5C81 /* Sequence.swift */; };
34E004A725B61D5200241419 /* StatusItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E004A625B61D5200241419 /* StatusItemViewModel.swift */; };
34E1902325B76CFE00E9491B /* CalendarPickerViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E1902225B76CFE00E9491B /* CalendarPickerViewModelTests.swift */; };
Expand Down Expand Up @@ -274,6 +275,7 @@
34D19FBF262299D300B2732C /* NSEdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSEdgeInsets.swift; sourceTree = "<group>"; };
34D19FC52622A02C00B2732C /* EventDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventDetailsViewModelTests.swift; sourceTree = "<group>"; };
34D19FCB2622B9CC00B2732C /* EventMeta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMeta.swift; sourceTree = "<group>"; };
34D25E49292F9E2100557E70 /* ImageButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageButton.swift; sourceTree = "<group>"; };
34D55FE225F06669007F5C81 /* Sequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = "<group>"; };
34E004A625B61D5200241419 /* StatusItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItemViewModel.swift; sourceTree = "<group>"; };
34E1902225B76CFE00E9491B /* CalendarPickerViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarPickerViewModelTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -503,6 +505,7 @@
children = (
34CC382C25B636A6006CBD99 /* Checkbox.swift */,
341B2B3D25D06A6F00336342 /* Dropdown.swift */,
34D25E49292F9E2100557E70 /* ImageButton.swift */,
34F128D025968044007DF31C /* Label.swift */,
348E704A25C61B8D00B3B160 /* Radio.swift */,
341FAC5C292EFFFC0005F934 /* TextView.swift */,
Expand Down Expand Up @@ -847,6 +850,7 @@
3421DA212693F12400056837 /* Calendar+Factory.swift in Sources */,
34934CD628E69520009635D4 /* Prefs+UserDefaults.swift in Sources */,
34FD09D925AE269600AAAAE2 /* DateProvider.swift in Sources */,
34D25E4A292F9E2100557E70 /* ImageButton.swift in Sources */,
34AC60C626925FA5005312B6 /* PreviewExtensions.swift in Sources */,
3477F3CE25FAE56A008EA888 /* EventDetailsViewModel.swift in Sources */,
3487A43C25E70F5B00FCC7D7 /* NextEventView.swift in Sources */,
Expand Down
57 changes: 57 additions & 0 deletions Calendr/Components/ImageButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// ImageButton.swift
// Calendr
//
// Created by Paker on 24/11/2022.
//

import Cocoa

class ImageButton: NSButton {

private var trackingArea: NSTrackingArea?

init() {
super.init(frame: .zero)

isBordered = false
bezelStyle = .roundRect
refusesFirstResponder = true
showsBorderOnlyWhileMouseInside = true // this actually controls highlight ¯\_(ツ)_/¯
setContentCompressionResistancePriority(.required, for: .horizontal)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// 🔨 For some reason addCursorRect is not reliable,
// maybe because the container may clip the touch area and mess up
// the mouse enter detection, but to be honest I have no idea why
override func updateTrackingAreas() {

if let trackingArea = trackingArea {
removeTrackingArea(trackingArea)
}

trackingArea = NSTrackingArea(
rect: bounds,
options: [.cursorUpdate, .mouseMoved, .activeAlways],
owner: self
)

addTrackingArea(trackingArea!)

super.updateTrackingAreas()
}

override func cursorUpdate(with event: NSEvent) {
super.cursorUpdate(with: event)
NSCursor.pointingHand.set()
}

override func mouseMoved(with event: NSEvent) {
super.mouseMoved(with: event)
cursorUpdate(with: event)
}
}
7 changes: 1 addition & 6 deletions Calendr/Events/EventDetailsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class EventDetailsViewController: NSViewController, NSPopoverDelegate {
private let contentStackView = NSStackView(.vertical)
private let participantsStackView = NSStackView(.vertical)
private let detailsStackView = NSStackView(.vertical)
private let linkBtn = NSButton()
private let linkBtn = ImageButton()

private let titleLabel = Label()
private let urlLabel = Label()
Expand Down Expand Up @@ -191,11 +191,6 @@ class EventDetailsViewController: NSViewController, NSPopoverDelegate {
return
}

linkBtn.setContentCompressionResistancePriority(.required, for: .horizontal)
linkBtn.refusesFirstResponder = true
linkBtn.bezelStyle = .roundRect
linkBtn.isBordered = false

viewModel.isInProgress
.bind { [linkBtn] isInProgress in
if link.isMeeting {
Expand Down
6 changes: 1 addition & 5 deletions Calendr/Events/EventView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class EventView: NSView {
private let subtitle = Label()
private let duration = Label()
private let progress = NSView()
private let linkBtn = NSButton()
private let linkBtn = ImageButton()
private let hoverLayer = CALayer()
private let colorBar = NSView()

Expand Down Expand Up @@ -123,10 +123,6 @@ class EventView: NSView {
colorBar.layer?.cornerRadius = 2
colorBar.width(equalTo: 4)

linkBtn.setContentCompressionResistancePriority(.required, for: .horizontal)
linkBtn.refusesFirstResponder = true
linkBtn.bezelStyle = .roundRect
linkBtn.isBordered = false
linkBtn.width(equalTo: 22)

let titleStackView = NSStackView(views: [icon, title]).with(spacing: 4).with(alignment: .firstBaseline)
Expand Down
25 changes: 9 additions & 16 deletions Calendr/Main/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ class MainViewController: NSViewController {
private let calendarView: CalendarView
private let eventListView: EventListView
private let titleLabel = Label()
private let prevBtn = NSButton()
private let resetBtn = NSButton()
private let nextBtn = NSButton()
private let pinBtn = NSButton()
private let remindersBtn = NSButton()
private let calendarBtn = NSButton()
private let settingsBtn = NSButton()
private let prevBtn = ImageButton()
private let resetBtn = ImageButton()
private let nextBtn = ImageButton()
private let pinBtn = ImageButton()
private let remindersBtn = ImageButton()
private let calendarBtn = ImageButton()
private let settingsBtn = ImageButton()

// ViewModels
private let calendarViewModel: CalendarViewModel
Expand Down Expand Up @@ -476,19 +476,12 @@ class MainViewController: NSViewController {
return scrollView
}

private func styleButton(_ button: NSButton) {
button.size(equalTo: 22)
button.bezelStyle = .regularSquare
button.isBordered = false
button.refusesFirstResponder = true
}

private func makeHeader() -> NSView {

titleLabel.font = .systemFont(ofSize: 14, weight: .medium)
titleLabel.textColor = .headerTextColor

[prevBtn, resetBtn, nextBtn].forEach(styleButton)
[prevBtn, resetBtn, nextBtn].forEach { $0.size(equalTo: 22) }

prevBtn.image = Icons.Calendar.prev
resetBtn.image = Icons.Calendar.reset.with(scale: .small)
Expand All @@ -502,7 +495,7 @@ class MainViewController: NSViewController {

private func makeToolBar() -> NSView {

[pinBtn, remindersBtn, calendarBtn, settingsBtn].forEach(styleButton)
[pinBtn, remindersBtn, calendarBtn, settingsBtn].forEach { $0.size(equalTo: 22) }

pinBtn.setButtonType(.toggle)
pinBtn.image = Icons.Calendar.unpinned
Expand Down

0 comments on commit 2da90dd

Please sign in to comment.