• 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 package ohos.devtools.views.trace.component;
17 
18 import com.intellij.ui.components.JBBox;
19 import ohos.devtools.views.trace.bean.WakeupBean;
20 import ohos.devtools.views.trace.listener.IScrollSliceLinkListener;
21 import ohos.devtools.views.trace.util.Final;
22 import ohos.devtools.views.trace.util.TimeUtils;
23 import ohos.devtools.views.trace.util.Utils;
24 
25 import javax.imageio.ImageIO;
26 import java.awt.AlphaComposite;
27 import java.awt.Color;
28 import java.awt.Composite;
29 import java.awt.Cursor;
30 import java.awt.Font;
31 import java.awt.Graphics;
32 import java.awt.Graphics2D;
33 import java.awt.Image;
34 import java.awt.Rectangle;
35 import java.awt.RenderingHints;
36 import java.awt.event.MouseEvent;
37 import java.awt.event.MouseMotionAdapter;
38 import java.awt.geom.Rectangle2D;
39 import java.io.IOException;
40 import java.util.ArrayList;
41 import java.util.List;
42 
43 /**
44  * bottom Slice panel
45  *
46  * @since 2021/04/20 12:24
47  */
48 public class ScrollSlicePanel extends BottomScrollPanel {
49     private Font font = getFont();
50     private List<LineComponent> comps = new ArrayList<>();
51     private List<SliceData> dataSource;
52     private WakeupBean wakeupBean;
53     private IScrollSliceLinkListener listener;
54 
55     /**
56      * create table line data
57      *
58      * @param key key
59      * @param value value
60      * @param linkable link
61      * @return SliceData data
62      */
createSliceData(String key, String value, boolean linkable)63     public static SliceData createSliceData(String key, String value, boolean linkable) {
64         SliceData data = new SliceData();
65         data.key = key;
66         data.value = value;
67         data.linkable = linkable;
68         return data;
69     }
70 
71     /**
72      * set component data source
73      *
74      * @param title table title
75      * @param dataSource table data source
76      * @param wakeupBean wakeup data information
77      */
setData(String title, List<SliceData> dataSource, WakeupBean wakeupBean)78     public void setData(String title, List<SliceData> dataSource, WakeupBean wakeupBean) {
79         this.dataSource = dataSource;
80         this.wakeupBean = wakeupBean;
81         box.removeAll();
82         JBBox b1 = JBBox.createVerticalBox();
83         b1.add(new TitlePanel(title));
84         comps.clear();
85         if (dataSource != null) {
86             for (SliceData sliceData : dataSource) {
87                 LineComponent lc = new LineComponent(sliceData.key, sliceData.value == null ? "" : sliceData.value,
88                     sliceData.linkable);
89                 lc.setListener(listener);
90                 comps.add(lc);
91                 b1.add(lc);
92             }
93         }
94         b1.add(JBBox.createVerticalGlue());
95         JBBox b2 = JBBox.createVerticalBox();
96         b2.add(new RightPanel());
97         b2.add(JBBox.createVerticalGlue());
98         box.add(b1);
99         box.add(b2);
100         revalidate();
101     }
102 
103     /**
104      * set link click listener
105      *
106      * @param listener listener
107      */
setScrollSliceLinkListener(IScrollSliceLinkListener listener)108     public void setScrollSliceLinkListener(IScrollSliceLinkListener listener) {
109         this.listener = listener;
110         for (LineComponent comp : comps) {
111             if (comp.linkable) {
112                 comp.setListener(listener);
113             }
114         }
115     }
116 
117     /**
118      * SliceData
119      *
120      * @since 2021/04/20 12:24
121      */
122     public static class SliceData {
123         /**
124          * parameter key
125          */
126         protected String key;
127 
128         /**
129          * parameter value
130          */
131         protected String value;
132 
133         /**
134          * parameter linkable
135          */
136         protected boolean linkable;
137     }
138 
139     /**
140      * RightPanel
141      *
142      * @since 2021/04/20 12:24
143      */
144     class RightPanel extends ChildPanel {
145         private final int[][] pointX = {{11, 2, 11, 20}, {13, 13, 18, 20, 15, 20, 18}, {103, 103, 98, 96, 101, 96, 98}};
146         private final int[][] pointY = {{50, 58, 66, 58}, {120, 124, 129, 127, 122, 117, 115}};
147         private final int strStartX = 30;
148         private final int lineCharSize = 60;
149 
150         /**
151          * RightPanel constructor
152          */
RightPanel()153         public RightPanel() {
154             super(0, 222);
155         }
156 
157         /**
158          * paint
159          *
160          * @param graphics graphics
161          */
162         @Override
paint(Graphics graphics)163         public void paint(Graphics graphics) {
164             super.paint(graphics);
165             setFont(Final.NORMAL_FONT);
166             if (wakeupBean == null || wakeupBean.getWakeupProcess() == null) {
167                 return;
168             }
169             graphics.setFont(font.deriveFont(13f));
170             if (graphics instanceof Graphics2D) {
171                 ((Graphics2D) graphics)
172                     .setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
173                 ((Graphics2D) graphics)
174                     .setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
175             }
176             graphics.drawString("Scheduling Latency", 10, 20);
177             graphics.fillRect(10, 30, 3, 130);
178             graphics.fillPolygon(pointX[0], pointY[0], pointX[0].length);
179             graphics.fillPolygon(pointX[1], pointY[1], pointX[1].length);
180             graphics.fillPolygon(pointX[2], pointY[1], pointX[2].length);
181             graphics.fillRect(13, 121, 90, 3);
182             graphics.setFont(font.deriveFont(11f));
183             graphics.drawString(
184                 "Wakeup @" + TimeUtils.getTimeString(wakeupBean.getWakeupTime()) + " on CPU " + wakeupBean
185                     .getWakeupCpu() + " by", strStartX, 55);
186             graphics
187                 .drawString("P:" + wakeupBean.getWakeupProcess() + " [ " + wakeupBean.getWakeupPid() + " ]", strStartX,
188                     75);
189             graphics
190                 .drawString("T:" + wakeupBean.getWakeupThread() + " [ " + wakeupBean.getWakeupTid() + " ]", strStartX,
191                     95);
192             graphics.drawString("Scheduling latency:" + TimeUtils.getTimeString(wakeupBean.getSchedulingLatency()), 115,
193                 125);
194             graphics.setFont(font.deriveFont(9f));
195             graphics.setColor(new Color(0x88, 0x88, 0x88));
196             int lines = wakeupBean.getSchedulingDesc().length() % lineCharSize == 0
197                 ? wakeupBean.getSchedulingDesc().length() / lineCharSize
198                 : wakeupBean.getSchedulingDesc().length() / lineCharSize + 1;
199             for (int index = 0; index < lines; index++) {
200                 String str = "";
201                 if (index == lines - 1) {
202                     str = wakeupBean.getSchedulingDesc().substring(index * lineCharSize);
203                 } else {
204                     str = wakeupBean.getSchedulingDesc().substring(index * lineCharSize, (index + 1) * lineCharSize);
205                 }
206                 graphics.drawString(str, 115, 142 + index * 14);
207             }
208             setFont(Final.NORMAL_FONT);
209         }
210     }
211 
212     /**
213      * TitlePanel
214      *
215      * @since 2021/04/20 12:24
216      */
217     class TitlePanel extends ChildLineComponent {
218         private String title;
219 
220         /**
221          * set title
222          *
223          * @param title title
224          */
TitlePanel(String title)225         public TitlePanel(String title) {
226             this.title = title;
227             setFont(Final.NORMAL_FONT);
228         }
229 
230         /**
231          * paint
232          *
233          * @param graphics graphics
234          */
235         @Override
paint(Graphics graphics)236         public void paint(Graphics graphics) {
237             super.paint(graphics);
238             graphics.setFont(font.deriveFont(13f));
239             graphics.drawString(title, 10, 20);
240         }
241     }
242 
243     /**
244      * LineComponent
245      *
246      * @since 2021/04/20 12:24
247      */
248     class LineComponent extends ChildLineComponent {
249         /**
250          * linkable
251          */
252         private boolean linkable;
253         private final int leftW = 200;
254         private String key;
255         private String value;
256         private IScrollSliceLinkListener listener;
257         private Rectangle linkRect;
258 
259         /**
260          * LineComponent constructor
261          *
262          * @param key key
263          * @param value value
264          * @param linkable linkable
265          */
LineComponent(String key, String value, boolean linkable)266         public LineComponent(String key, String value, boolean linkable) {
267             super();
268             this.key = key;
269             this.value = value;
270             this.linkable = linkable;
271             addMouseMotionListener(new MouseMotionAdapter() {
272                 @Override
273                 public void mouseMoved(final MouseEvent event) {
274                     if (Utils.pointInRect(linkRect, event.getX(), event.getY())) {
275                         setCursor(new Cursor(Cursor.HAND_CURSOR));
276                     } else {
277                         setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
278                     }
279                 }
280             });
281         }
282 
283         /**
284          * set link listener
285          *
286          * @param listener listener
287          */
setListener(IScrollSliceLinkListener listener)288         public void setListener(IScrollSliceLinkListener listener) {
289             this.listener = listener;
290         }
291 
292         /**
293          * child mouse clicked
294          *
295          * @param event event
296          */
297         @Override
childMouseClicked(final MouseEvent event)298         public void childMouseClicked(final MouseEvent event) {
299             if (Utils.pointInRect(linkRect, event.getX(), event.getY())) {
300                 if (listener != null) {
301                     listener.linkClick(value);
302                 }
303             }
304         }
305 
306         /**
307          * paint
308          *
309          * @param graphics graphics
310          */
311         @Override
paint(Graphics graphics)312         public void paint(Graphics graphics) {
313             super.paint(graphics);
314             graphics.setFont(font.deriveFont(11f));
315             if (graphics instanceof Graphics2D) {
316                 ((Graphics2D) graphics)
317                     .setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
318             }
319             if (mouseIn) {
320                 if (graphics instanceof Graphics2D) {
321                     graphics.setColor(getForeground());
322                     Composite originalComposite = ((Graphics2D) graphics).getComposite();
323                     ((Graphics2D) graphics).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.15f));
324                     graphics.fillRect(0, 0, leftW - 2, lineHeight);
325                     graphics.fillRect(leftW, 0, getWidth() - leftW, lineHeight);
326                     ((Graphics2D) graphics).setComposite(originalComposite);
327                 }
328             }
329             graphics.setColor(getForeground());
330             graphics.drawString(key, 10, lineHeight / 2 + 4);
331             int sw = getWidth() - (leftW + 2);
332             int chars = sw / 7;
333             if (value.length() > chars && chars > 0) {
334                 String vs1 = value.substring(0, chars);
335                 String vs2 = value.substring(chars, value.length() - 1);
336                 graphics.drawString(vs1, leftW + 2, lineHeight / 3);
337                 graphics.drawString(vs2, leftW + 2, (lineHeight * 2) / 3);
338             } else {
339                 graphics.drawString(value, leftW, lineHeight / 2 + 4);
340             }
341             if (linkable) {
342                 try {
343                     if (value != null && value.length() > 0) {
344                         Rectangle2D bounds = graphics.getFontMetrics(font).getStringBounds(value, graphics);
345                         linkRect = new Rectangle((int) (202 + bounds.getWidth() + 5), (lineHeight - 20) / 2, 20, 20);
346                         Image link = ImageIO.read(getClass().getResourceAsStream("/assets/link.png"));
347                         graphics.drawImage(link, Utils.getX(linkRect) + 2, Utils.getY(linkRect) + 3, 15, 15, null);
348                     }
349                 } catch (IOException ioException) {
350                     ioException.printStackTrace();
351                 }
352             }
353         }
354     }
355 }
356