فهرست منبع

【综合】AI工具悬浮UI处理

tangchao 2 ماه پیش
والد
کامیت
236def0784

+ 118 - 0
PDF Office/PDF Master/Class/GuideInfo/Controllers/FunctionGuide/KMAIToolsForCheckInGuideView.swift

@@ -0,0 +1,118 @@
+//
+//  KMAIToolsForCheckInGuideView.swift
+//  PDF Reader Pro
+//
+//  Created by User-Tangchao on 2024/12/31.
+//
+
+import Cocoa
+
+class KMAIToolsForCheckInGuideView: NSView {
+    private lazy var targetView_: KMGuideTargetView = {
+        let view = KMGuideTargetView(frame: NSRect(x: 0, y: 0, width: 56, height: 56))
+        view.lineWidth = 2
+        view.strokeColor = NSColor(red: 34/255, green: 122/255, blue: 255/255, alpha: 0.7)
+        return view
+    }()
+    private lazy var contentView: NSView = {
+        let view = NSView()
+        view.wantsLayer = true
+        view.layer?.backgroundColor = .white
+        view.layer?.cornerRadius = 10
+        view.layer?.borderWidth = 2
+        view.layer?.borderColor = NSColor(hex: "#4982E6").cgColor
+        return view
+    }()
+    private lazy var titleLabel: NSTextField = {
+        let view = NSTextField(labelWithString: NSLocalizedString("Try AI Tools Now", comment: ""))
+        view.font = .SFProTextBoldFont(14)
+        view.textColor = NSColor(hex: "#273C62")
+        return view
+    }()
+    
+    private lazy var button_: NSButton = {
+        let view = NSButton()
+        view.isBordered = false
+        view.title = ""
+        view.target = self
+        view.action = #selector(buttonAction)
+        return view
+    }()
+    
+    private var viewSize_: NSSize = .zero
+    var viewSize: NSSize {
+        get {
+            return viewSize_
+        }
+    }
+    
+    var itemClick: KMCommonClickBlock?
+    
+    convenience init() {
+        self.init(frame: .init(x: 0, y: 0, width: 200, height: 116))
+        
+        initSubviews()
+    }
+    
+    func initSubviews() {
+        addSubview(targetView_)
+        
+        addSubview(contentView)
+        contentView.addSubview(titleLabel)
+        contentView.addSubview(button_)
+        
+        let margin: CGFloat = 5
+        viewSize_ = .zero
+        viewSize_.height += margin
+        viewSize_.width += margin
+        
+        let targetWH: CGFloat = 56
+        viewSize_.height += targetWH
+        
+        targetView_.mas_makeConstraints { make in
+            make?.size.mas_equalTo()(NSMakeSize(targetWH, targetWH))
+            make?.centerX.mas_equalTo()(0)
+            make?.top.mas_equalTo()(margin)
+        }
+        
+        let vSpace: CGFloat = 8
+        viewSize_.height += vSpace
+        
+        let contentH: CGFloat = 42
+        viewSize_.height += contentH
+        
+        let width = titleWidth() + 36 * 2
+        viewSize_.width += width
+        
+        contentView.mas_makeConstraints { make in
+            make?.height.mas_equalTo()(contentH)
+            make?.top.equalTo()(targetView_.mas_bottom)?.offset()(vSpace)
+            make?.width.mas_equalTo()(width)
+//            make?.bottom.mas_equalTo()(-5)
+            make?.leading.mas_equalTo()(margin)
+            make?.centerX.mas_equalTo()(0)
+        }
+        
+        titleLabel.mas_makeConstraints { make in
+            make?.center.mas_equalTo()(0)
+        }
+        button_.mas_makeConstraints { make in
+            make?.edges.mas_equalTo()(0)
+        }
+        
+        viewSize_.height += margin
+        viewSize_.width += margin
+        
+        viewSize_.width = max(viewSize_.width, targetWH)
+    }
+    
+    func titleWidth() -> CGFloat {
+        let stringV = titleLabel.stringValue
+        let size = stringV.getTextRectSize(font: .SFProTextBoldFont(14), size: NSMakeSize(CGFLOAT_MAX, 24))
+        return size.width
+    }
+    
+    @objc func buttonAction() {
+        itemClick?(1)
+    }
+}

+ 2 - 0
PDF Office/PDF Master/Class/GuideInfo/KMGuideConfig.swift

@@ -19,6 +19,7 @@ let kKMGuideInfoAIResultSaveKey  = "kKMGuideInfoAIResultSaveKey"
 let kKMGuideInfoAITipIconViewKey  = "kKMGuideInfoAITipIconViewKey"
 let kKMGuideInfoEditPDFPopWindowKey  = "kKMGuideInfoEditPDFPopWindowKey"
 let kKMGuideInfoMeasureKey  = "kKMGuideInfoMeasureKey"
