001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui.input.form; 029 030import org.opencms.gwt.client.ui.I_CmsButton; 031import org.opencms.gwt.client.ui.I_CmsTruncable; 032import org.opencms.gwt.client.ui.css.I_CmsInputCss; 033import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 034import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 035import org.opencms.gwt.client.ui.input.form.CmsFieldTooltip.Data; 036import org.opencms.util.CmsStringUtil; 037 038import java.util.Arrays; 039import java.util.List; 040 041import com.google.common.base.Supplier; 042import com.google.common.base.Suppliers; 043import com.google.gwt.core.client.GWT; 044import com.google.gwt.dom.client.Style.Unit; 045import com.google.gwt.event.dom.client.ClickEvent; 046import com.google.gwt.event.dom.client.ClickHandler; 047import com.google.gwt.event.dom.client.MouseOutEvent; 048import com.google.gwt.event.dom.client.MouseOutHandler; 049import com.google.gwt.event.dom.client.MouseOverEvent; 050import com.google.gwt.event.dom.client.MouseOverHandler; 051import com.google.gwt.uibinder.client.UiBinder; 052import com.google.gwt.uibinder.client.UiField; 053import com.google.gwt.user.client.ui.Composite; 054import com.google.gwt.user.client.ui.Label; 055import com.google.gwt.user.client.ui.Panel; 056import com.google.gwt.user.client.ui.Widget; 057 058/** 059 * A row in a properties form.<p> 060 * 061 * This widget contains both a label and a panel into which an input widget for the form field can be placed. 062 * These widgets are next to each other horizontally. 063 * 064 * @since 8.0.0 065 */ 066public class CmsFormRow extends Composite implements I_CmsTruncable { 067 068 /** The ui binder interface for this widget. */ 069 protected interface I_CmsFormRowUiBinder extends UiBinder<Widget, CmsFormRow> { 070 // uibinder 071 } 072 073 /** The width of the label. */ 074 public static final int LABEL_WIDTH = 160; 075 076 /** The width of the opener. */ 077 public static final int OPENER_WIDTH = 16; 078 079 /** The default widget container width. */ 080 public static final int WIDGET_CONTAINER_WIDTH = 370; 081 082 /** The required right margin. */ 083 public static final int WIDGET_MARGIN_RIGHT = 15; 084 085 /** The CSS bundle used for this widget. */ 086 protected static I_CmsInputCss CSS = I_CmsInputLayoutBundle.INSTANCE.inputCss(); 087 088 /** The ui binder instance for this form row. */ 089 private static I_CmsFormRowUiBinder uiBinder = GWT.create(I_CmsFormRowUiBinder.class); 090 091 /** List of style names for the help icon. */ 092 public static List<String> ICON_STYLES = Arrays.asList( 093 I_CmsButton.ICON_FONT, 094 I_CmsButton.ICON_CIRCLE_HELP, 095 I_CmsLayoutBundle.INSTANCE.buttonCss().cmsFontIconButton(), 096 I_CmsLayoutBundle.INSTANCE.buttonCss().hoverBlack(), 097 I_CmsLayoutBundle.INSTANCE.buttonCss().helpIcon()); 098 099 /** The label used for displaying the information icon. */ 100 @UiField 101 protected Panel m_icon; 102 103 /** The label for the form row. */ 104 @UiField 105 protected Label m_label; 106 107 /** The widget container for the form row. */ 108 @UiField 109 protected Panel m_widgetContainer; 110 111 /** 112 * The default constructor. 113 */ 114 public CmsFormRow() { 115 116 Widget main = uiBinder.createAndBindUi(this); 117 initWidget(main); 118 main.addStyleName(I_CmsInputLayoutBundle.INSTANCE.inputCss().highTextBoxes()); 119 } 120 121 /** 122 * Returns the width of the label as a string.<p> 123 * 124 * @return the width of the label as a string 125 */ 126 public static String getLabelWidth() { 127 128 return LABEL_WIDTH + "px"; 129 } 130 131 /** 132 * Returns the width of the opener as a string.<p> 133 * 134 * @return the width of the opener as a string 135 */ 136 public static String getOpenerWidth() { 137 138 return OPENER_WIDTH + "px"; 139 } 140 141 /** 142 * Returns the left margin of the widget container as a string.<p> 143 * 144 * @return the left margin of the widget container as a string 145 */ 146 public static String getWidgetContainerLeftMargin() { 147 148 return OPENER_WIDTH + LABEL_WIDTH + "px"; 149 } 150 151 /** 152 * Returns the left margin of the widget container as a string.<p> 153 * 154 * @return the left margin of the widget container as a string 155 */ 156 public static String getWidgetContainerWidth() { 157 158 return WIDGET_CONTAINER_WIDTH + "px"; 159 } 160 161 /** 162 * Installs the DOM event handlers for displaying tooltips on a help icon.<p> 163 * 164 * The supplier passed in should not create a new tooltip data instance each time, 165 * but cache the different possible tooltip data instances. 166 * 167 * @param icon the help icon 168 * @param dataSupplier provides the tooltip data at the time the DOM events occur 169 */ 170 public static void installTooltipEventHandlers(final Panel icon, final Supplier<Data> dataSupplier) { 171 172 icon.addDomHandler(new MouseOverHandler() { 173 174 public void onMouseOver(MouseOverEvent event) { 175 176 CmsFieldTooltip.getHandler().buttonHover(dataSupplier.get()); 177 } 178 }, MouseOverEvent.getType()); 179 180 icon.addDomHandler(new MouseOutHandler() { 181 182 public void onMouseOut(MouseOutEvent event) { 183 184 CmsFieldTooltip.getHandler().buttonOut(dataSupplier.get()); 185 } 186 187 }, MouseOutEvent.getType()); 188 189 icon.addDomHandler(new ClickHandler() { 190 191 public void onClick(ClickEvent event) { 192 193 CmsFieldTooltip.getHandler().buttonClick(dataSupplier.get()); 194 195 } 196 }, ClickEvent.getType()); 197 } 198 199 /** 200 * Gets the icon.<p> 201 * 202 * @return the icon 203 */ 204 public Panel getIcon() { 205 206 return m_icon; 207 } 208 209 /** 210 * Returns the label for the form row.<p> 211 * 212 * @return the label for the form row 213 */ 214 public Label getLabel() { 215 216 return m_label; 217 } 218 219 /** 220 * Returns the widget container for the form row.<p> 221 * 222 * @return the widget container for the form row 223 */ 224 public Panel getWidgetContainer() { 225 226 return m_widgetContainer; 227 } 228 229 /** 230 * Initializes the style for the info button.<p> 231 */ 232 public void initInfoStyle() { 233 234 m_icon.addStyleName(I_CmsButton.ICON_FONT); 235 m_icon.addStyleName(I_CmsButton.ICON_CIRCLE_HELP); 236 m_icon.addStyleName(I_CmsLayoutBundle.INSTANCE.buttonCss().cmsFontIconButton()); 237 m_icon.addStyleName(I_CmsLayoutBundle.INSTANCE.buttonCss().hoverBlack()); 238 m_icon.addStyleName(I_CmsLayoutBundle.INSTANCE.buttonCss().helpIcon()); 239 } 240 241 /** 242 * Shows the info icon and sets the information text as its title.<p> 243 * 244 * @param info the info 245 * @param isHtml true if info should be interpreted as HTML rather than plain text 246 */ 247 public void setInfo(final String info, final boolean isHtml) { 248 249 if (info != null) { 250 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(info)) { 251 initInfoStyle(); 252 final Data tooltipData = new CmsFieldTooltip.Data(m_icon, info, isHtml); 253 final Panel icon = m_icon; 254 final Supplier<Data> dataSupplier = Suppliers.ofInstance(tooltipData); 255 installTooltipEventHandlers(icon, dataSupplier); 256 } 257 } 258 } 259 260 /** 261 * @see org.opencms.gwt.client.ui.I_CmsTruncable#truncate(java.lang.String, int) 262 */ 263 public void truncate(String textMetricsKey, int clientWidth) { 264 265 if (clientWidth > (WIDGET_CONTAINER_WIDTH + OPENER_WIDTH + LABEL_WIDTH + WIDGET_MARGIN_RIGHT)) { 266 int availableWidth = clientWidth - OPENER_WIDTH - WIDGET_MARGIN_RIGHT; 267 int widgetContainerWidth = (int)Math.round( 268 1.00 * availableWidth * ((1.00 + WIDGET_CONTAINER_WIDTH) / (WIDGET_CONTAINER_WIDTH + LABEL_WIDTH))); 269 int labelWidth = availableWidth - widgetContainerWidth; 270 m_label.setWidth(labelWidth + "px"); 271 m_widgetContainer.setWidth(widgetContainerWidth + "px"); 272 m_widgetContainer.getElement().getStyle().setMarginLeft(labelWidth + OPENER_WIDTH, Unit.PX); 273 for (Widget widget : m_widgetContainer) { 274 if (widget instanceof I_CmsTruncable) { 275 ((I_CmsTruncable)widget).truncate(textMetricsKey, widgetContainerWidth); 276 } 277 } 278 } 279 } 280 281}