From 2ab34d99ead76d7c487b210116e51a79c75b4009 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 12 Aug 2017 10:53:13 -0700 Subject: [PATCH] [kit] WIP: Getting preference window to work Rudimentary loading of colors from user defaults --- Metaballs.xcodeproj/project.pbxproj | 4 + Metaballs/Base.lproj/Main.storyboard | 49 +++++++- MetaballsKit/PreferencesViewController.swift | 121 +++++++++++++++++++ 3 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 MetaballsKit/PreferencesViewController.swift diff --git a/Metaballs.xcodeproj/project.pbxproj b/Metaballs.xcodeproj/project.pbxproj index e8f8f45..1159916 100644 --- a/Metaballs.xcodeproj/project.pbxproj +++ b/Metaballs.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + C09161701F3F5AE6009C4263 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C091616F1F3F5AE6009C4263 /* PreferencesViewController.swift */; }; C0BBE36B1F2E816500E68524 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0BBE36A1F2E816500E68524 /* AppDelegate.swift */; }; C0BBE36D1F2E816500E68524 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0BBE36C1F2E816500E68524 /* ViewController.swift */; }; C0BBE36F1F2E816500E68524 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0BBE36E1F2E816500E68524 /* Assets.xcassets */; }; @@ -43,6 +44,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + C091616F1F3F5AE6009C4263 /* PreferencesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = ""; }; C0BBE3671F2E816500E68524 /* Metaballs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Metaballs.app; sourceTree = BUILT_PRODUCTS_DIR; }; C0BBE36A1F2E816500E68524 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; C0BBE36C1F2E816500E68524 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -156,6 +158,7 @@ C0BBE3A31F2E81C700E68524 /* Metaballs.swift */, C0CE7BFF1F362C3F001516B6 /* Geometry.swift */, C0DF1D781F3789DC0038B0A0 /* Memory.swift */, + C091616F1F3F5AE6009C4263 /* PreferencesViewController.swift */, ); path = MetaballsKit; sourceTree = ""; @@ -377,6 +380,7 @@ C0DF1D791F3789DC0038B0A0 /* Memory.swift in Sources */, C0BBE3A41F2E81C700E68524 /* Metaballs.swift in Sources */, C0CE7C001F362C3F001516B6 /* Geometry.swift in Sources */, + C09161701F3F5AE6009C4263 /* PreferencesViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Metaballs/Base.lproj/Main.storyboard b/Metaballs/Base.lproj/Main.storyboard index a991ff4..b006e01 100644 --- a/Metaballs/Base.lproj/Main.storyboard +++ b/Metaballs/Base.lproj/Main.storyboard @@ -1,7 +1,9 @@ - - + + - + + + @@ -21,7 +23,11 @@ - + + + + + @@ -653,10 +659,10 @@ - + - + @@ -676,6 +682,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MetaballsKit/PreferencesViewController.swift b/MetaballsKit/PreferencesViewController.swift new file mode 100644 index 0000000..56071e8 --- /dev/null +++ b/MetaballsKit/PreferencesViewController.swift @@ -0,0 +1,121 @@ +// +// PreferencesViewController.swift +// Metaballs +// +// Created by Eryn Wells on 8/12/17. +// Copyright © 2017 Eryn Wells. All rights reserved. +// + +import Cocoa + +class PreferencesViewController: NSViewController { + public var defaults = UserDefaults.standard + + private var colorStackView = NSStackView() + private var colorViews = [ColorView]() + + private lazy var styleMenu: NSPopUpButton = { + let button = NSPopUpButton() + button.translatesAutoresizingMaskIntoConstraints = false + + let menu = NSMenu() + menu.addItem(withTitle: NSLocalizedString("Single Color", comment: "single color menu item"), action: nil, keyEquivalent: "") + menu.addItem(withTitle: NSLocalizedString("Two Color Gradient — Horizontal", comment: "two color horizontal gradient menu item"), action: nil, keyEquivalent: "") + button.menu = menu + + return button + }() + + override func loadView() { + let view = NSView() + view.translatesAutoresizingMaskIntoConstraints = false + + colorStackView.setAccessibilityIdentifier("colorStackView") + colorStackView.translatesAutoresizingMaskIntoConstraints = false + colorStackView.orientation = .vertical + colorStackView.alignment = .left + colorStackView.distribution = .fillProportionally + colorStackView.spacing = 8 + view.addSubview(colorStackView) + + let centerX = colorStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor) + centerX.priority = 999 + let centerY = colorStackView.centerYAnchor.constraint(equalTo: view.centerYAnchor) + centerY.priority = 999 + NSLayoutConstraint.activate([ + centerX, centerY, + colorStackView.topAnchor.constraint(greaterThanOrEqualTo: view.topAnchor, constant: 8), + colorStackView.leftAnchor.constraint(greaterThanOrEqualTo: view.leftAnchor, constant: 8), + colorStackView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -8), + colorStackView.rightAnchor.constraint(lessThanOrEqualTo: view.rightAnchor, constant: -8), + ]) + + colorStackView.addArrangedSubview(styleMenu) + for i in 0..<4 { + let colorView = ColorView() + colorView.translatesAutoresizingMaskIntoConstraints = false + colorView.label.stringValue = "Color \(i+1)" + colorStackView.addArrangedSubview(colorView) + colorViews.append(colorView) + } + + self.view = view + } + + + override func viewWillAppear() { + super.viewWillAppear() + prepareColorViews() + } + + private func prepareColorViews() { + guard let colors = defaults.array(forKey: "colors") else { return } + for (idx, cv) in colorViews.enumerated() { + if idx >= colors.count { + continue + } + if let color = colors[idx] as? NSColor { + cv.colorWell.color = color + } + } + } +} + +class ColorView: NSView { + private let stackView = NSStackView() + internal let colorWell = NSColorWell() + internal let label = NSTextField(labelWithString: "Hello") + + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + commonInit() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + commonInit() + } + + private func commonInit() { + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.orientation = .horizontal + stackView.spacing = 8 + stackView.alignment = .centerY + stackView.distribution = .equalSpacing + + colorWell.translatesAutoresizingMaskIntoConstraints = false + colorWell.setContentHuggingPriority(251, for: .horizontal) + stackView.addArrangedSubview(colorWell) + + label.translatesAutoresizingMaskIntoConstraints = false + stackView.addArrangedSubview(label) + + addSubview(stackView) + NSLayoutConstraint.activate([ + stackView.topAnchor.constraint(equalTo: topAnchor), + stackView.leftAnchor.constraint(equalTo: leftAnchor), + stackView.bottomAnchor.constraint(equalTo: bottomAnchor), + stackView.rightAnchor.constraint(equalTo: rightAnchor), + ]) + } +}