1 /*
2  * Copyright (c) 2020-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 #include "components/ui_axis.h"
17 #include "common/screen.h"
18 #include "engines/gfx/gfx_engine_manager.h"
19 
20 namespace OHOS {
UIAxis()21 UIAxis::UIAxis()
22     : maxRange_(0),
23       minRange_(0),
24       start_({0, 0}),
25       end_({0, 0}),
26       markInterval_(0),
27       dataPerMark_(0),
28       dataInterval_(0),
29       markDataCount_(AXIS_DEFAULT_MARK_INTERVAL),
30       enableReverse_(false)
31 {
32     SetStyle(STYLE_LINE_WIDTH, 1);
33     SetStyle(STYLE_LINE_COLOR, Color::White().full);
34 }
35 
SetLineColor(const ColorType & color)36 void UIAxis::SetLineColor(const ColorType& color)
37 {
38     SetStyle(STYLE_LINE_COLOR, color.full);
39 }
40 
SetMarkNum(uint16_t count)41 void UIXAxis::SetMarkNum(uint16_t count)
42 {
43     if ((count == 0) || (count > Screen::GetInstance().GetWidth())) {
44         return;
45     }
46     markDataCount_ = count;
47     UpdateAxis();
48 }
49 
SetDataRange(uint16_t min,uint16_t max)50 bool UIXAxis::SetDataRange(uint16_t min, uint16_t max)
51 {
52     if (max <= min) {
53         return false;
54     }
55     maxRange_ = max;
56     minRange_ = min;
57     return UpdateAxis();
58 }
59 
UpdateAxisPoints()60 void UIXAxis::UpdateAxisPoints()
61 {
62     Rect current = GetContentRect();
63     start_.x = current.GetLeft();
64     end_.x = current.GetRight();
65     start_.y = enableReverse_ ? current.GetTop() : current.GetBottom();
66     end_.y = start_.y;
67 }
68 
UpdateAxis()69 bool UIXAxis::UpdateAxis()
70 {
71     UpdateAxisPoints();
72     int16_t xAxisLength = end_.x - start_.x + 1;
73     if (xAxisLength <= 0) {
74         return false;
75     }
76 
77     if (markDataCount_ != 0) {
78         dataInterval_ = static_cast<float>((maxRange_ - minRange_) / markDataCount_);
79         markInterval_ = static_cast<float>(xAxisLength) / markDataCount_;
80         if (maxRange_ > minRange_) {
81             dataPerMark_ = markInterval_ / dataInterval_;
82         }
83     }
84 
85     return true;
86 }
87 
TranslateToPixel(int16_t & value)88 void UIXAxis::TranslateToPixel(int16_t& value)
89 {
90     float minXStep = dataPerMark_ ? dataPerMark_ : markInterval_;
91     value = start_.x + static_cast<int16_t>((value - minRange_) * minXStep);
92 }
93 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)94 void UIAxis::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
95 {
96     BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start_, end_, invalidatedArea, style_->lineWidth_,
97                                            style_->lineColor_, style_->lineOpa_);
98     DrawAxisMark(gfxDstBuffer, invalidatedArea);
99 }
100 
DrawAxisMark(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)101 void UIXAxis::DrawAxisMark(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
102 {
103     Point start;
104     Point end;
105     uint16_t index = 1;
106     while (index <= markDataCount_) {
107         start.y = start_.y;
108         start.x = start_.x + static_cast<int16_t>(index * markInterval_);
109         end.y = enableReverse_ ? (start.y + AXIS_DEFAULT_MARK_LENGTH) : (start.y - AXIS_DEFAULT_MARK_LENGTH);
110         end.x = start.x;
111 
112         BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea,
113                                                style_->lineWidth_, style_->lineColor_, style_->lineOpa_);
114         index++;
115     }
116 }
117 
SetMarkNum(uint16_t count)118 void UIYAxis::SetMarkNum(uint16_t count)
119 {
120     if ((count == 0) || (count > Screen::GetInstance().GetHeight())) {
121         return;
122     }
123     markDataCount_ = count;
124     dataInterval_ = static_cast<float>((maxRange_ - minRange_) / markDataCount_);
125 }
126 
SetDataRange(uint16_t min,uint16_t max)127 bool UIYAxis::SetDataRange(uint16_t min, uint16_t max)
128 {
129     if (max <= min) {
130         return false;
131     }
132 
133     maxRange_ = max;
134     minRange_ = min;
135     return UpdateAxis();
136 }
137 
UpdateAxisPoints()138 void UIYAxis::UpdateAxisPoints()
139 {
140     Rect current = GetContentRect();
141     int16_t top = current.GetTop();
142     int16_t bottom = current.GetBottom();
143 
144     start_.x = current.GetLeft();
145     end_.x = start_.x;
146     if (enableReverse_) {
147         start_.y = top;
148         end_.y = bottom;
149     } else {
150         start_.y = bottom;
151         end_.y = top;
152     }
153 }
154 
TranslateToPixel(int16_t & value)155 void UIYAxis::TranslateToPixel(int16_t& value)
156 {
157     float minYStep = dataPerMark_ ? dataPerMark_ : markInterval_;
158     if (enableReverse_) {
159         value = start_.y + static_cast<int16_t>((maxRange_ - value + minRange_) * minYStep);
160     } else {
161         value = start_.y - static_cast<int16_t>((value - minRange_) * minYStep);
162     }
163 }
164 
UpdateAxis()165 bool UIYAxis::UpdateAxis()
166 {
167     UpdateAxisPoints();
168     int16_t yAxisLength = enableReverse_ ? (end_.y - start_.y + 1) : (start_.y - end_.y + 1);
169     if (yAxisLength <= 0) {
170         return false;
171     }
172 
173     if (markDataCount_ != 0) {
174         dataInterval_ = static_cast<float>((maxRange_ - minRange_) / markDataCount_);
175         markInterval_ = static_cast<float>(yAxisLength) / markDataCount_;
176         if (dataInterval_ != 0) {
177             dataPerMark_ = markInterval_ / dataInterval_;
178         }
179     }
180     return true;
181 }
182 
DrawAxisMark(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)183 void UIYAxis::DrawAxisMark(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
184 {
185     uint16_t index = 1;
186     while (index <= markDataCount_) {
187         Point start;
188         Point end;
189         start.x = start_.x;
190         start.y = enableReverse_ ? (start_.y + static_cast<int16_t>(index * markInterval_))
191                                  : (start_.y - static_cast<int16_t>(index * markInterval_));
192         end.x = start.x + AXIS_DEFAULT_MARK_LENGTH;
193         end.y = start.y;
194 
195         BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea,
196                                                style_->lineWidth_, style_->lineColor_, style_->lineOpa_);
197         index++;
198     }
199 }
200 } // namespace OHOS
201