forked from kornelski/ImageAlpha
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathIAPreferencesController.py
More file actions
193 lines (154 loc) · 6.96 KB
/
IAPreferencesController.py
File metadata and controls
193 lines (154 loc) · 6.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#
# IAPreferencesController.py
#
import objc
from objc import *
from Foundation import *
from AppKit import *
# Toolbar item identifiers
TOOLBAR_GENERAL = "GeneralToolbarItem"
TOOLBAR_OXIPNG = "OxipngToolbarItem"
TOOLBAR_ZOPFLIPNG = "ZopflipngToolbarItem"
class IAPreferencesController(NSWindowController):
_sharedInstance = None
# IBOutlets for the three tab views
generalView = objc.IBOutlet()
oxipngView = objc.IBOutlet()
zopflipngView = objc.IBOutlet()
# IBOutlets for dither radio buttons
ditherDefaultButton = objc.IBOutlet()
ditherOnButton = objc.IBOutlet()
ditherOffButton = objc.IBOutlet()
_currentView = None
_toolbar = None
@classmethod
def sharedInstance(cls):
if cls._sharedInstance is None:
cls._sharedInstance = cls.alloc().initWithWindowNibName_("Preferences")
return cls._sharedInstance
def windowDidLoad(self):
super(IAPreferencesController, self).windowDidLoad()
self._setupToolbar()
# Select General tab by default
self._switchToView_(self.generalView, TOOLBAR_GENERAL)
# Initialize dither radio button states
self._updateDitherRadioButtons()
@objc.python_method
def _setupToolbar(self):
toolbar = NSToolbar.alloc().initWithIdentifier_("PreferencesToolbar")
toolbar.setDelegate_(self)
toolbar.setAllowsUserCustomization_(False)
toolbar.setDisplayMode_(NSToolbarDisplayModeIconAndLabel)
toolbar.setSelectedItemIdentifier_(TOOLBAR_GENERAL)
toolbar.setCenteredItemIdentifiers_(NSSet.setWithArray_([TOOLBAR_GENERAL, TOOLBAR_OXIPNG, TOOLBAR_ZOPFLIPNG]))
self.window().setToolbar_(toolbar)
# Use modern preferences window style (title shows tab name, centered toolbar)
self.window().setToolbarStyle_(2) # NSWindowToolbarStylePreference
self._toolbar = toolbar
# NSToolbar delegate methods
def toolbarAllowedItemIdentifiers_(self, toolbar):
return [TOOLBAR_GENERAL, TOOLBAR_OXIPNG, TOOLBAR_ZOPFLIPNG]
def toolbarDefaultItemIdentifiers_(self, toolbar):
return [TOOLBAR_GENERAL, TOOLBAR_OXIPNG, TOOLBAR_ZOPFLIPNG]
def toolbarSelectableItemIdentifiers_(self, toolbar):
return [TOOLBAR_GENERAL, TOOLBAR_OXIPNG, TOOLBAR_ZOPFLIPNG]
def toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_(self, toolbar, identifier, flag):
item = NSToolbarItem.alloc().initWithItemIdentifier_(identifier)
if identifier == TOOLBAR_GENERAL:
item.setLabel_("General")
# Use SF Symbol gear icon
gearImage = NSImage.imageWithSystemSymbolName_accessibilityDescription_("gearshape", "General")
item.setImage_(gearImage)
item.setTarget_(self)
item.setAction_(self.switchToGeneralTab_)
elif identifier == TOOLBAR_OXIPNG:
item.setLabel_("oxipng")
# Use SF Symbol compression icon
compressImage = NSImage.imageWithSystemSymbolName_accessibilityDescription_("arrow.down.right.and.arrow.up.left", "Compression")
item.setImage_(compressImage)
item.setTarget_(self)
item.setAction_(self.switchToOxipngTab_)
elif identifier == TOOLBAR_ZOPFLIPNG:
item.setLabel_("zopflipng")
# Use SF Symbol compression icon
compressImage = NSImage.imageWithSystemSymbolName_accessibilityDescription_("arrow.down.right.and.arrow.up.left", "Compression")
item.setImage_(compressImage)
item.setTarget_(self)
item.setAction_(self.switchToZopflipngTab_)
return item
@objc.IBAction
def setDitherDefault_(self, sender):
NSUserDefaults.standardUserDefaults().removeObjectForKey_("dithered")
self._updateDitherRadioButtons()
@objc.IBAction
def setDitherOn_(self, sender):
NSUserDefaults.standardUserDefaults().setBool_forKey_(True, "dithered")
self._updateDitherRadioButtons()
@objc.IBAction
def setDitherOff_(self, sender):
NSUserDefaults.standardUserDefaults().setBool_forKey_(False, "dithered")
self._updateDitherRadioButtons()
@objc.python_method
def _updateDitherRadioButtons(self):
"""Update radio button states based on current dithered preference."""
if self.ditherDefaultButton is None:
return
defaults = NSUserDefaults.standardUserDefaults()
stored = defaults.objectForKey_("dithered")
# Determine which button should be selected
# stored is None = default, True = on, False = off
if stored is None:
tag = -1 # default
elif hasattr(stored, "boolValue"):
tag = 1 if stored.boolValue() else 0
else:
tag = 1 if stored else 0
self.ditherDefaultButton.setState_(NSControlStateValueOn if tag == -1 else NSControlStateValueOff)
self.ditherOnButton.setState_(NSControlStateValueOn if tag == 1 else NSControlStateValueOff)
self.ditherOffButton.setState_(NSControlStateValueOn if tag == 0 else NSControlStateValueOff)
@objc.IBAction
def switchToGeneralTab_(self, sender):
self._switchToView_(self.generalView, TOOLBAR_GENERAL)
@objc.IBAction
def switchToOxipngTab_(self, sender):
self._switchToView_(self.oxipngView, TOOLBAR_OXIPNG)
@objc.IBAction
def switchToZopflipngTab_(self, sender):
self._switchToView_(self.zopflipngView, TOOLBAR_ZOPFLIPNG)
@objc.python_method
def _switchToView_(self, newView, identifier):
if newView is None:
return
window = self.window()
# Calculate new window frame
newFrame = window.frameRectForContentRect_(newView.frame())
currentFrame = window.frame()
# Keep top-left corner fixed
newFrame.origin.x = currentFrame.origin.x
newFrame.origin.y = currentFrame.origin.y + currentFrame.size.height - newFrame.size.height
# Remove current view if any
if self._currentView is not None:
self._currentView.removeFromSuperview()
# Resize window and add new view
window.setFrame_display_animate_(newFrame, True, True)
window.contentView().addSubview_(newView)
newView.setFrameOrigin_(NSMakePoint(0, 0))
self._currentView = newView
# Update toolbar selection
if self._toolbar is not None:
self._toolbar.setSelectedItemIdentifier_(identifier)
# Update window title to show current tab name
tabNames = {
TOOLBAR_GENERAL: "General",
TOOLBAR_OXIPNG: "oxipng",
TOOLBAR_ZOPFLIPNG: "zopflipng"
}
window.setTitle_(tabNames.get(identifier, "Preferences"))
# Action that can be called from First Responder
@objc.IBAction
def openPreferences_(self, sender):
controller = IAPreferencesController.sharedInstance()
controller.showWindow_(sender)
controller.window().makeKeyAndOrderFront_(sender)
# Add the action to NSApplication
NSApplication.openPreferences_ = openPreferences_