Permalink
Browse files

notification window design tweaks; notification window non-moveable; …

…close notification window on click
  • Loading branch information...
1 parent f39c360 commit a9eddfade85f422c5542e7fbb55c5f6883cbf4e9 Chris Smith committed Jan 14, 2017
@@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
4B1F4E8D1E21D3B800CFB827 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B1F4E8C1E21D3B800CFB827 /* Main.storyboard */; };
4B56EDFF1E19E6EC002D0804 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B56EDFE1E19E6EC002D0804 /* Scheduler.swift */; };
+ 4B5B85EB1E2A8B5600FE04FA /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5B85EA1E2A8B5600FE04FA /* OverlayView.swift */; };
4BA9F3AF1E188A06007D1506 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA9F3AE1E188A06007D1506 /* Constants.swift */; };
4BA9F3B11E189E96007D1506 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BA9F3B01E189E96007D1506 /* Assets.xcassets */; };
4BA9F3B91E18B34D007D1506 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA9F3B81E18B34D007D1506 /* AppDelegate.swift */; };
@@ -59,6 +60,7 @@
/* Begin PBXFileReference section */
4B1F4E8C1E21D3B800CFB827 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
4B56EDFE1E19E6EC002D0804 /* Scheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scheduler.swift; sourceTree = "<group>"; };
+ 4B5B85EA1E2A8B5600FE04FA /* OverlayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverlayView.swift; sourceTree = "<group>"; };
4BA9F3AE1E188A06007D1506 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
4BA9F3B01E189E96007D1506 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
4BA9F3B61E18B34D007D1506 /* HintLauncher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HintLauncher.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -231,6 +233,7 @@
children = (
4BFA68C11E21A4560031DF0C /* NotificationViewController.swift */,
4BFA68B51E2195A20031DF0C /* NotificationWindowController.swift */,
+ 4B5B85EA1E2A8B5600FE04FA /* OverlayView.swift */,
);
path = Notification;
sourceTree = "<group>";
@@ -432,6 +435,7 @@
4BE886381E22C473003E2DE0 /* Settings.swift in Sources */,
4B56EDFF1E19E6EC002D0804 /* Scheduler.swift in Sources */,
4BD7DC531E1383E500237385 /* AppDelegate.swift in Sources */,
+ 4B5B85EB1E2A8B5600FE04FA /* OverlayView.swift in Sources */,
4BD7DC771E15BAE600237385 /* Logging.swift in Sources */,
4BE8862A1E229088003E2DE0 /* LinkButton.swift in Sources */,
4BFA68B61E2195A20031DF0C /* NotificationWindowController.swift in Sources */,
@@ -8,6 +8,7 @@
import Cocoa
+
class NotificationViewController: NSViewController {
@IBOutlet var textView: NSTextView!
@@ -19,17 +20,18 @@ class NotificationViewController: NSViewController {
@IBOutlet var rightQuoteScrollView: NSScrollView!
@IBOutlet var leftQuoteScrollView: NSScrollView!
- let quoteTextFont = NSFont(name: "Georgia", size: 15)!
+ let quoteTextFont = NSFont(name: "Georgia", size: 14)!
let quoteTextColor = NSColor(red: 246/255, green: 246/255, blue: 246/255, alpha: 1.0)
- let quoteTextLineHeight: CGFloat = 19.0
- let quoteTextHeightPadding: CGFloat = 5
+ let quoteTextLineHeight: CGFloat = 19
+ let quoteTextHeightPadding: CGFloat = 7
- let quoteSourceFont = NSFont(name: "Georgia Italic", size: 15)!
+ let quoteSourceFont = NSFont(name: "Georgia Italic", size: 14)!
let quoteSourceColor = NSColor(red: 228/255, green: 228/255, blue: 228/255, alpha: 1.0)
let quoteSourceHeightPadding: CGFloat = 5
- let rightQuotationMarkXOffset: CGFloat = 14
- let rightQuotationMarkYOffset: CGFloat = -7
+ let rightQuotationMarkXOffset: CGFloat = -8
+ let rightQuotationMarkYOffset: CGFloat = -6
+ let leftQuotationMarkXOffset: CGFloat = 0
let leftQuotationMarkYOffset: CGFloat = -25
func setQuote(_ quote: Quote) {
@@ -74,21 +76,34 @@ class NotificationViewController: NSViewController {
func positionQuote() {
+ let textLayoutManager = textView.layoutManager!
+ let sourceLayoutManager = sourceView.layoutManager!
+
// force layout.
- textView.layoutManager?.ensureLayout(for: textView.textContainer!)
- sourceView.layoutManager?.ensureLayout(for: sourceView.textContainer!)
+ textLayoutManager.ensureLayout(for: textView.textContainer!)
+ sourceLayoutManager.ensureLayout(for: sourceView.textContainer!)
// get used rect for both parts.
- let textUsedRect = textView.layoutManager!.usedRect(for: textView.textContainer!)
- let sourceUsedRect = sourceView.layoutManager!.usedRect(for: sourceView.textContainer!)
+ let textUsedRect = textLayoutManager.usedRect(for: textView.textContainer!)
+ let sourceUsedRect = sourceLayoutManager.usedRect(for: sourceView.textContainer!)
+ // find width of the longest line of quote text.
+ var i = 0
+ var width = 0
+ while i < textLayoutManager.numberOfGlyphs {
+ var range = NSRange()
+ let rect = textLayoutManager.lineFragmentUsedRect(forGlyphAt: i, effectiveRange: &range)
+ width = max(width, Int(rect.width))
+ i = NSMaxRange(range)
+ }
+
// size and position quote text to center vertically, factoring in source.
let textSize = NSSize(
width: textScrollView.frame.width,
height: textUsedRect.height + quoteTextHeightPadding
)
let textOrigin = NSPoint(
- x: textScrollView.frame.origin.x,
+ x: (view.frame.width - CGFloat(width)) / 2,
y: (view.frame.height - textSize.height + sourceScrollView.frame.height) / 2
)
@@ -111,6 +126,8 @@ class NotificationViewController: NSViewController {
func positionQuotationMarks() {
+ textView.layoutManager?.ensureLayout(for: textView.textContainer!)
+
// get the used rect for the last displayed line of quote text.
let layoutManager = textView.layoutManager!
let lastUsedRect = layoutManager.lineFragmentUsedRect(
@@ -120,14 +137,14 @@ class NotificationViewController: NSViewController {
// position left quotation mark against vertically-centered quote text.
let leftOrigin = NSPoint(
- x: leftQuoteScrollView.frame.origin.x,
+ x: textScrollView.frame.origin.x - leftQuoteScrollView.frame.width + leftQuotationMarkXOffset,
y: textScrollView.frame.origin.y + textScrollView.frame.height + leftQuotationMarkYOffset
)
leftQuoteScrollView.setFrameOrigin(leftOrigin)
// position right quotation mark at end of last displayed character.
let rightOrigin = NSPoint(
- x: lastUsedRect.width + rightQuotationMarkXOffset,
+ x: textScrollView.frame.origin.x + lastUsedRect.width + rightQuotationMarkXOffset,
y: textScrollView.frame.origin.y + rightQuotationMarkYOffset
)
rightQuoteScrollView.setFrameOrigin(rightOrigin)
@@ -16,6 +16,11 @@ class NotificationWindowController: NSWindowController {
let visibleDuration: Double = 8.0
var animating = false
+ var timer: Timer? = nil
+
+ override func windowDidLoad() {
+ window?.isMovable = false
+ }
func showWindowWithText(_ sender: Any?, quote: Quote) {
@@ -74,7 +79,7 @@ class NotificationWindowController: NSWindowController {
}, completionHandler: {() -> Void in
// hold visible, then animate out.
- Timer.scheduledTimer(
+ self.timer = Timer.scheduledTimer(
timeInterval: self.visibleDuration,
target: self,
selector: #selector(self.animateOut),
@@ -108,4 +113,11 @@ class NotificationWindowController: NSWindowController {
self.animating = false
})
}
+
+ func dismiss() {
+ if animating {
+ timer?.invalidate()
+ animateOut()
+ }
+ }
}
@@ -0,0 +1,17 @@
+//
+// OverlayView.swift
+// Hint
+//
+// Created by Christopher Smith on 1/14/17.
+// Copyright © 2017 Chris Smith. All rights reserved.
+//
+
+import Cocoa
+
+
+class OverlayView: NSView {
+
+ override func mouseDown(with event: NSEvent) {
+ (window?.windowController as? NotificationWindowController)?.dismiss()
+ }
+}
@@ -859,7 +859,7 @@
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="RMF-hT-Xom" customClass="NSPanel">
<windowStyleMask key="styleMask" closable="YES" miniaturizable="YES" resizable="YES" utility="YES" HUD="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
- <rect key="contentRect" x="245" y="301" width="350" height="120"/>
+ <rect key="contentRect" x="245" y="301" width="350" height="130"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1028"/>
</window>
<connections>
@@ -875,21 +875,21 @@
<objects>
<viewController id="zfm-S6-1H3" customClass="NotificationViewController" customModule="Hint" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="YzD-jS-fPY" userLabel="Notification View">
- <rect key="frame" x="0.0" y="0.0" width="350" height="120"/>
+ <rect key="frame" x="0.0" y="0.0" width="349" height="130"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EiN-ue-GD3">
- <rect key="frame" x="23" y="35" width="305" height="80"/>
+ <rect key="frame" x="23" y="45" width="285" height="80"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="ksK-av-5se">
- <rect key="frame" x="0.0" y="0.0" width="305" height="80"/>
+ <rect key="frame" x="0.0" y="0.0" width="285" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView ambiguous="YES" editable="NO" selectable="NO" drawsBackground="NO" importsGraphics="NO" baseWritingDirection="leftToRight" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="yYD-7L-Pxc">
- <rect key="frame" x="0.0" y="0.0" width="307" height="80"/>
+ <rect key="frame" x="0.0" y="0.0" width="287" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
- <size key="minSize" width="305" height="80"/>
+ <size key="minSize" width="285" height="80"/>
<size key="maxSize" width="463" height="10000000"/>
<attributedString key="textStorage">
<fragment content="Lorem ipsum dolor sit amet, consectetur adipisici elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.">
@@ -904,7 +904,9 @@
</textView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+ <edgeInsets key="contentInsets" left="0.0" right="0.0" top="0.0" bottom="0.0"/>
</clipView>
+ <edgeInsets key="contentInsets" left="0.0" right="0.0" top="0.0" bottom="0.0"/>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="TxZ-so-MYO">
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
<autoresizingMask key="autoresizingMask"/>
@@ -915,18 +917,18 @@
</scroller>
</scrollView>
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bkj-aH-Qbf">
- <rect key="frame" x="0.0" y="87" width="31" height="33"/>
+ <rect key="frame" x="0.0" y="87" width="24" height="33"/>
<autoresizingMask key="autoresizingMask"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="h2A-Lt-zyj">
- <rect key="frame" x="0.0" y="0.0" width="31" height="33"/>
+ <rect key="frame" x="0.0" y="0.0" width="24" height="33"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView ambiguous="YES" editable="NO" selectable="NO" importsGraphics="NO" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="dqd-5d-hen">
- <rect key="frame" x="0.0" y="0.0" width="31" height="59"/>
+ <rect key="frame" x="0.0" y="0.0" width="24" height="59"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" red="0.6588235294117647" green="0.6588235294117647" blue="0.6588235294117647" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="calibratedWhite"/>
- <size key="minSize" width="31" height="33"/>
+ <size key="minSize" width="24" height="33"/>
<size key="maxSize" width="463" height="10000000"/>
<attributedString key="textStorage">
<fragment content="">
@@ -987,18 +989,18 @@
</scroller>
</scrollView>
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="S5T-X2-gmf">
- <rect key="frame" x="308" y="81" width="31" height="33"/>
+ <rect key="frame" x="308" y="81" width="24" height="33"/>
<autoresizingMask key="autoresizingMask"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="Xnd-i1-L0b">
- <rect key="frame" x="0.0" y="0.0" width="31" height="33"/>
+ <rect key="frame" x="0.0" y="0.0" width="24" height="33"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView ambiguous="YES" editable="NO" selectable="NO" importsGraphics="NO" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="w2I-Nw-5mV">
- <rect key="frame" x="0.0" y="26" width="31" height="59"/>
+ <rect key="frame" x="0.0" y="26" width="24" height="59"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" red="0.6588235294117647" green="0.6588235294117647" blue="0.6588235294117647" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="calibratedWhite"/>
- <size key="minSize" width="31" height="33"/>
+ <size key="minSize" width="24" height="33"/>
<size key="maxSize" width="463" height="10000000"/>
<attributedString key="textStorage">
<fragment content="">
@@ -1023,6 +1025,10 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
+ <customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EvP-L8-qex" customClass="OverlayView" customModule="Hint" customModuleProvider="target">
+ <rect key="frame" x="0.0" y="0.0" width="349" height="130"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ </customView>
</subviews>
</view>
<connections>
@@ -1036,7 +1042,7 @@
</viewController>
<customObject id="WIC-3F-ekQ" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="503" y="546"/>
+ <point key="canvasLocation" x="502.5" y="546"/>
</scene>
<!--View Controller-->
<scene sceneID="hIz-AP-VOD">
View
@@ -1,3 +1,4 @@
+Short quote|Source
One line quote One line quote|Source
Two line quote Two line quote Two line quote Two line quote|Source
Three line quote Three line quote Three line quote Three line quote Three line quote Three line quote|Source

0 comments on commit a9eddfa

Please sign in to comment.