Create Software Update preference pane with code (using NSGridView)

This commit is contained in:
Allan Odgaard
2020-04-19 12:01:31 +07:00
parent b938dce914
commit 9e7d727792
3 changed files with 65 additions and 189 deletions

View File

@@ -1,185 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="101200" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="SoftwareUpdatePreferences">
<connections>
<outlet property="view" destination="1" id="2"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="1">
<rect key="frame" x="0.0" y="0.0" width="480" height="201"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button id="5">
<rect key="frame" x="171" y="163" width="87" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Watch for:" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="6">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="-2" name="value" keyPath="disableSoftwareUpdates" id="59">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</button>
<button id="43">
<rect key="frame" x="171" y="138" width="230" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Ask before downloading updates" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="44">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="-2" name="value" keyPath="askBeforeDownloading" id="61"/>
</connections>
</button>
<textField verticalHuggingPriority="750" id="15">
<rect key="frame" x="72" y="44" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Crash Reports:" id="16">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button id="9">
<rect key="frame" x="171" y="43" width="162" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Submit to MacroMates" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="10">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="-2" name="value" keyPath="disableCrashReports" id="65">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</button>
<textField verticalHuggingPriority="750" id="19">
<rect key="frame" x="252" y="20" width="152" height="19"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="20">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="contactInfo" id="66"/>
<binding destination="-2" name="enabled" keyPath="disableCrashReports" id="72">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</textField>
<textField verticalHuggingPriority="750" id="25">
<rect key="frame" x="190" y="22" width="57" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Contact:" id="26">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" id="37">
<rect key="frame" x="259" y="159" width="148" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Normal Releases" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="40" id="38">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
<menu key="menu" title="OtherViews" id="39">
<items>
<menuItem title="Normal Releases" state="on" id="40"/>
<menuItem title="Nightly Builds" tag="1" id="41"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<binding destination="-2" name="enabled" keyPath="disableSoftwareUpdates" id="70">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="selectedTag" keyPath="softwareUpdateChannel" id="68">
<dictionary key="options">
<string key="NSValueTransformerName">OakSoftwareUpdateChannelTransformer</string>
</dictionary>
</binding>
</connections>
</popUpButton>
<textField verticalHuggingPriority="750" id="47">
<rect key="frame" x="56" y="164" width="112" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Software Update:" id="48">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="49">
<rect key="frame" x="91" y="106" width="77" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Last Check:" id="50">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" id="52">
<rect key="frame" x="167" y="70" width="111" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Check Now" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="53">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="performSoftwareUpdateCheck:" target="-1" id="YEG-1P-UwS"/>
<binding destination="-2" name="enabled" keyPath="isChecking" id="77">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</button>
<textField verticalHuggingPriority="750" id="54">
<rect key="frame" x="170" y="106" width="301" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Some time ago…" id="55">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="lastCheck" id="74"/>
</connections>
</textField>
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="56">
<rect key="frame" x="12" y="129" width="456" height="5"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="57">
<rect key="frame" x="12" y="67" width="456" height="5"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
</subviews>
<point key="canvasLocation" x="581" y="432.5"/>
</customView>
</objects>
</document>

View File

@@ -1,6 +1,4 @@
#import "PreferencesPane.h"
@interface SoftwareUpdatePreferences : PreferencesPane
@property (nonatomic, readonly) NSString* lastCheck;
@property (nonatomic, readonly, getter = isChecking) BOOL checking;
@end

View File

