[ios] Updated opening hours editor.

This commit is contained in:
Илья Гречухин 2015-12-28 17:36:14 +03:00 committed by Sergey Yershov
parent c79043734c
commit 226de1eb7b
8 changed files with 230 additions and 46 deletions

View file

@ -1,4 +1,5 @@
#import "MWMOpeningHoursAddScheduleTableViewCell.h"
#import "MWMOpeningHoursCommon.h"
#import "MWMOpeningHoursEditorViewController.h"
@interface MWMOpeningHoursAddScheduleTableViewCell ()
@ -14,6 +15,13 @@
return 84.0;
}
- (void)refresh
{
NSString * title = [NSString stringWithFormat:@"%@ %@", L(@"add_schedule_for"),
stringFromOpeningDays([self.model unhandledDays])];
[self.addScheduleButton setTitle:title forState:UIControlStateNormal];
}
#pragma mark - Actions
- (IBAction)addScheduleTap
@ -26,9 +34,7 @@
- (void)setModel:(MWMOpeningHoursModel *)model
{
_model = model;
NSString * unhandledDays = [model.unhandledDays componentsJoinedByString:@", "];
NSString * title = [NSString stringWithFormat:@"%@ %@", L(@"add_schedule_for"), unhandledDays];
[self.addScheduleButton setTitle:title forState:UIControlStateNormal];
[self refresh];
}
@end

View file