+let kKMGuideInfoAIToolsForCheckInKey  = "kKMGuideInfoAIToolsForCheckInKey"
 
 @objc public enum KMGuideInfoType: NSInteger {
     case none = 0
@@ -38,6 +39,7 @@ let kKMGuideInfoMeasureKey  = "kKMGuideInfoMeasureKey"
     case aiTipIconInfo         = 14//AI按钮
     case editPDFPopWindow       = 15 // 内容编辑悬浮窗口
     case measureGuide           = 16 // 测量
+    case aiToolForCheckIn       // ai工具(签到)
 }
 
 @objc public enum KMGuideActionType: NSInteger {

+ 25 - 0
PDF Office/PDF Master/Class/GuideInfo/KMGuideInfoWindowController.swift

@@ -27,6 +27,8 @@ class KMGuideInfoWindowController: NSWindowController {
     @objc var _digitalBoxRect: CGRect = .zero
     @objc var compareItemRect: CGRect = .zero
     
+    @objc var aiToolsItemRect: CGRect = .zero
+    
     @objc var purchaseHandle: ((_ view: KMGuideInfoWindowController)->Void)?
     @objc var normalGuideFinishHandle: ((_ view: KMGuideInfoWindowController)->Void)?
     @objc var finishHandle: ((_ view: KMGuideInfoWindowController, _ actionType: KMGuideActionType)->Void)?
@@ -83,6 +85,10 @@ class KMGuideInfoWindowController: NSWindowController {
             if (UserDefaults.standard.object(forKey: kKMGuideInfoMeasureKey) == nil) {
                 return true
             }
+        } else if type == .aiToolForCheckIn {
+            if (UserDefaults.standard.object(forKey: kKMGuideInfoAIToolsForCheckInKey) == nil) {
+                return true
+            }
         }
         return false
     }
@@ -112,6 +118,9 @@ class KMGuideInfoWindowController: NSWindowController {
         } else if type == .measureGuide {
             UserDefaults.standard.setValue("Show", forKey: kKMGuideInfoMeasureKey)
             UserDefaults.standard.synchronize()
+        } else if type == .aiToolForCheckIn {
+            UserDefaults.standard.setValue("Show", forKey: kKMGuideInfoAIToolsForCheckInKey)
+            UserDefaults.standard.synchronize()
         }
     }
     
@@ -512,6 +521,22 @@ class KMGuideInfoWindowController: NSWindowController {
                 
                 self.coverView.addSubview(self.editPDFPopGuideView!)
                 KMGuideInfoWindowController.setDidShowFor(.editPDFPopWindow)//记录
+            } else if self.type == .aiToolForCheckIn {
+                let view = KMAIToolsForCheckInGuideView()
+                let originP = self.aiToolsItemRect.origin
+                let point = NSMakePoint(originP.x-view.viewSize.width*0.5+20, originP.y-60)
+                view.frame.origin = point
+                view.frame.size = view.viewSize
+                view.itemClick = { [weak self] idx, _ in
+                    self?.closeAction()
+                    if idx == 1 { // try to
+                        if let data = self {
+                            self?.finishHandle?(data, .getIt)
+                        }
+                    }
+                }
+                self.coverView.addSubview(view)
+//                KMGuideInfoWindowController.setDidShowFor(.aiToolForCheckIn)//记录
             }
         }
     }

+ 31 - 1
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController.swift

@@ -1070,8 +1070,38 @@ import Cocoa
                 self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
                 guideWC.show()
             }
-        } else {
+        } else if showType == .aiToolForCheckIn && KMGuideInfoWindowController.availableShow(.aiToolForCheckIn) {
+            self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
+            guard let guideWC = self.guideInfoWindowController else {
+                return
+            }
+            
+            guideWC.type = .aiToolForCheckIn
+            
+            guard let item = self.toolbarController.findItem(KMDocumentAIToolsToolbarItemIdentifier) else {
+                return
+            }
+            guard let win = self.view.window else {
+                return
+            }
+            
+            guideWC.aiToolsItemRect = (win.contentView?.convert(item.frame, from: item.superview)) ?? .zero
             
+            guideWC.finishHandle = { [weak self] winC, type in
+                if type == .getIt {
+                    self?.showAITypeChooseView(aiConfigType: .none)
+                    return
+                }
+            }
+            
+            guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
+            var rect = self.view.window!.frame
+            rect.size.height -= 20
+            guideWC.window?.setFrame(rect, display: false)
+            guideWC.window?.minSize = rect.size
+            guideWC.window?.maxSize = rect.size
+            self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
+            guideWC.show()
         }
     }
     

+ 2 - 1
PDF Office/PDF Master/Class/Purchase/DMG/Verification/KMVerificationMessageViewController.m

@@ -891,8 +891,9 @@ NSPopoverDelegate>
     [KMLoginWindowsController.shared showWindow:nil];
 }
 
