• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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