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.
514 lines
16 KiB
514 lines
16 KiB
/** |
|
* |
|
*/ |
|
package com.fr.design.designer.creator.cardlayout; |
|
|
|
import com.fr.base.GraphHelper; |
|
import com.fr.base.iofile.attr.SharableAttrMark; |
|
import com.fr.design.constants.UIConstants; |
|
import com.fr.design.designer.beans.AdapterBus; |
|
import com.fr.design.designer.beans.ComponentAdapter; |
|
import com.fr.design.designer.beans.LayoutAdapter; |
|
import com.fr.design.designer.beans.adapters.layout.FRCardMainBorderLayoutAdapter; |
|
import com.fr.design.designer.beans.models.SelectionModel; |
|
import com.fr.design.designer.creator.XCreator; |
|
import com.fr.design.designer.creator.XCreatorUtils; |
|
import com.fr.design.designer.creator.XLayoutContainer; |
|
import com.fr.design.designer.creator.XWBorderLayout; |
|
import com.fr.design.designer.creator.XWidgetCreator; |
|
import com.fr.design.form.util.XCreatorConstants; |
|
import com.fr.design.icon.IconPathConstants; |
|
import com.fr.design.mainframe.DesignerContext; |
|
import com.fr.design.mainframe.EditingMouseListener; |
|
import com.fr.design.mainframe.FormDesigner; |
|
import com.fr.design.mainframe.WidgetHelpDialog; |
|
import com.fr.design.mainframe.WidgetPropertyPane; |
|
import com.fr.form.event.Listener; |
|
import com.fr.form.ui.CardSwitchButton; |
|
import com.fr.form.ui.LayoutBorderStyle; |
|
import com.fr.form.ui.Widget; |
|
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; |
|
import com.fr.form.ui.container.WBorderLayout; |
|
import com.fr.form.ui.container.WCardLayout; |
|
import com.fr.form.ui.container.WTabDisplayPosition; |
|
import com.fr.form.ui.container.WTitleLayout; |
|
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout; |
|
import com.fr.form.ui.container.cardlayout.WCardTagLayout; |
|
import com.fr.form.ui.container.cardlayout.WCardTitleLayout; |
|
import com.fr.general.ComparatorUtils; |
|
import com.fr.general.IOUtils; |
|
|
|
import com.fr.share.ShareConstants; |
|
import com.fr.stable.Constants; |
|
|
|
import javax.swing.Icon; |
|
import java.awt.AlphaComposite; |
|
import java.awt.Color; |
|
import java.awt.Component; |
|
import java.awt.Composite; |
|
import java.awt.Cursor; |
|
import java.awt.Dimension; |
|
import java.awt.Graphics; |
|
import java.awt.Graphics2D; |
|
import java.awt.Rectangle; |
|
import java.awt.RenderingHints; |
|
import java.awt.event.MouseEvent; |
|
import java.awt.image.BufferedImage; |
|
import java.util.ArrayList; |
|
import java.util.List; |
|
|
|
/** |
|
* card布局主体框架 |
|
* |
|
* |
|
* |
|
* @date: 2014-12-9-下午9:59:31 |
|
*/ |
|
public class XWCardMainBorderLayout extends XWBorderLayout { |
|
|
|
private Icon controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); |
|
private static final int CENTER = 1; |
|
private static final int NORTH = 0; |
|
private static final int TITLE_STYLE = 2; |
|
|
|
private static final int EDIT_BTN_WIDTH = 75; |
|
private static final int EDIT_BTN_HEIGHT = 20; |
|
private static final int BORDER_WIDTH = 1; |
|
|
|
private final int CARDMAINLAYOUT_CHILD_COUNT = 1; |
|
|
|
/** |
|
* 构造函数 |
|
*/ |
|
public XWCardMainBorderLayout(WCardMainBorderLayout border, Dimension dimension) { |
|
super(border, dimension); |
|
} |
|
|
|
/** |
|
* 获取当前组件里的控件 |
|
* |
|
* @return 控件 |
|
* |
|
* |
|
* @date 2014-12-10-下午1:46:33 |
|
* |
|
*/ |
|
@Override |
|
public WCardMainBorderLayout toData() { |
|
return (WCardMainBorderLayout) super.toData(); |
|
} |
|
|
|
/** |
|
* 添加标题区域 |
|
* |
|
* @param title 标题区域 |
|
* |
|
* |
|
* @date 2014-12-10-下午1:50:56 |
|
* |
|
*/ |
|
public void addTitlePart(XWCardTitleLayout title, String position){ |
|
toData().setTabPosition(position); |
|
this.add(title, position); |
|
} |
|
|
|
public int getTitleWidth(){ |
|
String position = toData().getTabPosition(); |
|
if(ComparatorUtils.equals(WBorderLayout.NORTH, position) || ComparatorUtils.equals(WBorderLayout.SOUTH, position)){ |
|
return getTitlePart().getHeight(); |
|
} |
|
return getTitlePart().getWidth(); |
|
} |
|
|
|
public void add(Component comp, String position) { |
|
super.add(comp, position); |
|
} |
|
|
|
|
|
/** |
|
* 将WLayout转换为XLayoutContainer |
|
*/ |
|
@Override |
|
public void convert() { |
|
isRefreshing = true; |
|
WBorderLayout wb = this.toData(); |
|
this.removeAll(); |
|
String[] arrs = {WBorderLayout.NORTH, WBorderLayout.SOUTH, WBorderLayout.EAST, WBorderLayout.WEST, WBorderLayout.CENTER}; |
|
for (int i = 0; i < arrs.length; i++) { |
|
Widget wgt = wb.getLayoutWidget(arrs[i]); |
|
//用来兼容之前titlePart设置不可见 |
|
if (wgt != null && ComparatorUtils.equals(arrs[i], WBorderLayout.NORTH) && !wgt.isVisible()) { |
|
wgt.setVisible(true); |
|
this.toData().setNorthSize(0); |
|
} |
|
if (wgt != null) { |
|
XWidgetCreator comp = (XWidgetCreator) XCreatorUtils.createXCreator(wgt, calculatePreferredSize(wgt)); |
|
this.add(comp, arrs[i]); |
|
comp.setBackupParent(this); |
|
} |
|
} |
|
dealCompatibility(wb); |
|
|
|
isRefreshing = false; |
|
} |
|
|
|
private void dealCompatibility(WBorderLayout wb){ |
|
WCardMainBorderLayout ob = (WCardMainBorderLayout)wb; |
|
WCardLayout cardLayout = ob.getCardPart(); |
|
//tab结构改变需要兼容以前的tab,重新命名tabpane |
|
WCardTitleLayout wCardTitleLayout = ob.getTitlePart(); |
|
if(cardLayout == null || wCardTitleLayout == null){ |
|
return; |
|
} |
|
WCardTagLayout wCardTagLayout = wCardTitleLayout.getTagPart(); |
|
String tabpaneName = cardLayout.getWidgetName(); |
|
if (!wCardTagLayout.isNewTab()) { |
|
wCardTagLayout.setWidgetName(tabpaneName); |
|
LayoutBorderStyle borderStyle = cardLayout.getBorderStyle(); |
|
if(borderStyle != null){ |
|
//新tab默认都有标题 |
|
borderStyle.setType(LayoutBorderStyle.TITLE); |
|
} |
|
String newCardLayoutName = XWCardLayout.DEFAULT_NAME + tabpaneName.replaceAll(XWCardTagLayout.DEFAULT_NAME, ""); |
|
cardLayout.setWidgetName(newCardLayoutName); |
|
//修改cardswitchbutton所绑定的cardlayoutname |
|
for (int i = 0, len = wCardTagLayout.getWidgetCount(); i < len; i++) { |
|
CardSwitchButton button = wCardTagLayout.getSwitchButton(i); |
|
button.setCardLayoutName(newCardLayoutName); |
|
} |
|
wCardTitleLayout.setCardName(newCardLayoutName); |
|
wCardTagLayout.setNewTab(true); |
|
//这边需要设置成默认值兼容之前的title高度(不知道为啥之前的title的高度会改变) |
|
if(this.toData().getNorthSize() != 0){ |
|
ob.setNorthSize(WTitleLayout.TITLE_HEIGHT); |
|
} |
|
for(int i = 0 ;i < cardLayout.getListenerSize(); i ++){ |
|
Listener listener = cardLayout.getListener(i); |
|
if(listener != null){ |
|
wCardTagLayout.addListener(listener); |
|
} |
|
} |
|
cardLayout.clearListeners(); |
|
} |
|
} |
|
|
|
/** |
|
* 切换到非添加状态 |
|
* |
|
* @return designer 表单设计器 |
|
*/ |
|
@Override |
|
public void stopAddingState(FormDesigner designer){ |
|
designer.stopAddingState(); |
|
return; |
|
} |
|
|
|
|
|
/** |
|
* 添加card区域 |
|
* |
|
* @param card card区域 |
|
* |
|
* |
|
* @date 2014-12-10-下午1:50:37 |
|
* |
|
*/ |
|
public void addCardPart(XWCardLayout card){ |
|
this.add(card, WBorderLayout.CENTER); |
|
} |
|
|
|
public XWCardLayout getCardPart(){ |
|
return this.getComponentCount() == TITLE_STYLE ? (XWCardLayout)this.getComponent(CENTER) : (XWCardLayout)this.getComponent(NORTH); |
|
} |
|
|
|
public XWCardTitleLayout getTitlePart(){ |
|
Component[] components = this.getComponents(); |
|
for(Component component : components){ |
|
if(component instanceof XWCardTitleLayout){ |
|
return (XWCardTitleLayout)component; |
|
} |
|
} |
|
return (XWCardTitleLayout)this.getComponent(NORTH); |
|
} |
|
|
|
/** |
|
* 控件树里需要隐藏xwcardmainLayout,返回其子组件xwcardLayout; |
|
* 标题样式下,this.getComponent(1)==xwcardLayout |
|
* 标准样式下,this.getComponent(0)==xwcardLayout |
|
* @return 子组件xwcardLayout |
|
*/ |
|
@Override |
|
public XCreator getXCreator() { |
|
return this; |
|
} |
|
|
|
/** |
|
* 控件树不显示此组件 |
|
* @param path 控件树list |
|
*/ |
|
@Override |
|
public void notShowInComponentTree(List<Component> path) { |
|
return; |
|
} |
|
|
|
@Override |
|
public int getShowXCreatorCount() { |
|
return CARDMAINLAYOUT_CHILD_COUNT; |
|
} |
|
|
|
@Override |
|
public ArrayList<XWTabFitLayout> getTargetChildrenList() { |
|
ArrayList<XWTabFitLayout> tabLayoutList = new ArrayList<XWTabFitLayout>(); |
|
XWCardLayout cardLayout = this.getCardPart(); |
|
for(int i=0, size=cardLayout.getComponentCount(); i<size; i++){ |
|
XWTabFitLayout tabLayout = (XWTabFitLayout)cardLayout.getComponent(i); |
|
tabLayoutList.add(tabLayout); |
|
} |
|
return tabLayoutList; |
|
} |
|
|
|
/** |
|
* 重新调整子组件的宽度 |
|
* @param width 宽度 |
|
* @param actualSize 是否按照实际大小计算 |
|
*/ |
|
@Override |
|
public void recalculateChildWidth(int width, boolean actualSize){ |
|
ArrayList<?> childrenList = this.getTargetChildrenList(); |
|
int size = childrenList.size(); |
|
if (size > 0) { |
|
for (int j = 0; j < size; j++) { |
|
XWTabFitLayout tabLayout = (XWTabFitLayout) childrenList |
|
.get(j); |
|
|
|
|
|
Dimension d = new Dimension(tabLayout.toData().getContainerWidth(), tabLayout.toData().getContainerHeight()); |
|
Rectangle rec = actualSize? new Rectangle(d): tabLayout.getBounds(); |
|
// 容器大小改变时,设下backupBound为其之前的实际大小 |
|
tabLayout.setBackupBound(rec); |
|
int refSize = rec.width; |
|
int offest = width - refSize; |
|
double percent = (double) offest / refSize; |
|
if (percent < 0 && !tabLayout.canReduce(percent)) { |
|
return; |
|
} |
|
tabLayout.setSize(rec.width + offest, rec.height); |
|
if(!actualSize){ |
|
updateChildWidgetBounds(tabLayout); |
|
} |
|
tabLayout.adjustCreatorsWidth(percent); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* 重新调整子组件的高度 |
|
* @param height 高度 |
|
* @param actualSize 是否按照实际大小计算 |
|
*/ |
|
@Override |
|
public void recalculateChildHeight(int height, boolean actualSize){ |
|
ArrayList<?> childrenList = this.getTargetChildrenList(); |
|
int size = childrenList.size(); |
|
if (size > 0) { |
|
for (int j = 0; j < size; j++) { |
|
XWTabFitLayout tabLayout = (XWTabFitLayout) childrenList |
|
.get(j); |
|
Dimension d = new Dimension(tabLayout.toData().getContainerWidth(), tabLayout.toData().getContainerHeight()); |
|
Rectangle rec = actualSize? new Rectangle(d): tabLayout.getBounds(); |
|
// 容器大小改变时,设下backupBound为其之前的实际大小 |
|
tabLayout.setBackupBound(rec); |
|
int refSize = rec.height; |
|
int offset = height - refSize - WCardMainBorderLayout.TAB_HEIGHT; |
|
if(offset < 0){ |
|
// 缩放时需要备份原tab布局宽高 |
|
tabLayout.setReferDim(new Dimension(rec.width, rec.height)); |
|
} |
|
double percent = (double) offset / refSize; |
|
if (percent < 0 && !tabLayout.canReduce(percent)) { |
|
return; |
|
} |
|
tabLayout.setSize(rec.width, rec.height + offset); |
|
if(!actualSize){ |
|
updateChildWidgetBounds(tabLayout); |
|
} |
|
tabLayout.adjustCreatorsHeight(percent); |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
/** |
|
* 更新下子组件bounds |
|
* @param tabLayout tabFit布局 |
|
*/ |
|
private void updateChildWidgetBounds(XWTabFitLayout tabLayout){ |
|
for (int m = 0; m < tabLayout.getComponentCount(); m++) { |
|
XCreator childCreator = tabLayout.getXCreator(m); |
|
BoundsWidget wgt = (BoundsWidget) tabLayout.toData() |
|
.getBoundsWidget(childCreator.toData()); |
|
wgt.setBounds(tabLayout.getComponent(m).getBounds()); |
|
} |
|
} |
|
|
|
@Override |
|
public void paint(Graphics g) { |
|
super.paint(g); |
|
//如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 |
|
if (isMouseEnter && !editable) { |
|
int x = 0; |
|
int y = 0; |
|
int w = getWidth(); |
|
int h = getHeight(); |
|
|
|
Graphics2D g2d = (Graphics2D) g; |
|
Composite oldComposite = g2d.getComposite(); |
|
//画白色的编辑层 |
|
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); |
|
g2d.setColor(XCreatorConstants.COVER_COLOR); |
|
g2d.fillRect(x, y, w, h); |
|
//画编辑按钮所在框 |
|
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
|
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR ? 0.9f : 0.7f); |
|
g2d.setColor(XCreatorConstants.EDIT_COLOR); |
|
g2d.setComposite(alphaComposite); |
|
g2d.fillRoundRect((x + w / 2 - EDIT_BTN_WIDTH / 2), (y + h / 2 - EDIT_BTN_HEIGHT / 2), EDIT_BTN_WIDTH, EDIT_BTN_HEIGHT, 4, 4); |
|
g2d.setComposite(oldComposite); |
|
|
|
//画编辑按钮图标 |
|
BufferedImage image = IOUtils.readImage(IconPathConstants.EDIT_ICON_PATH); |
|
g2d.drawImage( |
|
image, |
|
(x + w / 2 - 23), |
|
(y + h / 2 - image.getHeight() / 2), |
|
image.getWidth(), |
|
image.getHeight(), |
|
null, |
|
this |
|
); |
|
g2d.setColor(Color.WHITE); |
|
//画编辑文字 |
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
|
g2d.drawString(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Edit"), x + w / 2 - 2, y + h / 2 + 5); |
|
g.setColor(XCreatorConstants.FORM_BORDER_COLOR); |
|
GraphHelper.draw(g, new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - BORDER_WIDTH * 2, getHeight() - BORDER_WIDTH * 2), Constants.LINE_MEDIUM); |
|
paintExtro(g); |
|
} |
|
} |
|
|
|
public void paintExtro(Graphics g) { |
|
if (this.toData().getWidgetAttrMark(SharableAttrMark.XML_TAG) != null) { |
|
int width = getWidth() - ShareConstants.SHARE_EL_CONTROL_BUTTON_HW; |
|
g.setColor(UIConstants.NORMAL_BACKGROUND); |
|
g.fillArc(width, 0, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, |
|
0, 360); |
|
controlMode.paintIcon(this, g, width, 0); |
|
} |
|
} |
|
|
|
@Override |
|
public void paintBorder(Graphics g, Rectangle bounds){ |
|
if (!isMouseEnter) { |
|
super.paintBorder(g, bounds); |
|
} |
|
} |
|
|
|
/** |
|
* 响应点击事件 |
|
* |
|
* @param editingMouseListener 鼠标点击,位置处理器 |
|
* @param e 鼠标点击事件 |
|
*/ |
|
@Override |
|
public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e){ |
|
//帮助弹窗 |
|
if (this.isHelpBtnOnFocus()) { |
|
new WidgetHelpDialog(DesignerContext.getDesignerFrame(), this.toData().getDescription()).showWindow(e); |
|
return; |
|
} |
|
FormDesigner designer = editingMouseListener.getDesigner(); |
|
SelectionModel selectionModel = editingMouseListener.getSelectionModel(); |
|
boolean isEditing = e.getButton() == MouseEvent.BUTTON1 && |
|
(designer.getCursor().getType() == Cursor.HAND_CURSOR || e.getClickCount() == 2); |
|
setEditable(isEditing); |
|
|
|
selectionModel.selectACreatorAtMouseEvent(e); |
|
designer.repaint(); |
|
|
|
if (editingMouseListener.stopEditing()) { |
|
if (this != designer.getRootComponent()) { |
|
ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); |
|
editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* XWCardMainBorderLayout是card布局主体框架,tab的顶层布局 |
|
* @return |
|
*/ |
|
@Override |
|
public XLayoutContainer getTopLayout() { |
|
return this; |
|
} |
|
|
|
@Override |
|
public int getIndexOfChild(Object child) { |
|
XWCardTitleLayout titlePart = this.getTitlePart(); |
|
return titlePart.getIndexOfChild(child); |
|
} |
|
|
|
/** |
|
* data属性改变触发其他操作 |
|
* |
|
*/ |
|
@Override |
|
public void firePropertyChange(){ |
|
return; |
|
} |
|
|
|
|
|
public void resetTabDisplayPosition(WTabDisplayPosition wTabDisplayPosition){ |
|
XWCardTitleLayout xwCardTitleLayout = getTitlePart(); |
|
int titleSize = getTitleWidth(); |
|
xwCardTitleLayout.resetNewBtnPosition(wTabDisplayPosition); |
|
Rectangle parentBounds = new Rectangle(xwCardTitleLayout.getBounds()); |
|
switch (wTabDisplayPosition){ |
|
case TOP_POSITION: |
|
this.addTitlePart(xwCardTitleLayout, WBorderLayout.NORTH); |
|
parentBounds.height = titleSize; |
|
break; |
|
case LEFT_POSITION: |
|
this.addTitlePart(xwCardTitleLayout, WBorderLayout.WEST); |
|
parentBounds.width = titleSize; |
|
break; |
|
case BOTTOM_POSITION: |
|
this.addTitlePart(xwCardTitleLayout, WBorderLayout.SOUTH); |
|
parentBounds.height = titleSize; |
|
break; |
|
case RIGHT_POSITION: |
|
this.addTitlePart(xwCardTitleLayout, WBorderLayout.EAST); |
|
parentBounds.width = titleSize; |
|
break; |
|
default: |
|
break; |
|
} |
|
xwCardTitleLayout.setBounds(parentBounds); |
|
this.addCardPart((XWCardLayout)this.getComponent(0)); |
|
} |
|
|
|
@Override |
|
public LayoutAdapter getLayoutAdapter() { |
|
return new FRCardMainBorderLayoutAdapter(this); |
|
} |
|
|
|
/** |
|
* 是否支持共享-现只支持报表块、图表、tab块、绝对布局 |
|
* @return |
|
*/ |
|
public boolean isSupportShared() { |
|
return true; |
|
} |
|
|
|
}
|
|
|