Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
48b0aea
properly name `utilityAreaViewModel` across the project
plbstl May 12, 2024
8c8aad3
add article docs for `CodeEdit/UtilityAreaView`
plbstl May 12, 2024
8f89c21
update article docs for `CodeEdit/StatusBarView`
plbstl May 12, 2024
1a84281
properly name items in `CodeEdit/Features/UtilityArea/Toolbar`
plbstl May 12, 2024
9000664
remove UtilityAreaViewModel properties from status bar implementation
plbstl May 12, 2024
fe5c5bb
remove unused properties in `UtilityAreaViewModel`
plbstl May 12, 2024
cd8082e
delete `CursorLocation` model
plbstl May 12, 2024
6467f88
rename `StatusBarCursorLocationLabel` to `StatusBarCursorPositionLabel`
plbstl May 12, 2024
71d30f7
add `StatusBarViewModel`
plbstl May 12, 2024
60a2e65
show non-text file info in the status bar
plbstl May 12, 2024
d83152a
fix unpredictable image dimensions in status bar
plbstl May 12, 2024
20837cb
add UpdateStatusBarInfo view modifier to clean up implementation
plbstl May 12, 2024
c3f2138
move the `NonTextFileView.onDisappear` modifier to inside the view
plbstl May 12, 2024
9b03181
change `StatusBarViewModel.dimensions` from tuple to struct
plbstl May 12, 2024
a5938ea
refactor `StatusBarFileInfoView`
plbstl May 12, 2024
c63d0ef
fix SwiftLint violation
plbstl May 13, 2024
cfd410c
minor doc change in `UpdateStatusBarInfo`
plbstl May 13, 2024
773990c
remove unused editor variable in `UpdateStatusBarInfo`
plbstl May 13, 2024
a648652
refactor
plbstl May 13, 2024
7627aa6
Update CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarFile…
austincondiff May 16, 2024
817778f
Merge branch 'main' into show-file-info-in-status-bar
plbstl May 17, 2024
dcc3dba
properly resolve merge conflict
plbstl May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 60 additions & 32 deletions CodeEdit.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
WorkspaceView()
.environmentObject(workspace)
.environmentObject(workspace.editorManager)
.environmentObject(workspace.statusBarViewModel)
.environmentObject(workspace.utilityAreaModel)
}
}
Expand Down
1 change: 1 addition & 0 deletions CodeEdit/Features/Documents/WorkspaceDocument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {
}
}

