Welcome to mirror list, hosted at ThFree Co, Russian Federation.

MWMBottomMenuViewController.mm « BottomMenu « UI « Maps « iphone - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3c621687d671fe610321afec1985a30e6dcccea5 (plain)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
#import "MWMBottomMenuViewController.h"
#import <Pushwoosh/PushNotificationManager.h>
#import "EAGLView.h"
#import "MWMActivityViewController.h"
#import "MWMBottomMenuCollectionViewCell.h"
#import "MWMBottomMenuControllerProtocol.h"
#import "MWMBottomMenuLayout.h"
#import "MWMBottomMenuView.h"
#import "MWMButton.h"
#import "MWMCommon.h"
#import "MWMFrameworkListener.h"
#import "MWMFrameworkObservers.h"
#import "MWMLocationManager.h"
#import "MWMMapViewControlsManager.h"
#import "MWMRouter.h"
#import "MWMSearchManager.h"
#import "MWMSettingsViewController.h"
#import "MWMTextToSpeech.h"
#import "MapViewController.h"
#import "MapsAppDelegate.h"
#import "Statistics.h"
#import "SwiftBridge.h"
#import "UIImageView+Coloring.h"
#import "UIViewController+Navigation.h"

#import "3party/Alohalytics/src/alohalytics_objc.h"

#include "Framework.h"

#include "platform/mwm_version.hpp"

extern NSString * const kAlohalyticsTapEventKey;
extern NSString * const kSearchStateKey;

namespace
{
CGFloat constexpr kLayoutThreshold = 420.0;
}  // namespace

typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) {
  MWMBottomMenuViewCellAddPlace,
  MWMBottomMenuViewCellDownload,
  MWMBottomMenuViewCellSettings,
  MWMBottomMenuViewCellShare,
  MWMBottomMenuViewCellCount
};

@interface MWMMapViewControlsManager ()

@property(nonatomic) MWMBottomMenuViewController * menuController;

@end

@interface MWMBottomMenuViewController ()<UICollectionViewDataSource, UICollectionViewDelegate,
                                          MWMNavigationDashboardObserver, MWMSearchManagerObserver>

@property(nonatomic) MWMBottomMenuState restoreState;
@property(nonatomic) MWMDimBackground * dimBackground;
@property(nonatomic, readonly) NSUInteger additionalButtonsCount;
@property(weak, nonatomic) IBOutlet MWMButton * searchButton;
@property(weak, nonatomic) IBOutlet NSLayoutConstraint * mainButtonsHeight;
@property(weak, nonatomic) IBOutlet UICollectionView * additionalButtons;
@property(weak, nonatomic) MapViewController * controller;
@property(weak, nonatomic) id<MWMBottomMenuControllerProtocol> delegate;

@end

@implementation MWMBottomMenuViewController

+ (MWMBottomMenuViewController *)controller
{
  return [MWMMapViewControlsManager manager].menuController;
}

+ (void)updateAvailableArea:(CGRect)frame
{
  auto view = static_cast<MWMBottomMenuView *>([self controller].view);
  [view updateAvailableArea:frame];
}

- (instancetype)initWithParentController:(MapViewController *)controller
                                delegate:(id<MWMBottomMenuControllerProtocol>)delegate
{
  self = [super init];
  if (self)
  {
    _controller = controller;
    _delegate = delegate;
    [controller addChildViewController:self];
    [controller.view addSubview:self.view];
  }
  return self;
}

- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
- (void)viewDidLoad
{
  [super viewDidLoad];
  UICollectionView * bcv = self.additionalButtons;
  [bcv registerWithCellClass:[MWMBottomMenuCollectionViewPortraitCell class]];
  [bcv registerWithCellClass:[MWMBottomMenuCollectionViewLandscapeCell class]];
  MWMBottomMenuLayout * cvLayout =
      (MWMBottomMenuLayout *)self.additionalButtons.collectionViewLayout;
  cvLayout.layoutThreshold = kLayoutThreshold;
  self.menuView.layoutThreshold = kLayoutThreshold;

  [MWMSearchManager addObserver:self];
  [MWMNavigationDashboardManager addObserver:self];
}

- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  [self refreshLayout];
}

- (void)mwm_refreshUI { [self.view mwm_refreshUI]; }

#pragma mark - Refresh Collection View layout

