|
|
|
package com.fr.startup.ui;
|
|
|
|
|
|
|
|
import com.fr.base.svg.IconUtils;
|
|
|
|
import com.fr.design.components.tooltip.ModernToolTip;
|
|
|
|
import com.fr.design.gui.icontainer.UIScrollPane;
|
|
|
|
import com.fr.design.gui.ilable.UILabel;
|
|
|
|
import com.fr.design.gui.itextfield.FRGraphics2D;
|
|
|
|
import com.fr.design.i18n.Toolkit;
|
|
|
|
import com.fr.design.layout.FRGUIPaneFactory;
|
|
|
|
import com.fr.design.utils.ColorUtils;
|
|
|
|
import com.fr.start.common.DesignerStartupContext;
|
|
|
|
import com.fr.startup.metric.DesignerMetrics;
|
|
|
|
import com.fr.third.guava.collect.Lists;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
|
|
|
import javax.swing.BorderFactory;
|
|
|
|
import javax.swing.Icon;
|
|
|
|
import javax.swing.JComponent;
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
import javax.swing.JToolTip;
|
|
|
|
import javax.swing.JViewport;
|
|
|
|
import javax.swing.RepaintManager;
|
|
|
|
import javax.swing.ScrollPaneConstants;
|
|
|
|
import javax.swing.border.EmptyBorder;
|
|
|
|
import java.awt.BasicStroke;
|
|
|
|
import java.awt.BorderLayout;
|
|
|
|
import java.awt.Color;
|
|
|
|
import java.awt.Dimension;
|
|
|
|
import java.awt.FlowLayout;
|
|
|
|
import java.awt.Font;
|
|
|
|
import java.awt.Graphics;
|
|
|
|
import java.awt.Graphics2D;
|
|
|
|
import java.awt.GridLayout;
|
|
|
|
import java.awt.Image;
|
|
|
|
import java.awt.RenderingHints;
|
|
|
|
import java.awt.event.MouseAdapter;
|
|
|
|
import java.awt.event.MouseEvent;
|
|
|
|
import java.awt.image.ImageObserver;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
|
|
import static com.fr.startup.ui.StartupPageConstants.ARC_DIAMETER;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* created by Harrison on 2022/07/06
|
|
|
|
**/
|
|
|
|
public class StartupPageWorkspacePanel extends JPanel {
|
|
|
|
|
|
|
|
/* color */
|
|
|
|
|
|
|
|
private static final Color SHALLOW_WHITE_COLOR = new Color(248, 250, 254);
|
|
|
|
private static final Color HOVER_COLOR = new Color(65, 155, 249);
|
|
|
|
private static final Color PATH_COLOR = new Color(51, 51, 52, (int) Math.round(255 * 0.5));
|
|
|
|
|
|
|
|
/* 长度 */
|
|
|
|
|
|
|
|
private static final int SCROLL_BAR_WIDTH = 20;
|
|
|
|
|
|
|
|
private static final int CONTENT_WIDTH = StartupPageConstants.CONTENT_WIDTH + SCROLL_BAR_WIDTH;
|
|
|
|
private static final int BORDER_THIN = 2;
|
|
|
|
|
|
|
|
private static final int ITEM_VERTICAL_GAP = 20;
|
|
|
|
private static final int SINGLE_ITEM_HEIGHT = 72;
|
|
|
|
private static final int SCROLL_HEIGHT = SINGLE_ITEM_HEIGHT * 4 + ITEM_VERTICAL_GAP * 4;
|
|
|
|
|
|
|
|
private static final int NAME_LABEL_SIZE = 15;
|
|
|
|
private static final int PATH_LABEL_SIZE = 10;
|
|
|
|
|
|
|
|
private static final Dimension LABEL_DIMENSION = new Dimension(28, 28);
|
|
|
|
private static final Dimension PATH_DIMENSION = new Dimension(100, 20);
|
|
|
|
private static final Dimension SELECT_WORKSPACE_DIMENSION = new Dimension(210, 72);
|
|
|
|
private static final Dimension SELECT_CREATE_DIMENSION = new Dimension(60, 72);
|
|
|
|
|
|
|
|
private static final int COLUMN_LIMIT = 3;
|
|
|
|
private static final int DOUBLE_CLICK_COUNT = 2;
|
|
|
|
public static final int PARTITION_LIMIT = 2;
|
|
|
|
|
|
|
|
/* model */
|
|
|
|
|
|
|
|
private final StartupPageModel pageModel;
|
|
|
|
|
|
|
|
private final List<List<StartupWorkspaceBean>> partitions;
|
|
|
|
|
|
|
|
private Runnable selectWorkspaceRunnable;
|
|
|
|
|
|
|
|
private final Runnable createNewTemplateRunnable;
|
|
|
|
|
|
|
|
private final Runnable openEmptyTemplateRunnable;
|
|
|
|
|
|
|
|
private JComponent contentPanel;
|
|
|
|
|
|
|
|
private JPanel tailPanel;
|
|
|
|
|
|
|
|
private boolean showMore = true;
|
|
|
|
|
|
|
|
public StartupPageWorkspacePanel(StartupPageModel pageModel) {
|
|
|
|
|
|
|
|
this.setLayout(new BorderLayout(0, 0));
|
|
|
|
this.setBorder(new EmptyBorder(15, 0, 20, 0));
|
|
|
|
|
|
|
|
this.pageModel = pageModel;
|
|
|
|
|
|
|
|
List<StartupWorkspaceBean> workspaceInfos = pageModel.getWorkspaceInfos();
|
|
|
|
this.partitions = Lists.partition(workspaceInfos, COLUMN_LIMIT);
|
|
|
|
|
|
|
|
this.contentPanel = generateLimitContentPanel(partitions);
|
|
|
|
this.add(contentPanel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
if (partitions.size() > PARTITION_LIMIT) {
|
|
|
|
this.tailPanel = generateTailPanel();
|
|
|
|
this.add(tailPanel, BorderLayout.SOUTH);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.createNewTemplateRunnable = pageModel.getCreateNewTemplateRunnable();
|
|
|
|
this.openEmptyTemplateRunnable = pageModel.getOpenEmptyTemplateRunnable();
|
|
|
|
|
|
|
|
this.repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void showLessContent() {
|
|
|
|
|
|
|
|
this.remove(this.contentPanel);
|
|
|
|
|
|
|
|
this.contentPanel = generateLimitContentPanel(this.partitions);
|
|
|
|
this.add(contentPanel, BorderLayout.NORTH);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void showMoreContent() {
|
|
|
|
|
|
|
|
this.remove(this.contentPanel);
|
|
|
|
|
|
|
|
this.contentPanel = generateUnLimitContentPanel(this.partitions);
|
|
|
|
this.add(contentPanel, BorderLayout.NORTH);
|
|
|
|
}
|
|
|
|
private JComponent generateUnLimitContentPanel(List<List<StartupWorkspaceBean>> partitions) {
|
|
|
|
|
|
|
|
JComponent panel = generateUnLimitContentPanel0(partitions);
|
|
|
|
ColorUtils.transparentBackground(panel);
|
|
|
|
return panel;
|
|
|
|
}
|
|
|
|
|
|
|
|
private JComponent generateUnLimitContentPanel0(List<List<StartupWorkspaceBean>> partitions) {
|
|
|
|
|
|
|
|
JPanel workspaceDescWrapper = new JPanel();
|
|
|
|
workspaceDescWrapper.setLayout(new BorderLayout(0, 0));
|
|
|
|
workspaceDescWrapper.setBorder(new EmptyBorder(0, 0, 0, 0));
|
|
|
|
|
|
|
|
JPanel workspaceDescPanel = new JPanel();
|
|
|
|
workspaceDescPanel.setLayout(new GridLayout(partitions.size(), 1, 0, 0));
|
|
|
|
for (List<StartupWorkspaceBean> partition : partitions) {
|
|
|
|
JPanel partitionPanel = generatePartitionPanel(partition);
|
|
|
|
workspaceDescPanel.add(partitionPanel);
|
|
|
|
}
|
|
|
|
boolean needScroll = partitions.size() > 4;
|
|
|
|
if (needScroll) {
|
|
|
|
return generateScrollUnLimitContentPanel(workspaceDescWrapper, workspaceDescPanel);
|
|
|
|
}
|
|
|
|
workspaceDescWrapper.add(workspaceDescPanel, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
return workspaceDescWrapper;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
private JPanel generateScrollUnLimitContentPanel(JPanel workspaceDescWrapper, JPanel workspaceDescPanel) {
|
|
|
|
|
|
|
|
// 滚动条
|
|
|
|
UIScrollPane scrollPane = new UIScrollPane(workspaceDescPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
|
|
|
JViewport viewport = scrollPane.getViewport();
|
|
|
|
JViewport scrollViewport = new TransparentScrollViewPort();
|
|
|
|
// 动态画图
|
|
|
|
scrollViewport.addChangeListener(e -> repaintAll());
|
|
|
|
scrollViewport.setView(viewport.getView());
|
|
|
|
scrollPane.setViewport(scrollViewport);
|
|
|
|
scrollPane.setBorder(new EmptyBorder(10, 0, 0, 0));
|
|
|
|
scrollPane.setPreferredSize(new Dimension(CONTENT_WIDTH, SCROLL_HEIGHT));
|
|
|
|
workspaceDescWrapper.add(scrollPane, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
return workspaceDescWrapper;
|
|
|
|
}
|
|
|
|
|
|
|
|
private JPanel generateLimitContentPanel(List<List<StartupWorkspaceBean>> partitions) {
|
|
|
|
|
|
|
|
JPanel workspaceDescPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEFT, 0, 0);
|
|
|
|
int limit = 2;
|
|
|
|
for (int i = 0; i < partitions.size(); i++) {
|
|
|
|
if (i >= limit) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
List<StartupWorkspaceBean> partition = partitions.get(i);
|
|
|
|
|
|
|
|
JPanel partitionPanel = generatePartitionPanel(partition);
|
|
|
|
workspaceDescPanel.add(partitionPanel);
|
|
|
|
}
|
|
|
|
|
|
|
|
ColorUtils.transparentBackground(workspaceDescPanel);
|
|
|
|
|
|
|
|
return workspaceDescPanel;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
private JPanel generateTailPanel() {
|
|
|
|
|
|
|
|
AtomicReference<Color> hoverBackColorRef = new AtomicReference<>();
|
|
|
|
|
|
|
|
JPanel tailPanel = new JPanel();
|
|
|
|
{
|
|
|
|
tailPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
|
|
|
|
tailPanel.setBorder(new EmptyBorder(0, 0, 0, 20));
|
|
|
|
JPanel showAllPanel = new JPanel() {
|
|
|
|
@Override
|
|
|
|
protected void paintComponent(Graphics g) {
|
|
|
|
super.paintComponent(g);
|
|
|
|
if (hoverBackColorRef.get() != null) {
|
|
|
|
g.setColor(hoverBackColorRef.get());
|
|
|
|
Dimension preferredSize = getPreferredSize();
|
|
|
|
g.fillRoundRect(0, 0, preferredSize.width, preferredSize.height, 5, 5);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
showAllPanel.setLayout(new BorderLayout(5, 0));
|
|
|
|
showAllPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
|
|
|
|
|
|
|
|
UILabel fontLabel = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Expand_All"));
|
|
|
|
fontLabel.setForeground(HOVER_COLOR);
|
|
|
|
showAllPanel.setBackground(new Color(0, 0, 0, 0));
|
|
|
|
showAllPanel.add(fontLabel, BorderLayout.WEST);
|
|
|
|
|
|
|
|
UILabel iconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/startup/show_more.svg"));
|
|
|
|
showAllPanel.add(iconLabel, BorderLayout.EAST);
|
|
|
|
|
|
|
|
Color showAllBackground = showAllPanel.getBackground();
|
|
|
|
|
|
|
|
showAllPanel.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
|
|
public void mouseEntered(MouseEvent e) {
|
|
|
|
Color hoverBackColor = new Color(217, 235, 254);
|
|
|
|
hoverBackColorRef.set(hoverBackColor);
|
|
|
|
repaintAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseExited(MouseEvent e) {
|
|
|
|
hoverBackColorRef.set(null);
|
|
|
|
ColorUtils.syncBackground(showAllPanel, showAllBackground);
|
|
|
|
repaintAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mousePressed(MouseEvent e) {
|
|
|
|
doShowAllAction(fontLabel, iconLabel);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
tailPanel.add(showAllPanel);
|
|
|
|
Dimension preferredSize = tailPanel.getPreferredSize();
|
|
|
|
tailPanel.setPreferredSize(new Dimension(CONTENT_WIDTH, (int) preferredSize.getHeight()));
|
|
|
|
}
|
|
|
|
return tailPanel;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
private JPanel generatePartitionPanel(List<StartupWorkspaceBean> partition) {
|
|
|
|
|
|
|
|
JPanel partitionPanelWrapper = new JPanel();
|
|
|
|
partitionPanelWrapper.setBorder(new EmptyBorder(10,0,10,0));
|
|
|
|
partitionPanelWrapper.setLayout(new BorderLayout());
|
|
|
|
|
|
|
|
JPanel partitionPanel = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 20, 0);
|
|
|
|
partitionPanel.setName("partitionPanel");
|
|
|
|
|
|
|
|
for (StartupWorkspaceBean workspaceInfo : partition) {
|
|
|
|
|
|
|
|
JPanel workspaceItemDesc = FRGUIPaneFactory.createBorderLayout_S_Pane();
|
|
|
|
|
|
|
|
layoutSelectWorkspacePanel(workspaceInfo, workspaceItemDesc);
|
|
|
|
|
|
|
|
layoutSelectAndCreatePanel(workspaceInfo, workspaceItemDesc);
|
|
|
|
|
|
|
|
partitionPanel.add(workspaceItemDesc);
|
|
|
|
|
|
|
|
Dimension preferredSize = partitionPanel.getPreferredSize();
|
|
|
|
partitionPanel.setPreferredSize(new Dimension(CONTENT_WIDTH, (int) preferredSize.getHeight()));
|
|
|
|
}
|
|
|
|
|
|
|
|
partitionPanelWrapper.add(partitionPanel, BorderLayout.CENTER);
|
|
|
|
return partitionPanelWrapper;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void layoutSelectWorkspacePanel(StartupWorkspaceBean workspaceInfo, JPanel workspaceItemDesc) {
|
|
|
|
|
|
|
|
// 选择工作目录
|
|
|
|
// 图标 / 分隔符 / 说明-进入
|
|
|
|
// 选择并新建
|
|
|
|
AtomicReference<Color> borderColorRef = new AtomicReference<>(null);
|
|
|
|
|
|
|
|
JPanel selectWorkspacePanel = new JPanel() {
|
|
|
|
@Override
|
|
|
|
public JToolTip createToolTip() {
|
|
|
|
return new ModernToolTip();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void paintComponent(Graphics g) {
|
|
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
Color borderColor = borderColorRef.get();
|
|
|
|
|
|
|
|
Color backColor = Color.WHITE;
|
|
|
|
g2d.setColor(backColor);
|
|
|
|
// 直角和圆角上下叠合在一起
|
|
|
|
int rectOffset = 10;
|
|
|
|
int roundOffset = 15;
|
|
|
|
// 填充一个直角
|
|
|
|
g2d.fillRoundRect(0, 0, getWidth() - rectOffset, getHeight(), ARC_DIAMETER, ARC_DIAMETER);
|
|
|
|
// 填充一个圆角
|
|
|
|
g2d.fillRoundRect(getWidth() - roundOffset, 0, roundOffset, getHeight(), 0, 0);
|
|
|
|
paintBorderIfHover(g2d, borderColor, backColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 当悬浮的时候,将边框展示出来
|
|
|
|
* 会叠合,然后填充中间
|
|
|
|
*
|
|
|
|
* |----【-|--】
|
|
|
|
* | A 【C| B】
|
|
|
|
* |----【-|--】
|
|
|
|
*
|
|
|
|
* 见上面有两种线,分别是 A-| 和 B-【
|
|
|
|
* 这里会将 A 和 B 叠在一起,中间则存在 C,然后将 C 的部分扩大一点,然后填充上背景
|
|
|
|
* 则形成下面这种图形
|
|
|
|
*
|
|
|
|
* |----】
|
|
|
|
* |----】
|
|
|
|
*
|
|
|
|
* @param g2d 绘画
|
|
|
|
* @param borderColor 边框颜色
|
|
|
|
* @param backColor 背景颜色
|
|
|
|
*/
|
|
|
|
private void paintBorderIfHover(Graphics2D g2d, Color borderColor, Color backColor) {
|
|
|
|
|
|
|
|
if (borderColor != null) {
|
|
|
|
g2d.setColor(borderColor);
|
|
|
|
g2d.setStroke(new BasicStroke(BORDER_THIN));
|
|
|
|
// 需要一个修正值
|
|
|
|
int strokeOffset = BORDER_THIN / 2;
|
|
|
|
// 直角和圆角上下叠合在一起
|
|
|
|
int rectOffset = 10;
|
|
|
|
int roundOffset = 15;
|
|
|
|
// 画一个圆角
|
|
|
|
int fixRoundWidth = getWidth() - rectOffset;
|
|
|
|
int fixRoundHeight = getHeight() - BORDER_THIN;
|
|
|
|
g2d.drawRoundRect(strokeOffset, strokeOffset, fixRoundWidth, fixRoundHeight, ARC_DIAMETER, ARC_DIAMETER);
|
|
|
|
|
|
|
|
g2d.setColor(backColor);
|
|
|
|
|
|
|
|
// 绘制一个矩形,覆盖住多余的相交线
|
|
|
|
// 需要考虑上下的线宽
|
|
|
|
int coverHeight = getHeight() - (BORDER_THIN * 2);
|
|
|
|
// 偏左一点的 fixedX
|
|
|
|
int fixedX = getWidth() - roundOffset - BORDER_THIN;
|
|
|
|
// 圆角和直角相交的区域
|
|
|
|
int coverWidth = 15;
|
|
|
|
g2d.fillRect(fixedX, BORDER_THIN, coverWidth, coverHeight);
|
|
|
|
|
|
|
|
g2d.setColor(borderColor);
|
|
|
|
g2d.drawLine(getWidth() / 2, strokeOffset, getWidth(), strokeOffset);
|
|
|
|
g2d.drawLine(getWidth() / 2, getHeight() - strokeOffset, getWidth(), getHeight() - strokeOffset);
|
|
|
|
g2d.drawLine(getWidth() - strokeOffset, strokeOffset, getWidth() - strokeOffset, getHeight() - strokeOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
selectWorkspacePanel.setLayout(new BorderLayout(0,0));
|
|
|
|
selectWorkspacePanel.setToolTipText(Toolkit.i18nText("Fine-Design_Startup_Page_Double_Click_Enter_Workspace"));
|
|
|
|
selectWorkspacePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
|
|
|
{
|
|
|
|
|
|
|
|
JPanel iconPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
|
|
|
|
iconPanel.setBorder(new EmptyBorder(0, 10, 0, 10));
|
|
|
|
Icon icon = StartupPageUtil.getIcon4DescAreaByWorkspace(workspaceInfo);
|
|
|
|
UILabel label = new UILabel(icon);
|
|
|
|
label.setPreferredSize(LABEL_DIMENSION);
|
|
|
|
iconPanel.add(label, BorderLayout.CENTER);
|
|
|
|
selectWorkspacePanel.add(iconPanel, BorderLayout.WEST);
|
|
|
|
|
|
|
|
// desc / >箭头
|
|
|
|
JPanel descPanel = new JPanel();
|
|
|
|
descPanel.setLayout(FRGUIPaneFactory.createM_BorderLayout());
|
|
|
|
descPanel.setBorder(new EmptyBorder(0, 10, 0, 0));
|
|
|
|
|
|
|
|
JPanel simpleDescPanelWrapper = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.CENTER, 0, 0);
|
|
|
|
JPanel simpleDescPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
|
|
|
|
UILabel nameLabel = new UILabel(workspaceInfo.getName());
|
|
|
|
Font font = nameLabel.getFont();
|
|
|
|
Font newSizeFont = font.deriveFont(font.getStyle(), NAME_LABEL_SIZE);
|
|
|
|
nameLabel.setFont(newSizeFont);
|
|
|
|
nameLabel.setPreferredSize(PATH_DIMENSION);
|
|
|
|
Color nameForeground = nameLabel.getForeground();
|
|
|
|
simpleDescPanel.add(nameLabel,BorderLayout.NORTH);
|
|
|
|
|
|
|
|
UILabel pathLabel = new UILabel(workspaceInfo.getPath());
|
|
|
|
pathLabel.setPreferredSize(PATH_DIMENSION);
|
|
|
|
Font pathFont = pathLabel.getFont();
|
|
|
|
pathLabel.setFont(pathFont.deriveFont(pathFont.getStyle(), PATH_LABEL_SIZE));
|
|
|
|
Color pathColor = PATH_COLOR;
|
|
|
|
pathLabel.setForeground(pathColor);
|
|
|
|
simpleDescPanel.add(pathLabel, BorderLayout.SOUTH);
|
|
|
|
simpleDescPanelWrapper.add(simpleDescPanel);
|
|
|
|
|
|
|
|
descPanel.add(simpleDescPanelWrapper, BorderLayout.WEST);
|
|
|
|
|
|
|
|
MouseAdapter selectWorkspaceMouseListener = new MouseAdapter() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseEntered(MouseEvent e) {
|
|
|
|
Color hoverColor = HOVER_COLOR;
|
|
|
|
borderColorRef.set(hoverColor);
|
|
|
|
nameLabel.setForeground(hoverColor);
|
|
|
|
pathLabel.setForeground(hoverColor );
|
|
|
|
repaintAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseExited(MouseEvent e) {
|
|
|
|
borderColorRef.set(Color.WHITE);
|
|
|
|
nameLabel.setForeground(nameForeground);
|
|
|
|
pathLabel.setForeground(pathColor);
|
|
|
|
repaintAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mousePressed(MouseEvent e) {
|
|
|
|
|
|
|
|
int clickCount = e.getClickCount();
|
|
|
|
if (clickCount == DOUBLE_CLICK_COUNT) {
|
|
|
|
doOpenEmptyTemplate(workspaceInfo);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
doSwitchWorkspace(workspaceInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
UILabel arrowLabel = new UILabel(IconUtils.readIcon("/com/fr/design/startup/more.svg")) {
|
|
|
|
@Override
|
|
|
|
public JToolTip createToolTip() {
|
|
|
|
return new ModernToolTip();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
arrowLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Startup_Page_Enter_Workspace"));
|
|
|
|
arrowLabel.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
|
|
public void mouseEntered(MouseEvent e) {
|
|
|
|
arrowLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/more_hover.svg"));
|
|
|
|
selectWorkspaceMouseListener.mouseEntered(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseExited(MouseEvent e) {
|
|
|
|
arrowLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/more.svg"));
|
|
|
|
selectWorkspaceMouseListener.mouseExited(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mousePressed(MouseEvent e) {
|
|
|
|
doOpenEmptyTemplate(workspaceInfo);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
descPanel.add(arrowLabel, BorderLayout.EAST);
|
|
|
|
|
|
|
|
selectWorkspacePanel.add(descPanel, BorderLayout.CENTER);
|
|
|
|
selectWorkspacePanel.addMouseListener(selectWorkspaceMouseListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
ColorUtils.syncBackground(selectWorkspacePanel, Color.WHITE);
|
|
|
|
selectWorkspacePanel.setPreferredSize(SELECT_WORKSPACE_DIMENSION);
|
|
|
|
workspaceItemDesc.add(selectWorkspacePanel, BorderLayout.WEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void layoutSelectAndCreatePanel(StartupWorkspaceBean workspaceInfo, JPanel workspaceItemDesc) {
|
|
|
|
|
|
|
|
// 选择并新建
|
|
|
|
AtomicReference<Color> borderColorRef = new AtomicReference<>(null);
|
|
|
|
JPanel selectAndCreatePanel = new JPanel() {
|
|
|
|
@Override
|
|
|
|
public JToolTip createToolTip() {
|
|
|
|
return new ModernToolTip();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void paintComponent(Graphics g) {
|
|
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
Color borderColor = borderColorRef.get();
|
|
|
|
|
|
|
|
Color backColor = SHALLOW_WHITE_COLOR;
|
|
|
|
g2d.setColor(backColor);
|
|
|
|
|
|
|
|
// 见 layoutSelectWorkspacePanel 部分的分析
|
|
|
|
// 直角和圆角上下叠合在一起
|
|
|
|
int rectOffset = 10;
|
|
|
|
int roundOffset = 15;
|
|
|
|
int strokeOffset = BORDER_THIN / 2;
|
|
|
|
int fixedRoundOffset = roundOffset + strokeOffset;
|
|
|
|
g2d.fillRoundRect(0, 0, getWidth() - rectOffset, getHeight(), 0, 0);
|
|
|
|
g2d.fillRoundRect(getWidth() - fixedRoundOffset, 0, roundOffset, getHeight(), ARC_DIAMETER, ARC_DIAMETER);
|
|
|
|
if (borderColor != null) {
|
|
|
|
g2d.setColor(borderColor);
|
|
|
|
g2d.setStroke(new BasicStroke(BORDER_THIN));
|
|
|
|
|
|
|
|
int borderOffset = BORDER_THIN * 2;
|
|
|
|
// 画画的笔触需要调整一下
|
|
|
|
g2d.drawRoundRect(strokeOffset, strokeOffset, getWidth() - borderOffset, getHeight() - BORDER_THIN, ARC_DIAMETER, ARC_DIAMETER);
|
|
|
|
g2d.setColor(backColor);
|
|
|
|
int fillWidth = 15;
|
|
|
|
g2d.fillRect(0, 0, fillWidth, getHeight());
|
|
|
|
|
|
|
|
g2d.setColor(borderColor);
|
|
|
|
g2d.drawLine(strokeOffset, strokeOffset, fillWidth, strokeOffset);
|
|
|
|
g2d.drawLine(strokeOffset, getHeight() - strokeOffset, fillWidth, getHeight() - strokeOffset);
|
|
|
|
g2d.drawLine(strokeOffset, strokeOffset, strokeOffset, getHeight() - strokeOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
selectAndCreatePanel.setToolTipText(Toolkit.i18nText("Fine-Design_Startup_Page_Enter_Workspace_And_Create"));
|
|
|
|
selectAndCreatePanel.setBorder(new EmptyBorder(0, 0, 0, 0));
|
|
|
|
selectAndCreatePanel.setLayout(new BorderLayout());
|
|
|
|
{
|
|
|
|
UILabel label = new UILabel(IconUtils.readIcon("/com/fr/design/standard/system/add"));
|
|
|
|
label.setPreferredSize(new Dimension(ARC_DIAMETER, ARC_DIAMETER));
|
|
|
|
label.setForeground(HOVER_COLOR);
|
|
|
|
selectAndCreatePanel.add(label, BorderLayout.CENTER);
|
|
|
|
selectAndCreatePanel.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
|
|
public void mouseEntered(MouseEvent e) {
|
|
|
|
borderColorRef.set(HOVER_COLOR);
|
|
|
|
label.setIcon(IconUtils.readIcon("/com/fr/design/standard/system/add_hover.svg"));
|
|
|
|
repaintAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseExited(MouseEvent e) {
|
|
|
|
borderColorRef.set(null);
|
|
|
|
label.setIcon(IconUtils.readIcon("/com/fr/design/standard/system/add"));
|
|
|
|
repaintAll();
|
|
|
|
}
|
|
|
|
@Override
|
|
|
|
public void mousePressed(MouseEvent e) {
|
|
|
|
pageModel.setSelectWorkspaceInfo(workspaceInfo);
|
|
|
|
createNewTemplateRunnable.run();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
ColorUtils.syncBackground(selectAndCreatePanel, Color.GREEN);
|
|
|
|
selectAndCreatePanel.setPreferredSize(SELECT_CREATE_DIMENSION);
|
|
|
|
workspaceItemDesc.add(selectAndCreatePanel, BorderLayout.EAST);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSelectWorkspaceRunnable(Runnable selectWorkspaceRunnable) {
|
|
|
|
|
|
|
|
this.selectWorkspaceRunnable = selectWorkspaceRunnable;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doOpenEmptyTemplate(StartupWorkspaceBean workspaceInfo) {
|
|
|
|
|
|
|
|
pageModel.setSelectWorkspaceInfo(workspaceInfo);
|
|
|
|
openEmptyTemplateRunnable.run();
|
|
|
|
|
|
|
|
DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics();
|
|
|
|
designerMetrics.getStatistic().recordOpenEmptyTemplate();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doSwitchWorkspace(StartupWorkspaceBean workspaceInfo) {
|
|
|
|
|
|
|
|
StartupWorkspaceBean lastWorkspaceInfo = pageModel.getSelectWorkspaceInfo();
|
|
|
|
// selectWorkspaceRunnable
|
|
|
|
pageModel.setSelectWorkspaceInfo(workspaceInfo);
|
|
|
|
selectWorkspaceRunnable.run();
|
|
|
|
|
|
|
|
DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics();
|
|
|
|
designerMetrics.getStatistic().recordSwitchWorkspace(lastWorkspaceInfo, workspaceInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doShowAllAction(UILabel fontLabel, UILabel iconLabel) {
|
|
|
|
|
|
|
|
if (showMore) {
|
|
|
|
fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Collapse_Workspace"));
|
|
|
|
iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_less.svg"));
|
|
|
|
showMoreContent();
|
|
|
|
showMore = !showMore;
|
|
|
|
} else {
|
|
|
|
fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Expand_All"));
|
|
|
|
iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_more.svg"));
|
|
|
|
showLessContent();
|
|
|
|
showMore = !showMore;
|
|
|
|
}
|
|
|
|
DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics();
|
|
|
|
designerMetrics.getStatistic().recordShowAllAction();
|
|
|
|
|
|
|
|
repaintAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void repaintAll() {
|
|
|
|
|
|
|
|
this.getRootPane().repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 支持透明的滚动视图
|
|
|
|
*/
|
|
|
|
private class TransparentScrollViewPort extends JViewport {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 从而屏蔽掉 {@link RepaintManager.PaintManager#paintDoubleBuffered(JComponent, Image, Graphics, int, int, int, int)}
|
|
|
|
*
|
|
|
|
* @return 创建一个不会实际画图的 Graphics
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public Graphics getGraphics() {
|
|
|
|
|
|
|
|
Graphics graphics = super.getGraphics();
|
|
|
|
return new FRGraphics2D((Graphics2D) graphics) {
|
|
|
|
@Override
|
|
|
|
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|