Skip to content

Commit

Permalink
Merge pull request #485 from nangtrongvuon/bug_fixes/475-status-bar-r…
Browse files Browse the repository at this point in the history
…evamps

Status Bar Improvements
  • Loading branch information
nangtrongvuon committed Dec 17, 2019
2 parents 89b8739 + c424915 commit 915f6a6
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 70 deletions.
4 changes: 2 additions & 2 deletions Sources/XiEditor/ClientImplementation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class ClientImplementation: XiClient, DocumentsProviding, ConfigCacheProviding,
let document = documentForViewIdentifier(viewIdentifier: viewIdentifier)
DispatchQueue.main.async {
let newStatusItem = StatusItem(source, key, value, alignment)
document?.editViewController?.statusBar.addStatusItem(newStatusItem)
document?.editViewController?.addStatusItem(newStatusItem)
}
}

Expand All @@ -164,7 +164,7 @@ class ClientImplementation: XiClient, DocumentsProviding, ConfigCacheProviding,
func removeStatusItem(viewIdentifier: String, key: String) {
let document = documentForViewIdentifier(viewIdentifier: viewIdentifier)
DispatchQueue.main.async {
document?.editViewController?.statusBar.removeStatusItem(key)
document?.editViewController?.removeStatusItem(key)
}
}

Expand Down
14 changes: 3 additions & 11 deletions Sources/XiEditor/EditViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc
@IBOutlet weak var editContainerView: EditContainerView!
@IBOutlet var editView: EditView!
@IBOutlet weak var shadowView: ShadowView!

@IBOutlet weak var statusBar: StatusBar!

@IBOutlet weak var statusBarHeight: NSLayoutConstraint!
@IBOutlet weak var editViewHeight: NSLayoutConstraint!
@IBOutlet weak var editViewWidth: NSLayoutConstraint!

Expand Down Expand Up @@ -227,8 +229,6 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc

var hoverEvent: NSEvent?

let statusBar = StatusBar(frame: .zero)

