Fix sidebar behavior

This commit is contained in:
1024jp 2016-09-24 19:25:50 +09:00
parent 8a51465356
commit 24fec1dd48
5 changed files with 86 additions and 29 deletions

View File

@ -8,6 +8,7 @@ develop
### Improvements
- Enable Autosave and Versions by default.
- [beta] Improve sideview behavior.
### Fixes

View File

@ -236,15 +236,12 @@
<objects>
<tabViewController showSeguePresentationStyle="single" tabStyle="unspecified" id="7te-2x-zAq" customClass="SidebarViewController" customModule="CotEditor" customModuleProvider="target" sceneMemberID="viewController">
<viewControllerTransitionOptions key="transitionOptions" allowUserInteraction="YES"/>
<tabView key="tabView" misplaced="YES" id="wzn-c5-29x" customClass="InspectorTabView" customModule="CotEditor" customModuleProvider="target">
<tabView key="tabView" misplaced="YES" type="noTabsNoBorder" id="wzn-c5-29x" customClass="InspectorTabView" customModule="CotEditor" customModuleProvider="target">
<rect key="frame" x="252" y="0.0" width="200" height="300"/>
<autoresizingMask key="autoresizingMask"/>
<font key="font" metaFont="message"/>
<tabViewItems/>
</tabView>
<connections>
<outlet property="view" destination="wzn-c5-29x" id="9lx-vQ-Qu5"/>
</connections>
</tabViewController>
<customObject id="u7b-LP-b38" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>

View File