@@ -2,14 +2,17 @@
#import "Keys.h"
#import <BundlesManager/BundlesManager.h>
#import <OakAppKit/NSImage Additions.h>
#import <OakAppKit/OakUIConstructionFunctions.h>
#import <OakFoundation/NSDate Additions.h>
#import <OakFoundation/OakStringListTransformer.h>
#import <SoftwareUpdate/SoftwareUpdate.h>
#import <MenuBuilder/MenuBuilder.h>
// kUserDefaultsLastSoftwareUpdateCheckKey
@interface SoftwareUpdatePreferences ()
@property (nonatomic, readwrite, getter = isChecking) BOOL checking;
@property (nonatomic, readonly) NSString* lastCheck;
@property (nonatomic, getter = isChecking) BOOL checking;
@property (nonatomic) NSDate* lastPoll;
@property (nonatomic) NSString* errorString;
@@ -22,7 +25,7 @@
- (id)init
{
if(self = [super initWithNibName:@"SoftwareUpdatePreferences" label:@"Software Update" image:[NSImage imageNamed:@"Software Update" inSameBundleAsClass:[self class]]])
if(self = [super initWithNibName:nil label:@"Software Update" image:[NSImage imageNamed:@"Software Update" inSameBundleAsClass:[self class]]])
{
[OakStringListTransformer createTransformerWithName:@"OakSoftwareUpdateChannelTransformer" andObjectsArray:@[ kSoftwareUpdateChannelRelease, kSoftwareUpdateChannelPrerelease ]];
[self bind:@"checking" toObject:[SoftwareUpdate sharedInstance] withKeyPath:@"checking" options:nil];
@@ -68,4 +71,64 @@
[self.updateLastPollStringTimer invalidate];
self.updateLastPollStringTimer = nil;
}
- (void)loadView
{
NSButton* watchForUpdatesCheckBox = OakCreateCheckBox(@"Watch for:");
NSPopUpButton* updateChannelPopUp = OakCreatePopUpButton();
NSButton* askBeforeDownloadingCheckBox = OakCreateCheckBox(@"Ask before downloading updates");
NSStackView* watchForStackView = [NSStackView stackViewWithViews:@[ watchForUpdatesCheckBox, updateChannelPopUp ]];
watchForStackView.alignment = NSLayoutAttributeFirstBaseline;
NSTextField* lastCheckTextField = OakCreateLabel(@"Some time ago");
NSButton* checkNowButton = [NSButton buttonWithTitle:@"Check Now" target:nil action:@selector(performSoftwareUpdateCheck:)];
NSButton* submitCrashReportsCheckBox = OakCreateCheckBox(@"Submit to MacroMates");
NSTextField* contactTextField = [NSTextField textFieldWithString:@"Anonymous"];
NSFont* smallFont = [NSFont messageFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeSmall]];
contactTextField.font = smallFont;
contactTextField.controlSize = NSControlSizeSmall;
NSStackView* contactStackView = [NSStackView stackViewWithViews:@[
OakCreateLabel(@"Contact:", smallFont), contactTextField
]];
contactStackView.alignment = NSLayoutAttributeFirstBaseline;
contactStackView.edgeInsets = { .left = 18 };
MBMenu const updateChannelMenuItems = {
{ @"Normal Releases", .tag = 0 },
{ @"Nightly Builds", .tag = 1 },
};
MBCreateMenu(updateChannelMenuItems, updateChannelPopUp.menu);
NSGridView* gridView = [NSGridView gridViewWithViews:@[
@[ OakCreateLabel(@"Software update:"), watchForStackView ],
@[ NSGridCell.emptyContentView, askBeforeDownloadingCheckBox ],
@[ ],
@[ OakCreateLabel(@"Last check:"), lastCheckTextField ],
@[ NSGridCell.emptyContentView, checkNowButton ],
@[ ],
@[ OakCreateLabel(@"Crash reports:"), submitCrashReportsCheckBox ],
@[ NSGridCell.emptyContentView, contactStackView ],
]];
[contactTextField.trailingAnchor constraintEqualToAnchor:updateChannelPopUp.trailingAnchor].active = YES;
self.view = OakSetupGridViewWithSeparators(gridView, { 2, 5 });
[watchForUpdatesCheckBox bind:NSValueBinding toObject:self withKeyPath:@"disableSoftwareUpdates" options:@{ NSValueTransformerNameBindingOption: NSNegateBooleanTransformerName }];
[updateChannelPopUp bind:NSSelectedTagBinding toObject:self withKeyPath:@"softwareUpdateChannel" options:@{ NSValueTransformerNameBindingOption: @"OakSoftwareUpdateChannelTransformer" }];
[askBeforeDownloadingCheckBox bind:NSValueBinding toObject:self withKeyPath:@"askBeforeDownloading" options:nil];
[lastCheckTextField bind:NSValueBinding toObject:self withKeyPath:@"lastCheck" options:nil];
[submitCrashReportsCheckBox bind:NSValueBinding toObject:self withKeyPath:@"disableCrashReports" options:@{ NSValueTransformerNameBindingOption: NSNegateBooleanTransformerName }];
[contactTextField bind:NSValueBinding toObject:self withKeyPath:@"contactInfo" options:nil];
[updateChannelPopUp bind:NSEnabledBinding toObject:self withKeyPath:@"disableSoftwareUpdates" options:@{ NSValueTransformerNameBindingOption: NSNegateBooleanTransformerName }];
[askBeforeDownloadingCheckBox bind:NSEnabledBinding toObject:self withKeyPath:@"disableSoftwareUpdates" options:@{ NSValueTransformerNameBindingOption: NSNegateBooleanTransformerName }];
[checkNowButton bind:NSEnabledBinding toObject:self withKeyPath:@"checking" options:@{ NSValueTransformerNameBindingOption: NSNegateBooleanTransformerName }];
[contactTextField bind:NSEnabledBinding toObject:self withKeyPath:@"disableCrashReports" options:@{ NSValueTransformerNameBindingOption: NSNegateBooleanTransformerName }];
}
@end