aboutsummaryrefslogtreecommitdiff
path: root/Map/Presentation/Base Components/MapTextEditor/HoverView.swift
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-07-11 09:27:49 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2025-07-11 09:27:49 +0200
commit8564439356f4bcc3e21b19738eb87b4c0722c623 (patch)
tree1465f4e48be83d255e5c68de804ba940db238bea /Map/Presentation/Base Components/MapTextEditor/HoverView.swift
parentff3619fdf3fce82d95124654a18b66ca3ed380cd (diff)
Add missing vertex detection
Diffstat (limited to 'Map/Presentation/Base Components/MapTextEditor/HoverView.swift')
-rw-r--r--Map/Presentation/Base Components/MapTextEditor/HoverView.swift100
1 files changed, 100 insertions, 0 deletions
diff --git a/Map/Presentation/Base Components/MapTextEditor/HoverView.swift b/Map/Presentation/Base Components/MapTextEditor/HoverView.swift
new file mode 100644
index 0000000..4e42b99
--- /dev/null
+++ b/Map/Presentation/Base Components/MapTextEditor/HoverView.swift
@@ -0,0 +1,100 @@
+// Copyright (C) 2024 Rubén Beltrán del Río
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see https://map.tranquil.systems.
+import AppKit
+
+class HoverView: NSView {
+ weak var controller: MapTextEditorController?
+ private let action: () -> Void
+
+ init(
+ message: String,
+ action: @escaping () -> Void,
+ actionLabel: String = String(localized: "map_editor.add_missing_component"),
+ controller: MapTextEditorController
+ ) {
+ self.controller = controller
+ self.action = action
+ super.init(frame: .zero)
+
+ setupView(message: message, actionLabel: actionLabel)
+ setupTrackingArea()
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ private func setupView(message: String, actionLabel: String) {
+ wantsLayer = true
+ layer?.backgroundColor = NSColor.controlBackgroundColor.cgColor
+ layer?.borderColor = NSColor.separatorColor.cgColor
+ layer?.borderWidth = 1
+ layer?.cornerRadius = 8
+
+ let label = NSTextField(labelWithString: message)
+ label.font = NSFont.Theme.SmallControl.regular
+ label.textColor = NSColor.labelColor
+
+ let button = NSButton(title: actionLabel, target: self, action: #selector(buttonClicked))
+ button.bezelStyle = .accessoryBarAction
+ button.font = NSFont.Theme.SmallControl.emphasized
+ button.controlSize = .mini
+
+ addSubview(label)
+ addSubview(button)
+
+ label.translatesAutoresizingMaskIntoConstraints = false
+ button.translatesAutoresizingMaskIntoConstraints = false
+
+ NSLayoutConstraint.activate([
+ label.topAnchor.constraint(equalTo: topAnchor, constant: 8),
+ label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
+ label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8),
+
+ button.topAnchor.constraint(equalTo: topAnchor, constant: 8),
+ button.leadingAnchor.constraint(equalTo: label.trailingAnchor, constant: 8),
+ button.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
+ button.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8),
+
+ heightAnchor.constraint(equalToConstant: 32),
+ ])
+ }
+
+ private func setupTrackingArea() {
+ let trackingArea = NSTrackingArea(
+ rect: bounds,
+ options: [.mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow, .inVisibleRect],
+ owner: self,
+ userInfo: nil
+ )
+ addTrackingArea(trackingArea)
+ }
+
+ @objc private func buttonClicked() {
+ action()
+ }
+
+ override func mouseEntered(with event: NSEvent) {
+ super.mouseEntered(with: event)
+ controller?.isHoveringHoverView = true
+ controller?.hoverTimer?.invalidate()
+ }
+
+ override func mouseExited(with event: NSEvent) {
+ super.mouseExited(with: event)
+ controller?.isHoveringHoverView = false
+ controller?.scheduleHideHoverView()
+ }
+}