var statusBarViewModel = StatusBarViewModel()
var utilityAreaModel = UtilityAreaViewModel()
var searchState: SearchState?
var quickOpenViewModel: QuickOpenViewModel?
Expand Down
1 change: 0 additions & 1 deletion CodeEdit/Features/Editor/Views/EditorAreaFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import SwiftUI
struct EditorAreaFileView: View {

@EnvironmentObject private var editorManager: EditorManager

@EnvironmentObject private var editor: Editor

@Environment(\.edgeInsets)
Expand Down
1 change: 1 addition & 0 deletions CodeEdit/Features/Editor/Views/ImageFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct ImageFileView: View {
maxWidth: min(pixelWidth, proxy.size.width, nsImage.size.width),
maxHeight: min(pixelHeight, proxy.size.height, nsImage.size.height)
)

}
.frame(width: proxy.size.width, height: proxy.size.height)
}
Expand Down
36 changes: 24 additions & 12 deletions CodeEdit/Features/Editor/Views/NonTextFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,38 @@ struct NonTextFileView: View {
/// The file document you wish to open.
let fileDocument: CodeFileDocument

@EnvironmentObject private var editorManager: EditorManager
@EnvironmentObject private var statusBarViewModel: StatusBarViewModel

var body: some View {

if let fileURL = fileDocument.fileURL {
Group {
if let fileURL = fileDocument.fileURL {

switch fileDocument.utType {
case .some(.image):
ImageFileView(fileURL)
switch fileDocument.utType {
case .some(.image):
ImageFileView(fileURL)
.modifier(UpdateStatusBarInfo(withURL: fileURL))

case .some(.pdf):
PDFFileView(fileURL)
case .some(.pdf):
PDFFileView(fileURL)
.modifier(UpdateStatusBarInfo(withURL: fileURL))

default:
AnyFileView(fileURL)
}
default:
AnyFileView(fileURL)
.modifier(UpdateStatusBarInfo(withURL: fileURL))
}

} else {
ZStack {
Text("Cannot retrieve URL to the file you opened.")
} else {
ZStack {
Text("Cannot retrieve URL to the file you opened.")
}
}
}
.onDisappear {
statusBarViewModel.dimensions = nil
statusBarViewModel.fileSize = nil
}

}
}
18 changes: 0 additions & 18 deletions CodeEdit/Features/StatusBar/Models/CursorLocation.swift

This file was deleted.

14 changes: 14 additions & 0 deletions CodeEdit/Features/StatusBar/Models/ImageDimensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// ImageDimensions.swift
// CodeEdit
//
// Created by Paul Ebose on 2024/5/13.
//

import Foundation

/// Helper struct used to store the (width x height) of the currently opened image.
struct ImageDimensions {
var width: Int
var height: Int
}
27 changes: 27 additions & 0 deletions CodeEdit/Features/StatusBar/ViewModels/StatusBarViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// StatusBarViewModel.swift
// CodeEdit
//
// Created by Paul Ebose on 2024/5/12.
//

import SwiftUI

final class StatusBarViewModel: ObservableObject {

/// The file size of the currently opened file.
@Published var fileSize: Int?

/// The dimensions (width x height) of the currently opened image.
@Published var dimensions: ImageDimensions?

/// Indicates whether the breakpoint is enabled or not.
@Published var isBreakpointEnabled = true

/// The font style of items shown in the status bar.
private(set) var statusBarFont = Font.system(size: 11, weight: .medium)

/// The color of the text shown in the status bar.
private(set) var foregroundStyle = Color.secondary

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// UpdateStatusBarInfo.swift
// CodeEdit
//
// Created by Paul Ebose on 2024/5/12.
//

import SwiftUI

/// Updates ``StatusBarFileInfoView``'s `fileSize` and `dimensions`.
/// ```swift
/// FileView
/// .modifier(UpdateStatusBarInfo(withURL))
/// ```
struct UpdateStatusBarInfo: ViewModifier {

/// The URL of the file to compute information from.
let withURL: URL

@EnvironmentObject private var editorManager: EditorManager
@EnvironmentObject private var statusBarViewModel: StatusBarViewModel

/// This is returned by ``UpdateStatusBarInfo`` `.computeStatusBarInfo`.
private struct ComputedStatusBarInfo {
let fileSize: Int
let dimensions: ImageDimensions?
}

/// Compute information that can be used to update properties in ``StatusBarFileInfoView``.
/// - Parameter url: URL of the file to compute information from.
/// - Returns: The file size and its image dimensions (if any).
private func computeStatusBarInfo(url: URL) -> ComputedStatusBarInfo? {
guard let resourceValues = try? url.resourceValues(forKeys: [.contentTypeKey, .fileSizeKey]),
let contentType = resourceValues.contentType,
let fileSize = resourceValues.fileSize
else {
return nil
}

if contentType.conforms(to: .image), let imageReps = NSImage(contentsOf: url)?.representations.first {
let dimensions = ImageDimensions(width: imageReps.pixelsWide, height: imageReps.pixelsHigh)
return ComputedStatusBarInfo(fileSize: fileSize, dimensions: dimensions)
} else { // non-image file
return ComputedStatusBarInfo(fileSize: fileSize, dimensions: nil)
}
}

func body(content: Content) -> some View {
content
.onAppear {
let statusBarInfo = computeStatusBarInfo(url: withURL)
statusBarViewModel.fileSize = statusBarInfo?.fileSize
statusBarViewModel.dimensions = statusBarInfo?.dimensions
}
.onChange(of: editorManager.activeEditor.selectedTab) { newTab in
guard let newTab else { return }
let statusBarInfo = computeStatusBarInfo(url: newTab.file.url)
statusBarViewModel.fileSize = statusBarInfo?.fileSize
statusBarViewModel.dimensions = statusBarInfo?.dimensions
}
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// StatusBarBreakpointButton.swift
// CodeEditModules/StatusBar
// CodeEdit
//
// Created by Stef Kors on 14/04/2022.
//
Expand All @@ -9,13 +9,13 @@ import SwiftUI
import CodeEditSymbols

struct StatusBarBreakpointButton: View {
@EnvironmentObject private var model: UtilityAreaViewModel
@EnvironmentObject private var statusBarViewModel: StatusBarViewModel

var body: some View {
Button {
model.isBreakpointEnabled.toggle()
statusBarViewModel.isBreakpointEnabled.toggle()
} label: {
if model.isBreakpointEnabled {
if statusBarViewModel.isBreakpointEnabled {
Image.breakpointFill
.foregroundColor(.accentColor)
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
//
// StatusBarCursorLocationLabel.swift
// CodeEditModules/StatusBar
// StatusBarCursorPositionLabel.swift
// CodeEdit
//
// Created by Lukas Pistrol on 22.03.22.
//

import SwiftUI
import CodeEditSourceEditor

struct StatusBarCursorLocationLabel: View {
struct StatusBarCursorPositionLabel: View {
@Environment(\.controlActiveState)
private var controlActive
@Environment(\.modifierKeys)
private var modifierKeys

@EnvironmentObject private var model: UtilityAreaViewModel
@EnvironmentObject private var statusBarViewModel: StatusBarViewModel
@EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel
@EnvironmentObject private var editorManager: EditorManager

@State private var tab: EditorInstance?
Expand Down Expand Up @@ -87,7 +88,7 @@ struct StatusBarCursorLocationLabel: View {
EmptyView()
}
}
.font(model.toolbarFont)
.font(statusBarViewModel.statusBarFont)
.foregroundColor(foregroundColor)
.fixedSize()
.lineLimit(1)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// StatusBarFileInfoView.swift
// CodeEdit
//
// Created by Paul Ebose on 2024/5/12.
//

import SwiftUI

/// Shows media information about the currently opened file.
///
/// This currently shows the file size and image dimensions, if available.
struct StatusBarFileInfoView: View {

@EnvironmentObject private var statusBarViewModel: StatusBarViewModel

private let dimensionsNumberStyle = IntegerFormatStyle<Int>(locale: Locale(identifier: "en_US")).grouping(.never)

var body: some View {

HStack(spacing: 15) {

if let dimensions = statusBarViewModel.dimensions {
let width = dimensionsNumberStyle.format(dimensions.width)
let height = dimensionsNumberStyle.format(dimensions.height)

Text("\(width) × \(height)")
}

if let fileSize = statusBarViewModel.fileSize {
Text(fileSize.formatted(.byteCount(style: .memory)))
}

}
.font(statusBarViewModel.statusBarFont)
.foregroundStyle(statusBarViewModel.foregroundStyle)
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// StatusBarToggleUtilityAreaButton.swift
// CodeEditModules/StatusBar
// CodeEdit
//
// Created by Lukas Pistrol on 22.03.22.
//
Expand All @@ -11,25 +11,25 @@ internal struct StatusBarToggleUtilityAreaButton: View {
@Environment(\.controlActiveState)
var controlActiveState

@EnvironmentObject private var model: UtilityAreaViewModel
@EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel

internal var body: some View {
Button {
model.togglePanel()
utilityAreaViewModel.togglePanel()
} label: {
Image(systemName: "square.bottomthird.inset.filled")
}
.buttonStyle(.icon)
.keyboardShortcut("Y", modifiers: [.command, .shift])
.help(model.isCollapsed ? "Show the Utility area" : "Hide the Utility area")
.help(utilityAreaViewModel.isCollapsed ? "Show the Utility area" : "Hide the Utility area")
.onHover { isHovering($0) }
.onChange(of: controlActiveState) { newValue in
if newValue == .key {
CommandManager.shared.addCommand(
name: "Toggle Utility Area",
title: "Toggle Utility Area",
id: "open.drawer",
command: CommandClosureWrapper.init(closure: model.togglePanel)
command: CommandClosureWrapper.init(closure: utilityAreaViewModel.togglePanel)
)
}
}
Expand All @@ -38,7 +38,7 @@ internal struct StatusBarToggleUtilityAreaButton: View {
name: "Toggle Utility Area",
title: "Toggle Utility Area",
id: "open.drawer",
command: CommandClosureWrapper.init(closure: model.togglePanel)
command: CommandClosureWrapper.init(closure: utilityAreaViewModel.togglePanel)
)
}
}
Expand Down
11 changes: 6 additions & 5 deletions CodeEdit/Features/StatusBar/Views/StatusBarView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// StatusBarView.swift
// CodeEditModules/StatusBar
// CodeEdit
//
// Created by Lukas Pistrol on 19.03.22.
//
Expand All @@ -11,7 +11,9 @@ import SwiftUI
///
/// A View that lives on the bottom of the window and offers information
/// about compilation errors/warnings, git, cursor position in text,
/// indentation width (in spaces), text encoding and linebreak
/// indentation width (in spaces), text encoding and linebreak.
///
/// Also information about the file size and dimensions, if available.
///
/// Additionally it offers a togglable/resizable drawer which can
/// host a terminal or additional debug information
Expand All @@ -20,8 +22,6 @@ struct StatusBarView: View {
@Environment(\.controlActiveState)
private var controlActive

@EnvironmentObject private var model: UtilityAreaViewModel

static let height = 28.0

@Environment(\.colorScheme)
Expand All @@ -37,8 +37,9 @@ struct StatusBarView: View {
// StatusBarBreakpointButton()
// StatusBarDivider()
Spacer()
StatusBarFileInfoView()
HStack(alignment: .center, spacing: 10) {
StatusBarCursorLocationLabel()
StatusBarCursorPositionLabel()
}
StatusBarDivider()
StatusBarToggleUtilityAreaButton()
Expand Down
Loading