appjam 0.1.8.9 → 0.1.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.pbxproj +114 -0
  2. data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.xcworkspace/xcuserdata/eiffel.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  3. data/lib/appjam/generators/templates/blank/EiffelApplication/AppDelegate.m.tt +13 -1
  4. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/CustomBadge.h +52 -0
  5. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/CustomBadge.m +241 -0
  6. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherItem.h +58 -0
  7. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherItem.m +227 -0
  8. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherPageControl.h +37 -0
  9. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherPageControl.m +117 -0
  10. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherScrollView.h +23 -0
  11. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherScrollView.m +42 -0
  12. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherView.h +70 -0
  13. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherView.m +830 -0
  14. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherViewController.h +38 -0
  15. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MyLauncher/MyLauncherViewController.m +302 -0
  16. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/AESCrypt.h +37 -0
  17. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/AESCrypt.m +50 -0
  18. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/NSData+Base64.h +17 -0
  19. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/NSData+Base64.m +110 -0
  20. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/NSData+CommonCrypto.h +112 -0
  21. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/NSData+CommonCrypto.m +546 -0
  22. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/NSString+Base64.h +15 -0
  23. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/AESCrypt-ObjC/NSString+Base64.m +82 -0
  24. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCCrossHairView.h +16 -0
  25. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCCrossHairView.m +43 -0
  26. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCFrameView.h +55 -0
  27. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCFrameView.m +234 -0
  28. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCIntrospect.h +155 -0
  29. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCIntrospect.m +1654 -0
  30. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCIntrospectSettings.h +56 -0
  31. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCStatusBarOverlay.h +34 -0
  32. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/DCIntrospect/DCStatusBarOverlay.m +107 -0
  33. data/lib/appjam/version.rb +1 -1
  34. metadata +32 -3
