appjam 0.1.8.9 → 0.1.8.10

Sign up to get free protection for your applications and to get access to all the features.
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