// Popover that manages hover views.
lazy var infoPopover: NSPopover = {
let popover = NSPopover()
Expand Down Expand Up @@ -272,14 +272,6 @@ class EditViewController: NSViewController, EditViewDataSource, FindDelegate, Sc

func setupStatusBar() {
statusBar.hasUnifiedTitlebar = unifiedTitlebar
self.view.addSubview(statusBar)

NSLayoutConstraint.activate([
statusBar.heightAnchor.constraint(equalToConstant: statusBar.statusBarHeight),
statusBar.leadingAnchor.constraint(equalTo: editView.leadingAnchor),
statusBar.trailingAnchor.constraint(equalTo: editView.trailingAnchor),
statusBar.bottomAnchor.constraint(equalTo: editView.bottomAnchor)
])
}

func updateGutterWidth() {
Expand Down
33 changes: 22 additions & 11 deletions Sources/XiEditor/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand Down Expand Up @@ -61,27 +61,36 @@
</constraints>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="hEG-a6-BYd">
<rect key="frame" x="0.0" y="255" width="465" height="15"/>
<rect key="frame" x="0.0" y="231" width="465" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="O02-Lc-5gg" customClass="MarkerBar" customModule="XiEditor" customModuleProvider="target">
<rect key="frame" x="465" y="0.0" width="15" height="255"/>
<rect key="frame" x="465" y="0.0" width="15" height="231"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Tjs-fk-d3S" customClass="StatusBar" customModule="XiEditor" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="480" height="0.0"/>
<constraints>
<constraint firstAttribute="height" id="DO3-dq-Ibg"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstItem="x8W-KD-KOP" firstAttribute="leading" secondItem="q1P-kd-995" secondAttribute="leading" id="0m0-0O-Llk"/>
<constraint firstItem="x8W-KD-KOP" firstAttribute="top" secondItem="q1P-kd-995" secondAttribute="top" id="4lN-9b-wSx"/>
<constraint firstAttribute="trailing" secondItem="q1P-kd-995" secondAttribute="trailing" id="5IG-vx-2rb"/>
<constraint firstItem="Tjs-fk-d3S" firstAttribute="leading" secondItem="3ye-5b-Ab2" secondAttribute="leading" id="Cav-5o-0ue"/>
<constraint firstAttribute="bottom" secondItem="Tjs-fk-d3S" secondAttribute="bottom" id="F95-nZ-7H5"/>
<constraint firstItem="Qwv-ci-fVA" firstAttribute="leading" secondItem="q1P-kd-995" secondAttribute="leading" id="Pyq-kX-0wa"/>
<constraint firstItem="x8W-KD-KOP" firstAttribute="bottom" secondItem="q1P-kd-995" secondAttribute="bottom" id="Qak-2E-Fy6"/>
<constraint firstItem="Qwv-ci-fVA" firstAttribute="top" secondItem="q1P-kd-995" secondAttribute="top" id="Qwh-xz-kUZ"/>
<constraint firstItem="Qwv-ci-fVA" firstAttribute="bottom" secondItem="q1P-kd-995" secondAttribute="bottom" id="Sdy-8S-2NP"/>
<constraint firstItem="Tjs-fk-d3S" firstAttribute="top" secondItem="q1P-kd-995" secondAttribute="bottom" id="ZnH-DY-sje"/>
<constraint firstItem="x8W-KD-KOP" firstAttribute="trailing" secondItem="q1P-kd-995" secondAttribute="trailing" id="dL4-Ba-yMB"/>
<constraint firstItem="q1P-kd-995" firstAttribute="top" secondItem="3ye-5b-Ab2" secondAttribute="top" id="gHb-9s-5Ki"/>
<constraint firstItem="q1P-kd-995" firstAttribute="top" secondItem="3ye-5b-Ab2" secondAttribute="top" id="gWG-JW-SJf"/>
<constraint firstItem="q1P-kd-995" firstAttribute="leading" secondItem="3ye-5b-Ab2" secondAttribute="leading" id="kaS-IB-LV9"/>
<constraint firstAttribute="bottom" secondItem="q1P-kd-995" secondAttribute="bottom" id="ngA-1s-M67"/>
<constraint firstAttribute="trailing" secondItem="Tjs-fk-d3S" secondAttribute="trailing" id="kg5-PT-wI0"/>
<constraint firstItem="Qwv-ci-fVA" firstAttribute="trailing" secondItem="q1P-kd-995" secondAttribute="trailing" id="w93-aW-WKu"/>
</constraints>
</view>
Expand All @@ -92,6 +101,8 @@
<outlet property="editViewWidth" destination="1Gd-zC-FVY" id="DtT-d0-KdH"/>
<outlet property="scrollView" destination="Qwv-ci-fVA" id="4cE-10-pSP"/>
<outlet property="shadowView" destination="x8W-KD-KOP" id="mme-7Z-x1H"/>
<outlet property="statusBar" destination="Tjs-fk-d3S" id="MX5-p8-dzb"/>
<outlet property="statusBarHeight" destination="DO3-dq-Ibg" id="JwM-iA-km2"/>
<segue destination="9Ak-VM-8lJ" kind="modal" identifier="UserInputSegue" id="GqW-PV-ZCy"/>
</connections>
</viewController>
Expand Down Expand Up @@ -121,7 +132,7 @@ DQ
</connections>
</button>
<textField hidden="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Di9-5Q-3Ia">
<rect key="frame" x="20" y="20" width="275" height="22"/>
<rect key="frame" x="20" y="20" width="275" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="zlO-6u-liO">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
Expand All @@ -142,7 +153,7 @@ Gw
</connections>
</button>
<comboBox hidden="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AHD-SX-Tuj">
<rect key="frame" x="21" y="16" width="277" height="26"/>
<rect key="frame" x="21" y="16" width="277" height="25"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="nnP-RF-Vev">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
Expand Down Expand Up @@ -303,7 +314,7 @@ Gw
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<real value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
Expand Down Expand Up @@ -386,7 +397,7 @@ Gw
<rect key="frame" x="4" y="-1" width="32" height="19"/>
<buttonCell key="cell" type="roundRect" title="+" bezelStyle="roundedRect" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8uK-5I-cZg">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system" size="16"/>
<font key="font" metaFont="label" size="16"/>
</buttonCell>
<connections>
<action selector="addSearchField:" target="uoL-yg-E2H" id="0zi-0Z-ZCs"/>
Expand All @@ -396,7 +407,7 @@ Gw
<rect key="frame" x="38" y="-1" width="31" height="19"/>
<buttonCell key="cell" type="roundRect" title="-" bezelStyle="roundedRect" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0dQ-No-w5x">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system" size="16"/>
<font key="font" metaFont="label" size="16"/>
</buttonCell>
<connections>
<action selector="removeSearchField:" target="uoL-yg-E2H" id="9Wq-QC-w07"/>
Expand Down
92 changes: 47 additions & 45 deletions Sources/XiEditor/StatusBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ class StatusItem: NSTextField {
}

class StatusBar: NSView {

var currentItems = [String : StatusItem]()
var currentItems = [String: StatusItem]()
var hiddenItems: [StatusItem] {
return currentItems.values
.filter { $0.isHidden == true }
Expand All @@ -77,11 +76,12 @@ class StatusBar: NSView {

var hasUnifiedTitlebar: Bool?

var backgroundColor: NSColor = NSColor.windowBackgroundColor
var itemTextColor: NSColor = NSColor.labelColor
var borderColor: NSColor = NSColor.systemGray
var backgroundColor = NSColor.windowBackgroundColor
var itemTextColor = NSColor.labelColor
var borderColor = NSColor.systemGray

static let statusBarHeight: CGFloat = 20
let statusBarPadding: CGFloat = 10
let statusBarHeight: CGFloat = 24
let firstItemMargin: CGFloat = 5

// Difference (in points) to compensate for when status bar is resized
Expand All @@ -96,21 +96,12 @@ class StatusBar: NSView {
}

override var isFlipped: Bool {
return true;
}

override init(frame frameRect: NSRect) {
super.init(frame: .zero)
self.translatesAutoresizingMaskIntoConstraints = false
self.isHidden = true
updateStatusBarVisibility()
return true
}

@available(*, unavailable)
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
required init?(coder: NSCoder) {
super.init(coder: coder)
}

// Adds a status bar item.
func addStatusItem(_ item: StatusItem) {
if let existingItem = currentItems[item.key] {
Expand All @@ -123,7 +114,6 @@ class StatusBar: NSView {
currentItems[item.key] = item
self.needsUpdateConstraints = true
checkItemsFitFor(windowWidth: self.bounds.width)
updateStatusBarVisibility()
}

// Update a status bar item with a new value.
Expand All @@ -144,7 +134,6 @@ class StatusBar: NSView {
currentItems.removeValue(forKey: key)
self.needsUpdateConstraints = true
checkItemsFitFor(windowWidth: self.bounds.width)
updateStatusBarVisibility()
} else {
print("tried to remove item with \(key) that doesn't exist")
return
Expand All @@ -166,25 +155,21 @@ class StatusBar: NSView {
switch item.barAlignment {
case .left:
if item == leftItems.first {
let leftConstraint = item.leadingAnchor.constraint(equalTo:
self.leadingAnchor, constant: firstItemMargin)
let leftConstraint = item.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: firstItemMargin)
item.barConstraints.append(leftConstraint)
} else {
guard lastLeftItem != nil else { return }
let leftConstraint = item.leadingAnchor.constraint(equalTo:
lastLeftItem!.trailingAnchor, constant: statusBarPadding)
let leftConstraint = item.leadingAnchor.constraint(equalTo: lastLeftItem!.trailingAnchor, constant: statusBarPadding)
item.barConstraints.append(leftConstraint)
}
lastLeftItem = item
case .right:
if item == rightItems.first {
let rightConstraint = item.trailingAnchor.constraint(equalTo:
self.trailingAnchor, constant: -firstItemMargin)
let rightConstraint = item.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -firstItemMargin)
item.barConstraints.append(rightConstraint)
} else {
guard lastRightItem != nil else { return }
let rightConstraint = item.trailingAnchor.constraint(equalTo:
lastRightItem!.leadingAnchor, constant: -statusBarPadding)
let rightConstraint = item.trailingAnchor.constraint(equalTo: lastRightItem!.leadingAnchor, constant: -statusBarPadding)
item.barConstraints.append(rightConstraint)
}
lastRightItem = item
Expand Down Expand Up @@ -215,22 +200,6 @@ class StatusBar: NSView {
self.needsDisplay = true
}

// Shows/hides the statusbar based on whether it has any contents.
func updateStatusBarVisibility() {
if !currentItems.isEmpty {
self.hideTimer?.invalidate()
self.isHidden = false
} else if !self.isHidden {
// Wait a moment before hiding the bar to avoid blinking in the case
// that a single item is added and removed repeatedly in rapid succession.
if #available(OSX 10.12, *) {
hideTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in self.isHidden = true }
} else {
self.isHidden = true
}
}
}

// When items are added, expanded or removed, the status bar checks if
// any items need to be hidden or unhidden to make use of available space.
func checkItemsFitFor(windowWidth: CGFloat) {
Expand Down Expand Up @@ -285,5 +254,38 @@ class StatusBar: NSView {
path.line(to: CGPoint(x: dirtyRect.maxX, y: dirtyRect.minY))
path.stroke()
}
}

extension EditViewController {
func addStatusItem(_ item: StatusItem) {
self.statusBar.addStatusItem(item)
self.updateStatusBarVisibility()
}

func removeStatusItem(_ key: String) {
self.statusBar.removeStatusItem(key)
self.updateStatusBarVisibility()
}

// Shows/hides the statusbar based on whether it has any contents.
func updateStatusBarVisibility() {
if !statusBar.currentItems.isEmpty {
self.showStatusBar()
} else if statusBarHeight.constant > 0 {
// If status bar is currently showing, hide it after a delay.
Timer.scheduledTimer(timeInterval: 1.0,
target: self,
selector: #selector(hideStatusBar),
userInfo: nil,
repeats: false)
}
}

private func showStatusBar() {
statusBarHeight.constant = StatusBar.statusBarHeight
}

@objc private func hideStatusBar() {
statusBarHeight.constant = 0
}
}

0 comments on commit 915f6a6

Please sign in to comment.