You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
9.5 KiB
265 lines
9.5 KiB
package com.fr.design.mainframe.theme; |
|
|
|
import com.fr.base.GraphHelper; |
|
import com.fr.base.theme.TemplateTheme; |
|
import com.fr.base.theme.TemplateThemeConfig; |
|
import com.fr.base.theme.settings.ThemeThumbnail; |
|
import com.fr.design.designer.IntervalConstants; |
|
import com.fr.design.file.HistoryTemplateListCache; |
|
import com.fr.design.gui.ilable.UILabel; |
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
import com.fr.design.mainframe.JTemplate; |
|
import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog; |
|
import com.fr.general.IOUtils; |
|
import com.fr.general.locale.image.I18nImage; |
|
import com.fr.stable.Constants; |
|
import com.fr.stable.StringUtils; |
|
|
|
import javax.swing.BorderFactory; |
|
import javax.swing.Icon; |
|
import javax.swing.JPanel; |
|
import javax.swing.SwingUtilities; |
|
import java.awt.BorderLayout; |
|
import java.awt.Color; |
|
import java.awt.Dimension; |
|
import java.awt.Graphics; |
|
import java.awt.Graphics2D; |
|
import java.awt.Image; |
|
import java.awt.Rectangle; |
|
import java.awt.RenderingHints; |
|
import java.awt.Window; |
|
import java.awt.event.MouseAdapter; |
|
import java.awt.event.MouseEvent; |
|
|
|
/** |
|
* @author Starryi |
|
* @version 1.0 |
|
* Created by Starryi on 2021/8/13 |
|
*/ |
|
public class TemplateThemeBlock<T extends TemplateTheme> extends JPanel { |
|
public static final int INFO_HEIGHT = 30; |
|
public static final int CONTENT_WIDTH = ThemeThumbnail.WIDTH; |
|
public static final int CONTENT_HEIGHT = ThemeThumbnail.HEIGHT + INFO_HEIGHT; |
|
private static final Color HOVERING_BORDER_COLOR = new Color(65, 155, 249); |
|
|
|
private final String name; |
|
private final TemplateThemeConfig<T> config; |
|
private T theme; |
|
private final TemplateThemeProfilePane<T> profilePane; |
|
private final Icon theme4currentTemplateMarkIcon = IOUtils.readIcon("/com/fr/design/form/images/theme4currentTemplate.png"); |
|
private final Icon theme4NewTemplateMarkIcon= IOUtils.readIcon("/com/fr/design/form/images/theme4newTemplate.png"); |
|
private final Icon profileIcon = IOUtils.readIcon("/com/fr/design/icon/icon_edit.png"); |
|
private final boolean displayTheme4NewTemplateMarker; |
|
|
|
private final ThumbnailPane thumbnailPane; |
|
// UIButton会影响Block的手势监听,这里使用UILabel代替,点击事件也有Block代为处理 |
|
private UILabel profileButton; |
|
private boolean selected = false; |
|
private boolean hovering = false; |
|
|
|
private MouseAdapter clickListener; |
|
|
|
public TemplateThemeBlock(String name, |
|
boolean displayTheme4NewTemplateMarker, |
|
TemplateThemeConfig<T> config, |
|
TemplateThemeProfilePane<T> profilePane) { |
|
this.name = name; |
|
this.setName(name); |
|
this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker; |
|
this.config = config; |
|
this.profilePane = profilePane; |
|
this.thumbnailPane = new ThumbnailPane(); |
|
|
|
initializePane(); |
|
addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
if (clickListener != null) { |
|
clickListener.mouseClicked(e); |
|
} |
|
|
|
if (profileButton != null && profilePane != null) { |
|
delegateProfileButtonClick(e); |
|
} |
|
} |
|
|
|
@Override |
|
public void mouseEntered(MouseEvent e) { |
|
hovering = true; |
|
repaint(); |
|
} |
|
|
|
@Override |
|
public void mouseExited(MouseEvent e) { |
|
hovering = false; |
|
repaint(); |
|
} |
|
}); |
|
} |
|
|
|
private void initializePane() { |
|
setLayout(FRGUIPaneFactory.createBorderLayout()); |
|
setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); |
|
setBackground(Color.WHITE); |
|
|
|
thumbnailPane.setBackground(Color.WHITE); |
|
thumbnailPane.setPreferredSize(new Dimension(ThemeThumbnail.WIDTH, ThemeThumbnail.HEIGHT)); |
|
|
|
JPanel infoPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
infoPane.setPreferredSize(new Dimension(CONTENT_WIDTH, INFO_HEIGHT)); |
|
infoPane.setBackground(Color.WHITE); |
|
infoPane.setBorder(BorderFactory.createEmptyBorder(0, IntervalConstants.INTERVAL_L7,0,IntervalConstants.INTERVAL_L7)); |
|
|
|
UILabel titleLabel = new UILabel(name); |
|
titleLabel.setToolTipText(name); |
|
infoPane.add(titleLabel, BorderLayout.CENTER); |
|
|
|
if (profilePane != null) { |
|
addProfileButton(infoPane); |
|
} |
|
|
|
add(thumbnailPane, BorderLayout.CENTER); |
|
add(infoPane, BorderLayout.SOUTH); |
|
} |
|
|
|
public void setTheme(T theme) { |
|
this.theme = theme; |
|
Image image = null; |
|
if (theme != null) { |
|
ThemeThumbnail thumbnail = theme.getThumbnail(); |
|
if (thumbnail != null) { |
|
image = thumbnail.getImage(); |
|
} |
|
} |
|
thumbnailPane.setThumbnail(image); |
|
invalidate(); |
|
repaint(); |
|
} |
|
|
|
public T getTheme() { |
|
return this.theme; |
|
} |
|
|
|
public void setSelected(boolean selected) { |
|
this.selected = selected; |
|
repaint(); |
|
} |
|
|
|
public void addClickListener(MouseAdapter clickListener) { |
|
this.clickListener = clickListener; |
|
} |
|
|
|
private void addProfileButton(JPanel panel) { |
|
profileButton = new UILabel(profileIcon); |
|
profileButton.setPreferredSize(new Dimension(24, 24)); |
|
panel.add(profileButton, BorderLayout.EAST); |
|
} |
|
|
|
private void delegateProfileButtonClick(MouseEvent e) { |
|
int x = e.getX(); |
|
int y = e.getY(); |
|
|
|
int profileButtonX = profileButton.getX(); |
|
int profileButtonY = thumbnailPane.getHeight() + profileButton.getY(); |
|
|
|
boolean inX = profileButtonX <= x && x <= profileButtonX + profileButton.getWidth(); |
|
boolean inY = profileButtonY <= y && y <= profileButtonY + profileButton.getHeight(); |
|
if (inX && inY) { |
|
openProfileDialog(); |
|
} |
|
} |
|
|
|
private void openProfileDialog() { |
|
if (theme == null) { |
|
return; |
|
} |
|
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeBlock.this); |
|
TemplateThemeProfileDialog<T> profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane); |
|
try { |
|
profilePane.populateBean((T) theme.clone()); |
|
} catch (CloneNotSupportedException ex) { |
|
ex.printStackTrace(); |
|
} |
|
profileDialog.setVisible(true); |
|
} |
|
|
|
@Override |
|
public void paint(Graphics g) { |
|
super.paint(g); |
|
Graphics2D g2d = (Graphics2D) g; |
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
|
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
if (template != null) { |
|
TemplateThemeConfig<? extends TemplateTheme> templateUsingConfig = template.getUsingTemplateThemeConfig(); |
|
TemplateTheme templateTheme = template.getTemplateTheme(); |
|
if (templateUsingConfig == this.config && StringUtils.equals(templateTheme.getName(), name)) { |
|
theme4currentTemplateMarkIcon.paintIcon(this, g, getWidth() - 25, 0); |
|
} |
|
} |
|
|
|
if (displayTheme4NewTemplateMarker && StringUtils.equals(config.getThemeName4NewTemplate(), name)) { |
|
theme4NewTemplateMarkIcon.paintIcon(this, g, 0, thumbnailPane.getHeight() - 16); |
|
} |
|
|
|
if (selected || this.hovering) { |
|
g.setColor(HOVERING_BORDER_COLOR); |
|
Rectangle rectangle = new Rectangle(1, 1, this.getWidth() - 2, this.getHeight() - 2); |
|
GraphHelper.draw(g, rectangle, Constants.LINE_MEDIUM); |
|
} |
|
} |
|
|
|
private static class ThumbnailPane extends JPanel { |
|
private static final String LOADING_IMAGE_URL = "/com/fr/design/images/mainframe/loading/loading.gif"; |
|
private static final Image LOADING_IMAGE = I18nImage.getImage(LOADING_IMAGE_URL); |
|
private Image thumbnail = null; |
|
|
|
@Override |
|
public void paint(Graphics g) { |
|
super.paint(g); |
|
Graphics2D g2d = (Graphics2D) g; |
|
Color oldColor = g2d.getColor(); |
|
g2d.setColor(Color.WHITE); |
|
g2d.fillRect(0, 0, getWidth(), getHeight()); |
|
g2d.setColor(oldColor); |
|
|
|
paintCenterImage(g2d, thumbnail != null ? thumbnail : LOADING_IMAGE); |
|
} |
|
|
|
private void paintCenterImage(Graphics2D g2d, Image image) { |
|
if (image == null) { |
|
return; |
|
} |
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
|
|
|
int width = getWidth(); |
|
int height = getHeight(); |
|
int imgWidth = image.getWidth(null); |
|
int imgHeight = image.getHeight(null); |
|
|
|
if (width <= 0 || height <= 0 || imgWidth <= 0 || imgHeight <= 0) { |
|
return; |
|
} |
|
|
|
float imgAspect = 1.0F * imgWidth / imgHeight; |
|
|
|
if (1.0F * width / height > 1.0F * imgWidth / imgHeight) { |
|
imgHeight = height; |
|
imgWidth = (int) (1.0F * imgHeight * imgAspect); |
|
} else { |
|
imgWidth = width; |
|
imgHeight = (int) (1.0F * imgWidth / imgAspect); |
|
} |
|
int x = (width - imgWidth) / 2; |
|
int y = (height - imgHeight) / 2; |
|
|
|
g2d.drawImage(image, x, y, imgWidth, imgHeight, null); |
|
} |
|
|
|
public void setThumbnail(Image thumbnail) { |
|
this.thumbnail = thumbnail; |
|
invalidate(); |
|
repaint(); |
|
} |
|
} |
|
} |