Fix inspector undo, time changes and legacy disabled-state migration; verify secure template and 1039 regressions

这个提交包含在:
dayu 于 2026-10-21 22:53:12 +08:00 提交
1 父节点 f4c0d608a4
当前提交 f79d24eb01
19 个文件已更改
+298 -15

没有与搜索条件相匹配的文件

@@ -32,6 +32,7 @@ FOUNDATION_EXPORT PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings
@property (nonatomic, copy, readonly) NSString *statusMessage;
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager;
- (void)refresh;
- (void)documentDidChange;
- (void)beginInteraction;
- (void)endInteraction;
- (BOOL)setValue:(double)value forParameter:(UInt32)identifier;
+26 -5
查看文件
@@ -116,7 +116,7 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
}
if(![state valueForParameter:PGSmoothingEnabled])s.amount=s.midtoneDetail=s.highPassDetail=0;
if(![state valueForParameter:PGColorEnabled]) {s.skinBrightness=s.skinHue=s.skinSaturation=s.skinEvenTone=s.teethWhitening=s.eyeBrightening=0;s.skinTonePreset=0;}
if(![state valueForParameter:PGShapeEnabled])s.faceThin=s.faceBigEye=s.faceShort=s.faceNarrow=s.faceChin=s.faceV=s.faceJaw=s.faceCheekbone=s.faceSmallHead=0;
if(![state valueForParameter:PGShapeEnabled]) {s.faceThin=s.faceBigEye=s.faceShort=s.faceNarrow=s.faceChin=s.faceV=s.faceJaw=s.faceCheekbone=s.faceSmallHead=0;s.showTrackBox=0;}
return s;
}
@@ -128,6 +128,7 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
@property (nonatomic,strong) id<FxCustomParameterActionAPI_v4> action;
@property (nonatomic) BOOL interacting;
@property (nonatomic) NSTimeInterval pendingUntil;
@property (nonatomic) CMTime pendingTime;
@end
@implementation PGInspectorController
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager {
@@ -145,6 +146,7 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
}
- (void)finish {if(_interacting){_interacting=NO;[_action endAction:self];_action=nil;}}
- (void)readAtTime:(CMTime)time {
if(_pendingUntil && CMTimeCompare(time,_pendingTime)!=0)_pendingUntil=0;
id<FxParameterRetrievalAPI_v6> api=[_manager apiForProtocol:@protocol(FxParameterRetrievalAPI_v6)];
NSObject *object=nil;[api getCustomParameterValue:&object fromParameter:PGInspectorPanel atTime:time];
if([object isKindOfClass:PGInspectorState.class] && [(PGInspectorState *)object hasEdits]) {
@@ -162,16 +164,31 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
else [api getFloatValue:&value fromParameter:key atTime:time];
values[@(key)]=@(value);
}
_state=[PGInspectorState stateWithValues:values disabledParameters:[NSSet set] hasEdits:NO];
BOOL legacyDetail=YES;[api getBoolValue:&legacyDetail fromParameter:PGDetailEnabled atTime:time];
NSMutableSet *disabled=legacyDetail?[NSMutableSet set]:[NSMutableSet setWithObjects:@(PGHighPass),@(PGSharpness),nil];
// Earlier versions put high-pass smoothing under a different group. Keep
// its effective state when importing a document whose local-skin group was
// off, rather than turning a still-active global effect off on first edit.
if(![values[@(PGSmoothingEnabled)] boolValue] && legacyDetail && [values[@(PGHighPass)] doubleValue]>0) {
values[@(PGSmoothingEnabled)]=@YES;
[disabled addObject:@(PGMidtone)];[disabled addObject:@(PGAmount)];
}
_state=[PGInspectorState stateWithValues:values disabledParameters:disabled hasEdits:NO];
}
- (void)refresh {
if(_interacting)return;
if(![self start])return;
@try {[self readAtTime:[_action currentTime]];_statusMessage=@"";} @finally {[self finish];}
}
- (void)documentDidChange {if(_interacting)return;_pendingUntil=0;[self refresh];}
- (void)beginInteraction {
if(_interacting)return;
if([self start])[self readAtTime:[_action currentTime]];
if([self start]) {
// A new gesture starts from the authoritative document, including an
// immediate undo. The short pending hold only prevents display flicker;
// it must never resurrect an undone value in a subsequent edit.
_pendingUntil=0;[self readAtTime:[_action currentTime]];
}
}
- (void)endInteraction {[self finish];}
- (BOOL)commit:(PGInspectorState *)next {
@@ -190,7 +207,7 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
else if([d[@"kind"] isEqual:@"toggle"] || [d[@"kind"] isEqual:@"master"]) [api setBoolValue:value!=0 toParameter:key atTime:time];
else [api setFloatValue:value toParameter:key atTime:time];
}
_state=next;_pendingUntil=NSDate.timeIntervalSinceReferenceDate+.35;_statusMessage=@"";return YES;
_state=next;_pendingUntil=NSDate.timeIntervalSinceReferenceDate+.35;_pendingTime=time;_statusMessage=@"";return YES;
}
- (BOOL)setValue:(double)value forParameter:(UInt32)identifier {
NSDictionary *d=PGInspectorDescriptor(identifier);if(!d || !isfinite(value))return NO;
@@ -202,7 +219,11 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
}
- (BOOL)toggleEnabledForParameter:(UInt32)identifier {
NSDictionary *d=PGInspectorDescriptor(identifier);if(!d)return NO;
if([d[@"kind"] isEqual:@"master"] || [d[@"kind"] isEqual:@"toggle"])return [self setValue:![self.state valueForParameter:identifier] forParameter:identifier];
if([d[@"kind"] isEqual:@"master"] || [d[@"kind"] isEqual:@"toggle"]) {
BOOL owned=!_interacting;if(owned)[self beginInteraction];if(!_interacting)return NO;
BOOL ok=NO;@try {ok=[self setValue:![_state valueForParameter:identifier] forParameter:identifier];}
@finally {if(owned)[self finish];}return ok;
}
if(![d[@"bypass"] boolValue])return NO;
BOOL owned=!_interacting;if(owned)[self beginInteraction];if(!_interacting)return NO;
BOOL ok=NO;@try {
@@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
/// Also permits a deterministic controller in an offscreen preview or test.
- (instancetype)initWithController:(PGInspectorController *)controller;
- (void)refreshFromHost;
- (void)hostParameterChanged;
@end
NS_ASSUME_NONNULL_END
+5 -1
查看文件
@@ -253,7 +253,10 @@ static PGInspectorGlyphButton *PGUIButton(NSString *glyph, NSColor *accent, id t
}
if(number&&isfinite(number.doubleValue)){
double value=number.doubleValue/PGValueScale(_descriptor);value=fmin([_descriptor[@"max"]doubleValue],fmax([_descriptor[@"min"]doubleValue],value));
if(fabs(value-[_inspector.controller.state valueForParameter:[_descriptor[@"id"]unsignedIntValue]])>.0000001)[_inspector writeValue:value parameter:[_descriptor[@"id"]unsignedIntValue]];
// Commit explicit input even when it equals our last displayed value:
// the document may have changed while the field editor held focus.
// The controller rereads the host and deduplicates the actual value.
[_inspector writeValue:value parameter:[_descriptor[@"id"]unsignedIntValue]];
}else NSBeep();
_valueField.stringValue=PGFormattedValue(_descriptor,[_inspector.controller.state valueForParameter:[_descriptor[@"id"]unsignedIntValue]]);
}
@@ -331,6 +334,7 @@ static PGInspectorGlyphButton *PGUIButton(NSString *glyph, NSColor *accent, id t
}
- (BOOL)hasActiveTextEditor { for(PGInspectorCard *card in _cards)for(PGInspectorRow *row in card.rows)if(row.valueField.currentEditor)return YES;return NO; }
- (void)refreshFromHost { if(_interactionDepth || [self hasActiveTextEditor])return;[_controller refresh];[self reloadControls]; }
- (void)hostParameterChanged { if(_interactionDepth || [self hasActiveTextEditor])return;[_controller documentDidChange];[self reloadControls]; }
- (void)writeValue:(double)value parameter:(UInt32)identifier { [_controller setValue:value forParameter:identifier];[self reloadControls]; }
- (void)beginControlInteraction { if(_interactionDepth++==0)[_controller beginInteraction]; }
- (void)endControlInteraction { if(!_interactionDepth)return;if(--_interactionDepth==0){[_controller endInteraction];[self refreshFromHost];} }
+12 -1
查看文件
@@ -93,6 +93,7 @@ static CIImage *PGImageFromTile(FxImageTile *tile) {
@property BOOL analysisForward;
@property (strong) NSArray<NSString *> *loadedTracks;
@property BOOL reportedRender;
@property (strong) NSHashTable<PGInspectorView *> *inspectorViews;
@end
@implementation beatygrilPlugIn
@@ -103,6 +104,7 @@ static CIImage *PGImageFromTile(FxImageTile *tile) {
_analysisFaceProcessor=[PGFaceProcessor new];
_contexts=[NSMutableDictionary new]; _analysisSettings=PGBeautyDefaults();
_analysisTime=kCMTimeZero;
_inspectorViews=[NSHashTable weakObjectsHashTable];
}
return self;
}
@@ -165,7 +167,16 @@ static CIImage *PGImageFromTile(FxImageTile *tile) {
return ok ? YES : PGFail(error,@"宿主未能创建完整的人像美化参数。");
}
- (NSView *)createViewForParameterID:(UInt32)identifier {
return identifier==PGInspectorPanel ? [[PGInspectorView alloc] initWithAPIManager:_apiManager] : nil;
if(identifier!=PGInspectorPanel)return nil;
PGInspectorView *view=[[PGInspectorView alloc] initWithAPIManager:_apiManager];
@synchronized(_inspectorViews){[_inspectorViews addObject:view];}return view;
}
- (BOOL)parameterChanged:(UInt32)identifier atTime:(CMTime)time error:(NSError **)error {
// The host callback covers undo and playhead-driven parameter changes. Hop
// to AppKit's thread and avoid retaining remote inspector views in render.
NSArray *views;@synchronized(_inspectorViews){views=_inspectorViews.allObjects;}
for(PGInspectorView *view in views)dispatch_async(dispatch_get_main_queue(), ^{[view hostParameterChanged];});
return YES;
}
- (Class)classForCustomParameterID:(UInt32)identifier {return identifier==PGInspectorPanel?PGInspectorState.class:Nil;}
- (NSSet<Class> *)classesForCustomParameterID:(UInt32)identifier {