From 1a719e11e6ddf9cb421ab3d33b4c96c8551c5b76 Mon Sep 17 00:00:00 2001 From: True Zhuanjia Date: Mon, 8 Jun 2026 01:16:00 +0800 Subject: [PATCH] - tweak widget templates - minor improvements & fixes --- VoidLink/Input/OnScreenWidgetView.swift | 47 +++++++++--- VoidLink/Input/TouchPadGestureHandler.swift | 6 +- VoidLink/Input/UITouchUtil.swift | 6 +- VoidLink/Localization/Localizable.xcstrings | 68 ++++++++++++++++-- VoidLink/PresetConfigs/widgetTemplates.bin | Bin 595605 -> 595606 bytes .../PresetConfigs/widgetTemplatesIPhone.bin | Bin 559589 -> 555345 bytes ...LayoutOnScreenControlsViewController.swift | 4 +- .../StreamFrameViewController.m | 24 +++++++ VoidLinkPreview/WidgetPickerView.swift | 3 +- 9 files changed, 136 insertions(+), 22 deletions(-) diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift index ed94cd3f..6a316f55 100644 --- a/VoidLink/Input/OnScreenWidgetView.swift +++ b/VoidLink/Input/OnScreenWidgetView.swift @@ -400,6 +400,7 @@ import ObjectiveC.runtime @objc private(set) var firstTouchMoved: Bool = false private var mousePointerMoved: Bool private var twoTouchesDetected: Bool + private var scrollEventSent: Bool = false private var allSpawnedTouchesCount: Int = 0 // trackball @@ -681,6 +682,10 @@ import ObjectiveC.runtime self.isMagnifier = self.cmdString.contains("MAGNIFIER") self.hasAnchorMode = isDisplacementBasedStickPad || isDirectionPad + + self.isMultipleTouchEnabled = self.widgetType == WidgetTypeEnum.button + || CommandManager.mousePadWithButtonActions.contains(self.touchPadString) + || self.touchPadString == "MAGNIFIER" } // ====================================================================================================== @@ -1062,7 +1067,7 @@ import ObjectiveC.runtime } let attr = NSAttributedString( - string: self.folded ? "[\(text)]" : (self.isFolder ? " 🟡 \(text)" : "\(text)"), + string: (self.isFolder && self.folded) ? "[\(text)]" : (self.isFolder ? " 🟡 \(text)" : "\(text)"), attributes: [ .foregroundColor: UIColor(white:labelAlpha>0 ? 1.0 : 0, alpha: abs(labelAlpha)), // 填充色 .strokeColor: (labelAlpha>0 ? UIColor.black : UIColor.white).withAlphaComponent(abs(labelAlpha)*0.43), // 描边色 @@ -2060,14 +2065,11 @@ import ObjectiveC.runtime self.touchBegan = true self.directionPadTouchBegan = true self.firstTouchMoved = false + self.scrollEventSent = false self.tickFlag = 0 // super.touchesBegan(touches, with: event) if OnScreenWidgetView.editMode {self.parentViewController?.touchesBegan(touches, with: event)} - self.isMultipleTouchEnabled = self.widgetType == WidgetTypeEnum.button - || CommandManager.mousePadWithButtonActions.contains(self.touchPadString) - || self.touchPadString == "MAGNIFIER" - if !OnScreenWidgetView.editMode && self.touchPadString == "TRACKBALL" { stopTrackballMomentum() } @@ -2553,14 +2555,15 @@ import ObjectiveC.runtime private func handleTouchPadMoveEvent (_ touches: Set, with event: UIEvent?){ guard let touch = touches.first else { return } - if touches.count == 1{ // don't use event.alltouches.count here, it will counts all touches + let activeTouchesCount = UITouchUtil.touches(in: self, from: event).count + if activeTouchesCount == 1 { // don't use event.alltouches.count here, it will counts all touches self.getVector(touch: touch) switch self.touchPadString{ case "MOUSEPAD": DispatchQueue.global(qos: .userInteractive).async { self.weightedDeltaX = Int(self.deltaX * 1.7 * self.sensitivityFactorX) self.weightedDeltaY = Int(self.deltaY * 1.7 * self.sensitivityFactorY) - if self.firstTouchMoved {LiSendMouseMoveEvent(Int16(self.weightedDeltaX), Int16(self.weightedDeltaY))} + if self.firstTouchMoved, !self.scrollEventSent {LiSendMouseMoveEvent(Int16(self.weightedDeltaX), Int16(self.weightedDeltaY))} self.updateTouchLocation(touch: touch) } break @@ -2672,6 +2675,25 @@ import ObjectiveC.runtime break } } + if activeTouchesCount == 2 { + self.getVector(touch: touch) + switch self.touchPadString{ + case "MOUSEPAD": + if self.mouseButtonAction == .hovering, firstTouchMoved { + mousePointerMoved = false + let touchesArr = Array(touches) + let vector = UITouchUtil.midPointVector(between: touchesArr.first, and: touchesArr.last, in: self) + self.scrollEventSent = true + if abs(vector.dx) > 1.2*abs(vector.dy) { + LiSendHighResHScrollEvent(-Int16(vector.dx*5)) + } + else { + LiSendHighResScrollEvent(Int16(vector.dy*5)) + } + } + default: break + } + } if self.widgetType == WidgetTypeEnum.touchPad && self.touchPadString == "DS4TOUCH" { self.handleControllerTouchesMove(touches: touches) } @@ -3029,12 +3051,15 @@ import ObjectiveC.runtime if !OnScreenWidgetView.editMode && self.widgetType == WidgetTypeEnum.touchPad && CommandManager.mousePadWithButtonActions.contains(self.touchPadString) && allSpawnedTouchesCount == 1 && !twoTouchesDetected { self.handleMousePadButtonActionUp() } - if !OnScreenWidgetView.editMode && self.widgetType == WidgetTypeEnum.touchPad && CommandManager.mousePadWithButtonActions.contains(self.touchPadString) && twoTouchesDetected && touches.count == allSpawnedTouchesCount { // need to enable multi-touch first // touches.count == allCapturedTouchesCount means allfingers are lifting - if(self.mouseButtonAction == MouseButtonAction.hovering) {self.sendMouseRightButtonClickEvent()} - twoTouchesDetected = false + if self.mouseButtonAction == MouseButtonAction.hovering, !scrollEventSent {self.sendMouseRightButtonClickEvent()} + } + if touches.count == allSpawnedTouchesCount { firstTouchMoved = false + twoTouchesDetected = false + scrollEventSent = false + twoTouchesDetected = false } // then other types of pads or buttons with touchPad function @@ -3279,10 +3304,12 @@ import ObjectiveC.runtime if OnScreenWidgetView.capturer == nil, OnScreenWidgetView.editMode { if OnScreenWidgetView.isVerticallyAligned { self.center = CGPoint(x:OnScreenWidgetView.alignedX, y:self.center.y) + self.storedCenter = self.center OnScreenWidgetView.isVerticallyAligned = false } if OnScreenWidgetView.isHorizontallyAligned { self.center = CGPoint(x:self.center.x, y:OnScreenWidgetView.alignedY) + self.storedCenter = self.center OnScreenWidgetView.isHorizontallyAligned = false } } diff --git a/VoidLink/Input/TouchPadGestureHandler.swift b/VoidLink/Input/TouchPadGestureHandler.swift index 4f64fe76..b683dfac 100644 --- a/VoidLink/Input/TouchPadGestureHandler.swift +++ b/VoidLink/Input/TouchPadGestureHandler.swift @@ -49,12 +49,14 @@ import UIKit let midPointDeltaX = midPointVector.dx let midPointDeltaY = midPointVector.dy - inertialScroller.vector = CGVector(dx: midPointDeltaX, dy: midPointDeltaY) + let sendHorizontalScroll = abs(midPointDeltaX) > 1.2*abs(midPointDeltaY) + + inertialScroller.vector = CGVector(dx: sendHorizontalScroll ? midPointDeltaX : 0, dy: midPointDeltaY) let originalPinchDelta = currentDistance-previousDistance; let pinchDelta = enablePinch ? originalPinchDelta*7*pinchSensitivity : 0; LiSendHighResScrollEvent(Int16(pinchDelta + midPointDeltaY*7*scrollSensitivity)) - if enableHorizontalScroll {LiSendHighResHScrollEvent(Int16(-midPointDeltaX*7*scrollSensitivity))} + if enableHorizontalScroll, sendHorizontalScroll {LiSendHighResHScrollEvent(Int16(-midPointDeltaX*7*scrollSensitivity))} if enablePinch, ctrlDownForPinch { let midPointDelta = hypot(midPointDeltaX, midPointDeltaY) diff --git a/VoidLink/Input/UITouchUtil.swift b/VoidLink/Input/UITouchUtil.swift index 086a334c..9ca81593 100644 --- a/VoidLink/Input/UITouchUtil.swift +++ b/VoidLink/Input/UITouchUtil.swift @@ -10,8 +10,10 @@ import UIKit @objc class UITouchUtil: NSObject { @objc public static func touches(in view: UIView, from event: UIEvent?) -> Set { - guard (event?.allTouches) != nil else { return [] } - return event?.allTouches?.filter({ $0.view == view && ($0.type == .direct || $0.type == .pencil)}) ?? [] + guard let touches = event?.allTouches else { return [] } + return touches.filter { + $0.view === view && ($0.type == .direct || $0.type == .pencil) + } } @objc public static func distance(between touch1: UITouch?, and touch2: UITouch?, in view: UIView?) -> CGFloat { diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings index d9c0ba50..c5ddebb2 100644 --- a/VoidLink/Localization/Localizable.xcstrings +++ b/VoidLink/Localization/Localizable.xcstrings @@ -1220,7 +1220,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "Enter PiP" + "value" : "PiP" } }, "zh-Hans" : { @@ -1231,13 +1231,13 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "子母畫面" } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "子母畫面" } } @@ -1382,7 +1382,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "控制項夾" } } @@ -11839,7 +11839,7 @@ }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/nm6l9yixu0idsybg#32535f99" } }, @@ -12120,6 +12120,64 @@ } } }, + "pipDisabled" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Please enable Picture in Picture in both System Settings and the app settings." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "请在系统设置与 App 设置中启用画中画" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "請在系統設定與 App 設定中啟用子母畫面。" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "請在系統設定與 App 設定中啟用子母畫面。" + } + } + } + }, + "pipNotSupported" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Picture in Picture is not supported by the system." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "系统不支持画中画。" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "系統不支援子母畫面。" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "系統不支援子母畫面。" + } + } + } + }, "pipStackTip" : { "extractionState" : "manual", "localizations" : { diff --git a/VoidLink/PresetConfigs/widgetTemplates.bin b/VoidLink/PresetConfigs/widgetTemplates.bin index 90d3406762a14aedb7774581586b7ae9c85cae36..fd4f340263985bf87e4112d6de20bebe79a89c36 100644 GIT binary patch delta 5734 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 aiY{Z|6kWx@DY}z^Q}p2UQZY_>#!~>Sg;fRs delta 5939 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 diff --git a/VoidLink/PresetConfigs/widgetTemplatesIPhone.bin b/VoidLink/PresetConfigs/widgetTemplatesIPhone.bin index 663b4c830a008a309c3999a5690b01d770fab2b6..2fbdae730648062fe843a59256071d504b7bf9ad 100644 GIT binary patch delta 7769 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 ACjbBd diff --git a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift index efd6e33a..343bd460 100644 --- a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift +++ b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift @@ -1252,7 +1252,6 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg newWidget.sequence = widget.sequence newWidget.autoDockIdleDuration = widget.autoDockIdleDuration newWidget.autoDockSettledAlpha = widget.autoDockSettledAlpha - newWidget.folded = widget.folded newWidget.revealMode = widget.revealMode newWidget.bulkMoveEnabled = widget.bulkMoveEnabled newWidget.layoutUpdateDelegate = self @@ -1283,6 +1282,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg guard newWidget.widgetType == widget.widgetType else { return } view.insertSubview(newWidget, belowSubview: widgetPanelStack) newWidget.accessWidgetAttributes() + newWidget.folded = newWidget.isFolder && widget.folded newWidget.buttonMode = (newWidget.widgetType == .button && newWidget.touchPadString != "") ? .regular : widget.buttonMode newWidget.sensitivityFactorX = widget.sensitivityFactorX newWidget.componentSizeFactor = widget.componentSizeFactor @@ -1304,7 +1304,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg newWidget.adjustTransparency(alpha: widget.originalBackgroundAlpha, tweakBorderAlpha: false) newWidget.tweakLabelAlpha(alpha: widget.originalLabelAlpha) - if widget.isFolder {newWidget.reverseColorPhase(reversed: !newWidget.folded)} + if newWidget.isFolder {newWidget.reverseColorPhase(reversed: !newWidget.folded)} newWidget.tweakBorderAlpha(alpha: widget.borderAlpha) newWidget.tweakHighlightAlpha(alpha: widget.highlightAlpha) diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index e224d0ea..fb7b30ac 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -1057,6 +1057,30 @@ static NSString* VLTerminationHintForErrorCode(int errorCode) { } - (void)enterPip{ + if (@available(iOS 15.0, tvOS 15.0, *)) { + if(!_settings.enablePIP){ + AlertControllerUtil.autoCompletion = true; + [AlertControllerUtil showAlertIn:self + title:@"" + message:[LocalizationHelper localizedStringForKey:@"pipDisabled"] + withCancel:NO + buttonTitle:@"" + countdown:1 + action:^{} + completion:^{}]; + } + } + else { + AlertControllerUtil.autoCompletion = true; + [AlertControllerUtil showAlertIn:self + title:@"" + message:[LocalizationHelper localizedStringForKey:@"pipNotSupported"] + withCancel:NO + buttonTitle:@"" + countdown:1 + action:^{} + completion:^{}]; + } [self.pipController startPictureInPicture]; } diff --git a/VoidLinkPreview/WidgetPickerView.swift b/VoidLinkPreview/WidgetPickerView.swift index f5be7efd..bea04015 100644 --- a/VoidLinkPreview/WidgetPickerView.swift +++ b/VoidLinkPreview/WidgetPickerView.swift @@ -3280,7 +3280,8 @@ struct WidgetPickerView: View { } private var comboJoiner: String { - (isShortcutPickerMode || effectiveWidgetComboMode == .shortcut) ? "+" : "-" + (isShortcutPickerMode || effectiveWidgetComboMode == .shortcut) + && selectedFunctionalButtonOption?.allowsShortcutCombo != false ? "+" : "-" } private func setCreateWidgetSheetVisible(_ isVisible: Bool) {