From f501c702ca60c656bc7eab24c2ed0d968a858903 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 23 Jun 2022 14:45:13 +0200 Subject: [PATCH] Introduce plain styled control and editable text. --- .../argeo/cms/swt/widgets/EditableText.java | 135 ++++++++++++++++ .../argeo/cms/swt/widgets/StyledControl.java | 151 ++++++++++++++++++ 2 files changed, 286 insertions(+) create mode 100644 eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/EditableText.java create mode 100644 eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/StyledControl.java diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/EditableText.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/EditableText.java new file mode 100644 index 000000000..0612e8f9b --- /dev/null +++ b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/EditableText.java @@ -0,0 +1,135 @@ +package org.argeo.cms.swt.widgets; + +import org.argeo.cms.swt.CmsSwtUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** Editable text part displaying styled text. */ +public class EditableText extends StyledControl { + private static final long serialVersionUID = -6372283442330912755L; + + private boolean editable = true; + private boolean multiLine = true; + + private Color highlightColor; + private Composite highlight; + + private boolean useTextAsLabel = false; + + public EditableText(Composite parent, int style) { + super(parent, style); + editable = !(SWT.READ_ONLY == (style & SWT.READ_ONLY)); + multiLine = !(SWT.SINGLE == (style & SWT.SINGLE)); + highlightColor = parent.getDisplay().getSystemColor(SWT.COLOR_GRAY); + useTextAsLabel = SWT.FLAT == (style & SWT.FLAT); + } + + @Override + protected Control createControl(Composite box, String style) { + if (isEditing() && getEditable()) { + return createText(box, style, true); + } else { + if (useTextAsLabel) { + return createTextLabel(box, style); + } else { + return createLabel(box, style); + } + } + } + + protected Label createLabel(Composite box, String style) { + Label lbl = new Label(box, getStyle() | SWT.WRAP); + lbl.setLayoutData(CmsSwtUtils.fillWidth()); + if (style != null) + CmsSwtUtils.style(lbl, style); + CmsSwtUtils.markup(lbl); + if (mouseListener != null) + lbl.addMouseListener(mouseListener); + return lbl; + } + + protected Text createTextLabel(Composite box, String style) { + Text lbl = new Text(box, getStyle() | (multiLine ? SWT.MULTI : SWT.SINGLE)); + lbl.setEditable(false); + lbl.setLayoutData(CmsSwtUtils.fillWidth()); + if (style != null) + CmsSwtUtils.style(lbl, style); + CmsSwtUtils.markup(lbl); + if (mouseListener != null) + lbl.addMouseListener(mouseListener); + return lbl; + } + + protected Text createText(Composite box, String style, boolean editable) { + highlight = new Composite(box, SWT.NONE); + highlight.setBackground(highlightColor); + GridData highlightGd = new GridData(SWT.FILL, SWT.FILL, false, false); + highlightGd.widthHint = 5; + highlightGd.heightHint = 3; + highlight.setLayoutData(highlightGd); + + final Text text = new Text(box, getStyle() | (multiLine ? SWT.MULTI : SWT.SINGLE) | SWT.WRAP); + text.setEditable(editable); + GridData textLayoutData = CmsSwtUtils.fillWidth(); + // textLayoutData.heightHint = preferredHeight; + text.setLayoutData(textLayoutData); + if (style != null) + CmsSwtUtils.style(text, style); + text.setFocus(); + return text; + } + + @Override + protected void clear(boolean deep) { + if (highlight != null) + highlight.dispose(); + super.clear(deep); + } + + public void setText(String text) { + Control child = getControl(); + if (child instanceof Label) + ((Label) child).setText(text); + else if (child instanceof Text) + ((Text) child).setText(text); + } + + public Text getAsText() { + return (Text) getControl(); + } + + public Label getAsLabel() { + return (Label) getControl(); + } + + public String getText() { + Control child = getControl(); + + if (child instanceof Label) + return ((Label) child).getText(); + else if (child instanceof Text) + return ((Text) child).getText(); + else + throw new IllegalStateException("Unsupported control " + child.getClass()); + } + + /** @deprecated Use {@link #isEditable()} instead. */ + @Deprecated + public boolean getEditable() { + return isEditable(); + } + + public boolean isEditable() { + return editable; + } + + public void setUseTextAsLabel(boolean useTextAsLabel) { + this.useTextAsLabel = useTextAsLabel; + } + +} diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/StyledControl.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/StyledControl.java new file mode 100644 index 000000000..82c04a26c --- /dev/null +++ b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/StyledControl.java @@ -0,0 +1,151 @@ +package org.argeo.cms.swt.widgets; + +import org.argeo.api.cms.ux.CmsStyle; +import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.swt.SwtEditablePart; +import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** Editable text part displaying styled text. */ +public abstract class StyledControl extends Composite implements SwtEditablePart { + private static final long serialVersionUID = -6372283442330912755L; + private Control control; + + private Composite container; + private Composite box; + + protected MouseListener mouseListener; + protected FocusListener focusListener; + + private Boolean editing = Boolean.FALSE; + + private Composite ancestorToLayout; + + public StyledControl(Composite parent, int swtStyle) { + super(parent, swtStyle); + setLayout(CmsSwtUtils.noSpaceGridLayout()); + } + + protected abstract Control createControl(Composite box, String style); + + protected Composite createBox() { + Composite box = new Composite(container, SWT.INHERIT_DEFAULT); + setContainerLayoutData(box); + box.setLayout(CmsSwtUtils.noSpaceGridLayout(3)); + return box; + } + + protected Composite createContainer() { + Composite container = new Composite(this, SWT.INHERIT_DEFAULT); + setContainerLayoutData(container); + container.setLayout(CmsSwtUtils.noSpaceGridLayout()); + return container; + } + + @Override + public Control getControl() { + return control; + } + + protected synchronized Boolean isEditing() { + return editing; + } + + @Override + public synchronized void startEditing() { + assert !isEditing(); + editing = true; + // int height = control.getSize().y; + String style = (String) EclipseUiSpecificUtils.getStyleData(control); + clear(false); + refreshControl(style); + + // add the focus listener to the newly created edition control + if (focusListener != null) + control.addFocusListener(focusListener); + } + + @Override + public synchronized void stopEditing() { + assert isEditing(); + editing = false; + String style = (String) EclipseUiSpecificUtils.getStyleData(control); + clear(false); + refreshControl(style); + } + + protected void refreshControl(String style) { + control = createControl(box, style); + setControlLayoutData(control); + if (ancestorToLayout != null) + ancestorToLayout.layout(true, true); + else + getParent().layout(true, true); + } + + public void setStyle(CmsStyle style) { + setStyle(style.style()); + } + + public void setStyle(String style) { + Object currentStyle = null; + if (control != null) + currentStyle = EclipseUiSpecificUtils.getStyleData(control); + if (currentStyle != null && currentStyle.equals(style)) + return; + + clear(true); + refreshControl(style); + + if (style != null) { + CmsSwtUtils.style(box, style + "_box"); + CmsSwtUtils.style(container, style + "_container"); + } + } + + /** To be overridden */ + protected void setControlLayoutData(Control control) { + control.setLayoutData(CmsSwtUtils.fillWidth()); + } + + /** To be overridden */ + protected void setContainerLayoutData(Composite composite) { + composite.setLayoutData(CmsSwtUtils.fillWidth()); + } + + protected void clear(boolean deep) { + if (deep) { + for (Control control : getChildren()) + control.dispose(); + container = createContainer(); + box = createBox(); + } else { + control.dispose(); + } + } + + public void setMouseListener(MouseListener mouseListener) { + if (this.mouseListener != null && control != null) + control.removeMouseListener(this.mouseListener); + this.mouseListener = mouseListener; + if (control != null && this.mouseListener != null) + control.addMouseListener(mouseListener); + } + + public void setFocusListener(FocusListener focusListener) { + if (this.focusListener != null && control != null) + control.removeFocusListener(this.focusListener); + this.focusListener = focusListener; + if (control != null && this.focusListener != null) + control.addFocusListener(focusListener); + } + + public void setAncestorToLayout(Composite ancestorToLayout) { + this.ancestorToLayout = ancestorToLayout; + } + +} -- 2.30.2