1
mirror of https://code.videolan.org/videolan/vlc synced 2024-08-18 23:45:06 +02:00

macosx/main menu: refactor and modernize dynamic menu handling (closes #22204)

This commit is contained in:
Felix Paul Kühne 2019-04-16 23:11:34 +02:00
parent a3ae8cd476
commit a154475e74

View File

@ -57,21 +57,27 @@
#import <Sparkle/Sparkle.h>
#endif
typedef NS_ENUM(NSInteger, VLCObjectType) {
VLCObjectTypeInterface,
VLCObjectTypeAout,
VLCObjectTypeVout,
};
@interface VLCAutoGeneratedMenuContent : NSObject
{
char *psz_name;
vlc_object_t *vlc_object;
vlc_value_t value;
int i_type;
vlc_object_t *_vlcObject;
}
- (id)initWithVariableName:(const char *)name
ofObject:(vlc_object_t *)object
andValue:(vlc_value_t)value
ofType:(int)type;
- (const char *)name;
- (vlc_value_t)value;
- (vlc_object_t *)vlcObject;
- (int)type;
- (instancetype)initWithVariableName:(const char *)name
ofObject:(vlc_object_t *)object
withObjectType:(VLCObjectType)objectType
andValue:(vlc_value_t)value
ofVariableType:(int)type;
@property (readonly) char *variableName;
@property (readonly) vlc_value_t variableValue;
@property (readonly) vlc_object_t *vlcObject;
@property (readonly) VLCObjectType objectType;
@property (readonly) int variableType;
@end
@ -197,6 +203,7 @@
[self setupVarMenuItem:_add_intf
target:VLC_OBJECT(getIntf())
objectType:VLCObjectTypeInterface
var:"intf-add"
selector:@selector(toggleVar:)];
@ -599,27 +606,45 @@
if (p_mediaItem != NULL) {
audio_output_t *p_aout = [_playerController mainAudioOutput];
if (p_aout != NULL) {
[self setupVarMenuItem:_channels target:VLC_OBJECT(p_aout)
var:"stereo-mode" selector:@selector(toggleVar:)];
[self setupVarMenuItem:_channels
target:VLC_OBJECT(p_aout)
objectType:VLCObjectTypeAout
var:"stereo-mode"
selector:@selector(toggleVar:)];
[self setupVarMenuItem:_visual target:VLC_OBJECT(p_aout)
var:"visual" selector:@selector(toggleVar:)];
[self setupVarMenuItem:_visual
target:VLC_OBJECT(p_aout)
objectType:VLCObjectTypeAout
var:"visual"
selector:@selector(toggleVar:)];
aout_Release(p_aout);
}
vout_thread_t *p_vout = [_playerController videoOutputThreadForKeyWindow];
if (p_vout != NULL) {
[self setupVarMenuItem:_aspect_ratio target:VLC_OBJECT(p_vout)
var:"aspect-ratio" selector: @selector(toggleVar:)];
[self setupVarMenuItem:_aspect_ratio
target:VLC_OBJECT(p_vout)
objectType:VLCObjectTypeVout
var:"aspect-ratio"
selector:@selector(toggleVar:)];
[self setupVarMenuItem:_crop target:VLC_OBJECT(p_vout)
var:"crop" selector: @selector(toggleVar:)];
[self setupVarMenuItem:_crop
target:VLC_OBJECT(p_vout)
objectType:VLCObjectTypeVout
var:"crop"
selector:@selector(toggleVar:)];
[self setupVarMenuItem:_deinterlace target:VLC_OBJECT(p_vout)
var:"deinterlace" selector: @selector(toggleVar:)];
[self setupVarMenuItem:_deinterlace
target:VLC_OBJECT(p_vout)
objectType:VLCObjectTypeVout
var:"deinterlace"
selector:@selector(toggleVar:)];
[self setupVarMenuItem:_deinterlace_mode target:VLC_OBJECT(p_vout)
var:"deinterlace-mode" selector: @selector(toggleVar:)];
[self setupVarMenuItem:_deinterlace_mode
target:VLC_OBJECT(p_vout)
objectType:VLCObjectTypeVout
var:"deinterlace-mode"
selector:@selector(toggleVar:)];
vout_Release(p_vout);
@ -819,7 +844,6 @@
- (void)lockVideosAspectRatio:(id)sender
{
// FIXME: re-write the following using VLCPlayerController
[_playerController setAspectRatioIsLocked: ![sender state]];
[sender setState: [_playerController aspectRatioIsLocked]];
}
@ -1504,6 +1528,7 @@
- (void)setupVarMenuItem:(NSMenuItem *)menuItem
target:(vlc_object_t *)p_object
objectType:(VLCObjectType)objectType
var:(const char *)psz_variable
selector:(SEL)pf_callback
{
@ -1533,6 +1558,7 @@
[self setupVarMenu:menu
forMenuItem:menuItem
target:p_object
objectType:objectType
var:psz_variable
selector:pf_callback];
@ -1548,16 +1574,18 @@
case VLC_VAR_VOID:
data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName:psz_variable
ofObject:p_object
withObjectType:objectType
andValue:val
ofType:i_type];
ofVariableType:i_type];
[menuItem setRepresentedObject:data];
break;
case VLC_VAR_BOOL:
data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName:psz_variable
ofObject:p_object
withObjectType:objectType
andValue:val
ofType:i_type];
ofVariableType:i_type];
[menuItem setRepresentedObject:data];
if (!(i_type & VLC_VAR_ISCOMMAND))
[menuItem setState:val.b_bool ? NSOnState : NSOffState];
@ -1576,6 +1604,7 @@
- (void)setupVarMenu:(NSMenu *)menu
forMenuItem:(NSMenuItem *)parent
target:(vlc_object_t *)p_object
objectType:(VLCObjectType)objectType
var:(const char *)psz_variable
selector:(SEL)pf_callback
{
@ -1592,9 +1621,11 @@
[parent setEnabled:NO];
/* Aspect Ratio */
if ([[parent title] isEqualToString: _NS("Aspect ratio")] == YES) {
if ([[parent title] isEqualToString:_NS("Aspect ratio")] == YES) {
NSMenuItem *lmi_tmp2;
lmi_tmp2 = [menu addItemWithTitle: _NS("Lock Aspect Ratio") action: @selector(lockVideosAspectRatio:) keyEquivalent: @""];
lmi_tmp2 = [menu addItemWithTitle:_NS("Lock Aspect Ratio")
action:@selector(lockVideosAspectRatio:)
keyEquivalent:@""];
[lmi_tmp2 setTarget: self];
[lmi_tmp2 setEnabled: YES];
[lmi_tmp2 setState: [_playerController aspectRatioIsLocked]];
@ -1633,7 +1664,8 @@
if (var_Change(p_object, psz_variable, VLC_VAR_GETCHOICES,
&count, &val_list, &text_list) < 0) {
if ((i_type & VLC_VAR_TYPE) == VLC_VAR_STRING) free(val.psz_string);
if ((i_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
free(val.psz_string);
return;
}
@ -1653,8 +1685,9 @@
lmi = [menu addItemWithTitle:title action:pf_callback keyEquivalent:@""];
data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName:psz_variable
ofObject:p_object
withObjectType:objectType
andValue:val_list[i]
ofType:i_type];
ofVariableType:i_type];
[lmi setRepresentedObject:data];
[lmi setTarget:self];
@ -1673,8 +1706,9 @@
lmi = [menu addItemWithTitle: title action: pf_callback keyEquivalent: @""];
data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName:psz_variable
ofObject:p_object
withObjectType:objectType
andValue:val_list[i]
ofType:i_type];
ofVariableType:i_type];
[lmi setRepresentedObject:data];
[lmi setTarget:self];
@ -1715,7 +1749,7 @@
VLCAutoGeneratedMenuContent *menuContent = (VLCAutoGeneratedMenuContent *)data;
p_object = [menuContent vlcObject];
var_Set(p_object, [menuContent name], [menuContent value]);
var_Set(p_object, [menuContent variableName], [menuContent variableValue]);
}
}
@ -1838,20 +1872,34 @@
@implementation VLCAutoGeneratedMenuContent
-(id)initWithVariableName:(const char *)name
ofObject:(vlc_object_t *)object
andValue:(vlc_value_t)val
ofType:(int)type
- (instancetype)initWithVariableName:(const char *)name
ofObject:(vlc_object_t *)object
withObjectType:(VLCObjectType)objectType
andValue:(vlc_value_t)value
ofVariableType:(int)type;
{
self = [super init];
if (self != nil) {
vlc_object = vlc_object_hold(object);
psz_name = strdup(name);
i_type = type;
value = val;
if ((i_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
value.psz_string = strdup(val.psz_string);
switch (objectType) {
case VLCObjectTypeAout:
aout_Hold((audio_output_t *)object);
break;
case VLCObjectTypeVout:
vout_Hold((vout_thread_t *)object);
break;
default:
// No need to retain the interface because it will always be there
break;
}
_vlcObject = object;
_objectType = objectType;
_variableName = strdup(name);
_variableType = type;
_variableValue = value;
if ((type & VLC_VAR_TYPE) == VLC_VAR_STRING)
_variableValue.psz_string = strdup(value.psz_string);
}
return(self);
@ -1859,31 +1907,11 @@
- (void)dealloc
{
if (vlc_object)
vlc_object_release(vlc_object);
if ((i_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
free(value.psz_string);
free(psz_name);
}
- (const char *)name
{
return psz_name;
}
- (vlc_value_t)value
{
return value;
}
- (vlc_object_t *)vlcObject
{
return vlc_object;
}
- (int)type
{
return i_type;
if (_vlcObject && _objectType != VLCObjectTypeInterface)
vlc_object_release(_vlcObject);
if ((_variableType & VLC_VAR_TYPE) == VLC_VAR_STRING)
free(_variableValue.psz_string);
free(_variableName);
}
@end