@@ -0,0 +1,42 @@
1
+ //
2
+ // MyLauncherScrollView.m
3
+ // @rigoneri
4
+ //
5
+ // Copyright 2010 Rodrigo Neri
6
+ //
7
+ // Licensed under the Apache License, Version 2.0 (the "License");
8
+ // you may not use this file except in compliance with the License.
9
+ // You may obtain a copy of the License at
10
+ //
11
+ // http://www.apache.org/licenses/LICENSE-2.0
12
+ //
13
+ // Unless required by applicable law or agreed to in writing, software
14
+ // distributed under the License is distributed on an "AS IS" BASIS,
15
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ // See the License for the specific language governing permissions and
17
+ // limitations under the License.
18
+ //
19
+
20
+ #import "MyLauncherScrollView.h"
21
+
22
+ @implementation MyLauncherScrollView
23
+
24
+ - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
25
+ {
26
+ [super touchesBegan:touches withEvent:event];
27
+ [[self nextResponder] touchesBegan:touches withEvent:event];
28
+ }
29
+
30
+ - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent *)event
31
+ {
32
+ [super touchesMoved:touches withEvent:event];
33
+ [[self nextResponder] touchesMoved:touches withEvent:event];
34
+ }
35
+
36
+ - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent *)event
37
+ {
38
+ [super touchesEnded:touches withEvent:event];
39
+ [[self nextResponder] touchesEnded:touches withEvent:event];
40
+ }
41
+
42
+ @end
@@ -0,0 +1,70 @@
1
+ //
2
+ // MyLauncherView.h
3
+ // @rigoneri
4
+ //
5
+ // Copyright 2010 Rodrigo Neri
6
+ // Copyright 2011 David Jarrett
7
+ //
8
+ // Licensed under the Apache License, Version 2.0 (the "License");
9
+ // you may not use this file except in compliance with the License.
10
+ // You may obtain a copy of the License at
11
+ //
12
+ // http://www.apache.org/licenses/LICENSE-2.0
13
+ //
14
+ // Unless required by applicable law or agreed to in writing, software
15
+ // distributed under the License is distributed on an "AS IS" BASIS,
16
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ // See the License for the specific language governing permissions and
18
+ // limitations under the License.
19
+ //
20
+
21
+ #import <UIKit/UIKit.h>
22
+ #import "MyLauncherItem.h"
23
+ #import "MyLauncherPageControl.h"
24
+ #import "MyLauncherScrollView.h"
25
+
26
+ @protocol MyLauncherViewDelegate <NSObject>
27
+ -(void)launcherViewItemSelected:(MyLauncherItem*)item;
28
+ -(void)launcherViewDidBeginEditing:(id)sender;
29
+ -(void)launcherViewDidEndEditing:(id)sender;
30
+ @end
31
+
32
+ @interface MyLauncherView : UIView <UIScrollViewDelegate, MyLauncherItemDelegate> {
33
+ UIDeviceOrientation currentOrientation;
34
+ BOOL itemsAdded;
35
+ BOOL editing;
36
+ BOOL dragging;
37
+ BOOL editingAllowed;
38
+ NSInteger numberOfImmovableItems;
39
+
40
+ int columnCount;
41
+ int rowCount;
42
+ CGFloat itemWidth;
43
+ CGFloat itemHeight;
44
+ CGFloat minX;
45
+ CGFloat minY;
46
+ CGFloat paddingX;
47
+ CGFloat paddingY;
48
+ }
49
+
50
+ @property (nonatomic) BOOL editingAllowed;
51
+ @property (nonatomic) NSInteger numberOfImmovableItems;
52
+ @property (nonatomic, strong) id <MyLauncherViewDelegate> delegate;
53
+ @property (nonatomic, strong) MyLauncherScrollView *pagesScrollView;
54
+ @property (nonatomic, strong) MyLauncherPageControl *pageControl;
55
+ @property (nonatomic, strong) NSMutableArray *pages;
56
+
57
+ // Default for animation below is YES
58
+
59
+ -(void)setPages:(NSMutableArray *)pages animated:(BOOL)animated;
60
+ -(void)setPages:(NSMutableArray *)pages numberOfImmovableItems:(NSInteger)items;
61
+ -(void)setPages:(NSMutableArray *)pages numberOfImmovableItems:(NSInteger)items animated:(BOOL)animated;
62
+
63
+ -(void)viewDidAppear:(BOOL)animated;
64
+ -(void)setCurrentOrientation:(UIInterfaceOrientation)newOrientation;
65
+ -(void)layoutLauncher;
66
+ -(void)layoutLauncherAnimated:(BOOL)animated;
67
+ -(int)maxItemsPerPage;
68
+ -(int)maxPages;
69
+
70
+ @end
@@ -0,0 +1,830 @@
1
+ //
2
+ // MyLauncherView.m
3
+ // @rigoneri
4
+ //
5
+ // Copyright 2010 Rodrigo Neri
6
+ // Copyright 2011 David Jarrett
7
+ //
8
+ // Licensed under the Apache License, Version 2.0 (the "License");
9
+ // you may not use this file except in compliance with the License.
10
+ // You may obtain a copy of the License at
11
+ //
12
+ // http://www.apache.org/licenses/LICENSE-2.0
13
+ //
14
+ // Unless required by applicable law or agreed to in writing, software
15
+ // distributed under the License is distributed on an "AS IS" BASIS,
16
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ // See the License for the specific language governing permissions and
18
+ // limitations under the License.
19
+ //
20
+
21
+ #import "MyLauncherView.h"
22
+
23
+ struct NItemLocation {
24
+ NSInteger page;
25
+ NSInteger sindex;
26
+ };
27
+ typedef struct NItemLocation NItemLocation;
28
+
29
+ static const int pControllHeight = 30;
30
+ static const int maxPageCount = 6;
31
+
32
+ /* iPhone */
33
+ static const int maxItemsPageCount = 9;
34
+
35
+ static const int portraitItemWidth = 106;
36
+ static const int portraitItemHeight = 106;
37
+ static const int portraitColumnCount = 3;
38
+ static const int portraitRowCount = 3;
39
+ static const CGFloat portraitItemXStart = 0;
40
+ static const CGFloat portraitItemYStart = 0;
41
+ static const CGFloat portraitXPadding = 0;
42
+ static const CGFloat portraitYPadding = 0;
43
+
44
+ static const int landscapeItemWidth = 96;
45
+ static const int landscapeItemHeight = 96;
46
+ static const int landscapeColumnCount = 5;
47
+ static const int landscapeRowCount = 2;
48
+ static const CGFloat landscapeItemXStart = 0;
49
+ static const CGFloat landscapeItemYStart = 0;
50
+ static const CGFloat landscapeXPadding = 0;
51
+ static const CGFloat landscapeYPadding = 0;
52
+
53
+ /* iPad */
54
+ static const int iPadMaxItemsPageCount = 20;
55
+
56
+ static const int iPadPortraitItemWidth = 122;
57
+ static const int iPadPortraitItemHeight = 122;
58
+ static const int iPadPortraitColumnCount = 4;
59
+ static const int iPadPortraitRowCount = 5;
60
+ static const CGFloat iPadPortraitItemXStart = 58;
61
+ static const CGFloat iPadPortraitItemYStart = 30;
62
+ static const CGFloat iPadPortraitXPadding = 50;
63
+ static const CGFloat iPadPortraitYPadding = 50;
64
+
65
+ static const int iPadLandscapeItemWidth = 112;
66
+ static const int iPadLandscapeItemHeight = 112;
67
+ static const int iPadLandscapeColumnCount = 5;
68
+ static const int iPadLandscapeRowCount = 4;
69
+ static const CGFloat iPadLandscapeItemXStart = 58;
70
+ static const CGFloat iPadLandscapeItemYStart = 30;
71
+ static const CGFloat iPadLandscapeXPadding = 80;
72
+ static const CGFloat iPadLandscapeYPadding = 30;
73
+
74
+ @interface MyLauncherView ()
75
+ -(void)setupCurrentViewLayoutSettings;
76
+ -(void)layoutItems;
77
+ -(void)beginEditing;
78
+ -(void)animateItems;
79
+ -(void)organizePages;
80
+ -(NItemLocation)itemLocation;
81
+ -(BOOL)itemMovable:(MyLauncherItem *)itemToSearch;
82
+ -(void)savePages;
83
+ -(void)saveToUserDefaults:(id)object key:(NSString *)key;
84
+ -(UIDeviceOrientation)currentLayoutOrientation;
85
+ @property (nonatomic, retain) NSTimer *itemHoldTimer;
86
+ @property (nonatomic, retain) NSTimer *movePagesTimer;
87
+ @property (nonatomic, retain) MyLauncherItem *draggingItem;
88
+ @end
89
+
90
+ @implementation MyLauncherView
91
+
92
+ @synthesize editingAllowed, numberOfImmovableItems;
93
+ @synthesize delegate = _delegate;
94
+ @synthesize pagesScrollView = _pageScrollView;
95
+ @synthesize pageControl = _pageControl;
96
+ @synthesize pages = _pages;
97
+ @synthesize itemHoldTimer = _itemHoldTimer;
98
+ @synthesize movePagesTimer = _movePagesTimer;
99
+ @synthesize draggingItem = _draggingItem;
100
+
101
+ #pragma mark - View lifecycle
102
+
103
+ - (id)initWithFrame:(CGRect)frame
104
+ {
105
+ if ((self = [super initWithFrame:frame]))
106
+ {
107
+ dragging = NO;
108
+ editing = NO;
109
+ itemsAdded = NO;
110
+ editingAllowed = YES;
111
+ numberOfImmovableItems = -1;
112
+ [self setupCurrentViewLayoutSettings];
113
+
114
+ [self setPagesScrollView:[[MyLauncherScrollView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height - pControllHeight)]];
115
+ self.pagesScrollView.delegate = self;
116
+ self.pagesScrollView.pagingEnabled = YES;
117
+ self.pagesScrollView.showsHorizontalScrollIndicator = NO;
118
+ self.pagesScrollView.showsVerticalScrollIndicator = NO;
119
+ self.pagesScrollView.alwaysBounceHorizontal = YES;
120
+ self.pagesScrollView.scrollsToTop = NO;
121
+ self.pagesScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
122
+ self.pagesScrollView.delaysContentTouches = YES;
123
+ self.pagesScrollView.multipleTouchEnabled = NO;
124
+ [self addSubview:self.pagesScrollView];
125
+
126
+ [self setPageControl:[[MyLauncherPageControl alloc] initWithFrame:CGRectMake(0, frame.size.height - pControllHeight - 45, frame.size.width, pControllHeight)]]; //if starts landscape this will break...
127
+ self.pageControl.numberOfPages = 1;
128
+ self.pageControl.currentPage = 0;
129
+ self.pageControl.maxNumberOfPages = maxPageCount;
130
+ self.pageControl.backgroundColor = [UIColor clearColor];
131
+ [self.pageControl addTarget:self action:@selector(pageChanged) forControlEvents:UIControlEventValueChanged];
132
+ [self addSubview:self.pageControl];
133
+
134
+ [self addObserver:self forKeyPath:@"frame" options:0 context:nil];
135
+ }
136
+ return self;
137
+ }
138
+
139
+ -(void)viewDidAppear:(BOOL)animated
140
+ {
141
+ [self layoutItems];
142
+ }
143
+
144
+ - (void)dealloc
145
+ {
146
+ [self removeObserver:self forKeyPath:@"frame"];
147
+ }
148
+
149
+ #pragma mark - Setters
150
+
151
+ -(void)setPages:(NSMutableArray *)pages {
152
+ [self setPages:pages animated:YES];
153
+ }
154
+
155
+ -(void)setPages:(NSMutableArray *)pages animated:(BOOL)animated {
156
+ if (pages != _pages) {
157
+ if (_pages) {
158
+ for (NSArray *page in _pages) {
159
+ for (UIView *item in page) {
160
+ [item removeFromSuperview];
161
+ }
162
+ }
163
+ }
164
+
165
+ _pages = pages;
166
+ itemsAdded = NO;
167
+ [self layoutLauncherAnimated:animated];
168
+ }
169
+ }
170
+
171
+ -(void)setPages:(NSMutableArray *)pages numberOfImmovableItems:(NSInteger)items {
172
+ [self setPages:pages numberOfImmovableItems:items animated:YES];
173
+ }
174
+
175
+ -(void)setPages:(NSMutableArray *)pages numberOfImmovableItems:(NSInteger)items animated:(BOOL)animated {
176
+ [self setPages:pages animated:animated];
177
+ [self setNumberOfImmovableItems:items];
178
+ }
179
+
180
+ #pragma mark - View Orientation
181
+
182
+ - (void)setCurrentOrientation:(UIInterfaceOrientation)newOrientation {
183
+ if (newOrientation != currentOrientation &&
184
+ newOrientation != UIDeviceOrientationUnknown &&
185
+ newOrientation != UIDeviceOrientationFaceUp &&
186
+ newOrientation != UIDeviceOrientationFaceDown) {
187
+ currentOrientation = (UIDeviceOrientation)newOrientation;
188
+ }
189
+ }
190
+
191
+ - (UIDeviceOrientation)currentLayoutOrientation {
192
+ UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
193
+ [self setCurrentOrientation:(UIInterfaceOrientation)deviceOrientation];
194
+ return currentOrientation;
195
+ }
196
+
197
+ #pragma mark - ScrollView and PageControl Management
198
+
199
+ - (void)pageChanged
200
+ {
201
+ self.pagesScrollView.contentOffset = CGPointMake(self.pageControl.currentPage * self.pagesScrollView.frame.size.width, 0);
202
+ }
203
+
204
+ - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
205
+ {
206
+ self.pageControl.currentPage = floor((self.pagesScrollView.contentOffset.x - self.pagesScrollView.frame.size.width / 2) /
207
+ self.pagesScrollView.frame.size.width) + 1;
208
+
209
+ }
210
+
211
+ - (void)updateFrames
212
+ {
213
+ self.pagesScrollView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height - pControllHeight);
214
+ self.pageControl.frame = CGRectMake(0, self.frame.size.height - pControllHeight, self.frame.size.width, pControllHeight);
215
+ [self.pageControl setNeedsDisplay];
216
+ }
217
+
218
+ -(void)didChangeValueForKey:(NSString *)key {
219
+ if ([key isEqualToString:@"frame"]) {
220
+ [self updateFrames];
221
+ }
222
+ }
223
+
224
+ #pragma mark - Layout Settings
225
+
226
+ -(int)maxItemsPerPage {
227
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
228
+ return iPadMaxItemsPageCount;
229
+ }
230
+ return maxItemsPageCount;
231
+ }
232
+
233
+ -(int)maxPages {
234
+ return maxPageCount;
235
+ }
236
+
237
+ -(void)setupCurrentViewLayoutSettings {
238
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
239
+ if (UIDeviceOrientationIsLandscape([self currentLayoutOrientation])) {
240
+ minX = iPadLandscapeItemXStart;
241
+ minY = iPadLandscapeItemYStart;
242
+ paddingX = iPadLandscapeXPadding;
243
+ paddingY = iPadLandscapeYPadding;
244
+ columnCount = iPadLandscapeColumnCount;
245
+ rowCount = iPadLandscapeRowCount;
246
+ itemWidth = iPadLandscapeItemWidth;
247
+ itemHeight = iPadLandscapeItemHeight;
248
+ } else {
249
+ minX = iPadPortraitItemXStart;
250
+ minY = iPadPortraitItemYStart;
251
+ paddingX = iPadPortraitXPadding;
252
+ paddingY = iPadPortraitYPadding;
253
+ columnCount = iPadPortraitColumnCount;
254
+ rowCount = iPadPortraitRowCount;
255
+ itemWidth = iPadPortraitItemWidth;
256
+ itemHeight = iPadPortraitItemHeight;
257
+ }
258
+
259
+ } else {
260
+ if (UIDeviceOrientationIsLandscape([self currentLayoutOrientation]))
261
+ {
262
+ minX = landscapeItemXStart;
263
+ minY = landscapeItemYStart;
264
+ paddingX = landscapeXPadding;
265
+ paddingY = landscapeYPadding;
266
+ columnCount = landscapeColumnCount;
267
+ rowCount = landscapeRowCount;
268
+ itemWidth = landscapeItemWidth;
269
+ itemHeight = landscapeItemHeight;
270
+ } else {
271
+ minX = portraitItemXStart;
272
+ minY = portraitItemYStart;
273
+ paddingX = portraitXPadding;
274
+ paddingY = portraitYPadding;
275
+ columnCount = portraitColumnCount;
276
+ rowCount = portraitRowCount;
277
+ itemWidth = portraitItemWidth;
278
+ itemHeight = portraitItemHeight;
279
+ }
280
+ }
281
+ }
282
+
283
+ #pragma mark - Layout Management
284
+
285
+ -(void)layoutLauncher
286
+ {
287
+ [self layoutLauncherAnimated:YES];
288
+ }
289
+
290
+ -(void)layoutLauncherAnimated:(BOOL)animated
291
+ {
292
+ [self updateFrames];
293
+
294
+ [UIView animateWithDuration:animated ? 0.3 : 0
295
+ animations:^{
296
+ [self layoutItems];
297
+ }];
298
+
299
+ [self pageChanged];
300
+ }
301
+
302
+ -(void)layoutItems
303
+ {
304
+ CGFloat pageWidth = self.pagesScrollView.frame.size.width;
305
+
306
+ [self setupCurrentViewLayoutSettings];
307
+
308
+ for (NSMutableArray *page in self.pages)
309
+ {
310
+ CGFloat x = minX;
311
+ CGFloat y = minY;
312
+ int itemsCount = 1;
313
+ for (MyLauncherItem *item in page)
314
+ {
315
+ if(itemsAdded)
316
+ {
317
+ CGRect prevFrame = CGRectMake(x, y, itemWidth, itemHeight);
318
+
319
+ if(!item.dragging)
320
+ {
321
+ item.transform = CGAffineTransformIdentity;
322
+ if(item.frame.origin.x != x || item.frame.origin.y != y)
323
+ item.frame = prevFrame;
324
+ }
325
+ }
326
+ else
327
+ {
328
+ item.frame = CGRectMake(x, y, itemWidth, itemHeight);
329
+ item.delegate = self;
330
+ [item layoutItem];
331
+ [item addTarget:self action:@selector(itemTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside];
332
+ [item addTarget:self action:@selector(itemTouchedUpOutside:) forControlEvents:UIControlEventTouchUpOutside];
333
+ [item addTarget:self action:@selector(itemTouchedDown:) forControlEvents:UIControlEventTouchDown];
334
+ [item addTarget:self action:@selector(itemTouchCancelled:) forControlEvents:UIControlEventTouchCancel];
335
+ [self.pagesScrollView addSubview:item];
336
+ }
337
+ item.closeButton.hidden = editing ? NO : YES;
338
+ x += itemWidth + paddingX;
339
+
340
+ if ( itemsCount % columnCount == 0)
341
+ {
342
+ y += itemHeight + paddingY;
343
+ x = minX;
344
+ }
345
+
346
+ itemsCount++;
347
+ }
348
+
349
+ minX += pageWidth;
350
+ }
351
+
352
+ self.pageControl.numberOfPages = self.pages.count;
353
+ self.pagesScrollView.contentSize = CGSizeMake(self.pagesScrollView.frame.size.width * self.pages.count,
354
+ rowCount * itemHeight);
355
+
356
+ itemsAdded = YES;
357
+ }
358
+
359
+ -(void)organizePages
360
+ {
361
+ int currentPageIndex = 0;
362
+ for(NSMutableArray *page in self.pages)
363
+ {
364
+ int imaxItemsPageCount = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad ? iPadMaxItemsPageCount : maxItemsPageCount;
365
+ if(page.count > imaxItemsPageCount)
366
+ {
367
+ NSInteger nextPageIndex = currentPageIndex+1;
368
+ NSMutableArray *nextPage = [self.pages objectAtIndex:nextPageIndex];
369
+ if(nextPage)
370
+ {
371
+ MyLauncherItem *moveItem = [page lastObject];
372
+ [page removeObject:moveItem];
373
+ [nextPage insertObject:moveItem atIndex:0];
374
+ moveItem = nil;
375
+ }
376
+ else
377
+ {
378
+ [self.pages addObject:[NSMutableArray array]];
379
+ nextPage = [self.pages lastObject];
380
+ MyLauncherItem *moveItem = [page lastObject];
381
+ [page removeObject:moveItem];
382
+ [nextPage addObject:moveItem];
383
+ moveItem = nil;
384
+ }
385
+ }
386
+ currentPageIndex++;
387
+ }
388
+ }
389
+
390
+ #pragma mark - Touch Management
391
+
392
+ -(void)itemTouchedUpInside:(MyLauncherItem *)item
393
+ {
394
+ if(editing)
395
+ {
396
+ dragging = NO;
397
+ [self.draggingItem setDragging:NO];
398
+ self.draggingItem = nil;
399
+ self.pagesScrollView.scrollEnabled = YES;
400
+ [UIView animateWithDuration:0.3
401
+ animations:^{
402
+ [self layoutItems];
403
+ }];
404
+ }
405
+ else
406
+ {
407
+ [self.movePagesTimer invalidate];
408
+ self.movePagesTimer = nil;
409
+ [self.itemHoldTimer invalidate];
410
+ self.itemHoldTimer = nil;
411
+ [[self delegate] launcherViewItemSelected:item];
412
+ self.pagesScrollView.scrollEnabled = YES;
413
+ }
414
+ }
415
+
416
+ -(void)itemTouchedUpOutside:(MyLauncherItem *)item
417
+ {
418
+ [self.movePagesTimer invalidate];
419
+ self.movePagesTimer = nil;
420
+ [self.itemHoldTimer invalidate];
421
+ self.itemHoldTimer = nil;
422
+ dragging = NO;
423
+ [self.draggingItem setDragging:NO];
424
+ self.draggingItem = nil;
425
+ self.pagesScrollView.scrollEnabled = YES;
426
+ [UIView animateWithDuration:0.3
427
+ animations:^{
428
+ [self layoutItems];
429
+ }];
430
+ }
431
+
432
+ -(void)itemTouchedDown:(MyLauncherItem *)item
433
+ {
434
+ if (editing)
435
+ {
436
+ if (!self.draggingItem && [self itemMovable:item])
437
+ {
438
+ self.draggingItem = (MyLauncherItem*)item;
439
+ [self.draggingItem setDragging:YES];
440
+ [self.pagesScrollView addSubview:self.draggingItem];
441
+ dragging = YES;
442
+ }
443
+ }
444
+ else if (editingAllowed)
445
+ {
446
+ [self.itemHoldTimer invalidate];
447
+ self.itemHoldTimer = nil;
448
+
449
+ self.itemHoldTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(itemHoldTimer:) userInfo:item repeats:NO];
450
+ }
451
+ }
452
+
453
+ -(void)itemTouchCancelled:(MyLauncherItem *)item
454
+ {
455
+ if (editing) {
456
+ [self itemTouchedUpInside:item];
457
+ } else {
458
+ [self itemTouchedUpOutside:item];
459
+ }
460
+ }
461
+
462
+ -(void)itemHoldTimer:(NSTimer *)timer
463
+ {
464
+ self.itemHoldTimer = nil;
465
+
466
+ [self beginEditing];
467
+
468
+ MyLauncherItem *heldItem = (MyLauncherItem*)timer.userInfo;
469
+ if ([self itemMovable:heldItem]) {
470
+ self.draggingItem = heldItem;
471
+ [self.draggingItem setSelected:NO];
472
+ [self.draggingItem setHighlighted:NO];
473
+ [self.draggingItem setDragging:YES];
474
+
475
+ [self.pagesScrollView addSubview:self.draggingItem];
476
+ dragging = YES;
477
+ }
478
+ self.pagesScrollView.scrollEnabled = NO;
479
+ }
480
+
481
+ -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
482
+ {
483
+ [super touchesMoved:touches withEvent:event];
484
+
485
+ if(dragging)
486
+ {
487
+ for (UITouch* touch in touches)
488
+ {
489
+ CGPoint location = [touch locationInView:self];
490
+ self.draggingItem.center = CGPointMake(location.x + self.pagesScrollView.contentOffset.x, location.y);
491
+ [self setupCurrentViewLayoutSettings];
492
+
493
+ NItemLocation sItemLocation = [self itemLocation];
494
+ NSInteger page = sItemLocation.page;
495
+ NSInteger sindex = sItemLocation.sindex;
496
+
497
+ CGFloat dragItemX = self.draggingItem.center.x - self.pagesScrollView.contentOffset.x;
498
+ CGFloat dragItemY = self.draggingItem.center.y;
499
+ CGFloat distanceWidth = itemWidth + paddingX;
500
+ CGFloat distanceHeight = itemHeight + paddingY;
501
+
502
+ NSInteger dragItemColumn = floor(dragItemX/distanceWidth); // item width
503
+ NSInteger dragItemRow = floor(dragItemY/distanceHeight); // item height
504
+ NSInteger dragIndex = (dragItemRow * columnCount) + dragItemColumn;
505
+ NSInteger currentPageIndex = floor(self.pagesScrollView.contentOffset.x/self.pagesScrollView.frame.size.width);
506
+
507
+ NSMutableArray *itemPage = [self.pages objectAtIndex:page];
508
+ if(currentPageIndex != page && dragIndex >= [itemPage count])
509
+ {
510
+ dragIndex = 0;
511
+ }
512
+
513
+ if(sindex != dragIndex || (dragIndex == 0 && [itemPage count] == 1 && currentPageIndex != page))
514
+ {
515
+ if (dragIndex < [itemPage count])
516
+ {
517
+ MyLauncherItem *itemToMove = [itemPage objectAtIndex:dragIndex];
518
+ if ([self itemMovable:itemToMove]) {
519
+ [itemPage removeObjectAtIndex:sindex];
520
+
521
+ NSMutableArray *currentPage = [self.pages objectAtIndex:currentPageIndex];
522
+ if(dragIndex > currentPage.count)
523
+ {
524
+ dragIndex = currentPage.count;
525
+ [currentPage insertObject:self.draggingItem atIndex:dragIndex];
526
+ [self organizePages];
527
+ }
528
+ else
529
+ {
530
+ [currentPage insertObject:self.draggingItem atIndex:dragIndex];
531
+ [self organizePages];
532
+ [UIView animateWithDuration:0.3
533
+ animations:^{
534
+ [self layoutItems];
535
+ }];
536
+ }
537
+ }
538
+ }
539
+ }
540
+
541
+ //Moving Pages
542
+ if(location.x + self.pagesScrollView.contentOffset.x < self.pagesScrollView.contentOffset.x + 20)
543
+ {
544
+ if(currentPageIndex > 0)
545
+ {
546
+ if(!self.movePagesTimer)
547
+ [self setMovePagesTimer:[NSTimer scheduledTimerWithTimeInterval:0.7
548
+ target:self
549
+ selector:@selector(movePagesTimer:)
550
+ userInfo:@"left"
551
+ repeats:NO]];
552
+ }
553
+ }
554
+ else if(location.x + self.pagesScrollView.contentOffset.x > self.pagesScrollView.contentOffset.x + self.pagesScrollView.frame.size.width - 20)
555
+ {
556
+ if(!self.movePagesTimer)
557
+ [self setMovePagesTimer:[NSTimer scheduledTimerWithTimeInterval:0.7
558
+ target:self
559
+ selector:@selector(movePagesTimer:)
560
+ userInfo:@"right"
561
+ repeats:NO]];
562
+ }
563
+ else
564
+ {
565
+ [self.movePagesTimer invalidate];
566
+ self.movePagesTimer = nil;
567
+ }
568
+ }
569
+ }
570
+ }
571
+
572
+ -(void)movePagesTimer:(NSTimer*)timer
573
+ {
574
+ self.movePagesTimer = nil;
575
+
576
+ if([(NSString*)timer.userInfo isEqualToString:@"right"])
577
+ {
578
+ CGFloat newX = self.pagesScrollView.contentOffset.x + self.pagesScrollView.frame.size.width;
579
+
580
+ NSInteger currentPageIndex = floor(newX/self.pagesScrollView.frame.size.width);
581
+ if(currentPageIndex + 1 > self.pages.count)
582
+ {
583
+ if(self.pages.count <= maxPageCount)
584
+ {
585
+ [self.pages addObject:[NSMutableArray array]];
586
+ self.pageControl.numberOfPages = self.pages.count;
587
+ }
588
+ }
589
+ self.pageControl.currentPage = currentPageIndex;
590
+
591
+ CGPoint offset = CGPointMake(newX, 0);
592
+ [UIView animateWithDuration:0.3 animations:^{
593
+ [self.pagesScrollView setContentOffset:offset];
594
+ self.draggingItem.frame = CGRectMake(self.draggingItem.frame.origin.x + self.pagesScrollView.frame.size.width,
595
+ self.draggingItem.frame.origin.y,
596
+ self.draggingItem.frame.size.width,
597
+ self.draggingItem.frame.size.height);
598
+ }];
599
+ }
600
+ else if([(NSString*)timer.userInfo isEqualToString:@"left"])
601
+ {
602
+ NSInteger currentPageIndex = floor(self.pagesScrollView.contentOffset.x/self.pagesScrollView.frame.size.width);
603
+ self.pageControl.currentPage = --currentPageIndex;
604
+ CGFloat newX = self.pagesScrollView.contentOffset.x - self.pagesScrollView.frame.size.width;
605
+ CGPoint offset = CGPointMake(newX, 0);
606
+ [UIView animateWithDuration:0.3 animations:^{
607
+ [self.pagesScrollView setContentOffset:offset];
608
+ self.draggingItem.frame = CGRectMake(self.draggingItem.frame.origin.x - self.pagesScrollView.frame.size.width,
609
+ self.draggingItem.frame.origin.y,
610
+ self.draggingItem.frame.size.width,
611
+ self.draggingItem.frame.size.height);
612
+ }];
613
+ }
614
+ }
615
+
616
+ -(NItemLocation)itemLocation
617
+ {
618
+ NItemLocation i;
619
+
620
+ int itemPage = 0;
621
+ for (NSMutableArray *page in self.pages)
622
+ {
623
+ int itemOrder = 0;
624
+ for (MyLauncherItem *item in page)
625
+ {
626
+ if(item == self.draggingItem)
627
+ {
628
+ i.page = itemPage;
629
+ i.sindex = itemOrder;
630
+ return i;
631
+ }
632
+ itemOrder++;
633
+ }
634
+
635
+ itemPage++;
636
+ }
637
+ i.page = 0;
638
+ i.sindex = 0;
639
+
640
+ return i;
641
+ }
642
+
643
+ #pragma mark -
644
+ #pragma mark Editing Management
645
+
646
+ -(void)beginEditing
647
+ {
648
+ if(editing)
649
+ return;
650
+
651
+ editing = YES;
652
+
653
+ if(self.pages.count <= maxPageCount)
654
+ {
655
+ [self.pages addObject:[NSMutableArray array]];
656
+ self.pageControl.numberOfPages = self.pages.count;
657
+ self.pagesScrollView.contentSize = CGSizeMake(self.pages.count*self.pagesScrollView.frame.size.width,
658
+ self.pagesScrollView.frame.size.height);
659
+ }
660
+
661
+ [self animateItems];
662
+ [[self delegate] launcherViewDidBeginEditing:self];
663
+ }
664
+
665
+ -(void)endEditing
666
+ {
667
+ editing = NO;
668
+ self.pagesScrollView.scrollEnabled = YES;
669
+
670
+ for (int i = 0; i < self.pages.count; ++i)
671
+ {
672
+ NSArray* itemPage = [self.pages objectAtIndex:i];
673
+ if(itemPage.count == 0)
674
+ {
675
+ [self.pages removeObjectAtIndex:i];
676
+ --i;
677
+ }
678
+ else
679
+ {
680
+ for (MyLauncherItem* item in itemPage)
681
+ item.transform = CGAffineTransformIdentity;
682
+ }
683
+ }
684
+
685
+ self.pageControl.numberOfPages = self.pages.count;
686
+ self.pagesScrollView.contentSize = CGSizeMake(self.pagesScrollView.frame.size.width * self.pages.count,
687
+ self.pagesScrollView.frame.size.height);
688
+
689
+ [self layoutItems];
690
+ [self savePages];
691
+ [[self delegate] launcherViewDidEndEditing:self];
692
+ }
693
+
694
+ -(void)animateItems
695
+ {
696
+ static BOOL animatesLeft = NO;
697
+
698
+ if (editing)
699
+ {
700
+ CGAffineTransform animateUp = CGAffineTransformMakeScale(1.0, 1.0);
701
+ CGAffineTransform animateDown = CGAffineTransformMakeScale(0.9, 0.9);
702
+
703
+ [UIView beginAnimations:nil context:nil];
704
+
705
+ NSInteger i = 0;
706
+ NSInteger animatingItems = 0;
707
+ for (NSArray* itemPage in self.pages)
708
+ {
709
+ for (MyLauncherItem* item in itemPage)
710
+ {
711
+ item.closeButton.hidden = !editing;
712
+ if (item != self.draggingItem && [self itemMovable:item])
713
+ {
714
+ ++animatingItems;
715
+ if (i % 2)
716
+ item.transform = animatesLeft ? animateDown : animateUp;
717
+ else
718
+ item.transform = animatesLeft ? animateUp : animateDown;
719
+ }
720
+ ++i;
721
+ }
722
+ }
723
+
724
+ if (animatingItems >= 1)
725
+ {
726
+ [UIView setAnimationDuration:0.05];
727
+ [UIView setAnimationDelegate:self];
728
+ [UIView setAnimationDidStopSelector:@selector(animateItems)];
729
+ animatesLeft = !animatesLeft;
730
+ }
731
+ else
732
+ {
733
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
734
+ [self performSelector:@selector(animateItems) withObject:nil afterDelay:0.05];
735
+ }
736
+
737
+ [UIView commitAnimations];
738
+ }
739
+ }
740
+
741
+ -(void)didDeleteItem:(id)item
742
+ {
743
+ MyLauncherItem *ditem = (MyLauncherItem*)item;
744
+
745
+ for (NSMutableArray *page in self.pages)
746
+ {
747
+ int i = 0;
748
+ for (MyLauncherItem *aitem in page)
749
+ {
750
+ if(aitem == ditem)
751
+ {
752
+ if (i < numberOfImmovableItems)
753
+ numberOfImmovableItems--;
754
+ [page removeObjectAtIndex:i];
755
+ [UIView animateWithDuration:0.3
756
+ animations:^{
757
+ [self layoutItems];
758
+ }];
759
+ return;
760
+ }
761
+ i++;
762
+ }
763
+ }
764
+ }
765
+
766
+ -(BOOL)itemMovable:(MyLauncherItem *)itemToSearch
767
+ {
768
+ int count = 0;
769
+ for (NSMutableArray *page in self.pages) {
770
+ if ([page containsObject:itemToSearch]) {
771
+ count = count + [page indexOfObject:itemToSearch];
772
+ if (count >= numberOfImmovableItems) {
773
+ break;
774
+ }
775
+ return NO;
776
+ } else {
777
+ count = count + [page count];
778
+ if (count >= numberOfImmovableItems) {
779
+ break;
780
+ } if ([page count] < maxItemsPageCount) {
781
+ numberOfImmovableItems = [page count];
782
+ break;
783
+ }
784
+ }
785
+ }
786
+ return YES;
787
+ }
788
+
789
+ #pragma mark - myLauncher caching
790
+
791
+ -(void)savePages
792
+ {
793
+ NSMutableArray *pagesToSave = [[NSMutableArray alloc] init];
794
+
795
+ for(NSArray *page in self.pages)
796
+ {
797
+ NSMutableArray *pageToSave = [[NSMutableArray alloc] init];
798
+
799
+ for(MyLauncherItem *item in page)
800
+ {
801
+ NSMutableDictionary *itemToSave = [[NSMutableDictionary alloc] init];
802
+ [itemToSave setObject:item.title forKey:@"title"];
803
+ [itemToSave setObject:item.image forKey:@"image"];
804
+ [itemToSave setObject:item.iPadImage forKey:@"iPadImage"];
805
+ [itemToSave setObject:[NSString stringWithFormat:@"%d", [item deletable]] forKey:@"deletable"];
806
+ [itemToSave setObject:item.controllerStr forKey:@"controller"];
807
+ [itemToSave setObject:item.controllerTitle forKey:@"controllerTitle"];
808
+ [itemToSave setObject:[NSNumber numberWithInt:2] forKey:@"myLauncherViewItemVersion"];
809
+
810
+ [pageToSave addObject:itemToSave];
811
+ }
812
+ [pagesToSave addObject:pageToSave];
813
+ }
814
+
815
+ [self saveToUserDefaults:pagesToSave key:@"myLauncherView"];
816
+ [self saveToUserDefaults:[NSNumber numberWithInt:numberOfImmovableItems] key:@"myLauncherViewImmovable"];
817
+ }
818
+
819
+ -(void)saveToUserDefaults:(id)object key:(NSString *)key
820
+ {
821
+ NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
822
+
823
+ if (standardUserDefaults)
824
+ {
825
+ [standardUserDefaults setObject:object forKey:key];
826
+ [standardUserDefaults synchronize];
827
+ }
828
+ }
829
+
830
+ @end