@ -27,7 +27,7 @@ using namespace osmoh;
[super awakeFromNib];
NSCalendar * cal = [NSCalendar currentCalendar];
cal.locale = [NSLocale currentLocale];
self.firstWeekday = [cal firstWeekday];
self.firstWeekday = cal.firstWeekday;
NSArray<NSString *> * weekdaySymbols = cal.shortStandaloneWeekdaySymbols;
for (UILabel * label in self.labels)
{

View file

@ -0,0 +1,9 @@
#include "3party/opening_hours/opening_hours.hpp"
#include "editor/opening_hours_ui.hpp"
#include "base/assert.hpp"
NSDateComponents * dateComponentsFromTime(osmoh::Time const & time);
NSDate * dateFromTime(osmoh::Time const & time);
NSString * stringFromTime(osmoh::Time const & time);
NSString * stringFromOpeningDays(editor::ui::TOpeningDays const & openingDays);

View file

@ -0,0 +1,69 @@
#import "MWMOpeningHoursCommon.h"
NSDateComponents * dateComponentsFromTime(osmoh::Time const & time)
{
NSDateComponents * dc = [[NSDateComponents alloc] init];
dc.hour = time.GetHoursCount();
dc.minute = time.GetMinutesCount();
return dc;
}
NSDate * dateFromTime(osmoh::Time const & time)
{
NSCalendar * cal = [NSCalendar currentCalendar];
cal.locale = [NSLocale currentLocale];
return [cal dateFromComponents:dateComponentsFromTime(time)];
}
NSString * stringFromTime(osmoh::Time const & time)
{
NSDateFormatter * fmt = [[NSDateFormatter alloc] init];
fmt.locale = [NSLocale currentLocale];
fmt.timeStyle = NSDateFormatterShortStyle;
fmt.dateStyle = NSDateFormatterNoStyle;
return [fmt stringFromDate:dateFromTime(time)];
}
NSString * stringFromOpeningDays(editor::ui::TOpeningDays const & openingDays)
{
NSCalendar * cal = [NSCalendar currentCalendar];
cal.locale = [NSLocale currentLocale];
NSUInteger const firstWeekday = cal.firstWeekday - 1;
NSArray<NSString *> * weekdaySymbols = cal.shortStandaloneWeekdaySymbols;
NSMutableArray<NSString *> * spanNames = [NSMutableArray arrayWithCapacity:2];
NSMutableArray<NSString *> * spans = [NSMutableArray array];
auto weekdayFromDay = ^(NSUInteger day)
{
NSUInteger idx = day + 1;
if (idx > static_cast<NSUInteger>(osmoh::Weekday::Saturday))
idx -= static_cast<NSUInteger>(osmoh::Weekday::Saturday);
return static_cast<osmoh::Weekday>(idx);
};
auto joinSpanNames = ^
{
NSUInteger const spanNamesCount = spanNames.count;
if (spanNamesCount == 0)
return;
else if (spanNamesCount == 1)
[spans addObject:spanNames[0]];
else if (spanNamesCount == 2)
[spans addObject:[spanNames componentsJoinedByString:@"-"]];
else
ASSERT(false, ("Invalid span names count."));
[spanNames removeAllObjects];
};
NSUInteger const weekDaysCount = 7;
for (NSUInteger i = 0, day = firstWeekday; i < weekDaysCount; ++i, ++day)
{
osmoh::Weekday const wd = weekdayFromDay(day);
if (openingDays.find(wd) == openingDays.end())
joinSpanNames();
else
spanNames[(spanNames.count == 0 ? 0 : 1)] = weekdaySymbols[static_cast<NSInteger>(wd) - 1];
}
joinSpanNames();
return [spans componentsJoinedByString:@", "];
}

View file

@ -2,6 +2,7 @@
#import "MWMOpeningHoursEditorViewController.h"
#import "MWMOpeningHoursModel.h"
#import "MWMOpeningHoursSection.h"
#import "MWMTextView.h"
extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
@(MWMOpeningHoursEditorDaysSelectorCell) : @"MWMOpeningHoursDaysSelectorTableViewCell",
@ -16,9 +17,20 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
};
@interface MWMOpeningHoursEditorViewController ()<UITableViewDelegate, UITableViewDataSource,
MWMOpeningHoursModelProtocol>
UITextViewDelegate, MWMOpeningHoursModelProtocol>
@property (weak, nonatomic, readwrite) IBOutlet UITableView * tableView;
@property (weak, nonatomic, readwrite) IBOutlet UIView * advancedEditor;
@property (weak, nonatomic, readwrite) IBOutlet MWMTextView * editorView;
@property (weak, nonatomic) IBOutlet UIView * helpView;
@property (weak, nonatomic) IBOutlet UITextView * help;
@property (weak, nonatomic, readwrite) IBOutlet NSLayoutConstraint * ohTextViewHeight;
@property (weak, nonatomic) IBOutlet UIView * exampleValuesSeparator;
@property (weak, nonatomic) IBOutlet UIImageView * exampleValuesExpandView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * exampesButtonBottomOffset;
@property (weak, nonatomic, readwrite) IBOutlet UIButton * toggleModeButton;
@property (nonatomic) BOOL exampleExpanded;
@property (nonatomic) MWMOpeningHoursModel * model;
@ -31,6 +43,7 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
[super viewDidLoad];
[self configNavBar];
[self configTable];
[self configAdvancedEditor];
[self configData];
}
@ -56,6 +69,12 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
}];
}
- (void)configAdvancedEditor
{
[self.editorView setTextContainerInset:{12, 10, 12, 10}];
[self setExampleExpanded:NO];
}
- (void)configData
{
self.model = [[MWMOpeningHoursModel alloc] initWithDelegate:self];
@ -65,6 +84,9 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
- (void)onDone
{
[self.model updateOpeningHours];
std::string str = self.openingHours.UTF8String;
// TODO (AlexZ): Store edited opening time
}
#pragma mark - Table
@ -112,6 +134,8 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
- (NSInteger)numberOfSectionsInTableView:(UITableView * _Nonnull)tableView
{
if (!self.model.isSimpleMode)
return 0;
return self.model.count + (self.model.canAddSection ? 1 : 0);
}
@ -137,4 +161,38 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
[self fillCell:cell atIndexPath:indexPath];
}
#pragma mark - Advanced mode
- (void)setExampleExpanded:(BOOL)exampleExpanded
{
_exampleExpanded = exampleExpanded;
self.help.hidden = !exampleExpanded;
self.exampesButtonBottomOffset.priority = exampleExpanded ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh;
self.exampleValuesSeparator.hidden = !exampleExpanded;
self.exampleValuesExpandView.image = [UIImage imageNamed:exampleExpanded ? @"ic_arrow_gray_up" : @"ic_arrow_gray_down"];
if (exampleExpanded)
[self.editorView resignFirstResponder];
else
[self.editorView becomeFirstResponder];
}
- (IBAction)toggleExample
{
self.exampleExpanded = !self.exampleExpanded;
}
- (IBAction)toggleMode
{
self.model.isSimpleMode = !self.model.isSimpleMode;
}
#pragma mark - UITextViewDelegate
- (void)textViewDidChange:(UITextView *)textView
{
self.openingHours = textView.text;
self.navigationItem.rightBarButtonItem.enabled = self.model.isValid;
self.toggleModeButton.enabled = self.model.isSimpleModeCapable;
}
@end

View file

