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.
376 lines
14 KiB
376 lines
14 KiB
package com.fr.design.widget.ui.designer.component; |
|
|
|
import com.fr.design.designer.beans.AdapterBus; |
|
import com.fr.design.designer.beans.adapters.layout.FRFitLayoutAdapter; |
|
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.XWFitLayout; |
|
import com.fr.design.designer.creator.XWParameterLayout; |
|
import com.fr.design.designer.creator.cardlayout.XWCardLayout; |
|
import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; |
|
import com.fr.design.dialog.BasicPane; |
|
import com.fr.design.dialog.FineJOptionPane; |
|
import com.fr.design.event.GlobalNameListener; |
|
import com.fr.design.event.GlobalNameObserver; |
|
import com.fr.design.event.UIObserver; |
|
import com.fr.design.event.UIObserverListener; |
|
import com.fr.design.file.HistoryTemplateListCache; |
|
import com.fr.design.gui.ispinner.UISpinner; |
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
import com.fr.design.mainframe.FormDesigner; |
|
import com.fr.design.mainframe.JForm; |
|
import com.fr.design.mainframe.JTemplate; |
|
import com.fr.design.mainframe.WidgetPropertyPane; |
|
import com.fr.design.utils.ComponentUtils; |
|
import com.fr.design.widget.WidgetBoundsPaneFactory; |
|
import com.fr.form.ui.PaddingMargin; |
|
import com.fr.form.ui.Widget; |
|
import com.fr.form.ui.container.WFitLayout; |
|
import com.fr.form.ui.container.WLayout; |
|
import com.fr.general.IOUtils; |
|
|
|
import javax.swing.*; |
|
import javax.swing.event.ChangeEvent; |
|
import javax.swing.event.ChangeListener; |
|
import javax.swing.plaf.basic.BasicButtonUI; |
|
import java.awt.*; |
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
|
|
import static com.fr.design.i18n.Toolkit.i18nText; |
|
|
|
|
|
/** |
|
* Created by ibm on 2017/7/30. |
|
*/ |
|
|
|
public class WidgetBoundPane extends BasicPane { |
|
private static final int MINHEIGHT = WLayout.MIN_HEIGHT; |
|
private static final int MINWIDTH = WLayout.MIN_WIDTH; |
|
protected XLayoutContainer parent; |
|
protected XCreator creator; |
|
protected UISpinner width; |
|
protected UISpinner height; |
|
protected AspectRatioLockedButton ratioLockedButton; |
|
|
|
public WidgetBoundPane(XCreator source) { |
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
|
this.creator = source; |
|
this.parent = getParent(source); |
|
initBoundPane(); |
|
} |
|
|
|
public XLayoutContainer getParent(XCreator source) { |
|
if(source.acceptType(XWCardTagLayout.class)){ |
|
return (XLayoutContainer)source.getParent(); |
|
} |
|
XLayoutContainer container = XCreatorUtils.getParentXLayoutContainer(source); |
|
if (source.acceptType(XWFitLayout.class) || source.acceptType(XWParameterLayout.class)) { |
|
container = null; |
|
} |
|
return container; |
|
} |
|
|
|
public void initBoundPane() { |
|
width = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0d); |
|
height = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0d); |
|
width.setGlobalName(i18nText("Fine-Design_Form_Coords_And_Size")); |
|
height.setGlobalName(i18nText("Fine-Design_Form_Coords_And_Size")); |
|
if (creator.acceptType(XWCardLayout.class)) { |
|
width.setEnabled(false); |
|
height.setEnabled(false); |
|
} |
|
|
|
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
if (jTemplate.isJWorkBook() || !((JForm)jTemplate).isSelectRootPane()) { |
|
ratioLockedButton = new AspectRatioLockedButton(width, height); |
|
ratioLockedButton.setGlobalName(i18nText("Fine-Design_Form_Coords_And_Size")); |
|
ratioLockedButton.setLockEnabled(false); |
|
} |
|
|
|
this.add(WidgetBoundsPaneFactory.createBoundsPane(width, height, ratioLockedButton, getNameAttribute())); |
|
} |
|
|
|
protected WidgetBoundsPaneFactory.NameAttribute getNameAttribute() { |
|
WidgetBoundsPaneFactory.NameAttribute nameAttribute = WidgetBoundsPaneFactory.NameAttribute.DEFAULT; |
|
if (!isComponent()) { |
|
nameAttribute = WidgetBoundsPaneFactory.NameAttribute.WIDGET; |
|
} |
|
return nameAttribute; |
|
} |
|
|
|
protected boolean isComponent() { |
|
XCreator creator = XCreatorUtils.getXCreatorInnerWidget(this.creator); |
|
return creator.isComponent(); |
|
} |
|
|
|
|
|
public void update() { |
|
fix(); |
|
} |
|
|
|
@Override |
|
protected String title4PopupWindow() { |
|
return "widgetBound"; |
|
} |
|
|
|
public void populate() { |
|
if (ratioLockedButton == null) { |
|
Rectangle bounds = new Rectangle(creator.getBounds()); |
|
width.setValue(bounds.width); |
|
height.setValue(bounds.height); |
|
} else { |
|
ratioLockedButton.populate(creator); |
|
} |
|
} |
|
|
|
public void fix() { |
|
Rectangle bounds = new Rectangle(creator.getBounds()); |
|
creator.setBackupBound(creator.getBounds()); |
|
int w = (int) width.getValue(); |
|
int h = (int) height.getValue(); |
|
Rectangle rec = ComponentUtils.getRelativeBounds(parent); |
|
WLayout wabs = parent.toData(); |
|
if (bounds.width != w) { |
|
limitWidth(wabs, w, bounds, rec); |
|
} |
|
if (bounds.height != h) { |
|
limitHeight(wabs, h, bounds, rec); |
|
} |
|
if (ratioLockedButton != null) { |
|
ratioLockedButton.update(creator); |
|
} |
|
} |
|
|
|
|
|
public void adjustComponents(Rectangle bounds, int difference, int row) { |
|
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); |
|
Rectangle backupBounds = getBound(); |
|
FRFitLayoutAdapter layoutAdapter = (FRFitLayoutAdapter) AdapterBus.searchLayoutAdapter(formDesigner, creator); |
|
if (layoutAdapter != null) { |
|
layoutAdapter.setEdit(true); |
|
layoutAdapter.calculateBounds(backupBounds, bounds, creator, row, difference); |
|
} |
|
} |
|
|
|
public void limitWidth(WLayout wabs, int w, Rectangle bounds, Rectangle rec) { |
|
int difference = 0; |
|
int minWidth = (int) (MINWIDTH * ((WFitLayout) wabs).getResolutionScaling()); |
|
PaddingMargin margin = wabs.getMargin(); |
|
if (bounds.width != w) { |
|
if (bounds.width == rec.width - margin.getLeft() - margin.getRight()) { |
|
FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Beyond_Bounds")); |
|
width.setValue(bounds.width); |
|
return; |
|
} else if (w < minWidth) { |
|
FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Min_Width") + Integer.toString(minWidth)); |
|
width.setValue(bounds.width); |
|
return; |
|
} |
|
difference = bounds.width - w; |
|
bounds.width = w; |
|
} |
|
wabs.setBounds(creator.toData(), bounds); |
|
adjustComponents(bounds, difference, 0); |
|
} |
|
|
|
public void limitHeight(WLayout wabs, int h, Rectangle bounds, Rectangle rec) { |
|
int difference = 0; |
|
PaddingMargin margin = wabs.getMargin(); |
|
int minHeight = (int) (MINHEIGHT * ((WFitLayout) wabs).getResolutionScaling()); |
|
if (bounds.height != h) { |
|
if (bounds.height == rec.height - margin.getTop() - margin.getBottom()) { |
|
FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Beyond_Bounds")); |
|
height.setValue(bounds.height); |
|
return; |
|
} else if (h < minHeight) { |
|
FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Min_Height") + Integer.toString(minHeight)); |
|
height.setValue(bounds.height); |
|
return; |
|
} |
|
difference = bounds.height - h; |
|
bounds.height = h; |
|
} |
|
wabs.setBounds(creator.toData(), bounds); |
|
adjustComponents(bounds, difference, 1); |
|
} |
|
|
|
|
|
public Rectangle getBound() { |
|
Rectangle bounds = new Rectangle(creator.getBounds()); |
|
if (parent == null) { |
|
return bounds; |
|
} |
|
Rectangle rec = ComponentUtils.getRelativeBounds(parent); |
|
bounds.x += rec.x; |
|
bounds.y += rec.y; |
|
return bounds; |
|
|
|
} |
|
|
|
protected static class AspectRatioLockedButton extends JButton implements UIObserver, GlobalNameObserver { |
|
|
|
private final Icon enabledLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_lock_enabled.png"); |
|
private final Icon disabledLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_lock_disabled.png"); |
|
private final Icon enabledUnLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_unlock_enabled.png"); |
|
private final Icon disabledUnLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_unlock_disabled.png"); |
|
|
|
private UIObserverListener uiObserverListener; |
|
private GlobalNameListener globalNameListener; |
|
private String globalName = null; |
|
|
|
private final UISpinner mWidthSpinner; |
|
private final UISpinner mHeightSpinner; |
|
|
|
protected double aspectRatioBackup = 0; |
|
|
|
public AspectRatioLockedButton(UISpinner widthSpinner, UISpinner heightSpinner) { |
|
setUI(new BasicButtonUI()); |
|
setBorderPainted(false); |
|
setBorder(null); |
|
setContentAreaFilled(false); |
|
setPreferredSize(new Dimension(24, 24)); |
|
|
|
this.mWidthSpinner = widthSpinner; |
|
this.mHeightSpinner = heightSpinner; |
|
|
|
addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
double width = mWidthSpinner.getValue(); |
|
double height = mHeightSpinner.getValue(); |
|
boolean nextLocked = !isLocked(); |
|
|
|
if (nextLocked && width > 0 && height > 0) { |
|
setLocked(true); |
|
aspectRatioBackup = width / height; |
|
} else { |
|
setLocked(false); |
|
aspectRatioBackup = -1; |
|
} |
|
|
|
if (globalNameListener != null) { |
|
globalNameListener.setGlobalName(globalName); |
|
} |
|
|
|
if (uiObserverListener != null) { |
|
uiObserverListener.doChange(); |
|
} |
|
} |
|
}); |
|
|
|
mWidthSpinner.addChangeListener(new ChangeListener() { |
|
@Override |
|
public void stateChanged(ChangeEvent e) { |
|
if (isLockEnabled() && isLocked()) { |
|
if (mWidthSpinner.getValue() == 0) { |
|
setLocked(false); |
|
aspectRatioBackup = -1; |
|
} else if (aspectRatioBackup > 0) { |
|
double value = mWidthSpinner.getValue() / aspectRatioBackup; |
|
mHeightSpinner.setValue(Math.round(value), false); |
|
} |
|
} |
|
} |
|
}); |
|
mHeightSpinner.addChangeListener(new ChangeListener() { |
|
@Override |
|
public void stateChanged(ChangeEvent e) { |
|
if (isLockEnabled() && isLocked()) { |
|
if (mHeightSpinner.getValue() == 0) { |
|
setLocked(false); |
|
aspectRatioBackup = -1; |
|
}else if (aspectRatioBackup > 0) { |
|
double value = mHeightSpinner.getValue() * aspectRatioBackup; |
|
mWidthSpinner.setValue(Math.round(value), false); |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
@Override |
|
public Icon getIcon() { |
|
if (this.isLocked()) { |
|
if (this.isLockEnabled()) { |
|
return enabledLocked; |
|
} else { |
|
return disabledLocked; |
|
} |
|
} else { |
|
if (this.isLockEnabled()) { |
|
return enabledUnLocked; |
|
} else { |
|
return disabledUnLocked; |
|
} |
|
} |
|
} |
|
|
|
public void setLocked(boolean locked) { |
|
this.setSelected(locked); |
|
} |
|
|
|
public boolean isLocked() { |
|
return this.isSelected(); |
|
} |
|
|
|
public boolean isLockEnabled() { |
|
return this.isEnabled(); |
|
} |
|
|
|
public void setLockEnabled(boolean enabled) { |
|
this.setEnabled(enabled); |
|
setToolTipText(isLockEnabled() ? null : i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Button_ToolTip")); |
|
} |
|
|
|
public void populate(XCreator creator) { |
|
Rectangle bounds = new Rectangle(creator.getBounds()); |
|
Widget widget = creator.toData(); |
|
|
|
aspectRatioBackup = widget.getAspectRatioBackup(); |
|
setLocked(widget.isAspectRatioLocked()); |
|
|
|
mWidthSpinner.setValue(bounds.width, false); |
|
mHeightSpinner.setValue(bounds.height, false); |
|
} |
|
|
|
public void update(XCreator creator) { |
|
Widget widget = creator.toData(); |
|
if (widget != null) { |
|
if (this.isLocked()) { |
|
widget.setAspectRatioLocked(true); |
|
widget.setAspectRatioBackup(this.aspectRatioBackup); |
|
} else { |
|
widget.setAspectRatioLocked(false); |
|
widget.setAspectRatioBackup(-1.0); |
|
} |
|
} |
|
} |
|
|
|
@Override |
|
public void registerChangeListener(UIObserverListener listener) { |
|
uiObserverListener = listener; |
|
} |
|
|
|
@Override |
|
public boolean shouldResponseChangeListener() { |
|
return true; |
|
} |
|
|
|
@Override |
|
public void registerNameListener(GlobalNameListener listener) { |
|
this.globalNameListener = listener; |
|
} |
|
|
|
@Override |
|
public boolean shouldResponseNameListener() { |
|
return true; |
|
} |
|
|
|
@Override |
|
public void setGlobalName(String name) { |
|
this.globalName = name; |
|
} |
|
} |
|
}
|
|
|