- (void)refreshLayout
{
  MWMBottomMenuLayout * cvLayout =
      (MWMBottomMenuLayout *)self.additionalButtons.collectionViewLayout;
  cvLayout.buttonsCount = [self collectionView:self.additionalButtons numberOfItemsInSection:0];
  [self.additionalButtons reloadData];
  [self.menuView refreshLayout];
}

#pragma mark - Layout

- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
  [self.additionalButtons reloadData];
}

#pragma mark - MWMNavigationDashboardObserver

- (void)onNavigationDashboardStateChanged
{
  auto const navigationState = [MWMNavigationDashboardManager manager].state;
  if (navigationState == MWMNavigationDashboardStateHidden)
    self.state = MWMBottomMenuStateInactive;
  else
    self.state = MWMBottomMenuStateHidden;
}

#pragma mark - MWMSearchManagerObserver

- (void)onSearchManagerStateChanged
{
  auto state = [MWMSearchManager manager].state;
  self.searchButton.selected = (state != MWMSearchManagerStateHidden);
}

#pragma mark - UICollectionViewDataSource

- (NSInteger)collectionView:(nonnull UICollectionView *)collectionView
     numberOfItemsInSection:(NSInteger)section
{
  return MWMBottomMenuViewCellCount;
}

- (nonnull UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView
                          cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
  BOOL const isWideMenu = self.view.width > kLayoutThreshold;
  Class cls = isWideMenu ? [MWMBottomMenuCollectionViewLandscapeCell class]
                         : [MWMBottomMenuCollectionViewPortraitCell class];
  auto cell = static_cast<MWMBottomMenuCollectionViewCell *>(
      [collectionView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
  NSInteger item = indexPath.item;
  if (isWideMenu && isInterfaceRightToLeft())
    item = [self collectionView:collectionView numberOfItemsInSection:indexPath.section] - item - 1;
  switch (item)
  {
  case MWMBottomMenuViewCellAddPlace:
  {
    BOOL const isEnabled =
        [MWMNavigationDashboardManager manager].state == MWMNavigationDashboardStateHidden &&
        GetFramework().CanEditMap();
    [cell configureWithImageName:@"ic_add_place"
                           label:L(@"placepage_add_place_button")
                      badgeCount:0
                       isEnabled:isEnabled];
    break;
  }
  case MWMBottomMenuViewCellDownload:
  {
    auto & s = GetFramework().GetStorage();
    storage::Storage::UpdateInfo updateInfo{};
    s.GetUpdateInfo(s.GetRootId(), updateInfo);
    [cell configureWithImageName:@"ic_menu_download"
                           label:L(@"download_maps")
                      badgeCount:updateInfo.m_numberOfMwmFilesToUpdate
                       isEnabled:YES];
  }
  break;
  case MWMBottomMenuViewCellSettings:
    [cell configureWithImageName:@"ic_menu_settings"
                           label:L(@"settings")
                      badgeCount:0
                       isEnabled:YES];
    break;
  case MWMBottomMenuViewCellShare:
    [cell configureWithImageName:@"ic_menu_share"
                           label:L(@"share_my_location")
                      badgeCount:0
                       isEnabled:YES];
    break;
  }
  return cell;
}

#pragma mark - UICollectionViewDelegate

- (void)collectionView:(nonnull UICollectionView *)collectionView
    didSelectItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
  MWMBottomMenuCollectionViewCell * cell = static_cast<MWMBottomMenuCollectionViewCell *>(
      [collectionView cellForItemAtIndexPath:indexPath]);
  if (!cell.isEnabled)
    return;
  switch (indexPath.item)
  {
  case MWMBottomMenuViewCellAddPlace: [self menuActionAddPlace]; break;
  case MWMBottomMenuViewCellDownload: [self menuActionDownloadMaps]; break;
  case MWMBottomMenuViewCellSettings: [self menuActionOpenSettings]; break;
  case MWMBottomMenuViewCellShare: [self menuActionShareLocation]; break;
  }
}

#pragma mark - Buttons actions

- (void)menuActionAddPlace
{
  [Statistics logEvent:kStatEditorAddClick withParameters:@{kStatValue : kStatMenu}];
  GetPlatform().GetMarketingService().SendPushWooshTag(marketing::kEditorAddDiscovered);
  self.state = self.restoreState;
  [self.delegate addPlace:NO hasPoint:NO point:m2::PointD()];
}

- (void)menuActionDownloadMaps
{
  [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatDownloadMaps}];
  self.state = MWMBottomMenuStateInactive;
  [self.delegate actionDownloadMaps:mwm::DownloaderMode::Downloaded];
}

