# CutBox.app

## Coverage Report

#### Created: 2024-03-12 03:40

    .../Source/Components/Popup/PopupController.swift

    Line

    Count

    Source (jump to first uncovered line)

    1

    //

    2

    //  PopupController.swift

    3

    //  CutBox

    4

    //

    5

    //  Created by Jason Milkins on 17/3/18.

    6

    //  Copyright © 2018-2023 ocodo. All rights reserved.

    7

    //

    8

    9

    import Cocoa

    10

    11

    class PopupController: CutBoxBaseWindowController {

    12

    13

    179

        let panel = PopupPanel()

    14

    15

    179

        let backgroundView = PopupBackgroundView()

    16

    179

        let containerView = PopupContainerView()

    17

        var contentView: CutBoxBaseView

    18

    19

        var currentHeight: Double = 0

    20

        var currentWidth: Double = 0

    21

    22

    179

        var proportionalWidth: Double = 1.0 / 1.6

    23

    179

        var proportionalHeight: Double = 1.0 / 1.8

    24

        var proportionalTopPadding: CGFloat = 0

    25

    26

        var contentInset: CGFloat {

    27

    11

            get {

    28

    11

                return containerView.contentInset

    29

    11

            }

    30

    31

    1

            set {

    32

    1

                let size = containerView.frame.size

    33

    1

                containerView.contentInset = newValue

    34

    1

                resizePopup(width: Double(size.width),

    35

    1

                            height: Double(size.height))

    36

    1

            }

    37

        }

    38

    39

        var isOpen: Bool = false

    40

    41

        var isOpening: Bool = false

    42

    43

        var willOpenPopup: (() -> Void)?

    44

        var didOpenPopup: (() -> Void)?

    45

        var willClosePopup: (() -> Void)?

    46

        var didClosePopup: (() -> Void)?

    47

    48

        var lastMouseDownEvent: NSEvent?

    49

        var mouseDownEventMonitor: Any?

    50

        var mouseUpEventMonitor: Any?

    51

    52

        var lastKeyDownEvent: NSEvent?

    53

        var keyDownEventMonitor: Any?

    54

    55

    178

        init(content: CutBoxBaseView) {

    56

    178

            self.contentView = content

    57

    178

            super.init(window: panel)

    58

    178

            setup()

    59

    178

        }

    60

    61

    1

        required init?(coder: NSCoder) {

    62

    1

            self.contentView = coder.decodeObject(forKey: "contentView") as? CutBoxBaseView ?? CutBoxBaseView()

    63

    1

            super.init(coder: coder)

    64

    1

            self.window = panel

    65

    1

            setup()

    66

    1

        }

    67

    68

    179

        func setup() {

    69

    179

            panel.windowController = self

    70

    179

            panel.acceptsMouseMovedEvents = true

    71

    179

    72

    179

            panel.level = NSWindow.Level(rawValue:

    73

    179

                Int(CGWindowLevelForKey(CGWindowLevelKey.popUpMenuWindow))

    74

    179

            )

    75

    179

    76

    179

            panel.isOpaque = false

    77

    179

            panel.backgroundColor = NSColor.clear

    78

    179

            panel.styleMask = .nonactivatingPanel

    79

    179

            panel.hidesOnDeactivate = false

    80

    179

            panel.hasShadow = true

    81

    179

            panel.delegate = self

    82

    179

            panel.contentView = backgroundView

    83

    179

            backgroundView.addSubview(containerView)

    84

    179

    85

    179

            containerView.setup()

    86

    179

            containerView.contentView = contentView

    87

    179

            panel.initialFirstResponder = contentView

    88

    179

        }

    89

    90

    3

        func openPopup() {

    91

    3

            openPanel()

    92

    3

        }

    93

    94

    8

        func closePopup() {

    95

    8

            closePanel()

    96

    8

        }

    97

    98

    2

        @objc func togglePopup() {

    99

    2

            if isOpen {

    100

    1

                closePopup()

    101

    2

            } else {

    102

    1

                openPopup()

    103

    2

            }

    104

    2

        }

    105

    106

    5

        func resizePopup(width: Double, height: Double) {

    107

    5

            guard let screen = NSScreen.currentScreenForMouseLocation()

    108

    5

                else { return }

    109

    5

            var frame = panel.frame

    110

    5

            var newSize = CGSize(width: width,

    111

    5

                                 height: height)

    112

    5

    113

    5

            newSize.height += contentInset * 2

    114

    5

            newSize.width += contentInset * 2

    115

    5

    116

    5

            frame.origin.y = (screen.frame.height - CGFloat(height))

    117

    5

    118

    5

            frame.size.height = newSize.height

    119

    5

    120

    5

            let widthDifference = newSize.width - frame.size.width

    121

    5

            if widthDifference != 0 {

    122

    5

                frame.size.width = newSize.width

    123

    5

            }

    124

    5

    125

    5

            currentWidth = width

    126

    5

            currentHeight = height

    127

    5

    128

    5

            containerView.resetConstraints()

    129

    5

            panel.setFrame(frame, display: true, animate: panel.isVisible)

    130

    5

        }

    131

    132

    1

        func proportionalResizePopup() {

    133

    1

            guard let screen = NSScreen.currentScreenForMouseLocation()

    134

    1

                else { return }

    135

    1

    136

    1

            var proportionalWidth = self.proportionalWidth

    137

    1

    138

    1

            if screen.frame.width < screen.frame.height {

    139

    0

                proportionalWidth += 0.25

    140

    1

            }

    141

    1

    142

    1

            let width = Double(screen.frame.width) * proportionalWidth

    143

    1

            let height = Double(screen.frame.height) * self.proportionalHeight

    144

    1

    145

    1

            currentWidth = width

    146

    1

            currentHeight = height

    147

    1

    148

    1

            resizePopup(width: width, height: height)

    149

    1

        }

    150

    151

    1

        func resizePopup(width: Double) {

    152

    1

            if width != currentWidth {

    153

    1

                resizePopup(

    154

    1

                    width: width,

    155

    1

                    height: Double(contentView.frame.size.height))

    156

    1

            }

    157

    1

        }

    158

    159

    1

        func resizePopup(height: Double) {

    160

    1

            if height != currentHeight {

    161

    1

                resizePopup(

    162

    1

                    width: Double(contentView.frame.size.width),

    163

    1

                    height: height)

    164

    1

            }

    165

    1

        }

    166

    167

    3

        private func openPanel() {

    168

    3

            self.isOpening = true

    169

    3

            willOpenPopup?()

    170

    3

            self.isOpen = true

    171

    3

            self.contentView.isHidden = false

    172

    3

            let panelRect = rect(forPanel: self.panel)

    173

    3

            self.panel.setFrame(panelRect, display: true)

    174

    3

    175

    3

            NSApp.activate(ignoringOtherApps: false)

    176

    3

    177

    3

            self.panel.makeKeyAndOrderFront(self)

    178

    3

            self.panel.alphaValue = 1

    179

    3

            self.isOpening = false

    180

    3

            if self.isOpen {

    181

    3

                self.didOpenPopup?()

    182

    3

                self.panel.makeKeyAndOrderFront(self)

    183

    3

            }

    184

    3

        }

    185

    186

    8

        private func closePanel() {

    187

    8

            willClosePopup?()

    188

    8

            self.isOpen = false

    189

    8

            self.contentView.isHidden = true

    190

    8

            self.panel.alphaValue = 0

    191

    8

            if !self.isOpen {

    192

    8

                self.panel.orderOut(nil)

    193

    8

                self.didClosePopup?()

    194

    8

            }

    195

    8

        }

    196

    197

    3

        private func rect(forPanel panel: NSPanel) -> CGRect {

    198

    3

            guard let screen = NSScreen.currentScreenForMouseLocation()

    199

    3

                else { return CGRect.zero }

    200

    3

    201

    3

            let screenRect = screen.frame

    202

    3

            var panelRect = panel.frame

    203

    3

    204

    3

            panelRect.origin.y = screenRect.maxY - panelRect.height

    205

    3

            panelRect.origin.x = round(screenRect.midX - panelRect.width / 2)

    206

    3

    207

    3

            if panelRect.maxX > screenRect.maxX {

    208

    3

                panelRect.origin.x -= panelRect.maxX - screenRect.maxX

    209

    3

            }

    210

    3

    211

    3

            if panelRect.minX < screenRect.minX {

    212

    3

                panelRect.origin.x -= screenRect.minX - panelRect.minX

    213

    3

            }

    214

    3

    215

    3

            if panelRect.maxY > screenRect.maxY {

    216

    0

                panelRect.origin.y -= panelRect.maxY - screenRect.maxY

    217

    3

            }

    218

    3

    219

    3

            if panelRect.minY < screenRect.minY {

    220

    3

                panelRect.origin.y -= screenRect.minY - panelRect.minY

    221

    3

            }

    222

    3

    223

    3

            var proportionalTopPadding = self.proportionalTopPadding

    224

    3

    225

    3

            if screenRect.width < screenRect.height {

    226

    0

                proportionalTopPadding -= 0.09

    227

    3

            }

    228

    3

    229

    3

            let padding = screenRect.height * proportionalTopPadding

    230

    3

    231

    3

            panelRect.origin.y -= padding

    232

    3

    233

    3

            return panelRect

    234

    3

        }

    235

    }