diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-07-11 09:27:49 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-07-11 09:27:49 +0200 |
| commit | 8564439356f4bcc3e21b19738eb87b4c0722c623 (patch) | |
| tree | 1465f4e48be83d255e5c68de804ba940db238bea /Map/Presentation/Base Components/MapTextEditor/HoverView.swift | |
| parent | ff3619fdf3fce82d95124654a18b66ca3ed380cd (diff) | |
Add missing vertex detection
Diffstat (limited to 'Map/Presentation/Base Components/MapTextEditor/HoverView.swift')
| -rw-r--r-- | Map/Presentation/Base Components/MapTextEditor/HoverView.swift | 100 |
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() + } +} |