mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-04 12:17:41 +08:00
PL-10022 Help icons for UI fields
This commit is contained in:
parent
e4ce5365ee
commit
e928e7f0cc
@ -25,6 +25,7 @@ import com.haulmont.cuba.core.config.SourceType;
|
||||
import com.haulmont.cuba.core.config.defaults.Default;
|
||||
import com.haulmont.cuba.core.config.defaults.DefaultBoolean;
|
||||
import com.haulmont.cuba.core.config.defaults.DefaultInt;
|
||||
import com.haulmont.cuba.core.config.defaults.DefaultString;
|
||||
import com.haulmont.cuba.core.config.type.Factory;
|
||||
import com.haulmont.cuba.core.config.type.IntegerListTypeFactory;
|
||||
|
||||
@ -115,4 +116,9 @@ public interface DesktopConfig extends Config {
|
||||
@Property("cuba.desktop.loginDialogDefaultPassword")
|
||||
@Default("admin")
|
||||
String getLoginDialogDefaultPassword();
|
||||
|
||||
@Property("cuba.desktop.showTooltipShortcut")
|
||||
@Source(type = SourceType.DATABASE)
|
||||
@DefaultString("F1")
|
||||
String getShowTooltipShortcut();
|
||||
}
|
@ -44,6 +44,7 @@
|
||||
<xs:element name="font" type="fontType"/>
|
||||
<xs:element name="insets" type="insetsType"/>
|
||||
<xs:element name="dimension" type="dimensionType"/>
|
||||
<xs:element name="int" type="intType" maxOccurs="unbounded" minOccurs="0"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
@ -70,6 +71,11 @@
|
||||
<xs:attribute type="xs:string" name="value" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="intType">
|
||||
<xs:attribute type="xs:string" name="property" use="required"/>
|
||||
<xs:attribute type="xs:integer" name="value" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="layoutSettingsType">
|
||||
<xs:attribute type="xs:int" name="margin-size" use="optional"/>
|
||||
<xs:attribute type="xs:int" name="spacing-size" use="optional"/>
|
||||
|
@ -21,6 +21,8 @@ import com.haulmont.cuba.desktop.sys.DesktopToolTipManager;
|
||||
import com.haulmont.cuba.desktop.sys.layout.BoxLayoutAdapter;
|
||||
import com.haulmont.cuba.desktop.sys.vcl.ToolTipButton;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.Component.HasContextHelp;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@ -37,20 +39,24 @@ public class ComponentCaption extends JPanel {
|
||||
}
|
||||
|
||||
private void takeOwnerProperties() {
|
||||
if (label == null) {
|
||||
label = new JLabel();
|
||||
add(label);
|
||||
if (!(owner instanceof DesktopCheckBox)) {
|
||||
if (label == null) {
|
||||
label = new JLabel();
|
||||
add(label);
|
||||
}
|
||||
|
||||
label.setText(((Component.HasCaption) owner).getCaption());
|
||||
}
|
||||
|
||||
label.setText(((Component.HasCaption) owner).getCaption());
|
||||
if (((Component.HasCaption) owner).getDescription() != null) {
|
||||
String contextHelpText = getContextHelpText();
|
||||
if (StringUtils.isNotEmpty(contextHelpText)) {
|
||||
if (toolTipButton == null) {
|
||||
toolTipButton = new ToolTipButton();
|
||||
toolTipButton.setFocusable(false);
|
||||
DesktopToolTipManager.getInstance().registerTooltip(toolTipButton);
|
||||
add(toolTipButton);
|
||||
}
|
||||
toolTipButton.setToolTipText(((Component.HasCaption) owner).getDescription());
|
||||
toolTipButton.setToolTipText(contextHelpText);
|
||||
} else if (toolTipButton != null) {
|
||||
remove(toolTipButton);
|
||||
toolTipButton = null;
|
||||
@ -60,6 +66,15 @@ public class ComponentCaption extends JPanel {
|
||||
setEnabled(owner.isEnabled());
|
||||
}
|
||||
|
||||
protected String getContextHelpText() {
|
||||
if (owner instanceof HasContextHelp) {
|
||||
return DesktopComponentsHelper.getContextHelpText(
|
||||
((HasContextHelp) owner).getContextHelpText(),
|
||||
((HasContextHelp) owner).isContextHelpTextHtmlEnabled());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
takeOwnerProperties();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.google.common.collect.Iterables;
|
||||
import com.haulmont.bali.datastruct.Pair;
|
||||
import com.haulmont.cuba.desktop.gui.data.DesktopContainerHelper;
|
||||
import com.haulmont.cuba.desktop.sys.layout.BoxLayoutAdapter;
|
||||
import com.haulmont.cuba.desktop.sys.layout.MigLayoutHelper;
|
||||
import com.haulmont.cuba.gui.ComponentsHelper;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.Frame;
|
||||
@ -74,37 +75,31 @@ public abstract class DesktopAbstractBox
|
||||
remove(component);
|
||||
}
|
||||
|
||||
int implIndex = getActualIndex(index);
|
||||
|
||||
// add caption first
|
||||
ComponentCaption caption = null;
|
||||
boolean haveDescription = false;
|
||||
if (DesktopContainerHelper.hasExternalCaption(component)) {
|
||||
caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
impl.add(caption, layoutAdapter.getCaptionConstraints(component), implIndex); // CAUTION this dramatically wrong
|
||||
implIndex++;
|
||||
} else if (DesktopContainerHelper.hasExternalDescription(component)) {
|
||||
caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
haveDescription = true;
|
||||
}
|
||||
|
||||
JComponent composition = DesktopComponentsHelper.getComposition(component);
|
||||
//if component have description without caption, we need to wrap
|
||||
// component to view Description button horizontally after component
|
||||
if (haveDescription) {
|
||||
boolean hasExternalCaption = DesktopContainerHelper.hasExternalCaption(component);
|
||||
if (hasExternalCaption
|
||||
|| DesktopContainerHelper.hasExternalContextHelp(component)) {
|
||||
ComponentCaption caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
|
||||
JPanel wrapper = new LayoutSlot();
|
||||
BoxLayoutAdapter adapter = BoxLayoutAdapter.create(wrapper);
|
||||
adapter.setExpandLayout(true);
|
||||
adapter.setSpacing(false);
|
||||
adapter.setMargin(false);
|
||||
wrapper.add(composition);
|
||||
wrapper.add(caption,new CC().alignY("top"));
|
||||
impl.add(wrapper, layoutAdapter.getConstraints(component), implIndex);
|
||||
|
||||
if (hasExternalCaption) {
|
||||
adapter.setFlowDirection(BoxLayoutAdapter.FlowDirection.Y);
|
||||
wrapper.add(caption, 0);
|
||||
} else {
|
||||
wrapper.add(caption, new CC().alignY("top"));
|
||||
}
|
||||
|
||||
impl.add(wrapper, layoutAdapter.getConstraints(component), index);
|
||||
wrappers.put(component, new Pair<>(wrapper, adapter));
|
||||
} else {
|
||||
impl.add(composition, layoutAdapter.getConstraints(component), implIndex);
|
||||
impl.add(composition, layoutAdapter.getConstraints(component), index);
|
||||
}
|
||||
|
||||
if (component.getId() != null) {
|
||||
@ -152,16 +147,6 @@ public abstract class DesktopAbstractBox
|
||||
frame.registerComponent(component);
|
||||
}
|
||||
|
||||
protected int getActualIndex(int originalIndex) {
|
||||
int index = originalIndex;
|
||||
Object[] components = ownComponents.toArray();
|
||||
for (int i = 0; i < originalIndex; i++) {
|
||||
if (DesktopContainerHelper.hasExternalCaption((Component)components[i]))
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Component component) {
|
||||
JComponent composition = DesktopComponentsHelper.getComposition(component);
|
||||
@ -269,15 +254,16 @@ public abstract class DesktopAbstractBox
|
||||
|
||||
protected void updateComponentInternal(Component child) {
|
||||
boolean componentReAdded = false;
|
||||
if (DesktopContainerHelper.mayHaveExternalCaption(child)) {
|
||||
if (DesktopContainerHelper.mayHaveExternalCaption(child)
|
||||
|| DesktopContainerHelper.mayHaveExternalContextHelp(child)) {
|
||||
if (captions.containsKey(child)
|
||||
&& !DesktopContainerHelper.hasExternalCaption(child)
|
||||
&& !DesktopContainerHelper.hasExternalDescription(child)) {
|
||||
&& !DesktopContainerHelper.hasExternalContextHelp(child)) {
|
||||
reAddChild(child);
|
||||
componentReAdded = true;
|
||||
} else if (!captions.containsKey(child)
|
||||
&& (DesktopContainerHelper.hasExternalCaption(child)
|
||||
|| DesktopContainerHelper.hasExternalDescription(child))) {
|
||||
|| DesktopContainerHelper.hasExternalContextHelp(child))) {
|
||||
reAddChild(child);
|
||||
componentReAdded = true;
|
||||
} else if (captions.containsKey(child)) {
|
||||
@ -295,6 +281,19 @@ public abstract class DesktopAbstractBox
|
||||
JComponent composition;
|
||||
if (wrappers.containsKey(child)) {
|
||||
composition = wrappers.get(child).getFirst();
|
||||
CC constraints = MigLayoutHelper.getConstraints(child);
|
||||
if (child.getHeight() == -1.0) {
|
||||
MigLayoutHelper.applyHeight(constraints, -1, UNITS_PIXELS, false);
|
||||
} else {
|
||||
MigLayoutHelper.applyHeight(constraints, 100, UNITS_PERCENTAGE, false);
|
||||
}
|
||||
if (child.getWidth() == -1.0) {
|
||||
MigLayoutHelper.applyWidth(constraints, -1, UNITS_PIXELS, false);
|
||||
} else {
|
||||
MigLayoutHelper.applyWidth(constraints, 100, UNITS_PERCENTAGE, false);
|
||||
}
|
||||
BoxLayoutAdapter adapter = wrappers.get(child).getSecond();
|
||||
adapter.updateConstraints(DesktopComponentsHelper.getComposition(child), constraints);
|
||||
} else {
|
||||
composition = DesktopComponentsHelper.getComposition(child);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import com.haulmont.cuba.gui.components.compatibility.ComponentValueListenerWrap
|
||||
import com.haulmont.cuba.gui.components.validators.BeanValidator;
|
||||
import com.haulmont.cuba.gui.data.Datasource;
|
||||
import com.haulmont.cuba.gui.data.ValueListener;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
@ -52,6 +53,9 @@ public abstract class DesktopAbstractField<C extends JComponent> extends Desktop
|
||||
protected boolean required;
|
||||
protected String requiredMessage;
|
||||
|
||||
protected String contextHelpText;
|
||||
protected Boolean contextHelpTextHtmlEnable = false;
|
||||
|
||||
protected Set<Validator> validators = new LinkedHashSet<>();
|
||||
|
||||
// todo move nimbus constants to theme
|
||||
@ -290,4 +294,32 @@ public abstract class DesktopAbstractField<C extends JComponent> extends Desktop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
return contextHelpText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
if (!ObjectUtils.equals(this.contextHelpText, contextHelpText)) {
|
||||
this.contextHelpText = contextHelpText;
|
||||
|
||||
requestContainerUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextHelpTextHtmlEnabled() {
|
||||
return contextHelpTextHtmlEnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
if (!ObjectUtils.equals(this.contextHelpTextHtmlEnable, enabled)) {
|
||||
contextHelpTextHtmlEnable = enabled;
|
||||
|
||||
requestContainerUpdate();
|
||||
}
|
||||
}
|
||||
}
|
@ -28,6 +28,8 @@ import com.haulmont.cuba.desktop.sys.vcl.JTabbedPaneExt;
|
||||
import com.haulmont.cuba.gui.components.*;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.Frame;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.Action;
|
||||
@ -42,6 +44,8 @@ public class DesktopComponentsHelper {
|
||||
|
||||
public static final int BUTTON_HEIGHT = 30;
|
||||
public static final int FIELD_HEIGHT = 28;
|
||||
public static final int TOOLTIP_WIDTH = 500;
|
||||
|
||||
|
||||
// todo move nimbus constants to theme
|
||||
public static final Color defaultBgColor = (Color) UIManager.get("nimbusLightBackground");
|
||||
@ -458,4 +462,11 @@ public class DesktopComponentsHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getContextHelpText(String contextHelpText, boolean contextHelpTextHtmlEnabled) {
|
||||
if (StringUtils.isNotEmpty(contextHelpText)) {
|
||||
return contextHelpTextHtmlEnabled ? contextHelpText : StringEscapeUtils.escapeHtml(contextHelpText);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -371,11 +371,13 @@ public class DesktopFieldGroup extends DesktopAbstractComponent<JPanel>
|
||||
DesktopAbstractComponent fieldImpl = (DesktopAbstractComponent) fieldComponent;
|
||||
fci.setComposition(fieldImpl);
|
||||
|
||||
if (fci.getDescription() != null) {
|
||||
if (fci.getContextHelpText() != null) {
|
||||
ToolTipButton tooltipBtn = new ToolTipButton();
|
||||
tooltipBtn.setVisible(fieldComponent.isVisible());
|
||||
tooltipBtn.setToolTipText(fci.getDescription());
|
||||
fci.setToolTipButton(new ToolTipButton());
|
||||
tooltipBtn.setToolTipText(DesktopComponentsHelper.getContextHelpText(
|
||||
fci.getContextHelpText(),
|
||||
fci.isContextHelpTextHtmlEnabled()));
|
||||
fci.setToolTipButton(tooltipBtn);
|
||||
} else {
|
||||
fci.setToolTipButton(null);
|
||||
}
|
||||
@ -455,11 +457,13 @@ public class DesktopFieldGroup extends DesktopAbstractComponent<JPanel>
|
||||
impl.add(label, labelCc.cell(colIndex * 3, insertRowIndex, 1, 1));
|
||||
}
|
||||
|
||||
if (Strings.isNullOrEmpty(fci.getDescription())) {
|
||||
if (Strings.isNullOrEmpty(fci.getContextHelpText())) {
|
||||
fci.setToolTipButton(null);
|
||||
} else if (fci.getToolTipButton() == null) {
|
||||
ToolTipButton toolTipButton = new ToolTipButton();
|
||||
toolTipButton.setToolTipText(fci.getDescription());
|
||||
toolTipButton.setToolTipText(DesktopComponentsHelper.getContextHelpText(
|
||||
fci.getContextHelpText(),
|
||||
fci.isContextHelpTextHtmlEnabled()));
|
||||
toolTipButton.setVisible(fieldComponent.isVisible());
|
||||
fci.setToolTipButton(toolTipButton);
|
||||
}
|
||||
@ -504,11 +508,13 @@ public class DesktopFieldGroup extends DesktopAbstractComponent<JPanel>
|
||||
DesktopAbstractComponent fieldImpl = (DesktopAbstractComponent) fci.getComponentNN();
|
||||
fci.setComposition(fieldImpl);
|
||||
|
||||
if (fci.getDescription() != null) {
|
||||
if (fci.getContextHelpText() != null) {
|
||||
ToolTipButton tooltipBtn = new ToolTipButton();
|
||||
tooltipBtn.setVisible(fci.getComponentNN().isVisible());
|
||||
tooltipBtn.setToolTipText(fci.getDescription());
|
||||
fci.setToolTipButton(new ToolTipButton());
|
||||
tooltipBtn.setToolTipText(DesktopComponentsHelper.getContextHelpText(
|
||||
fci.getContextHelpText(),
|
||||
fci.isContextHelpTextHtmlEnabled()));
|
||||
fci.setToolTipButton(tooltipBtn);
|
||||
} else {
|
||||
fci.setToolTipButton(null);
|
||||
}
|
||||
@ -546,6 +552,12 @@ public class DesktopFieldGroup extends DesktopAbstractComponent<JPanel>
|
||||
if (fci.getTargetRequiredMessage() != null) {
|
||||
cubaField.setRequiredMessage(fci.getTargetRequiredMessage());
|
||||
}
|
||||
if (fci.getTargetContextHelpText() != null) {
|
||||
cubaField.setContextHelpText(fci.getTargetContextHelpText());
|
||||
}
|
||||
if (fci.getTargetContextHelpTextHtmlEnabled() != null) {
|
||||
cubaField.setContextHelpTextHtmlEnabled(fci.getTargetContextHelpTextHtmlEnabled());
|
||||
}
|
||||
if (fci.getTargetEditable() != null) {
|
||||
cubaField.setEditable(fci.getTargetEditable());
|
||||
}
|
||||
@ -1057,6 +1069,8 @@ public class DesktopFieldGroup extends DesktopAbstractComponent<JPanel>
|
||||
protected CollectionDatasource targetOptionsDatasource;
|
||||
protected String targetCaption;
|
||||
protected String targetDescription;
|
||||
protected String targetContextHelpText;
|
||||
protected Boolean targetContextHelpTextHtmlEnabled;
|
||||
protected Formatter targetFormatter;
|
||||
protected boolean isTargetCustom;
|
||||
|
||||
@ -1415,6 +1429,40 @@ public class DesktopFieldGroup extends DesktopAbstractComponent<JPanel>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
if (component instanceof Field) {
|
||||
return ((Field) component).getContextHelpText();
|
||||
}
|
||||
return targetContextHelpText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
if (component instanceof Field) {
|
||||
((Field) component).setContextHelpText(contextHelpText);
|
||||
} else {
|
||||
this.targetContextHelpText = contextHelpText;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isContextHelpTextHtmlEnabled() {
|
||||
if (component instanceof Field) {
|
||||
return ((Field) component).isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
return targetContextHelpTextHtmlEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(Boolean enabled) {
|
||||
if (component instanceof Field) {
|
||||
((Field) component).setContextHelpTextHtmlEnabled(enabled);
|
||||
} else {
|
||||
this.targetContextHelpTextHtmlEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
if (component instanceof Field) {
|
||||
@ -1577,6 +1625,22 @@ public class DesktopFieldGroup extends DesktopAbstractComponent<JPanel>
|
||||
this.targetRequiredMessage = targetRequiredMessage;
|
||||
}
|
||||
|
||||
public String getTargetContextHelpText() {
|
||||
return targetContextHelpText;
|
||||
}
|
||||
|
||||
public void setTargetContextHelpText(String targetContextHelpText) {
|
||||
this.targetContextHelpText = targetContextHelpText;
|
||||
}
|
||||
|
||||
public Boolean getTargetContextHelpTextHtmlEnabled() {
|
||||
return targetContextHelpTextHtmlEnabled;
|
||||
}
|
||||
|
||||
public void setTargetContextHelpTextHtmlEnabled(Boolean targetContextHelpTextHtmlEnabled) {
|
||||
this.targetContextHelpTextHtmlEnabled = targetContextHelpTextHtmlEnabled;
|
||||
}
|
||||
|
||||
public CollectionDatasource getTargetOptionsDatasource() {
|
||||
return targetOptionsDatasource;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.haulmont.bali.datastruct.Pair;
|
||||
import com.haulmont.cuba.desktop.gui.data.DesktopContainerHelper;
|
||||
import com.haulmont.cuba.desktop.sys.layout.BoxLayoutAdapter;
|
||||
import com.haulmont.cuba.desktop.sys.layout.GridLayoutAdapter;
|
||||
import com.haulmont.cuba.desktop.sys.layout.MigLayoutHelper;
|
||||
import com.haulmont.cuba.gui.ComponentsHelper;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.Frame;
|
||||
@ -81,30 +82,26 @@ public class DesktopGridLayout extends DesktopAbstractComponent<JPanel> implemen
|
||||
}
|
||||
|
||||
final JComponent composition = DesktopComponentsHelper.getComposition(component);
|
||||
|
||||
// add caption first
|
||||
ComponentCaption caption = null;
|
||||
boolean haveDescription = false;
|
||||
if (DesktopContainerHelper.hasExternalCaption(component)) {
|
||||
caption = new ComponentCaption(component);
|
||||
boolean hasExternalCaption = DesktopContainerHelper.hasExternalCaption(component);
|
||||
if (hasExternalCaption
|
||||
|| DesktopContainerHelper.hasExternalContextHelp(component)) {
|
||||
ComponentCaption caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
impl.add(caption, layoutAdapter.getCaptionConstraints(component, col, row, col2, row2));
|
||||
} else if (DesktopContainerHelper.hasExternalDescription(component)) {
|
||||
caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
haveDescription = true;
|
||||
}
|
||||
|
||||
// if component have description without caption, we need to wrap
|
||||
// component to view Description button horizontally after component
|
||||
if (haveDescription) {
|
||||
JPanel wrapper = new LayoutSlot();
|
||||
BoxLayoutAdapter adapter = BoxLayoutAdapter.create(wrapper);
|
||||
adapter.setExpandLayout(true);
|
||||
adapter.setSpacing(false);
|
||||
adapter.setMargin(false);
|
||||
wrapper.add(composition);
|
||||
wrapper.add(caption, new CC().alignY("top"));
|
||||
|
||||
if (hasExternalCaption) {
|
||||
adapter.setFlowDirection(BoxLayoutAdapter.FlowDirection.Y);
|
||||
wrapper.add(caption, 0);
|
||||
} else {
|
||||
wrapper.add(caption, new CC().alignY("top"));
|
||||
}
|
||||
|
||||
impl.add(wrapper, layoutAdapter.getConstraints(component, col, row, col2, row2));
|
||||
wrappers.put(component, new Pair<>(wrapper, adapter));
|
||||
} else {
|
||||
@ -327,15 +324,16 @@ public class DesktopGridLayout extends DesktopAbstractComponent<JPanel> implemen
|
||||
public void updateComponent(Component child) {
|
||||
boolean componentReAdded = false;
|
||||
|
||||
if (DesktopContainerHelper.mayHaveExternalCaption(child)) {
|
||||
if (DesktopContainerHelper.mayHaveExternalCaption(child)
|
||||
|| DesktopContainerHelper.mayHaveExternalContextHelp(child)) {
|
||||
if (captions.containsKey(child)
|
||||
&& !DesktopContainerHelper.hasExternalCaption(child)
|
||||
&& !DesktopContainerHelper.hasExternalDescription(child)) {
|
||||
&& !DesktopContainerHelper.hasExternalContextHelp(child)) {
|
||||
reAddChild(child);
|
||||
componentReAdded = true;
|
||||
} else if (!captions.containsKey(child)
|
||||
&& (DesktopContainerHelper.hasExternalCaption(child)
|
||||
|| DesktopContainerHelper.hasExternalDescription(child))) {
|
||||
|| DesktopContainerHelper.hasExternalContextHelp(child))) {
|
||||
reAddChild(child);
|
||||
componentReAdded = true;
|
||||
} else if (captions.containsKey(child)) {
|
||||
@ -353,6 +351,19 @@ public class DesktopGridLayout extends DesktopAbstractComponent<JPanel> implemen
|
||||
JComponent composition;
|
||||
if (wrappers.containsKey(child)) {
|
||||
composition = wrappers.get(child).getFirst();
|
||||
CC constraints = MigLayoutHelper.getConstraints(child);
|
||||
if (child.getHeight() == -1.0) {
|
||||
MigLayoutHelper.applyHeight(constraints, -1, UNITS_PIXELS, false);
|
||||
} else {
|
||||
MigLayoutHelper.applyHeight(constraints, 100, UNITS_PERCENTAGE, false);
|
||||
}
|
||||
if (child.getWidth() == -1.0) {
|
||||
MigLayoutHelper.applyWidth(constraints, -1, UNITS_PIXELS, false);
|
||||
} else {
|
||||
MigLayoutHelper.applyWidth(constraints, 100, UNITS_PERCENTAGE, false);
|
||||
}
|
||||
BoxLayoutAdapter adapter = wrappers.get(child).getSecond();
|
||||
adapter.updateConstraints(DesktopComponentsHelper.getComposition(child), constraints);
|
||||
} else {
|
||||
composition = DesktopComponentsHelper.getComposition(child);
|
||||
}
|
||||
|
@ -199,6 +199,24 @@ public class DesktopListEditor extends DesktopAbstractField<JPanel> implements L
|
||||
public void setDescription(String description) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextHelpTextHtmlEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEditableToComponent(boolean editable) {
|
||||
delegate.setEditable(editable);
|
||||
|
@ -46,6 +46,7 @@ import com.haulmont.cuba.gui.data.ValueListener;
|
||||
import com.haulmont.cuba.gui.data.impl.WeakCollectionChangeListener;
|
||||
import net.miginfocom.layout.CC;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -601,6 +602,22 @@ public class DesktopTokenList extends DesktopAbstractField<JPanel> implements To
|
||||
DesktopToolTipManager.getInstance().registerTooltip(impl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
if (!ObjectUtils.equals(this.contextHelpText, contextHelpText)) {
|
||||
this.contextHelpText = contextHelpText;
|
||||
|
||||
// for now, DesktopTokenList doesn't provide context help
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
if (!ObjectUtils.equals(this.contextHelpTextHtmlEnable, enabled)) {
|
||||
contextHelpTextHtmlEnable = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getValue() {
|
||||
|
@ -992,37 +992,33 @@ public class DesktopWindow implements Window, Component.Disposable,
|
||||
remove(component);
|
||||
}
|
||||
|
||||
int implIndex = getActualIndex(index);
|
||||
|
||||
ComponentCaption caption = null;
|
||||
boolean haveDescription = false;
|
||||
if (DesktopContainerHelper.hasExternalCaption(component)) {
|
||||
caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
getContainer().add(caption, layoutAdapter.getCaptionConstraints(component), implIndex); // CAUTION this dramatically wrong
|
||||
implIndex++;
|
||||
} else if (DesktopContainerHelper.hasExternalDescription(component)) {
|
||||
caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
haveDescription = true;
|
||||
}
|
||||
|
||||
JComponent composition = DesktopComponentsHelper.getComposition(component);
|
||||
// if component have description without caption, we need to wrap
|
||||
// component to view Description button horizontally after component
|
||||
if (haveDescription) {
|
||||
boolean hasExternalCaption = DesktopContainerHelper.hasExternalCaption(component);
|
||||
if (hasExternalCaption
|
||||
|| DesktopContainerHelper.hasExternalContextHelp(component)) {
|
||||
ComponentCaption caption = new ComponentCaption(component);
|
||||
captions.put(component, caption);
|
||||
|
||||
JPanel wrapper = new JPanel();
|
||||
BoxLayoutAdapter adapter = BoxLayoutAdapter.create(wrapper);
|
||||
adapter.setExpandLayout(true);
|
||||
adapter.setSpacing(false);
|
||||
adapter.setMargin(false);
|
||||
wrapper.add(composition);
|
||||
wrapper.add(caption, new CC().alignY("top"));
|
||||
getContainer().add(wrapper, layoutAdapter.getConstraints(component), implIndex);
|
||||
|
||||
if (hasExternalCaption) {
|
||||
adapter.setFlowDirection(BoxLayoutAdapter.FlowDirection.Y);
|
||||
wrapper.add(caption, 0);
|
||||
} else {
|
||||
wrapper.add(caption, new CC().alignY("top"));
|
||||
}
|
||||
|
||||
getContainer().add(wrapper, layoutAdapter.getConstraints(component), index);
|
||||
wrappers.put(component, new Pair<>(wrapper, adapter));
|
||||
} else {
|
||||
getContainer().add(composition, layoutAdapter.getConstraints(component), implIndex);
|
||||
getContainer().add(composition, layoutAdapter.getConstraints(component), index);
|
||||
}
|
||||
|
||||
if (component.getId() != null) {
|
||||
componentByIds.put(component.getId(), component);
|
||||
}
|
||||
@ -1126,17 +1122,6 @@ public class DesktopWindow implements Window, Component.Disposable,
|
||||
requestRepaint();
|
||||
}
|
||||
|
||||
protected int getActualIndex(int originalIndex) {
|
||||
int index = originalIndex;
|
||||
Object[] components = ownComponents.toArray();
|
||||
for (int i = 0; i < originalIndex; i++) {
|
||||
if (DesktopContainerHelper.hasExternalCaption((Component) components[i])) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getOwnComponent(String id) {
|
||||
return componentByIds.get(id);
|
||||
@ -1378,15 +1363,16 @@ public class DesktopWindow implements Window, Component.Disposable,
|
||||
@Override
|
||||
public void updateComponent(Component child) {
|
||||
boolean componentReAdded = false;
|
||||
if (DesktopContainerHelper.mayHaveExternalCaption(child)) {
|
||||
if (DesktopContainerHelper.mayHaveExternalCaption(child)
|
||||
|| DesktopContainerHelper.mayHaveExternalContextHelp(child)) {
|
||||
if (captions.containsKey(child)
|
||||
&& !DesktopContainerHelper.hasExternalCaption(child)
|
||||
&& !DesktopContainerHelper.hasExternalDescription(child)) {
|
||||
&& !DesktopContainerHelper.hasExternalContextHelp(child)) {
|
||||
reAddChild(child);
|
||||
componentReAdded = true;
|
||||
} else if (!captions.containsKey(child)
|
||||
&& (DesktopContainerHelper.hasExternalCaption(child)
|
||||
|| DesktopContainerHelper.hasExternalDescription(child))) {
|
||||
|| DesktopContainerHelper.hasExternalContextHelp(child))) {
|
||||
reAddChild(child);
|
||||
componentReAdded = true;
|
||||
} else if (captions.containsKey(child)) {
|
||||
@ -1404,6 +1390,19 @@ public class DesktopWindow implements Window, Component.Disposable,
|
||||
JComponent composition;
|
||||
if (wrappers.containsKey(child)) {
|
||||
composition = wrappers.get(child).getFirst();
|
||||
CC constraints = MigLayoutHelper.getConstraints(child);
|
||||
if (child.getHeight() == -1.0) {
|
||||
MigLayoutHelper.applyHeight(constraints, -1, UNITS_PIXELS, false);
|
||||
} else {
|
||||
MigLayoutHelper.applyHeight(constraints, 100, UNITS_PERCENTAGE, false);
|
||||
}
|
||||
if (child.getWidth() == -1.0) {
|
||||
MigLayoutHelper.applyWidth(constraints, -1, UNITS_PIXELS, false);
|
||||
} else {
|
||||
MigLayoutHelper.applyWidth(constraints, 100, UNITS_PERCENTAGE, false);
|
||||
}
|
||||
BoxLayoutAdapter adapter = wrappers.get(child).getSecond();
|
||||
adapter.updateConstraints(DesktopComponentsHelper.getComposition(child), constraints);
|
||||
} else {
|
||||
composition = DesktopComponentsHelper.getComposition(child);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.haulmont.cuba.desktop.gui.components.DesktopCheckBox;
|
||||
import com.haulmont.cuba.desktop.gui.components.DesktopComponent;
|
||||
import com.haulmont.cuba.desktop.gui.components.DesktopContainer;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.Component.HasContextHelp;
|
||||
import com.haulmont.cuba.gui.components.Field;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
@ -56,6 +57,18 @@ public class DesktopContainerHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean mayHaveExternalContextHelp(Component component) {
|
||||
return component instanceof HasContextHelp;
|
||||
}
|
||||
|
||||
public static boolean hasExternalContextHelp(Component component) {
|
||||
if (component instanceof HasContextHelp) {
|
||||
final String contextHelp = ((HasContextHelp) component).getContextHelpText();
|
||||
return StringUtils.isNotEmpty(contextHelp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void assignContainer(Component component, DesktopContainer container) {
|
||||
if (component instanceof DesktopComponent) {
|
||||
((DesktopComponent) component).setContainer(container);
|
||||
|
@ -41,6 +41,8 @@
|
||||
<dimension property="DateField.dimension" value="110 28"/>
|
||||
<!--the expected dimension of one digit. to configure width only-->
|
||||
<dimension property="TimeField.digitWidth" value="23 -1"/>
|
||||
|
||||
<int property="Tooltip.maxWidth" value="500"/>
|
||||
</ui-defaults>
|
||||
|
||||
<layout margin-size="5" spacing-size="3"/>
|
||||
|
@ -17,9 +17,16 @@
|
||||
|
||||
package com.haulmont.cuba.desktop.sys;
|
||||
|
||||
import com.haulmont.cuba.core.global.AppBeans;
|
||||
import com.haulmont.cuba.core.global.Configuration;
|
||||
import com.haulmont.cuba.desktop.DesktopConfig;
|
||||
import com.haulmont.cuba.desktop.gui.components.DesktopComponentsHelper;
|
||||
import com.haulmont.cuba.desktop.sys.vcl.ToolTipButton;
|
||||
import com.haulmont.cuba.gui.components.KeyCombination;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.StyleContext;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
@ -28,24 +35,23 @@ import java.awt.event.*;
|
||||
*/
|
||||
public class DesktopToolTipManager extends MouseAdapter {
|
||||
|
||||
public static final int F1_CODE = 112;
|
||||
protected static int CLOSE_TIME = 500;
|
||||
protected static int SHOW_TIME = 1000;
|
||||
|
||||
private static int CLOSE_TIME = 500;
|
||||
private static int SHOW_TIME = 1000;
|
||||
protected boolean tooltipShowing = false;
|
||||
|
||||
private boolean tooltipShowing = false;
|
||||
protected JToolTip toolTipWindow;
|
||||
protected Popup window;
|
||||
protected JComponent component;
|
||||
|
||||
private JToolTip toolTipWindow;
|
||||
private Popup window;
|
||||
private JComponent component;
|
||||
protected Timer showTimer = new Timer(SHOW_TIME, null);
|
||||
protected Timer closeTimer;
|
||||
|
||||
private Timer showTimer = new Timer(SHOW_TIME, null);
|
||||
private Timer closeTimer;
|
||||
|
||||
private MouseListener componentMouseListener = new ComponentMouseListener();
|
||||
private KeyListener fieldKeyListener = new FieldKeyListener();
|
||||
private ActionListener btnActionListener = new ButtonClickListener();
|
||||
protected Configuration configuration = AppBeans.get(Configuration.NAME);
|
||||
|
||||
protected MouseListener componentMouseListener = new ComponentMouseListener();
|
||||
protected KeyListener fieldKeyListener = new FieldKeyListener();
|
||||
protected ActionListener btnActionListener = new ButtonClickListener();
|
||||
|
||||
private static DesktopToolTipManager instance;
|
||||
|
||||
@ -61,23 +67,20 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private DesktopToolTipManager() {
|
||||
protected DesktopToolTipManager() {
|
||||
closeTimer = new Timer(CLOSE_TIME, null);
|
||||
closeTimer.setRepeats(false);
|
||||
closeTimer.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
window.hide();
|
||||
window = null;
|
||||
tooltipShowing = false;
|
||||
toolTipWindow.removeMouseListener(DesktopToolTipManager.this);
|
||||
component.removeMouseListener(DesktopToolTipManager.this);
|
||||
closeTimer.addActionListener(e -> {
|
||||
window.hide();
|
||||
window = null;
|
||||
tooltipShowing = false;
|
||||
toolTipWindow.removeMouseListener(DesktopToolTipManager.this);
|
||||
component.removeMouseListener(DesktopToolTipManager.this);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
|
||||
private MouseEvent event;
|
||||
protected MouseEvent event;
|
||||
|
||||
@Override
|
||||
public void eventDispatched(AWTEvent e) {
|
||||
@ -96,7 +99,7 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
}, AWTEvent.MOUSE_EVENT_MASK);
|
||||
}
|
||||
|
||||
private boolean isPointInComponent(Point point, JComponent component) {
|
||||
protected boolean isPointInComponent(Point point, JComponent component) {
|
||||
if (!component.isShowing())
|
||||
return false;
|
||||
|
||||
@ -108,7 +111,7 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
|
||||
/**
|
||||
* Register tooltip for component.
|
||||
* Tooltip is displayed when user press F1 on focused component
|
||||
* The tooltip is displayed when a user either presses F1 on a focused component or hovers over it.
|
||||
* ToolTip text is taken from {@link javax.swing.JComponent#getToolTipText()}.
|
||||
*
|
||||
* @param component component to register
|
||||
@ -116,6 +119,9 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
public void registerTooltip(final JComponent component) {
|
||||
component.removeKeyListener(fieldKeyListener);
|
||||
component.addKeyListener(fieldKeyListener);
|
||||
|
||||
component.removeMouseListener(componentMouseListener);
|
||||
component.addMouseListener(componentMouseListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,7 +160,7 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
btn.addActionListener(btnActionListener);
|
||||
}
|
||||
|
||||
private void hideTooltip() {
|
||||
protected void hideTooltip() {
|
||||
closeTimer.stop();
|
||||
if (window != null) {
|
||||
window.hide();
|
||||
@ -165,10 +171,14 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private void showTooltip(JComponent field, String text) {
|
||||
protected void showTooltip(JComponent field, String text) {
|
||||
if (!field.isShowing())
|
||||
return;
|
||||
|
||||
if (StringUtils.isEmpty(text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
|
||||
if (pointerInfo == null) {
|
||||
return;
|
||||
@ -198,21 +208,43 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
}
|
||||
|
||||
component = field;
|
||||
final JToolTip toolTip = new JToolTip();
|
||||
|
||||
toolTip.setTipText("<html>" + text + "</html>");
|
||||
final JToolTip toolTip = new CubaToolTip();
|
||||
toolTip.setTipText(text);
|
||||
final Popup tooltipContainer = PopupFactory.getSharedInstance().getPopup(field, toolTip, x, y);
|
||||
tooltipContainer.show();
|
||||
window = tooltipContainer;
|
||||
toolTipWindow = toolTip;
|
||||
|
||||
tooltipShowing = true;
|
||||
if ((!(field instanceof ToolTipButton)) && ((field instanceof AbstractButton) || (field instanceof JLabel))) {
|
||||
if (!(field instanceof ToolTipButton)) {
|
||||
toolTip.addMouseListener(this);
|
||||
field.addMouseListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected class CubaToolTip extends JToolTip {
|
||||
@Override
|
||||
public void setTipText(String tipText) {
|
||||
UIDefaults lafDefaults = UIManager.getLookAndFeelDefaults();
|
||||
int maxTooltipWidth = lafDefaults.getInt("Tooltip.maxWidth");
|
||||
if (maxTooltipWidth == 0) {
|
||||
maxTooltipWidth = DesktopComponentsHelper.TOOLTIP_WIDTH;
|
||||
}
|
||||
|
||||
FontMetrics fontMetrics = StyleContext.getDefaultStyleContext().getFontMetrics(getFont());
|
||||
int actualWidth = SwingUtilities.computeStringWidth(fontMetrics, tipText);
|
||||
|
||||
if (actualWidth < maxTooltipWidth) {
|
||||
tipText = "<html>" + tipText + "</html>";
|
||||
} else {
|
||||
tipText = "<html><body width=\"" + maxTooltipWidth + "px\">" + tipText + "</body></html>";
|
||||
}
|
||||
|
||||
super.setTipText(tipText);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
closeTimer.start();
|
||||
@ -225,9 +257,9 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private class ComponentMouseListener extends MouseAdapter {
|
||||
protected class ComponentMouseListener extends MouseAdapter {
|
||||
|
||||
private JComponent cmp;
|
||||
protected JComponent cmp;
|
||||
|
||||
{
|
||||
showTimer.setRepeats(false);
|
||||
@ -243,7 +275,7 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
if (window != null) {
|
||||
if (e.getSource() != component && e.getSource() != toolTipWindow && component instanceof AbstractButton) {
|
||||
if (e.getSource() != component && e.getSource() != toolTipWindow) {
|
||||
hideTooltip();
|
||||
cmp = (JComponent) e.getSource();
|
||||
showTimer.start();
|
||||
@ -272,10 +304,14 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private class FieldKeyListener extends KeyAdapter {
|
||||
protected class FieldKeyListener extends KeyAdapter {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == F1_CODE) {
|
||||
String showTooltipShortcut = configuration.getConfig(DesktopConfig.class).getShowTooltipShortcut();
|
||||
KeyStroke keyStroke = DesktopComponentsHelper
|
||||
.convertKeyCombination(KeyCombination.create(showTooltipShortcut));
|
||||
|
||||
if (KeyStroke.getKeyStrokeForEvent(e).equals(keyStroke)) {
|
||||
hideTooltip();
|
||||
JComponent field = (JComponent) e.getSource();
|
||||
showTooltip(field, field.getToolTipText());
|
||||
@ -287,7 +323,7 @@ public class DesktopToolTipManager extends MouseAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private class ButtonClickListener implements ActionListener {
|
||||
protected class ButtonClickListener implements ActionListener {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
@ -393,6 +393,8 @@ public class DesktopThemeLoaderImpl implements DesktopThemeLoader {
|
||||
return loadInsets(element);
|
||||
} else if ("dimension".equals(elementName)) {
|
||||
return loadDimension(element);
|
||||
} else if ("int".equals(elementName)) {
|
||||
return Integer.parseInt(element.attributeValue("value"));
|
||||
} else {
|
||||
log.error("Uknown UI property value: " + elementName);
|
||||
return null;
|
||||
|
@ -89,7 +89,7 @@ org.javassist/javassist = 3.21.0-GA
|
||||
org.hibernate/hibernate-validator = 5.4.2.Final
|
||||
org.glassfish.web/javax.el = 2.2.6
|
||||
|
||||
com.vaadin = 7.7.11.cuba.1
|
||||
com.vaadin = 7.7.11.cuba.3
|
||||
com.vaadin/vaadin-shared = ${com.vaadin}
|
||||
com.vaadin/vaadin-server = ${com.vaadin}
|
||||
com.vaadin/vaadin-client = ${com.vaadin}
|
||||
|
@ -346,6 +346,35 @@ public interface Component {
|
||||
void setDescription(String description);
|
||||
}
|
||||
|
||||
/**
|
||||
* A sub-interface implemented by components that can provide a context help.
|
||||
*/
|
||||
interface HasContextHelp {
|
||||
/**
|
||||
* @return context help text
|
||||
*/
|
||||
String getContextHelpText();
|
||||
|
||||
/**
|
||||
* Sets context help text. If set, then a special icon will be added for a field.
|
||||
*
|
||||
* @param contextHelpText context help text to be set
|
||||
*/
|
||||
void setContextHelpText(String contextHelpText);
|
||||
|
||||
/**
|
||||
* @return true if field accepts context help text in HTML format, false otherwise
|
||||
*/
|
||||
boolean isContextHelpTextHtmlEnabled();
|
||||
|
||||
/**
|
||||
* Defines if context help text can be presented as HTML.
|
||||
*
|
||||
* @param enabled true if field accepts context help text in HTML format, false otherwise
|
||||
*/
|
||||
void setContextHelpTextHtmlEnabled(boolean enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Layout having a mouse click listener.
|
||||
*/
|
||||
|
@ -22,7 +22,8 @@ import java.util.Collection;
|
||||
* Base interface for "fields" - components intended to display and edit value of a certain entity attribute.
|
||||
*/
|
||||
public interface Field extends DatasourceComponent, Component.HasCaption, Component.HasValue, Component.Editable,
|
||||
Component.BelongToFrame, Component.Validatable, Component.HasIcon {
|
||||
Component.BelongToFrame, Component.Validatable, Component.HasIcon,
|
||||
Component.HasContextHelp {
|
||||
/**
|
||||
* @return whether the field must contain a non-null value
|
||||
*/
|
||||
|
@ -441,6 +441,36 @@ public interface FieldGroup extends Component, Component.BelongToFrame, Componen
|
||||
* @return options datasource
|
||||
*/
|
||||
CollectionDatasource getOptionsDatasource();
|
||||
|
||||
/**
|
||||
* @return context help text
|
||||
*/
|
||||
String getContextHelpText();
|
||||
|
||||
/**
|
||||
* Set context help text for declarative field.
|
||||
*
|
||||
* If {@link #isBound()} is true and Component implements {@link Field} then sets context help text
|
||||
* to the connected Component.
|
||||
*
|
||||
* @param contextHelpText context help text to be set
|
||||
*/
|
||||
void setContextHelpText(String contextHelpText);
|
||||
|
||||
/**
|
||||
* @return true if field accepts context help text in HTML format, null if not set for a declarative field
|
||||
*/
|
||||
Boolean isContextHelpTextHtmlEnabled();
|
||||
|
||||
/**
|
||||
* Defines if context help text can be presented as HTML.
|
||||
* <p>
|
||||
* If {@link #isBound()} is true and Component implements {@link Field} then sets this attribute
|
||||
* to the connected Component.
|
||||
*
|
||||
* @param enabled true if field accepts context help text in HTML format
|
||||
*/
|
||||
void setContextHelpTextHtmlEnabled(Boolean enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -887,6 +887,11 @@
|
||||
<xs:attribute name="description" type="resourceString"/>
|
||||
</xs:attributeGroup>
|
||||
|
||||
<xs:attributeGroup name="hasContextHelp">
|
||||
<xs:attribute name="contextHelpText" type="resourceString"/>
|
||||
<xs:attribute name="contextHelpTextHtmlEnabled" type="xs:boolean"/>
|
||||
</xs:attributeGroup>
|
||||
|
||||
<xs:attributeGroup name="hasCaptionProp">
|
||||
<xs:attribute name="caption" type="resourceString"/>
|
||||
</xs:attributeGroup>
|
||||
@ -1157,6 +1162,7 @@
|
||||
<xs:attributeGroup ref="hasTabIndex"/>
|
||||
<xs:attributeGroup ref="hasEditable"/>
|
||||
<xs:attributeGroup ref="hasDatasource"/>
|
||||
<xs:attributeGroup ref="hasContextHelp"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
@ -1205,6 +1211,7 @@
|
||||
<xs:attributeGroup ref="hasEditable"/>
|
||||
<xs:attributeGroup ref="hasRequirements"/>
|
||||
<xs:attributeGroup ref="hasDatasource"/>
|
||||
<xs:attributeGroup ref="hasContextHelp"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
@ -2106,6 +2113,7 @@
|
||||
<xs:attributeGroup ref="hasEditState"/>
|
||||
<xs:attributeGroup ref="hasVisibility"/>
|
||||
<xs:attributeGroup ref="hasTabIndex"/>
|
||||
<xs:attributeGroup ref="hasContextHelp"/>
|
||||
|
||||
<xs:attribute name="width" type="componentSize"/>
|
||||
|
||||
@ -2210,6 +2218,7 @@
|
||||
<xs:attributeGroup ref="hasCaptionSource"/>
|
||||
<xs:attributeGroup ref="hasDatasourceProp"/>
|
||||
<xs:attributeGroup ref="hasTabIndex"/>
|
||||
<xs:attributeGroup ref="hasContextHelp"/>
|
||||
|
||||
<xs:attribute name="refreshOptionsOnLookupClose" type="xs:boolean"/>
|
||||
<xs:attribute name="position" type="tokenListPosition"/>
|
||||
|
@ -228,6 +228,19 @@ public abstract class AbstractComponentLoader<T extends Component> implements Co
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadContextHelp(Component.HasContextHelp component, Element element) {
|
||||
String contextHelpText = element.attributeValue("contextHelpText");
|
||||
if (StringUtils.isNotEmpty(contextHelpText)) {
|
||||
contextHelpText = loadResourceString(contextHelpText);
|
||||
component.setContextHelpText(contextHelpText);
|
||||
}
|
||||
|
||||
String htmlEnabled = element.attributeValue("contextHelpTextHtmlEnabled");
|
||||
if (StringUtils.isNotEmpty(htmlEnabled)) {
|
||||
component.setContextHelpTextHtmlEnabled(Boolean.parseBoolean(htmlEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean loadVisible(Component component, Element element) {
|
||||
if (component instanceof DatasourceComponent
|
||||
&& ((DatasourceComponent) component).getDatasource() != null) {
|
||||
|
@ -42,6 +42,7 @@ public abstract class AbstractFieldLoader<T extends Field> extends AbstractDatas
|
||||
loadCaption(resultComponent, element);
|
||||
loadIcon(resultComponent, element);
|
||||
loadDescription(resultComponent, element);
|
||||
loadContextHelp(resultComponent, element);
|
||||
|
||||
loadValidators(resultComponent, element);
|
||||
loadRequired(resultComponent, element);
|
||||
|
@ -432,6 +432,7 @@ public class FieldGroupLoader extends AbstractComponentLoader<FieldGroup> {
|
||||
}
|
||||
}
|
||||
loadDescription(field, element);
|
||||
loadContextHelp(field, element);
|
||||
|
||||
field.setXmlDescriptor(element);
|
||||
|
||||
@ -490,6 +491,19 @@ public class FieldGroupLoader extends AbstractComponentLoader<FieldGroup> {
|
||||
return field;
|
||||
}
|
||||
|
||||
protected void loadContextHelp(FieldGroup.FieldConfig field, Element element) {
|
||||
String contextHelpText = element.attributeValue("contextHelpText");
|
||||
if (StringUtils.isNotEmpty(contextHelpText)) {
|
||||
contextHelpText = loadResourceString(contextHelpText);
|
||||
field.setContextHelpText(contextHelpText);
|
||||
}
|
||||
|
||||
String htmlEnabled = element.attributeValue("contextHelpTextHtmlEnabled");
|
||||
if (StringUtils.isNotEmpty(htmlEnabled)) {
|
||||
field.setContextHelpTextHtmlEnabled(Boolean.parseBoolean(htmlEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
protected String getDefaultCaption(FieldGroup.FieldConfig fieldConfig, Datasource fieldDatasource) {
|
||||
String caption = fieldConfig.getCaption();
|
||||
if (caption == null) {
|
||||
|
@ -45,6 +45,7 @@ public class FileUploadFieldLoader extends AbstractFieldLoader<FileUploadField>
|
||||
|
||||
loadCaption(resultComponent, element);
|
||||
loadDescription(resultComponent, element);
|
||||
loadContextHelp(resultComponent, element);
|
||||
|
||||
loadTabIndex(resultComponent, element);
|
||||
|
||||
|
@ -48,6 +48,7 @@ public class TokenListLoader extends AbstractFieldLoader<TokenList> {
|
||||
loadCaption(resultComponent, element);
|
||||
loadIcon(resultComponent, element);
|
||||
loadDescription(resultComponent, element);
|
||||
loadContextHelp(resultComponent, element);
|
||||
|
||||
loadHeight(resultComponent, element);
|
||||
loadWidth(resultComponent, element);
|
||||
|
@ -31,6 +31,9 @@ import com.vaadin.shared.ui.ComponentStateUtil;
|
||||
public class CubaCaptionWidget extends VCaption {
|
||||
|
||||
public static final String CUBA_CLASSNAME = "c-caption";
|
||||
public static final String CONTEXT_HELP_CLASSNAME = "c-context-help-button";
|
||||
|
||||
protected Element contextHelpIndicatorElement;
|
||||
|
||||
protected boolean captionPlacedAfterComponentByDefault = true;
|
||||
|
||||
@ -141,6 +144,13 @@ public class CubaCaptionWidget extends VCaption {
|
||||
captionText = null;
|
||||
}
|
||||
|
||||
if (ComponentStateUtil.hasDescription(owner.getState())
|
||||
&& captionText != null) {
|
||||
addStyleDependentName("hasdescription");
|
||||
} else {
|
||||
removeStyleDependentName("hasdescription");
|
||||
}
|
||||
|
||||
AriaHelper.handleInputRequired(owner.getWidget(), showRequired);
|
||||
|
||||
if (showRequired) {
|
||||
@ -162,6 +172,24 @@ public class CubaCaptionWidget extends VCaption {
|
||||
requiredFieldIndicator = null;
|
||||
}
|
||||
|
||||
if (owner.getState() instanceof AbstractFieldState) {
|
||||
AbstractFieldState state = (AbstractFieldState) owner
|
||||
.getState();
|
||||
if (state.contextHelpText != null && !state.contextHelpText.isEmpty()) {
|
||||
if (contextHelpIndicatorElement == null) {
|
||||
contextHelpIndicatorElement = DOM.createDiv();
|
||||
contextHelpIndicatorElement.setClassName(CONTEXT_HELP_CLASSNAME);
|
||||
|
||||
DOM.insertChild(getElement(), contextHelpIndicatorElement, getContextHelpInsertPosition());
|
||||
}
|
||||
} else {
|
||||
if (contextHelpIndicatorElement != null) {
|
||||
contextHelpIndicatorElement.removeFromParent();
|
||||
contextHelpIndicatorElement = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AriaHelper.handleInputInvalid(owner.getWidget(), showError);
|
||||
|
||||
if (showError) {
|
||||
@ -209,6 +237,9 @@ public class CubaCaptionWidget extends VCaption {
|
||||
if (errorIndicatorElement != null && errorIndicatorElement.getParentElement() == getElement()) {
|
||||
width += WidgetUtil.getRequiredWidth(errorIndicatorElement);
|
||||
}
|
||||
if (contextHelpIndicatorElement != null && contextHelpIndicatorElement.getParentElement() == getElement()) {
|
||||
width += WidgetUtil.getRequiredWidth(contextHelpIndicatorElement);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
@ -218,6 +249,10 @@ public class CubaCaptionWidget extends VCaption {
|
||||
return super.getTextElement();
|
||||
}
|
||||
|
||||
public Element getContextHelpIndicatorElement() {
|
||||
return contextHelpIndicatorElement;
|
||||
}
|
||||
|
||||
public Element getRequiredIndicatorElement() {
|
||||
return requiredFieldIndicator;
|
||||
}
|
||||
@ -226,6 +261,21 @@ public class CubaCaptionWidget extends VCaption {
|
||||
return errorIndicatorElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInsertPosition(InsertPosition element) {
|
||||
int pos = super.getInsertPosition(element);
|
||||
|
||||
if (contextHelpIndicatorElement != null) {
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
protected int getContextHelpInsertPosition() {
|
||||
return super.getInsertPosition(null);
|
||||
}
|
||||
|
||||
public void setCaptionHolder(CaptionHolder captionHolder) {
|
||||
this.captionHolder = captionHolder;
|
||||
}
|
||||
|
@ -17,7 +17,10 @@
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui.client.checkbox;
|
||||
|
||||
import com.google.gwt.aria.client.Roles;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaCheckBox;
|
||||
import com.vaadin.client.VTooltip;
|
||||
import com.vaadin.client.communication.StateChangeEvent;
|
||||
import com.vaadin.client.ui.checkbox.CheckBoxConnector;
|
||||
import com.vaadin.shared.ui.Connect;
|
||||
@ -25,6 +28,8 @@ import com.vaadin.shared.ui.Connect;
|
||||
@Connect(value = CubaCheckBox.class, loadStyle = Connect.LoadStyle.EAGER)
|
||||
public class CubaCheckBoxConnector extends CheckBoxConnector {
|
||||
|
||||
public static final String CONTEXT_HELP_CLASSNAME = "c-context-help-button";
|
||||
|
||||
@Override
|
||||
public boolean delegateCaptionHandling() {
|
||||
return getWidget().captionManagedByLayout;
|
||||
@ -45,5 +50,20 @@ public class CubaCheckBoxConnector extends CheckBoxConnector {
|
||||
getWidget().captionManagedByLayout = getState().captionManagedByLayout;
|
||||
|
||||
super.onStateChanged(stateChangeEvent);
|
||||
|
||||
if (!getWidget().captionManagedByLayout
|
||||
&& getState().contextHelpText != null
|
||||
&& !getState().contextHelpText.isEmpty()) {
|
||||
getWidget().contextHelpIcon = DOM.createSpan();
|
||||
getWidget().contextHelpIcon.setInnerHTML("?");
|
||||
getWidget().contextHelpIcon.setClassName(CONTEXT_HELP_CLASSNAME);
|
||||
Roles.getTextboxRole().setAriaHiddenState(getWidget().contextHelpIcon, true);
|
||||
|
||||
getWidget().getElement().appendChild(getWidget().contextHelpIcon);
|
||||
DOM.sinkEvents(getWidget().contextHelpIcon, VTooltip.TOOLTIP_EVENTS);
|
||||
} else if (getWidget().contextHelpIcon != null) {
|
||||
getWidget().contextHelpIcon.removeFromParent();
|
||||
getWidget().contextHelpIcon = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -17,17 +17,20 @@
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui.client.checkbox;
|
||||
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.event.dom.client.BlurEvent;
|
||||
import com.google.gwt.event.dom.client.BlurHandler;
|
||||
import com.google.gwt.event.dom.client.FocusEvent;
|
||||
import com.google.gwt.event.dom.client.FocusHandler;
|
||||
import com.google.gwt.i18n.client.HasDirection;
|
||||
import com.vaadin.client.BrowserInfo;
|
||||
import com.vaadin.client.ui.Icon;
|
||||
import com.vaadin.client.ui.VCheckBox;
|
||||
|
||||
public class CubaCheckBoxWidget extends VCheckBox implements FocusHandler, BlurHandler {
|
||||
|
||||
protected boolean captionManagedByLayout = false;
|
||||
protected Element contextHelpIcon;
|
||||
|
||||
public CubaCheckBoxWidget() {
|
||||
addBlurHandler(this);
|
||||
|
@ -17,12 +17,13 @@
|
||||
package com.haulmont.cuba.web.toolkit.ui.client.cssactionslayout;
|
||||
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaCssActionsLayout;
|
||||
import com.vaadin.client.ApplicationConnection;
|
||||
import com.vaadin.client.Paintable;
|
||||
import com.vaadin.client.UIDL;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.caption.CubaCaptionWidget;
|
||||
import com.vaadin.client.*;
|
||||
import com.vaadin.client.communication.StateChangeEvent;
|
||||
import com.vaadin.client.ui.ShortcutActionHandler;
|
||||
import com.vaadin.client.ui.csslayout.CssLayoutConnector;
|
||||
import com.vaadin.shared.AbstractComponentState;
|
||||
import com.vaadin.shared.AbstractFieldState;
|
||||
import com.vaadin.shared.ui.Connect;
|
||||
import com.vaadin.shared.ui.MarginInfo;
|
||||
|
||||
@ -60,4 +61,17 @@ public class CubaCssActionsLayoutConnector extends CssLayoutConnector implements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VCaption createCaption(ComponentConnector child) {
|
||||
return new CubaCaptionWidget(child, getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCaptionNeeded(ComponentConnector child) {
|
||||
AbstractComponentState state = child.getState();
|
||||
return super.isCaptionNeeded(child) || (state instanceof AbstractFieldState
|
||||
&& ((AbstractFieldState) state).contextHelpText != null
|
||||
&& !((AbstractFieldState) state).contextHelpText.isEmpty());
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ public class CubaFieldGroupLayoutComponentSlot extends CubaGridLayoutSlot implem
|
||||
protected static final String INDICATORS_CLASSNAME = "caption-indicators";
|
||||
|
||||
protected Element requiredElement = null;
|
||||
protected Element tooltipElement = null;
|
||||
protected Element contextHelpIndicatorElement = null;
|
||||
protected Element errorIndicatorElement = null;
|
||||
|
||||
protected Element rightCaption = null;
|
||||
@ -365,6 +365,15 @@ public class CubaFieldGroupLayoutComponentSlot extends CubaGridLayoutSlot implem
|
||||
requiredElement = null;
|
||||
}
|
||||
|
||||
if (captionWidget.getContextHelpIndicatorElement() != null) {
|
||||
captionWidget.getContextHelpIndicatorElement().removeFromParent();
|
||||
contextHelpIndicatorElement = captionWidget.getContextHelpIndicatorElement();
|
||||
rightCaption.appendChild(contextHelpIndicatorElement);
|
||||
} else if (contextHelpIndicatorElement != null) {
|
||||
contextHelpIndicatorElement.removeFromParent();
|
||||
contextHelpIndicatorElement = null;
|
||||
}
|
||||
|
||||
if (captionWidget.getErrorIndicatorElement() != null) {
|
||||
captionWidget.getErrorIndicatorElement().removeFromParent();
|
||||
|
||||
|
@ -25,6 +25,8 @@ import com.vaadin.client.ui.ShortcutActionHandler;
|
||||
import com.vaadin.client.ui.VGridLayout;
|
||||
import com.vaadin.client.ui.gridlayout.GridLayoutConnector;
|
||||
import com.vaadin.client.ui.layout.VLayoutSlot;
|
||||
import com.vaadin.shared.AbstractComponentState;
|
||||
import com.vaadin.shared.AbstractFieldState;
|
||||
import com.vaadin.shared.ui.Connect;
|
||||
|
||||
@Connect(CubaGridLayout.class)
|
||||
@ -43,7 +45,11 @@ public class CubaGridLayoutConnector extends GridLayoutConnector implements Pain
|
||||
// CAUTION copied from GridLayoutConnector.updateCaption(ComponentConnector childConnector)
|
||||
VGridLayout layout = getWidget();
|
||||
VGridLayout.Cell cell = layout.widgetToCell.get(childConnector.getWidget());
|
||||
if (VCaption.isNeeded(childConnector.getState())) {
|
||||
AbstractComponentState state = childConnector.getState();
|
||||
if (VCaption.isNeeded(state)
|
||||
|| (state instanceof AbstractFieldState
|
||||
&& ((AbstractFieldState) state).contextHelpText != null
|
||||
&& !((AbstractFieldState) state).contextHelpText.isEmpty())) {
|
||||
VLayoutSlot layoutSlot = cell.slot;
|
||||
VCaption caption = layoutSlot.getCaption();
|
||||
if (caption == null) {
|
||||
|
@ -18,13 +18,20 @@
|
||||
package com.haulmont.cuba.web.toolkit.ui.client.orderedactionslayout;
|
||||
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaOrderedActionsLayout;
|
||||
import com.vaadin.client.ApplicationConnection;
|
||||
import com.vaadin.client.Paintable;
|
||||
import com.vaadin.client.UIDL;
|
||||
import com.vaadin.client.*;
|
||||
import com.vaadin.client.ui.AbstractFieldConnector;
|
||||
import com.vaadin.client.ui.Icon;
|
||||
import com.vaadin.client.ui.ShortcutActionHandler;
|
||||
import com.vaadin.client.ui.aria.AriaHelper;
|
||||
import com.vaadin.client.ui.orderedlayout.AbstractOrderedLayoutConnector;
|
||||
import com.vaadin.client.ui.orderedlayout.CaptionPosition;
|
||||
import com.vaadin.shared.AbstractFieldState;
|
||||
import com.vaadin.shared.ComponentConstants;
|
||||
import com.vaadin.shared.communication.URLReference;
|
||||
import com.vaadin.shared.ui.Connect;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Connect(CubaOrderedActionsLayout.class)
|
||||
public class CubaOrderedActionsLayoutConnector extends AbstractOrderedLayoutConnector implements Paintable {
|
||||
|
||||
@ -46,4 +53,60 @@ public class CubaOrderedActionsLayoutConnector extends AbstractOrderedLayoutConn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateCaptionInternal(ComponentConnector child) {
|
||||
// CAUTION copied from superclass
|
||||
CubaOrderedLayoutSlot slot = (CubaOrderedLayoutSlot) getWidget().getSlot(child.getWidget());
|
||||
|
||||
String caption = child.getState().caption;
|
||||
URLReference iconUrl = child.getState().resources
|
||||
.get(ComponentConstants.ICON_RESOURCE);
|
||||
String iconUrlString = iconUrl != null ? iconUrl.getURL() : null;
|
||||
Icon icon = child.getConnection().getIcon(iconUrlString);
|
||||
|
||||
List<String> styles = child.getState().styles;
|
||||
String error = child.getState().errorMessage;
|
||||
boolean showError = error != null;
|
||||
if (child.getState() instanceof AbstractFieldState) {
|
||||
AbstractFieldState abstractFieldState = (AbstractFieldState) child
|
||||
.getState();
|
||||
showError = showError && !abstractFieldState.hideErrors;
|
||||
}
|
||||
boolean required = false;
|
||||
if (child instanceof AbstractFieldConnector) {
|
||||
required = ((AbstractFieldConnector) child).isRequired();
|
||||
}
|
||||
boolean enabled = child.isEnabled();
|
||||
|
||||
if (slot.hasCaption() && null == caption) {
|
||||
slot.setCaptionResizeListener(null);
|
||||
}
|
||||
|
||||
// Haulmont API
|
||||
String contextHelpText = null;
|
||||
if (child.getState() instanceof AbstractFieldState) {
|
||||
contextHelpText = ((AbstractFieldState) child.getState()).contextHelpText;
|
||||
}
|
||||
|
||||
// Haulmont API
|
||||
slot.setCaption(caption, contextHelpText, icon, styles, error, showError, required,
|
||||
enabled, child.getState().captionAsHtml);
|
||||
|
||||
AriaHelper.handleInputRequired(child.getWidget(), required);
|
||||
AriaHelper.handleInputInvalid(child.getWidget(), showError);
|
||||
AriaHelper.bindCaption(child.getWidget(), slot.getCaptionElement());
|
||||
|
||||
if (slot.hasCaption()) {
|
||||
CaptionPosition pos = slot.getCaptionPosition();
|
||||
slot.setCaptionResizeListener(slotCaptionResizeListener);
|
||||
if (child.isRelativeHeight()
|
||||
&& (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) {
|
||||
getWidget().updateCaptionOffset(slot.getCaptionElement());
|
||||
} else if (child.isRelativeWidth()
|
||||
&& (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) {
|
||||
getWidget().updateCaptionOffset(slot.getCaptionElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -35,12 +35,16 @@ import java.util.List;
|
||||
|
||||
public class CubaOrderedLayoutSlot extends Slot {
|
||||
|
||||
public static final String CONTEXT_HELP_CLASSNAME = "c-context-help-button";
|
||||
|
||||
protected Element contextHelpIcon;
|
||||
protected String contextHelpText;
|
||||
|
||||
public CubaOrderedLayoutSlot(VAbstractOrderedLayout layout, Widget widget) {
|
||||
super(layout, widget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCaption(String captionText, Icon icon, List<String> styles,
|
||||
public void setCaption(String captionText, String contextHelpText, Icon icon, List<String> styles,
|
||||
String error, boolean showError, boolean required, boolean enabled, boolean captionAsHtml) {
|
||||
// CAUTION copied from super
|
||||
// Caption wrappers
|
||||
@ -48,7 +52,7 @@ public class CubaOrderedLayoutSlot extends Slot {
|
||||
final Element focusedElement = WidgetUtil.getFocusedElement();
|
||||
// By default focus will not be lost
|
||||
boolean focusLost = false;
|
||||
if (captionText != null || icon != null || error != null || required) {
|
||||
if (captionText != null || icon != null || error != null || required || contextHelpText != null) {
|
||||
if (caption == null) {
|
||||
caption = DOM.createDiv();
|
||||
captionWrap = DOM.createDiv();
|
||||
@ -134,6 +138,30 @@ public class CubaOrderedLayoutSlot extends Slot {
|
||||
requiredIcon = null;
|
||||
}
|
||||
|
||||
// Context Help
|
||||
// Haulmont API
|
||||
this.contextHelpText = contextHelpText;
|
||||
if (contextHelpText != null && !contextHelpText.isEmpty()) {
|
||||
if (contextHelpIcon == null) {
|
||||
contextHelpIcon = DOM.createSpan();
|
||||
// TODO decide something better (e.g. use CSS to insert the
|
||||
// character)
|
||||
contextHelpIcon.setInnerHTML("?");
|
||||
contextHelpIcon.setClassName(CONTEXT_HELP_CLASSNAME);
|
||||
|
||||
// The question mark should not be read by the screen reader, as it is
|
||||
// purely visual. Required state is set at the element level for
|
||||
// the screen reader.
|
||||
Roles.getTextboxRole().setAriaHiddenState(contextHelpIcon, true);
|
||||
}
|
||||
if (caption != null) {
|
||||
caption.appendChild(contextHelpIcon);
|
||||
}
|
||||
} else if (this.contextHelpIcon != null) {
|
||||
this.contextHelpIcon.removeFromParent();
|
||||
this.contextHelpIcon = null;
|
||||
}
|
||||
|
||||
// Error
|
||||
if (error != null && showError) {
|
||||
if (errorIcon == null) {
|
||||
|
@ -20,20 +20,17 @@ package com.haulmont.cuba.web.toolkit.ui.client.tooltip;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.Node;
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.event.dom.client.*;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.caption.CubaCaptionWidget;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.checkbox.CubaCheckBoxWidget;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.resizabletextarea.CubaResizableTextAreaWrapperWidget;
|
||||
import com.vaadin.client.*;
|
||||
import com.vaadin.client.ui.VGridLayout;
|
||||
import com.vaadin.client.ui.gridlayout.GridLayoutConnector;
|
||||
import com.vaadin.client.ui.layout.ComponentConnectorLayoutSlot;
|
||||
import com.vaadin.client.ui.orderedlayout.Slot;
|
||||
|
||||
import static com.haulmont.cuba.web.toolkit.ui.client.caption.CubaCaptionWidget.CONTEXT_HELP_CLASSNAME;
|
||||
|
||||
public class CubaTooltip extends VTooltip {
|
||||
|
||||
@ -43,7 +40,11 @@ public class CubaTooltip extends VTooltip {
|
||||
// If required indicators are not visible we show tooltip on mouse hover otherwise only by mouse click
|
||||
protected static Boolean requiredIndicatorVisible = null;
|
||||
|
||||
protected Element contextHelpElement = DOM.createDiv();
|
||||
|
||||
public CubaTooltip() {
|
||||
contextHelpElement.setClassName("c-tooltip-context-help");
|
||||
DOM.appendChild(getWidget().getElement(), contextHelpElement);
|
||||
tooltipEventHandler = new CubaTooltipEventHandler();
|
||||
}
|
||||
|
||||
@ -81,13 +82,57 @@ public class CubaTooltip extends VTooltip {
|
||||
Profiler.leave("VTooltip.connectHandlersToWidget");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setTooltipText(TooltipInfo info) {
|
||||
super.setTooltipText(info);
|
||||
|
||||
if (info.getTitle() != null && !info.getTitle().isEmpty()) {
|
||||
description.removeAttribute("aria-hidden");
|
||||
} else {
|
||||
description.setAttribute("aria-hidden", "true");
|
||||
}
|
||||
|
||||
String contextHelp = info.getContextHelp();
|
||||
if (contextHelp != null && !contextHelp.isEmpty()) {
|
||||
if (info.isContextHelpHtmlEnabled()) {
|
||||
contextHelpElement.setInnerHTML(contextHelp);
|
||||
} else {
|
||||
if (contextHelp.contains("\n")) {
|
||||
contextHelp = WidgetUtil.escapeHTML(contextHelp).replace("\n", "<br/>");
|
||||
contextHelpElement.setInnerHTML(contextHelp);
|
||||
} else {
|
||||
contextHelpElement.setInnerText(contextHelp);
|
||||
}
|
||||
}
|
||||
contextHelpElement.getStyle().clearDisplay();
|
||||
} else {
|
||||
contextHelpElement.setInnerHTML("");
|
||||
contextHelpElement.getStyle().setDisplay(Style.Display.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
contextHelpElement.setInnerHTML("");
|
||||
super.hide();
|
||||
}
|
||||
|
||||
public class CubaTooltipEventHandler extends TooltipEventHandler {
|
||||
|
||||
protected ComponentConnector currentConnector = null;
|
||||
|
||||
protected boolean isTooltipElement(Element element) {
|
||||
return (REQUIRED_INDICATOR.equals(element.getClassName())
|
||||
|| ERROR_INDICATOR.equals(element.getClassName()));
|
||||
return (isRequiredIndicator(element)
|
||||
|| isContextHelpElement(element));
|
||||
}
|
||||
|
||||
protected boolean isRequiredIndicator(Element element) {
|
||||
return REQUIRED_INDICATOR.equals(element.getClassName())
|
||||
|| ERROR_INDICATOR.equals(element.getClassName());
|
||||
}
|
||||
|
||||
protected boolean isContextHelpElement(Element element) {
|
||||
return CONTEXT_HELP_CLASSNAME.equals(element.getClassName());
|
||||
}
|
||||
|
||||
protected void checkRequiredIndicatorVisible() {
|
||||
@ -114,22 +159,21 @@ public class CubaTooltip extends VTooltip {
|
||||
|
||||
@Override
|
||||
protected TooltipInfo getTooltipFor(Element element) {
|
||||
checkRequiredIndicatorVisible();
|
||||
Element originalElement = element;
|
||||
|
||||
if (!requiredIndicatorVisible) {
|
||||
if (isClassNameExcluded(element.getClassName())) {
|
||||
return null;
|
||||
} else {
|
||||
return super.getTooltipFor(element);
|
||||
}
|
||||
if (isClassNameExcluded(element.getClassName())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isTooltipElement(element)) {
|
||||
element = element.getParentElement().cast();
|
||||
|
||||
int index = DOM.getChildIndex(element.getParentElement().cast(), element);
|
||||
int indexOfComponent = index == 0 ? index + 1 : index - 1;
|
||||
element = DOM.getChild(element.getParentElement().cast(), indexOfComponent);
|
||||
Widget widget = WidgetUtil.findWidget(element);
|
||||
if (!(widget instanceof CubaCheckBoxWidget)) {
|
||||
int index = DOM.getChildIndex(element.getParentElement().cast(), element);
|
||||
int indexOfComponent = index == 0 ? index + 1 : index - 1;
|
||||
element = DOM.getChild(element.getParentElement().cast(), indexOfComponent);
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationConnection ac = getApplicationConnection();
|
||||
@ -159,35 +203,40 @@ public class CubaTooltip extends VTooltip {
|
||||
+ " returned a tooltip even though hasTooltip claims there are no tooltips for the connector.";
|
||||
currentConnector = connector;
|
||||
|
||||
return info;
|
||||
return updateTooltip(info, originalElement);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected TooltipInfo updateTooltip(TooltipInfo info, Element element) {
|
||||
if (isContextHelpElement(element)) {
|
||||
info.setTitle(null);
|
||||
info.setErrorMessage(null);
|
||||
} else {
|
||||
info.setContextHelp(null);
|
||||
checkRequiredIndicatorVisible();
|
||||
|
||||
if (requiredIndicatorVisible && isRequiredIndicator(element)) {
|
||||
info.setTitle(null);
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseDown(MouseDownEvent event) {
|
||||
checkRequiredIndicatorVisible();
|
||||
|
||||
if (requiredIndicatorVisible) {
|
||||
Element element = event.getNativeEvent().getEventTarget().cast();
|
||||
if (isTooltipElement(element)) {
|
||||
closeNow();
|
||||
handleShowHide(event, false);
|
||||
} else {
|
||||
hideTooltip();
|
||||
}
|
||||
Element element = event.getNativeEvent().getEventTarget().cast();
|
||||
if (isTooltipElement(element)) {
|
||||
closeNow();
|
||||
handleShowHide(event, false);
|
||||
} else {
|
||||
hideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleShowHide(DomEvent domEvent, boolean isFocused) {
|
||||
checkRequiredIndicatorVisible();
|
||||
|
||||
if (!requiredIndicatorVisible) {
|
||||
super.handleShowHide(domEvent, isFocused);
|
||||
}
|
||||
|
||||
// CAUTION copied from parent with changes
|
||||
Event event = Event.as(domEvent.getNativeEvent());
|
||||
Element element = Element.as(event.getEventTarget());
|
||||
@ -214,28 +263,25 @@ public class CubaTooltip extends VTooltip {
|
||||
handleHideEvent();
|
||||
currentConnector = null;
|
||||
} else {
|
||||
boolean hasTooltipIndicator = hasIndicators(currentConnector);
|
||||
boolean elementIsIndicator = elementIsIndicator(element);
|
||||
|
||||
if ((hasTooltipIndicator && elementIsIndicator) || (!hasTooltipIndicator)) {
|
||||
if (closing) {
|
||||
closeTimer.cancel();
|
||||
closing = false;
|
||||
}
|
||||
|
||||
if (isTooltipOpen()) {
|
||||
closeNow();
|
||||
}
|
||||
|
||||
setTooltipText(info);
|
||||
updatePosition(event, isFocused);
|
||||
|
||||
if (BrowserInfo.get().isIOS()) {
|
||||
element.focus();
|
||||
}
|
||||
|
||||
showTooltip(domEvent instanceof MouseDownEvent && elementIsIndicator);
|
||||
if (closing) {
|
||||
closeTimer.cancel();
|
||||
closing = false;
|
||||
}
|
||||
|
||||
if (isTooltipOpen()) {
|
||||
closeNow();
|
||||
}
|
||||
|
||||
setTooltipText(info);
|
||||
updatePosition(event, isFocused);
|
||||
|
||||
if (BrowserInfo.get().isIOS()) {
|
||||
element.focus();
|
||||
}
|
||||
|
||||
showTooltip(domEvent instanceof MouseDownEvent && elementIsIndicator);
|
||||
}
|
||||
|
||||
handledByFocus = isFocused;
|
||||
@ -244,59 +290,7 @@ public class CubaTooltip extends VTooltip {
|
||||
|
||||
protected boolean elementIsIndicator(Element relativeElement) {
|
||||
return relativeElement != null
|
||||
&& (REQUIRED_INDICATOR.equals(relativeElement.getClassName())
|
||||
|| ERROR_INDICATOR.equals(relativeElement.getClassName()));
|
||||
}
|
||||
|
||||
protected boolean hasIndicators(ComponentConnector connector) {
|
||||
if (connector == null || connector.getWidget() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Widget parentWidget = connector.getWidget().getParent();
|
||||
|
||||
if (parentWidget instanceof Slot) {
|
||||
Slot slot = (Slot) parentWidget;
|
||||
if (slot.getCaptionElement() != null) {
|
||||
com.google.gwt.user.client.Element captionElement = slot.getCaptionElement();
|
||||
for (int i = 0; i < captionElement.getChildCount(); i++) {
|
||||
Node child = captionElement.getChild(i);
|
||||
if (child instanceof Element
|
||||
&& (elementIsIndicator(((Element) child)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (connector.getParent() instanceof GridLayoutConnector) {
|
||||
GridLayoutConnector gridLayoutConnector = (GridLayoutConnector) connector.getParent();
|
||||
VGridLayout gridWidget = gridLayoutConnector.getWidget();
|
||||
VGridLayout.Cell cell = gridWidget.widgetToCell.get(connector.getWidget());
|
||||
|
||||
ComponentConnectorLayoutSlot slot = cell.slot;
|
||||
if (slot != null) {
|
||||
VCaption caption = slot.getCaption();
|
||||
if (caption != null) {
|
||||
com.google.gwt.user.client.Element captionElement = caption.getElement();
|
||||
for (int i = 0; i < captionElement.getChildCount(); i++) {
|
||||
Node child = captionElement.getChild(i);
|
||||
if (child instanceof Element
|
||||
&& (elementIsIndicator(((Element) child)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (caption instanceof CubaCaptionWidget) {
|
||||
CubaCaptionWidget cubaCaptionWidget = (CubaCaptionWidget) caption;
|
||||
if (cubaCaptionWidget.getRequiredIndicatorElement() != null
|
||||
|| cubaCaptionWidget.getErrorIndicatorElement() != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
&& isTooltipElement(relativeElement);
|
||||
}
|
||||
}
|
||||
}
|
@ -426,4 +426,24 @@ public abstract class WebAbstractField<T extends com.vaadin.ui.AbstractField>
|
||||
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
return component.getContextHelpText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
component.setContextHelpText(contextHelpText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextHelpTextHtmlEnabled() {
|
||||
return component.isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
component.setContextHelpTextHtmlEnabled(enabled);
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@ import com.haulmont.cuba.web.toolkit.ui.CubaFieldGroup;
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaFieldGroupLayout;
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaFieldWrapper;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
@ -325,6 +326,12 @@ public class WebFieldGroup extends WebAbstractComponent<CubaFieldGroupLayout>
|
||||
if (fci.getTargetRequiredMessage() != null) {
|
||||
cubaField.setRequiredMessage(fci.getTargetRequiredMessage());
|
||||
}
|
||||
if (fci.getTargetContextHelpText() != null) {
|
||||
cubaField.setContextHelpText(fci.getTargetContextHelpText());
|
||||
}
|
||||
if (fci.getTargetContextHelpTextHtmlEnabled() != null) {
|
||||
cubaField.setContextHelpTextHtmlEnabled(fci.getTargetContextHelpTextHtmlEnabled());
|
||||
}
|
||||
if (fci.getTargetEditable() != null) {
|
||||
cubaField.setEditable(fci.getTargetEditable());
|
||||
}
|
||||
@ -813,6 +820,8 @@ public class WebFieldGroup extends WebAbstractComponent<CubaFieldGroupLayout>
|
||||
protected CollectionDatasource targetOptionsDatasource;
|
||||
protected String targetCaption;
|
||||
protected String targetDescription;
|
||||
protected String targetContextHelpText;
|
||||
protected Boolean targetContextHelpTextHtmlEnabled;
|
||||
protected Formatter targetFormatter;
|
||||
protected boolean isTargetCustom;
|
||||
|
||||
@ -1204,6 +1213,54 @@ public class WebFieldGroup extends WebAbstractComponent<CubaFieldGroupLayout>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
if (component instanceof Field) {
|
||||
return ((Field) component).getContextHelpText();
|
||||
}
|
||||
if (composition != null && isWrapped()) {
|
||||
return composition.getContextHelpText();
|
||||
}
|
||||
return targetContextHelpText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
if (component instanceof Field) {
|
||||
((Field) component).setContextHelpText(contextHelpText);
|
||||
} else if (composition != null && isWrapped()) {
|
||||
composition.setContextHelpText(contextHelpText);
|
||||
} else {
|
||||
this.targetContextHelpText = contextHelpText;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isContextHelpTextHtmlEnabled() {
|
||||
if (component instanceof Field) {
|
||||
return ((Field) component).isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
if (composition != null && isWrapped()) {
|
||||
return composition.isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
return BooleanUtils.isTrue(targetContextHelpTextHtmlEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(Boolean enabled) {
|
||||
if (component instanceof Field) {
|
||||
checkNotNullArgument(enabled, "Unable to reset contextHelpTextHtmlEnabled " +
|
||||
"flag for the bound FieldConfig");
|
||||
((Field) component).setContextHelpTextHtmlEnabled(enabled);
|
||||
} else if (composition != null && isWrapped()) {
|
||||
checkNotNullArgument(enabled, "Unable to reset contextHelpTextHtmlEnabled " +
|
||||
"flag for the bound FieldConfig");
|
||||
composition.setContextHelpTextHtmlEnabled(enabled);
|
||||
} else {
|
||||
this.targetContextHelpTextHtmlEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Formatter getFormatter() {
|
||||
if (component instanceof HasFormatter) {
|
||||
@ -1356,6 +1413,22 @@ public class WebFieldGroup extends WebAbstractComponent<CubaFieldGroupLayout>
|
||||
this.targetRequiredMessage = targetRequiredMessage;
|
||||
}
|
||||
|
||||
public String getTargetContextHelpText() {
|
||||
return targetContextHelpText;
|
||||
}
|
||||
|
||||
public void setTargetContextHelpText(String targetContextHelpText) {
|
||||
this.targetContextHelpText = targetContextHelpText;
|
||||
}
|
||||
|
||||
public Boolean getTargetContextHelpTextHtmlEnabled() {
|
||||
return targetContextHelpTextHtmlEnabled;
|
||||
}
|
||||
|
||||
public void setTargetContextHelpTextHtmlEnabled(Boolean targetContextHelpTextHtmlEnabled) {
|
||||
this.targetContextHelpTextHtmlEnabled = targetContextHelpTextHtmlEnabled;
|
||||
}
|
||||
|
||||
public CollectionDatasource getTargetOptionsDatasource() {
|
||||
return targetOptionsDatasource;
|
||||
}
|
||||
|
@ -203,6 +203,26 @@ public class WebLookupPickerField extends WebLookupField implements LookupPicker
|
||||
return pickerField.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
return pickerField.getContextHelpText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
pickerField.setContextHelpText(contextHelpText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextHelpTextHtmlEnabled() {
|
||||
return pickerField.isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
pickerField.setContextHelpTextHtmlEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Action getAction(String id) {
|
||||
|
@ -119,6 +119,26 @@ public class WebResizableTextArea extends WebAbstractTextArea<CubaTextArea> impl
|
||||
wrapper.setDescription(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
return wrapper.getContextHelpText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
wrapper.setContextHelpText(contextHelpText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextHelpTextHtmlEnabled() {
|
||||
return wrapper.isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
wrapper.setContextHelpTextHtmlEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return wrapper.isRequired();
|
||||
|
@ -188,6 +188,26 @@ public class WebSearchPickerField extends WebSearchField implements SearchPicker
|
||||
return pickerField.getCaption();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
return pickerField.getContextHelpText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
pickerField.setContextHelpText(contextHelpText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextHelpTextHtmlEnabled() {
|
||||
return pickerField.isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
pickerField.setContextHelpTextHtmlEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Action getAction(String id) {
|
||||
|
@ -67,6 +67,26 @@ public class WebSuggestionPickerField extends WebSuggestionField implements Sugg
|
||||
return pickerField.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextHelpText() {
|
||||
return pickerField.getContextHelpText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpText(String contextHelpText) {
|
||||
pickerField.setContextHelpText(contextHelpText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextHelpTextHtmlEnabled() {
|
||||
return pickerField.isContextHelpTextHtmlEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextHelpTextHtmlEnabled(boolean enabled) {
|
||||
pickerField.setContextHelpTextHtmlEnabled(enabled);
|
||||
}
|
||||
|
||||
protected void initValueSync(WebPickerField.Picker picker) {
|
||||
component.addValueChangeListener(e -> {
|
||||
if (updateComponentValue)
|
||||
|
@ -24,6 +24,34 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.c-context-help-button {
|
||||
display: inline-block;
|
||||
font-size: 0;
|
||||
width: $v-font-size;
|
||||
}
|
||||
|
||||
.c-context-help-button::before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f059";
|
||||
font-size: $v-font-size;
|
||||
padding-left: .2em;
|
||||
}
|
||||
|
||||
.v-required-field-indicator {
|
||||
padding: 0 0 0 .2em;
|
||||
}
|
||||
|
||||
.v-tooltip {
|
||||
.c-tooltip-context-help {
|
||||
margin-top: $v-tooltip-padding-vertical * 2;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.v-errormessage[aria-hidden="true"]+.v-tooltip-text[aria-hidden="true"]+.c-tooltip-context-help {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@if $v-show-required-indicators == false {
|
||||
.v-required-field-indicator {
|
||||
display: none;
|
||||
|
@ -29,6 +29,20 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.c-context-help-button {
|
||||
display: inline-block;
|
||||
|
||||
color: transparent;
|
||||
background: transparent no-repeat top right;
|
||||
background-image: url(sprites/question.png); /** sprite-ref: components; */
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.c-context-help-button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.#{$primary-stylename}text {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
@ -60,5 +60,13 @@
|
||||
font-weight: bold;
|
||||
margin: 1px 0 4px 0;
|
||||
}
|
||||
|
||||
.c-tooltip-context-help {
|
||||
padding: 2px 4px;
|
||||
border: none;
|
||||
border-top: 1px solid #fffef5;
|
||||
border-bottom: 1px solid #fbf8d9;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user