1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CALENDAR_CALENDAR_COMPONENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CALENDAR_CALENDAR_COMPONENT_H
18 
19 #include "core/components/button/button_component.h"
20 #include "core/components/calendar/calendar_data_adapter.h"
21 #include "core/components/calendar/calendar_theme.h"
22 #include "core/components/flex/flex_component.h"
23 #include "core/components/image/image_component.h"
24 #include "core/components/swiper/render_swiper.h"
25 #include "core/components/swiper/swiper_component.h"
26 #include "core/pipeline/base/composed_component.h"
27 #include "core/pipeline/base/render_component.h"
28 
29 namespace OHOS::Ace {
30 
31 using CalenderRequestFocusImpl = std::function<void()>;
32 
33 class ACE_EXPORT CalendarController : public AceType {
34     DECLARE_ACE_TYPE(CalendarController, AceType);
35 
36 public:
37     CalendarController(
38         const CalendarDataAdapterAction& dataAdapterAction, const WeakPtr<PipelineContext>& pipelineContext);
39     ~CalendarController() override = default;
40 
41     void Initialize();
42     void GoToPrevMonth(int32_t selected);
43     void GoToNextMonth(int32_t selected);
44     void GoTo(int32_t year, int32_t month, int32_t day);
45 
SetSwiperController(const RefPtr<SwiperController> & swiperController)46     void SetSwiperController(const RefPtr<SwiperController>& swiperController)
47     {
48         swiperController_ = swiperController;
49     }
50 
GetDataAdapter()51     const RefPtr<CalendarDataAdapter>& GetDataAdapter() const
52     {
53         return dataAdapter_;
54     }
55 
SetToday(const CalendarDay & today)56     void SetToday(const CalendarDay& today)
57     {
58         dataAdapter_->SetToday(today);
59     }
60 
GetToday()61     const CalendarDay& GetToday()
62     {
63         return dataAdapter_->GetToday();
64     }
65 
RequestFocus()66     void RequestFocus()
67     {
68         if (requestFocusImpl_) {
69             requestFocusImpl_();
70         }
71     }
72 
SetRequestFocusImpl(const CalenderRequestFocusImpl & requestFocusImpl)73     void SetRequestFocusImpl(const CalenderRequestFocusImpl& requestFocusImpl)
74     {
75         requestFocusImpl_ = requestFocusImpl;
76     }
77 
SetFirstEnter(bool firstEnter)78     void SetFirstEnter(bool firstEnter)
79     {
80         firstEnter_ = firstEnter;
81     }
82 
GetFirstEnter()83     bool GetFirstEnter() const
84     {
85         return firstEnter_;
86     }
87 
SetNeedFocus(bool needFocus)88     void SetNeedFocus(bool needFocus)
89     {
90         needFocus_ = needFocus;
91     }
92 
IsNeedFocus()93     bool IsNeedFocus() const
94     {
95         return needFocus_;
96     }
97 
NotifyFocusChanged(bool focusStatus)98     void NotifyFocusChanged(bool focusStatus) const
99     {
100         if (dataAdapter_) {
101             dataAdapter_->NotifyFocusChanged(focusStatus);
102         }
103     }
104 
SetRenderSwiper(const RefPtr<RenderSwiper> & renderSwiper)105     void SetRenderSwiper(const RefPtr<RenderSwiper>& renderSwiper)
106     {
107         renderSwiper_ = renderSwiper;
108     }
109 
GetRenderSwiper()110     const RefPtr<RenderSwiper>& GetRenderSwiper() const
111     {
112         return renderSwiper_;
113     }
114 
GetCurrentIndex()115     int32_t GetCurrentIndex()
116     {
117         return currentMonthIndex_;
118     }
119 
JumpMonth()120     void JumpMonth()
121     {
122         while (!swiperReverseCache_.empty()) {
123             swiperController_->SwipeTo(swiperReverseCache_.front().first, swiperReverseCache_.front().second);
124             swiperReverseCache_.pop();
125         }
126     }
127 
SetFirstLoad(bool firstLoad)128     void SetFirstLoad(bool firstLoad)
129     {
130         firstLoad_ = firstLoad;
131     }
132 
GetFirstLoad()133     bool GetFirstLoad() const
134     {
135         return firstLoad_;
136     }
137 
138     void RequestMonthData(int32_t index);
139     void CalculateNextIndex(int32_t index);
140     void UpdateTheme();
141     void UpdateTitle(const CalendarDay& today);
142 
GetCurrentMonth()143     const CalendarMonth& GetCurrentMonth() const
144     {
145         return currentCalendarMonth_;
146     }
147 
SetCardTitle(const RefPtr<RenderText> & renderText)148     void SetCardTitle(const RefPtr<RenderText>& renderText)
149     {
150         renderText_ = renderText;
151     }
152 
SetRightRowImage(const RefPtr<RenderImage> & rightRowImage)153     void SetRightRowImage(const RefPtr<RenderImage>& rightRowImage)
154     {
155         rightImage_ = rightRowImage;
156     }
157 
SetLeftRowImage(const RefPtr<RenderImage> & leftRowImage)158     void SetLeftRowImage(const RefPtr<RenderImage>& leftRowImage)
159     {
160         leftImage_ = leftRowImage;
161     }
162 
SetRightRowImage(const RefPtr<ImageComponent> & rightRowImage)163     void SetRightRowImage(const RefPtr<ImageComponent>& rightRowImage)
164     {
165         rightImageComponent_ = rightRowImage;
166     }
167 
SetLeftRowImage(const RefPtr<ImageComponent> & leftRowImage)168     void SetLeftRowImage(const RefPtr<ImageComponent>& leftRowImage)
169     {
170         leftImageComponent_ = leftRowImage;
171     }
172 
SetHasMoved(bool hasMoved)173     void SetHasMoved(bool hasMoved)
174     {
175         dataAdapter_->SetHasMoved(hasMoved);
176     }
177 
HasMoved()178     bool HasMoved()
179     {
180         return dataAdapter_->HasMoved();
181     }
182 
SetFirstSetToday(bool firstSetToday)183     void SetFirstSetToday(bool firstSetToday)
184     {
185         firstSetToday_ = firstSetToday;
186     }
187 
FirstSetToday()188     bool FirstSetToday()
189     {
190         return firstSetToday_;
191     }
192 
SetCrossMonthDay(const CalendarDay & crossMonthDay)193     void SetCrossMonthDay(const CalendarDay& crossMonthDay)
194     {
195         dataAdapter_->SetCrossMonth(true);
196         crossMonthDay_ = crossMonthDay;
197     }
198 
GetCrossMonthDay()199     const CalendarDay& GetCrossMonthDay()
200     {
201         return crossMonthDay_;
202     }
203 
SetCrossMonth(bool isCrossMonth)204     void SetCrossMonth(bool isCrossMonth)
205     {
206         dataAdapter_->SetCrossMonth(isCrossMonth);
207     }
208 
IsCrossMonth()209     bool IsCrossMonth()
210     {
211         return dataAdapter_->IsCrossMonth();
212     }
213 
214 private:
215     enum class SwipeDirection {
216         NEXT,
217         PREV,
218     };
219 
220     void GoToMonth(SwipeDirection direction, int32_t selected);
221     void JumpToMonth(const CalendarMonth& calendarMonth, int32_t selected, SwipeDirection direction);
222     void SetButtonClickColor(const RefPtr<RenderNode>& node, const Color& clickColor) const;
223 
224     RefPtr<SwiperController> swiperController_;
225     RefPtr<RenderSwiper> renderSwiper_;
226     RefPtr<CalendarDataAdapter> dataAdapter_;
227     CalendarMonth currentCalendarMonth_;
228     CalendarDay crossMonthDay_;
229     CalenderRequestFocusImpl requestFocusImpl_;
230     int32_t currentMonthIndex_ = 1;
231     bool firstEnter_ = true;
232     bool needFocus_ = false;
233     bool firstLoad_ = true;
234     bool firstSetToday_ = true;
235     std::queue<std::pair<int32_t, bool>> swiperReverseCache_;
236 
237     RefPtr<RenderText> renderText_;
238     RefPtr<RenderImage> leftImage_;
239     RefPtr<RenderImage> rightImage_;
240     RefPtr<ImageComponent> leftImageComponent_;
241     RefPtr<ImageComponent> rightImageComponent_;
242 };
243 
244 class ACE_EXPORT CalendarComponent : public ComposedComponent {
245     DECLARE_ACE_TYPE(CalendarComponent, ComposedComponent);
246 
247 public:
248     CalendarComponent(const ComposeId& id, const std::string& name);
249     ~CalendarComponent() override = default;
250 
251     RefPtr<Element> CreateElement() override;
252     RefPtr<Component> Build(
253         const WeakPtr<PipelineContext>& pipelineContext, const RefPtr<CalendarController>& calendarController);
254     void GoTo(int32_t year, int32_t month, int32_t day);
255 
SetSelectedChangeEvent(const EventMarker & selectedChangeEvent)256     void SetSelectedChangeEvent(const EventMarker& selectedChangeEvent)
257     {
258         selectedChangeEvent_ = selectedChangeEvent;
259     }
260 
SetRequestDataEvent(const EventMarker & requestDataEvent)261     void SetRequestDataEvent(const EventMarker& requestDataEvent)
262     {
263         requestDataEvent_ = requestDataEvent;
264     }
265 
SetDataAdapterAction(const CalendarDataAdapterAction & dataAdapterAction)266     void SetDataAdapterAction(const CalendarDataAdapterAction& dataAdapterAction)
267     {
268         dataAdapterAction_ = dataAdapterAction;
269     }
270 
GetDataAdapterAction()271     const CalendarDataAdapterAction& GetDataAdapterAction()
272     {
273         return dataAdapterAction_;
274     }
275 
SetCalendarDate(const CalendarDay & date)276     void SetCalendarDate(const CalendarDay& date)
277     {
278         date_ = date;
279         isSetToday_ = true;
280     }
281 
GetCalendarController()282     const RefPtr<CalendarController>& GetCalendarController() const
283     {
284         return calendarController_;
285     }
286 
287     void RequestMonthData(int32_t index);
288 
SetAxis(Axis axis)289     void SetAxis(Axis axis)
290     {
291         axis_ = axis;
292     }
293 
GetAxis()294     Axis GetAxis() const
295     {
296         return axis_;
297     }
298 
SetShowLunar(bool showLunar)299     void SetShowLunar(bool showLunar)
300     {
301         showLunar_ = showLunar;
302     }
303 
GetPreClickId()304     const EventMarker& GetPreClickId() const
305     {
306         return preClickId_;
307     }
308 
GetNextClickId()309     const EventMarker& GetNextClickId() const
310     {
311         return nextClickId_;
312     }
313 
GetDateClickId()314     const EventMarker& GetDateClickId() const
315     {
316         return dateClickId_;
317     }
318 
SetCardCalendar(bool cardCalendar)319     void SetCardCalendar(bool cardCalendar)
320     {
321         cardCalendar_ = cardCalendar;
322     }
323 
IsCardCalendar()324     bool IsCardCalendar() const
325     {
326         return cardCalendar_;
327     }
328 
SetStartDayOfWeek(int32_t indexOfWeek)329     void SetStartDayOfWeek(int32_t indexOfWeek)
330     {
331         startDayOfWeek_ = indexOfWeek;
332     }
333 
GetStartDayOfWeek()334     int32_t GetStartDayOfWeek() const
335     {
336         return startDayOfWeek_;
337     }
338 
IsShowLunar()339     bool IsShowLunar() const
340     {
341         return showLunar_;
342     }
343 
IsSetToday()344     bool IsSetToday() const
345     {
346         return isSetToday_;
347     }
348 
GetDate()349     const CalendarDay& GetDate() const
350     {
351         return date_;
352     }
353 
GetCalendarData()354     const std::string& GetCalendarData() const
355     {
356         return calendarData_;
357     }
358 
SetShowHoliday(bool showHoliday)359     void SetShowHoliday(bool showHoliday)
360     {
361         showHoliday_ = showHoliday;
362     }
363 
GetShowHoliday()364     bool GetShowHoliday() const
365     {
366         return showHoliday_;
367     }
368 
SetOffDays(const std::string & offDays)369     void SetOffDays(const std::string& offDays)
370     {
371         offDays_ = offDays;
372     }
373 
GetOffDays()374     const std::string& GetOffDays() const
375     {
376         return offDays_;
377     }
378 
GetHolidays()379     const std::string& GetHolidays() const
380     {
381         return holidays_;
382     }
383 
SetHolidays(const std::string & holidays)384     void SetHolidays(const std::string& holidays)
385     {
386         holidays_ = holidays;
387     }
388 
GetWorkDays()389     const std::string& GetWorkDays() const
390     {
391         return workDays_;
392     }
393 
SetWorkDays(const std::string & workDays)394     void SetWorkDays(const std::string& workDays)
395     {
396         workDays_ = workDays;
397     }
398 
SetNeedSlide(bool needSlide)399     void SetNeedSlide(bool needSlide)
400     {
401         needSlide_ = needSlide;
402     }
403 
IsNeedSlide()404     bool IsNeedSlide() const
405     {
406         return needSlide_;
407     }
408 
IsV2Component()409     bool IsV2Component() const
410     {
411         return isV2Component_;
412     }
413 
SetV2Component(bool isV2Component)414     void SetV2Component(bool isV2Component)
415     {
416         isV2Component_ = isV2Component;
417     }
418 
SetCalendarTheme(const RefPtr<CalendarTheme> & theme)419     void SetCalendarTheme(const RefPtr<CalendarTheme>& theme)
420     {
421         theme_ = theme;
422     }
423 
GetCalendarTheme()424     const RefPtr<CalendarTheme>& GetCalendarTheme()
425     {
426         return theme_;
427     }
428 
SetCalendarType(CalendarType type)429     void SetCalendarType(CalendarType type)
430     {
431         type_ = type;
432     }
433 
GetCalendarType()434     CalendarType GetCalendarType() const
435     {
436         return type_;
437     }
438 
439     void SetCalendarData(const std::string& value);
440     void BuildCardCalendarTitle(RefPtr<ColumnComponent>& col);
441     const EventMarker& GetSelectedChangeEvent() const;
442     const EventMarker& GetRequestDataEvent() const;
443     RefPtr<ButtonComponent> InitCardButton(bool isPreArrow);
444 
445 protected:
446     RefPtr<CalendarTheme> theme_;
447 
448 private:
449     Axis axis_ { Axis::HORIZONTAL };
450     CalendarType type_ { CalendarType::NORMAL };
451     int32_t startDayOfWeek_ = 6; // the default is Sunday
452     bool showHoliday_ = true;
453     bool showLunar_ = true;
454     bool isSetToday_ = false;
455     bool cardCalendar_ = false;
456     bool needSlide_ = false;
457     bool isV2Component_ = false;
458     std::string calendarData_;
459     std::string offDays_ = "5, 6"; // The default day of rest is Saturday and Sunday
460     std::string holidays_;
461     std::string workDays_;
462     ColorMode colorMode_ = ColorMode::LIGHT;
463     CalendarDay date_;
464     EventMarker selectedChangeEvent_;
465     EventMarker requestDataEvent_;
466     EventMarker preClickId_;
467     EventMarker nextClickId_;
468     EventMarker dateClickId_;
469     CalendarDataAdapterAction dataAdapterAction_;
470     RefPtr<CalendarController> calendarController_;
471     RefPtr<SwiperComponent> swiperContainer_;
472 };
473 
474 class CalendarMonthComponent : public RenderComponent {
475     DECLARE_ACE_TYPE(CalendarMonthComponent, RenderComponent);
476 
477 public:
478     CalendarMonthComponent(int32_t indexOfContainer, const RefPtr<CalendarController>& calendarController);
479     ~CalendarMonthComponent() override = default;
480 
481     RefPtr<RenderNode> CreateRenderNode() override;
482     RefPtr<Element> CreateElement() override;
483 
GetIndexOfContainer()484     int32_t GetIndexOfContainer() const
485     {
486         return indexOfContainer_;
487     }
488 
SetSelectedChangeEvent(const EventMarker & selectedChangeEvent)489     void SetSelectedChangeEvent(const EventMarker& selectedChangeEvent)
490     {
491         selectedChangeEvent_ = selectedChangeEvent;
492     }
493 
GetSelectedChangeEvent()494     const EventMarker& GetSelectedChangeEvent() const
495     {
496         return selectedChangeEvent_;
497     }
498 
GetCalendarController()499     const RefPtr<CalendarController>& GetCalendarController() const
500     {
501         return calendarController_;
502     }
503 
SetCalendarTheme(const RefPtr<CalendarTheme> & calendarTheme)504     void SetCalendarTheme(const RefPtr<CalendarTheme>& calendarTheme)
505     {
506         calendarTheme_ = calendarTheme;
507     }
508 
GetCalendarTheme()509     const RefPtr<CalendarTheme>& GetCalendarTheme() const
510     {
511         return calendarTheme_;
512     }
513 
SetCardCalendar(bool cardCalendar)514     void SetCardCalendar(bool cardCalendar)
515     {
516         cardCalendar_ = cardCalendar;
517     }
518 
IsCardCalendar()519     bool IsCardCalendar() const
520     {
521         return cardCalendar_;
522     }
523 
SetCalendarType(CalendarType type)524     void SetCalendarType(CalendarType type)
525     {
526         type_ = type;
527     }
528 
GetCalendarType()529     CalendarType GetCalendarType() const
530     {
531         return type_;
532     }
533 
534 private:
535     bool cardCalendar_ = false;
536     int32_t indexOfContainer_ = 0;
537     EventMarker selectedChangeEvent_;
538     RefPtr<CalendarController> calendarController_;
539     RefPtr<CalendarTheme> calendarTheme_;
540     CalendarType type_ { CalendarType::NORMAL };
541 };
542 
543 } // namespace OHOS::Ace
544 
545 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CALENDAR_CALENDAR_COMPONENT_H
546