@ -29,9 +29,13 @@ import Cocoa
final class InspectorTabView: NSTabView {
// MARK: Public Properties
let segmentedControl = NSSegmentedControl()
// MARK: Private Properties
private let segmentedControl = NSSegmentedControl()
private let ControlHeight: CGFloat = 28.0
@ -49,9 +53,6 @@ final class InspectorTabView: NSTabView {
self.segmentedControl.cell = SwitcherSegmentedCell()
self.segmentedControl.segmentStyle = .texturedSquare
self.segmentedControl.frame.origin.y = floor((self.ControlHeight - self.segmentedControl.intrinsicContentSize.height) / 2)
self.segmentedControl.wantsLayer = true
self.segmentedControl.action = #selector(InspectorTabView.selectTabViewItemWithSegmentedControl)
self.segmentedControl.target = self
self.addSubview(self.segmentedControl)
self.rebuildSegmentedControl()
@ -131,13 +132,6 @@ final class InspectorTabView: NSTabView {
// MARK: Private Methods
/// switch tab from the private control
func selectTabViewItemWithSegmentedControl(_ sender: NSSegmentedControl) {
super.selectTabViewItem(at: sender.selectedSegment)
}
/// update selection of the private control
private func invalidateControlSelection() {

View File

@ -27,6 +27,12 @@
import Cocoa
protocol TabViewControllerDelegate: class {
func tabViewController(_ viewController: NSTabViewController, didSelect tabViewIndex: Int)
}
final class SidebarViewController: NSTabViewController {
enum TabIndex: Int {
@ -35,6 +41,13 @@ final class SidebarViewController: NSTabViewController {
case incompatibleCharacters
}
// MARK: Public Properties
weak var delegate: TabViewControllerDelegate?
var selectedTabIndex: TabIndex { return TabIndex(rawValue: self.selectedTabViewItemIndex) ?? .documentInspector }
// MARK: Private Properties
private weak var documentInspectorTabViewItem: NSTabViewItem?
@ -63,6 +76,11 @@ final class SidebarViewController: NSTabViewController {
self.documentInspectorTabViewItem = documentInspectorTabViewItem
self.incompatibleCharactersTabViewItem = incompatibleCharactersTabViewItem
// bind segmentedControl manually (2016-09 on macOS 10.12)
if let segmentedControl = (self.tabView as? InspectorTabView)?.segmentedControl {
segmentedControl.bind(NSSelectedIndexBinding, to: self, withKeyPath: #keyPath(selectedTabViewItemIndex))
}
}
@ -77,4 +95,12 @@ final class SidebarViewController: NSTabViewController {
}
}
override var selectedTabViewItemIndex: Int {
didSet {
self.delegate?.tabViewController(self, didSelect: self.selectedTabViewItemIndex)
}
}
}

View File

@ -27,10 +27,12 @@
import Cocoa
final class WindowContentViewController: NSSplitViewController {
final class WindowContentViewController: NSSplitViewController, TabViewControllerDelegate {
// MARK: Private Properties
private var isSynchronizingTabs = false
@IBOutlet private weak var documentViewItem: NSSplitViewItem?
@IBOutlet private weak var sidebarViewItem: NSSplitViewItem?
@ -60,6 +62,8 @@ final class WindowContentViewController: NSSplitViewController {
self.isSidebarShown = Defaults[.showDocumentInspector]
self.sidebarThickness = Defaults[.sidebarWidth]
self.sidebarViewController?.delegate = self
}
@ -72,8 +76,8 @@ final class WindowContentViewController: NSSplitViewController {
// adjust sidebar visibility if this new window was just added to an existing window
if let other = self.siblings.first(where: { $0 != self }) {
self.isSidebarShown = other.isSidebarShown
self.sidebarThickness = other.sidebarThickness
self.setSidebarShown(other.isSidebarShown, index: other.sidebarViewController!.selectedTabIndex)
}
}
@ -104,8 +108,26 @@ final class WindowContentViewController: NSSplitViewController {
}
}
// MARK: Sidebar View Controller Delegate
/// synchronize sidebar pane among window tabs
func tabViewController(_ viewController: NSTabViewController, didSelect tabViewIndex: Int) {
guard !self.isSynchronizingTabs else { return }
self.isSynchronizingTabs = true
self.siblings.lazy
.filter { $0 != self }
.forEach { $0.sidebarViewController?.selectedTabViewItemIndex = tabViewIndex }
self.isSynchronizingTabs = false
}
// MARK: Public Methods
/// deliver editor to outer view controllers
@ -118,8 +140,7 @@ final class WindowContentViewController: NSSplitViewController {
/// display desired sidebar pane
func showSidebarPane(index: SidebarViewController.TabIndex) {
self.sidebarViewController?.tabView.selectTabViewItem(at: index.rawValue)
self.sidebarViewItem?.animator().isCollapsed = false
self.setSidebarShown(true, index: index, animate: true)
}
@ -144,9 +165,9 @@ final class WindowContentViewController: NSSplitViewController {
// MARK: Private Methods
/// split view item to view controller
private var sidebarViewController: NSTabViewController? {
private var sidebarViewController: SidebarViewController? {
return self.sidebarViewItem?.viewController as? NSTabViewController
return self.sidebarViewItem?.viewController as? SidebarViewController
}
@ -169,22 +190,40 @@ final class WindowContentViewController: NSSplitViewController {
return !(self.sidebarViewItem?.isCollapsed ?? true)
}
set {
// update current tab possibly with an animation
self.sidebarViewItem?.isCollapsed = !newValue
// and then update background tabs
self.siblings.lazy
.filter { $0 != self }
.forEach { $0.sidebarViewItem?.isCollapsed = !newValue }
}
}
/// set visibility and tab of sidebar
private func setSidebarShown(_ shown: Bool, index: SidebarViewController.TabIndex? = nil, animate: Bool = false) {
if let index = index {
self.siblings.forEach { sibling in
sibling.sidebarViewItem?.isCollapsed = !newValue
sibling.sidebarViewController!.selectedTabViewItemIndex = index.rawValue
}
}
if animate { NSAnimationContext.current().allowsImplicitAnimation = true }
self.isSidebarShown = shown
if animate { NSAnimationContext.current().allowsImplicitAnimation = false }
}
/// toggle visibility of pane in sidebar
private func toggleVisibilityOfSidebarTabItem(index: SidebarViewController.TabIndex) {
let isCollapsed = self.isSidebarShown && (index.rawValue == self.sidebarViewController!.selectedTabViewItemIndex)
let shown = !self.isSidebarShown || (index.rawValue != self.sidebarViewController!.selectedTabViewItemIndex)
self.siblings.forEach { sibling in
sibling.sidebarViewController!.selectedTabViewItemIndex = index.rawValue
sibling.sidebarViewItem!.animator().isCollapsed = isCollapsed
}
self.setSidebarShown(shown, index: index, animate: true)
}