source: launchers/macosx/I2PLauncher/userinterface/preferences/PreferencesViewController.swift @ 68ad4eec

Last change on this file since 68ad4eec was 68ad4eec, checked in by meeh <meeh@…>, 2 years ago

Mac OS X Launcher: Adding user interface classes for the different Preferences views so far.

  • Property mode set to 100644
File size: 7.3 KB
Line 
1//
2//  PreferencesViewController.swift
3//  I2PLauncher
4//
5//  Created by Mikal Villa on 07/11/2018.
6//  Copyright © 2018 The I2P Project. All rights reserved.
7//
8// Table view programming guide from Apple:
9// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TableView/Introduction/Introduction.html
10//
11
12import Cocoa
13
14
15class PreferencesViewController: NSViewController {
16 
17  enum ShowAsMode {
18    case bothIcon
19    case menubarIcon
20    case dockIcon
21  }
22 
23  var changeDockMenubarIconTimer: Timer?
24 
25  // MARK: - Advanced settings objects
26  @IBOutlet weak var advPrefTableView: NSTableView!
27 
28  // MARK: - Launcher settings objects
29  @IBOutlet var radioDockIcon: NSButton?
30  @IBOutlet var radioMenubarIcon: NSButton?
31  @IBOutlet var radioBothIcon: NSButton?
32  @IBOutlet var checkboxStartWithOSX: NSButton?
33  @IBOutlet var checkboxStartFirefoxAlso: NSButton?
34 
35  // MARK: - Router objects
36  @IBOutlet var checkboxStartWithLauncher: NSButton?
37  @IBOutlet var checkboxStopWithLauncher: NSButton?
38  @IBOutlet var buttonResetRouterConfig: NSButton?
39 
40 
41  override func viewDidLoad() {
42    super.viewDidLoad()
43   
44    self.preferredContentSize = NSMakeSize(self.view.frame.size.width, self.view.frame.size.height)
45   
46    if (advPrefTableView != nil) {
47      // For data feeding and view
48      advPrefTableView.delegate = self
49      advPrefTableView.dataSource = self
50     
51      // Responding to Double-Click
52      advPrefTableView.target = self
53      advPrefTableView.doubleAction = #selector(tableViewDoubleClick(_:))
54     
55      // Always redraw preference items which might have changed state since last draw.
56      Preferences.shared().redrawPrefTableItems()
57     
58      // For sorting
59      advPrefTableView.tableColumns[0].sortDescriptorPrototype = NSSortDescriptor(key: "name", ascending: true)
60      advPrefTableView.tableColumns[1].sortDescriptorPrototype = NSSortDescriptor(key: "defaultValue", ascending: true)
61      advPrefTableView.tableColumns[2].sortDescriptorPrototype = NSSortDescriptor(key: "selectedValue", ascending: true)
62    }
63   
64    // Update radio buttons to reflect runtime/stored preferences
65    self.updateRadioButtonEffect(mode: Preferences.shared().showAsIconMode, withSideEffect: false)
66   
67  }
68 
69  override func viewDidAppear() {
70    super.viewDidAppear()
71   
72    // Update window title
73    self.parent?.view.window?.title = self.title!
74  }
75 
76  // MARK: - Router settings functions
77 
78  @IBAction func checkboxStartRouterWithLauncherClicked(_ sender: NSButton) {
79    switch sender.state {
80    case NSOnState:
81      print("on")
82      Preferences.shared().startRouterOnLauncherStart = true
83    case NSOffState:
84      print("off")
85      Preferences.shared().startRouterOnLauncherStart = false
86    case NSMixedState:
87      print("mixed")
88    default: break
89    }
90  }
91 
92  @IBAction func checkboxStopRouterWithLauncherClicked(_ sender: NSButton) {
93    switch sender.state {
94    case NSOnState:
95      print("on")
96      Preferences.shared().stopRouterOnLauncherShutdown = true
97    case NSOffState:
98      print("off")
99      Preferences.shared().stopRouterOnLauncherShutdown = false
100    case NSMixedState:
101      print("mixed")
102    default: break
103    }
104  }
105 
106  @IBAction func buttonResetRouterConfigClicked(_ sender: Any) {
107    // TODO: Add a modal dialog asking user if they are **really** sure
108  }
109 
110  // MARK: - Launcher settings functions
111 
112  @IBAction func checkboxStartLauncherOnOSXStartupClicked(_ sender: NSButton) {
113    switch sender.state {
114    case NSOnState:
115      print("on")
116    case NSOffState:
117      print("off")
118    case NSMixedState:
119      print("mixed")
120    default: break
121    }
122  }
123  @IBAction func checkboxStartFirefoxAlsoAtLaunchClicked(_ sender: NSButton) {
124    switch sender.state {
125    case NSOnState:
126      print("on")
127    case NSOffState:
128      print("off")
129    case NSMixedState:
130      print("mixed")
131    default: break
132    }
133  }
134 
135  // MARK: - Radio buttons functions
136 
137  func updateDockMenubarIcons(_ mode: ShowAsMode) -> Bool {
138    // Update preferences with latest choise
139    Preferences.shared().showAsIconMode = mode
140    // Update runtime
141    switch mode {
142    case .bothIcon, .dockIcon:
143      // Show dock icon
144      print("Preferences: Update Dock Icon -> Show")
145      if (!getDockIconStateIsShowing()) {
146        return triggerDockIconShowHide(showIcon: true)
147      }
148    case .menubarIcon:
149      // Hide dock icon
150      print("Preferences: Update Dock Icon -> Hide")
151      if (getDockIconStateIsShowing()) {
152        return triggerDockIconShowHide(showIcon: false)
153      }
154    }
155    // Note: In reality, this won't ever happen.
156    // The switch statement above would return before this.
157    return false
158  }
159 
160  func updateRadioButtonEffect(mode: ShowAsMode, withSideEffect: Bool = true) {
161    changeDockMenubarIconTimer?.invalidate()
162   
163    radioDockIcon?.state = NSOffState
164    radioMenubarIcon?.state = NSOffState
165    radioBothIcon?.state = NSOffState
166   
167    switch mode {
168    case .bothIcon:
169      radioBothIcon?.state = NSOnState
170    case .dockIcon:
171      radioDockIcon?.state = NSOnState
172    case .menubarIcon:
173      radioMenubarIcon?.state = NSOnState
174    }
175   
176    if (withSideEffect) {
177      if #available(OSX 10.12, *) {
178        changeDockMenubarIconTimer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { _ in
179          // If we're on 10.12 or later
180          self.updateDockMenubarIcons(mode)
181        })
182      } else {
183        // Fallback on earlier versions
184        self.updateDockMenubarIcons(mode)
185      }
186    }
187  }
188 
189  @IBAction func radioBothIconSelected(_ sender: Any) {
190    updateRadioButtonEffect(mode: ShowAsMode.bothIcon)
191  }
192 
193  @IBAction func radioDockIconOnlySelected(_ sender: Any) {
194    updateRadioButtonEffect(mode: ShowAsMode.dockIcon)
195  }
196 
197  @IBAction func radioMenubarOnlySelected(_ sender: Any) {
198    updateRadioButtonEffect(mode: ShowAsMode.menubarIcon)
199  }
200 
201  // MARK: - Triggers
202 
203  func triggerDockIconHideShow(showIcon state: Bool) -> Bool {
204    // Get transform state.
205    var transformState: ProcessApplicationTransformState
206    if state {
207      transformState = ProcessApplicationTransformState(kProcessTransformToForegroundApplication)
208    } else {
209      transformState = ProcessApplicationTransformState(kProcessTransformToUIElementApplication)
210    }
211   
212    // Show / hide dock icon.
213    var psn = ProcessSerialNumber(highLongOfPSN: 0, lowLongOfPSN: UInt32(kCurrentProcess))
214    let transformStatus: OSStatus = TransformProcessType(&psn, transformState)
215    return transformStatus == 0
216  }
217 
218  func triggerDockIconShowHide(showIcon state: Bool) -> Bool {
219    var result: Bool
220    if state {
221      result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.regular)
222    } else {
223      result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.accessory)
224    }
225    return result
226  }
227 
228  func getDockIconStateIsShowing() -> Bool {
229    if NSApp.activationPolicy() == NSApplicationActivationPolicy.regular {
230      return true
231    } else {
232      return false
233    }
234  }
235 
236 
237  // MARK: - Advanced
238 
239  @IBAction func checkboxEnableAdvancedPreferencesClicked(_ sender: NSButton) {
240    switch sender.state {
241    case NSOnState:
242      print("on")
243      Preferences.shared().allowAdvancedPreferenceEdit = true
244    case NSOffState:
245      print("off")
246      Preferences.shared().allowAdvancedPreferenceEdit = false
247    case NSMixedState:
248      print("mixed")
249    default: break
250    }
251  }
252
253 
254  // End of Class
255}
256
257
Note: See TracBrowser for help on using the repository browser.