Files
virtual-controller/remote-client-ios/remote-client-ios/Core/VC-Arrange/Arrange-Functions-Gestures.swift
T
Paul Lipscomb d6201c59b4 Multi-iPad dest_id routing, activity ring, context menu hide, live label/visibility sync
Desktop:
- Replace Remote checkbox with T: dest_spin (0=Off, 1-9=tablet) on all widgets
- dest_id persisted in get_state/set_state, broadcast in tablet snapshot
- dest_spin.valueChanged triggers save + broadcast to iPad
- _on_widget_visibility_from_tablet updates dest_spin from iPad hide event
- _broadcast_preset_update shared helper; ws_server.has_clients guard
- label editingFinished triggers live label sync to iPad

iOS:
- VC-Arrange/VC-Logging/Widgets-Reusable-UI file reorganisation
- ArrangeObjects/ArrangeView rename, 7-bucket Arrange-Functions split
- myTabletId (UserDefaults) + tabletIdField next to port in toolbar
- Preset filter: destId == myTabletId instead of visible bool
- BaseWidget activity ring: long press gesture (touch) + final update() flash
- Context menu long press (arrange mode): hide widget, save layout, send dest_id:0
- Same-UUID preset check skips Preset Switched alert on visibility/label updates
- autoSwitchEnabled, toolbarStatusLabel, presetLabel, statusToken

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 21:56:35 -04:00

55 lines
2.0 KiB
Swift

import UIKit
extension ArrangeObjects {
// MARK: - Gestures
func addDragGesture(to view: UIView) {
let pan = UIPanGestureRecognizer(target: self, action: #selector(handleGesturePan(_:)))
view.addGestureRecognizer(pan)
}
@objc func handleGesturePan(_ gesture: UIPanGestureRecognizer) {
guard self.isLocked == false, let view = gesture.view else { return }
let translation = gesture.translation(in: self.containerView)
view.center = CGPoint(x: view.center.x + translation.x, y: view.center.y + translation.y)
gesture.setTranslation(.zero, in: self.containerView)
}
func addContextMenuGesture(to view: UIView) {
let press = UILongPressGestureRecognizer(target: self, action: #selector(handleGestureLongPress(_:)))
press.minimumPressDuration = 0.5
press.cancelsTouchesInView = false
view.addGestureRecognizer(press)
}
@objc func handleGestureLongPress(_ gesture: UILongPressGestureRecognizer) {
guard self.isLocked == false else { return }
guard gesture.state == .began else { return }
guard let widget = gesture.view as? BaseWidget else { return }
let alert = UIAlertController(title: widget.displayName, message: nil, preferredStyle: .actionSheet)
alert.overrideUserInterfaceStyle = .dark
alert.addAction(UIAlertAction(title: "Hide", style: .destructive) { [weak self] _ in
self?.hideWidget(widget)
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
if let popover = alert.popoverPresentationController {
popover.sourceView = widget
popover.sourceRect = widget.bounds
}
self.present(alert, animated: true)
}
func hideWidget(_ widget: BaseWidget) {
widget.removeFromSuperview()
self.widgets.removeValue(forKey: widget.uid)
self.saveLayout()
self.wsClientSendJSON(["event": "widget_visibility", "uid": widget.uid, "dest_id": 0])
}
}