Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/Packages
/*.xcodeproj
xcuserdata/
.swiftpm

.theos
/packages
Expand Down
1 change: 1 addition & 0 deletions Sources/Pinnacle/Hooks/SBIconListViewHook.x.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class SBIconListViewHook: ClassHook<SBIconListView> {

// orion:new
func _pinnacleForIconViews(_ action:(SBIconView) -> Void) {
if target.subviews.isEmpty { return } // Fixes a crash issue
var iconViews: [UIView]
if target.subviews[0].isKind(of: SBFTouchPassThroughView.classForCoder()) {
iconViews = target.subviews[0].subviews
Expand Down
128 changes: 119 additions & 9 deletions Sources/Pinnacle/Hooks/SBIconViewHook.x.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import PinnacleC
class SBIconViewHook: ClassHook<SBIconView> {
@Property var hasInit = false
@Property var icon: SBApplicationIcon?

@Property var grabberView: UIImageView? = nil

@Property var row: UInt? = nil
@Property var column: UInt? = nil
Expand All @@ -14,7 +16,12 @@ class SBIconViewHook: ClassHook<SBIconView> {
func didMoveToSuperview() {
orig.didMoveToSuperview()

guard !target.isFolderIcon() else { return }
guard !target.isFolderIcon() else {
if grabberView != nil {
grabberView?.removeFromSuperview()
}
return
}
guard target.icon != nil else { return }
guard target.icon.isKind(of: SBApplicationIcon.classForCoder()) else { return }
icon = target.icon as? SBApplicationIcon
Expand All @@ -23,6 +30,30 @@ class SBIconViewHook: ClassHook<SBIconView> {
guard !target.superview!.isKind(of: SBDockIconListView.classForCoder()) else { return }

guard !target.isKind(of: PinnacleIconView.classForCoder()) else { return }

if grabberImage == nil {
grabberImage = UIImage(contentsOfFile: grabberPath())
}

if grabberView == nil {
let iconSize = _pinnacleGetImageSize()

grabberView = UIImageView(frame: CGRectMake(iconSize.width * -0.06, iconSize.height * -0.06, iconSize.width * 1.12, iconSize.height * 1.12))
grabberView?.isUserInteractionEnabled = false
grabberView?.contentMode = .scaleAspectFit
}

grabberView?.alpha = 1
_pinnacleUpdateIndicator(bundleID: icon!.applicationBundleID())

if !grabberView!.isDescendant(of: target) {
target.addSubview(grabberView!)
}
target.sendSubviewToBack(grabberView!)

_pinnacleForSubviews({(iconView: PinnacleIconView) -> Void in
iconView.removeFromSuperview()
})

guard !hasInit else { return }
hasInit = true
Expand All @@ -39,10 +70,54 @@ class SBIconViewHook: ClassHook<SBIconView> {

target.addGestureRecognizer(swipeGesture)
scrollViewPanGesture?.require(toFail: swipeGesture)

if settings!.activationGestureDirection == "both" {
let secondSwipeGesture = UISwipeGestureRecognizer()
secondSwipeGesture.direction = .up

secondSwipeGesture.addTarget(target, action: #selector(_pinnacleHandleActivation))

target.addGestureRecognizer(secondSwipeGesture)
scrollViewPanGesture?.require(toFail: secondSwipeGesture)
}
}

// orion:new
func _pinnacleUpdateIndicator(bundleID: String) {
if settings!.indicator == "none" {
grabberView?.image = nil
return
}

let data = getStackData(for: bundleID)
var direction = 0

let offsets = [
(0, -1), // Up
(1, 0), // Right
(0, 1), // Down
(-1, 0) // Left
]

for (index, bundle) in data.enumerated() {
direction = (direction + 1) % 4
let (xDir, yDir) = offsets[direction]

if !bundle.contains("dev.rugmj.PinnaclePlaceholder") {
if settings!.indicator == "apps" {
// TODO: App previews
} else {
grabberView?.image = grabberImage
return
}
}
}

grabberView?.image = nil
}

// orion:new
@objc func _pinnacleHandleActivation() {
@objc func _pinnacleHandleActivation() {
guard !target.isFolderIcon() else { return }
guard !active else { return }
active = true
Expand Down Expand Up @@ -146,9 +221,9 @@ class SBIconViewHook: ClassHook<SBIconView> {
UIView.animate(withDuration: settings!.fadeDuration, animations: {
self.target.alpha = 1
})

guard !target.icon.isKind(of: SBWidgetIcon.classForCoder()) else { return }

if let x = originalX, let y = originalY {
UIView.animate(
withDuration: settings!.iconMoveDuration,
Expand All @@ -161,12 +236,37 @@ class SBIconViewHook: ClassHook<SBIconView> {
self.target.frame.origin.x = x
}
}

for subview in target.subviews {
if let iconView = subview as? PinnacleIconView {
iconView._pinnacleReset()

if self.grabberView != nil {
if target.isFolderIcon() {
self.grabberView?.removeFromSuperview()
} else {
if !self.grabberView!.isDescendant(of: target) {
target.addSubview(self.grabberView!)
}
if icon!.applicationBundleID() != nil {
_pinnacleUpdateIndicator(bundleID: self.icon!.applicationBundleID())
} else {
self.grabberView?.image = nil
}
target.sendSubviewToBack(self.grabberView!)
UIView.animate(
withDuration: settings!.iconMoveDuration,
delay: 0,
usingSpringWithDamping: settings!.springDamping,
initialSpringVelocity: settings!.springInitialVelocity
)
{
self.grabberView?.alpha = 1
}
}
}


_pinnacleForSubviews({(iconView: PinnacleIconView) -> Void in
iconView._pinnacleReset()
})

}


Expand Down Expand Up @@ -227,7 +327,17 @@ class SBIconViewHook: ClassHook<SBIconView> {
} else {
yDiff *= directions[2] as! Int
}



UIView.animate(
withDuration: settings!.iconMoveDuration,
delay: 0,
usingSpringWithDamping: settings!.springDamping,
initialSpringVelocity: settings!.springInitialVelocity
)
{
self.grabberView?.alpha = 0
}

_pinnacleMoveWith(x: xDiff, y: yDiff)
}
Expand Down
6 changes: 4 additions & 2 deletions Sources/Pinnacle/PinnacleIconView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ class PinnacleIconView: SBIconView {
self.init()
setupCommonProperties(xDir: xDir, yDir: yDir, bundle: bundle, parentBundle: parentBundle, index: index)

let image = UIImage(contentsOfFile: plusCirclePath())
if placeholderImage == nil {
placeholderImage = UIImage(contentsOfFile: plusCirclePath())
}

let imageView = UIImageView(image: image)
let imageView = UIImageView(image: placeholderImage)
imageView.frame = CGRect(x: 0, y: 0, width: 60, height: 60)

imageView.isUserInteractionEnabled = true
Expand Down
5 changes: 4 additions & 1 deletion Sources/Pinnacle/Tweak.x.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Pinnacle: Tweak {
})
}, name, nil, .deliverImmediately)

if settings!.activationGestureDirection == "down" {
if settings!.activationGestureDirection != "up" {
SpotlightHookGroup().activate()
}
}
Expand Down Expand Up @@ -102,3 +102,6 @@ func normalise(_ number: Int) -> Int {
}

var settings: Settings?

var grabberImage: UIImage? = nil
var placeholderImage: UIImage? = nil
1 change: 1 addition & 0 deletions Sources/Pinnacle/TweakPreferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ struct Settings: Codable {
var springInitialVelocity = 0.0
var hapticFeedback = true
var activationGestureDirection = "up"
var indicator = "none"
}
5 changes: 5 additions & 0 deletions Sources/PinnacleC/Tweak.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@
return JBROOT_PATH_NSSTRING(
@"/Library/Tweak Support/dev.rugmj.pinnacle/plus-circle.png");
}

NSString *grabberPath() {
return JBROOT_PATH_NSSTRING(
@"/Library/Tweak Support/dev.rugmj.pinnacle/grabber.png");
}
1 change: 1 addition & 0 deletions Sources/PinnacleC/include/Tweak.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <objc/NSObjCRuntime.h>

NSString *plusCirclePath();
NSString *grabberPath();

@interface SBSearchScrollView : UIScrollView
@end
Expand Down
2 changes: 1 addition & 1 deletion control
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: dev.rugmj.pinnacle
Name: Pinnacle
Version: 1.1.0
Version: 1.2.0
Architecture: iphoneos-arm
Description: A new way to organise your apps
Maintainer: rugmj
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import libroot
final class PreferenceStorage: ObservableObject {
static let registry: String = jbRootPath("/var/mobile/Library/Preferences/dev.rugmj.pinnacleprefs.plist")

@Published(key: "enabled", registry: registry) var isEnabled: Bool = true
@Published(key: "showAppLabels", registry: registry) var isEnabled: Bool = true
@Published(key: "enabled", registry: registry) var isEnabled: Bool = true
@Published(key: "showAppLabels", registry: registry) var showAppLabels: Bool = true
@Published(key: "fadeAmount", registry: registry) var fadeAmount: Double = 0.3
@Published(key: "fadeDuration", registry: registry) var fadeDuration: Double = 0.2
@Published(key: "iconMoveDuration", registry: registry) var iconMoveDuration: Double = 0.5
@Published(key: "springDamping", registry: registry) var springDamping: Double = 0.6
@Published(key: "springInitialVelocity", registry: registry) var springInitialVelocity: Double = 0.0
@Published(key: "hapticFeedback", registry: registry) var hapticFeedback = true
@Published(key: "activationGestureDirection", registry: registry) var activationGestureDirection = "up"
@Published(key: "indicator", registry: registry) var indicator = "none"

private var cancellables: Set<AnyCancellable> = []

Expand Down
12 changes: 12 additions & 0 deletions pinnacleprefs/Sources/PinnaclePrefs/Main/RootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,23 @@ struct RootView: View {
Picker("Gesture Direction", selection: $preferenceStorage.activationGestureDirection) {
Text("Up").tag("up")
Text("Down").tag("down")
Text("Either").tag("both")
}.pickerStyle(.segmented)

} header: {
Text("Gesture")
}

Section {
Picker("Visual Indicator", selection: $preferenceStorage.indicator) {
Text("None").tag("none")
Text("Grabbers").tag("grabbers")
//Text("App Previews").tag("apps")
}.pickerStyle(.segmented)

} header: {
Text("Indicator")
}

Section {
SliderWithLabel(
Expand Down