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.util; 029 030import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 031 032import com.google.gwt.dom.client.Element; 033import com.google.gwt.dom.client.Style.Unit; 034import com.google.gwt.event.dom.client.HasAllMouseHandlers; 035import com.google.gwt.event.dom.client.MouseMoveEvent; 036import com.google.gwt.event.dom.client.MouseMoveHandler; 037import com.google.gwt.event.dom.client.MouseOutEvent; 038import com.google.gwt.event.dom.client.MouseOutHandler; 039import com.google.gwt.event.dom.client.MouseOverEvent; 040import com.google.gwt.event.dom.client.MouseOverHandler; 041import com.google.gwt.event.shared.HandlerRegistration; 042import com.google.gwt.user.client.DOM; 043import com.google.gwt.user.client.Timer; 044import com.google.gwt.user.client.Window; 045import com.google.gwt.user.client.ui.RootPanel; 046 047/** 048 * A tool-tip handler. Allowing to show any HTML as a tool-tip on mouse over.<p> 049 * 050 * @since 8.0.0 051 */ 052public class CmsToolTipHandler implements MouseOverHandler, MouseMoveHandler, MouseOutHandler { 053 054 /** The default tool-tip left offset. */ 055 private static final int DEFAULT_OFFSET_LEFT = 10; 056 057 /** The default tool-tip top offset. */ 058 private static final int DEFAULT_OFFSET_TOP = 10; 059 060 /** Time to wait before removing the tool tip. */ 061 private static final int REMOVE_SCHEDULE = 10000; 062 063 /** The mouse move handler registration. */ 064 private HandlerRegistration m_moveHandlerRegistration; 065 066 /** The tool-tip left offset. */ 067 private int m_offsetLeft; 068 069 /** The tool-tip top offset. */ 070 private int m_offsetTop; 071 072 /** The mouse out handler registration. */ 073 private HandlerRegistration m_outHandlerRegistration; 074 075 /** The mouse over handler registration. */ 076 private HandlerRegistration m_overHandlerRegistration; 077 078 /** Timer to remove the tool tip again. */ 079 private Timer m_removeTimer; 080 081 /** Flag indicating if the tool-tip is currently showing. */ 082 private boolean m_showing; 083 084 /** The widget to show the tool-tip for. */ 085 private HasAllMouseHandlers m_target; 086 087 /** The tool-tip element. */ 088 private Element m_toolTip; 089 090 /** The tool-tip HTML to show. */ 091 private String m_toolTipHtml; 092 093 /** 094 * Constructor. Adds the tool-tip handler to the target.<p> 095 * 096 * @param target the target to show the tool-tip on 097 * @param toolTipHtml the tool-tip content 098 */ 099 public CmsToolTipHandler(HasAllMouseHandlers target, String toolTipHtml) { 100 101 m_target = target; 102 m_toolTipHtml = toolTipHtml; 103 m_offsetLeft = DEFAULT_OFFSET_LEFT; 104 m_offsetTop = DEFAULT_OFFSET_TOP; 105 m_overHandlerRegistration = m_target.addMouseOverHandler(this); 106 } 107 108 /** 109 * Removes the tool-tip and mouse move and out handlers.<p> 110 */ 111 public void clearShowing() { 112 113 m_showing = false; 114 if (m_toolTip != null) { 115 m_toolTip.removeFromParent(); 116 m_toolTip = null; 117 } 118 if (m_moveHandlerRegistration != null) { 119 m_moveHandlerRegistration.removeHandler(); 120 m_moveHandlerRegistration = null; 121 } 122 if (m_outHandlerRegistration != null) { 123 m_outHandlerRegistration.removeHandler(); 124 m_outHandlerRegistration = null; 125 } 126 m_removeTimer = null; 127 } 128 129 /** 130 * Returns the tool-tip HTML.<p> 131 * 132 * @return the tool-tip HTML 133 */ 134 public String getToolTipHtml() { 135 136 return m_toolTipHtml; 137 } 138 139 /** 140 * Returns if the tool-tip is showing.<p> 141 * 142 * @return <code>true</code> if the tool-tip is showing 143 */ 144 public boolean isShowing() { 145 146 return m_showing; 147 } 148 149 /** 150 * @see com.google.gwt.event.dom.client.MouseMoveHandler#onMouseMove(com.google.gwt.event.dom.client.MouseMoveEvent) 151 */ 152 public void onMouseMove(MouseMoveEvent event) { 153 154 m_removeTimer.schedule(REMOVE_SCHEDULE); 155 setToolTipPosition(event.getClientX(), event.getClientY()); 156 } 157 158 /** 159 * @see com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google.gwt.event.dom.client.MouseOutEvent) 160 */ 161 public void onMouseOut(MouseOutEvent event) { 162 163 if (m_removeTimer != null) { 164 m_removeTimer.cancel(); 165 } 166 clearShowing(); 167 } 168 169 /** 170 * @see com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google.gwt.event.dom.client.MouseOverEvent) 171 */ 172 public void onMouseOver(MouseOverEvent event) { 173 174 // make sure not to double assign any handlers 175 if (m_removeTimer != null) { 176 m_removeTimer.cancel(); 177 } 178 clearShowing(); 179 180 createTimer(); 181 m_removeTimer.schedule(REMOVE_SCHEDULE); 182 183 m_showing = true; 184 m_moveHandlerRegistration = m_target.addMouseMoveHandler(this); 185 m_outHandlerRegistration = m_target.addMouseOutHandler(this); 186 if (m_toolTip == null) { 187 m_toolTip = DOM.createDiv(); 188 m_toolTip.addClassName(I_CmsLayoutBundle.INSTANCE.generalCss().toolTip()); 189 m_toolTip.addClassName(I_CmsLayoutBundle.INSTANCE.generalCss().cornerAll()); 190 } 191 m_toolTip.setInnerHTML(m_toolTipHtml); 192 RootPanel.getBodyElement().appendChild(m_toolTip); 193 setToolTipPosition(event.getClientX(), event.getClientY()); 194 } 195 196 /** 197 * Removes this tool-tip handler completely. This instance will not be reusable.<p> 198 */ 199 public void removeHandler() { 200 201 clearShowing(); 202 if (m_overHandlerRegistration != null) { 203 m_overHandlerRegistration.removeHandler(); 204 m_overHandlerRegistration = null; 205 } 206 m_target = null; 207 } 208 209 /** 210 * Sets the tool-tip left offset.<p> 211 * 212 * @param offsetLeft the tool-tip left offset to set 213 */ 214 public void setOffsetLeft(int offsetLeft) { 215 216 m_offsetLeft = offsetLeft; 217 } 218 219 /** 220 * Sets the tool-tip top offset.<p> 221 * 222 * @param offsetTop the tool-tip top offset to set 223 */ 224 public void setOffsetTop(int offsetTop) { 225 226 m_offsetTop = offsetTop; 227 } 228 229 /** 230 * Sets the tool-tip HTML.<p> 231 * 232 * @param toolTipHtml the tool-tip HTML to set 233 */ 234 public void setToolTipHtml(String toolTipHtml) { 235 236 m_toolTipHtml = toolTipHtml; 237 if (m_showing) { 238 m_toolTip.setInnerHTML(toolTipHtml); 239 } 240 } 241 242 /** 243 * Creates the remove tool tip timer.<p> 244 */ 245 private void createTimer() { 246 247 m_removeTimer = new Timer() { 248 249 /** 250 * @see com.google.gwt.user.client.Timer#run() 251 */ 252 @Override 253 public void run() { 254 255 clearShowing(); 256 } 257 }; 258 } 259 260 /** 261 * Sets the tool-tip position.<p> 262 * 263 * @param clientLeft the mouse pointer left position relative to the client window 264 * @param clientTop the mouse pointer top position relative to the client window 265 */ 266 private void setToolTipPosition(int clientLeft, int clientTop) { 267 268 if (m_toolTip != null) { 269 int height = m_toolTip.getOffsetHeight(); 270 int width = m_toolTip.getOffsetWidth(); 271 int windowHeight = Window.getClientHeight(); 272 int windowWidth = Window.getClientWidth(); 273 int scrollLeft = Window.getScrollLeft(); 274 int scrollTop = Window.getScrollTop(); 275 int left = clientLeft + scrollLeft + m_offsetLeft; 276 if ((left + width) > (windowWidth + scrollLeft)) { 277 left = (windowWidth + scrollLeft) - m_offsetLeft - width; 278 } 279 m_toolTip.getStyle().setLeft(left, Unit.PX); 280 int top = clientTop + scrollTop + m_offsetTop; 281 if (((top + height) > (windowHeight + scrollTop)) && ((height + m_offsetTop) < clientTop)) { 282 top = (clientTop + scrollTop) - m_offsetTop - height; 283 } 284 m_toolTip.getStyle().setTop(top, Unit.PX); 285 } 286 } 287}