├── Capture1.jpg
├── Capture1.png
├── LICENSE
├── MARKDOWN_REFERENCE.md
├── README.md
├── SideBarDemo.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcuserdata
│ └── thierryh24.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── SideBarDemo.xcscheme
│ └── xcschememanagement.plist
├── SideBarDemo
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── Department-50.imageset
│ │ ├── Contents.json
│ │ └── Department-50.png
│ ├── DownArrow.imageset
│ │ ├── Contents.json
│ │ ├── down-arrow-light-1.png
│ │ ├── down-arrow-light.png
│ │ ├── down-arrow-light@2x-1.png
│ │ ├── down-arrow-light@2x.png
│ │ ├── down-arrow.png
│ │ └── down-arrow@2x.png
│ ├── Human_resource.imageset
│ │ ├── Contents.json
│ │ └── Human_resource_icons-09-512.png
│ ├── RightArrow.imageset
│ │ ├── Contents.json
│ │ ├── right-arrow-light-1.png
│ │ ├── right-arrow-light.png
│ │ ├── right-arrow-light@2x-1.png
│ │ ├── right-arrow-light@2x.png
│ │ ├── right-arrow.png
│ │ └── right-arrow@2x.png
│ ├── account.imageset
│ │ ├── Contents.json
│ │ └── account.png
│ ├── application-sidebar-list.imageset
│ │ ├── Contents.json
│ │ └── application-sidebar-list.png
│ ├── clock.imageset
│ │ ├── Contents.json
│ │ └── clock.png
│ ├── employee.imageset
│ │ ├── Contents.json
│ │ └── employee.png
│ ├── film.imageset
│ │ ├── Contents.json
│ │ └── film.png
│ └── smiley.imageset
│ │ ├── Contents.json
│ │ └── smiley.png
├── Base.lproj
│ └── MainMenu.xib
├── Info.plist
├── MainWindowController.swift
├── MainWindowController.xib
├── Resource
│ ├── abundance-church-family.jpg
│ ├── hand-tuning-peg-instrument.jpg
│ ├── mobile-phone-and-headphones-on-white-wooden-table.jpg
│ ├── rayban-ray-bans-spectacles.jpg
│ ├── record-vinyl-turntable.jpg
│ ├── vintage-radio-on-glass-table.jpg
│ └── woman-writing-in-music-sheet.jpg
├── SideBarDemo.entitlements
└── View
│ ├── CommunController.swift
│ ├── ContentView1Controller.swift
│ ├── ContentView1Controller.xib
│ ├── ContentView2Controller.swift
│ ├── ContentView2Controller.xib
│ ├── ContentView3Controller.swift
│ ├── ContentView3Controller.xib
│ ├── ContentView4Controller.swift
│ ├── ContentView4Controller.xib
│ ├── ContentView5Controller.swift
│ ├── ContentView5Controller.xib
│ ├── ContentView6Controller.swift
│ ├── ContentView6Controller.xib
│ ├── ContentView7Controller.swift
│ └── ContentView7Controller.xib
├── SideBarDemoTests
├── Info.plist
└── SideBarDemoTests.swift
├── SideBarDemoUITests
├── Info.plist
└── SideBarDemoUITests.swift
└── THSideBar
├── THSideBarCellView.swift
├── THSideBarData.swift
├── THSideBarDataSource.swift
├── THSideBarDelegate.swift
├── THSideBarDragDrop.swift
├── THSideBarViewController.swift
├── THSideBarViewController.xib
└── THTextFieldDelegate.swift
/Capture1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/Capture1.jpg
--------------------------------------------------------------------------------
/Capture1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/Capture1.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/MARKDOWN_REFERENCE.md:
--------------------------------------------------------------------------------
1 | ### Headers
2 |
3 | ```markdown
4 | # H1
5 | ## H2
6 | ### H3
7 | #### H4
8 | ##### H5
9 | ###### H6
10 | ```
11 |
12 | ### Text
13 |
14 | ```markdown
15 | _italic_ or *italic*
16 |
17 | **bold** or __bold__
18 |
19 | ~~strikethrough~~
20 | ```
21 |
22 | ### Blockquotes
23 |
24 | ```markdown
25 | > This is a blockquote
26 | ```
27 |
28 | ### Horizontal Rule
29 |
30 | ```markdown
31 | ---
32 |
33 | ***
34 |
35 | ___
36 | ```
37 |
38 | ### Lists
39 |
40 | ```markdown
41 | 1. Ordered list
42 | 2. ...
43 |
44 | - Unordered list
45 | * With *
46 | + With +
47 | ```
48 |
49 | ### Links
50 |
51 | ```markdown
52 | [Inine](https://a.com)
53 |
54 | [Inline with title](https://a.com "A title")
55 |
56 | [Reference][1]
57 |
58 | [Link to file](./Docs/SETUP.md)
59 |
60 | [1]: https://a.com
61 | ```
62 |
63 | ### Images
64 |
65 | ```markdown
66 | 
67 |
68 | ![Reference][logo]
69 |
70 | [logo]: https://a.com/logo.png
71 | ```
72 |
73 | ### Code
74 |
75 | ````markdown
76 | `Inline code`
77 |
78 | ```javascript
79 | const x = 5;
80 | const plusTwo = a => a + 2;
81 | ```
82 | ````
83 |
84 | ### Tables
85 |
86 | ```markdown
87 | | Column 1 | Column 2 | Column 3 |
88 | | ------------- |:-------------:| ---------:|
89 | | Col 3 is | right-aligned | $1600 |
90 | | Col 2 is | centered | $12 |
91 | | Tables | are neat | $1 |
92 | ```
93 |
94 | ### HTML
95 |
96 | ```markdown
97 | Link
98 |
99 | ```
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | # SideBarDemo
7 | NSOutlineView and badge
8 |
9 | 
10 |
11 |
12 | # THSideBar
13 |
14 |
15 | THSideBar framework written in Swift for OS X
16 |
17 |
18 |
19 |
20 | [](https://starchart.cc/thierryH91200/THSideBar)
21 |
22 |
23 | # Usage
24 |
25 | ### look at example
26 |
27 | ## Initialize the THSideBar
28 |
29 | ```
30 | var sideBarViewController : THSideBarViewController?
31 |
32 |
33 |
34 | ```
35 |
36 |
37 | ## Add THSideBar to the view hierarchy
38 |
39 | ```
40 | self.sideBarViewController = THSideBarViewController()
41 | addSubview(subView: (sideBarViewController?.view)!, toView: sourceView)
42 |
43 | sideBarViewController?.delegate = self
44 | sideBarViewController?.allowDragAndDrop = false/true
45 | sideBarViewController?.saveSection = false/true
46 | setUpLayoutConstraints(item: sideBarViewController!.view, toItem: sourceView)
47 | self.sideBarViewController!.view.setFrameSize( NSMakeSize(100, 200))
48 | ```
49 |
50 | ## Init data
51 |
52 | ```
53 | let item1 = Account(name:"ContentView1", icon:NSImage (named: NSImage.Name(rawValue: "Human_resource"))!, nameView: "ContentView1Controller", badge: "10", colorBadge: .blue)
54 | let item2 = Account(name:"ContentView2", icon:NSImage (named: NSImage.Name(rawValue: "Human_resource"))!, nameView: "ContentView2Controller", badge: "-5", colorBadge: .red)
55 | let item3 = Account(name:"ContentView3", icon:NSImage (named: NSImage.Name(rawValue: "employee"))!, nameView: "ContentView3Controller", badge: "3", colorBadge: .blue)
56 | let item4 = Account(name:"ContentView4", icon:NSImage (named: NSImage.Name(rawValue: "employee"))!, nameView: "ContentView4Controller", badge: "1", colorBadge: .blue)
57 |
58 | account1.accounts.append(item1)
59 | account1.accounts.append(item2)
60 | account2.accounts.append(item3)
61 | account2.accounts.append(item4)
62 |
63 | allSection.sections.removeAll()
64 | allSection.sections.append(account1)
65 | allSection.sections.append(account2)
66 | allSection.dump()
67 | sideBarViewController?.initData( allSection: allSection )
68 |
69 | ```
70 |
71 | ## create all the viewController
72 |
73 |
74 | ```
75 | extension MainWindowController: THSideBarViewDelegate
76 | {
77 | func changeView(item : Item)
78 | {
79 | var vc = NSView()
80 |
81 | if item.nameView == "City" {
82 |
83 | nameCity = item.name
84 | NotificationCenter.send(.updateView)
85 | return
86 | }
87 |
88 | switch item.nameView
89 | {
90 | case "ContentView1Controller":
91 | vc = contentView1Controller.view
92 |
93 | case "ContentView2Controller":
94 | vc = contentView2Controller.view
95 |
96 | case "ContentView3Controller":
97 | vc = contentView3Controller.view
98 |
99 | case "ContentView4Controller":
100 | vc = contentView4Controller.view
101 |
102 | case "ContentView5Controller":
103 | vc = contentView5Controller.view
104 |
105 | case "ContentView6Controller":
106 | vc = contentView6Controller.view
107 |
108 | case "ContentView7Controller":
109 | vc = contentView7Controller.view
110 |
111 | default:
112 | vc = contentView1Controller.view
113 | }
114 |
115 | addSubview(subView: vc, toView: tableTargetView)
116 | vc.translatesAutoresizingMaskIntoConstraints = false
117 |
118 | var viewBindingsDict = [String: AnyObject]()
119 | viewBindingsDict["vc"] = vc
120 | tableTargetView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[vc]|", options: [], metrics: nil, views: viewBindingsDict))
121 | tableTargetView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[vc]|", options: [], metrics: nil, views: viewBindingsDict))
122 | }
123 |
124 | ```
125 |
126 | ## Custom NSOutlineView
127 |
128 | var isSaveSection = true // Ideal for dynamic sections
129 | var colorBackGround = NSColor.blue
130 | var rowSizeStyle = NSTableView.RowSizeStyle.small
131 | var allowDragAndDrop = true
132 |
133 |
--------------------------------------------------------------------------------
/SideBarDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0305FAC41F80AE3900D9B979 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0305FAC31F80AE3900D9B979 /* AppDelegate.swift */; };
11 | 0305FAC61F80AE3900D9B979 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0305FAC51F80AE3900D9B979 /* Assets.xcassets */; };
12 | 0305FAC91F80AE3900D9B979 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0305FAC71F80AE3900D9B979 /* MainMenu.xib */; };
13 | 0305FAD51F80AE3900D9B979 /* SideBarDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0305FAD41F80AE3900D9B979 /* SideBarDemoTests.swift */; };
14 | 0305FAE01F80AE3900D9B979 /* SideBarDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0305FADF1F80AE3900D9B979 /* SideBarDemoUITests.swift */; };
15 | 0305FAF21F80BBA500D9B979 /* THSideBarCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0305FAF11F80BBA500D9B979 /* THSideBarCellView.swift */; };
16 | 0305FAF41F8117A600D9B979 /* ContentView1Controller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0305FAF31F8117A600D9B979 /* ContentView1Controller.xib */; };
17 | 0305FAF61F8117BC00D9B979 /* ContentView2Controller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0305FAF51F8117BC00D9B979 /* ContentView2Controller.xib */; };
18 | 0305FAF81F8117D500D9B979 /* ContentView3Controller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0305FAF71F8117D500D9B979 /* ContentView3Controller.xib */; };
19 | 032081E01FA309BB000925C6 /* ContentView5Controller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 032081DC1FA309BB000925C6 /* ContentView5Controller.xib */; };
20 | 032081E11FA309BB000925C6 /* ContentView4Controller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 032081DD1FA309BB000925C6 /* ContentView4Controller.xib */; };
21 | 032081E21FA309BB000925C6 /* ContentView7Controller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 032081DE1FA309BB000925C6 /* ContentView7Controller.xib */; };
22 | 032081E31FA309BB000925C6 /* ContentView6Controller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 032081DF1FA309BB000925C6 /* ContentView6Controller.xib */; };
23 | 032081EB1FA30C97000925C6 /* abundance-church-family.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 032081E41FA30C96000925C6 /* abundance-church-family.jpg */; };
24 | 032081EC1FA30C97000925C6 /* mobile-phone-and-headphones-on-white-wooden-table.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 032081E51FA30C96000925C6 /* mobile-phone-and-headphones-on-white-wooden-table.jpg */; };
25 | 032081ED1FA30C97000925C6 /* hand-tuning-peg-instrument.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 032081E61FA30C96000925C6 /* hand-tuning-peg-instrument.jpg */; };
26 | 032081EE1FA30C97000925C6 /* vintage-radio-on-glass-table.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 032081E71FA30C96000925C6 /* vintage-radio-on-glass-table.jpg */; };
27 | 032081EF1FA30C97000925C6 /* woman-writing-in-music-sheet.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 032081E81FA30C96000925C6 /* woman-writing-in-music-sheet.jpg */; };
28 | 032081F01FA30C97000925C6 /* rayban-ray-bans-spectacles.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 032081E91FA30C96000925C6 /* rayban-ray-bans-spectacles.jpg */; };
29 | 032081F11FA30C97000925C6 /* record-vinyl-turntable.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 032081EA1FA30C96000925C6 /* record-vinyl-turntable.jpg */; };
30 | 032081F31FA31F2B000925C6 /* THSideBarDragDrop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032081F21FA31F2B000925C6 /* THSideBarDragDrop.swift */; };
31 | 0324E0901FA085EF00D0AB52 /* THSideBarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0324E08F1FA085EF00D0AB52 /* THSideBarDelegate.swift */; };
32 | 0324E0921FA0867400D0AB52 /* THSideBarDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0324E0911FA0867400D0AB52 /* THSideBarDataSource.swift */; };
33 | 0336FB2322DAF11900FEC527 /* CommunController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0336FB2222DAF11900FEC527 /* CommunController.swift */; };
34 | 0346867C1FC7634B0065C180 /* THTextFieldDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0346867B1FC7634B0065C180 /* THTextFieldDelegate.swift */; };
35 | 034CF9EB22E5BC22005BDF21 /* MARKDOWN_REFERENCE.md in Resources */ = {isa = PBXBuildFile; fileRef = 034CF9EA22E5BC22005BDF21 /* MARKDOWN_REFERENCE.md */; };
36 | 034D65631FBD6C0F00D980A9 /* ContentView1Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D65621FBD6C0F00D980A9 /* ContentView1Controller.swift */; };
37 | 034D65651FBD6C3100D980A9 /* ContentView2Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D65641FBD6C3100D980A9 /* ContentView2Controller.swift */; };
38 | 034D65671FBD6C5800D980A9 /* ContentView3Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D65661FBD6C5800D980A9 /* ContentView3Controller.swift */; };
39 | 034D65691FBD6C7B00D980A9 /* ContentView4Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D65681FBD6C7B00D980A9 /* ContentView4Controller.swift */; };
40 | 034D656B1FBD6CA700D980A9 /* ContentView5Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D656A1FBD6CA700D980A9 /* ContentView5Controller.swift */; };
41 | 034D656D1FBD6CC100D980A9 /* ContentView6Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D656C1FBD6CC100D980A9 /* ContentView6Controller.swift */; };
42 | 034D656F1FBD6CD800D980A9 /* ContentView7Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D656E1FBD6CD800D980A9 /* ContentView7Controller.swift */; };
43 | 034D65721FBD72A300D980A9 /* THSideBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034D65701FBD72A300D980A9 /* THSideBarViewController.swift */; };
44 | 034D65731FBD72A300D980A9 /* THSideBarViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 034D65711FBD72A300D980A9 /* THSideBarViewController.xib */; };
45 | 035BAA8F22CCB4820081B76B /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 035BAA8E22CCB4820081B76B /* README.md */; };
46 | 0361A1281F9FD05B00FED796 /* THSideBarData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0361A1271F9FD05B00FED796 /* THSideBarData.swift */; };
47 | 0373C89D1FBC03F40000757D /* MainWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0373C89C1FBC03F40000757D /* MainWindowController.xib */; };
48 | 0373C89F1FBC04020000757D /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0373C89E1FBC04020000757D /* MainWindowController.swift */; };
49 | /* End PBXBuildFile section */
50 |
51 | /* Begin PBXContainerItemProxy section */
52 | 0305FAD11F80AE3900D9B979 /* PBXContainerItemProxy */ = {
53 | isa = PBXContainerItemProxy;
54 | containerPortal = 0305FAB81F80AE3900D9B979 /* Project object */;
55 | proxyType = 1;
56 | remoteGlobalIDString = 0305FABF1F80AE3900D9B979;
57 | remoteInfo = SideBarDemo;
58 | };
59 | 0305FADC1F80AE3900D9B979 /* PBXContainerItemProxy */ = {
60 | isa = PBXContainerItemProxy;
61 | containerPortal = 0305FAB81F80AE3900D9B979 /* Project object */;
62 | proxyType = 1;
63 | remoteGlobalIDString = 0305FABF1F80AE3900D9B979;
64 | remoteInfo = SideBarDemo;
65 | };
66 | /* End PBXContainerItemProxy section */
67 |
68 | /* Begin PBXFileReference section */
69 | 0305FAC01F80AE3900D9B979 /* SideBarDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SideBarDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
70 | 0305FAC31F80AE3900D9B979 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
71 | 0305FAC51F80AE3900D9B979 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
72 | 0305FAC81F80AE3900D9B979 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
73 | 0305FACA1F80AE3900D9B979 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
74 | 0305FACB1F80AE3900D9B979 /* SideBarDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SideBarDemo.entitlements; sourceTree = ""; };
75 | 0305FAD01F80AE3900D9B979 /* SideBarDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SideBarDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
76 | 0305FAD41F80AE3900D9B979 /* SideBarDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarDemoTests.swift; sourceTree = ""; };
77 | 0305FAD61F80AE3900D9B979 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
78 | 0305FADB1F80AE3900D9B979 /* SideBarDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SideBarDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
79 | 0305FADF1F80AE3900D9B979 /* SideBarDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarDemoUITests.swift; sourceTree = ""; };
80 | 0305FAE11F80AE3900D9B979 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
81 | 0305FAF11F80BBA500D9B979 /* THSideBarCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = THSideBarCellView.swift; sourceTree = ""; };
82 | 0305FAF31F8117A600D9B979 /* ContentView1Controller.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ContentView1Controller.xib; sourceTree = ""; };
83 | 0305FAF51F8117BC00D9B979 /* ContentView2Controller.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ContentView2Controller.xib; sourceTree = ""; };
84 | 0305FAF71F8117D500D9B979 /* ContentView3Controller.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ContentView3Controller.xib; sourceTree = ""; };
85 | 032081DC1FA309BB000925C6 /* ContentView5Controller.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContentView5Controller.xib; sourceTree = ""; };
86 | 032081DD1FA309BB000925C6 /* ContentView4Controller.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContentView4Controller.xib; sourceTree = ""; };
87 | 032081DE1FA309BB000925C6 /* ContentView7Controller.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContentView7Controller.xib; sourceTree = ""; };
88 | 032081DF1FA309BB000925C6 /* ContentView6Controller.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContentView6Controller.xib; sourceTree = ""; };
89 | 032081E41FA30C96000925C6 /* abundance-church-family.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "abundance-church-family.jpg"; sourceTree = ""; };
90 | 032081E51FA30C96000925C6 /* mobile-phone-and-headphones-on-white-wooden-table.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "mobile-phone-and-headphones-on-white-wooden-table.jpg"; sourceTree = ""; };
91 | 032081E61FA30C96000925C6 /* hand-tuning-peg-instrument.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "hand-tuning-peg-instrument.jpg"; sourceTree = ""; };
92 | 032081E71FA30C96000925C6 /* vintage-radio-on-glass-table.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "vintage-radio-on-glass-table.jpg"; sourceTree = ""; };
93 | 032081E81FA30C96000925C6 /* woman-writing-in-music-sheet.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "woman-writing-in-music-sheet.jpg"; sourceTree = ""; };
94 | 032081E91FA30C96000925C6 /* rayban-ray-bans-spectacles.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "rayban-ray-bans-spectacles.jpg"; sourceTree = ""; };
95 | 032081EA1FA30C96000925C6 /* record-vinyl-turntable.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "record-vinyl-turntable.jpg"; sourceTree = ""; };
96 | 032081F21FA31F2B000925C6 /* THSideBarDragDrop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = THSideBarDragDrop.swift; sourceTree = ""; };
97 | 0324E08F1FA085EF00D0AB52 /* THSideBarDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = THSideBarDelegate.swift; sourceTree = ""; };
98 | 0324E0911FA0867400D0AB52 /* THSideBarDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = THSideBarDataSource.swift; sourceTree = ""; };
99 | 0336FB2222DAF11900FEC527 /* CommunController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommunController.swift; sourceTree = ""; };
100 | 0346867B1FC7634B0065C180 /* THTextFieldDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = THTextFieldDelegate.swift; sourceTree = ""; };
101 | 034CF9EA22E5BC22005BDF21 /* MARKDOWN_REFERENCE.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = MARKDOWN_REFERENCE.md; sourceTree = ""; };
102 | 034D65621FBD6C0F00D980A9 /* ContentView1Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView1Controller.swift; sourceTree = ""; };
103 | 034D65641FBD6C3100D980A9 /* ContentView2Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView2Controller.swift; sourceTree = ""; };
104 | 034D65661FBD6C5800D980A9 /* ContentView3Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView3Controller.swift; sourceTree = ""; };
105 | 034D65681FBD6C7B00D980A9 /* ContentView4Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView4Controller.swift; sourceTree = ""; };
106 | 034D656A1FBD6CA700D980A9 /* ContentView5Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView5Controller.swift; sourceTree = ""; };
107 | 034D656C1FBD6CC100D980A9 /* ContentView6Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView6Controller.swift; sourceTree = ""; };
108 | 034D656E1FBD6CD800D980A9 /* ContentView7Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView7Controller.swift; sourceTree = ""; };
109 | 034D65701FBD72A300D980A9 /* THSideBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = THSideBarViewController.swift; sourceTree = ""; };
110 | 034D65711FBD72A300D980A9 /* THSideBarViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = THSideBarViewController.xib; sourceTree = ""; };
111 | 035BAA8E22CCB4820081B76B /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
112 | 0361A1271F9FD05B00FED796 /* THSideBarData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = THSideBarData.swift; sourceTree = ""; };
113 | 0373C89C1FBC03F40000757D /* MainWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainWindowController.xib; sourceTree = ""; };
114 | 0373C89E1FBC04020000757D /* MainWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowController.swift; sourceTree = ""; };
115 | /* End PBXFileReference section */
116 |
117 | /* Begin PBXFrameworksBuildPhase section */
118 | 0305FABD1F80AE3900D9B979 /* Frameworks */ = {
119 | isa = PBXFrameworksBuildPhase;
120 | buildActionMask = 2147483647;
121 | files = (
122 | );
123 | runOnlyForDeploymentPostprocessing = 0;
124 | };
125 | 0305FACD1F80AE3900D9B979 /* Frameworks */ = {
126 | isa = PBXFrameworksBuildPhase;
127 | buildActionMask = 2147483647;
128 | files = (
129 | );
130 | runOnlyForDeploymentPostprocessing = 0;
131 | };
132 | 0305FAD81F80AE3900D9B979 /* Frameworks */ = {
133 | isa = PBXFrameworksBuildPhase;
134 | buildActionMask = 2147483647;
135 | files = (
136 | );
137 | runOnlyForDeploymentPostprocessing = 0;
138 | };
139 | /* End PBXFrameworksBuildPhase section */
140 |
141 | /* Begin PBXGroup section */
142 | 0305FAB71F80AE3900D9B979 = {
143 | isa = PBXGroup;
144 | children = (
145 | 034CF9EA22E5BC22005BDF21 /* MARKDOWN_REFERENCE.md */,
146 | 035BAA8E22CCB4820081B76B /* README.md */,
147 | 0324E08E1FA0847700D0AB52 /* THSideBar */,
148 | 0305FAC21F80AE3900D9B979 /* SideBarDemo */,
149 | 0305FAD31F80AE3900D9B979 /* SideBarDemoTests */,
150 | 0305FADE1F80AE3900D9B979 /* SideBarDemoUITests */,
151 | 0305FAC11F80AE3900D9B979 /* Products */,
152 | );
153 | sourceTree = "";
154 | };
155 | 0305FAC11F80AE3900D9B979 /* Products */ = {
156 | isa = PBXGroup;
157 | children = (
158 | 0305FAC01F80AE3900D9B979 /* SideBarDemo.app */,
159 | 0305FAD01F80AE3900D9B979 /* SideBarDemoTests.xctest */,
160 | 0305FADB1F80AE3900D9B979 /* SideBarDemoUITests.xctest */,
161 | );
162 | name = Products;
163 | sourceTree = "";
164 | };
165 | 0305FAC21F80AE3900D9B979 /* SideBarDemo */ = {
166 | isa = PBXGroup;
167 | children = (
168 | 034D65611FBD6BDB00D980A9 /* View */,
169 | 0305FAC31F80AE3900D9B979 /* AppDelegate.swift */,
170 | 0305FAC51F80AE3900D9B979 /* Assets.xcassets */,
171 | 0305FACA1F80AE3900D9B979 /* Info.plist */,
172 | 0373C89E1FBC04020000757D /* MainWindowController.swift */,
173 | 0373C89C1FBC03F40000757D /* MainWindowController.xib */,
174 | 0305FAC71F80AE3900D9B979 /* MainMenu.xib */,
175 | 032081DB1FA3098E000925C6 /* Resource */,
176 | 0305FACB1F80AE3900D9B979 /* SideBarDemo.entitlements */,
177 | );
178 | path = SideBarDemo;
179 | sourceTree = "";
180 | };
181 | 0305FAD31F80AE3900D9B979 /* SideBarDemoTests */ = {
182 | isa = PBXGroup;
183 | children = (
184 | 0305FAD41F80AE3900D9B979 /* SideBarDemoTests.swift */,
185 | 0305FAD61F80AE3900D9B979 /* Info.plist */,
186 | );
187 | path = SideBarDemoTests;
188 | sourceTree = "";
189 | };
190 | 0305FADE1F80AE3900D9B979 /* SideBarDemoUITests */ = {
191 | isa = PBXGroup;
192 | children = (
193 | 0305FADF1F80AE3900D9B979 /* SideBarDemoUITests.swift */,
194 | 0305FAE11F80AE3900D9B979 /* Info.plist */,
195 | );
196 | path = SideBarDemoUITests;
197 | sourceTree = "";
198 | };
199 | 032081DB1FA3098E000925C6 /* Resource */ = {
200 | isa = PBXGroup;
201 | children = (
202 | 032081E41FA30C96000925C6 /* abundance-church-family.jpg */,
203 | 032081E61FA30C96000925C6 /* hand-tuning-peg-instrument.jpg */,
204 | 032081E51FA30C96000925C6 /* mobile-phone-and-headphones-on-white-wooden-table.jpg */,
205 | 032081E91FA30C96000925C6 /* rayban-ray-bans-spectacles.jpg */,
206 | 032081EA1FA30C96000925C6 /* record-vinyl-turntable.jpg */,
207 | 032081E71FA30C96000925C6 /* vintage-radio-on-glass-table.jpg */,
208 | 032081E81FA30C96000925C6 /* woman-writing-in-music-sheet.jpg */,
209 | );
210 | path = Resource;
211 | sourceTree = "";
212 | };
213 | 0324E08E1FA0847700D0AB52 /* THSideBar */ = {
214 | isa = PBXGroup;
215 | children = (
216 | 0305FAF11F80BBA500D9B979 /* THSideBarCellView.swift */,
217 | 0361A1271F9FD05B00FED796 /* THSideBarData.swift */,
218 | 0324E0911FA0867400D0AB52 /* THSideBarDataSource.swift */,
219 | 0324E08F1FA085EF00D0AB52 /* THSideBarDelegate.swift */,
220 | 032081F21FA31F2B000925C6 /* THSideBarDragDrop.swift */,
221 | 0346867B1FC7634B0065C180 /* THTextFieldDelegate.swift */,
222 | 034D65701FBD72A300D980A9 /* THSideBarViewController.swift */,
223 | 034D65711FBD72A300D980A9 /* THSideBarViewController.xib */,
224 | );
225 | path = THSideBar;
226 | sourceTree = "";
227 | };
228 | 034D65611FBD6BDB00D980A9 /* View */ = {
229 | isa = PBXGroup;
230 | children = (
231 | 034D65621FBD6C0F00D980A9 /* ContentView1Controller.swift */,
232 | 0305FAF31F8117A600D9B979 /* ContentView1Controller.xib */,
233 | 034D65641FBD6C3100D980A9 /* ContentView2Controller.swift */,
234 | 0305FAF51F8117BC00D9B979 /* ContentView2Controller.xib */,
235 | 034D65661FBD6C5800D980A9 /* ContentView3Controller.swift */,
236 | 0305FAF71F8117D500D9B979 /* ContentView3Controller.xib */,
237 | 034D65681FBD6C7B00D980A9 /* ContentView4Controller.swift */,
238 | 032081DD1FA309BB000925C6 /* ContentView4Controller.xib */,
239 | 034D656A1FBD6CA700D980A9 /* ContentView5Controller.swift */,
240 | 032081DC1FA309BB000925C6 /* ContentView5Controller.xib */,
241 | 034D656C1FBD6CC100D980A9 /* ContentView6Controller.swift */,
242 | 032081DF1FA309BB000925C6 /* ContentView6Controller.xib */,
243 | 034D656E1FBD6CD800D980A9 /* ContentView7Controller.swift */,
244 | 032081DE1FA309BB000925C6 /* ContentView7Controller.xib */,
245 | 0336FB2222DAF11900FEC527 /* CommunController.swift */,
246 | );
247 | path = View;
248 | sourceTree = "";
249 | };
250 | /* End PBXGroup section */
251 |
252 | /* Begin PBXNativeTarget section */
253 | 0305FABF1F80AE3900D9B979 /* SideBarDemo */ = {
254 | isa = PBXNativeTarget;
255 | buildConfigurationList = 0305FAE41F80AE3900D9B979 /* Build configuration list for PBXNativeTarget "SideBarDemo" */;
256 | buildPhases = (
257 | 0305FABC1F80AE3900D9B979 /* Sources */,
258 | 0305FABD1F80AE3900D9B979 /* Frameworks */,
259 | 0305FABE1F80AE3900D9B979 /* Resources */,
260 | );
261 | buildRules = (
262 | );
263 | dependencies = (
264 | );
265 | name = SideBarDemo;
266 | productName = SideBarDemo;
267 | productReference = 0305FAC01F80AE3900D9B979 /* SideBarDemo.app */;
268 | productType = "com.apple.product-type.application";
269 | };
270 | 0305FACF1F80AE3900D9B979 /* SideBarDemoTests */ = {
271 | isa = PBXNativeTarget;
272 | buildConfigurationList = 0305FAE71F80AE3900D9B979 /* Build configuration list for PBXNativeTarget "SideBarDemoTests" */;
273 | buildPhases = (
274 | 0305FACC1F80AE3900D9B979 /* Sources */,
275 | 0305FACD1F80AE3900D9B979 /* Frameworks */,
276 | 0305FACE1F80AE3900D9B979 /* Resources */,
277 | );
278 | buildRules = (
279 | );
280 | dependencies = (
281 | 0305FAD21F80AE3900D9B979 /* PBXTargetDependency */,
282 | );
283 | name = SideBarDemoTests;
284 | productName = SideBarDemoTests;
285 | productReference = 0305FAD01F80AE3900D9B979 /* SideBarDemoTests.xctest */;
286 | productType = "com.apple.product-type.bundle.unit-test";
287 | };
288 | 0305FADA1F80AE3900D9B979 /* SideBarDemoUITests */ = {
289 | isa = PBXNativeTarget;
290 | buildConfigurationList = 0305FAEA1F80AE3900D9B979 /* Build configuration list for PBXNativeTarget "SideBarDemoUITests" */;
291 | buildPhases = (
292 | 0305FAD71F80AE3900D9B979 /* Sources */,
293 | 0305FAD81F80AE3900D9B979 /* Frameworks */,
294 | 0305FAD91F80AE3900D9B979 /* Resources */,
295 | );
296 | buildRules = (
297 | );
298 | dependencies = (
299 | 0305FADD1F80AE3900D9B979 /* PBXTargetDependency */,
300 | );
301 | name = SideBarDemoUITests;
302 | productName = SideBarDemoUITests;
303 | productReference = 0305FADB1F80AE3900D9B979 /* SideBarDemoUITests.xctest */;
304 | productType = "com.apple.product-type.bundle.ui-testing";
305 | };
306 | /* End PBXNativeTarget section */
307 |
308 | /* Begin PBXProject section */
309 | 0305FAB81F80AE3900D9B979 /* Project object */ = {
310 | isa = PBXProject;
311 | attributes = {
312 | LastSwiftUpdateCheck = 0910;
313 | LastUpgradeCheck = 1100;
314 | ORGANIZATIONNAME = thierryH24;
315 | TargetAttributes = {
316 | 0305FABF1F80AE3900D9B979 = {
317 | CreatedOnToolsVersion = 9.1;
318 | LastSwiftMigration = 1020;
319 | ProvisioningStyle = Automatic;
320 | SystemCapabilities = {
321 | com.apple.Sandbox = {
322 | enabled = 0;
323 | };
324 | };
325 | };
326 | 0305FACF1F80AE3900D9B979 = {
327 | CreatedOnToolsVersion = 9.1;
328 | LastSwiftMigration = 1020;
329 | ProvisioningStyle = Automatic;
330 | TestTargetID = 0305FABF1F80AE3900D9B979;
331 | };
332 | 0305FADA1F80AE3900D9B979 = {
333 | CreatedOnToolsVersion = 9.1;
334 | LastSwiftMigration = 1020;
335 | ProvisioningStyle = Automatic;
336 | TestTargetID = 0305FABF1F80AE3900D9B979;
337 | };
338 | };
339 | };
340 | buildConfigurationList = 0305FABB1F80AE3900D9B979 /* Build configuration list for PBXProject "SideBarDemo" */;
341 | compatibilityVersion = "Xcode 8.0";
342 | developmentRegion = en;
343 | hasScannedForEncodings = 0;
344 | knownRegions = (
345 | en,
346 | Base,
347 | );
348 | mainGroup = 0305FAB71F80AE3900D9B979;
349 | productRefGroup = 0305FAC11F80AE3900D9B979 /* Products */;
350 | projectDirPath = "";
351 | projectRoot = "";
352 | targets = (
353 | 0305FABF1F80AE3900D9B979 /* SideBarDemo */,
354 | 0305FACF1F80AE3900D9B979 /* SideBarDemoTests */,
355 | 0305FADA1F80AE3900D9B979 /* SideBarDemoUITests */,
356 | );
357 | };
358 | /* End PBXProject section */
359 |
360 | /* Begin PBXResourcesBuildPhase section */
361 | 0305FABE1F80AE3900D9B979 /* Resources */ = {
362 | isa = PBXResourcesBuildPhase;
363 | buildActionMask = 2147483647;
364 | files = (
365 | 0305FAF41F8117A600D9B979 /* ContentView1Controller.xib in Resources */,
366 | 032081EB1FA30C97000925C6 /* abundance-church-family.jpg in Resources */,
367 | 032081E31FA309BB000925C6 /* ContentView6Controller.xib in Resources */,
368 | 0305FAF61F8117BC00D9B979 /* ContentView2Controller.xib in Resources */,
369 | 0305FAF81F8117D500D9B979 /* ContentView3Controller.xib in Resources */,
370 | 032081EC1FA30C97000925C6 /* mobile-phone-and-headphones-on-white-wooden-table.jpg in Resources */,
371 | 032081E11FA309BB000925C6 /* ContentView4Controller.xib in Resources */,
372 | 032081F01FA30C97000925C6 /* rayban-ray-bans-spectacles.jpg in Resources */,
373 | 032081ED1FA30C97000925C6 /* hand-tuning-peg-instrument.jpg in Resources */,
374 | 0373C89D1FBC03F40000757D /* MainWindowController.xib in Resources */,
375 | 0305FAC61F80AE3900D9B979 /* Assets.xcassets in Resources */,
376 | 032081F11FA30C97000925C6 /* record-vinyl-turntable.jpg in Resources */,
377 | 032081E01FA309BB000925C6 /* ContentView5Controller.xib in Resources */,
378 | 035BAA8F22CCB4820081B76B /* README.md in Resources */,
379 | 0305FAC91F80AE3900D9B979 /* MainMenu.xib in Resources */,
380 | 032081EE1FA30C97000925C6 /* vintage-radio-on-glass-table.jpg in Resources */,
381 | 032081EF1FA30C97000925C6 /* woman-writing-in-music-sheet.jpg in Resources */,
382 | 034CF9EB22E5BC22005BDF21 /* MARKDOWN_REFERENCE.md in Resources */,
383 | 034D65731FBD72A300D980A9 /* THSideBarViewController.xib in Resources */,
384 | 032081E21FA309BB000925C6 /* ContentView7Controller.xib in Resources */,
385 | );
386 | runOnlyForDeploymentPostprocessing = 0;
387 | };
388 | 0305FACE1F80AE3900D9B979 /* Resources */ = {
389 | isa = PBXResourcesBuildPhase;
390 | buildActionMask = 2147483647;
391 | files = (
392 | );
393 | runOnlyForDeploymentPostprocessing = 0;
394 | };
395 | 0305FAD91F80AE3900D9B979 /* Resources */ = {
396 | isa = PBXResourcesBuildPhase;
397 | buildActionMask = 2147483647;
398 | files = (
399 | );
400 | runOnlyForDeploymentPostprocessing = 0;
401 | };
402 | /* End PBXResourcesBuildPhase section */
403 |
404 | /* Begin PBXSourcesBuildPhase section */
405 | 0305FABC1F80AE3900D9B979 /* Sources */ = {
406 | isa = PBXSourcesBuildPhase;
407 | buildActionMask = 2147483647;
408 | files = (
409 | 0305FAF21F80BBA500D9B979 /* THSideBarCellView.swift in Sources */,
410 | 0361A1281F9FD05B00FED796 /* THSideBarData.swift in Sources */,
411 | 034D656D1FBD6CC100D980A9 /* ContentView6Controller.swift in Sources */,
412 | 034D65721FBD72A300D980A9 /* THSideBarViewController.swift in Sources */,
413 | 0346867C1FC7634B0065C180 /* THTextFieldDelegate.swift in Sources */,
414 | 034D65671FBD6C5800D980A9 /* ContentView3Controller.swift in Sources */,
415 | 0336FB2322DAF11900FEC527 /* CommunController.swift in Sources */,
416 | 034D65651FBD6C3100D980A9 /* ContentView2Controller.swift in Sources */,
417 | 034D65631FBD6C0F00D980A9 /* ContentView1Controller.swift in Sources */,
418 | 034D656F1FBD6CD800D980A9 /* ContentView7Controller.swift in Sources */,
419 | 0324E0921FA0867400D0AB52 /* THSideBarDataSource.swift in Sources */,
420 | 032081F31FA31F2B000925C6 /* THSideBarDragDrop.swift in Sources */,
421 | 0324E0901FA085EF00D0AB52 /* THSideBarDelegate.swift in Sources */,
422 | 0305FAC41F80AE3900D9B979 /* AppDelegate.swift in Sources */,
423 | 0373C89F1FBC04020000757D /* MainWindowController.swift in Sources */,
424 | 034D656B1FBD6CA700D980A9 /* ContentView5Controller.swift in Sources */,
425 | 034D65691FBD6C7B00D980A9 /* ContentView4Controller.swift in Sources */,
426 | );
427 | runOnlyForDeploymentPostprocessing = 0;
428 | };
429 | 0305FACC1F80AE3900D9B979 /* Sources */ = {
430 | isa = PBXSourcesBuildPhase;
431 | buildActionMask = 2147483647;
432 | files = (
433 | 0305FAD51F80AE3900D9B979 /* SideBarDemoTests.swift in Sources */,
434 | );
435 | runOnlyForDeploymentPostprocessing = 0;
436 | };
437 | 0305FAD71F80AE3900D9B979 /* Sources */ = {
438 | isa = PBXSourcesBuildPhase;
439 | buildActionMask = 2147483647;
440 | files = (
441 | 0305FAE01F80AE3900D9B979 /* SideBarDemoUITests.swift in Sources */,
442 | );
443 | runOnlyForDeploymentPostprocessing = 0;
444 | };
445 | /* End PBXSourcesBuildPhase section */
446 |
447 | /* Begin PBXTargetDependency section */
448 | 0305FAD21F80AE3900D9B979 /* PBXTargetDependency */ = {
449 | isa = PBXTargetDependency;
450 | target = 0305FABF1F80AE3900D9B979 /* SideBarDemo */;
451 | targetProxy = 0305FAD11F80AE3900D9B979 /* PBXContainerItemProxy */;
452 | };
453 | 0305FADD1F80AE3900D9B979 /* PBXTargetDependency */ = {
454 | isa = PBXTargetDependency;
455 | target = 0305FABF1F80AE3900D9B979 /* SideBarDemo */;
456 | targetProxy = 0305FADC1F80AE3900D9B979 /* PBXContainerItemProxy */;
457 | };
458 | /* End PBXTargetDependency section */
459 |
460 | /* Begin PBXVariantGroup section */
461 | 0305FAC71F80AE3900D9B979 /* MainMenu.xib */ = {
462 | isa = PBXVariantGroup;
463 | children = (
464 | 0305FAC81F80AE3900D9B979 /* Base */,
465 | );
466 | name = MainMenu.xib;
467 | sourceTree = "";
468 | };
469 | /* End PBXVariantGroup section */
470 |
471 | /* Begin XCBuildConfiguration section */
472 | 0305FAE21F80AE3900D9B979 /* Debug */ = {
473 | isa = XCBuildConfiguration;
474 | buildSettings = {
475 | ALWAYS_SEARCH_USER_PATHS = NO;
476 | CLANG_ANALYZER_NONNULL = YES;
477 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
479 | CLANG_CXX_LIBRARY = "libc++";
480 | CLANG_ENABLE_MODULES = YES;
481 | CLANG_ENABLE_OBJC_ARC = YES;
482 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
483 | CLANG_WARN_BOOL_CONVERSION = YES;
484 | CLANG_WARN_COMMA = YES;
485 | CLANG_WARN_CONSTANT_CONVERSION = YES;
486 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
487 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
488 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
489 | CLANG_WARN_EMPTY_BODY = YES;
490 | CLANG_WARN_ENUM_CONVERSION = YES;
491 | CLANG_WARN_INFINITE_RECURSION = YES;
492 | CLANG_WARN_INT_CONVERSION = YES;
493 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
494 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
495 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
496 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
497 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
498 | CLANG_WARN_STRICT_PROTOTYPES = YES;
499 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
500 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
501 | CLANG_WARN_UNREACHABLE_CODE = YES;
502 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
503 | CODE_SIGN_IDENTITY = "-";
504 | COPY_PHASE_STRIP = NO;
505 | DEBUG_INFORMATION_FORMAT = dwarf;
506 | ENABLE_STRICT_OBJC_MSGSEND = YES;
507 | ENABLE_TESTABILITY = YES;
508 | GCC_C_LANGUAGE_STANDARD = gnu11;
509 | GCC_DYNAMIC_NO_PIC = NO;
510 | GCC_NO_COMMON_BLOCKS = YES;
511 | GCC_OPTIMIZATION_LEVEL = 0;
512 | GCC_PREPROCESSOR_DEFINITIONS = (
513 | "DEBUG=1",
514 | "$(inherited)",
515 | );
516 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
517 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
518 | GCC_WARN_UNDECLARED_SELECTOR = YES;
519 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
520 | GCC_WARN_UNUSED_FUNCTION = YES;
521 | GCC_WARN_UNUSED_VARIABLE = YES;
522 | MACOSX_DEPLOYMENT_TARGET = 10.14;
523 | MTL_ENABLE_DEBUG_INFO = YES;
524 | ONLY_ACTIVE_ARCH = YES;
525 | SDKROOT = macosx;
526 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
527 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
528 | };
529 | name = Debug;
530 | };
531 | 0305FAE31F80AE3900D9B979 /* Release */ = {
532 | isa = XCBuildConfiguration;
533 | buildSettings = {
534 | ALWAYS_SEARCH_USER_PATHS = NO;
535 | CLANG_ANALYZER_NONNULL = YES;
536 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
537 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
538 | CLANG_CXX_LIBRARY = "libc++";
539 | CLANG_ENABLE_MODULES = YES;
540 | CLANG_ENABLE_OBJC_ARC = YES;
541 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
542 | CLANG_WARN_BOOL_CONVERSION = YES;
543 | CLANG_WARN_COMMA = YES;
544 | CLANG_WARN_CONSTANT_CONVERSION = YES;
545 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
546 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
547 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
548 | CLANG_WARN_EMPTY_BODY = YES;
549 | CLANG_WARN_ENUM_CONVERSION = YES;
550 | CLANG_WARN_INFINITE_RECURSION = YES;
551 | CLANG_WARN_INT_CONVERSION = YES;
552 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
553 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
554 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
555 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
556 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
557 | CLANG_WARN_STRICT_PROTOTYPES = YES;
558 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
559 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
560 | CLANG_WARN_UNREACHABLE_CODE = YES;
561 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
562 | CODE_SIGN_IDENTITY = "-";
563 | COPY_PHASE_STRIP = NO;
564 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
565 | ENABLE_NS_ASSERTIONS = NO;
566 | ENABLE_STRICT_OBJC_MSGSEND = YES;
567 | GCC_C_LANGUAGE_STANDARD = gnu11;
568 | GCC_NO_COMMON_BLOCKS = YES;
569 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
570 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
571 | GCC_WARN_UNDECLARED_SELECTOR = YES;
572 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
573 | GCC_WARN_UNUSED_FUNCTION = YES;
574 | GCC_WARN_UNUSED_VARIABLE = YES;
575 | MACOSX_DEPLOYMENT_TARGET = 10.14;
576 | MTL_ENABLE_DEBUG_INFO = NO;
577 | SDKROOT = macosx;
578 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
579 | };
580 | name = Release;
581 | };
582 | 0305FAE51F80AE3900D9B979 /* Debug */ = {
583 | isa = XCBuildConfiguration;
584 | buildSettings = {
585 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
586 | CODE_SIGN_IDENTITY = "-";
587 | CODE_SIGN_STYLE = Automatic;
588 | COMBINE_HIDPI_IMAGES = YES;
589 | INFOPLIST_FILE = SideBarDemo/Info.plist;
590 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
591 | MACOSX_DEPLOYMENT_TARGET = 10.14;
592 | MARKETING_VERSION = 2.0;
593 | PRODUCT_BUNDLE_IDENTIFIER = com.thierry24100.SideBarDemo;
594 | PRODUCT_NAME = "$(TARGET_NAME)";
595 | SWIFT_VERSION = 5.0;
596 | };
597 | name = Debug;
598 | };
599 | 0305FAE61F80AE3900D9B979 /* Release */ = {
600 | isa = XCBuildConfiguration;
601 | buildSettings = {
602 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
603 | CODE_SIGN_IDENTITY = "-";
604 | CODE_SIGN_STYLE = Automatic;
605 | COMBINE_HIDPI_IMAGES = YES;
606 | INFOPLIST_FILE = SideBarDemo/Info.plist;
607 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
608 | MACOSX_DEPLOYMENT_TARGET = 10.14;
609 | MARKETING_VERSION = 2.0;
610 | PRODUCT_BUNDLE_IDENTIFIER = com.thierry24100.SideBarDemo;
611 | PRODUCT_NAME = "$(TARGET_NAME)";
612 | SWIFT_VERSION = 5.0;
613 | };
614 | name = Release;
615 | };
616 | 0305FAE81F80AE3900D9B979 /* Debug */ = {
617 | isa = XCBuildConfiguration;
618 | buildSettings = {
619 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
620 | BUNDLE_LOADER = "$(TEST_HOST)";
621 | CODE_SIGN_STYLE = Automatic;
622 | COMBINE_HIDPI_IMAGES = YES;
623 | INFOPLIST_FILE = SideBarDemoTests/Info.plist;
624 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
625 | PRODUCT_BUNDLE_IDENTIFIER = com.thierry24100..SideBarDemoTests;
626 | PRODUCT_NAME = "$(TARGET_NAME)";
627 | SWIFT_VERSION = 5.0;
628 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SideBarDemo.app/Contents/MacOS/SideBarDemo";
629 | };
630 | name = Debug;
631 | };
632 | 0305FAE91F80AE3900D9B979 /* Release */ = {
633 | isa = XCBuildConfiguration;
634 | buildSettings = {
635 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
636 | BUNDLE_LOADER = "$(TEST_HOST)";
637 | CODE_SIGN_STYLE = Automatic;
638 | COMBINE_HIDPI_IMAGES = YES;
639 | INFOPLIST_FILE = SideBarDemoTests/Info.plist;
640 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
641 | PRODUCT_BUNDLE_IDENTIFIER = com.thierry24100..SideBarDemoTests;
642 | PRODUCT_NAME = "$(TARGET_NAME)";
643 | SWIFT_VERSION = 5.0;
644 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SideBarDemo.app/Contents/MacOS/SideBarDemo";
645 | };
646 | name = Release;
647 | };
648 | 0305FAEB1F80AE3900D9B979 /* Debug */ = {
649 | isa = XCBuildConfiguration;
650 | buildSettings = {
651 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
652 | CODE_SIGN_STYLE = Automatic;
653 | COMBINE_HIDPI_IMAGES = YES;
654 | INFOPLIST_FILE = SideBarDemoUITests/Info.plist;
655 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
656 | PRODUCT_BUNDLE_IDENTIFIER = com.thierry24100..SideBarDemoUITests;
657 | PRODUCT_NAME = "$(TARGET_NAME)";
658 | SWIFT_VERSION = 5.0;
659 | TEST_TARGET_NAME = SideBarDemo;
660 | };
661 | name = Debug;
662 | };
663 | 0305FAEC1F80AE3900D9B979 /* Release */ = {
664 | isa = XCBuildConfiguration;
665 | buildSettings = {
666 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
667 | CODE_SIGN_STYLE = Automatic;
668 | COMBINE_HIDPI_IMAGES = YES;
669 | INFOPLIST_FILE = SideBarDemoUITests/Info.plist;
670 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
671 | PRODUCT_BUNDLE_IDENTIFIER = com.thierry24100..SideBarDemoUITests;
672 | PRODUCT_NAME = "$(TARGET_NAME)";
673 | SWIFT_VERSION = 5.0;
674 | TEST_TARGET_NAME = SideBarDemo;
675 | };
676 | name = Release;
677 | };
678 | /* End XCBuildConfiguration section */
679 |
680 | /* Begin XCConfigurationList section */
681 | 0305FABB1F80AE3900D9B979 /* Build configuration list for PBXProject "SideBarDemo" */ = {
682 | isa = XCConfigurationList;
683 | buildConfigurations = (
684 | 0305FAE21F80AE3900D9B979 /* Debug */,
685 | 0305FAE31F80AE3900D9B979 /* Release */,
686 | );
687 | defaultConfigurationIsVisible = 0;
688 | defaultConfigurationName = Release;
689 | };
690 | 0305FAE41F80AE3900D9B979 /* Build configuration list for PBXNativeTarget "SideBarDemo" */ = {
691 | isa = XCConfigurationList;
692 | buildConfigurations = (
693 | 0305FAE51F80AE3900D9B979 /* Debug */,
694 | 0305FAE61F80AE3900D9B979 /* Release */,
695 | );
696 | defaultConfigurationIsVisible = 0;
697 | defaultConfigurationName = Release;
698 | };
699 | 0305FAE71F80AE3900D9B979 /* Build configuration list for PBXNativeTarget "SideBarDemoTests" */ = {
700 | isa = XCConfigurationList;
701 | buildConfigurations = (
702 | 0305FAE81F80AE3900D9B979 /* Debug */,
703 | 0305FAE91F80AE3900D9B979 /* Release */,
704 | );
705 | defaultConfigurationIsVisible = 0;
706 | defaultConfigurationName = Release;
707 | };
708 | 0305FAEA1F80AE3900D9B979 /* Build configuration list for PBXNativeTarget "SideBarDemoUITests" */ = {
709 | isa = XCConfigurationList;
710 | buildConfigurations = (
711 | 0305FAEB1F80AE3900D9B979 /* Debug */,
712 | 0305FAEC1F80AE3900D9B979 /* Release */,
713 | );
714 | defaultConfigurationIsVisible = 0;
715 | defaultConfigurationName = Release;
716 | };
717 | /* End XCConfigurationList section */
718 | };
719 | rootObject = 0305FAB81F80AE3900D9B979 /* Project object */;
720 | }
721 |
--------------------------------------------------------------------------------
/SideBarDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SideBarDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SideBarDemo.xcodeproj/xcuserdata/thierryh24.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/SideBarDemo.xcodeproj/xcuserdata/thierryh24.xcuserdatad/xcschemes/SideBarDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
42 |
48 |
49 |
50 |
52 |
58 |
59 |
60 |
61 |
62 |
72 |
74 |
80 |
81 |
82 |
83 |
86 |
87 |
88 |
89 |
95 |
97 |
103 |
104 |
105 |
106 |
108 |
109 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/SideBarDemo.xcodeproj/xcuserdata/thierryh24.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SideBarDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 0305FABF1F80AE3900D9B979
16 |
17 | primary
18 |
19 |
20 | 0305FACF1F80AE3900D9B979
21 |
22 | primary
23 |
24 |
25 | 0305FADA1F80AE3900D9B979
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/SideBarDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 01/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 | @IBOutlet weak var window: NSWindow!
15 |
16 | var mainWindowController: MainWindowController?
17 |
18 | func applicationDidFinishLaunching(_ aNotification: Notification) {
19 | // Insert code here to initialize your application
20 |
21 | initializeLibraryAndShowMainWindow()
22 | }
23 |
24 | func applicationWillTerminate(_ aNotification: Notification) {
25 | // Insert code here to tear down your application
26 | }
27 |
28 | func applicationShouldTerminateAfterLastWindowClosed (_ sender: NSApplication) -> Bool
29 | {
30 | return true
31 | }
32 |
33 | func initializeLibraryAndShowMainWindow() {
34 |
35 | mainWindowController = MainWindowController(windowNibName: "MainWindowController")
36 | mainWindowController?.showWindow(self)
37 | }
38 |
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/Department-50.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Department-50.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/Department-50.imageset/Department-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/Department-50.imageset/Department-50.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/DownArrow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "filename" : "down-arrow-light.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "filename" : "down-arrow.png",
11 | "appearances" : [
12 | {
13 | "appearance" : "luminosity",
14 | "value" : "light"
15 | }
16 | ],
17 | "scale" : "1x"
18 | },
19 | {
20 | "idiom" : "mac",
21 | "filename" : "down-arrow-light-1.png",
22 | "appearances" : [
23 | {
24 | "appearance" : "luminosity",
25 | "value" : "dark"
26 | }
27 | ],
28 | "scale" : "1x"
29 | },
30 | {
31 | "idiom" : "mac",
32 | "filename" : "down-arrow-light@2x.png",
33 | "scale" : "2x"
34 | },
35 | {
36 | "idiom" : "mac",
37 | "filename" : "down-arrow@2x.png",
38 | "appearances" : [
39 | {
40 | "appearance" : "luminosity",
41 | "value" : "light"
42 | }
43 | ],
44 | "scale" : "2x"
45 | },
46 | {
47 | "idiom" : "mac",
48 | "filename" : "down-arrow-light@2x-1.png",
49 | "appearances" : [
50 | {
51 | "appearance" : "luminosity",
52 | "value" : "dark"
53 | }
54 | ],
55 | "scale" : "2x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light-1.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light@2x-1.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow-light@2x.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/DownArrow.imageset/down-arrow@2x.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/Human_resource.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Human_resource_icons-09-512.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/Human_resource.imageset/Human_resource_icons-09-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/Human_resource.imageset/Human_resource_icons-09-512.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/RightArrow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "filename" : "right-arrow-light.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "filename" : "right-arrow.png",
11 | "appearances" : [
12 | {
13 | "appearance" : "luminosity",
14 | "value" : "light"
15 | }
16 | ],
17 | "scale" : "1x"
18 | },
19 | {
20 | "idiom" : "mac",
21 | "filename" : "right-arrow-light-1.png",
22 | "appearances" : [
23 | {
24 | "appearance" : "luminosity",
25 | "value" : "dark"
26 | }
27 | ],
28 | "scale" : "1x"
29 | },
30 | {
31 | "idiom" : "mac",
32 | "filename" : "right-arrow-light@2x.png",
33 | "scale" : "2x"
34 | },
35 | {
36 | "idiom" : "mac",
37 | "filename" : "right-arrow@2x.png",
38 | "appearances" : [
39 | {
40 | "appearance" : "luminosity",
41 | "value" : "light"
42 | }
43 | ],
44 | "scale" : "2x"
45 | },
46 | {
47 | "idiom" : "mac",
48 | "filename" : "right-arrow-light@2x-1.png",
49 | "appearances" : [
50 | {
51 | "appearance" : "luminosity",
52 | "value" : "dark"
53 | }
54 | ],
55 | "scale" : "2x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light-1.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light@2x-1.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow-light@2x.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/RightArrow.imageset/right-arrow@2x.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/account.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "account.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/account.imageset/account.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/account.imageset/account.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/application-sidebar-list.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "application-sidebar-list.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/application-sidebar-list.imageset/application-sidebar-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/application-sidebar-list.imageset/application-sidebar-list.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/clock.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "clock.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/clock.imageset/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/clock.imageset/clock.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/employee.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "employee.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/employee.imageset/employee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/employee.imageset/employee.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/film.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "film.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/film.imageset/film.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/film.imageset/film.png
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/smiley.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "smiley.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SideBarDemo/Assets.xcassets/smiley.imageset/smiley.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Assets.xcassets/smiley.imageset/smiley.png
--------------------------------------------------------------------------------
/SideBarDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | Copyright © 2017 thierryH24. All rights reserved.
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/SideBarDemo/MainWindowController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainWindowController.swift
3 | // iMeteoGraph
4 | //
5 | // Created by thierryH24 on 04/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 | var nameCity = ""
12 |
13 | class MainWindowController: NSWindowController {
14 |
15 | @IBOutlet weak var sourceView: NSView!
16 | @IBOutlet weak var sourceView1: NSView!
17 |
18 | @IBOutlet weak var tableTargetView: NSView!
19 | @IBOutlet weak var splitView: NSSplitView!
20 |
21 | var sideBarViewController1 : THSideBarViewController?
22 | var sideBarViewController2 : THSideBarViewController?
23 |
24 | var contentView1Controller = ContentView1Controller()
25 | var contentView2Controller = ContentView2Controller()
26 | var contentView3Controller = ContentView3Controller()
27 | var contentView4Controller = ContentView4Controller()
28 | var contentView5Controller = ContentView5Controller()
29 | var contentView6Controller = ContentView6Controller()
30 | var contentView7Controller = ContentView7Controller()
31 |
32 | override func windowDidLoad() {
33 | super.windowDidLoad()
34 |
35 | splitView.autosaveName = "splitView"
36 | splitView.minPossiblePositionOfDivider(at: 0)
37 | splitView.maxPossiblePositionOfDivider(at: 999)
38 |
39 | setUpSourceList1()
40 | setUpSourceList2()
41 | }
42 |
43 | func setUpSourceList1()
44 | {
45 | self.sideBarViewController1 = THSideBarViewController()
46 | addSubview(subView: (sideBarViewController1?.view)!, toView: sourceView)
47 |
48 | sideBarViewController1?.delegate = self
49 | sideBarViewController1?.isAllowDragAndDrop = true
50 | sideBarViewController1?.isSaveSection = false
51 | sideBarViewController1?.rowStyle = .medium
52 | sideBarViewController1?.name = "view"
53 |
54 | setUpLayoutConstraints(item: sideBarViewController1!.view, toItem: sourceView)
55 | let sections = initData1()
56 |
57 | sideBarViewController1?.initData( allSection: sections )
58 | sideBarViewController1?.reloadData()
59 | }
60 |
61 | func initData1() -> [Section] {
62 |
63 | var section = [Section]()
64 |
65 | let item1 = Item(name:"ContentView1", icon: "Human_resource", nameView: "ContentView1Controller", badge: "10", colorBadge: .blue)
66 | let item2 = Item(name:"ContentView2", icon: "Human_resource", nameView: "ContentView2Controller", badge: "-5", colorBadge: .red)
67 | let item3 = Item(name:"ContentView3", icon: "employee", nameView: "ContentView3Controller", badge: "3", colorBadge: .blue)
68 | let item4 = Item(name:"ContentView4", icon: "employee", nameView: "ContentView4Controller", badge: "1", colorBadge: .blue)
69 | let item5 = Item(name:"ContentView5", icon: "employee", nameView: "ContentView5Controller", badge: "3", colorBadge: .blue)
70 | let item6 = Item(name:"ContentView6", icon: "employee", nameView: "ContentView6Controller", badge: "8", colorBadge: .blue)
71 | let item7 = Item(name:"ContentView7", icon: "employee", nameView: "ContentView7Controller", badge: "-1", colorBadge: .red)
72 |
73 | let sectionItem = Item(name:"Account1", icon: "Human_resource", nameView: "ContentView1Controller", badge: "10", colorBadge: .blue)
74 | var item = [Item]()
75 | item.append(item1)
76 | item.append(item2)
77 | let section1 = Section(section: sectionItem, item: item)
78 |
79 | var item20 = [Item]()
80 | item20.append(item3)
81 | item20.append(item4)
82 | item20.append(item5)
83 | item20.append(item6)
84 | item20.append(item7)
85 | let sectionItem2 = Item(name:"Account3", icon: "Human_resource", nameView: "ContentView1Controller", badge: "40", colorBadge: .blue)
86 | let section2 = Section(section: sectionItem2, item: item20)
87 |
88 | section.removeAll()
89 | section.append(section1)
90 | section.append(section2)
91 | // sideBarViewController1?.initData( allSection: section )
92 | return section
93 |
94 | }
95 |
96 | func setUpSourceList2()
97 | {
98 | self.sideBarViewController2 = THSideBarViewController()
99 | addSubview(subView: (sideBarViewController2?.view)!, toView: sourceView1)
100 |
101 | sideBarViewController2?.delegate = self
102 | sideBarViewController2?.colorBackGround = #colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1)
103 | sideBarViewController2?.rowStyle = .small
104 | sideBarViewController2?.name = "city"
105 | sideBarViewController2?.isSaveSection = true
106 | sideBarViewController2?.isAllowDragAndDrop = true
107 |
108 | setUpLayoutConstraints(item: sideBarViewController2!.view, toItem: sourceView1)
109 |
110 | var sections = sideBarViewController2?.load()
111 | if sections?.count ?? 0 == 0 {
112 | sections = initData2()
113 | sideBarViewController2?.save()
114 | }
115 | sideBarViewController2?.initData( allSection: sections! )
116 | sideBarViewController2?.reloadData()
117 | }
118 |
119 | func initData2() -> [Section] {
120 |
121 | var section = [Section]()
122 |
123 | sideBarViewController2?.group.title = "City"
124 |
125 | let item1 = Item(name:"London", icon: "Human_resource", nameView: "City", badge: "3", colorBadge: .blue)
126 | item1.isHidden = true
127 |
128 | let item2 = Item(name:"Paris", icon: "employee", nameView: "City", badge: "-8", colorBadge: .red)
129 | item2.isHidden = true
130 |
131 | let item3 = Item(name:"Tokyo", icon: "Human_resource", nameView: "City", badge: "-2", colorBadge: .red)
132 | let item4 = Item(name:"Mexico", icon: "employee", nameView: "City", badge: "0", colorBadge: .blue)
133 | let item5 = Item(name:"Ottawa", icon: "employee", nameView: "City", badge: "0", colorBadge: .blue)
134 | let item6 = Item(name:"Berlin", icon: "employee", nameView: "City", badge: "0", colorBadge: .blue)
135 | let item7 = Item(name:"Madrid", icon: "employee", nameView: "City", badge: "0", colorBadge: .blue)
136 | let item8 = Item(name:"Bruxelles", icon: "employee", nameView: "City", badge: "0", colorBadge: .blue)
137 | let item9 = Item(name:"New Delhi", icon: "employee", nameView: "City", badge: "0", colorBadge: .blue)
138 | let item10 = Item(name:"Washingtown", icon: "employee", nameView: "City", badge: "0", colorBadge: .blue)
139 |
140 | var item = [Item]()
141 | item.append(item1)
142 | item.append(item2)
143 | item.append(item3)
144 | item.append(item4)
145 | item.append(item5)
146 | item.append(item6)
147 | item.append(item7)
148 | item.append(item8)
149 | item.append(item9)
150 | item.append(item10)
151 |
152 | let sectionItem = Item(name:"Cities", icon: "Human_resource", nameView: "ContentView1Controller", badge: "10", colorBadge: .blue)
153 |
154 | item = item.sorted(by: { $0.name < $1.name })
155 | let section1 = Section(section: sectionItem, item: item)
156 |
157 | section.removeAll()
158 | section.append(section1)
159 | // sideBarViewController2?.initData( allSection: section3 )
160 | return section
161 | }
162 |
163 | func addSubview(subView: NSView, toView parentView : NSView)
164 | {
165 | let myView = parentView.subviews
166 | if myView.count > 0
167 | {
168 | parentView.replaceSubview(myView[0], with: subView)
169 | print("replace View : ", subView)
170 | }
171 | else
172 | {
173 | parentView.addSubview(subView)
174 | print("add View : ", subView)
175 | }
176 | }
177 |
178 | func setUpLayoutConstraints(item : NSView, toItem: NSView)
179 | {
180 | item.translatesAutoresizingMaskIntoConstraints = false
181 | let sourceListLayoutConstraints = [
182 | NSLayoutConstraint(item: item, attribute: .left, relatedBy: .equal, toItem: toItem, attribute: .left, multiplier: 1, constant: 0),
183 | NSLayoutConstraint(item: item, attribute: .right, relatedBy: .equal, toItem: toItem, attribute: .right, multiplier: 1, constant: 0),
184 | NSLayoutConstraint(item: item, attribute: .top, relatedBy: .equal, toItem: toItem, attribute: .top, multiplier: 1, constant: 0),
185 | NSLayoutConstraint(item: item, attribute: .bottom, relatedBy: .equal, toItem: toItem, attribute: .bottom, multiplier: 1, constant: 0)]
186 | NSLayoutConstraint.activate(sourceListLayoutConstraints)
187 | }
188 |
189 | @IBAction func ItemPlus(_ sender: Any) {
190 | let account8 = Item(name:"Account 8", icon: "account", nameView: "ContentView4Controller", badge: "5", colorBadge: .blue)
191 | sideBarViewController1?.sections[0].item.append(account8)
192 |
193 | sideBarViewController1?.sidebarOutlineView.sizeLastColumnToFit()
194 | sideBarViewController1?.sidebarOutlineView.reloadData()
195 | }
196 |
197 | @IBAction func buttonBadgeP(_ sender: Any) {
198 | let selectedIndex = 1
199 | let badge = sideBarViewController1?.sections[0].item[selectedIndex - 1].badge
200 | var numBadge = Int(badge!)
201 |
202 | numBadge = numBadge! + 1
203 | sideBarViewController1?.sections[0].item[selectedIndex - 1].badge = String(describing: numBadge!)
204 | sideBarViewController1?.sections[0].item[selectedIndex - 1].colorBadge = numBadge! >= 0 ? .blue : .red
205 |
206 | sideBarViewController1?.sidebarOutlineView.sizeLastColumnToFit()
207 | sideBarViewController1?.sidebarOutlineView.reloadData()
208 |
209 | let item = sideBarViewController1?.sections[0].item[selectedIndex - 1]
210 | sideBarViewController1?.sidebarOutlineView.reloadItem(item)
211 |
212 | sideBarViewController1?.sidebarOutlineView.selectRowIndexes(NSIndexSet(index: selectedIndex ) as IndexSet, byExtendingSelection: false)
213 | }
214 |
215 | @IBAction func buttonBadgeM(_ sender: Any) {
216 | let selectedIndex = 1
217 | let item = sideBarViewController1?.sections[0].item[selectedIndex - 1]
218 | var numBadge = Int((item?.badge)!)
219 |
220 | numBadge = numBadge! - 1
221 | sideBarViewController1?.sections[0].item[selectedIndex - 1].badge = String(describing: numBadge!)
222 | sideBarViewController1?.sections[0].item[selectedIndex - 1].colorBadge = numBadge! >= 0 ? .blue : .red
223 |
224 | sideBarViewController1?.sidebarOutlineView.sizeLastColumnToFit()
225 | sideBarViewController1?.sidebarOutlineView.reloadData()
226 |
227 | sideBarViewController1?.sidebarOutlineView.selectRowIndexes(NSIndexSet(index: selectedIndex ) as IndexSet, byExtendingSelection: false)
228 | }
229 | }
230 |
231 | // just for the debug
232 | extension NSView {
233 |
234 | override open var description: String {
235 | let id = identifier ?? NSUserInterfaceItemIdentifier(rawValue: "view ")
236 | return "id: \(String(describing: id))"
237 | }
238 | }
239 |
240 | extension MainWindowController: THSideBarViewDelegate
241 | {
242 | func changeView(item : Item)
243 | {
244 | var vc = NSView()
245 |
246 | if item.nameView == "City" {
247 |
248 | nameCity = item.name
249 | NotificationCenter.send(.updateView)
250 | return
251 | }
252 |
253 | switch item.nameView
254 | {
255 | case "ContentView1Controller":
256 | vc = contentView1Controller.view
257 |
258 | case "ContentView2Controller":
259 | vc = contentView2Controller.view
260 |
261 | case "ContentView3Controller":
262 | vc = contentView3Controller.view
263 |
264 | case "ContentView4Controller":
265 | vc = contentView4Controller.view
266 |
267 | case "ContentView5Controller":
268 | vc = contentView5Controller.view
269 |
270 | case "ContentView6Controller":
271 | vc = contentView6Controller.view
272 |
273 | case "ContentView7Controller":
274 | vc = contentView7Controller.view
275 |
276 | default:
277 | vc = contentView1Controller.view
278 | }
279 |
280 | addSubview(subView: vc, toView: tableTargetView)
281 | vc.translatesAutoresizingMaskIntoConstraints = false
282 |
283 | var viewBindingsDict = [String: AnyObject]()
284 | viewBindingsDict["vc"] = vc
285 | tableTargetView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[vc]|", options: [], metrics: nil, views: viewBindingsDict))
286 | tableTargetView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[vc]|", options: [], metrics: nil, views: viewBindingsDict))
287 | }
288 | }
289 |
290 |
291 |
292 |
293 |
--------------------------------------------------------------------------------
/SideBarDemo/MainWindowController.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemo/Resource/abundance-church-family.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Resource/abundance-church-family.jpg
--------------------------------------------------------------------------------
/SideBarDemo/Resource/hand-tuning-peg-instrument.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Resource/hand-tuning-peg-instrument.jpg
--------------------------------------------------------------------------------
/SideBarDemo/Resource/mobile-phone-and-headphones-on-white-wooden-table.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Resource/mobile-phone-and-headphones-on-white-wooden-table.jpg
--------------------------------------------------------------------------------
/SideBarDemo/Resource/rayban-ray-bans-spectacles.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Resource/rayban-ray-bans-spectacles.jpg
--------------------------------------------------------------------------------
/SideBarDemo/Resource/record-vinyl-turntable.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Resource/record-vinyl-turntable.jpg
--------------------------------------------------------------------------------
/SideBarDemo/Resource/vintage-radio-on-glass-table.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Resource/vintage-radio-on-glass-table.jpg
--------------------------------------------------------------------------------
/SideBarDemo/Resource/woman-writing-in-music-sheet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thierryH91200/THSideBar/ae134d8e9a05363c0a53a81d4dcb61dc7194bc2d/SideBarDemo/Resource/woman-writing-in-music-sheet.jpg
--------------------------------------------------------------------------------
/SideBarDemo/SideBarDemo.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/SideBarDemo/View/CommunController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CommunController.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierry hentic on 14/07/2019.
6 | // Copyright © 2019 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class CommunController
13 | {
14 | static let shared = CommunController()
15 |
16 | func initLayer( titleView: NSView, textLayer: CATextLayer) {
17 |
18 | let titleView = titleView
19 | let textLayer = textLayer
20 |
21 | let layer = CALayer()
22 | layer.frame = titleView.frame
23 | layer.backgroundColor = NSColor.clear.cgColor
24 | titleView.layer = layer
25 | titleView.wantsLayer = true
26 | layer.layoutManager = CAConstraintLayoutManager()
27 |
28 | textLayer.frame = layer.frame
29 | textLayer.string = ""
30 | textLayer.font = "Menlo" as CFTypeRef
31 | textLayer.fontSize = 32.0
32 | textLayer.shadowOpacity = 0.5
33 | textLayer.allowsFontSubpixelQuantization = true
34 | textLayer.foregroundColor = CGColor(red: 13.0/255.0, green: 116.0/255.0, blue: 1.0, alpha: 1.0)
35 |
36 | textLayer.addConstraint(constraint(attribute: .midX, relativeTo: "superlayer", attribute2: .midX))
37 | textLayer.addConstraint(constraint(attribute: .midY, relativeTo: "superlayer", attribute2: .midY))
38 |
39 | layer.addSublayer(textLayer)
40 | }
41 |
42 | func constraint(attribute: CAConstraintAttribute, relativeTo: String, attribute2: CAConstraintAttribute) -> CAConstraint
43 | {
44 | return CAConstraint(attribute: attribute, relativeTo: relativeTo, attribute: attribute2)
45 | }
46 |
47 | }
48 |
49 | extension NotificationCenter {
50 |
51 | /// Send(Post) Notification
52 | static func send(_ key: Notification.Name) {
53 | self.default.post(
54 | name: key,
55 | object: nil
56 | )
57 | }
58 |
59 | /// Receive(addObserver) Notification
60 | static func receive(instance: Any, name: Notification.Name, selector: Selector) {
61 | self.default.addObserver(
62 | instance,
63 | selector: selector,
64 | name: name,
65 | object: nil
66 | )
67 | }
68 |
69 | /// Remove(removeObserver) Notification
70 | static func remove( instance: Any, name: Notification.Name ) {
71 | self.default.removeObserver(
72 | instance,
73 | name: name,
74 | object: nil
75 | )
76 | }
77 |
78 | }
79 |
80 | public extension Notification.Name {
81 |
82 | static let updateView = Notification.Name( "updateView")
83 | }
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView1Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView1Controller.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 16/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class ContentView1Controller: NSViewController {
13 |
14 | @IBOutlet weak var titleView: NSView!
15 |
16 | let textLayer = CATextLayer()
17 | let nameView = "View1 : "
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do view setup here.
22 |
23 | NotificationCenter.receive(instance: self, name: .updateView, selector: #selector(UpdateView(_: )))
24 | CommunController.shared.initLayer(titleView: titleView, textLayer: textLayer)
25 | UpdateView(Notification(name: .updateView))
26 | }
27 |
28 | @objc func UpdateView(_ notification: Notification) {
29 | textLayer.string = nameView + nameCity
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView1Controller.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView2Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView2Controller.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 16/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class ContentView2Controller: NSViewController {
13 |
14 | @IBOutlet weak var titleView: NSView!
15 |
16 | let textLayer = CATextLayer()
17 | let nameView = "View2 : "
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do view setup here.
22 |
23 | NotificationCenter.receive(instance: self, name: .updateView, selector: #selector(UpdateView(_: )))
24 | CommunController.shared.initLayer(titleView: titleView, textLayer: textLayer)
25 | UpdateView(Notification(name: .updateView))
26 | }
27 |
28 | @objc func UpdateView(_ notification: Notification) {
29 | textLayer.string = nameView + nameCity
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView2Controller.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView3Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView3Controller.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 16/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class ContentView3Controller: NSViewController {
13 |
14 | @IBOutlet weak var titleView: NSView!
15 |
16 | let textLayer = CATextLayer()
17 | let nameView = "View3 : "
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do view setup here.
22 |
23 | NotificationCenter.receive(instance: self, name: .updateView, selector: #selector(UpdateView(_: )))
24 | CommunController.shared.initLayer(titleView: titleView, textLayer: textLayer)
25 | UpdateView(Notification(name: .updateView))
26 | }
27 |
28 | @objc func UpdateView(_ notification: Notification) {
29 | textLayer.string = nameView + nameCity
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView3Controller.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView4Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView4Controller.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 16/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class ContentView4Controller: NSViewController {
13 |
14 | @IBOutlet weak var titleView: NSView!
15 |
16 | let textLayer = CATextLayer()
17 | let nameView = "View4 : "
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do view setup here.
22 |
23 | NotificationCenter.receive(instance: self, name: .updateView, selector: #selector(UpdateView(_: )))
24 | CommunController.shared.initLayer(titleView: titleView, textLayer: textLayer)
25 | UpdateView(Notification(name: .updateView))
26 | }
27 |
28 | @objc func UpdateView(_ notification: Notification) {
29 | textLayer.string = nameView + nameCity
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView4Controller.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView5Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView5Controller.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 16/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class ContentView5Controller: NSViewController {
13 |
14 | @IBOutlet weak var titleView: NSView!
15 |
16 | let textLayer = CATextLayer()
17 | let nameView = "View5 : "
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do view setup here.
22 |
23 | NotificationCenter.receive(instance: self, name: .updateView, selector: #selector(UpdateView(_: )))
24 | CommunController.shared.initLayer(titleView: titleView, textLayer: textLayer)
25 | UpdateView(Notification(name: .updateView))
26 | }
27 |
28 | @objc func UpdateView(_ notification: Notification) {
29 | textLayer.string = nameView + nameCity
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView5Controller.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView6Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView6Controller.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 16/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class ContentView6Controller: NSViewController {
13 |
14 | @IBOutlet weak var titleView: NSView!
15 |
16 | let textLayer = CATextLayer()
17 | let nameView = "View6 : "
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do view setup here.
22 |
23 | NotificationCenter.receive(instance: self, name: .updateView, selector: #selector(UpdateView(_: )))
24 | CommunController.shared.initLayer(titleView: titleView, textLayer: textLayer)
25 | UpdateView(Notification(name: .updateView))
26 | }
27 |
28 | @objc func UpdateView(_ notification: Notification) {
29 | textLayer.string = nameView + nameCity
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView6Controller.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView7Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView7Controller.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 16/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class ContentView7Controller: NSViewController {
13 |
14 | @IBOutlet weak var titleView: NSView!
15 |
16 | let textLayer = CATextLayer()
17 | let nameView = "View7 : "
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do view setup here.
22 |
23 | NotificationCenter.receive(instance: self, name: .updateView, selector: #selector(UpdateView(_: )))
24 | CommunController.shared.initLayer(titleView: titleView, textLayer: textLayer)
25 | UpdateView(Notification(name: .updateView))
26 | }
27 |
28 | @objc func UpdateView(_ notification: Notification) {
29 | textLayer.string = nameView + nameCity
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SideBarDemo/View/ContentView7Controller.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/SideBarDemoTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SideBarDemoTests/SideBarDemoTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarDemoTests.swift
3 | // SideBarDemoTests
4 | //
5 | // Created by thierryH24 on 01/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import SideBarDemo
11 |
12 | class SideBarDemoTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/SideBarDemoUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SideBarDemoUITests/SideBarDemoUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarDemoUITests.swift
3 | // SideBarDemoUITests
4 | //
5 | // Created by thierryH24 on 01/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class SideBarDemoUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/THSideBar/THSideBarCellView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SidebarTableCellView.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 01/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | class KSHeaderCellView : NSTableCellView {
13 |
14 | var fillColor = #colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1)
15 |
16 | override func draw(_ dirtyRect: NSRect) {
17 |
18 | super.draw(dirtyRect)
19 | }
20 | }
21 |
22 | class THSideBarCellView: NSTableCellView {
23 |
24 | var attribut = [NSAttributedString.Key : Any] ()
25 |
26 | var backgroundColor : CGColor = NSColor.green.cgColor
27 | var cornerRadius : CGFloat = 8.0
28 | var title = "0"
29 | var foregroundColor = NSColor.white
30 | var font = NSFont(name: "Avenir", size: 10.0)!
31 |
32 | @IBOutlet var button: NSButton!
33 |
34 | override func draw(_ dirtyRect: NSRect) {
35 | super.draw(dirtyRect)
36 |
37 | // Drawing code here.
38 | }
39 |
40 | // The standard rowSizeStyle does some specific layout for us. To customize layout for our button, we first call super and then modify things
41 | // Overlapping accesses to 'textFrame', but modification requires exclusive access; consider copying to a local variable
42 | override func viewWillDraw() {
43 | super.viewWillDraw()
44 | if button.isHidden == false
45 | {
46 | button.wantsLayer = true
47 | button.layer?.backgroundColor = backgroundColor
48 | button.layer?.cornerRadius = cornerRadius
49 |
50 | let paragraph = NSMutableParagraphStyle()
51 | paragraph.alignment = .center
52 | attribut[ .font] = font
53 | attribut[ .paragraphStyle] = paragraph
54 | attribut[ .foregroundColor] = foregroundColor
55 |
56 | let attributText = NSMutableAttributedString(string: title)
57 | attributText.setAttributes(attribut, range: NSMakeRange(0, attributText.length))
58 | button.attributedTitle = attributText
59 |
60 | button.sizeToFit()
61 | var buttonFrame = button.frame
62 | buttonFrame.origin.x = self.frame.width - buttonFrame.width
63 | button.frame = buttonFrame
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/THSideBar/THSideBarData.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarData.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 25/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 | public class Item : Codable {
12 |
13 | var name: String
14 | var nameView: String
15 | var icon : String
16 | var badge: String
17 | var colorBadge : NSColor
18 | var isHidden : Bool
19 |
20 | init(name: String, icon: String, nameView : String, badge : String, colorBadge : NSColor) {
21 | self.name = name
22 | self.nameView = nameView
23 | self.icon = icon
24 | self.badge = badge
25 | self.colorBadge = colorBadge
26 | self.isHidden = false
27 | }
28 |
29 | enum CodingKeys: String, CodingKey {
30 | case name = "name"
31 | case nameView = "nameView"
32 | case icon = "icon"
33 | case badge = "badge"
34 | case colorBadge = "colorBadge"
35 | case isHidden = "isHidden"
36 | }
37 |
38 | required public init(from decoder: Decoder) throws {
39 | let container = try decoder.container(keyedBy: CodingKeys.self)
40 | name = try container.decode(String.self, forKey: .name)
41 | nameView = try container.decode(String.self, forKey: .nameView)
42 | badge = try container.decode(String.self, forKey: .badge)
43 | icon = try container.decode(String.self, forKey: .icon)
44 | colorBadge = try container.decode(Color.self, forKey: .colorBadge).uiColor
45 | isHidden = try container.decode(Bool.self, forKey: .isHidden)
46 | }
47 |
48 | public func encode(to encoder: Encoder) throws {
49 | var container = encoder.container(keyedBy: CodingKeys.self)
50 | try container.encode(name, forKey: .name)
51 | try container.encode(nameView, forKey: .nameView)
52 | try container.encode(icon, forKey: .icon)
53 | try container.encode(badge, forKey: .badge)
54 | try container.encode(Color(uiColor: colorBadge), forKey: .colorBadge)
55 | try container.encode(isHidden, forKey: .isHidden)
56 | }
57 | }
58 |
59 | class Section : Codable {
60 |
61 | var section : Item
62 | var item : [Item]
63 |
64 | init(section: Item, item: [Item]) {
65 | self.section = section
66 | self.item = item
67 | }
68 |
69 | enum CodingKeys: String, CodingKey {
70 | case item = "item"
71 | case section = "section"
72 | }
73 |
74 | }
75 |
76 | public class Color : Codable {
77 | var red : CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, alpha: CGFloat = 0.0
78 |
79 | var uiColor : NSColor {
80 | return NSColor(red: red, green: green, blue: blue, alpha: alpha)
81 | }
82 |
83 | init(uiColor : NSColor) {
84 | uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
85 | }
86 | }
87 |
88 | extension Section: Equatable {
89 | static func == (lhs: Section, rhs: Section) -> Bool {
90 | return lhs.section.name == rhs.section.name &&
91 | lhs.section.nameView == rhs.section.nameView &&
92 | lhs.section.icon == rhs.section.icon
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/THSideBar/THSideBarDataSource.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarDataSource.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 25/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 | extension THSideBarViewController: NSOutlineViewDataSource {
12 |
13 | /// Number of items in the sidebar
14 | func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
15 |
16 | var count = 0
17 | if item == nil {
18 | //at root
19 | count = sections.count
20 | } else {
21 | let section = item as! Section
22 | count = section.item.count
23 | }
24 | return count
25 | }
26 |
27 | /// Returns the child item at the specified index of a given item
28 | func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
29 |
30 | if item == nil {
31 | return sections[index]
32 | } else {
33 | let section = item as! Section
34 | return section.item[index]
35 |
36 | }
37 | }
38 |
39 | /// Whether rows are expandable by an arrow
40 | func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
41 | if let section = item as? Section {
42 | return section.item.count > 0
43 | } else {
44 | return false
45 | }
46 | }
47 |
48 | func isSourceGroupItem(_ item: Any) -> Bool
49 | {
50 | if item is Section {
51 | return true
52 | }
53 | return false
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/THSideBar/THSideBarDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarDelegate.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 25/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | public protocol THSideBarViewDelegate : class
13 | {
14 | /// Called when a value has been selected inside the outline.
15 | func changeView( item : Item)
16 | }
17 |
18 | extension THSideBarViewController: NSOutlineViewDelegate {
19 |
20 |
21 | /// When a row is clicked on should it be selected
22 | public func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool
23 | {
24 | return !isSourceGroupItem(item)
25 | }
26 |
27 | /// Height of each row
28 | func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
29 | if isSourceGroupItem(item) == true {
30 | return 30.0
31 | }
32 | return 20.0
33 | }
34 |
35 | /// Whether a row should be collapsed
36 | func outlineView(_ outlineView: NSOutlineView, shouldCollapseItem item: Any) -> Bool {
37 | return isSourceGroupItem(item)
38 | }
39 |
40 | func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
41 |
42 | if let section = item as? Section
43 | {
44 | let cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "FeedCellHeader"), owner: self) as! KSHeaderCellView
45 |
46 | // cell.fillColor = self.colorBackGround
47 | cell.wantsLayer = true
48 | cell.layer?.backgroundColor = self.colorBackGround.cgColor
49 |
50 |
51 | cell.textField!.stringValue = section.section.name.uppercased()
52 | // cell.imageView!.image = section.icon
53 | return cell
54 | }
55 | else if let account = item as? Item
56 | {
57 | let cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "FeedCell"), owner: self) as? THSideBarCellView
58 |
59 | // cell?.imageView!.image = account.icon
60 | // cell?.backgroundColor = account.colorBadge.cgColor
61 |
62 |
63 | var attribut = [NSAttributedString.Key : Any]()
64 | attribut[.foregroundColor] = NSColor.gray
65 | attribut[ .font] = NSFont.boldSystemFont(ofSize: 12.0)
66 | let attributText = NSMutableAttributedString(string: account.name )
67 | attributText.setAttributes(attribut, range: NSMakeRange(0, attributText.length))
68 |
69 | cell?.textField!.delegate = self
70 | cell?.textField!.attributedStringValue = attributText
71 | cell?.textField!.textColor = colorText
72 |
73 | cell?.button.isHidden = account.isHidden
74 | cell?.title = account.badge
75 | // cell?.backgroundColor = account.colorBadge.cgColor
76 |
77 | cell?.button?.bezelStyle = .inline // Make it appear as a normal label and not a button
78 | cell?.needsDisplay = true
79 | return cell
80 | }
81 | return nil
82 | }
83 |
84 | public func outlineViewSelectionDidChange(_ notification: Notification)
85 | {
86 | guard let outlineView = notification.object as? NSOutlineView else { return }
87 |
88 | let selectedIndex = outlineView.selectedRow
89 | if let item = outlineView.item(atRow: selectedIndex) as? Item
90 | {
91 | delegate?.changeView( item : item)
92 | }
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/THSideBar/THSideBarDragDrop.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarDataSource.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 25/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | extension THSideBarViewController: NSPasteboardItemDataProvider {
13 |
14 | func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
15 |
16 | let pbItem = NSPasteboardItem()
17 | if let playlist = item as? Item {
18 |
19 | pbItem.setString(playlist.name, forType: NSPasteboard.PasteboardType.string)
20 | return pbItem
21 | }
22 | return nil
23 | }
24 |
25 | func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItems draggedItems: [Any]) {
26 | draggedNode = draggedItems[0] as AnyObject?
27 | session.draggingPasteboard.setData(Data(), forType: NSPasteboard.PasteboardType(rawValue: REORDER_PASTEBOARD_TYPE))
28 | debugPrint("Drag session begin")
29 | }
30 |
31 | func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
32 | debugPrint("Drag session ended")
33 | self.draggedNode = nil
34 | if isSaveSection == true {
35 | save()
36 | }
37 | }
38 |
39 | func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
40 |
41 | let canDrag = index >= 0 //&& item != nil
42 | print(index," ", item)
43 |
44 | if canDrag == true {
45 | return .move
46 | } else {
47 | return NSDragOperation()
48 | }
49 | }
50 |
51 | func outlineView(_ outlineView: NSOutlineView,
52 | acceptDrop info: NSDraggingInfo,
53 | item: Any?,
54 | childIndex index: Int) -> Bool {
55 |
56 | guard (draggedNode is Item) == true else { return false }
57 |
58 | var retVal = false
59 |
60 | let srcItem = draggedNode as! Item
61 | let srcParent = outlineView.parent(forItem: srcItem) as? Section
62 | let fromIndex = sidebarOutlineView.childIndex(forItem: srcItem)
63 |
64 | var toIndex = index
65 | let toParent = item as? Section
66 |
67 | if toParent != nil && srcParent != nil
68 | {
69 | print("")
70 | print("move srcItem : \(srcItem.name)")
71 | print(" srcParent : \(srcParent!.section.name)")
72 | print(" fromIndex : \(fromIndex)")
73 | print("")
74 | print(" toParent : \(toParent!.section.name)")
75 | print(" toIndex : \(toIndex)")
76 |
77 | }
78 | else
79 | {
80 | print("destination or parent is nil")
81 | }
82 |
83 | guard toParent != nil else { return false }
84 |
85 | if (toIndex == NSOutlineViewDropOnItemIndex) // This should never happen, prevented in validateDrop
86 | {
87 | toIndex = 0
88 | }
89 | else if toIndex > fromIndex && srcParent == toParent {
90 | toIndex -= 1
91 | }
92 |
93 | if fromIndex != toIndex || srcParent != toParent
94 | {
95 | self.moveItemAtIndex(fromIndex : fromIndex, oldParent: srcParent, toIndex: toIndex, newParent: toParent)
96 | outlineView.moveItem(at: fromIndex, inParent: srcParent, to: toIndex, inParent: toParent)
97 | retVal = true
98 | }
99 |
100 | print(" returning:\(retVal)")
101 | return retVal
102 | }
103 |
104 | /// NSPasteboardItemDataProvider
105 | func pasteboard(_ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: NSPasteboard.PasteboardType)
106 | {
107 | let s = "Outline Pasteboard Item"
108 | item.setString(s, forType: type)
109 | }
110 |
111 | func moveItemAtIndex( fromIndex: Int, oldParent: Section?, toIndex: Int, newParent: Section?)
112 | {
113 | // var removedSection : Section?
114 | var removedItem : Item?
115 |
116 | let oldParent = oldParent
117 | let newParent = newParent
118 |
119 | if oldParent == nil
120 | {
121 | // removedSection = self.deleteSection(element: allSection, index: fromIndex)
122 | }
123 | else
124 | {
125 | removedItem = oldParent?.item.remove(at: fromIndex)
126 | }
127 |
128 |
129 | if newParent == nil
130 | {
131 | // self.add(section: allSection, element: removedSection! , index: toIndex)
132 | }
133 | else
134 | {
135 | newParent!.item.insert(removedItem! , at: toIndex)
136 | }
137 | }
138 |
139 | }
140 |
141 |
--------------------------------------------------------------------------------
/THSideBar/THSideBarViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarViewController.swift
3 | // iMeteoGraph
4 | //
5 | // Created by thierryH24 on 07/11/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 |
10 | import AppKit
11 |
12 |
13 | class THSideBarViewController: NSViewController {
14 |
15 | @IBOutlet var sidebarOutlineView: JPOutliveView!
16 | @IBOutlet weak var group: NSButton!
17 |
18 | /// delegate to receive events
19 | open weak var delegate: THSideBarViewDelegate?
20 |
21 | var draggedNode:AnyObject? = nil
22 |
23 | var sections = [ Section]()
24 |
25 | var isAllowDragAndDrop = false
26 | var isSaveSection = false
27 | var colorBackGround = #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)
28 | var rowStyle = NSTableView.RowSizeStyle.medium
29 | var colorText = NSColor.black
30 |
31 | var selectIndex = [1]
32 | let Defaults = UserDefaults.standard
33 | var name = ""
34 |
35 | let REORDER_PASTEBOARD_TYPE = "com.outline.item"
36 |
37 | override func viewDidLoad() {
38 | super.viewDidLoad()
39 | // Do view setup here.
40 | }
41 |
42 | override open func viewDidAppear()
43 | {
44 | super.viewDidAppear()
45 |
46 | if isAllowDragAndDrop == true {
47 | // Register for the dropped object types we can accept.
48 | sidebarOutlineView.registerForDraggedTypes([NSPasteboard.PasteboardType(rawValue: REORDER_PASTEBOARD_TYPE)])
49 |
50 | // Disable dragging items from our view to other applications.
51 | sidebarOutlineView.setDraggingSourceOperationMask(NSDragOperation(), forLocal: false)
52 |
53 | // Enable dragging items within and into our view.
54 | sidebarOutlineView.setDraggingSourceOperationMask(NSDragOperation.every, forLocal: true)
55 | }
56 |
57 | sidebarOutlineView.rowSizeStyle = rowStyle
58 |
59 | let index = sidebarOutlineView.row(forItem: 1)
60 | sidebarOutlineView.scrollRowToVisible(index)
61 | sidebarOutlineView.selectRowIndexes(IndexSet(selectIndex), byExtendingSelection: false)
62 | }
63 |
64 | func initData( allSection: [Section]) {
65 | self.sections = allSection
66 | }
67 |
68 | func reloadData() {
69 |
70 | sidebarOutlineView.sizeLastColumnToFit()
71 | sidebarOutlineView.reloadData()
72 | sidebarOutlineView.floatsGroupRows = false
73 |
74 | sidebarOutlineView.rowSizeStyle = rowStyle
75 | sidebarOutlineView.expandItem(nil, expandChildren: true)
76 | sidebarOutlineView.selectRowIndexes(IndexSet(selectIndex), byExtendingSelection: false)
77 | }
78 |
79 |
80 | func load() -> [Section] {
81 | var model = [Section]()
82 | let json = UserDefaults.standard.data(forKey: name)
83 | if let json = json {
84 | do {
85 | let decoder = JSONDecoder()
86 | model = try decoder.decode(Array.self, from: json)
87 | return model
88 | } catch let DecodingError.dataCorrupted(context) {
89 | print(context)
90 | } catch let DecodingError.keyNotFound(key, context) {
91 | print("Key '\(key)' not found:", context.debugDescription)
92 | print("codingPath:", context.codingPath)
93 | } catch let DecodingError.valueNotFound(value, context) {
94 | print("Value '\(value)' not found:", context.debugDescription)
95 | print("codingPath:", context.codingPath)
96 | } catch let DecodingError.typeMismatch(type, context) {
97 | print("Type '\(type)' mismatch:", context.debugDescription)
98 | print("codingPath:", context.codingPath)
99 | } catch {
100 | print("error: ", error)
101 | }
102 | }
103 | return []
104 | }
105 |
106 | func save()
107 | {
108 | do {
109 | let encoder = JSONEncoder()
110 | encoder.outputFormatting = .prettyPrinted
111 |
112 | let data = try encoder.encode(sections)
113 | Defaults.set(data, forKey: name)
114 |
115 | } catch {
116 | print("error: ", error)
117 | }
118 | }
119 | }
120 |
121 | class JPOutliveView : NSOutlineView {
122 |
123 | let kOutlineCellWidth : CGFloat = 30
124 | let kOutlineMinLeftMargin : CGFloat = 25
125 |
126 | override func makeView(withIdentifier identifier: NSUserInterfaceItemIdentifier, owner: Any?) -> NSView? {
127 |
128 | let view = super.makeView(withIdentifier:identifier, owner:owner)
129 |
130 | if identifier == NSOutlineView.disclosureButtonIdentifier
131 | {
132 | if let btnView = view as? NSButton {
133 |
134 | let targetSize = NSSize(width: 20.0, height: 20.0)
135 | let image = NSImage(named: "RightArrow")?.resized(to: targetSize)
136 | let alternateImage = NSImage(named: "DownArrow")?.resized(to: targetSize)
137 |
138 |
139 | btnView.image = image
140 | btnView.alternateImage = alternateImage
141 |
142 | btnView.frame = NSMakeRect(0, 0, 50, 50)
143 | }
144 | }
145 | return view
146 | }
147 |
148 | override func frameOfOutlineCell(atRow row: Int) -> NSRect {
149 | var superFrame = super.frameOfOutlineCell(atRow: row)
150 | superFrame.size.width = 30
151 | return superFrame
152 | }
153 |
154 | override func frameOfCell(atColumn column: Int, row: Int) -> NSRect {
155 | let superFrame = super.frameOfCell(atColumn: column, row: row)
156 |
157 | if (column == 0) {
158 | // expand by kOutlineCellWidth to the left to cancel the indent
159 | var adjustment = kOutlineCellWidth
160 |
161 | // ...but be extra defensive because we have no fucking clue what is going on here
162 | if (superFrame.origin.x - adjustment < kOutlineMinLeftMargin) {
163 | print("adjustment amount is incorrect: adjustment ")
164 | adjustment = max(0, superFrame.origin.x - kOutlineMinLeftMargin);
165 | }
166 | return NSMakeRect(superFrame.origin.x - adjustment, superFrame.origin.y, superFrame.size.width + adjustment, superFrame.size.height)
167 |
168 | }
169 | return superFrame
170 | }
171 |
172 |
173 |
174 | }
175 |
176 | extension NSImage {
177 | func resized(to newSize: NSSize) -> NSImage? {
178 | if let bitmapRep = NSBitmapImageRep(
179 | bitmapDataPlanes: nil, pixelsWide: Int(newSize.width), pixelsHigh: Int(newSize.height),
180 | bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false,
181 | colorSpaceName: .calibratedRGB, bytesPerRow: 0, bitsPerPixel: 0
182 | ) {
183 | bitmapRep.size = newSize
184 | NSGraphicsContext.saveGraphicsState()
185 | NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: bitmapRep)
186 | draw(in: NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height), from: .zero, operation: .copy, fraction: 1.0)
187 | NSGraphicsContext.restoreGraphicsState()
188 |
189 | let resizedImage = NSImage(size: newSize)
190 | resizedImage.addRepresentation(bitmapRep)
191 | return resizedImage
192 | }
193 |
194 | return nil
195 | }
196 | }
197 |
198 |
199 |
200 |
201 |
--------------------------------------------------------------------------------
/THSideBar/THSideBarViewController.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/THSideBar/THTextFieldDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SideBarDataSource.swift
3 | // SideBarDemo
4 | //
5 | // Created by thierryH24 on 25/10/2017.
6 | // Copyright © 2017 thierryH24. All rights reserved.
7 | //
8 |
9 | import AppKit
10 |
11 |
12 | extension THSideBarViewController: NSTextFieldDelegate {
13 |
14 | func controlTextDidEndEditing(_ obj: Notification) {
15 |
16 | let textField = obj.object as! NSTextField
17 | let row = sidebarOutlineView.row(for: textField)
18 | let item = sidebarOutlineView.item(atRow: row)
19 |
20 | if let theItem = item as? Item
21 | {
22 | theItem.name = textField.stringValue
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------