Add edited indicator to window tab (close #904)

This commit is contained in:
1024jp 2022-06-28 01:36:37 +09:00
parent 8af486506c
commit 7796fed581
13 changed files with 91 additions and 11 deletions

View File

@ -5,6 +5,11 @@ Change Log
4.4.0 (unreleased)
--------------------------
### New Features
- Display a dot in the window tab if the document has unsaved changes.
### Improvements
- Change the system requirement to __macOS 12 Moneterey and later__.

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="Lgm-sL-YIF">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -169,15 +168,17 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView toolTip="This style is customized." translatesAutoresizingMaskIntoConstraints="NO" id="cbJ-XK-bnG" customClass="DotView" customModule="CotEditor" customModuleProvider="target">
<rect key="frame" x="5" y="4" width="4" height="4"/>
<rect key="frame" x="0.0" y="0.0" width="16" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="KbQ-uH-zf8"/>
<constraint firstAttribute="width" secondItem="cbJ-XK-bnG" secondAttribute="height" multiplier="1:1" id="ZE1-ZW-sTB"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="color">
<color key="value" name="tertiaryLabelColor" catalog="System" colorSpace="catalog"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="dotLength">
<real key="value" value="4"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<binding destination="9MN-yG-hHM" name="hidden" keyPath="objectValue.state" id="uBD-Ia-4YK">
@ -188,7 +189,7 @@
</connections>
</customView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="B3Y-Nj-FSx">
<rect key="frame" x="12" y="0.0" width="265" height="16"/>
<rect key="frame" x="14" y="0.0" width="263" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="7hV-jt-xSx">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -201,11 +202,12 @@
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="B3Y-Nj-FSx" secondAttribute="bottom" id="4bc-8w-fDr"/>
<constraint firstItem="cbJ-XK-bnG" firstAttribute="centerY" secondItem="9MN-yG-hHM" secondAttribute="centerY" constant="2" id="6NR-Dc-qjR"/>
<constraint firstItem="B3Y-Nj-FSx" firstAttribute="top" secondItem="9MN-yG-hHM" secondAttribute="top" id="JKi-hq-c4N"/>
<constraint firstItem="B3Y-Nj-FSx" firstAttribute="leading" secondItem="cbJ-XK-bnG" secondAttribute="trailing" constant="5" id="Rvk-hT-fMi"/>
<constraint firstItem="cbJ-XK-bnG" firstAttribute="leading" secondItem="9MN-yG-hHM" secondAttribute="leading" constant="5" id="k20-HG-Pr3"/>
<constraint firstAttribute="bottom" secondItem="cbJ-XK-bnG" secondAttribute="bottom" id="RH0-lJ-ZZL"/>
<constraint firstItem="B3Y-Nj-FSx" firstAttribute="leading" secondItem="cbJ-XK-bnG" secondAttribute="trailing" id="Rvk-hT-fMi"/>
<constraint firstItem="cbJ-XK-bnG" firstAttribute="leading" secondItem="9MN-yG-hHM" secondAttribute="leading" id="k20-HG-Pr3"/>
<constraint firstAttribute="trailing" secondItem="B3Y-Nj-FSx" secondAttribute="trailing" constant="2" id="loU-tZ-CZ0"/>
<constraint firstItem="cbJ-XK-bnG" firstAttribute="top" secondItem="9MN-yG-hHM" secondAttribute="top" id="vdE-ic-WvJ"/>
</constraints>
<connections>
<outlet property="textField" destination="B3Y-Nj-FSx" id="qzD-8z-WxE"/>

View File

@ -74,6 +74,14 @@ final class DocumentWindowController: NSWindowController, NSWindowDelegate {
window.setFrame(.init(origin: window.frame.origin, size: frameSize), display: false)
}
// set edited indicator to window tab
let dotView = DotView()
dotView.isHidden = true
dotView.color = .tertiaryLabelColor
dotView.toolTip = "Document has unsaved changes".localized
self.window?.tab.accessoryView = dotView
NSLayoutConstraint(item: dotView, attribute: .height, relatedBy: .equal, toItem: dotView, attribute: .width, multiplier: 1, constant: 0).isActive = true
// observe opacity setting change
if let window = self.window as? DocumentWindow {
self.opacityObserver = UserDefaults.standard.publisher(for: .windowAlpha, initial: true)
@ -125,6 +133,8 @@ final class DocumentWindowController: NSWindowController, NSWindowDelegate {
override func setDocumentEdited(_ dirtyFlag: Bool) {
self.window?.tab.accessoryView?.isHidden = !dirtyFlag
super.setDocumentEdited(self.isWhitepaper ? false : dirtyFlag)
}

View File

@ -8,7 +8,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2015-2018 1024jp
// © 2015-2022 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -23,14 +23,15 @@
// limitations under the License.
//
import Cocoa
import AppKit
@IBDesignable
final class DotView: NSView {
// MARK: Inspectable Properties
@IBInspectable var color: NSColor = .labelColor
@Invalidating(.display) @IBInspectable var color: NSColor = .labelColor
@Invalidating(.display) @IBInspectable var dotLength: CGFloat = 4
@ -39,10 +40,18 @@ final class DotView: NSView {
override func draw(_ dirtyRect: NSRect) {
assert(self.dotLength <= self.bounds.width)
assert(self.dotLength <= self.bounds.height)
let rect = NSRect(x: (self.bounds.width - self.dotLength) / 2,
y: (self.bounds.height - self.dotLength) / 2,
width: self.dotLength,
height: self.dotLength)
NSGraphicsContext.saveGraphicsState()
self.color.setFill()
NSBezierPath(ovalIn: self.bounds).fill()
NSBezierPath(ovalIn: rect).fill()
NSGraphicsContext.restoreGraphicsState()
}

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Das Dokument enthält ungesicherte Änderungen.";
/* MARK: Toolbar */
"Syntax Style" = "Syntaxstil";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Document has unsaved changes";
/* MARK: Toolbar */
"Syntax Style" = "Syntax Style";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Document has unsaved changes"; // FIXME: added
/* MARK: Toolbar */
"Syntax Style" = "Syntaxe";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Document has unsaved changes"; // FIXME: added
/* MARK: Toolbar */
"Syntax Style" = "Stile sintassi";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "書類に保存されていない変更があります";
/* MARK: Toolbar */
"Syntax Style" = "シンタックス";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Document has unsaved changes"; // FIXME: added
/* MARK: Toolbar */
"Syntax Style" = "Estilo da Sintaxe";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Document has unsaved changes"; // FIXME: added
/* MARK: Toolbar */
"Syntax Style" = "Sözdizim Biçemi";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Document has unsaved changes"; // FIXME: added
/* MARK: Toolbar */
"Syntax Style" = "语法样式";
// tooltip

View File

@ -220,6 +220,12 @@
/* MARK: Document Window */
// tooltip for the "edited" indicator in window tab
"Document has unsaved changes" = "Document has unsaved changes";
/* MARK: Toolbar */
"Syntax Style" = "文法樣式";
// tooltip