@ -1,9 +1,14 @@
#import "MWMOpeningHoursEditorCells.h"
#import "MWMOpeningHoursTableViewCell.h"
#import "MWMTextView.h"
@protocol MWMOpeningHoursModelProtocol <NSObject>
@property (nonnull, copy, nonatomic) NSString * openingHours;
@property (weak, nonatomic, readonly) UITableView * tableView;
@property (weak, nonatomic, readonly) UIView * advancedEditor;
@property (weak, nonatomic, readonly) MWMTextView * editorView;
@property (weak, nonatomic, readonly) UIButton * toggleModeButton;
@end
@ -11,7 +16,10 @@
@property (nonatomic, readonly) NSUInteger count;
@property (nonatomic, readonly) BOOL canAddSection;
@property (nonnull, nonatomic, readonly) NSArray<NSString *> * unhandledDays;
@property (nonatomic, readonly) BOOL isValid;
@property (nonatomic) BOOL isSimpleMode;
@property (nonatomic, readonly) BOOL isSimpleModeCapable;
- (instancetype _Nullable)initWithDelegate:(id<MWMOpeningHoursModelProtocol> _Nonnull)delegate;
@ -23,5 +31,8 @@
- (CGFloat)heightForIndexPath:(NSIndexPath * _Nonnull)indexPath withWidth:(CGFloat)width;
- (void)fillCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell atIndexPath:(NSIndexPath * _Nonnull)indexPath;
- (NSUInteger)numberOfRowsInSection:(NSUInteger)section;
- (editor::ui::TOpeningDays)unhandledDays;
- (void)updateOpeningHours;
@end

View file

