d6201c59b4
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>
87 lines
3.4 KiB
Swift
87 lines
3.4 KiB
Swift
import UIKit
|
|
|
|
extension ArrangeObjects {
|
|
|
|
// MARK: - UI Updates
|
|
|
|
func updateUIFromConnectionState(_ state: ConnectionState) {
|
|
self.connectionState = state
|
|
let green = UIColor(red: 0, green: 0.9, blue: 0.46, alpha: 1)
|
|
let red = UIColor(red: 0.8, green: 0.2, blue: 0.2, alpha: 1)
|
|
let gray = UIColor(white: 0.3, alpha: 1)
|
|
|
|
switch state {
|
|
case .notStarted:
|
|
self.statusLabel.text = "not started"
|
|
self.connectButton.setTitle("Connect", for: .normal)
|
|
self.connectButton.backgroundColor = green
|
|
self.connectButton.setTitleColor(.black, for: .normal)
|
|
self.connectButton.isEnabled = true
|
|
case .connecting:
|
|
self.statusLabel.text = "connecting..."
|
|
self.connectButton.setTitle("Connecting...", for: .normal)
|
|
self.connectButton.backgroundColor = gray
|
|
self.connectButton.setTitleColor(.lightGray, for: .normal)
|
|
self.connectButton.isEnabled = false
|
|
case .connected:
|
|
self.statusLabel.text = "connected"
|
|
self.connectButton.setTitle("Disconnect", for: .normal)
|
|
self.connectButton.backgroundColor = red
|
|
self.connectButton.setTitleColor(.white, for: .normal)
|
|
self.connectButton.isEnabled = true
|
|
case .disconnected:
|
|
self.statusLabel.text = "disconnected"
|
|
self.connectButton.setTitle("Reconnect", for: .normal)
|
|
self.connectButton.backgroundColor = green
|
|
self.connectButton.setTitleColor(.black, for: .normal)
|
|
self.connectButton.isEnabled = true
|
|
}
|
|
}
|
|
|
|
func updateUIArrangeLockButtons() {
|
|
let green = UIColor(red: 0, green: 0.9, blue: 0.46, alpha: 1)
|
|
self.lockButton.backgroundColor = self.isLocked ? green : UIColor(white: 0.15, alpha: 1)
|
|
self.lockButton.setTitleColor(self.isLocked ? .black : .lightGray, for: .normal)
|
|
self.arrangeButton.backgroundColor = self.isLocked ? UIColor(white: 0.15, alpha: 1) : green
|
|
self.arrangeButton.setTitleColor(self.isLocked ? .lightGray : .black, for: .normal)
|
|
}
|
|
|
|
func updateUIFromDawState(_ json: [String: Any]) {
|
|
let track = json["track"] as? String
|
|
let bar = json["bar"] as? Int
|
|
let playing = json["playing"] as? Bool
|
|
|
|
self.feedbackWidgets.forEach { $0.updateDaw(track: track, bar: bar, playing: playing) }
|
|
|
|
var parts: [String] = []
|
|
if let track = track { parts.append(track) }
|
|
if let bar = bar { parts.append("Bar \(bar)") }
|
|
if let playing = playing { parts.append(playing ? "▶" : "■") }
|
|
if parts.count > 0 { self.statusLabel.text = parts.joined(separator: " ") }
|
|
}
|
|
|
|
func updateWidget(uid: String, value: Int) {
|
|
self.widgets[uid]?.update(value: value)
|
|
}
|
|
|
|
func showStatus(_ message: String) {
|
|
DispatchQueue.main.async {
|
|
self.statusToken += 1
|
|
let token = self.statusToken
|
|
self.toolbarStatusLabel.text = message
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
|
|
if self.statusToken == token {
|
|
self.toolbarStatusLabel.text = ""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func statusTimestamp() -> String {
|
|
let formatter = DateFormatter()
|
|
formatter.dateFormat = "h:mm:ss a"
|
|
return "Today \(formatter.string(from: Date()))"
|
|
}
|
|
|
|
}
|