Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
13
iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.h
Normal file
13
iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#import "MWMViewController.h"
|
||||
|
||||
#include "storage/storage_defines.hpp"
|
||||
|
||||
@class MapViewController;
|
||||
|
||||
@interface MWMMapDownloadDialog : UIView
|
||||
|
||||
+ (instancetype)dialogForController:(MapViewController *)controller;
|
||||
|
||||
- (void)processViewportCountryEvent:(storage::CountryId const &)countryId;
|
||||
|
||||
@end
|
||||
299
iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.mm
Normal file
299
iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.mm
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
#import "MWMMapDownloadDialog.h"
|
||||
#import <SafariServices/SafariServices.h>
|
||||
#import "CLLocation+Mercator.h"
|
||||
#import "MWMCircularProgress.h"
|
||||
#import "MWMStorage+UI.h"
|
||||
#import "MapViewController.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#include <CoreApi/Framework.h>
|
||||
|
||||
#include "storage/country_info_getter.hpp"
|
||||
|
||||
#include "platform/downloader_defines.hpp"
|
||||
#include "platform/local_country_file_utils.hpp"
|
||||
#include "platform/network_policy.hpp"
|
||||
#include "platform/preferred_languages.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
BOOL canAutoDownload(storage::CountryId const &countryId) {
|
||||
if (![MWMSettings autoDownloadEnabled])
|
||||
return NO;
|
||||
if (GetPlatform().ConnectionStatus() != Platform::EConnectionType::CONNECTION_WIFI)
|
||||
return NO;
|
||||
CLLocation *lastLocation = [MWMLocationManager lastLocation];
|
||||
if (!lastLocation)
|
||||
return NO;
|
||||
auto const &countryInfoGetter = GetFramework().GetCountryInfoGetter();
|
||||
if (countryId != countryInfoGetter.GetRegionCountryId(lastLocation.mercator))
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
using namespace storage;
|
||||
|
||||
@interface MWMMapDownloadDialog () <MWMStorageObserver, MWMCircularProgressProtocol>
|
||||
@property(strong, nonatomic) IBOutlet UILabel *explanationTitle;
|
||||
@property(strong, nonatomic) IBOutlet UILabel *explanationText;
|
||||
@property(strong, nonatomic) IBOutlet UILabel *parentNode;
|
||||
@property(strong, nonatomic) IBOutlet UILabel *node;
|
||||
@property(strong, nonatomic) IBOutlet UILabel *nodeSize;
|
||||
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *nodeTop;
|
||||
@property(strong, nonatomic) IBOutlet UIButton *downloadButton;
|
||||
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *explanationHeight;
|
||||
@property(strong, nonatomic) IBOutlet UIView *progressWrapper;
|
||||
|
||||
@property(weak, nonatomic) MapViewController *controller;
|
||||
@property(nonatomic) MWMCircularProgress *progress;
|
||||
@property(nonatomic) NSMutableArray<NSDate *> *skipDownloadTimes;
|
||||
@property(nonatomic) BOOL isAutoDownloadCancelled;
|
||||
|
||||
@end
|
||||
|
||||
NSString * const kOfflineMapsExplained = @"OfflineMapsExplained";
|
||||
|
||||
@implementation MWMMapDownloadDialog {
|
||||
CountryId m_countryId;
|
||||
CountryId m_autoDownloadCountryId;
|
||||
}
|
||||
|
||||
+ (instancetype)dialogForController:(MapViewController *)controller {
|
||||
MWMMapDownloadDialog *dialog = [NSBundle.mainBundle loadNibNamed:[self className] owner:nil options:nil].firstObject;
|
||||
dialog.controller = controller;
|
||||
return dialog;
|
||||
}
|
||||
|
||||
- (void)configDialog {
|
||||
auto &f = GetFramework();
|
||||
auto const &s = f.GetStorage();
|
||||
auto const &p = f.GetDownloadingPolicy();
|
||||
|
||||
NodeAttrs nodeAttrs;
|
||||
s.GetNodeAttrs(m_countryId, nodeAttrs);
|
||||
|
||||
if (!nodeAttrs.m_present && ![MWMRouter isRoutingActive]) {
|
||||
BOOL const isMultiParent = nodeAttrs.m_parentInfo.size() > 1;
|
||||
BOOL const noParrent = (nodeAttrs.m_parentInfo[0].m_id == s.GetRootId());
|
||||
BOOL const hideParent = (noParrent || isMultiParent);
|
||||
self.parentNode.hidden = hideParent;
|
||||
if (hideParent) {
|
||||
[NSLayoutConstraint activateConstraints:@[self.nodeTop]];
|
||||
} else {
|
||||
[NSLayoutConstraint deactivateConstraints:@[self.nodeTop]];
|
||||
self.parentNode.text = @(nodeAttrs.m_topmostParentInfo[0].m_localName.c_str());
|
||||
self.parentNode.textColor = [UIColor blackSecondaryText];
|
||||
}
|
||||
self.node.text = @(nodeAttrs.m_nodeLocalName.c_str());
|
||||
self.node.textColor = [UIColor blackPrimaryText];
|
||||
self.nodeSize.hidden = NO;
|
||||
self.nodeSize.textColor = [UIColor blackSecondaryText];
|
||||
self.nodeSize.text = formattedSize(nodeAttrs.m_mwmSize);
|
||||
self.nodeSize.font = [UIFont medium14].monospaced;
|
||||
if ([NSUserDefaults.standardUserDefaults integerForKey:kOfflineMapsExplained] > 1) {
|
||||
[NSLayoutConstraint activateConstraints:@[self.explanationHeight]];
|
||||
} else {
|
||||
[NSLayoutConstraint deactivateConstraints:@[self.explanationHeight]];
|
||||
}
|
||||
self.explanationTitle.text = L(@"offline_explanation_title");
|
||||
self.explanationText.text = L(@"offline_explanation_text");
|
||||
|
||||
switch (nodeAttrs.m_status) {
|
||||
case NodeStatus::NotDownloaded:
|
||||
case NodeStatus::Partly: {
|
||||
MapViewController *controller = self.controller;
|
||||
BOOL const isMapVisible = [controller.navigationController.topViewController isEqual:controller];
|
||||
if (isMapVisible && !self.isAutoDownloadCancelled && canAutoDownload(m_countryId)) {
|
||||
NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;
|
||||
NSInteger offlineMapsExplained = [userDefaults integerForKey:kOfflineMapsExplained] + 1;
|
||||
[userDefaults setInteger:offlineMapsExplained forKey:kOfflineMapsExplained];
|
||||
|
||||
m_autoDownloadCountryId = m_countryId;
|
||||
[[MWMStorage sharedStorage] downloadNode:@(m_countryId.c_str())
|
||||
onSuccess:^{
|
||||
[self showInQueue];
|
||||
}];
|
||||
} else {
|
||||
m_autoDownloadCountryId = kInvalidCountryId;
|
||||
[self showDownloadRequest];
|
||||
}
|
||||
[[MWMCarPlayService shared] showNoMapAlert];
|
||||
break;
|
||||
}
|
||||
case NodeStatus::Downloading:
|
||||
if (nodeAttrs.m_downloadingProgress.m_bytesTotal != 0)
|
||||
[self showDownloading:(CGFloat)nodeAttrs.m_downloadingProgress.m_bytesDownloaded /
|
||||
nodeAttrs.m_downloadingProgress.m_bytesTotal];
|
||||
break;
|
||||
case NodeStatus::Applying:
|
||||
case NodeStatus::InQueue:
|
||||
[self showInQueue];
|
||||
break;
|
||||
case NodeStatus::Undefined:
|
||||
case NodeStatus::Error:
|
||||
if (p.IsAutoRetryDownloadFailed()) {
|
||||
[self showError:nodeAttrs.m_error];
|
||||
} else {
|
||||
[self showInQueue];
|
||||
}
|
||||
break;
|
||||
case NodeStatus::OnDisk:
|
||||
case NodeStatus::OnDiskOutOfDate:
|
||||
[self removeFromSuperview];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
if (self.superview)
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)addToSuperview {
|
||||
if (self.superview)
|
||||
return;
|
||||
MapViewController *controller = self.controller;
|
||||
[controller.view insertSubview:self aboveSubview:controller.controlsView];
|
||||
[[MWMStorage sharedStorage] addObserver:self];
|
||||
|
||||
// Center dialog in the parent view.
|
||||
[self.centerXAnchor constraintEqualToAnchor:controller.view.centerXAnchor].active = YES;
|
||||
[self.centerYAnchor constraintEqualToAnchor:controller.view.centerYAnchor].active = YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)removeFromSuperview {
|
||||
[[MWMCarPlayService shared] hideNoMapAlert];
|
||||
self.progress.state = MWMCircularProgressStateNormal;
|
||||
[[MWMStorage sharedStorage] removeObserver:self];
|
||||
[super removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)showError:(NodeErrorCode)errorCode {
|
||||
if (errorCode == NodeErrorCode::NoError)
|
||||
return;
|
||||
self.nodeSize.textColor = [UIColor red];
|
||||
self.nodeSize.text = L(@"country_status_download_failed");
|
||||
self.downloadButton.hidden = YES;
|
||||
self.progressWrapper.hidden = NO;
|
||||
self.progress.state = MWMCircularProgressStateFailed;
|
||||
MWMAlertViewController *avc = self.controller.alertController;
|
||||
[self addToSuperview];
|
||||
auto const retryBlock = ^{
|
||||
[self showInQueue];
|
||||
[[MWMStorage sharedStorage] retryDownloadNode:@(self->m_countryId.c_str())];
|
||||
};
|
||||
auto const cancelBlock = ^{
|
||||
[[MWMStorage sharedStorage] cancelDownloadNode:@(self->m_countryId.c_str())];
|
||||
};
|
||||
switch (errorCode) {
|
||||
case NodeErrorCode::NoError:
|
||||
break;
|
||||
case NodeErrorCode::UnknownError:
|
||||
[avc presentDownloaderInternalErrorAlertWithOkBlock:retryBlock cancelBlock:cancelBlock];
|
||||
break;
|
||||
case NodeErrorCode::OutOfMemFailed:
|
||||
[avc presentDownloaderNotEnoughSpaceAlert];
|
||||
break;
|
||||
case NodeErrorCode::NoInetConnection:
|
||||
[avc presentDownloaderNoConnectionAlertWithOkBlock:retryBlock cancelBlock:cancelBlock];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showDownloadRequest {
|
||||
self.downloadButton.hidden = NO;
|
||||
self.progressWrapper.hidden = YES;
|
||||
[self addToSuperview];
|
||||
}
|
||||
|
||||
- (void)showDownloading:(CGFloat)progress {
|
||||
self.nodeSize.textColor = [UIColor blackSecondaryText];
|
||||
self.nodeSize.text =
|
||||
[NSString stringWithFormat:@"%@ %.0f%%", L(@"downloader_downloading"), progress * 100.f];
|
||||
self.downloadButton.hidden = YES;
|
||||
self.progressWrapper.hidden = NO;
|
||||
self.progress.progress = progress;
|
||||
[self addToSuperview];
|
||||
}
|
||||
|
||||
- (void)showInQueue {
|
||||
self.nodeSize.textColor = [UIColor blackSecondaryText];
|
||||
self.nodeSize.text = L(@"downloader_queued");
|
||||
self.downloadButton.hidden = YES;
|
||||
self.progressWrapper.hidden = NO;
|
||||
self.progress.state = MWMCircularProgressStateSpinner;
|
||||
[self addToSuperview];
|
||||
}
|
||||
|
||||
- (void)processViewportCountryEvent:(CountryId const &)countryId {
|
||||
m_countryId = countryId;
|
||||
if (countryId == kInvalidCountryId)
|
||||
[self removeFromSuperview];
|
||||
else
|
||||
[self configDialog];
|
||||
}
|
||||
|
||||
#pragma mark - MWMStorageObserver
|
||||
|
||||
- (void)processCountryEvent:(NSString *)countryId {
|
||||
if (m_countryId != countryId.UTF8String)
|
||||
return;
|
||||
if (self.superview)
|
||||
[self configDialog];
|
||||
else
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)processCountry:(NSString *)countryId
|
||||
downloadedBytes:(uint64_t)downloadedBytes
|
||||
totalBytes:(uint64_t)totalBytes {
|
||||
if (self.superview && m_countryId == countryId.UTF8String)
|
||||
[self showDownloading:(CGFloat)downloadedBytes / totalBytes];
|
||||
}
|
||||
|
||||
#pragma mark - MWMCircularProgressDelegate
|
||||
|
||||
- (void)progressButtonPressed:(nonnull MWMCircularProgress *)progress {
|
||||
if (progress.state == MWMCircularProgressStateFailed) {
|
||||
[self showInQueue];
|
||||
[[MWMStorage sharedStorage] retryDownloadNode:@(m_countryId.c_str())];
|
||||
} else {
|
||||
if (m_autoDownloadCountryId == m_countryId)
|
||||
self.isAutoDownloadCancelled = YES;
|
||||
[[MWMStorage sharedStorage] cancelDownloadNode:@(m_countryId.c_str())];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)downloadAction {
|
||||
NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;
|
||||
NSInteger offlineMapsExplained = [userDefaults integerForKey:kOfflineMapsExplained] + 1;
|
||||
[userDefaults setInteger:offlineMapsExplained forKey:kOfflineMapsExplained];
|
||||
|
||||
[[MWMStorage sharedStorage] downloadNode:@(m_countryId.c_str())
|
||||
onSuccess:^{ [self showInQueue]; }];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (MWMCircularProgress *)progress {
|
||||
if (!_progress) {
|
||||
_progress = [MWMCircularProgress downloaderProgressForParentView:self.progressWrapper];
|
||||
_progress.delegate = self;
|
||||
}
|
||||
return _progress;
|
||||
}
|
||||
|
||||
- (NSMutableArray<NSDate *> *)skipDownloadTimes {
|
||||
if (!_skipDownloadTimes)
|
||||
_skipDownloadTimes = [@[] mutableCopy];
|
||||
return _skipDownloadTimes;
|
||||
}
|
||||
|
||||
@end
|
||||
175
iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.xib
Normal file
175
iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.xib
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="24127" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24063"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="I6H-BQ-1TG" customClass="MWMMapDownloadDialog">
|
||||
<rect key="frame" x="0.0" y="0.0" width="200" height="361"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RvB-y5-5iX">
|
||||
<rect key="frame" x="0.0" y="0.0" width="200" height="81.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="750" verticalCompressionResistancePriority="753" text="Title" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3ki-f1-eeZ">
|
||||
<rect key="frame" x="16" y="19" width="168" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="750" verticalCompressionResistancePriority="753" text="Text" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ls5-nm-zjo">
|
||||
<rect key="frame" x="16" y="43.5" width="168" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LCO-7E-srL" userLabel="Divider">
|
||||
<rect key="frame" x="0.0" y="80.5" width="200" height="1"/>
|
||||
<color key="backgroundColor" systemColor="opaqueSeparatorColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="wqE-10-TUx"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="3ki-f1-eeZ" secondAttribute="trailing" constant="16" id="6nX-Re-jqZ"/>
|
||||
<constraint firstItem="LCO-7E-srL" firstAttribute="leading" secondItem="RvB-y5-5iX" secondAttribute="leading" id="HBn-fD-OpE"/>
|
||||
<constraint firstItem="ls5-nm-zjo" firstAttribute="top" secondItem="3ki-f1-eeZ" secondAttribute="bottom" constant="4" id="KzG-oR-PAR"/>
|
||||
<constraint firstAttribute="trailing" secondItem="ls5-nm-zjo" secondAttribute="trailing" constant="16" id="MJj-zB-w2b"/>
|
||||
<constraint firstAttribute="bottom" secondItem="LCO-7E-srL" secondAttribute="bottom" id="Tfu-HV-8xZ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="LCO-7E-srL" secondAttribute="trailing" id="VH1-4J-Lb4"/>
|
||||
<constraint firstAttribute="height" id="drU-cO-jmt"/>
|
||||
<constraint firstItem="LCO-7E-srL" firstAttribute="top" secondItem="ls5-nm-zjo" secondAttribute="bottom" constant="21" id="huT-bw-r1m"/>
|
||||
<constraint firstItem="3ki-f1-eeZ" firstAttribute="top" secondItem="RvB-y5-5iX" secondAttribute="top" constant="19" id="l1b-RC-c30"/>
|
||||
<constraint firstItem="ls5-nm-zjo" firstAttribute="leading" secondItem="RvB-y5-5iX" secondAttribute="leading" constant="16" id="uwk-LS-Oyj"/>
|
||||
<constraint firstItem="3ki-f1-eeZ" firstAttribute="leading" secondItem="RvB-y5-5iX" secondAttribute="leading" constant="16" id="v49-pB-FIP"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="drU-cO-jmt"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Россия" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GQf-xO-gh1">
|
||||
<rect key="frame" x="14" y="100.5" width="172" height="109.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54000000000000004" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="medium16:blackSecondaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="260" verticalCompressionResistancePriority="751" text="Доминиканская республика" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vMH-GY-Vm2">
|
||||
<rect key="frame" x="14" y="212" width="172" height="48"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="20"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="medium20:blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="260" text="16 МБ" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vU4-G9-kcd">
|
||||
<rect key="frame" x="14" y="268" width="172" height="17"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54000000000000004" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iyV-Rb-bea">
|
||||
<rect key="frame" x="20" y="297" width="160" height="44"/>
|
||||
<color key="backgroundColor" red="0.1176470588" green="0.58823529409999997" blue="0.94117647059999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="i64-mO-Txs"/>
|
||||
<constraint firstAttribute="width" constant="160" id="tIM-Zn-N9S"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<state key="normal" title="Скачать карту">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="country_status_download_without_size"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="FlatNormalButton"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="downloadAction" destination="I6H-BQ-1TG" eventType="touchUpInside" id="gK1-oH-Xye"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="usc-Cm-gmg" userLabel="ProgressViewWrapper">
|
||||
<rect key="frame" x="84" y="303" width="32" height="32"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="LiD-Zk-ocz"/>
|
||||
<constraint firstAttribute="height" constant="32" id="jrx-nU-VSG"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="GQf-xO-gh1" firstAttribute="leading" secondItem="iyV-Rb-bea" secondAttribute="leading" constant="-6" id="4vl-GS-oaZ"/>
|
||||
<constraint firstItem="usc-Cm-gmg" firstAttribute="centerX" secondItem="iyV-Rb-bea" secondAttribute="centerX" id="7DI-KV-B8S"/>
|
||||
<constraint firstItem="vU4-G9-kcd" firstAttribute="leading" secondItem="iyV-Rb-bea" secondAttribute="leading" constant="-6" id="8nk-Fu-pae"/>
|
||||
<constraint firstAttribute="trailing" secondItem="RvB-y5-5iX" secondAttribute="trailing" id="9rv-Kg-SEX"/>
|
||||
<constraint firstAttribute="trailing" secondItem="iyV-Rb-bea" secondAttribute="trailing" constant="20" id="C8t-0i-lpV"/>
|
||||
<constraint firstItem="vMH-GY-Vm2" firstAttribute="leading" secondItem="iyV-Rb-bea" secondAttribute="leading" constant="-6" id="E4i-Dd-AQA"/>
|
||||
<constraint firstAttribute="bottom" secondItem="iyV-Rb-bea" secondAttribute="bottom" priority="500" constant="20" id="HSh-rd-XIZ"/>
|
||||
<constraint firstItem="vMH-GY-Vm2" firstAttribute="top" secondItem="GQf-xO-gh1" secondAttribute="bottom" priority="500" constant="2" id="Kje-IL-qJy"/>
|
||||
<constraint firstItem="vU4-G9-kcd" firstAttribute="top" secondItem="vMH-GY-Vm2" secondAttribute="bottom" constant="8" id="S4i-o8-W4I"/>
|
||||
<constraint firstItem="iyV-Rb-bea" firstAttribute="top" secondItem="vU4-G9-kcd" secondAttribute="bottom" constant="12" id="VN6-NK-qgb"/>
|
||||
<constraint firstItem="vMH-GY-Vm2" firstAttribute="top" secondItem="RvB-y5-5iX" secondAttribute="bottom" priority="800" constant="19" id="XpP-Zw-jAa"/>
|
||||
<constraint firstItem="iyV-Rb-bea" firstAttribute="leading" secondItem="I6H-BQ-1TG" secondAttribute="leading" constant="20" id="atf-Me-rzF"/>
|
||||
<constraint firstItem="RvB-y5-5iX" firstAttribute="leading" secondItem="I6H-BQ-1TG" secondAttribute="leading" id="c55-Kg-7X1"/>
|
||||
<constraint firstItem="GQf-xO-gh1" firstAttribute="top" secondItem="RvB-y5-5iX" secondAttribute="bottom" constant="19" id="dJk-R4-Uwg"/>
|
||||
<constraint firstItem="RvB-y5-5iX" firstAttribute="top" secondItem="I6H-BQ-1TG" secondAttribute="top" id="duL-BL-ibL"/>
|
||||
<constraint firstAttribute="trailing" secondItem="iyV-Rb-bea" secondAttribute="trailing" priority="500" constant="20" id="hgA-l8-VzT"/>
|
||||
<constraint firstItem="vU4-G9-kcd" firstAttribute="trailing" secondItem="iyV-Rb-bea" secondAttribute="trailing" constant="6" id="jZP-5b-Nbs"/>
|
||||
<constraint firstItem="usc-Cm-gmg" firstAttribute="centerY" secondItem="iyV-Rb-bea" secondAttribute="centerY" id="pxa-11-yUj"/>
|
||||
<constraint firstItem="GQf-xO-gh1" firstAttribute="trailing" secondItem="iyV-Rb-bea" secondAttribute="trailing" constant="6" id="sMn-Pe-OLX"/>
|
||||
<constraint firstItem="vMH-GY-Vm2" firstAttribute="trailing" secondItem="iyV-Rb-bea" secondAttribute="trailing" constant="6" id="wqD-4Q-AwL"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="DialogView"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="XpP-Zw-jAa"/>
|
||||
<exclude reference="hgA-l8-VzT"/>
|
||||
<exclude reference="C8t-0i-lpV"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="hgA-l8-VzT"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="C8t-0i-lpV"/>
|
||||
<include reference="HSh-rd-XIZ"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<connections>
|
||||
<outlet property="downloadButton" destination="iyV-Rb-bea" id="6fy-CY-zos"/>
|
||||
<outlet property="explanationHeight" destination="drU-cO-jmt" id="AAd-rw-kWs"/>
|
||||
<outlet property="explanationText" destination="ls5-nm-zjo" id="XFr-4s-UEW"/>
|
||||
<outlet property="explanationTitle" destination="3ki-f1-eeZ" id="Y4O-1s-mCP"/>
|
||||
<outlet property="node" destination="vMH-GY-Vm2" id="LJq-UU-a3U"/>
|
||||
<outlet property="nodeSize" destination="vU4-G9-kcd" id="DMJ-NW-mxf"/>
|
||||
<outlet property="nodeTop" destination="XpP-Zw-jAa" id="zCV-UY-ru9"/>
|
||||
<outlet property="parentNode" destination="GQf-xO-gh1" id="gWT-r0-LTv"/>
|
||||
<outlet property="progressWrapper" destination="usc-Cm-gmg" id="NTd-bU-rDE"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="417.39130434782612" y="539.39732142857144"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<systemColor name="opaqueSeparatorColor">
|
||||
<color red="0.77647058820000003" green="0.77647058820000003" blue="0.7843137255" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
14
iphone/Maps/Classes/Widgets/MWMMapWidgets.h
Normal file
14
iphone/Maps/Classes/Widgets/MWMMapWidgets.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include <CoreApi/Framework.h>
|
||||
|
||||
@interface MWMMapWidgets : NSObject
|
||||
|
||||
+ (MWMMapWidgets *)widgetsManager;
|
||||
|
||||
- (void)setupWidgets:(Framework::DrapeCreationParams &)p;
|
||||
|
||||
- (void)resize:(CGSize)size;
|
||||
- (void)updateAvailableArea:(CGRect)frame;
|
||||
- (void)updateLayout:(CGRect)frame;
|
||||
- (void)updateLayoutForAvailableArea;
|
||||
|
||||
@end
|
||||
91
iphone/Maps/Classes/Widgets/MWMMapWidgets.mm
Normal file
91
iphone/Maps/Classes/Widgets/MWMMapWidgets.mm
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#import "MWMMapWidgets.h"
|
||||
#import "EAGLView.h"
|
||||
#import "MapViewController.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
@interface MWMMapWidgets ()
|
||||
|
||||
@property(nonatomic) float visualScale;
|
||||
@property(nonatomic) CGRect availableArea;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMMapWidgets
|
||||
{
|
||||
std::unique_ptr<gui::Skin> m_skin;
|
||||
}
|
||||
|
||||
+ (MWMMapWidgets *)widgetsManager
|
||||
{
|
||||
return [MapViewController sharedController].mapView.widgetsManager;
|
||||
}
|
||||
|
||||
- (void)setupWidgets:(Framework::DrapeCreationParams &)p
|
||||
{
|
||||
self.visualScale = p.m_visualScale;
|
||||
m_skin.reset(new gui::Skin(gui::ResolveGuiSkinFile("default"), p.m_visualScale));
|
||||
m_skin->Resize(p.m_surfaceWidth, p.m_surfaceHeight);
|
||||
m_skin->ForEach(
|
||||
[&p](gui::EWidget widget, gui::Position const & pos) { p.m_widgetsInitInfo[widget] = pos; });
|
||||
p.m_widgetsInitInfo[gui::WIDGET_SCALE_FPS_LABEL] = gui::Position(m2::PointF(self.visualScale * 10, self.visualScale * 45), dp::LeftTop);
|
||||
}
|
||||
|
||||
- (void)resize:(CGSize)size
|
||||
{
|
||||
if (m_skin != nullptr)
|
||||
m_skin->Resize(size.width, size.height);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if ([MWMCarPlayService shared].isCarplayActivated) {
|
||||
CGRect bounds = [MapViewController sharedController].mapView.bounds;
|
||||
[self updateLayout: bounds];
|
||||
return;
|
||||
}
|
||||
[self updateLayoutForAvailableArea];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)updateAvailableArea:(CGRect)frame
|
||||
{
|
||||
if (CGRectEqualToRect(self.availableArea, frame))
|
||||
return;
|
||||
self.availableArea = frame;
|
||||
if ([MWMCarPlayService shared].isCarplayActivated) {
|
||||
return;
|
||||
}
|
||||
[self updateLayout:frame];
|
||||
}
|
||||
|
||||
- (void)updateLayoutForAvailableArea
|
||||
{
|
||||
[self updateLayout:self.availableArea];
|
||||
}
|
||||
|
||||
- (void)updateLayout:(CGRect)frame
|
||||
{
|
||||
if (m_skin == nullptr)
|
||||
return;
|
||||
gui::TWidgetsLayoutInfo layout;
|
||||
auto const vs = self.visualScale;
|
||||
auto const viewHeight = [MapViewController sharedController].mapView.height;
|
||||
auto const viewWidth = [MapViewController sharedController].mapView.width;
|
||||
auto const rulerOffset =
|
||||
m2::PointF(frame.origin.x * vs, (frame.origin.y + frame.size.height - viewHeight) * vs);
|
||||
auto const kCompassAdditionalYOffset = [TrackRecordingManager.shared isActive] ? 50 : 0;
|
||||
auto const compassOffset =
|
||||
m2::PointF((frame.origin.x + frame.size.width - viewWidth) * vs, (frame.origin.y + kCompassAdditionalYOffset) * vs);
|
||||
m_skin->ForEach([&](gui::EWidget w, gui::Position const & pos) {
|
||||
m2::PointF pivot = pos.m_pixelPivot;
|
||||
switch (w)
|
||||
{
|
||||
case gui::WIDGET_RULER:
|
||||
case gui::WIDGET_COPYRIGHT: pivot += rulerOffset; break;
|
||||
case gui::WIDGET_COMPASS: pivot += compassOffset; break;
|
||||
case gui::WIDGET_SCALE_FPS_LABEL:
|
||||
case gui::WIDGET_CHOOSE_POSITION_MARK: break;
|
||||
}
|
||||
layout[w] = pivot;
|
||||
});
|
||||
GetFramework().SetWidgetLayout(std::move(layout));
|
||||
}
|
||||
|
||||
@end
|
||||
7
iphone/Maps/Classes/Widgets/MWMMapWidgetsHelper.h
Normal file
7
iphone/Maps/Classes/Widgets/MWMMapWidgetsHelper.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
@interface MWMMapWidgetsHelper : NSObject
|
||||
|
||||
+ (void)updateAvailableArea:(CGRect)frame;
|
||||
+ (void)updateLayout:(CGRect)frame;
|
||||
+ (void)updateLayoutForAvailableArea;
|
||||
|
||||
@end
|
||||
21
iphone/Maps/Classes/Widgets/MWMMapWidgetsHelper.mm
Normal file
21
iphone/Maps/Classes/Widgets/MWMMapWidgetsHelper.mm
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#import "MWMMapWidgetsHelper.h"
|
||||
#import "MWMMapWidgets.h"
|
||||
|
||||
@implementation MWMMapWidgetsHelper
|
||||
|
||||
+ (void)updateAvailableArea:(CGRect)frame
|
||||
{
|
||||
[[MWMMapWidgets widgetsManager] updateAvailableArea:frame];
|
||||
}
|
||||
|
||||
+ (void)updateLayout:(CGRect)frame
|
||||
{
|
||||
[[MWMMapWidgets widgetsManager] updateLayout:frame];
|
||||
}
|
||||
|
||||
+ (void)updateLayoutForAvailableArea
|
||||
{
|
||||
[[MWMMapWidgets widgetsManager] updateLayoutForAvailableArea];
|
||||
}
|
||||
|
||||
@end
|
||||
Loading…
Add table
Add a link
Reference in a new issue