@ -1,24 +1,26 @@
#import "MWMOpeningHoursCommon.h"
#import "MWMOpeningHoursModel.h"
#import "MWMOpeningHoursSection.h"
#include "editor/opening_hours_ui.hpp"
#include "editor/ui2oh.hpp"
extern UITableViewRowAnimation const kMWMOpeningHoursEditorRowAnimation = UITableViewRowAnimationFade;
@interface MWMOpeningHoursModel () <MWMOpeningHoursSectionProtocol>
@property (weak, nonatomic, readwrite) UITableView * tableView;
@property (weak, nonatomic) id<MWMOpeningHoursModelProtocol> delegate;
@property (nonatomic) NSMutableArray<MWMOpeningHoursSection *> * sections;
@end
using namespace editor::ui;
using namespace editor;
using namespace osmoh;
@implementation MWMOpeningHoursModel
{
TimeTableSet timeTableSet;
ui::TimeTableSet timeTableSet;
}
- (instancetype _Nullable)initWithDelegate:(id<MWMOpeningHoursModelProtocol> _Nonnull)delegate
@ -26,10 +28,8 @@ using namespace osmoh;
self = [super init];
if (self)
{
_tableView = delegate.tableView;
_sections = [NSMutableArray arrayWithCapacity:timeTableSet.Size()];
while (self.sections.count < timeTableSet.Size())
[self addSection];
self.delegate = delegate;
self.isSimpleMode = self.isSimpleModeCapable;
}
return self;
}
@ -38,8 +38,6 @@ using namespace osmoh;
{
[self.sections addObject:[[MWMOpeningHoursSection alloc] initWithDelegate:self]];
[self refreshSectionsIndexes];
NSIndexSet * set = [[NSIndexSet alloc] initWithIndex:self.count - 1];
[self.tableView reloadSections:set withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
- (void)refreshSectionsIndexes
@ -56,6 +54,8 @@ using namespace osmoh;
NSAssert(self.canAddSection, @"Can not add schedule");
timeTableSet.Append(timeTableSet.GetComplementTimeTable());
[self addSection];
[self.tableView reloadSections:[[NSIndexSet alloc] initWithIndex:self.sections.count - 1]
withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
NSAssert(timeTableSet.Size() == self.sections.count, @"Inconsistent state");
[self.sections[self.sections.count - 1] scrollIntoView];
}
@ -69,13 +69,16 @@ using namespace osmoh;
[self refreshSectionsIndexes];
if (needRealDelete)
{
NSIndexSet * set = [[NSIndexSet alloc] initWithIndex:index];
[self.tableView deleteSections:set withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
[self.tableView deleteSections:[[NSIndexSet alloc] initWithIndex:index]
withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
[self.tableView reloadSections:[[NSIndexSet alloc] initWithIndex:self.count]
withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
else
{
NSIndexSet * set = [[NSIndexSet alloc] initWithIndexesInRange:{index, self.count - index + 1}];
[self.tableView reloadSections:set withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
NSRange reloadRange = {index, self.count - index + 1};
[self.tableView reloadSections:[[NSIndexSet alloc] initWithIndexesInRange:reloadRange]
withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
}
@ -88,7 +91,7 @@ using namespace osmoh;
}
}
- (TTimeTableProxy)getTimeTableProxy:(NSUInteger)index
- (ui::TTimeTableProxy)getTimeTableProxy:(NSUInteger)index
{
NSAssert(index < self.count, @"Invalid section index");
return timeTableSet.Get(index);
@ -122,6 +125,18 @@ using namespace osmoh;
return self.sections[section].numberOfRows;
}
- (ui::TOpeningDays)unhandledDays
{
return timeTableSet.GetUnhandledDays();
}
- (void)updateOpeningHours
{
stringstream sstr;
sstr << MakeOpeningHours(timeTableSet).GetRule();
self.delegate.openingHours = @(sstr.str().c_str());
}
#pragma mark - Properties
- (NSUInteger)count
@ -135,30 +150,50 @@ using namespace osmoh;
return !timeTableSet.GetUnhandledDays().empty();
}
- (NSArray<NSString *> *)unhandledDays
- (UITableView *)tableView
{
auto const unhandledDays = timeTableSet.GetUnhandledDays();
NSCalendar * cal = [NSCalendar currentCalendar];
cal.locale = [NSLocale currentLocale];
NSUInteger const firstWeekday = [cal firstWeekday] - 1;
Weekday (^day2Weekday)(NSUInteger) = ^Weekday(NSUInteger day)
{
NSUInteger idx = day + 1;
if (idx > static_cast<NSUInteger>(Weekday::Saturday))
idx -= static_cast<NSUInteger>(Weekday::Saturday);
return static_cast<Weekday>(idx);
};
return self.delegate.tableView;
}
NSArray<NSString *> * weekdaySymbols = cal.shortStandaloneWeekdaySymbols;
NSMutableArray<NSString *> * dayNames = [NSMutableArray arrayWithCapacity:unhandledDays.size()];
NSUInteger const weekDaysCount = 7;
for (NSUInteger i = 0, day = firstWeekday; i < weekDaysCount; ++i, ++day)
- (BOOL)isValid
{
return osmoh::OpeningHours(self.delegate.openingHours.UTF8String).IsValid();
}
- (void)setIsSimpleMode:(BOOL)isSimpleMode
{
if (_isSimpleMode == isSimpleMode)
return;
_isSimpleMode = isSimpleMode;
id<MWMOpeningHoursModelProtocol> delegate = self.delegate;
if (isSimpleMode && MakeTimeTableSet(osmoh::OpeningHours(delegate.openingHours.UTF8String), timeTableSet))
{
Weekday const wd = day2Weekday(day);
if (unhandledDays.find(wd) != unhandledDays.end())
[dayNames addObject:weekdaySymbols[static_cast<NSInteger>(wd) - 1]];
_isSimpleMode = YES;
delegate.tableView.hidden = NO;
delegate.advancedEditor.hidden = YES;
[delegate.toggleModeButton setTitle:L(@"advanced_mode") forState:UIControlStateNormal];
_sections = [NSMutableArray arrayWithCapacity:timeTableSet.Size()];
while (self.sections.count < timeTableSet.Size())
[self addSection];
[delegate.tableView reloadData];
}
return dayNames;
else
{
_isSimpleMode = NO;
[self updateOpeningHours];
delegate.tableView.hidden = YES;
delegate.advancedEditor.hidden = NO;
[delegate.toggleModeButton setTitle:L(@"simple_mode") forState:UIControlStateNormal];
MWMTextView * ev = delegate.editorView;
ev.text = delegate.openingHours;
[ev becomeFirstResponder];
}
}
- (BOOL)isSimpleModeCapable
{
ui::TimeTableSet tts;
return MakeTimeTableSet(osmoh::OpeningHours(self.delegate.openingHours.UTF8String), tts);
}
@end

View file

@ -1,3 +1,4 @@
#import "MWMOpeningHoursCommon.h"
#import "MWMOpeningHoursSection.h"
#import "MWMOpeningHoursTableViewCell.h"
@ -116,12 +117,7 @@ using namespace osmoh;
TTimeTableProxy tt = [self getTimeTableProxy];
NSUInteger const index = isClosed ? [self closedTimeIndex:row] : 0;
Timespan span = isClosed ? tt.GetExcludeTime()[index] : tt.GetOpeningTime();
Time const & t = isStart ? span.GetStart() : span.GetEnd();
NSDateComponents * time = [[NSDateComponents alloc] init];
time.hour = t.GetHoursCount();
time.minute = t.GetMinutesCount();
return time;
return dateComponentsFromTime(isStart ? span.GetStart() : span.GetEnd());
}
- (void)setTime:(NSDateComponents *)time isStart:(BOOL)isStart isClosed:(BOOL)isClosed