1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-11-28 02:54:31 +03:00

GH-339 Make the preview component roughly work

- re-model the view component hierarchy
This commit is contained in:
Tae Won Ha 2016-12-21 07:33:39 +01:00
parent 9b377c9d34
commit 738635ca51
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
8 changed files with 127 additions and 18 deletions

View File

@ -36,6 +36,7 @@
4B183E101E06E29C0079E8A8 /* CocoaMarkdown.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B183E0D1E06E2940079E8A8 /* CocoaMarkdown.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4B183E161E07C1420079E8A8 /* preview in Resources */ = {isa = PBXBuildFile; fileRef = 4B183E151E07C1420079E8A8 /* preview */; };
4B183E1B1E08748B0079E8A8 /* NeoVimAutoCommandEvent.generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B183E1A1E08748B0079E8A8 /* NeoVimAutoCommandEvent.generated.h */; settings = {ATTRIBUTES = (Public, ); }; };
4B183E1E1E09931E0079E8A8 /* MarkdownRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B183E1D1E09931E0079E8A8 /* MarkdownRenderer.swift */; };
4B22F7F01D7C029400929B0E /* ScorerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B22F7EF1D7C029400929B0E /* ScorerTest.swift */; };
4B22F7F21D7C6B9000929B0E /* ImageAndTextTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B22F7F11D7C6B9000929B0E /* ImageAndTextTableCell.swift */; };
4B238BE11D3BF24200CBDD98 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B238BE01D3BF24200CBDD98 /* Application.swift */; };
@ -303,6 +304,7 @@
4B183E0D1E06E2940079E8A8 /* CocoaMarkdown.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaMarkdown.framework; path = Carthage/Build/Mac/CocoaMarkdown.framework; sourceTree = SOURCE_ROOT; };
4B183E151E07C1420079E8A8 /* preview */ = {isa = PBXFileReference; lastKnownFileType = folder; path = preview; sourceTree = "<group>"; };
4B183E1A1E08748B0079E8A8 /* NeoVimAutoCommandEvent.generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NeoVimAutoCommandEvent.generated.h; sourceTree = "<group>"; };
4B183E1D1E09931E0079E8A8 /* MarkdownRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownRenderer.swift; sourceTree = "<group>"; };
4B1BB3521D16C5E500CA4FEF /* InputTestView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTestView.swift; sourceTree = "<group>"; };
4B22F7EF1D7C029400929B0E /* ScorerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScorerTest.swift; sourceTree = "<group>"; };
4B22F7F11D7C6B9000929B0E /* ImageAndTextTableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageAndTextTableCell.swift; sourceTree = "<group>"; };
@ -495,6 +497,7 @@
1929BA610ADEA2BA4424FBE5 /* Preview */ = {
isa = PBXGroup;
children = (
4B183E1C1E0992FD0079E8A8 /* Preview Renderers */,
1929B8DA5AA33536F0082200 /* PreviewComponent.swift */,
1929BB8BCA48637156F92945 /* PreviewService.swift */,
);
@ -523,6 +526,14 @@
name = "File Browser";
sourceTree = "<group>";
};
4B183E1C1E0992FD0079E8A8 /* Preview Renderers */ = {
isa = PBXGroup;
children = (
4B183E1D1E09931E0079E8A8 /* MarkdownRenderer.swift */,
);
name = "Preview Renderers";
sourceTree = "<group>";
};
4B1AC1AF1D7F395300898F0B /* Open Quickly */ = {
isa = PBXGroup;
children = (
@ -1249,6 +1260,7 @@
1929BD3F9E609BFADB27584B /* Scorer.swift in Sources */,
4B6B0A781DA2A1A500212D6D /* FileOutlineView.swift in Sources */,
4BB409EE1DDA77E9005F39A2 /* ProxyWorkspaceBar.swift in Sources */,
4B183E1E1E09931E0079E8A8 /* MarkdownRenderer.swift in Sources */,
4BAD84E81D7CA8FC00A79CC3 /* OpenQuicklyFilterOperation.swift in Sources */,
1929B0E0C3BC59F52713D5A2 /* FoundationCommons.swift in Sources */,
1929B3CEE0C1A1850E9CCE2F /* BasicTypes.swift in Sources */,

View File

@ -12,7 +12,7 @@ enum BufferListAction {
case open(buffer: NeoVimBuffer)
}
class BufferListComponent: ViewComponent, NSTableViewDataSource, NSTableViewDelegate {
class BufferListComponent: StandardViewComponent, NSTableViewDataSource, NSTableViewDelegate {
fileprivate var buffers: [NeoVimBuffer] = []
fileprivate let bufferList = NSTableView.standardTableView()

View File

@ -12,6 +12,11 @@ protocol Flow: class {
var sink: Observable<Any> { get }
}
protocol ViewComponent: Flow {
var view: NSView { get }
}
class PublishingFlow: Flow {
var sink: Observable<Any> {
@ -62,7 +67,7 @@ class EmbeddableComponent: Flow {
fileprivate let subject = PublishSubject<Any>()
fileprivate let source: Observable<Any>
fileprivate let disposeBag = DisposeBag()
let disposeBag = DisposeBag()
init(source: Observable<Any>) {
self.source = source
@ -116,10 +121,11 @@ class StandardComponent: NSObject, Flow {
}
}
class ViewComponent: NSView, Flow {
class StandardViewComponent: NSView, ViewComponent {
var view: NSView {
preconditionFailure("Please override")
return self
}
var sink: Observable<Any> {

View File

@ -46,7 +46,7 @@ struct FileBrowserData: StandardPrefData {
}
}
class FileBrowserComponent: ViewComponent, ToolDataHolder {
class FileBrowserComponent: StandardViewComponent, ToolDataHolder {
fileprivate let fileView: FileOutlineView
fileprivate let fileItemService: FileItemService

View File

@ -444,18 +444,18 @@ extension MainWindowComponent {
let fileBrowserTool = self.tools[.fileBrowser]!
if fileBrowserTool.isSelected {
if fileBrowserTool.viewComponent.isFirstResponder {
if fileBrowserTool.viewComponent.view.isFirstResponder {
fileBrowserTool.toggle()
self.focusNeoVimView(self)
} else {
fileBrowserTool.viewComponent.beFirstResponder()
fileBrowserTool.viewComponent.view.beFirstResponder()
}
return
}
fileBrowserTool.toggle()
fileBrowserTool.viewComponent.beFirstResponder()
fileBrowserTool.viewComponent.view.beFirstResponder()
}
@IBAction func focusNeoVimView(_ sender: Any?) {

View File

@ -0,0 +1,43 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Cocoa
import RxSwift
import PureLayout
import CocoaMarkdown
enum PreviewRendererAction {
case htmlString(html: String)
case error
}
class MarkdownRenderer: StandardFlow {
override func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is PreviewAction }
.map { $0 as! PreviewAction }
.subscribe(onNext: { action in
switch action {
case let .refresh(url):
self.render(from: url)
}
})
}
fileprivate func render(from url: URL) {
let doc = CMDocument(contentsOfFile: url.path)
let renderer = CMHTMLRenderer(document: doc)
guard let html = renderer?.render() else {
self.publish(event: PreviewRendererAction.error)
return
}
self.publish(event: PreviewRendererAction.htmlString(html: html))
}
}

View File

@ -6,7 +6,7 @@
import Cocoa
import RxSwift
class PrefPane: ViewComponent {
class PrefPane: StandardViewComponent {
// Return true to place this to the upper left corner when the scroll view is bigger than this view.
override var isFlipped: Bool {

View File

@ -8,6 +8,11 @@ import RxSwift
import PureLayout
import WebKit
enum PreviewAction {
case refresh(url: URL)
}
struct PreviewPrefData: StandardPrefData {
static let `default` = PreviewPrefData()
@ -24,23 +29,44 @@ struct PreviewPrefData: StandardPrefData {
}
}
class PreviewComponent: ViewComponent {
class PreviewComponent: NSView, ViewComponent {
fileprivate let flow: EmbeddableComponent
fileprivate let previewService = PreviewService()
fileprivate let markdownRenderer: MarkdownRenderer
let webview = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
fileprivate let webview = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(source: Observable<Any>) {
super.init(source: source)
webview.loadHTMLString(self.previewService.emptyPreview(), baseURL: nil)
var sink: Observable<Any> {
return self.flow.sink
}
override func addViews() {
var view: NSView {
return self
}
init(source: Observable<Any>) {
self.flow = EmbeddableComponent(source: source)
self.markdownRenderer = MarkdownRenderer(source: self.flow.sink)
super.init(frame: .zero)
self.configureForAutoLayout()
self.flow.set(subscription: self.subscription)
self.webview.loadHTMLString(self.previewService.emptyPreview(), baseURL: nil)
self.addViews()
self.addReactions()
}
fileprivate func addViews() {
let webview = self.webview
webview.configureForAutoLayout()
@ -49,7 +75,7 @@ class PreviewComponent: ViewComponent {
webview.autoPinEdgesToSuperviewEdges()
}
override func subscription(source: Observable<Any>) -> Disposable {
fileprivate func subscription(source: Observable<Any>) -> Disposable {
return source
.filter { $0 is MainWindowAction }
.map { $0 as! MainWindowAction }
@ -57,7 +83,11 @@ class PreviewComponent: ViewComponent {
switch action {
case let .currentBufferChanged(mainWindow, currentBuffer):
NSLog("\(currentBuffer)")
guard let url = currentBuffer.url else {
return
}
self.flow.publish(event: PreviewAction.refresh(url: url))
default:
return
@ -65,4 +95,22 @@ class PreviewComponent: ViewComponent {
}
})
}
fileprivate func addReactions() {
self.markdownRenderer.sink
.filter { $0 is PreviewRendererAction }
.map { $0 as! PreviewRendererAction }
.subscribe(onNext: { action in
switch action {
case let .htmlString(html):
self.webview.loadHTMLString(html, baseURL: nil)
case .error:
self.webview.loadHTMLString(self.previewService.emptyPreview(), baseURL: nil)
}
})
.addDisposableTo(self.flow.disposeBag)
}
}