Skip to content

Commit

Permalink
Issue #386: Support vertical blind
Browse files Browse the repository at this point in the history
  • Loading branch information
mipolansk committed Jun 5, 2024
1 parent 37d45c7 commit 3be1f3f
Show file tree
Hide file tree
Showing 43 changed files with 1,536 additions and 41 deletions.
48 changes: 48 additions & 0 deletions SUPLA.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,12 @@
A58316FC2B64510A006113F8 /* ThermometerValueStringProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58316FB2B64510A006113F8 /* ThermometerValueStringProvider.swift */; };
A58316FE2B6452AB006113F8 /* ThermometerAndHumidityValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58316FD2B6452AB006113F8 /* ThermometerAndHumidityValueProvider.swift */; };
A58317002B645814006113F8 /* ThermometerAndHumidityValueStringProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58316FF2B645814006113F8 /* ThermometerAndHumidityValueStringProvider.swift */; };
A58A63052C0715E500A9D02D /* VerticalBlindsVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A63042C0715E500A9D02D /* VerticalBlindsVM.swift */; };
A58A63072C07163E00A9D02D /* VerticalBlindWindowState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A63062C07163E00A9D02D /* VerticalBlindWindowState.swift */; };
A58A63092C07168400A9D02D /* VerticalBlindMarker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A63082C07168400A9D02D /* VerticalBlindMarker.swift */; };
A58A630B2C071ACB00A9D02D /* VerticalBlindsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A630A2C071ACB00A9D02D /* VerticalBlindsVC.swift */; };
A58A630E2C071B0600A9D02D /* VerticalBlindsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A630D2C071B0600A9D02D /* VerticalBlindsView.swift */; };
A58A63132C09B56000A9D02D /* VerticalBlindsVMTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A63122C09B56000A9D02D /* VerticalBlindsVMTests.swift */; };
A58A9BFA2A9F77BB00D28848 /* BaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A9BF92A9F77BB00D28848 /* BaseCell.swift */; };
A58A9BFE2AA0A4BD00D28848 /* UIView+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A9BFD2AA0A4BD00D28848 /* UIView+Ext.swift */; };
A58A9C012AA0AD0E00D28848 /* ThermostatCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A9C002AA0AD0E00D28848 /* ThermostatCell.swift */; };
Expand Down Expand Up @@ -2033,6 +2039,12 @@
A58316FB2B64510A006113F8 /* ThermometerValueStringProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThermometerValueStringProvider.swift; sourceTree = "<group>"; };
A58316FD2B6452AB006113F8 /* ThermometerAndHumidityValueProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThermometerAndHumidityValueProvider.swift; sourceTree = "<group>"; };
A58316FF2B645814006113F8 /* ThermometerAndHumidityValueStringProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThermometerAndHumidityValueStringProvider.swift; sourceTree = "<group>"; };
A58A63042C0715E500A9D02D /* VerticalBlindsVM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VerticalBlindsVM.swift; path = SUPLA/Features/Details/WindowDetail/VerticalBlind/VerticalBlindsVM.swift; sourceTree = SOURCE_ROOT; };
A58A63062C07163E00A9D02D /* VerticalBlindWindowState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalBlindWindowState.swift; sourceTree = "<group>"; };
A58A63082C07168400A9D02D /* VerticalBlindMarker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalBlindMarker.swift; sourceTree = "<group>"; };
A58A630A2C071ACB00A9D02D /* VerticalBlindsVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalBlindsVC.swift; sourceTree = "<group>"; };
A58A630D2C071B0600A9D02D /* VerticalBlindsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalBlindsView.swift; sourceTree = "<group>"; };
A58A63122C09B56000A9D02D /* VerticalBlindsVMTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalBlindsVMTests.swift; sourceTree = "<group>"; };
A58A9BF92A9F77BB00D28848 /* BaseCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCell.swift; sourceTree = "<group>"; };
A58A9BFD2AA0A4BD00D28848 /* UIView+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Ext.swift"; sourceTree = "<group>"; };
A58A9C002AA0AD0E00D28848 /* ThermostatCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThermostatCell.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3088,6 +3100,7 @@
A5074BBB2BCE5CBF0081B6B1 /* UI */ = {
isa = PBXGroup;
children = (
A58A630C2C071AF400A9D02D /* VerticalBlind */,
A5AD70192C00B1C300A36318 /* Controls */,
A50E5D782BFF551B00303BAE /* Curtain */,
A50B5D3B2BFB6E9100918D18 /* ProjectorScreen */,
Expand Down Expand Up @@ -3203,6 +3216,7 @@
A50B5D102BECC58800918D18 /* WindowDetail */ = {
isa = PBXGroup;
children = (
A58A63112C09B54B00A9D02D /* VerticalBlind */,
A5AD702A2C04771500A36318 /* Curtain */,
A50B5D312BF54FE600918D18 /* TerraceAwning */,
A50B5D1E2BECE8B100918D18 /* FacadeBlinds */,
Expand Down Expand Up @@ -3943,6 +3957,7 @@
A55A8D6C2BA831AD00C540D4 /* WindowDetail */ = {
isa = PBXGroup;
children = (
A58A63032C07154700A9D02D /* VerticalBlind */,
A50E5D712BFF540700303BAE /* Curtain */,
A50B5D342BFB6BDB00918D18 /* ProjectorScreen */,
A50B5D272BF49F0D00918D18 /* TerraceAwning */,
Expand Down Expand Up @@ -4012,7 +4027,9 @@
A55A8D9A2BAB802B00C540D4 /* RollerShutterAction.swift */,
A50B5D052BEA4DA700918D18 /* RollerShutterWindowState.swift */,
A50B5D072BEA4E2A00918D18 /* FacadeBlindWindowState.swift */,
A58A63062C07163E00A9D02D /* VerticalBlindWindowState.swift */,
A50B5D092BEA4EC700918D18 /* FacadeBlindMarker.swift */,
A58A63082C07168400A9D02D /* VerticalBlindMarker.swift */,
A50B5D2C2BF49F7700918D18 /* TerraceAwningWindowState.swift */,
A50B5D372BFB6D1400918D18 /* ProjectorScreenState.swift */,
A50E5D762BFF548200303BAE /* CurtainWindowState.swift */,
Expand Down Expand Up @@ -4326,6 +4343,31 @@
path = Model;
sourceTree = "<group>";
};
A58A63032C07154700A9D02D /* VerticalBlind */ = {
isa = PBXGroup;
children = (
A58A630A2C071ACB00A9D02D /* VerticalBlindsVC.swift */,
A58A63042C0715E500A9D02D /* VerticalBlindsVM.swift */,
);
path = VerticalBlind;
sourceTree = "<group>";
};
A58A630C2C071AF400A9D02D /* VerticalBlind */ = {
isa = PBXGroup;
children = (
A58A630D2C071B0600A9D02D /* VerticalBlindsView.swift */,
);
path = VerticalBlind;
sourceTree = "<group>";
};
A58A63112C09B54B00A9D02D /* VerticalBlind */ = {
isa = PBXGroup;
children = (
A58A63122C09B56000A9D02D /* VerticalBlindsVMTests.swift */,
);
path = VerticalBlind;
sourceTree = "<group>";
};
A58A9BF82A9F77A400D28848 /* Cells */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -5832,6 +5874,7 @@
A55501FC2B83F28800FD3296 /* InsertNotificationUseCase.swift in Sources */,
01C1719922C7F55B005983E1 /* SAMeasurementItem+CoreDataClass.m in Sources */,
A55A8D722BA8406900C540D4 /* WindowDetailVC.swift in Sources */,
A58A630E2C071B0600A9D02D /* VerticalBlindsView.swift in Sources */,
A5F29BE62A27739000ED700A /* MoveableCell.swift in Sources */,
A5AE7A8F2A3AE0290097FA8B /* TitleArrowButtonCell.swift in Sources */,
A5CE73292B4607AE003F882C /* EspConfigResult.swift in Sources */,
Expand Down Expand Up @@ -5893,6 +5936,7 @@
A55501F52B83842000FD3296 /* NotificationsLogVC.swift in Sources */,
A55A8DAC2BAC60A200C540D4 /* SAAuthorizationDialogVM.swift in Sources */,
0148933425AA12DB00B9974E /* SADiwCalibrationTool.m in Sources */,
A58A630B2C071ACB00A9D02D /* VerticalBlindsVC.swift in Sources */,
01C1719222C7F3A2005983E1 /* SAElectricityMeasurementItem+CoreDataProperties.m in Sources */,
A5D837DD2AF12B5B002A420D /* BaseLoadMeasurementsUseCase.swift in Sources */,
40AB8BDE1DCB32EB0030F3DE /* SARateApp.m in Sources */,
Expand Down Expand Up @@ -6266,6 +6310,7 @@
A530EE082A557EE400F8DAEE /* CircleControlButtonView.swift in Sources */,
A57C88302ACAA445000B0F10 /* ValuesFormatter.swift in Sources */,
A52BFEB92B065BF800A2F64C /* SuplaConfigResult.swift in Sources */,
A58A63052C0715E500A9D02D /* VerticalBlindsVM.swift in Sources */,
40A6757F1BA1A5B6004A51C4 /* SuplaApp.m in Sources */,
A50B5D502BFCBDFB00918D18 /* OpenedClosedGroupActivePercentageProvider.swift in Sources */,
018CFD2023281A5900888CB7 /* SAElectricityMeterExtendedValue.m in Sources */,
Expand All @@ -6274,6 +6319,7 @@
A54149272B63031800B44BD6 /* GpmDetailVM.swift in Sources */,
A51BE8FC2AA7300A00718F2F /* ThermometerValues.swift in Sources */,
A5F29BD82A26240E00ED700A /* ThermostatMeasurementItemRepository.swift in Sources */,
A58A63072C07163E00A9D02D /* VerticalBlindWindowState.swift in Sources */,
A5F29BC42A24E35C00ED700A /* ChangeGroupsVisibilityUseCase.swift in Sources */,
A5B3CBEF2B625D9000F95AC3 /* WeightValueProvider.swift in Sources */,
A50B5D4E2BFCBDAE00918D18 /* HeatpolThermostatGroupActivePercentageProvider.swift in Sources */,
Expand Down Expand Up @@ -6415,6 +6461,7 @@
A5A14A312B60F76A004B1598 /* IconValueCell.swift in Sources */,
A5AE7A852A3AC7020097FA8B /* BaseSettingsCell.swift in Sources */,
A52BFEEC2B173F7100A2F64C /* ReadProfileByIdUseCase.swift in Sources */,
A58A63092C07168400A9D02D /* VerticalBlindMarker.swift in Sources */,
A530EE242A57006A00F8DAEE /* LiquidSensorIconNameProducer.swift in Sources */,
A55A8D912BAB13B300C540D4 /* RollerShutterValue.swift in Sources */,
A530EDFD2A54153000F8DAEE /* SwitchDetailNavigationCoordinator.swift in Sources */,
Expand Down Expand Up @@ -6516,6 +6563,7 @@
A530EE392A57FCE200F8DAEE /* GetChannelBaseStateUseCaseTests.swift in Sources */,
A5E40B662B86249E00DB6ABE /* GpmHistoryDetailVMTests.swift in Sources */,
A5ABE5B72ABC278700FFA50B /* ChannelConfigEventsManagerMock.swift in Sources */,
A58A63132C09B56000A9D02D /* VerticalBlindsVMTests.swift in Sources */,
A59AB8D12A3091EE00D91F1F /* SceneRepositoryMock.swift in Sources */,
A59AB8B32A3078FB00D91F1F /* SceneListVMTests.swift in Sources */,
A54A06882AF9252C00C03DBC /* MultiAccountProfileManagerTests.swift in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions SUPLA/ChannelCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ -(void) updateCellView {
case SUPLA_CHANNELFNC_TERRACE_AWNING:
case SUPLA_CHANNELFNC_PROJECTOR_SCREEN:
case SUPLA_CHANNELFNC_CURTAIN:
case SUPLA_CHANNELFNC_VERTICAL_BLIND:
self.left_OnlineStatus.hidden = YES;
self.right_OnlineStatus.hidden = NO;
break;
Expand Down Expand Up @@ -392,6 +393,7 @@ -(void) updateCellView {
case SUPLA_CHANNELFNC_TERRACE_AWNING:
case SUPLA_CHANNELFNC_PROJECTOR_SCREEN:
case SUPLA_CHANNELFNC_CURTAIN:
case SUPLA_CHANNELFNC_VERTICAL_BLIND:
br = [MGSwipeButton buttonWithTitle:NSLocalizedString(@"Open", nil) icon:nil backgroundColor:[UIColor blackColor]];
bl = [MGSwipeButton buttonWithTitle:NSLocalizedString(@"Close", nil) icon:nil backgroundColor:[UIColor blackColor]];
break;
Expand Down
14 changes: 13 additions & 1 deletion SUPLA/Core/UI/Details/StandardDetailVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ class StandardDetailVC<S : ViewState, E : ViewEvent, VM : StandardDetailVM<S, E>
viewControllers.append(projectorScreenDetail())
case .curtain:
viewControllers.append(curtainDetail())

case .verticalBlind:
viewControllers.append(verticalBlindDetail())
}
}

Expand Down Expand Up @@ -277,6 +278,17 @@ class StandardDetailVC<S : ViewState, E : ViewEvent, VM : StandardDetailVM<S, E>
)
return vc
}

private func verticalBlindDetail() -> VerticalBlindsVC {
let vc = VerticalBlindsVC(itemBundle: item)
vc.navigationCoordinator = navigationCoordinator
vc.tabBarItem = UITabBarItem(
title: settings.showBottomLabels ? Strings.StandardDetail.tabGeneral : nil,
image: .iconGeneral,
tag: DetailTabTag.Window.rawValue
)
return vc
}
}

protocol NavigationItemProvider: AnyObject {
Expand Down
3 changes: 2 additions & 1 deletion SUPLA/Core/UI/TableView/BaseTableViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class BaseTableViewModel<S: ViewState, E: ViewEvent>: BaseViewModel<S, E> {
SUPLA_CHANNELFNC_CONTROLLINGTHEFACADEBLIND,
SUPLA_CHANNELFNC_TERRACE_AWNING,
SUPLA_CHANNELFNC_PROJECTOR_SCREEN,
SUPLA_CHANNELFNC_CURTAIN:
SUPLA_CHANNELFNC_CURTAIN,
SUPLA_CHANNELFNC_VERTICAL_BLIND:
return true
case SUPLA_CHANNELFNC_LIGHTSWITCH,
SUPLA_CHANNELFNC_POWERSWITCH,
Expand Down
3 changes: 2 additions & 1 deletion SUPLA/Core/UI/TableView/ChannelBaseTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ class ChannelBaseTableViewController<S: ViewState, E: ViewEvent, VM: BaseTableVi
SUPLA_CHANNELFNC_CONTROLLINGTHEROLLERSHUTTER,
SUPLA_CHANNELFNC_TERRACE_AWNING,
SUPLA_CHANNELFNC_PROJECTOR_SCREEN,
SUPLA_CHANNELFNC_CURTAIN:
SUPLA_CHANNELFNC_CURTAIN,
SUPLA_CHANNELFNC_VERTICAL_BLIND:
return cellIdForIcon
default:
return cellIdForChannel
Expand Down
6 changes: 4 additions & 2 deletions SUPLA/Features/ChannelList/Cells/IconCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ final class IconCell: BaseCell<ChannelWithChildren> {
SUPLA_CHANNELFNC_CONTROLLINGTHEROLLERSHUTTER,
SUPLA_CHANNELFNC_TERRACE_AWNING,
SUPLA_CHANNELFNC_PROJECTOR_SCREEN,
SUPLA_CHANNELFNC_CURTAIN: true
SUPLA_CHANNELFNC_CURTAIN,
SUPLA_CHANNELFNC_VERTICAL_BLIND: true
default: false
}
}
Expand All @@ -118,7 +119,8 @@ final class IconCell: BaseCell<ChannelWithChildren> {
SUPLA_CHANNELFNC_CONTROLLINGTHEROLLERSHUTTER,
SUPLA_CHANNELFNC_TERRACE_AWNING,
SUPLA_CHANNELFNC_PROJECTOR_SCREEN,
SUPLA_CHANNELFNC_CURTAIN: true
SUPLA_CHANNELFNC_CURTAIN,
SUPLA_CHANNELFNC_VERTICAL_BLIND: true
default: false
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
Copyright (C) AC SOFTWARE SP. Z O.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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

struct VerticalBlindMarker: Equatable {
let position: CGFloat
let tilt: CGFloat
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright (C) AC SOFTWARE SP. Z O.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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

struct VerticalBlindWindowState: WindowState, Equatable, Changeable {
/**
* The blind roller position in percentage
* 0 - open
* 100 - closed
*/
var position: WindowGroupedValue

var positionTextFormat: WindowGroupedValueFormat = .percentage

/**
* Slat tilt as percentage - 0 up to 100
*/
var slatTilt: WindowGroupedValue? = nil

var tiltTextFormat: WindowGroupedValueFormat = .degree

var tilt0Angle: CGFloat? = nil

var tilt100Angle: CGFloat? = nil

var markers: [VerticalBlindMarker] = []

var slatTiltDegrees: CGFloat? {
guard let tilt = slatTilt else { return nil }
return tilt.asAngle(tilt0Angle ?? DEFAULT_TILT_0_ANGLE, tilt100Angle ?? DEFAULT_TILT_100_ANGLE)
}

var slatTiltText: String {
guard let tilt = slatTilt else { return Strings.FacadeBlindsDetail.noTilt }
return tilt.asString(tiltTextFormat, value0: tilt0Angle, value100: tilt100Angle)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import RxSwift

class WindowHorizontalControls: WindowControls {
override var intrinsicContentSize: CGSize {
return CGSize(width: ControlButtonType.left.width * 2, height: ControlButtonType.up.height * 2)
let touchTimeIconHeight: CGFloat = 25
let height = ControlButtonType.left.height * 2 + Dimens.distanceTiny + Dimens.distanceDefault + touchTimeIconHeight
return CGSize(width: ControlButtonType.left.width * 2, height: height)
}

override var isEnabled: Bool {
Expand Down Expand Up @@ -90,16 +92,17 @@ class WindowHorizontalControls: WindowControls {

private func setupLayout() {
NSLayoutConstraint.activate([
holdToMoveButton.centerYAnchor.constraint(equalTo: centerYAnchor),
moveTimeView.topAnchor.constraint(equalTo: topAnchor),
moveTimeView.centerXAnchor.constraint(equalTo: centerXAnchor),

holdToMoveButton.leftAnchor.constraint(equalTo: leftAnchor),
holdToMoveButton.rightAnchor.constraint(equalTo: rightAnchor),
holdToMoveButton.topAnchor.constraint(equalTo: moveTimeView.bottomAnchor, constant: Dimens.distanceTiny),

pressToMoveButton.topAnchor.constraint(equalTo: holdToMoveButton.bottomAnchor, constant: Dimens.distanceSmall),
pressToMoveButton.topAnchor.constraint(equalTo: holdToMoveButton.bottomAnchor, constant: Dimens.distanceDefault),
pressToMoveButton.leftAnchor.constraint(equalTo: leftAnchor),
pressToMoveButton.rightAnchor.constraint(equalTo: rightAnchor),

moveTimeView.centerXAnchor.constraint(equalTo: centerXAnchor),
moveTimeView.bottomAnchor.constraint(equalTo: holdToMoveButton.topAnchor, constant: -Dimens.distanceSmall)
pressToMoveButton.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
}
Loading

0 comments on commit 3be1f3f

Please sign in to comment.