- (IBAction)menuActionOpenSettings
{
  [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatSettings}];
  self.state = self.restoreState;
  [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"settingsAndMore"];
  [self.controller performSegueWithIdentifier:@"Map2Settings" sender:nil];
}

- (void)menuActionShareLocation
{
  [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatShare}];
  [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"share@"];
  CLLocation * lastLocation = [MWMLocationManager lastLocation];
  if (!lastLocation)
  {
    [[[UIAlertView alloc] initWithTitle:L(@"unknown_current_position")
                                message:nil
                               delegate:nil
                      cancelButtonTitle:L(@"ok")
                      otherButtonTitles:nil] show];
    return;
  }
  CLLocationCoordinate2D const coord = lastLocation.coordinate;
  NSIndexPath * cellIndex = [NSIndexPath indexPathForItem:MWMBottomMenuViewCellShare inSection:0];
  MWMBottomMenuCollectionViewCell * cell =
      (MWMBottomMenuCollectionViewCell *)[self.additionalButtons cellForItemAtIndexPath:cellIndex];
  MWMActivityViewController * shareVC =
      [MWMActivityViewController shareControllerForMyPosition:coord];
  [shareVC presentInParentViewController:self.controller anchorView:cell.icon];
}

- (IBAction)point2PointButtonTouchUpInside:(UIButton *)sender
{
  [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatPointToPoint}];
  BOOL const isSelected = !sender.isSelected;
  [MWMRouter enableAutoAddLastLocation:NO];
  if (isSelected)
    [[MWMMapViewControlsManager manager] onRoutePrepare];
  else
    [MWMRouter stopRouting];
}

- (IBAction)searchButtonTouchUpInside
{
  [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatSearch}];
  [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"search"];
  self.state = MWMBottomMenuStateInactive;
  auto searchManager = [MWMSearchManager manager];
  if (searchManager.state == MWMSearchManagerStateHidden)
    searchManager.state = MWMSearchManagerStateDefault;
  else
    searchManager.state = MWMSearchManagerStateHidden;
}

- (IBAction)bookmarksButtonTouchUpInside
{
  [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatBookmarks}];
  [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"bookmarks"];
  self.state = MWMBottomMenuStateInactive;
  [self.controller openBookmarks];
}

- (IBAction)menuButtonTouchUpInside
{
  switch (self.state)
  {
  case MWMBottomMenuStateHidden: NSAssert(false, @"Incorrect state"); break;
  case MWMBottomMenuStateInactive:
    if ([self.menuView isCompact])
    {
      [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatRegular}];
      if (IPAD)
      {
        [MWMSearchManager manager].state = MWMSearchManagerStateHidden;
        [MWMRouter stopRouting];
      }
    }
    else
    {
      [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatExpand}];
      self.state = MWMBottomMenuStateActive;
    }
    break;
  case MWMBottomMenuStateActive:
    [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatCollapse}];
    self.state = MWMBottomMenuStateInactive;
    break;
  }
}

#pragma mark - Properties

- (MWMBottomMenuView *)menuView { return (MWMBottomMenuView *)self.view; }
- (MWMDimBackground *)dimBackground
{
  if (!_dimBackground)
    _dimBackground = [[MWMDimBackground alloc] initWithMainView:self.view];
  return _dimBackground;
}

- (void)setState:(MWMBottomMenuState)state
{
  runAsyncOnMainQueue(^{
    [self.controller setNeedsStatusBarAppearanceUpdate];
  });
  MWMBottomMenuView * view = self.menuView;
  BOOL const menuActive = (state == MWMBottomMenuStateActive);
  if (menuActive)
    [self.controller.view bringSubviewToFront:view];

  __weak auto wSelf = self;
  [self.dimBackground setVisible:menuActive
                       tapAction:^{
                         // In case when there are 2 touch events (dimBackgroundTap &
                         // menuButtonTouchUpInside)
                         // if dimBackgroundTap is processed first then menuButtonTouchUpInside
                         // behaves as if menu is
                         // inactive this is wrong case, so we postpone dimBackgroundTap to make
                         // sure
                         // menuButtonTouchUpInside processed first
                         dispatch_async(dispatch_get_main_queue(), ^{
                           wSelf.state = MWMBottomMenuStateInactive;
                         });
                       }];
  view.state = state;
}

- (MWMBottomMenuState)state { return self.menuView.state; }
@end