Skip to content

Commit f491963

Browse files
Styling updates
1 parent 3529374 commit f491963

File tree

3 files changed

+48
-43
lines changed

3 files changed

+48
-43
lines changed

CodeEdit/Features/NavigatorArea/IssueNavigator/OutlineView/IssueNavigatorViewController+NSOutlineViewDelegate.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ extension IssueNavigatorViewController: NSOutlineViewDelegate {
3636

3737
func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
3838
if item is DiagnosticIssueNode {
39+
// TODO: DIAGNOSTIC CELLS SHOULD MIGHT SPAN MULTIPLE ROWS, SO SHOW MULTIPLE LINES
3940
let lines = Double(Settings.shared.preferences.general.issueNavigatorDetail.rawValue)
4041
return rowHeight * lines
4142
}

CodeEdit/Features/NavigatorArea/OutlineView/IssueTableViewCell.swift

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@
55
// Created by Abe Malla on 3/16/25.
66
//
77

8-
import SwiftUI
98
import AppKit
109

1110
class IssueTableViewCell: StandardTableViewCell {
1211

1312
private var nodeIconView: NSImageView?
14-
private var detailLabel: NSTextField?
1513

1614
var issueNode: (any IssueNode)?
1715

@@ -24,60 +22,62 @@ class IssueTableViewCell: StandardTableViewCell {
2422
super.init(frame: frameRect, isEditable: isEditable)
2523
self.issueNode = node
2624

27-
secondaryLabelRightAligned = false
2825
configureForNode(node)
2926
}
3027

3128
override func configLabel(label: NSTextField, isEditable: Bool) {
3229
super.configLabel(label: label, isEditable: isEditable)
33-
label.lineBreakMode = .byTruncatingTail
34-
}
3530

36-
override func createIcon() -> NSImageView {
37-
let icon = super.createIcon()
38-
if let diagnosticNode = issueNode as? DiagnosticIssueNode {
39-
icon.contentTintColor = diagnosticNode.severityColor
31+
if issueNode is DiagnosticIssueNode {
32+
label.maximumNumberOfLines = 4
33+
label.lineBreakMode = .byTruncatingTail
34+
label.cell?.wraps = true
35+
label.cell?.isScrollable = false
36+
label.preferredMaxLayoutWidth = frame.width - iconWidth - 20
37+
} else {
38+
label.lineBreakMode = .byTruncatingTail
4039
}
41-
return icon
40+
}
41+
42+
override func configSecondaryLabel(secondaryLabel: NSTextField) {
43+
super.configSecondaryLabel(secondaryLabel: secondaryLabel)
44+
secondaryLabel.font = .systemFont(ofSize: fontSize-2, weight: .medium)
4245
}
4346

4447
func configureForNode(_ node: (any IssueNode)?) {
4548
guard let node = node else { return }
4649

50+
secondaryLabelRightAligned = true
4751
textField?.stringValue = node.name
4852

49-
if let fileIssueNode = node as? FileIssueNode {
53+
if let projectIssueNode = node as? ProjectIssueNode {
54+
imageView?.image = projectIssueNode.nsIcon
55+
imageView?.contentTintColor = NSColor.folderBlue
56+
} else if let fileIssueNode = node as? FileIssueNode {
5057
imageView?.image = fileIssueNode.nsIcon
58+
if Settings.shared.preferences.general.fileIconStyle == .color {
59+
imageView?.contentTintColor = NSColor(fileIssueNode.iconColor)
60+
} else {
61+
imageView?.contentTintColor = NSColor.coolGray
62+
}
5163
} else if let diagnosticNode = node as? DiagnosticIssueNode {
52-
imageView?.image = diagnosticNode.icon
64+
imageView?.image = diagnosticNode.nsIcon
65+
.withSymbolConfiguration(
66+
NSImage.SymbolConfiguration(paletteColors: [.white, diagnosticNode.severityColor])
67+
)
5368
imageView?.contentTintColor = diagnosticNode.severityColor
5469
}
5570

56-
if let diagnosticNode = node as? DiagnosticIssueNode {
57-
setupDetailLabel(with: diagnosticNode.locationString)
58-
} else if let projectNode = node as? ProjectIssueNode {
71+
if let projectNode = node as? ProjectIssueNode {
5972
let issuesCount = projectNode.errorCount + projectNode.warningCount
6073

6174
if issuesCount > 0 {
75+
secondaryLabelRightAligned = false
6276
secondaryLabel?.stringValue = "\(issuesCount) issues"
6377
}
6478
}
6579
}
6680

67-
private func setupDetailLabel(with text: String) {
68-
detailLabel?.removeFromSuperview()
69-
70-
let detail = NSTextField(labelWithString: text)
71-
detail.translatesAutoresizingMaskIntoConstraints = false
72-
detail.drawsBackground = false
73-
detail.isBordered = false
74-
detail.font = .systemFont(ofSize: fontSize-2)
75-
detail.textColor = .secondaryLabelColor
76-
77-
addSubview(detail)
78-
detailLabel = detail
79-
}
80-
8181
/// Returns the font size for the current row height. Defaults to `13.0`
8282
private var fontSize: Double {
8383
switch self.frame.height {

CodeEdit/Features/NavigatorArea/ViewModels/IssueNavigatorViewModel.swift

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,19 @@ protocol IssueNode: Identifiable, Hashable {
163163
var id: UUID { get }
164164
var name: String { get }
165165
var isExpandable: Bool { get }
166+
var nsIcon: NSImage { get }
166167
}
167168

168169
/// Represents the project (root) node in the issue navigator
169170
class ProjectIssueNode: IssueNode, ObservableObject {
170171
let id: UUID = UUID()
171172
let name: String
173+
172174
@Published var files: [FileIssueNode]
173175
@Published var isExpanded: Bool
174176

175-
var icon: Image {
176-
Image(systemName: "folder")
177+
var nsIcon: NSImage {
178+
return NSImage(systemSymbolName: "folder.fill.badge.gearshape", accessibilityDescription: "Root folder")!
177179
}
178180

179181
var isExpandable: Bool {
@@ -212,35 +214,37 @@ class FileIssueNode: IssueNode, ObservableObject {
212214
let id: UUID = UUID()
213215
let uri: DocumentUri
214216
let name: String
217+
215218
@Published var diagnostics: [DiagnosticIssueNode]
216219
@Published var isExpanded: Bool
217220

218221
/// Returns the extension of the file or an empty string if no extension is present.
219222
var type: FileIcon.FileType {
220-
let filename = (uri as NSString).pathExtension
221-
let fileExtension = (filename as NSString).pathExtension.lowercased()
222-
223+
let fileExtension = (uri as NSString).pathExtension.lowercased()
223224
if !fileExtension.isEmpty {
224225
if let type = FileIcon.FileType(rawValue: fileExtension) {
225226
return type
226227
}
227228
}
228-
if let type = FileIcon.FileType(rawValue: filename.lowercased()) {
229-
return type
230-
}
231229
return .txt
232230
}
233231

234-
/// Return the icon of the file as `Image`
235-
var icon: Image {
236-
return Image(systemName: FileIcon.fileIcon(fileType: type))
232+
/// Returns a `Color` for a specific `fileType`
233+
///
234+
/// If not specified otherwise this will return `Color.accentColor`
235+
var iconColor: SwiftUI.Color {
236+
FileIcon.iconColor(fileType: type)
237237
}
238238

239239
/// Return the icon of the file as `NSImage`
240240
var nsIcon: NSImage {
241241
let systemImage = FileIcon.fileIcon(fileType: type)
242-
return NSImage(systemSymbolName: systemImage, accessibilityDescription: systemImage)
243-
?? NSImage(systemSymbolName: "doc", accessibilityDescription: "doc")!
242+
if let customImage = NSImage.symbol(named: systemImage) {
243+
return customImage
244+
} else {
245+
return NSImage(systemSymbolName: systemImage, accessibilityDescription: systemImage)
246+
?? NSImage(systemSymbolName: "doc", accessibilityDescription: "doc")!
247+
}
244248
}
245249

246250
var isExpandable: Bool {
@@ -285,7 +289,7 @@ class DiagnosticIssueNode: IssueNode, ObservableObject {
285289
false
286290
}
287291

288-
var icon: NSImage {
292+
var nsIcon: NSImage {
289293
switch diagnostic.severity {
290294
case .error:
291295
return NSImage(systemSymbolName: "exclamationmark.octagon.fill", accessibilityDescription: "")!

0 commit comments

Comments
 (0)