• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2023 Shenzhen Kaihong Digital Industry Development 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 */
15const { X2DFast } = require('./graphics/X2DFast');
16const { Scr } = require('./XDefine');
17const { XTools } = require('./XTools');
18
19const MenuType = {
20  BUTTON: 0, // 按钮
21  CONTENT: 1, // 目录
22  DIVIDER: 2, // 分割线
23};
24
25const MenuGroupSize = {
26  DELETE: 1, // 目录
27  NODEMENU: 3, // 分割线
28};
29
30const MOUSETYPE_MOVE = 2;
31const DRAWTEXT_OFFSETX = -3;
32const DRAWTEXT_OFFSETY = -2;
33
34class RightMenu {
35  static backgroundImg_ = -1;
36  static backgroundCut_ = -1;
37
38  static popItemFocusImg_ = -1;
39  static popItemFocusCut_ = -1;
40  static MENU = null;
41  static PADDING = 16;
42  static FOCUS_ITEM_MARGIN = 4;
43  static FOCUS_ITEM_HEIGHT = 32;
44  static TEXT_SIZE = 14;
45  static isDarkBackground_ = true;
46  static Reset(detail, x, y) {
47    RightMenu.MENU = {
48      x: x === null ? XTools.MOUSE_POS.x : x,
49      y: y === null ? XTools.MOUSE_POS.y : y,
50      detail: detail,
51      needClose: false,
52    };
53  }
54  static Append(detail) {
55    if (RightMenu.MENU) {
56      RightMenu.MENU.detail.push(...detail);
57    }
58  }
59  static Button(icon, name, hootkey, callback) {
60    return {
61      type: 0,
62      icon: icon,
63      name: name,
64      hk: hootkey,
65      cb: () => {
66        callback(this);
67        RightMenu.close();
68      },
69    };
70  }
71  static Group(icon, name, objs) {
72    return {
73      type: 1,
74      icon: icon,
75      name: name,
76      open: false,
77      group: objs,
78    };
79  }
80  static Gap() {
81    return {
82      type: 2,
83    };
84  }
85  static close() {
86    if (RightMenu.MENU) {
87      RightMenu.MENU.needClose = true;
88    }
89  }
90  static Draw() {
91    if (RightMenu.MENU) {
92      RightMenu.DrawGroup(
93        RightMenu.MENU.detail,
94        RightMenu.MENU.x,
95        RightMenu.MENU.y
96      );
97      if (RightMenu.MENU.needClose) {
98        RightMenu.MENU = null;
99      }
100    }
101  }
102  static MENUW = 155;
103  static DrawGroup(grp, x, y) {
104    let w = RightMenu.MENUW;
105    let l = 0;
106    for (let e of grp) {
107      if (e.type !== MenuType.DIVIDER) {
108        l += 1;
109      }
110    }
111    if (grp.length === MenuGroupSize.NODEMENU) {
112      X2DFast.px2f.drawCut(this.backgroundCut_, x, y, 1, 0.88, 0, -1, -1);
113    } else if (grp.length === MenuGroupSize.DELETE) {
114      X2DFast.px2f.drawCut(this.backgroundCut_, x, y, 1, 0.3, 0, -1, -1);
115    } else {
116      X2DFast.px2f.drawCut(this.backgroundCut_, x, y, 1, 1, 0, -1, -1);
117    }
118    for (let e of grp) {
119      e.rect = [x, y, w, 32];
120      if (e.on) {
121        X2DFast.px2f.drawCut(
122          this.popItemFocusCut_,
123          x + RightMenu.FOCUS_ITEM_MARGIN,
124          y
125        );
126      }
127      if (e.type === MenuType.DIVIDER) {
128        e.rect = [x, y, w, 0];
129        X2DFast.px2f.drawLine(x, y, x + w, y, 0xff808080, 2);
130        continue;
131      }
132      let OFFY_ = y + RightMenu.FOCUS_ITEM_HEIGHT / 2 - RightMenu.TEXT_SIZE / 2;
133      let textColor = this.isDarkBackground_ ? 0xffffffff : 0xff000000;
134      X2DFast.px2f.drawText(
135        e.name,
136        RightMenu.TEXT_SIZE,
137        x + RightMenu.PADDING,
138        OFFY_,
139        1,
140        1,
141        0,
142        0,
143        0,
144        textColor
145      );
146      if (e.type === MenuType.BUTTON) {
147        if (e.hk) {
148          X2DFast.px2f.drawText(
149            e.hk,
150            RightMenu.TEXT_SIZE,
151            x + w,
152            OFFY_,
153            1,
154            1,
155            0,
156            -3,
157            -2,
158            0xff808080
159          );
160        }
161      } else if (e.type === MenuType.CONTENT) {
162        if (e.open) {
163          RightMenu.callDrawText('<', x, w, OFFY_, textColor);
164          RightMenu.DrawGroup(e.group, x + w, y);
165        } else {
166          RightMenu.callDrawText('>', x, w, OFFY_, textColor);
167        }
168      }
169      y += 32;
170    }
171  }
172  static callDrawText(symbol, x, w, OFFY_, textColor) {
173    X2DFast.px2f.drawText(symbol, RightMenu.TEXT_SIZE, x + w, OFFY_, 1, 1, 0,
174      DRAWTEXT_OFFSETX, DRAWTEXT_OFFSETY, textColor);
175  }
176
177  static Touch(msg, x, y) {
178    if (RightMenu.MENU) {
179      if (RightMenu.TouchGroup(RightMenu.MENU.detail, msg, x, y)) {
180        return true;
181      } else if (msg !== MOUSETYPE_MOVE) {
182        RightMenu.MENU.needClose = true;
183      }
184    }
185    return false;
186  }
187
188  isClicked() {
189    if (this.clicked_) {
190      this.clicked_ = false;
191      return true;
192    }
193    return false;
194  }
195
196  static TouchGroup(grp, msg, x, y) {
197    for (let e of grp) {
198      e.on = false;
199    }
200    for (let e of grp) {
201      if (!e.rect) {
202        return false;
203      }
204      if (XTools.InRect(x, y, ...e.rect)) {
205        if (e.type === MenuType.CONTENT && msg === 1) {
206          e.open = !e.open;
207        }
208        if (e.type === MenuType.DIVIDER) {
209        }
210        if (e.type === MenuType.BUTTON) {
211          if (msg === 1) {
212            e.cb();
213          }
214        }
215        e.on = true;
216        return true;
217      }
218      if (e.type === MenuType.CONTENT) {
219        if (e.open && RightMenu.TouchGroup(e.group, msg, x, y)) {
220          return true;
221        }
222      }
223    }
224    return false;
225  }
226}
227
228module.exports = {
229  RightMenu,
230};
231