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; 029 030import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 031import org.opencms.gwt.client.util.CmsPositionBean; 032import org.opencms.gwt.client.util.CmsPositionBean.Area; 033 034import java.util.Iterator; 035 036import com.google.gwt.core.client.GWT; 037import com.google.gwt.dom.client.Element; 038import com.google.gwt.dom.client.NativeEvent; 039import com.google.gwt.dom.client.Style; 040import com.google.gwt.dom.client.Style.Cursor; 041import com.google.gwt.dom.client.Style.Unit; 042import com.google.gwt.event.dom.client.ClickEvent; 043import com.google.gwt.event.dom.client.ClickHandler; 044import com.google.gwt.event.dom.client.HasClickHandlers; 045import com.google.gwt.event.dom.client.HasMouseDownHandlers; 046import com.google.gwt.event.dom.client.HasMouseMoveHandlers; 047import com.google.gwt.event.dom.client.HasMouseUpHandlers; 048import com.google.gwt.event.dom.client.MouseDownEvent; 049import com.google.gwt.event.dom.client.MouseDownHandler; 050import com.google.gwt.event.dom.client.MouseMoveEvent; 051import com.google.gwt.event.dom.client.MouseMoveHandler; 052import com.google.gwt.event.dom.client.MouseUpEvent; 053import com.google.gwt.event.dom.client.MouseUpHandler; 054import com.google.gwt.event.logical.shared.HasValueChangeHandlers; 055import com.google.gwt.event.logical.shared.ValueChangeEvent; 056import com.google.gwt.event.logical.shared.ValueChangeHandler; 057import com.google.gwt.event.shared.HandlerRegistration; 058import com.google.gwt.uibinder.client.UiBinder; 059import com.google.gwt.uibinder.client.UiField; 060import com.google.gwt.user.client.DOM; 061import com.google.gwt.user.client.ui.Composite; 062import com.google.gwt.user.client.ui.FlowPanel; 063import com.google.gwt.user.client.ui.HTMLPanel; 064import com.google.gwt.user.client.ui.HasWidgets; 065import com.google.gwt.user.client.ui.IndexedPanel; 066import com.google.gwt.user.client.ui.Widget; 067 068/** 069 * Select area widget. Allows the user to select an area inside the widget.<p> 070 * 071 * @since 8.0.0 072 */ 073public class CmsAreaSelectPanel extends Composite 074implements HasWidgets, IndexedPanel, HasValueChangeHandlers<CmsPositionBean>, HasMouseDownHandlers, HasMouseUpHandlers, 075HasClickHandlers, HasMouseMoveHandlers, MouseDownHandler, MouseUpHandler, MouseMoveHandler { 076 077 /** The ui-binder interface. */ 078 protected interface I_CmsAreaSelectPanelUiBinder extends UiBinder<HTMLPanel, CmsAreaSelectPanel> { 079 // GWT interface, nothing to do 080 } 081 082 /** States of the slect area panel. */ 083 private enum State { 084 /** Dragging the selection. */ 085 DRAGGING, /** Nothing selected. */ 086 EMPTY, /** Resizing the height. */ 087 RESIZE_HEIGHT, /** Resizing the width. */ 088 RESIZE_WIDTH, /** Selected. */ 089 SELECTED, /** Selecting new selection. */ 090 SELECTING 091 } 092 093 /** The ui-binder for this widget. */ 094 private static I_CmsAreaSelectPanelUiBinder m_uiBinder = GWT.create(I_CmsAreaSelectPanelUiBinder.class); 095 096 /** The marker. */ 097 @UiField 098 protected Element m_marker; 099 100 /** Select overlay. */ 101 @UiField 102 protected Element m_overlayBottom; 103 104 /** Select overlay. */ 105 @UiField 106 protected Element m_overlayLeft; 107 108 /** Select overlay. */ 109 @UiField 110 protected Element m_overlayRight; 111 112 /** Select overlay. */ 113 @UiField 114 protected Element m_overlayTop; 115 116 /** The panel holding added widgets. */ 117 @UiField 118 protected FlowPanel m_panel; 119 120 /** The currently selected area. */ 121 private CmsPositionBean m_currentSelection; 122 123 /** Select area size. */ 124 private int m_elementHeight; 125 126 /** Select area size. */ 127 private int m_elementWidth; 128 129 /** Starting point of the selection. */ 130 private int m_firstX; 131 132 /** Starting point of the selection. */ 133 private int m_firstY; 134 135 /** Fixed selection ratio. */ 136 private double m_heightToWidth; 137 138 /** Fire all events flag. */ 139 private boolean m_isFireAll; 140 141 /** The main widget. */ 142 private HTMLPanel m_main; 143 144 /** Style of the selection marker. */ 145 private Style m_markerStyle; 146 147 /** Mouse over area. */ 148 private Area m_mouseOverArea; 149 150 /** Cursor offset while dragging a selection. */ 151 private int m_moveOffsetX; 152 153 /** Cursor offset while dragging a selection. */ 154 private int m_moveOffsetY; 155 156 /** Style of image overlay. */ 157 private Style m_overlayBottomStyle; 158 159 /** Style of image overlay. */ 160 private Style m_overlayLeftStyle; 161 162 /** Style of image overlay. */ 163 private Style m_overlayRightStyle; 164 165 /** Style of image overlay. */ 166 private Style m_overlayTopStyle; 167 168 /** Select area state. */ 169 private State m_state; 170 171 /** 172 * Constructor.<p> 173 */ 174 public CmsAreaSelectPanel() { 175 176 m_main = m_uiBinder.createAndBindUi(this); 177 initWidget(m_main); 178 m_state = State.EMPTY; 179 m_heightToWidth = 0; 180 setHandlers(); 181 182 m_markerStyle = m_marker.getStyle(); 183 m_overlayLeftStyle = m_overlayLeft.getStyle(); 184 m_overlayBottomStyle = m_overlayBottom.getStyle(); 185 m_overlayRightStyle = m_overlayRight.getStyle(); 186 m_overlayTopStyle = m_overlayTop.getStyle(); 187 188 } 189 190 /** 191 * @see com.google.gwt.user.client.ui.HasWidgets#add(com.google.gwt.user.client.ui.Widget) 192 */ 193 public void add(Widget w) { 194 195 m_panel.add(w); 196 } 197 198 /** 199 * @see com.google.gwt.event.dom.client.HasClickHandlers#addClickHandler(com.google.gwt.event.dom.client.ClickHandler) 200 */ 201 public HandlerRegistration addClickHandler(ClickHandler handler) { 202 203 return addDomHandler(handler, ClickEvent.getType()); 204 } 205 206 /** 207 * @see com.google.gwt.event.dom.client.HasMouseDownHandlers#addMouseDownHandler(com.google.gwt.event.dom.client.MouseDownHandler) 208 */ 209 public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) { 210 211 return addDomHandler(handler, MouseDownEvent.getType()); 212 } 213 214 /** 215 * @see com.google.gwt.event.dom.client.HasMouseMoveHandlers#addMouseMoveHandler(com.google.gwt.event.dom.client.MouseMoveHandler) 216 */ 217 public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) { 218 219 return addDomHandler(handler, MouseMoveEvent.getType()); 220 } 221 222 /** 223 * @see com.google.gwt.event.dom.client.HasMouseUpHandlers#addMouseUpHandler(com.google.gwt.event.dom.client.MouseUpHandler) 224 */ 225 public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) { 226 227 return addDomHandler(handler, MouseUpEvent.getType()); 228 } 229 230 /** 231 * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) 232 */ 233 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<CmsPositionBean> handler) { 234 235 return addHandler(handler, ValueChangeEvent.getType()); 236 } 237 238 /** 239 * @see com.google.gwt.user.client.ui.HasWidgets#clear() 240 */ 241 public void clear() { 242 243 m_panel.clear(); 244 } 245 246 /** 247 * Removes the current selection.<p> 248 */ 249 public void clearSelection() { 250 251 m_state = State.EMPTY; 252 showSelect(false); 253 m_currentSelection = null; 254 } 255 256 /** 257 * Returns the position of the selected area, or <code>null</code> if nothing is selected.<p> 258 * 259 * @param relative if <code>true</code> the relative position is returned, otherwise the absolute position 260 * 261 * @return the position of the selected area 262 */ 263 public CmsPositionBean getAreaPosition(boolean relative) { 264 265 // returning the relative position 266 if (relative) { 267 return new CmsPositionBean(m_currentSelection); 268 } 269 270 // returning the absolute position 271 CmsPositionBean abs = new CmsPositionBean(m_currentSelection); 272 abs.setTop(m_currentSelection.getTop() + getElement().getAbsoluteTop()); 273 abs.setLeft(m_currentSelection.getLeft() + getElement().getAbsoluteLeft()); 274 return abs; 275 } 276 277 /** 278 * @see com.google.gwt.user.client.ui.IndexedPanel#getWidget(int) 279 */ 280 public Widget getWidget(int index) { 281 282 return m_panel.getWidget(index); 283 } 284 285 /** 286 * @see com.google.gwt.user.client.ui.IndexedPanel#getWidgetCount() 287 */ 288 public int getWidgetCount() { 289 290 return m_panel.getWidgetCount(); 291 } 292 293 /** 294 * @see com.google.gwt.user.client.ui.IndexedPanel#getWidgetIndex(com.google.gwt.user.client.ui.Widget) 295 */ 296 public int getWidgetIndex(Widget child) { 297 298 return m_panel.getWidgetIndex(child); 299 } 300 301 /** 302 * Returns if the value change event will always be fired, or only when a select/resize/move operation is finished.<p> 303 * 304 * @return <code>true</code> if the value change event will always be fired 305 */ 306 public boolean isFireAll() { 307 308 return m_isFireAll; 309 } 310 311 /** 312 * @see com.google.gwt.user.client.ui.HasWidgets#iterator() 313 */ 314 public Iterator<Widget> iterator() { 315 316 return m_panel.iterator(); 317 } 318 319 /** 320 * @see com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google.gwt.event.dom.client.MouseDownEvent) 321 */ 322 public void onMouseDown(MouseDownEvent event) { 323 324 if (event.getNativeButton() != NativeEvent.BUTTON_LEFT) { 325 // only act on left button down, ignore right click 326 return; 327 } 328 cacheElementSize(); 329 switch (m_state) { 330 case EMPTY: 331 DOM.setCapture(getElement()); 332 m_state = State.SELECTING; 333 m_firstX = event.getRelativeX(getElement()); 334 m_firstY = event.getRelativeY(getElement()); 335 m_currentSelection = new CmsPositionBean(); 336 setSelectPosition(m_firstX, m_firstY, 0, 0); 337 showSelect(true); 338 339 break; 340 case SELECTED: 341 342 m_firstX = event.getRelativeX(getElement()); 343 m_firstY = event.getRelativeY(getElement()); 344 if (m_mouseOverArea == null) { 345 // mouse not over selection, remove selection 346 clearSelection(); 347 fireChangeEvent(true); 348 break; 349 } 350 switch (m_mouseOverArea) { 351 case BORDER_TOP: 352 m_state = State.RESIZE_HEIGHT; 353 354 // fixing opposite border 355 m_firstX = m_currentSelection.getLeft(); 356 m_firstY = m_currentSelection.getTop() + m_currentSelection.getHeight(); 357 break; 358 case BORDER_BOTTOM: 359 m_state = State.RESIZE_HEIGHT; 360 361 // fixing opposite border 362 m_firstX = m_currentSelection.getLeft(); 363 m_firstY = m_currentSelection.getTop(); 364 break; 365 case BORDER_LEFT: 366 m_state = State.RESIZE_WIDTH; 367 368 // fixing opposite border 369 m_firstX = m_currentSelection.getLeft() + m_currentSelection.getWidth(); 370 m_firstY = m_currentSelection.getTop(); 371 break; 372 case BORDER_RIGHT: 373 m_state = State.RESIZE_WIDTH; 374 375 // fixing opposite border 376 m_firstX = m_currentSelection.getLeft(); 377 m_firstY = m_currentSelection.getTop(); 378 break; 379 case CENTER: 380 m_state = State.DRAGGING; 381 m_moveOffsetX = m_firstX - m_currentSelection.getLeft(); 382 m_moveOffsetY = m_firstY - m_currentSelection.getTop(); 383 break; 384 case CORNER_BOTTOM_LEFT: 385 m_state = State.SELECTING; 386 387 // fixing opposite corner 388 m_firstX = m_currentSelection.getLeft() + m_currentSelection.getWidth(); 389 m_firstY = m_currentSelection.getTop(); 390 break; 391 case CORNER_BOTTOM_RIGHT: 392 m_state = State.SELECTING; 393 // fixing opposite corner 394 m_firstX = m_currentSelection.getLeft(); 395 m_firstY = m_currentSelection.getTop(); 396 break; 397 case CORNER_TOP_LEFT: 398 m_state = State.SELECTING; 399 400 // fixing opposite corner 401 m_firstX = m_currentSelection.getLeft() + m_currentSelection.getWidth(); 402 m_firstY = m_currentSelection.getTop() + m_currentSelection.getHeight(); 403 break; 404 case CORNER_TOP_RIGHT: 405 m_state = State.SELECTING; 406 407 // fixing opposite corner 408 m_firstX = m_currentSelection.getLeft(); 409 m_firstY = m_currentSelection.getTop() + m_currentSelection.getHeight(); 410 break; 411 default: 412 } 413 DOM.setCapture(getElement()); 414 415 break; 416 case DRAGGING: 417 case RESIZE_HEIGHT: 418 case RESIZE_WIDTH: 419 case SELECTING: 420 default: 421 // Messed up selection state. 422 // May happen if mouse-cursor was moved outside the window or frame while button pressed and button was released outside. 423 if (m_currentSelection != null) { 424 m_state = State.SELECTED; 425 fireChangeEvent(true); 426 } else { 427 // this should never happen 428 clearSelection(); 429 } 430 } 431 432 event.preventDefault(); 433 event.stopPropagation(); 434 } 435 436 /** 437 * @see com.google.gwt.event.dom.client.MouseMoveHandler#onMouseMove(com.google.gwt.event.dom.client.MouseMoveEvent) 438 */ 439 public void onMouseMove(MouseMoveEvent event) { 440 441 int secondX = event.getRelativeX(getElement()); 442 int secondY = event.getRelativeY(getElement()); 443 cacheElementSize(); 444 // restricting cursor input to the area of the select panel 445 secondX = (secondX < 0) ? 0 : ((secondX > m_elementWidth) ? m_elementWidth : secondX); 446 secondY = (secondY < 0) ? 0 : ((secondY > m_elementHeight) ? m_elementHeight : secondY); 447 448 switch (m_state) { 449 case SELECTING: 450 if (m_heightToWidth > 0) { 451 // fixed height to width ratio 452 // calculate the appropriate dimensions 453 int tempX = getXForY(secondX, secondY); 454 if (((tempX > secondX) && (secondX > m_firstX)) || ((tempX < secondX) && (secondX < m_firstX))) { 455 secondY = getYForX(secondX, secondY); 456 } else { 457 secondX = tempX; 458 } 459 } 460 positionX(secondX); 461 positionY(secondY); 462 fireChangeEvent(false); 463 break; 464 case DRAGGING: 465 moveTo(secondX - m_moveOffsetX, secondY - m_moveOffsetY); 466 fireChangeEvent(false); 467 break; 468 case RESIZE_HEIGHT: 469 if (m_heightToWidth > 0) { 470 // fixed ratio, need the recalculate width to 471 int tempX = getXForY(secondX, secondY); 472 if ((tempX < 0) || (tempX > m_elementWidth)) { 473 tempX = secondX; 474 secondY = getYForX(secondX, secondY); 475 } 476 positionX(tempX); 477 } 478 positionY(secondY); 479 fireChangeEvent(false); 480 break; 481 case RESIZE_WIDTH: 482 if (m_heightToWidth > 0) { 483 // fixed ratio, need the recalculate height to 484 int tempY = getYForX(secondX, secondY); 485 if ((tempY < 0) || (tempY > m_elementWidth)) { 486 tempY = secondY; 487 secondX = getXForY(secondX, secondY); 488 } 489 positionY(getYForX(secondX, secondY)); 490 } 491 positionX(secondX); 492 fireChangeEvent(false); 493 break; 494 case SELECTED: 495 // read over which area of the selection the cursor is positioned 496 m_mouseOverArea = m_currentSelection.getArea(secondX, secondY, 30); 497 498 // show the appropriate cursor 499 if (m_mouseOverArea == null) { 500 m_markerStyle.setCursor(Cursor.DEFAULT); 501 break; 502 } 503 switch (m_mouseOverArea) { 504 case BORDER_LEFT: 505 case BORDER_RIGHT: 506 m_markerStyle.setCursor(Cursor.E_RESIZE); 507 break; 508 case BORDER_TOP: 509 case BORDER_BOTTOM: 510 m_markerStyle.setCursor(Cursor.N_RESIZE); 511 break; 512 case CENTER: 513 m_markerStyle.setCursor(Cursor.MOVE); 514 break; 515 case CORNER_BOTTOM_RIGHT: 516 case CORNER_TOP_LEFT: 517 m_markerStyle.setCursor(Cursor.NW_RESIZE); 518 break; 519 case CORNER_TOP_RIGHT: 520 case CORNER_BOTTOM_LEFT: 521 m_markerStyle.setCursor(Cursor.NE_RESIZE); 522 break; 523 default: 524 } 525 break; 526 case EMPTY: 527 default: 528 } 529 530 } 531 532 /** 533 * @see com.google.gwt.event.dom.client.MouseUpHandler#onMouseUp(com.google.gwt.event.dom.client.MouseUpEvent) 534 */ 535 public void onMouseUp(MouseUpEvent event) { 536 537 switch (m_state) { 538 case SELECTING: 539 case DRAGGING: 540 case RESIZE_HEIGHT: 541 case RESIZE_WIDTH: 542 m_state = State.SELECTED; 543 m_mouseOverArea = null; 544 fireChangeEvent(true); 545 DOM.releaseCapture(getElement()); 546 event.preventDefault(); 547 event.stopPropagation(); 548 break; 549 case SELECTED: 550 case EMPTY: 551 default: 552 } 553 } 554 555 /** 556 * @see com.google.gwt.user.client.ui.IndexedPanel#remove(int) 557 */ 558 public boolean remove(int index) { 559 560 return m_panel.remove(index); 561 } 562 563 /** 564 * @see com.google.gwt.user.client.ui.HasWidgets#remove(com.google.gwt.user.client.ui.Widget) 565 */ 566 public boolean remove(Widget w) { 567 568 return m_panel.remove(w); 569 } 570 571 /** 572 * Resets the select area ratio.<p> 573 */ 574 public void resetRatio() { 575 576 m_heightToWidth = 0; 577 } 578 579 /** 580 * Sets the selection area.<p> 581 * 582 * @param relative <code>true</code> if provided position is relative to the select area, not absolute to the page 583 * @param pos the area position to select 584 */ 585 public void setAreaPosition(boolean relative, CmsPositionBean pos) { 586 587 if (pos == null) { 588 return; 589 } 590 m_state = State.SELECTED; 591 showSelect(true); 592 m_currentSelection = new CmsPositionBean(); 593 m_firstX = pos.getLeft(); 594 m_firstY = pos.getTop(); 595 if (!relative) { 596 m_firstX -= getElement().getAbsoluteLeft(); 597 m_firstY -= getElement().getAbsoluteTop(); 598 } 599 // setSelectPosition(m_firstX, m_firstY, 0, 0); 600 setSelectPosition(m_firstX, m_firstY, pos.getHeight(), pos.getWidth()); 601 } 602 603 /** 604 * Sets if the value change event will always be fired, or only when a select/resize/move operation is finished.<p> 605 * 606 * @param isFireAll <code>true</code> to always be fire the value change event 607 */ 608 public void setFireAll(boolean isFireAll) { 609 610 m_isFireAll = isFireAll; 611 } 612 613 /** 614 * Sets a fixed selection ratio. Set <code>0</code> to remove the fix.<p> 615 * 616 * @param heightToWidth the height to width ratio 617 */ 618 public void setRatio(double heightToWidth) { 619 620 m_heightToWidth = heightToWidth; 621 } 622 623 /** 624 * Caches the select area element size.<p> 625 */ 626 private void cacheElementSize() { 627 628 // cache element size if necessary 629 if ((m_elementHeight == 0) && (m_elementWidth == 0)) { 630 m_elementHeight = getElement().getOffsetHeight(); 631 m_elementWidth = getElement().getOffsetWidth(); 632 } 633 } 634 635 /** 636 * Fires the value change event.<p> 637 * 638 * @param alwaysFire <code>true</code> to always fire the change event, ignoring the fire all flag 639 */ 640 private void fireChangeEvent(boolean alwaysFire) { 641 642 if (alwaysFire || m_isFireAll) { 643 ValueChangeEvent.fire(this, m_currentSelection); 644 } 645 } 646 647 /** 648 * Calculates the matching X (left/width) value in case of a fixed height/width ratio.<p> 649 * 650 * @param newX the cursor X offset to the selection area 651 * @param newY the cursor Y offset to the selection area 652 * 653 * @return the matching X value 654 */ 655 private int getXForY(int newX, int newY) { 656 657 int width = (int)Math.floor((newY - m_firstY) / m_heightToWidth); 658 int result = m_firstX + width; 659 if (((m_firstX - newX) * (m_firstX - result)) < 0) { 660 result = m_firstX - width; 661 } 662 return result; 663 } 664 665 /** 666 * Calculates the matching Y (top/height) value in case of a fixed height/width ratio.<p> 667 * 668 * @param newX the cursor X offset to the selection area 669 * @param newY the cursor Y offset to the selection area 670 * 671 * @return the matching Y value 672 */ 673 private int getYForX(int newX, int newY) { 674 675 int height = (int)Math.floor((newX - m_firstX) * m_heightToWidth); 676 int result = m_firstY + height; 677 if (((m_firstY - newY) * (m_firstY - result)) < 0) { 678 result = m_firstY - height; 679 } 680 return result; 681 } 682 683 /** 684 * Moves the select area to the specified position, while keeping the size.<p> 685 * 686 * @param posX the new X position 687 * @param posY the new Y position 688 */ 689 private void moveTo(int posX, int posY) { 690 691 posX = (posX < 0) 692 ? 0 693 : (((posX + m_currentSelection.getWidth()) >= m_elementWidth) 694 ? m_elementWidth - m_currentSelection.getWidth() 695 : posX); 696 posY = (posY < 0) 697 ? 0 698 : (((posY + m_currentSelection.getHeight()) >= m_elementHeight) 699 ? m_elementHeight - m_currentSelection.getHeight() 700 : posY); 701 702 m_markerStyle.setTop(posY, Unit.PX); 703 m_markerStyle.setLeft(posX, Unit.PX); 704 705 m_overlayLeftStyle.setWidth(posX, Unit.PX); 706 707 m_overlayTopStyle.setLeft(posX, Unit.PX); 708 m_overlayTopStyle.setHeight(posY, Unit.PX); 709 710 m_overlayBottomStyle.setLeft(posX, Unit.PX); 711 m_overlayBottomStyle.setHeight(m_elementHeight - posY - m_currentSelection.getHeight(), Unit.PX); 712 713 m_overlayRightStyle.setWidth(m_elementWidth - posX - m_currentSelection.getWidth(), Unit.PX); 714 715 m_currentSelection.setTop(posY); 716 m_currentSelection.setLeft(posX); 717 } 718 719 /** 720 * Setting a new left/top value for the selection.<p> 721 * 722 * @param secondX the cursor X offset to the selection area 723 */ 724 private void positionX(int secondX) { 725 726 if (secondX < m_firstX) { 727 setSelectPositionX(secondX, m_firstX - secondX); 728 } else { 729 setSelectWidth(secondX - m_firstX); 730 } 731 } 732 733 /** 734 * Setting a new top/height value for the selection.<p> 735 * 736 * @param secondY the cursor Y offset to the selection area 737 */ 738 private void positionY(int secondY) { 739 740 if (secondY < m_firstY) { 741 setSelectPositionY(secondY, m_firstY - secondY); 742 } else { 743 setSelectHeight(secondY - m_firstY); 744 } 745 } 746 747 /** 748 * Sets self as mouse down, up and move handler.<p> 749 */ 750 private void setHandlers() { 751 752 addMouseDownHandler(this); 753 addMouseMoveHandler(this); 754 addMouseUpHandler(this); 755 } 756 757 /** 758 * Adjusts the select area height, while keeping the Y position of the top/left corner.<p> 759 * 760 * @param height the new height 761 */ 762 private void setSelectHeight(int height) { 763 764 m_markerStyle.setHeight(height, Unit.PX); 765 766 m_overlayBottomStyle.setHeight(m_elementHeight - m_currentSelection.getTop() - height, Unit.PX); 767 768 m_currentSelection.setHeight(height); 769 } 770 771 /** 772 * Sets position and size of the select area.<p> 773 * 774 * @param posX the new X position 775 * @param posY the new Y position 776 * @param height the new height 777 * @param width the new width 778 */ 779 private void setSelectPosition(int posX, int posY, int height, int width) { 780 781 setSelectPositionX(posX, width); 782 setSelectPositionY(posY, height); 783 } 784 785 /** 786 * Sets X position and width of the select area.<p> 787 * 788 * @param posX the new X position 789 * @param width the new width 790 */ 791 private void setSelectPositionX(int posX, int width) { 792 793 m_markerStyle.setLeft(posX, Unit.PX); 794 m_markerStyle.setWidth(width, Unit.PX); 795 796 m_overlayLeftStyle.setWidth(posX, Unit.PX); 797 m_overlayTopStyle.setLeft(posX, Unit.PX); 798 m_overlayTopStyle.setWidth(width, Unit.PX); 799 m_overlayBottomStyle.setLeft(posX, Unit.PX); 800 m_overlayBottomStyle.setWidth(width, Unit.PX); 801 m_overlayRightStyle.setWidth(m_elementWidth - posX - width, Unit.PX); 802 803 m_currentSelection.setLeft(posX); 804 m_currentSelection.setWidth(width); 805 } 806 807 /** 808 * Sets Y position and height of the select area.<p> 809 * 810 * @param posY the new Y position 811 * @param height the new height 812 */ 813 private void setSelectPositionY(int posY, int height) { 814 815 m_markerStyle.setTop(posY, Unit.PX); 816 m_markerStyle.setHeight(height, Unit.PX); 817 818 m_overlayTopStyle.setHeight(posY, Unit.PX); 819 m_overlayBottomStyle.setHeight(m_elementHeight - posY - height, Unit.PX); 820 821 m_currentSelection.setTop(posY); 822 m_currentSelection.setHeight(height); 823 } 824 825 /** 826 * Adjusts the select area width, while keeping the X position of the top/left corner.<p> 827 * 828 * @param width the new width 829 */ 830 private void setSelectWidth(int width) { 831 832 m_markerStyle.setWidth(width, Unit.PX); 833 834 m_overlayTopStyle.setWidth(width, Unit.PX); 835 m_overlayBottomStyle.setWidth(width, Unit.PX); 836 m_overlayRightStyle.setWidth(m_elementWidth - m_currentSelection.getLeft() - width, Unit.PX); 837 838 m_currentSelection.setWidth(width); 839 } 840 841 /** 842 * Shows or hides the select area.<p> 843 * 844 * @param show if <code>true</code> the select area will be shown 845 */ 846 private void showSelect(boolean show) { 847 848 if (show) { 849 m_main.addStyleName(I_CmsLayoutBundle.INSTANCE.selectAreaCss().showSelect()); 850 return; 851 } 852 m_main.removeStyleName(I_CmsLayoutBundle.INSTANCE.selectAreaCss().showSelect()); 853 } 854}