CutBox.app

Coverage Report

Created: 2024-03-12 03:40

.../Source/App/SearchAndPreview/SearchAndPreviewViewBase.swift
Line
Count
Source (jump to first uncovered line)
1
//
2
//  SearchPreviewViewBase.swift
3
//  CutBox
4
//
5
//  Created by Jason Milkins on 20/5/18.
6
//  Copyright © 2018-2023 ocodo. All rights reserved.
7
//
8
9
import RxSwift
10
import RxCocoa
11
import Cocoa
12
import CoreImage
13
14
let useTextCommands: [Selector] = [
15
    "deleteBackwards:",
16
    "deleteForwards:",
17
    "deleteWord:",
18
    "deleteWordBackwards:",
19
    "cut",
20
    "copy",
21
    "paste",
22
    "undo",
23
    "redo",
24
    "selectAll"
25
10
].map { Selector($0) }
26
27
class SearchAndPreviewViewBase: CutBoxBaseView {
28
29
    @IBOutlet weak var searchContainer: CutBoxBaseBox!
30
    @IBOutlet weak var searchTextContainer: CutBoxBaseBox!
31
    @IBOutlet weak var searchTextPlaceholder: CutBoxBaseTextField!
32
    @IBOutlet weak var searchText: SearchTextView!
33
    @IBOutlet weak var itemsList: NSTableView!
34
    @IBOutlet weak var preview: CutBoxBaseTextView!
35
    @IBOutlet weak var previewContainer: CutBoxBaseBox!
36
    @IBOutlet weak var iconImageView: NSImageView!
37
    @IBOutlet weak var searchScopeImageButton: CutBoxBaseButton!
38
    @IBOutlet weak var mainContainer: CutBoxBaseStackView!
39
    @IBOutlet weak var container: CutBoxBaseStackView!
40
    @IBOutlet weak var bottomBar: CutBoxBaseView!
41
42
    @IBOutlet weak var searchTextContainerHeight: NSLayoutConstraint!
43
    @IBOutlet weak var mainTopConstraint: NSLayoutConstraint!
44
    @IBOutlet weak var mainLeadingConstraint: NSLayoutConstraint!
45
    @IBOutlet weak var mainTrailingConstraint: NSLayoutConstraint!
46
    @IBOutlet weak var mainBottomConstraint: NSLayoutConstraint!
47
48
    var searchTextHeight: CGFloat {
49
1
        get {
50
1
            return searchTextContainerHeight.constant
51
1
        }
52
51
        set {
53
51
            searchTextContainerHeight.constant = newValue
54
51
        }
55
    }
56
57
    var spacing: CGFloat {
58
52
        get {
59
52
            return mainContainer.spacing
60
52
        }
61
51
        set {
62
51
            mainContainer.spacing = newValue
63
51
            container.spacing = newValue
64
51
            mainTopConstraint.constant = newValue
65
51
            mainLeadingConstraint.constant = newValue
66
51
            mainTrailingConstraint.constant = newValue
67
51
            mainBottomConstraint.constant = newValue
68
51
        }
69
    }
70
71
154
    var filterTextPublisher = PublishSubject<String>()
72
73
    var placeHolderTextString = ""
74
75
154
    let disposeBag = DisposeBag()
76
154
    var prefs = CutBoxPreferencesService.shared
77
78
82
    override init(frame: NSRect) {
79
82
        super.init(frame: frame)
80
82
    }
81
82
72
    required init?(coder decoder: NSCoder) {
83
72
        super.init(coder: decoder)
84
72
    }
85
86
1
    override var acceptsFirstResponder: Bool {
87
1
        return true
88
1
    }
89
90
2
    var selectedItems: IndexSet? {
91
2
        self.itemsList?
92
2
        .selectedRowIndexes
93
2
    }
94
95
    var menuDelegate: NSMenuDelegate? {
96
1
        get {
97
1
            self.itemsList?
98
1
                .menu?.delegate
99
1
        }
100
101
75
        set {
102
75
            self.itemsList?
103
75
                .menu?.delegate = newValue
104
75
        }
105
    }
106
107
    var itemsDelegate: NSTableViewDelegate? {
108
1
        get {
109
1
            self.itemsList?.delegate
110
1
        }
111
112
75
        set {
113
75
            self.itemsList?.delegate = newValue
114
75
        }
115
    }
116
117
    var itemsDataSource: NSTableViewDataSource? {
118
1
        get {
119
1
            self.itemsList?.dataSource
120
1
        }
121
122
75
        set {
123
75
            self.itemsList?.dataSource = newValue
124
75
        }
125
    }
126
127
    var previewString: String? {
128
1
        get {
129
1
            self.preview?.string
130
1
        }
131
132
4
        set {
133
4
            self.preview?.string = newValue!
134
4
        }
135
    }
136
137
4
    func setTextScale() {
138
4
        self.preview?.font = prefs.searchViewClipPreviewFont
139
4
    }
140
141
4
    func hideSearchResults(_ bool: Bool) {
142
4
        self.bottomBar?.isHidden = bool
143
4
        self.container?.isHidden = bool
144
4
    }
145
146
1.15k
    func hidePreview(_ bool: Bool) {
147
1.15k
        self.previewContainer?.isHidden = bool
148
1.15k
    }
149
150
72
    func setupPlaceholder() {
151
72
        filterTextPublisher
152
72
            .map { $0.isEmpty ? self.placeHolderTextString : "" }
153
72
            .bind(to: searchTextPlaceholder.rx.text)
154
72
            .disposed(by: disposeBag)
155
72
    }
156
157
2
    func scrollRowToVisible(_ row: Int) {
158
2
        self.itemsList?.scrollRowToVisible(row)
159
2
    }
160
161
17
    func reloadData() {
162
17
        self.itemsList?.reloadData()
163
17
    }
164
165
5
    func selectRowIndexes(_ indexes: IndexSet, byExtendingSelection extend: Bool) {
166
5
        self.itemsList?.selectRowIndexes(indexes, byExtendingSelection: extend)
167
5
    }
168
169
4
    var selectedRowIndexes: IndexSet? {
170
4
        self.itemsList?.selectedRowIndexes
171
4
    }
172
173
72
    override func awakeFromNib() {
174
72
        self.preview.textContainer!.widthTracksTextView = false
175
72
176
72
        self.preview.textContainer!.containerSize = CGSize(
177
72
            width: CGFloat.greatestFiniteMagnitude,
178
72
            height: CGFloat.greatestFiniteMagnitude
179
72
        )
180
72
181
72
        setupPlaceholder()
182
72
    }
183
184
    func colorizeMagnifier(image: NSImage = CutBoxImageRef.magnitude.image(),
185
                           tooltip: String = "search_scope_tooltip_all".l7n,
186
                           alpha: Double = 0.75,
187
150
                           color: NSColor = NSColor.white) {
188
150
189
150
        let image = image
190
150
        let blended = image.tint(color: color)
191
150
192
150
        self.searchScopeImageButton?.alphaValue = alpha
193
150
        self.searchScopeImageButton?.image = blended
194
150
        self.searchScopeImageButton?.toolTip = toolTip
195
150
    }
196
197
51
    func applyTheme() {
198
51
        let theme = prefs.currentTheme
199
51
200
51
        colorizeMagnifier(color: theme.searchText.placeholderTextColor)
201
51
202
51
        self.spacing = theme.spacing
203
51
        self.searchTextHeight = 60 - (spacing * 2.0)
204
51
205
51
        preview?.font = prefs.searchViewClipPreviewFont
206
51
        searchTextPlaceholder?.font = prefs.searchViewTextFieldFont
207
51
        searchText?.font = prefs.searchViewTextFieldFont
208
51
209
51
        itemsList?.backgroundColor = theme.clip.backgroundColor
210
51
211
51
        searchContainer?.fillColor = theme.popupBackgroundColor
212
51
213
51
        searchText?.textColor = theme.searchText.textColor
214
51
        searchText?.insertionPointColor = theme.searchText.cursorColor
215
51
        searchTextContainer?.fillColor = theme.searchText.backgroundColor
216
51
        searchTextPlaceholder?.textColor = theme.searchText.placeholderTextColor
217
51
218
51
        preview?.backgroundColor = theme.preview.backgroundColor
219
51
        previewContainer?.fillColor = theme.preview.backgroundColor
220
51
        preview?.textColor = theme.preview.textColor
221
51
222
51
        preview?.selectedTextAttributes[.backgroundColor] = theme.preview.selectedTextBackgroundColor
223
51
        preview?.selectedTextAttributes[.foregroundColor] = theme.preview.selectedTextColor
224
51
    }
225
}