-- (void)userGiftAction:(id *)sender {
+- (void)userGiftAction:(id)sender {
     NSLog(@"userGiftAction ...");
+    [self buttonAction:sender];
 }
 
 #pragma mark - NSNotification Methods

+ 8 - 0
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -57,6 +57,9 @@
 		6536FDEB2C9C49C0004A0FB9 /* KMNoteFooterCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6536FDEA2C9C49C0004A0FB9 /* KMNoteFooterCellView.xib */; };
 		6536FDEC2C9C49C0004A0FB9 /* KMNoteFooterCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6536FDEA2C9C49C0004A0FB9 /* KMNoteFooterCellView.xib */; };
 		6536FDED2C9C49C1004A0FB9 /* KMNoteFooterCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6536FDEA2C9C49C0004A0FB9 /* KMNoteFooterCellView.xib */; };
+		653792F82D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653792F72D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift */; };
+		653792F92D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653792F72D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift */; };
+		653792FA2D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653792F72D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift */; };
 		653F389F2CE9FDF1009E97B2 /* AIConfigWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 653F389E2CE9FDF1009E97B2 /* AIConfigWindowController.xib */; };
 		653F38A02CE9FDF1009E97B2 /* AIConfigWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 653F389E2CE9FDF1009E97B2 /* AIConfigWindowController.xib */; };
 		653F38A12CE9FDF1009E97B2 /* AIConfigWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 653F389E2CE9FDF1009E97B2 /* AIConfigWindowController.xib */; };
@@ -5871,6 +5874,7 @@
 		6536FDE22C9C1EF2004A0FB9 /* KMNoteReplyHanddler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNoteReplyHanddler.swift; sourceTree = "<group>"; };
 		6536FDE62C9C49A6004A0FB9 /* KMNoteFooterCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNoteFooterCellView.swift; sourceTree = "<group>"; };
 		6536FDEA2C9C49C0004A0FB9 /* KMNoteFooterCellView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMNoteFooterCellView.xib; sourceTree = "<group>"; };
+		653792F72D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMAIToolsForCheckInGuideView.swift; sourceTree = "<group>"; };
 		653F389E2CE9FDF1009E97B2 /* AIConfigWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AIConfigWindowController.xib; sourceTree = "<group>"; };
 		653F38A22CE9FE2B009E97B2 /* KMProductCompareWC.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMProductCompareWC.xib; sourceTree = "<group>"; };
 		654858C92D126A1D00EC73F5 /* KMCheckInWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMCheckInWindowController.swift; sourceTree = "<group>"; };
@@ -12629,6 +12633,7 @@
 				BB1B0ABB2B4FC6E800889528 /* KMCustomColorGuideView.xib */,
 				BB234F032BA3D798008B3754 /* KMAIIconGuideView.swift */,
 				BB234F022BA3D798008B3754 /* KMAIIconGuideView.xib */,
+				653792F72D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift */,
 			);
 			path = FunctionGuide;
 			sourceTree = "<group>";
@@ -17917,6 +17922,7 @@
 				ADD1B6E82946C02600C3FFF7 /* KMPrintChoosePageSizeMultipageView.swift in Sources */,
 				AD58F40E2B1DAAA800299EE0 /* KMPrintDefaultView.swift in Sources */,
 				9F1FE4ED29406E4700E952CA /* ThrobberView.m in Sources */,
+				653792F82D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift in Sources */,
 				9FC346452CCFA96800F35823 /* KMForgotPasswordView.swift in Sources */,
 				AD055E4A2B72346E0035F824 /* KMBookmarkSheetView.swift in Sources */,
 				9F0CB4F9298655E500007028 /* KMDesignToken+Border.swift in Sources */,
@@ -19764,6 +19770,7 @@
 				BB6B4C09292F53CE0071CA06 /* KMMergeFileModel.swift in Sources */,
 				651169E82D13F68D0011E76B /* KMNewUserGuideCellView.swift in Sources */,
 				AD0E8AB52A31B78900DBFD3C /* KMDMGPurchaseManager.swift in Sources */,
+				653792F92D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift in Sources */,
 				BBEC00B8295C2C1600A26C98 /* KMBatesPropertyHomeController.swift in Sources */,
 				9F1F82B5292DEF370092C4B4 /* KMCloudDocumentsViewController.swift in Sources */,
 				BBB7898B2BE8BF2300F7E09C /* AIHeaderView.swift in Sources */,
@@ -20600,6 +20607,7 @@
 				BBB7899E2BE8BF2400F7E09C /* CustomCornerView.swift in Sources */,
 				BBEC00AA295BDECF00A26C98 /* KMHeaderFooterContentInfoView.swift in Sources */,
 				BB570ADD2B512C90005E7E4A /* KMLeftSideViewController+Thumbnail.swift in Sources */,
+				653792FA2D240E1D0062C2CF /* KMAIToolsForCheckInGuideView.swift in Sources */,
 				BBB14A552978DD5400936EDB /* KMRedactTools.swift in Sources */,
 				ADCFFC0429C004AD007D3657 /* KMBookMarkTableRowView.swift in Sources */,
 				BBEC00CE295C31F900A26C98 /* KMBatesModel.swift in Sources */,