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 #include "layout_controller.h"
17
18 #include <algorithm>
19 #include <cmath>
20 #include <fstream>
21 #include <iostream>
22 #include <regex>
23 #include <sstream>
24
25 #include "layout_header.h"
26 #include "rects.h"
27 #include "weston.h"
28
29
30 #define LOG_LABEL "wms-wmlayout"
31
32 #define LOGD(fmt, ...) weston_log("%{public}s debug %{public}d:%{public}s " fmt "\n", \
33 LOG_LABEL, __LINE__, __func__, ##__VA_ARGS__)
34
35 #define LOGI(fmt, ...) weston_log("%{public}s info %{public}d:%{public}s " fmt "\n", \
36 LOG_LABEL, __LINE__, __func__, ##__VA_ARGS__)
37
38 #define LOGE(fmt, ...) weston_log("%{public}s error %{public}d:%{public}s " fmt "\n", \
39 LOG_LABEL, __LINE__, __func__, ##__VA_ARGS__)
40
41 // C interface
LayoutControllerInit(int32_t width,int32_t height)42 void LayoutControllerInit(int32_t width, int32_t height)
43 {
44 OHOS::WMServer::LayoutController::GetInstance().Init(width, height);
45 }
46
LayoutControllerCalcWindowDefaultLayout(uint32_t type,uint32_t mode,uint32_t * zIndex,struct layout * outLayout)47 int32_t LayoutControllerCalcWindowDefaultLayout(uint32_t type,
48 uint32_t mode, uint32_t *zIndex, struct layout *outLayout)
49 {
50 struct OHOS::WMServer::Layout layout = {};
51 auto ret = OHOS::WMServer::LayoutController::GetInstance().CalcWindowDefaultLayout(type, mode, layout);
52 if (zIndex != nullptr) {
53 *zIndex = layout.zIndex;
54 }
55 if (outLayout != nullptr) {
56 *outLayout = layout.layout;
57 }
58 return ret;
59 }
60
61 // C++ interface
62 namespace OHOS::WMServer {
GetInstance()63 LayoutController &LayoutController::GetInstance()
64 {
65 static LayoutController instance;
66 return instance;
67 }
68
Init(int32_t width,int32_t height)69 void LayoutController::Init(int32_t width, int32_t height)
70 {
71 displayWidth = width;
72 displayHeight = height;
73 if (!init) {
74 InitByDefaultValue();
75 InitByParseSCSS();
76 init = true;
77 }
78 }
79
CalcWindowDefaultLayout(uint32_t type,uint32_t mode,struct Layout & outLayout)80 int32_t LayoutController::CalcWindowDefaultLayout(uint32_t type, uint32_t mode, struct Layout &outLayout)
81 {
82 auto it = modeLayoutMap[mode].find(type);
83 if (it == modeLayoutMap[mode].end()) {
84 if (mode == WINDOW_MODE_UNSET) {
85 return 1;
86 } else {
87 it = modeLayoutMap[WINDOW_MODE_UNSET].find(type);
88 if (it == modeLayoutMap[WINDOW_MODE_UNSET].end()) {
89 return 1;
90 }
91 }
92 }
93
94 struct layout rect = { 0, 0, static_cast<double>(displayWidth), static_cast<double>(displayHeight) };
95 outLayout = it->second;
96 if (outLayout.positionType == Layout::PositionType::RELATIVE) {
97 CalcNormalRect(rect);
98 }
99
100 constexpr double full = 100.0; // 100%
101 constexpr int32_t half = 2;
102 outLayout.layout.x = floor(rect.w * outLayout.layout.x / full + 1e-6);
103 outLayout.layout.y = floor(rect.h * outLayout.layout.y / full + 1e-6);
104 outLayout.layout.w = floor(rect.w * outLayout.layout.w / full + 1e-6);
105 outLayout.layout.h = floor(rect.h * outLayout.layout.h / full + 1e-6);
106 if (outLayout.pTypeX == Layout::XPositionType::LFT) {
107 outLayout.layout.x = floor(rect.x + 1e-6);
108 } else if (outLayout.pTypeX == Layout::XPositionType::MID) {
109 outLayout.layout.x = floor(rect.x + (rect.w - outLayout.layout.w) / half + 1e-6);
110 } else if (outLayout.pTypeX == Layout::XPositionType::RGH) {
111 outLayout.layout.x = floor(rect.x + rect.w - outLayout.layout.w + 1e-6);
112 } else {
113 outLayout.layout.x += floor(rect.x + 1e-6);
114 }
115
116 if (outLayout.pTypeY == Layout::YPositionType::TOP) {
117 outLayout.layout.y = floor(rect.y + 1e-6);
118 } else if (outLayout.pTypeY == Layout::YPositionType::MID) {
119 outLayout.layout.y = floor(rect.y + (rect.h - outLayout.layout.h) / half + 1e-6);
120 } else if (outLayout.pTypeY == Layout::YPositionType::BTM) {
121 outLayout.layout.y = floor(rect.y + rect.h - outLayout.layout.h + 1e-6);
122 } else {
123 outLayout.layout.y += floor(rect.y + 1e-6);
124 }
125 return 0;
126 }
127
128 #define DEF_LYT_MACRO(wt, lt, ptx, pty, _x, _y, _w, _h) \
129 modeLayoutMap[WINDOW_MODE_UNSET][WINDOW_TYPE_##wt] = { \
130 .zIndex = WINDOW_TYPE_##wt, \
131 .positionType = Layout::PositionType::lt, \
132 .pTypeX = Layout::XPositionType::ptx, \
133 .pTypeY = Layout::YPositionType::pty, \
134 .layout = { .x = _x, .y = _y, .w = _w, .h = _h, }, \
135 }
136
137 #define DEF_POS_LYT(lt, ptx, pty, w, h, wt) \
138 DEF_LYT_MACRO(wt, lt, ptx, pty, 0, 0, w, h)
139
140 #define DEF_RCT_LYT(lt, x, y, w, h, wt) \
141 DEF_LYT_MACRO(wt, lt, UNSET, UNSET, x, y, w, h)
142
InitByDefaultValue()143 void LayoutController::InitByDefaultValue()
144 {
145 constexpr double full = 100.0; // 100%
146 DEF_POS_LYT(RELATIVE, MID, MID, full, full, NORMAL);
147 modeLayoutMap[WINDOW_MODE_FREE][WINDOW_TYPE_NORMAL] = {
148 .zIndex = static_cast<int32_t>(51.0 + 1e-6),
149 .positionType = Layout::PositionType::FIXED,
150 .pTypeX = Layout::XPositionType::MID,
151 .pTypeY = Layout::YPositionType::MID,
152 .layout = {
153 .x = 0,
154 .y = 0,
155 .w = full,
156 .h = full,
157 },
158 };
159 DEF_POS_LYT(STATIC, MID, TOP, full, 7.0, STATUS_BAR);
160 DEF_POS_LYT(STATIC, MID, BTM, full, 7.0, NAVI_BAR);
161 DEF_POS_LYT(FIXED, MID, MID, 80.0, 30.0, ALARM_SCREEN);
162 DEF_POS_LYT(FIXED, MID, MID, full, full, SYSTEM_UI);
163 DEF_POS_LYT(RELATIVE, MID, MID, full, full, LAUNCHER);
164 DEF_POS_LYT(FIXED, MID, MID, full, full, VIDEO);
165 DEF_POS_LYT(RELATIVE, MID, BTM, full, 33.3, INPUT_METHOD);
166 DEF_POS_LYT(RELATIVE, MID, BTM, 90.0, 33.3, INPUT_METHOD_SELECTOR);
167 DEF_RCT_LYT(FIXED, 2.5, 2.5, 95.0, 40.0, VOLUME_OVERLAY);
168 DEF_POS_LYT(FIXED, MID, TOP, full, 50.0, NOTIFICATION_SHADE);
169 DEF_RCT_LYT(RELATIVE, 7.5, 7.5, 85.0, 50.0, FLOAT);
170 }
171
InitByParseSCSS()172 void LayoutController::InitByParseSCSS()
173 {
174 return;
175 }
176
CalcNormalRect(struct layout & layout)177 bool LayoutController::CalcNormalRect(struct layout &layout)
178 {
179 Rects totalRects(0, 0, displayWidth, displayHeight);
180 for (const auto &[type, layout] : modeLayoutMap[WINDOW_MODE_UNSET]) {
181 if (layout.positionType == Layout::PositionType::STATIC) {
182 struct Layout nowLayout = {};
183 CalcWindowDefaultLayout(type, WINDOW_MODE_UNSET, nowLayout);
184 Rects rect(static_cast<int32_t>(nowLayout.layout.x + 1e-6),
185 static_cast<int32_t>(nowLayout.layout.y + 1e-6),
186 static_cast<int32_t>(nowLayout.layout.w + 1e-6),
187 static_cast<int32_t>(nowLayout.layout.h + 1e-6));
188 totalRects -= rect;
189 }
190 }
191 if (totalRects.GetSize() == 1) {
192 layout.x = totalRects.GetX(0);
193 layout.y = totalRects.GetY(0);
194 layout.w = totalRects.GetW(0);
195 layout.h = totalRects.GetH(0);
196 return true;
197 }
198 LOGE("CalcNormalRect failed, size: %{public}d", totalRects.GetSize());
199 for (int32_t i = 0; i < totalRects.GetSize(); i++) {
200 LOGE(" +[%{public}d] = (%{public}d, %{public}d) %{public}dx%{public}d", i,
201 totalRects.GetX(i), totalRects.GetY(i), totalRects.GetW(i), totalRects.GetH(i));
202 }
203 return false;
204 }
205
206 } // namespace OHOS::WMServer
207