From a2be466eae16fea145dd4ffdbceeda03cc9b8048 Mon Sep 17 00:00:00 2001 From: Sharker <1548742234@qq.com> Date: Sun, 19 May 2024 22:50:25 +0800 Subject: [PATCH] Fix tips view blank (#499) * Revert "Revert "Feautre tips view (#418)" (#477)" This reverts commit 11fd8685deefb4515ddc495294346ff7b1e7907b. * fix: https://github.com/tisfeng/Easydict/issues/452 blank for tips view * feat: add type of tips cell * feat: support tips cell update cell type * fix: when selection translation the text is empty set special tips cell type * fix: update show tips status * fix: resolve merge dev * fix: update action type * pref: stash ocr error tips * fix: control show tips code * fix: update view * fix: add mini cell height * fix: tips cell type * fix: remove unuse code * fix: called showTipsView when showTips == true * fix: display when user just want show query window again * perf: improve displaying tips view * perf: do not reload tableView when starting query text * perf: remove unused Localizable.xcstrings * perf: close tips view when just updating query text * perf: close tips view when starting OCR image * chore(deps): bump rexml in the bundler group across 1 directory Bumps the bundler group with 1 update in the / directory: [rexml](https://github.com/ruby/rexml). Updates `rexml` from 3.2.6 to 3.2.8 - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.2.6...v3.2.8) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect dependency-group: bundler ... Signed-off-by: dependabot[bot] * perf(UI): add icon for disableTipsView toggle * perf(UI): adjust advanced tab height --------- Signed-off-by: dependabot[bot] Co-authored-by: Tisfeng Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jerry <89069957+Jerry23011@users.noreply.github.com> --- Easydict.xcodeproj/project.pbxproj | 6 + .../tip_Normal.imageset/Contents.json | 22 ++ .../tip_Normal.imageset/tip_Normal.png | Bin 0 -> 907 bytes .../tip_Normal.imageset/tip_Normal@2x.png | Bin 0 -> 2088 bytes Easydict/App/Localizable.xcstrings | 169 +++++++++++ .../Configuration+Defaults.swift | 2 + .../Feature/Configuration/Configuration.swift | 2 + .../Swift/View/SettingView/SettingView.swift | 2 +- .../Tabs/TabView/AdvancedTab.swift | 8 + .../EZCategory/NSString/NSString+EZUtils.h | 5 + .../EZCategory/NSString/NSString+EZUtils.m | 17 +- .../ViewController/Cell/EZTableTipsCell.h | 45 +++ .../ViewController/Cell/EZTableTipsCell.m | 282 ++++++++++++++++++ .../View/CustomButton/EZButton/EZButton.h | 2 + .../View/CustomButton/EZButton/EZButton.m | 6 + .../EZBaseQueryViewController.h | 6 + .../EZBaseQueryViewController.m | 81 ++++- .../Window/WindowManager/EZWindowManager.m | 14 +- Gemfile.lock | 7 +- 19 files changed, 665 insertions(+), 11 deletions(-) create mode 100644 Easydict/App/Assets.xcassets/tip_Normal.imageset/Contents.json create mode 100644 Easydict/App/Assets.xcassets/tip_Normal.imageset/tip_Normal.png create mode 100644 Easydict/App/Assets.xcassets/tip_Normal.imageset/tip_Normal@2x.png create mode 100644 Easydict/objc/ViewController/Cell/EZTableTipsCell.h create mode 100644 Easydict/objc/ViewController/Cell/EZTableTipsCell.m diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 9c6675780..b9ae9f3ed 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -303,6 +303,7 @@ 9672D7D22B4008B40023B8FB /* MASShortcutBinder+EZMASShortcutBinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 9672D7D12B4008B40023B8FB /* MASShortcutBinder+EZMASShortcutBinder.m */; }; 967712EA2B5B913600105E0F /* KeyHolder in Frameworks */ = {isa = PBXBuildFile; productRef = 967712E92B5B913600105E0F /* KeyHolder */; }; 967712EE2B5B943400105E0F /* Shortcut.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967712ED2B5B943400105E0F /* Shortcut.swift */; }; + 96DFEB832B82588000F5C7EF /* EZTableTipsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 96DFEB822B82588000F5C7EF /* EZTableTipsCell.m */; }; A0B65CA0F31AC8ECFB8347CC /* Pods_EasydictTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 378E73A7EA8FC8FB9C975A63 /* Pods_EasydictTests.framework */; }; B87AC7E36367075BA5D13234 /* Pods_Easydict.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6372B33DFF803C7096A82250 /* Pods_Easydict.framework */; }; C415C0AD2B450D4800A9D231 /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415C0AC2B450D4800A9D231 /* GeminiService.swift */; }; @@ -841,6 +842,8 @@ 9672D7D02B4008B40023B8FB /* MASShortcutBinder+EZMASShortcutBinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MASShortcutBinder+EZMASShortcutBinder.h"; sourceTree = ""; }; 9672D7D12B4008B40023B8FB /* MASShortcutBinder+EZMASShortcutBinder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MASShortcutBinder+EZMASShortcutBinder.m"; sourceTree = ""; }; 967712ED2B5B943400105E0F /* Shortcut.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shortcut.swift; sourceTree = ""; }; + 96DFEB812B82588000F5C7EF /* EZTableTipsCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZTableTipsCell.h; sourceTree = ""; }; + 96DFEB822B82588000F5C7EF /* EZTableTipsCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZTableTipsCell.m; sourceTree = ""; }; A230E9A2358C7FBC7FB26189 /* Pods-EasydictTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EasydictTests.debug.xcconfig"; path = "Target Support Files/Pods-EasydictTests/Pods-EasydictTests.debug.xcconfig"; sourceTree = ""; }; C415C0AC2B450D4800A9D231 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AdvancedTabItemView.swift; path = Easydict/Swift/View/AdvancedTabItemView.swift; sourceTree = SOURCE_ROOT; }; @@ -1579,6 +1582,8 @@ children = ( 0396D60F292C932F006A11D9 /* EZSelectLanguageCell.h */, 0396D610292C932F006A11D9 /* EZSelectLanguageCell.m */, + 96DFEB812B82588000F5C7EF /* EZTableTipsCell.h */, + 96DFEB822B82588000F5C7EF /* EZTableTipsCell.m */, 037852B7295D49F900D0E2CF /* EZTableRowView.h */, 037852B8295D49F900D0E2CF /* EZTableRowView.m */, ); @@ -3093,6 +3098,7 @@ 03B022FE29231FA6001C7E63 /* EZBaseQueryViewController.m in Sources */, DC6D9C892B3969510055EFFC /* Appearance.swift in Sources */, 0396D611292C932F006A11D9 /* EZSelectLanguageCell.m in Sources */, + 96DFEB832B82588000F5C7EF /* EZTableTipsCell.m in Sources */, 036196752A000F5900806370 /* FWEncryptorAES.m in Sources */, 9643D9462B71D103000FBEA6 /* KeyHolderRowView.swift in Sources */, 0399C6A829A74E0F00B4AFCC /* EZQueryResult+EZDeepLTranslateResponse.m in Sources */, diff --git a/Easydict/App/Assets.xcassets/tip_Normal.imageset/Contents.json b/Easydict/App/Assets.xcassets/tip_Normal.imageset/Contents.json new file mode 100644 index 000000000..f008b3dac --- /dev/null +++ b/Easydict/App/Assets.xcassets/tip_Normal.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "tip_Normal.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tip_Normal@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Easydict/App/Assets.xcassets/tip_Normal.imageset/tip_Normal.png b/Easydict/App/Assets.xcassets/tip_Normal.imageset/tip_Normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b424c640e5254e7028b2e1cc3d9851aa73ae04ac GIT binary patch literal 907 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~m(&Q)G+$o^ zEg+kNfw4W4fd!-lh^2s-fq{7eBLg##W(0{XV1mnvEMP{kK?*nB{qUE8f$6KKi(`m| z;L;FpAK^d|TjRM49R#|ax*HlbrOL#XsA_SSX7;QzxY{8t?0F}-amDFJWqa_Qx<{&>GHys++*Xo_gQ>J!})Hjjd1@*foj)iiP*Ql0qmQ_zFv3G+i$ zJCc?*eq8hLmt}HqP06=D1uk~W%j=JQZvDaZbl#r1J16C2>*`OmS>AV2Bgo~1((wlu zgyihgU%Z(1Yimc{p86y`f%E?$|;RMT07gKesPd}q&# ziFmguYsT`NnC|O#+gEqrxj65lk#b{{!Pm{5u@X0S2vmDX`N{D%Z#c@z=f3jMo6kGv zo@Fs(y?NqHqV1V;Yi@qOFt4ywAnL)gmwA~UE!$GooUO?42okzeY1KM!U;aUb{tsMc zHjmA#zZkWurR@*$Y35^yDE+$l`i$O^U3c5I*z(M5Uy)wYI^(q*xB0^);}80W8$*Qz zjlC?&en_}jAO99~S#+x43_*tou>sclYM)HiZ!h*wuv5Fv2a4ya@mt}HpFdz-57pSues&(3C1qa?%slQh7gJJH5*0i>IktKd7-<^@M^yIR*bTIW~+9Rb|=bF0(loEBf zm;d>lvPa_SY_6cqYYb+G-(Ru#f{bnL-i)>TTg#n;XMak1-MLA}IK3wBx{1p2CA0Xq zu1ITCX{i@A`D1Qke$A0rHz}!x=e>3OrCCx!Av&$TYlYkPgTe~DWM4fT;P5# literal 0 HcmV?d00001 diff --git a/Easydict/App/Assets.xcassets/tip_Normal.imageset/tip_Normal@2x.png b/Easydict/App/Assets.xcassets/tip_Normal.imageset/tip_Normal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a8001c97e72770a12dd0e749c5c0fafef9941b8b GIT binary patch literal 2088 zcmV+@2-o+CP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91D4+uX1ONa40RR91C;$Ke0D9(TtN;K9l1W5CR9FeMSZiz)RTMsVW_J5r z=yO|I5GheHzS6XX5MNPDd_*x(FcO3DhYE@B#GfX{M1N?E!AE=~Dxy)0MkGQi#t=o3 zV7E`8Qjm6|2;JQR+ittt-JPAeo^xlWo!y;fr?uW>_uhN%Io~~V?s?o91`E{M+Q1`S z@E-+<9SIDFA6Ot*P!z;~e%v&jnAC3_92=V|#_wi*O-ub{I%7X0ZYTQdV;7TgYr&3kAN%TJKyKGoH#gVn zob3V5n%u|~4H60XMjhC%__TL+v@~`EMnVA#xOG`wldLHBF{a-I46egXYsDJl=Yhij z=TfJZ$?WPoeeSF!qnD~17#G1bkcjc;EPA27=n<1(TT8<=2zqmOF!T=1NioGMzl1*b z2r6FWA$bNE`y`XrUL-}Ys;{psuVh;@8T|{p;)LteTq$T5>{!uo4_fPUr1?AwhqbK= z+}N(bsul@qsu(V5kep7z;Gfg*`wQR(&WC4DYey6&ueX6~F2fVPf(b^tZ|gM*G1f5tkAV#?9F?1qVWgyjHs zkaAld^uSY_OJGrD;pbz>=<$|;$HSrZ@;EGOVh}hcGfjs(nyV}O&W^`Vy4l;6g5-0O zEd7LgmXdOtHmm~A(kB4)1n|_1|2yudC?#k#fTr36G&eFh)US{q+}%)Fwj&fvOgakL zh^`b|R_}WQW!BQMKK=NWP{>W|J2WWy)xQM6J(kk2Xpjlkpz;949qk*{r>0I?wkdNPYNGbt^v z664MHB!RF9Q((_^9yfPrk|d!|mO=$2;r8n_*n2=x3~YEuq#mF2GDi7oJpLBO z;f1bX_(Ou3u^>8ijhWroabT}f#wP}mgt4boLQRi#gZkI2AbA@>iyaa)`V-bu3kMDH zcuS0n&YEjgn$BRC`=m8EeFl|Vi+uwJZkQVW$BVDhQ9);)G$Ag!NIbJ>rbJ%H_ywX} zh&gAZ@uRcWv&$+K92Q@bzdz>;RNdUx#J0=jj*DB6q8jsT@H7X%2%Bt(vL+5?O@>cR z9Frh5X1GGlY8?Y9o0rNT!w?OPnGb7VXEWu@idql>dr4+s$aL%+fbwMk)=w@o7RxW; zf|kRI$=bl^`NL4q!p`Nh&xzgj%$oQ_E;Z7VjT2eA&Ww z;Lz31mCT?c8hTk{l3gN{TI7l^+`U5mOoK+x9w1cHS&NkVoMyN zocPFkDZE*|`=t>@ghiP2mdF|3iq#9N7Q0hndfq!qUUF-$@g2dZ>e6e%k9PkNKV>OW zt&|=1l(0?bqr6(hn%j1Do~Xr|*H6cz@Xe2O{TJ2?PEYEa#u5o}=fEph&(eyjkGRZF zW6> zG&7mzWI+qKeWibk*HiL7&1>-zQCFSs%Ct6tFHE8H#sj3))Yk6d$OlB9OPiO1v;kgl zo%2b7-SJ8_uf2rV7Ql2xe*Wccj(n#^f`Y#LV@wMFq5WqC>->$5+n+c!>`0$0(b;+2 zp-d9n^fcDDoJIjcO*Sv6I262sILE*FE6Cv(?KON{bXnV`QpTkq7CmRsP2Mafmy>xb zh}GZ=+GF3hJM*jATF_+q^>G+D3ea^GKa$?Y79ao)2VH{Vq43 z*=#~t!+BefQ0Uvrl9u>KFzt)rlU8Geq4(J|7XMy6*4M~#y+ett+M2byi^;!QY`Ff! Sl5~v#0000("disableTipsViewKey", default: false) } extension Defaults.Keys { diff --git a/Easydict/Swift/Feature/Configuration/Configuration.swift b/Easydict/Swift/Feature/Configuration/Configuration.swift index 3d8ce3dc1..20228a10d 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration.swift @@ -104,6 +104,8 @@ class Configuration: NSObject { @DefaultsWrapper(.selectQueryTextWhenWindowActivate) var selectQueryTextWhenWindowActivate: Bool + @DefaultsWrapper(.disableTipsView) var disableTipsView: Bool + var disabledAutoSelect: Bool = false var isRecordingSelectTextShortcutKey: Bool = false diff --git a/Easydict/Swift/View/SettingView/SettingView.swift b/Easydict/Swift/View/SettingView/SettingView.swift index 888b8e413..7fc3f7af4 100644 --- a/Easydict/Swift/View/SettingView/SettingView.swift +++ b/Easydict/Swift/View/SettingView/SettingView.swift @@ -78,7 +78,7 @@ struct SettingView: View { case .disabled: 500 case .advanced: - 280 + 310 case .privacy: 320 case .about: diff --git a/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift index acfe0f381..dea07a23a 100644 --- a/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift +++ b/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift @@ -29,6 +29,13 @@ struct AdvancedTab: View { .tag(option) } } + Toggle(isOn: $disableTipsView) { + AdvancedTabItemView( + color: .yellow, + systemImage: "lightbulb.fill", + labelText: "disable_tips_view" + ) + } } Section { Toggle(isOn: $enableBetaFeature) { @@ -58,6 +65,7 @@ struct AdvancedTab: View { @Default(.defaultTTSServiceType) private var defaultTTSServiceType @Default(.enableBetaFeature) private var enableBetaFeature @Default(.enableBetaNewApp) private var enableBetaNewApp + @Default(.disableTipsView) private var disableTipsView } @available(macOS 13, *) diff --git a/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.h b/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.h index 90f3965ab..d422fb0c7 100644 --- a/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.h +++ b/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.h @@ -156,6 +156,11 @@ static NSArray *const EZDashCharacterList = @[ @"—", @"-", @"–" ]; - (NSString *)removeAlphabetAndNumbers; +#pragma mark - Check Empty String +#ifndef EZ_isEmptyString +FOUNDATION_EXPORT BOOL EZ_isEmptyString(id param); +#endif + @end NS_ASSUME_NONNULL_END diff --git a/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.m b/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.m index 9494781fe..333988292 100644 --- a/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.m +++ b/Easydict/objc/Utility/EZCategory/NSString/NSString+EZUtils.m @@ -20,6 +20,19 @@ @"「" : @"」", }; +BOOL EZ_isEmptyString(id param) { + if (!param) { + return YES; + } + if ([param isKindOfClass:[NSString class]]) { + NSString *str = param; + return (str.length == 0); + } + NSCAssert(NO, @"isEmptyString: param %@ is not NSString", param); + return YES; +} + + @implementation NSString (EZUtils) /// Check if it is a single letter of the alphabet, like 'a', 'A' @@ -224,7 +237,7 @@ - (BOOL)isEnglishWordWithLanguage:(EZLanguage)language { } - (NLLanguage)detectText { - NLTagger *tagger = [[NLTagger alloc] initWithTagSchemes:@[NLTagSchemeLanguage]]; + NLTagger *tagger = [[NLTagger alloc] initWithTagSchemes:@[ NLTagSchemeLanguage ]]; tagger.string = self; NLLanguage language = [tagger dominantLanguage]; return language; @@ -466,7 +479,7 @@ - (NSString *)suffixQuote { } return quotes; } - + - (NSString *)tryToRemovePrefixQuote { NSString *prefixQuote = [self prefixQuote]; diff --git a/Easydict/objc/ViewController/Cell/EZTableTipsCell.h b/Easydict/objc/ViewController/Cell/EZTableTipsCell.h new file mode 100644 index 000000000..8782c3ea0 --- /dev/null +++ b/Easydict/objc/ViewController/Cell/EZTableTipsCell.h @@ -0,0 +1,45 @@ +// +// EZTableTipsCell.h +// Easydict +// +// Created by Sharker on 2024/2/18. +// Copyright © 2024 izual. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, EZTipsCellType) { + EZTipsCellTypeNone = -1, + EZTipsCellTypeTextEmpty = 0, + EZTipsCellTypeMouseHover, + EZTipsCellTypeBeep, + EZTipsCellTypeEditButton, + EZTipsCellTypeMightSelecting, + EZTipsCellTypeWordSelectionOCR, + EZTipsCellTypeSelectWords, + EZTipsCellTypeStillPopup, +}; + +@interface EZTableTipsCell : NSTableRowView + +- (CGFloat)cellHeight; + + +- (instancetype)initWithFrame:(CGRect)frame type:(EZTipsCellType)type; + +/// update tips cell content with type +/// - Parameters: +/// - content: string value for content +/// - type: cell type default value is none +- (void)updateTipsContent:(NSString *)content type:(EZTipsCellType)type; + + +/// update tips cell of type +/// - Parameter type: cell type default value is none +- (void)updateTipsCellType:(EZTipsCellType)type; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Easydict/objc/ViewController/Cell/EZTableTipsCell.m b/Easydict/objc/ViewController/Cell/EZTableTipsCell.m new file mode 100644 index 000000000..15468578f --- /dev/null +++ b/Easydict/objc/ViewController/Cell/EZTableTipsCell.m @@ -0,0 +1,282 @@ +// +// EZTableTipsCell.m +// Easydict +// +// Created by Sharker on 2024/2/18. +// Copyright © 2024 izual. All rights reserved. +// + +#import "EZTableTipsCell.h" +#import "EZOpenLinkButton.h" +#import "NSImage+EZSymbolmage.h" +#import "EZLanguageManager.h" +#import "NSString+EZUtils.h" + +@interface EZTableTipsCell () +@property (nonatomic, strong) NSView *contentView; +@property (nonatomic, strong) NSImageView *tipsIconImageView; +@property (nonatomic, strong) NSTextField *tipsNameLabel; +@property (nonatomic, strong) NSTextField *tipsContentLabel; +@property (nonatomic, strong) EZOpenLinkButton *moreBtn; +@property (nonatomic, strong) EZOpenLinkButton *solveBtn; +@property (nonatomic, strong) NSDictionary *dataDict; +@property (nonatomic, strong) NSString *questionSolveURL; +@property (nonatomic, strong) NSString *seeMoreURL; +@property (nonatomic, assign) EZTipsCellType tipsType; +@end + +@implementation EZTableTipsCell + +- (instancetype)initWithFrame:(CGRect)frame type:(EZTipsCellType)type { + self = [super initWithFrame:frame]; + if (self) { + self.tipsType = type; + [self setupUI]; + [self updateQuestionContent]; + } + return self; +} + +- (void)updateTipsCellType:(EZTipsCellType)type { + [self updateTipsContent:@"" type:type]; +} + +- (void)updateTipsContent:(NSString *)content type:(EZTipsCellType)type { + if (!EZ_isEmptyString(content)) { + self.tipsContentLabel.stringValue = content; + } + self.tipsType = type; + [self updateQuestionContent]; +} + +- (void)setupUI { + // mas key + self.contentView.mas_key = @"topBarView"; + self.tipsIconImageView.mas_key = @"tipsIconImageView"; + self.tipsNameLabel.mas_key = @"tipsNameLabel"; + self.moreBtn.mas_key = @"moreBtn"; + self.solveBtn.mas_key = @"solveBtn"; + + CGSize iconSize = CGSizeMake(20, 20); + + // constraints + [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(0); + }]; + + [self.tipsIconImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(9); + make.top.mas_equalTo(9); + make.size.mas_equalTo(iconSize); + }]; + + [self.tipsNameLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.tipsIconImageView.mas_right).offset(6); + make.centerY.mas_equalTo(self.tipsIconImageView.mas_centerY).offset(1); + }]; + + [self.solveBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(9); + make.top.mas_equalTo(self.tipsContentLabel.mas_bottom).offset(9); + make.size.mas_equalTo(CGSizeMake(98, 32)); + }]; + + [self.moreBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.solveBtn.mas_right).offset(20); + make.top.mas_equalTo(self.solveBtn); + make.size.mas_equalTo(CGSizeMake(94, 32)); + }]; +} + +- (void)updateConstraints { + [self.tipsContentLabel mas_updateConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(9); + make.width.mas_lessThanOrEqualTo(self.bounds.size.width - 9); + make.top.mas_equalTo(self.tipsNameLabel.mas_bottom).offset(12); + }]; + + [super updateConstraints]; +} + +- (void)updateQuestionContent { + NSArray *questions = self.dataDict[@"questions"]; + NSInteger index = 0; + if (self.tipsType == EZTipsCellTypeNone) { + // random question and slove + index = arc4random() % questions.count; + } else { + // show special question + index = self.tipsType; + } + self.tipsContentLabel.stringValue = questions[index]; + NSArray *solves; + if ([EZLanguageManager.shared isSystemChineseFirstLanguage]) { + solves = self.dataDict[@"solveZh"]; + } else { + solves = self.dataDict[@"solveEn"]; + } + self.questionSolveURL = solves[index]; + self.solveBtn.link = self.questionSolveURL; +} + +- (CGFloat)cellHeight { + CGFloat cellHeight = 9 + 20 + 12 + self.tipsContentLabel.height + 9 + 32 + 6; + return cellHeight; +} + +#pragma mark - Accesstor +- (NSView *)contentView { + if (!_contentView) { + mm_weakify(self); + _contentView = [NSView mm_make:^(NSView *_Nonnull view) { + mm_strongify(self); + [self addSubview:view]; + view.wantsLayer = YES; + view.layer.cornerRadius = EZCornerRadius_8; + [view.layer excuteLight:^(CALayer *layer) { + layer.backgroundColor = [NSColor ez_titleBarBgLightColor].CGColor; + } dark:^(CALayer *layer) { + layer.backgroundColor = [NSColor ez_titleBarBgDarkColor].CGColor; + }]; + }]; + } + return _contentView; +} + +- (NSImageView *)tipsIconImageView { + if (!_tipsIconImageView) { + mm_weakify(self); + _tipsIconImageView = [NSImageView mm_make:^(NSImageView *imageView) { + mm_strongify(self); + [self.contentView addSubview:imageView]; + [imageView setImage:[NSImage imageNamed:@"tip_Normal"]]; + }]; + } + return _tipsIconImageView; +} + +- (NSTextField *)tipsNameLabel { + if (!_tipsNameLabel) { + mm_weakify(self); + _tipsNameLabel = [NSTextField mm_make:^(NSTextField *label) { + mm_strongify(self); + [self.contentView addSubview:label]; + label.stringValue = NSLocalizedString(@"tips_title", nil); + label.editable = NO; + label.bordered = NO; + label.backgroundColor = NSColor.clearColor; + label.alignment = NSTextAlignmentCenter; + label.font = [NSFont systemFontOfSize:14]; + [label excuteLight:^(NSTextField *label) { + label.textColor = [NSColor ez_resultTextLightColor]; + } dark:^(NSTextField *label) { + label.textColor = [NSColor ez_resultTextDarkColor]; + }]; + }]; + } + return _tipsNameLabel; +} + +- (NSTextField *)tipsContentLabel { + if (!_tipsContentLabel) { + mm_weakify(self); + _tipsContentLabel = [NSTextField mm_make:^(NSTextField *label) { + mm_strongify(self); + [self.contentView addSubview:label]; + label.editable = NO; + label.bordered = NO; + label.backgroundColor = NSColor.clearColor; + label.alignment = NSTextAlignmentLeft; + label.stringValue = self.dataDict[@"questions"][0]; + label.usesSingleLineMode = NO; + label.maximumNumberOfLines = 0; + [label excuteLight:^(NSTextField *label) { + label.textColor = [NSColor ez_resultTextLightColor]; + } dark:^(NSTextField *label) { + label.textColor = [NSColor ez_resultTextDarkColor]; + }]; + }]; + } + return _tipsContentLabel; +} + +- (EZOpenLinkButton *)moreBtn { + if (!_moreBtn) { + _moreBtn = [[EZOpenLinkButton alloc] init]; + [self addSubview:_moreBtn]; + NSImage *moreBtnImage = [NSImage ez_imageWithSymbolName:@"ellipsis.circle.fill"]; + _moreBtn.image = moreBtnImage; + _moreBtn.title = NSLocalizedString(@"tips_more", nil); + _moreBtn.imagePosition = NSImageLeft; + _moreBtn.edgeInsets = NSEdgeInsetsMake(0, 3, 0, 3); + [_moreBtn excuteLight:^(NSButton *button) { + button.image = [button.image imageWithTintColor:[NSColor ez_imageTintLightColor]]; + } dark:^(NSButton *button) { + button.image = [button.image imageWithTintColor:[NSColor ez_imageTintDarkColor]]; + }]; + _moreBtn.link = self.seeMoreURL; + } + return _moreBtn; +} + +- (EZOpenLinkButton *)solveBtn { + if (!_solveBtn) { + _solveBtn = [[EZOpenLinkButton alloc] init]; + [self addSubview:_solveBtn]; + NSImage *solveBtnImage = [NSImage ez_imageWithSymbolName:@"link.circle.fill"]; + _solveBtn.image = solveBtnImage; + _solveBtn.imagePosition = NSImageLeft; + _solveBtn.title = NSLocalizedString(@"tips_solve", nil); + _solveBtn.edgeInsets = NSEdgeInsetsMake(0, 3, 0, 3); + [_solveBtn excuteLight:^(NSButton *button) { + button.image = [button.image imageWithTintColor:[NSColor ez_imageTintLightColor]]; + } dark:^(NSButton *button) { + button.image = [button.image imageWithTintColor:[NSColor ez_imageTintDarkColor]]; + }]; + } + return _solveBtn; +} + +- (NSDictionary *)dataDict { + if (!_dataDict) { + _dataDict = @{ + @"questions" : @[ + NSLocalizedString(@"tips_text_empty", nil), + NSLocalizedString(@"tips_mouse_hover", nil), + NSLocalizedString(@"tips_edit_button", nil), + NSLocalizedString(@"tips_word_selection_OCR", nil), + NSLocalizedString(@"tips_select_words", nil), + NSLocalizedString(@"tips_still_pop_up", nil), + ], + @"solveEn" : @[ + @"https://github.com/tisfeng/Easydict/wiki/FAQ#why-is-the-text-empty-when-i-select-words-in-some-applications", + @"https://github.com/tisfeng/Easydict/wiki/FAQ#why-cant-i-use-mouse-hover-to-select-words-in-some-applications", + @"https://github.com/tisfeng/Easydict/wiki/FAQ#why-does-the-edit-button-in-the-upper-right-corner-flicker-when-selecting-words-in-some-applications", + @"https://github.com/tisfeng/Easydict/wiki/FAQ#why-do-word-selection-and-ocr-need-to-enable-system-related-permissions", + @"https://github.com/tisfeng/Easydict/wiki/FAQ#why-cant-i-select-words-on-some-web-pages-in-the-browser", + @"https://github.com/tisfeng/Easydict/wiki/FAQ#why-does-macos-still-pop-up-asking-for-permissions-even-though-i-have-given-easydict-the-accessibilityscreen-recording-permissions" + ], + @"solveZh" : @[ + @"https://github.com/tisfeng/Easydict/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98#%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E6%9F%90%E4%BA%9B%E5%BA%94%E7%94%A8%E4%B8%AD%E5%8F%96%E8%AF%8D%E6%96%87%E6%9C%AC%E4%B8%BA%E7%A9%BA", + @"https://github.com/tisfeng/Easydict/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98#%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E6%9F%90%E4%BA%9B%E5%BA%94%E7%94%A8%E4%B8%AD%E6%97%A0%E6%B3%95%E4%BD%BF%E7%94%A8%E9%BC%A0%E6%A0%87%E5%88%92%E8%AF%8D", + @"https://github.com/tisfeng/Easydict/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98#%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E6%9F%90%E4%BA%9B%E5%BA%94%E7%94%A8%E5%8F%96%E8%AF%8D%E6%97%B6%E5%8F%B3%E4%B8%8A%E8%A7%92%E7%BC%96%E8%BE%91%E6%8C%89%E9%92%AE%E4%BC%9A%E5%87%BA%E7%8E%B0%E9%97%AA%E7%83%81", + @"https://github.com/tisfeng/Easydict/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98#%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8F%96%E8%AF%8D%E5%92%8C-ocr-%E9%9C%80%E8%A6%81%E5%BC%80%E5%90%AF%E7%B3%BB%E7%BB%9F%E7%9B%B8%E5%85%B3%E6%9D%83%E9%99%90", + @"https://github.com/tisfeng/Easydict/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98#%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E6%9F%90%E4%BA%9B%E7%BD%91%E9%A1%B5%E6%97%A0%E6%B3%95%E5%8F%96%E8%AF%8D", + @"https://github.com/tisfeng/Easydict/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98#%E5%B7%B2%E7%BB%8F%E7%BB%99-easydict-%E8%BE%85%E5%8A%A9%E5%8A%9F%E8%83%BD%E5%BD%95%E5%B1%8F%E6%9D%83%E9%99%90-macos-%E4%BB%8D%E7%84%B6%E5%BC%B9%E7%AA%97%E8%A6%81%E6%B1%82%E7%BB%99%E4%BA%88%E6%9D%83%E9%99%90" + ], + }; + } + return _dataDict; +} + +- (NSString *)seeMoreURL { + if (!_seeMoreURL) { + if ([EZLanguageManager.shared isSystemChineseFirstLanguage]) { + _seeMoreURL = @"https://github.com/tisfeng/Easydict/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98"; + } else { + _seeMoreURL = @"https://github.com/tisfeng/Easydict/wiki/FAQ"; + } + } + return _seeMoreURL; +} +@end diff --git a/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.h b/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.h index 8426194ab..333c13991 100644 --- a/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.h +++ b/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.h @@ -65,6 +65,8 @@ typedef NS_ENUM(NSUInteger, EZButtonState) { @property (nonatomic, copy) NSAttributedString *attrTitle; +@property (nonatomic, assign) NSEdgeInsets edgeInsets; // setting button padding + @property (nonatomic, copy, nullable) void (^clickBlock)(EZButton *button); @property (nonatomic, copy, nullable) void (^mouseEnterBlock)(EZButton *button); diff --git a/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.m b/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.m index adcaa7d6a..7d6f94200 100644 --- a/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.m +++ b/Easydict/objc/ViewController/View/CustomButton/EZButton/EZButton.m @@ -39,6 +39,12 @@ - (void)viewWillMoveToSuperview:(NSView *)newSuperview { [self updateButtonApperaceWithState:self.buttonState]; } +- (void)drawRect:(NSRect)dirtyRect { + NSRect originRect = self.bounds; + self.bounds = NSInsetRect(originRect, self.edgeInsets.left + self.edgeInsets.right, self.edgeInsets.top + self.edgeInsets.bottom); + [super drawRect:dirtyRect]; + self.bounds = originRect; +} #pragma mark - Mouse Actions diff --git a/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.h b/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.h index 42cd85c3a..83788c7d5 100644 --- a/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.h +++ b/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.h @@ -11,6 +11,7 @@ #import "EZQueryModel.h" #import "EZQueryResult.h" #import "EZTitlebar.h" +#import "EZTableTipsCell.h" NS_ASSUME_NONNULL_BEGIN @@ -64,6 +65,11 @@ NS_ASSUME_NONNULL_BEGIN - (void)receiveTitlebarAction:(EZTitlebarQuickAction)action; +- (void)updateActionType:(EZActionType)actionType; + +/// show tips view +- (void)showTipsView:(BOOL)isVisible; + @end NS_ASSUME_NONNULL_END diff --git a/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m b/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m index 6a5c0b963..a72a77804 100644 --- a/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m +++ b/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m @@ -31,6 +31,7 @@ static NSString *const EZQueryViewId = @"EZQueryViewId"; static NSString *const EZSelectLanguageCellId = @"EZSelectLanguageCellId"; +static NSString *const EZTableTipsCellId = @"EZTableTipsCellId"; static NSString *const EZResultViewId = @"EZResultViewId"; static NSString *const EZColumnId = @"EZColumnId"; @@ -54,6 +55,7 @@ @interface EZBaseQueryViewController ()