Files
Duy Tran KhanhandDuy Tran Khanh 33cb7d0125 Custom Controls revisions implemenation (#292)
* Move control loaders to CustomControlsUtils.m

* WIP Drawer support (currently broken)

Also, updated MetalANGLE for helping debug stuff on crash.

* temp

* ControlDrawer: free orientation

* Avoid scrolling the hotbar in grab mode

* Popover: fix the frame inside the arrow

* Changes

- Attempt to allow Microsoft login when offline.
- Custom controls: drawer and sub-buttons are now visible.
- Pickers in Preferences: pre-select at the saved index.

* Bump version code to 4, hide sub-button by default

* Fix text trucanting

* impl scroll buttons, rewrite some parts to objc

* Virtual mouse implementation

Also, possible fix for popover crashes on iPad

Exception type: NSInternalInconsistencyException
> Reason: Tried to set <UIBarButtonItem: 0x10fee5660> menuOnTouchDown
menu=0x2810dce10 image=<UIImage:0x280149050 symbol(system:
ellipsis.circle) {20, 19} baseline=3.5,contentInsets={1, 1.5, 1,
1.5},alignmentRectInsets={-0.5, 0, -0.5, 0}
config=<traits=(UserInterfaceIdiom = Pad, DisplayScale = 2,
DisplayGamut = sRGB, HorizontalSizeClass = Regular, VerticalSizeClass
= Regular, UserInterfaceStyle = Dark, UserInterfaceLayoutDirection =
LTR, PreferredContentSizeCategory = L, AccessibilityContrast =
Normal)>> as sourceView of
<_UIAlertControllerActionSheetRegularPresentationController:
0x12043f5a0>, even though it is not a kind of UIView.

* Swap item between hands by double-tap item moment

* Basic editor (only several stuff implemented)

There's no save/load yet, so it's just a preview for now.

* Control editor (preview only)
TODO: Color picker for iOS < 14

* Save, load and set default are here

* Changes

- Ported Snap and Align from Android
- Added options: create and delete button

TODO:
- color picker for iOS < 14
- drawer editor
- maybe more

* Editor: Added orientation changer for drawer

Added some more check to determine whether dynamic position should be
visible (when the button is not a sub-button, or the parent drawer
doesn't use the FREE orientation)

* Editor: implemented adding drawer and sub-button

* Added a warning about unfinished custom controls

Co-authored-by: Duy Tran Khanh <[email protected]>
2021-11-26 10:35:21 +07:00

119 lines
3.8 KiB
Objective-C

#import "ControlDrawer.h"
#import "CustomControlsUtils.h"
#import "../LauncherPreferences.h"
#import "../utils.h"
#define DOWN 0
#define LEFT 1
#define UP 2
#define RIGHT 3
@implementation ControlDrawer
+ (id)buttonWithData:(NSMutableDictionary *)drawerData {
ControlDrawer *instance = [self buttonWithProperties:drawerData[@"properties"] willUpdate:NO];
instance.buttons = [[NSMutableArray alloc] init];
instance.drawerData = drawerData;
[instance update];
return instance;
}
- (ControlSubButton *)addButtonProp:(NSMutableDictionary *)prop {
[self.drawerData[@"buttonProperties"] addObject:prop];
return [self addButton:[ControlSubButton buttonWithProperties:prop]];
}
- (ControlSubButton *)addButton:(ControlSubButton *)button {
[self.buttons addObject:button];
button.parentDrawer = self;
button.hidden = !isControlModifiable;
return button;
}
- (void)restoreButtonVisibility {
for (ControlButton *button in self.buttons) {
button.hidden = !self.areButtonsVisible;
}
}
- (void)switchButtonVisibility {
self.areButtonsVisible = !self.areButtonsVisible;
[self restoreButtonVisibility];
}
// NOTE: Unlike Android's impl, this method uses dp instead of px (no call to dpToPx)
- (void)alignButtons {
NSString *orientation = (NSString *)self.drawerData[@"orientation"];
if ([orientation isEqualToString:@"FREE"]) {
return;
}
for (int i = 0; i < self.buttons.count; i++) {
ControlButton *button = self.buttons[i];
if ([orientation isEqualToString:@"RIGHT"]) {
button.properties[@"dynamicX"] = [self generateDynamicX:self.frame.origin.x + ([self.properties[@"width"] floatValue] + 2.0) * (i+1)];
button.properties[@"dynamicY"] = [self generateDynamicY:self.frame.origin.y];
} else if ([orientation isEqualToString:@"LEFT"]) {
button.properties[@"dynamicX"] = [self generateDynamicX:self.frame.origin.x - ([self.properties[@"width"] floatValue] + 2.0) * (i+1)];
button.properties[@"dynamicY"] = [self generateDynamicY:self.frame.origin.y];
} else if ([orientation isEqualToString:@"UP"]) {
button.properties[@"dynamicY"] = [self generateDynamicY:self.frame.origin.y - ([self.properties[@"height"] floatValue] + 2.0) * (i+1)];
button.properties[@"dynamicX"] = [self generateDynamicX:self.frame.origin.x];
} else if ([orientation isEqualToString:@"DOWN"]) {
button.properties[@"dynamicY"] = [self generateDynamicY:self.frame.origin.y + ([self.properties[@"height"] floatValue] + 2.0) * (i+1)];
button.properties[@"dynamicX"] = [self generateDynamicX:self.frame.origin.x];
} else {
NSLog(@"DEBUG: %s: Unsupported button orientation %@", __FILE__, orientation);
}
[button update];
}
}
- (void)resizeButtons {
for (ControlButton *button in self.buttons) {
button.properties[@"width"] = self.properties[@"width"];
button.properties[@"height"] = self.properties[@"height"];
[button update];
}
}
- (void)syncButtons {
[self alignButtons];
[self resizeButtons];
}
- (BOOL)containsChild:(ControlButton *)button {
return [self.buttons containsObject:button];
}
- (void)preProcessProperties {
[super preProcessProperties];
self.properties[@"isHideable"] = @(YES);
}
/*
- (void)setHidden:(BOOL)hidden {
super
}
*/
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
if (!isControlModifiable) {
[self switchButtonVisibility];
}
}
- (BOOL)canSnap:(ControlButton *)button {
return [super canSnap:button] && ![self containsChild:button];
}
- (void)snapAndAlignX:(CGFloat)x Y:(CGFloat)y {
[super snapAndAlignX:x Y:y];
[self alignButtons];
}
@end