• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_NG_PATTERNS_TIME_PICKER_TIME_PICKER_ROW_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TIME_PICKER_TIME_PICKER_ROW_PATTERN_H
18 
19 #include <optional>
20 
21 #include "base/i18n/localization.h"
22 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
23 #include "core/components_ng/pattern/time_picker/timepicker_column_pattern.h"
24 #include "core/components_ng/pattern/time_picker/timepicker_event_hub.h"
25 #include "core/components_ng/pattern/time_picker/timepicker_layout_property.h"
26 #include "core/components_ng/pattern/time_picker/timepicker_paint_method.h"
27 #include "core/components_ng/pattern/time_picker/timepicker_row_accessibility_property.h"
28 #include "core/components_v2/inspector/utils.h"
29 
30 namespace OHOS::Ace::NG {
31 namespace {
32 const Dimension TIME_FOCUS_PAINT_WIDTH = 2.0_vp;
33 }
34 
35 class TimePickerRowPattern : public LinearLayoutPattern {
36     DECLARE_ACE_TYPE(TimePickerRowPattern, LinearLayoutPattern);
37 
38 public:
TimePickerRowPattern()39     TimePickerRowPattern() : LinearLayoutPattern(false) {};
40 
41     ~TimePickerRowPattern() override = default;
42 
IsAtomicNode()43     bool IsAtomicNode() const override
44     {
45         return true;
46     }
47 
CreateEventHub()48     RefPtr<EventHub> CreateEventHub() override
49     {
50         return MakeRefPtr<TimePickerEventHub>();
51     }
52 
CreateNodePaintMethod()53     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
54     {
55         auto paintMethod = MakeRefPtr<TimePickerPaintMethod>();
56         paintMethod->SetEnabled(enabled_);
57         paintMethod->SetBackgroundColor(backgroundColor_);
58         return paintMethod;
59     }
60 
CreateLayoutAlgorithm()61     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
62     {
63         return MakeRefPtr<LinearLayoutAlgorithm>();
64     }
65 
SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode)66     void SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode)
67     {
68         weakButtonConfirm_ = buttonConfirmNode;
69     }
70 
SetCancelNode(WeakPtr<FrameNode> buttonCancelNode)71     void SetCancelNode(WeakPtr<FrameNode> buttonCancelNode)
72     {
73         weakButtonCancel_ = buttonCancelNode;
74     }
75 
76     void OnLanguageConfigurationUpdate() override;
77 
CreateLayoutProperty()78     RefPtr<LayoutProperty> CreateLayoutProperty() override
79     {
80         return MakeRefPtr<TimePickerLayoutProperty>();
81     }
82 
CreateAccessibilityProperty()83     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
84     {
85         return MakeRefPtr<TimePickerRowAccessibilityProperty>();
86     }
87 
88     void OnColumnsBuilding();
89 
GetAllChildNode()90     const std::unordered_map<std::string, RefPtr<FrameNode>>& GetAllChildNode()
91     {
92         return allChildNode_;
93     }
94 
95     void UpdateAllChildNode();
96 
97     void HandleHourColumnBuilding();
98 
99     void FlushColumn();
100 
101     void FlushAmPmFormatString();
102 
103     void OnDataLinking(
104         const RefPtr<FrameNode>& tag, bool isAdd, uint32_t index, std::vector<RefPtr<FrameNode>>& resultTags);
105 
106     void HandleHour12Change(bool isAdd, uint32_t index, std::vector<RefPtr<FrameNode>>& resultTags);
107 
108     void SetChangeCallback(ColumnChangeCallback&& value);
109 
110     void HandleColumnChange(const RefPtr<FrameNode>& tag, bool isAdd, uint32_t index, bool needNotify);
111 
112     void SetEventCallback(EventCallback&& value);
113 
114     void FireChangeEvent(bool refresh);
115 
116     std::string GetSelectedObject(bool isColumnChange, int32_t status = -1);
117 
118     PickerTime GetCurrentTime();
119 
120     uint32_t GetHourFromAmPm(bool isAm, uint32_t amPmhour) const;
121 
HasTitleNode()122     bool HasTitleNode() const
123     {
124         return titleId_.has_value();
125     }
126 
GetTitleId()127     int32_t GetTitleId()
128     {
129         if (!titleId_.has_value()) {
130             titleId_ = ElementRegister::GetInstance()->MakeUniqueId();
131         }
132         return titleId_.value();
133     }
134 
GetShowCount()135     uint32_t GetShowCount() const
136     {
137         return showCount_;
138     }
139 
SetShowCount(uint32_t showCount)140     void SetShowCount(uint32_t showCount)
141     {
142         showCount_ = showCount;
143     }
144 
GetOptionCount(const RefPtr<FrameNode> & frameNode)145     uint32_t GetOptionCount(const RefPtr<FrameNode>& frameNode)
146     {
147         return optionsTotalCount_[frameNode];
148     }
149 
GetOptionValue(const RefPtr<FrameNode> & frmeNode,uint32_t index)150     std::string GetOptionValue(const RefPtr<FrameNode>& frmeNode, uint32_t index)
151     {
152         if (index >= GetOptionCount(frmeNode)) {
153             LOGE("index out of range.");
154             return nullptr;
155         }
156         return options_[frmeNode][index];
157     }
158 
HasDividerNode()159     bool HasDividerNode() const
160     {
161         return DividerId_.has_value();
162     }
163 
GetDividerId()164     int32_t GetDividerId()
165     {
166         if (!DividerId_.has_value()) {
167             DividerId_ = ElementRegister::GetInstance()->MakeUniqueId();
168         }
169         return DividerId_.value();
170     }
171 
172     const std::string& GetOptionsValue(const RefPtr<FrameNode>& frameNode, uint32_t optionIndex);
173 
GetOptionsCount()174     const std::map<RefPtr<FrameNode>, uint32_t>& GetOptionsCount() const
175     {
176         return optionsTotalCount_;
177     }
178 
SetHour24(bool value)179     void SetHour24(bool value)
180     {
181         hour24_ = value;
182     }
183 
GetHour24()184     bool GetHour24() const
185     {
186         auto timePickerLayoutProperty = GetLayoutProperty<TimePickerLayoutProperty>();
187         CHECK_NULL_RETURN(timePickerLayoutProperty, hour24_);
188         return timePickerLayoutProperty->GetIsUseMilitaryTimeValue(hour24_);
189     }
190 
ClearOptionsHour()191     void ClearOptionsHour()
192     {
193         // when switch IsUseMilitaryTime state, should clear options_[hourColumn]
194         // Hour24 : Index = [0, 23] -> hour = [0, 23]
195         // Hour12 : Index = [0, 11] -> hour = [1, 12]
196         auto hourColumn = allChildNode_["hour"];
197         CHECK_NULL_VOID(hourColumn);
198         options_[hourColumn].clear();
199     }
200 
SetSelectedTime(const PickerTime & value)201     void SetSelectedTime(const PickerTime& value)
202     {
203         selectedTime_ = value;
204     }
205 
GetSelectedTime()206     const PickerTime& GetSelectedTime()
207     {
208         return selectedTime_;
209     }
210 
SetDialogTitleDate(const PickerDate & value)211     void SetDialogTitleDate(const PickerDate& value)
212     {
213         dialogTitleDate_ = value;
214     }
215 
GetDialogTitleDate()216     const PickerDate& GetDialogTitleDate()
217     {
218         return dialogTitleDate_;
219     }
220 
HasAmPmNode()221     bool HasAmPmNode() const
222     {
223         return amPmId_.has_value();
224     }
225 
GetAmPmId()226     int32_t GetAmPmId()
227     {
228         if (!amPmId_.has_value()) {
229             amPmId_ = ElementRegister::GetInstance()->MakeUniqueId();
230         }
231         return amPmId_.value();
232     }
233 
HasHourNode()234     bool HasHourNode() const
235     {
236         return hourId_.has_value();
237     }
238 
GetHourId()239     int32_t GetHourId()
240     {
241         if (!hourId_.has_value()) {
242             hourId_ = ElementRegister::GetInstance()->MakeUniqueId();
243         }
244         return hourId_.value();
245     }
246 
HasMinuteNode()247     bool HasMinuteNode() const
248     {
249         return minuteId_.has_value();
250     }
251 
GetMinuteId()252     int32_t GetMinuteId()
253     {
254         if (!minuteId_.has_value()) {
255             minuteId_ = ElementRegister::GetInstance()->MakeUniqueId();
256         }
257         return minuteId_.value();
258     }
259 
GetHasSecond()260     bool GetHasSecond() const
261     {
262         return hasSecond_;
263     }
SetHasSecond(bool value)264     void SetHasSecond(bool value)
265     {
266         hasSecond_ = value;
267     }
268 
GetColumn(int32_t tag)269     RefPtr<FrameNode> GetColumn(int32_t tag) const
270     {
271         auto iter = std::find_if(timePickerColumns_.begin(), timePickerColumns_.end(),
272             [tag](const RefPtr<FrameNode>& column) { return column->GetId() == tag; });
273         return (iter == timePickerColumns_.end()) ? nullptr : *iter;
274     }
275 
SetColumn(const RefPtr<FrameNode> & value)276     void SetColumn(const RefPtr<FrameNode>& value)
277     {
278         timePickerColumns_.emplace_back(value);
279     }
280 
SetBackgroundColor(const Color & color)281     void SetBackgroundColor(const Color& color)
282     {
283         backgroundColor_ = color;
284     }
285 
286     bool IsAmHour(uint32_t hourOf24) const;
287 
288     uint32_t GetAmPmHour(uint32_t hourOf24) const;
289 
290     std::string GetAmFormatString() const;
291 
292     std::string GetPmFormatString() const;
293 
294     std::string AddZeroPrefix(const std::string& value) const;
295 
296     std::string GetHourFormatString(uint32_t hour) const;
297 
298     std::string GetMinuteFormatString(uint32_t minute) const;
299 
GetFocusPattern()300     FocusPattern GetFocusPattern() const override
301     {
302         auto pipeline = PipelineBase::GetCurrentContext();
303         CHECK_NULL_RETURN(pipeline, FocusPattern());
304         auto pickerTheme = pipeline->GetTheme<PickerTheme>();
305         CHECK_NULL_RETURN(pickerTheme, FocusPattern());
306         auto focusColor = pickerTheme->GetFocusColor();
307         FocusPaintParam focusPaintParams;
308         focusPaintParams.SetPaintColor(focusColor);
309         focusPaintParams.SetPaintWidth(TIME_FOCUS_PAINT_WIDTH);
310         return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParams };
311     }
312 
ToJsonValue(std::unique_ptr<JsonValue> & json)313     void ToJsonValue(std::unique_ptr<JsonValue>& json) const override
314     {
315         json->Put("selected", selectedTime_.ToString(false, false).c_str());
316     }
317 
318     void CreateAmPmNode();
319     void OnColorConfigurationUpdate() override;
320 
SetContentRowNode(RefPtr<FrameNode> & contentRowNode)321     void SetContentRowNode(RefPtr<FrameNode>& contentRowNode)
322     {
323         contentRowNode_ = contentRowNode;
324     }
325 
SetbuttonTitleNode(RefPtr<FrameNode> & buttonTitleNode)326     void SetbuttonTitleNode(RefPtr<FrameNode>& buttonTitleNode)
327     {
328         buttonTitleNode_ = buttonTitleNode;
329     }
330 
SetPickerTag(bool isPicker)331     void SetPickerTag(bool isPicker)
332     {
333         isPicker_ = isPicker;
334     }
335 
336     void SetFocusDisable();
337     void SetFocusEnable();
338 
339 private:
340     void OnModifyDone() override;
341     void OnAttachToFrameNode() override;
342     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
343 
344     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
345     bool OnKeyEvent(const KeyEvent& event);
346     bool HandleDirectionKey(KeyCode code);
347     void InitDisabled();
348     void GetInnerFocusPaintRect(RoundRect& paintRect);
349     void PaintFocusState();
350     void SetButtonIdeaSize();
351     double SetAmPmButtonIdeaSize();
352 
353     RefPtr<ClickEvent> clickEventListener_;
354     bool enabled_ = true;
355     int32_t focusKeyID_ = 0;
356     std::unordered_map<std::string, RefPtr<FrameNode>> allChildNode_;
357     std::map<RefPtr<FrameNode>, std::unordered_map<uint32_t, std::string>> options_;
358     std::map<RefPtr<FrameNode>, uint32_t> optionsTotalCount_;
359     uint32_t showCount_ = 0;
360     Color backgroundColor_ = Color::WHITE;
361     // true, use 24 hours style; false, use 12 hours style.
362     bool hour24_ = !Localization::GetInstance()->IsAmPmHour();
363     PickerTime selectedTime_ = PickerTime::Current();
364     PickerDate dialogTitleDate_ = PickerDate::Current();
365     std::optional<int32_t> amPmId_;
366     std::optional<int32_t> hourId_;
367     std::optional<int32_t> minuteId_;
368     std::optional<int32_t> titleId_;
369     std::optional<int32_t> ButtonTitleId_;
370     std::optional<int32_t> DividerId_;
371     WeakPtr<FrameNode> weakButtonConfirm_;
372     WeakPtr<FrameNode> weakButtonCancel_;
373 
374     bool hasSecond_ = false;
375     std::vector<RefPtr<FrameNode>> timePickerColumns_;
376     std::vector<std::string> vecAmPm_ = Localization::GetInstance()->GetAmPmStrings();
377 
378     ACE_DISALLOW_COPY_AND_MOVE(TimePickerRowPattern);
379 
380     RefPtr<FrameNode> buttonTitleNode_;
381     RefPtr<FrameNode> contentRowNode_;
382     bool isPicker_ = false;
383 };
384 } // namespace OHOS::Ace::NG
385 
386 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TIME_PICKER_TIME_PICKER_ROW_PATTERN_H
387