Skip to content

Commit

Permalink
inline date time picker for sitemap
Browse files Browse the repository at this point in the history
Signed-off-by: Tassilo Karge <[email protected]>
  • Loading branch information
TAKeanice committed Nov 13, 2024
1 parent e2a3e0a commit 36b3645
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 39 deletions.
4 changes: 4 additions & 0 deletions openHAB.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
1224F78F228A89FD00750965 /* WatchMessageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1224F78D228A89FC00750965 /* WatchMessageService.swift */; };
2F6412EE2CE494A80039FB28 /* DatePickerUITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6412ED2CE494A80039FB28 /* DatePickerUITableViewCell.swift */; };
2FEFD8F62BE7C5BE00E387B9 /* TextInputUITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEFD8F52BE7C5BE00E387B9 /* TextInputUITableViewCell.swift */; };
4D6470DA2561F935007B03FC /* openHABIntents.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 4D6470D32561F935007B03FC /* openHABIntents.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
653B54C0285C0AC700298ECD /* OpenHABRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653B54BF285C0AC700298ECD /* OpenHABRootViewController.swift */; };
Expand Down Expand Up @@ -270,6 +271,7 @@

/* Begin PBXFileReference section */
1224F78D228A89FC00750965 /* WatchMessageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WatchMessageService.swift; sourceTree = "<group>"; };
2F6412ED2CE494A80039FB28 /* DatePickerUITableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerUITableViewCell.swift; sourceTree = "<group>"; };
2FEFD8F52BE7C5BE00E387B9 /* TextInputUITableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextInputUITableViewCell.swift; sourceTree = "<group>"; };
4D38D951256897490039DA6E /* SetNumberValueIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetNumberValueIntentHandler.swift; sourceTree = "<group>"; };
4D38D959256897770039DA6E /* SetStringValueIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetStringValueIntentHandler.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -897,6 +899,7 @@
DF4B84101886DA9900F34902 /* Widgets */ = {
isa = PBXGroup;
children = (
2F6412ED2CE494A80039FB28 /* DatePickerUITableViewCell.swift */,
DAF0A28E2C56F1EE00A14A6A /* ColorPickerCell.swift */,
DF06F1FB18FEC2020011E7B9 /* ColorPickerViewController.swift */,
DF4B84121886DAC400F34902 /* FrameUITableViewCell.swift */,
Expand Down Expand Up @@ -1547,6 +1550,7 @@
935B484625342B8E00E44CF0 /* URL+Static.swift in Sources */,
B7D5ECE121499E55001B0EC6 /* MapViewTableViewCell.swift in Sources */,
DA6B2EF52C89F8F200DF77CF /* ColorPickerView.swift in Sources */,
2F6412EE2CE494A80039FB28 /* DatePickerUITableViewCell.swift in Sources */,
DAA42BAA21DC983B00244B2A /* VideoUITableViewCell.swift in Sources */,
DFB2623B18830A3600D3244D /* AppDelegate.swift in Sources */,
DA6B2EF72C8B92E800DF77CF /* SelectionView.swift in Sources */,
Expand Down
46 changes: 46 additions & 0 deletions openHAB/DatePickerUITableViewCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2010-2024 Contributors to the openHAB project
//
// See the NOTICE file(s) distributed with this work for additional
// information.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0
//
// SPDX-License-Identifier: EPL-2.0

import OpenHABCore
import UIKit

class DatePickerUITableViewCell: GenericUITableViewCell {
override var widget: OpenHABWidget! {
get {
super.widget
}
set(widget) {
super.widget = widget
switch widget.inputHint {
case .date:
datePicker.datePickerMode = .date
case .time:
datePicker.datePickerMode = .time
case .datetime:
datePicker.datePickerMode = .dateAndTime
default:
fatalError("Must not use this cell for input other than date and time")
}
datePicker.date = ISO8601DateFormatter().date(from: widget.state) ?? Date.now
}
}

weak var controller: OpenHABSitemapViewController!

@IBOutlet private(set) var datePicker: UIDatePicker! {
didSet {
datePicker.addAction(UIAction { [weak self] _ in
guard let self else { return }
controller?.sendCommand(widget.item, commandToSend: datePicker.date.ISO8601Format())
}, for: .valueChanged)
}
}
}
32 changes: 30 additions & 2 deletions openHAB/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,38 @@
</accessibility>
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="TextInputUITableViewCell" id="7ql-eP-dwj" userLabel="TextInputUITableViewCell" customClass="TextInputUITableViewCell" customModule="openHAB" customModuleProvider="target">
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="DatePickerUITableViewCell" id="3hT-nD-bR5" customClass="DatePickerUITableViewCell" customModule="openHAB" customModuleProvider="target">
<rect key="frame" x="0.0" y="85" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3hT-nD-bR5" id="6YV-6e-W01">
<rect key="frame" x="0.0" y="0.0" width="348.66666666666669" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="101" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="780" text="Temp blabla ballall llalla" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2sF-SD-siy">
<rect key="frame" x="61.999999999999986" y="12" width="172.66666666666663" height="20"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="highlightedColor"/>
</label>
<datePicker contentMode="scaleToFill" horizontalHuggingPriority="800" horizontalCompressionResistancePriority="800" contentHorizontalAlignment="center" contentVerticalAlignment="center" datePickerMode="dateAndTime" minuteInterval="1" style="compact" translatesAutoresizingMaskIntoConstraints="NO" id="z76-h7-KYr">
<rect key="frame" x="242.66666666666663" y="4" width="98" height="36"/>
</datePicker>
</subviews>
<constraints>
<constraint firstItem="2sF-SD-siy" firstAttribute="centerY" secondItem="6YV-6e-W01" secondAttribute="centerY" id="IBS-3s-ubY"/>
<constraint firstAttribute="trailing" secondItem="z76-h7-KYr" secondAttribute="trailing" constant="8" id="NfO-Ga-1yL"/>
<constraint firstItem="2sF-SD-siy" firstAttribute="leading" secondItem="6YV-6e-W01" secondAttribute="leading" constant="62" id="UGb-4M-K26"/>
<constraint firstItem="z76-h7-KYr" firstAttribute="leading" secondItem="2sF-SD-siy" secondAttribute="trailing" constant="8" symbolic="YES" id="UH0-6J-KUC"/>
<constraint firstItem="z76-h7-KYr" firstAttribute="centerY" secondItem="6YV-6e-W01" secondAttribute="centerY" id="hmX-72-IFM"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="customTextLabel" destination="2sF-SD-siy" id="GjT-Fl-gux"/>
<outlet property="datePicker" destination="z76-h7-KYr" id="AgZ-MY-7HG"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="TextInputUITableViewCell" id="7ql-eP-dwj" userLabel="TextInputUITableViewCell" customClass="TextInputUITableViewCell" customModule="openHAB" customModuleProvider="target">
<rect key="frame" x="0.0" y="129" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="7ql-eP-dwj" id="djo-VL-ZpJ">
<rect key="frame" x="0.0" y="0.0" width="348.66666666666669" height="44"/>
<autoresizingMask key="autoresizingMask"/>
Expand All @@ -69,7 +98,6 @@
</label>
</subviews>
<constraints>
<constraint firstItem="D4l-PV-8or" firstAttribute="width" relation="greaterThanOrEqual" secondItem="djo-VL-ZpJ" secondAttribute="width" multiplier="0.1" priority="999" placeholder="YES" id="7WF-4Z-quI"/>
<constraint firstItem="OhF-CW-Anz" firstAttribute="centerY" secondItem="djo-VL-ZpJ" secondAttribute="centerY" id="9Lv-Q7-Jqy"/>
<constraint firstItem="OhF-CW-Anz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="D4l-PV-8or" secondAttribute="trailing" constant="8" id="Uxn-Cp-qdN"/>
<constraint firstAttribute="trailing" secondItem="OhF-CW-Anz" secondAttribute="trailing" constant="5" id="eq4-X2-Qod"/>
Expand Down
68 changes: 31 additions & 37 deletions openHAB/OpenHABSitemapViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,13 @@ extension OpenHABSitemapViewController: UITableViewDelegate, UITableViewDataSour
case .mapview:
cell = tableView.dequeueReusableCell(for: indexPath) as MapViewTableViewCell
case .input:
cell = tableView.dequeueReusableCell(for: indexPath) as TextInputUITableViewCell
if [.date, .time, .datetime].contains(widget.inputHint) {
let pickerCell = tableView.dequeueReusableCell(for: indexPath) as DatePickerUITableViewCell
pickerCell.controller = self
cell = pickerCell
} else {
cell = tableView.dequeueReusableCell(for: indexPath) as TextInputUITableViewCell
}
case .group, .text, .defaultWidget, .unknown:
cell = tableView.dequeueReusableCell(for: indexPath) as GenericUITableViewCell
}
Expand Down Expand Up @@ -804,56 +810,44 @@ extension OpenHABSitemapViewController: UITableViewDelegate, UITableViewDataSour
navigationController?.pushViewController(hostingController, animated: true)
} else if widget.type == .input {
let hint = widget.inputHint
// TODO: proper texts instead of hardcoded values
let alert = UIAlertController(
title: "Enter new value",
message: "Current value for \(widget.label) is \(widget.state)",
preferredStyle: .alert
)
let textExtractor: ((UIAlertController) -> String?)?
let textFieldAdder: ((UITextField) -> Void)?

let textExtractor: () -> String?
switch hint {
case .date:
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
alert.view.addSubview(datePicker)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
dateFormatter.timeStyle = .none
textExtractor = { dateFormatter.string(from: datePicker.date) }
case .datetime:
let datePicker = UIDatePicker()
datePicker.datePickerMode = .dateAndTime
alert.view.addSubview(datePicker)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
dateFormatter.timeStyle = .full
textExtractor = { dateFormatter.string(from: datePicker.date) }
case .time:
let datePicker = UIDatePicker()
datePicker.datePickerMode = .time
alert.view.addSubview(datePicker)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .none
dateFormatter.timeStyle = .full
textExtractor = { dateFormatter.string(from: datePicker.date) }
case .date, .time, .datetime:
// value setting is handeled by the cell itself
textExtractor = nil
textFieldAdder = nil
case .number:
alert.addTextField { textField in
textFieldAdder = { textField in
textField.text = widget.state
textField.clearButtonMode = .always
textField.delegate = self
textField.keyboardType = .numbersAndPunctuation
}
// replace expected decimal separator
textExtractor = { alert.textFields?[0].text?.replacingOccurrences(of: NSLocale.current.decimalSeparator ?? "", with: ".") }
textExtractor = { $0.textFields?[0].text?.replacingOccurrences(of: NSLocale.current.decimalSeparator ?? "", with: ".") }
case .text:
alert.addTextField { textField in
textFieldAdder = { textField in
textField.text = widget.state
textField.clearButtonMode = .always
textField.keyboardType = .default
}
textExtractor = { alert.textFields?[0].text }
textExtractor = { $0.textFields?[0].text }
}
guard let textExtractor, let textFieldAdder else {
return
}

// TODO: proper texts instead of hardcoded values
let alert = UIAlertController(
title: "Enter new value",
message: "Current value for \(widget.label) is \(widget.state)",
preferredStyle: .alert
)
alert.addTextField(configurationHandler: textFieldAdder)
let sendAction = UIAlertAction(title: "Set value", style: .destructive, handler: { [weak self] _ in
self?.sendCommand(widget.item, commandToSend: textExtractor())
self?.sendCommand(widget.item, commandToSend: textExtractor(alert))
})
alert.addAction(sendAction)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
Expand Down

0 comments on commit 36b3645

Please sign in to comment.