You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IWindow.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.itmill.toolkit.terminal.gwt.client.ui;
  5. import java.util.Iterator;
  6. import java.util.Vector;
  7. import com.google.gwt.user.client.Command;
  8. import com.google.gwt.user.client.DOM;
  9. import com.google.gwt.user.client.DeferredCommand;
  10. import com.google.gwt.user.client.Element;
  11. import com.google.gwt.user.client.Event;
  12. import com.google.gwt.user.client.Window;
  13. import com.google.gwt.user.client.ui.Frame;
  14. import com.google.gwt.user.client.ui.PopupPanel;
  15. import com.google.gwt.user.client.ui.RootPanel;
  16. import com.google.gwt.user.client.ui.ScrollListener;
  17. import com.google.gwt.user.client.ui.ScrollPanel;
  18. import com.google.gwt.user.client.ui.Widget;
  19. import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
  20. import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
  21. import com.itmill.toolkit.terminal.gwt.client.Paintable;
  22. import com.itmill.toolkit.terminal.gwt.client.UIDL;
  23. import com.itmill.toolkit.terminal.gwt.client.Util;
  24. /**
  25. * "Sub window" component.
  26. *
  27. * TODO update position / scrollposition / size to client
  28. *
  29. * @author IT Mill Ltd
  30. */
  31. public class IWindow extends PopupPanel implements Paintable, ScrollListener {
  32. private static final int MIN_HEIGHT = 60;
  33. private static final int MIN_WIDTH = 80;
  34. private static Vector windowOrder = new Vector();
  35. public static final String CLASSNAME = "i-window";
  36. /**
  37. * pixels used by inner borders and paddings horizontally (calculated on
  38. * attach)
  39. */
  40. private int borderWidthHorizontal = 0;
  41. private static final int STACKING_OFFSET_PIXELS = 15;
  42. private static final int Z_INDEX_BASE = 10000;
  43. private Paintable layout;
  44. private Element contents;
  45. private Element header;
  46. private Element footer;
  47. private Element resizeBox;
  48. private final ScrollPanel contentPanel = new ScrollPanel();
  49. private boolean dragging;
  50. private int startX;
  51. private int startY;
  52. private int origX;
  53. private int origY;
  54. private boolean resizing;
  55. private int origW;
  56. private int origH;
  57. private Element closeBox;
  58. protected ApplicationConnection client;
  59. private String id;
  60. ShortcutActionHandler shortcutHandler;
  61. /** Last known positionx read from UIDL or updated to application connection */
  62. private int uidlPositionX = -1;
  63. /** Last known positiony read from UIDL or updated to application connection */
  64. private int uidlPositionY = -1;
  65. private boolean modal = false;
  66. private boolean resizable = true;
  67. private Element modalityCurtain;
  68. private Element draggingCurtain;
  69. private Element headerText;
  70. public IWindow() {
  71. super();
  72. final int order = windowOrder.size();
  73. setWindowOrder(order);
  74. windowOrder.add(this);
  75. constructDOM();
  76. setPopupPosition(order * STACKING_OFFSET_PIXELS, order
  77. * STACKING_OFFSET_PIXELS);
  78. contentPanel.addScrollListener(this);
  79. }
  80. private void bringToFront() {
  81. int curIndex = windowOrder.indexOf(this);
  82. if (curIndex + 1 < windowOrder.size()) {
  83. windowOrder.remove(this);
  84. windowOrder.add(this);
  85. for (; curIndex < windowOrder.size(); curIndex++) {
  86. ((IWindow) windowOrder.get(curIndex)).setWindowOrder(curIndex);
  87. }
  88. }
  89. }
  90. /**
  91. * Returns true if window is the topmost window
  92. *
  93. * @return
  94. */
  95. private boolean isActive() {
  96. return windowOrder.lastElement().equals(this);
  97. }
  98. public void setWindowOrder(int order) {
  99. int zIndex = (order + Z_INDEX_BASE);
  100. if (modal) {
  101. zIndex += 1000;
  102. DOM.setStyleAttribute(modalityCurtain, "zIndex", "" + zIndex);
  103. }
  104. DOM.setStyleAttribute(getElement(), "zIndex", "" + zIndex);
  105. }
  106. protected void constructDOM() {
  107. setStyleName(CLASSNAME);
  108. header = DOM.createDiv();
  109. DOM.setElementProperty(header, "className", CLASSNAME + "-outerheader");
  110. headerText = DOM.createDiv();
  111. DOM.setElementProperty(headerText, "className", CLASSNAME + "-header");
  112. contents = DOM.createDiv();
  113. DOM.setElementProperty(contents, "className", CLASSNAME + "-contents");
  114. footer = DOM.createDiv();
  115. DOM.setElementProperty(footer, "className", CLASSNAME + "-footer");
  116. resizeBox = DOM.createDiv();
  117. DOM
  118. .setElementProperty(resizeBox, "className", CLASSNAME
  119. + "-resizebox");
  120. closeBox = DOM.createDiv();
  121. DOM.setElementProperty(closeBox, "className", CLASSNAME + "-closebox");
  122. DOM.appendChild(footer, resizeBox);
  123. DOM.sinkEvents(getElement(), Event.ONLOSECAPTURE);
  124. DOM.sinkEvents(closeBox, Event.ONCLICK);
  125. DOM.sinkEvents(contents, Event.ONCLICK);
  126. final Element wrapper = DOM.createDiv();
  127. DOM.setElementProperty(wrapper, "className", CLASSNAME + "-wrap");
  128. final Element wrapper2 = DOM.createDiv();
  129. DOM.setElementProperty(wrapper2, "className", CLASSNAME + "-wrap2");
  130. DOM.sinkEvents(wrapper, Event.ONKEYDOWN);
  131. DOM.appendChild(wrapper2, closeBox);
  132. DOM.appendChild(wrapper2, header);
  133. DOM.appendChild(header, headerText);
  134. DOM.appendChild(wrapper2, contents);
  135. DOM.appendChild(wrapper2, footer);
  136. DOM.appendChild(wrapper, wrapper2);
  137. DOM.appendChild(super.getContainerElement(), wrapper);
  138. sinkEvents(Event.MOUSEEVENTS);
  139. setWidget(contentPanel);
  140. }
  141. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  142. id = uidl.getId();
  143. this.client = client;
  144. // Workaround needed for Testing Tools (GWT generates window DOM
  145. // slightly different in different browsers).
  146. DOM.setElementProperty(closeBox, "id", id + "_window_close");
  147. if (uidl.hasAttribute("invisible")) {
  148. this.hide();
  149. return;
  150. }
  151. if (client.updateComponent(this, uidl, false)) {
  152. return;
  153. }
  154. if (uidl.getBooleanAttribute("modal") != modal) {
  155. setModal(!modal);
  156. }
  157. if (uidl.getBooleanAttribute("resizable") != resizable) {
  158. setResizable(!resizable);
  159. }
  160. // Initialize the position form UIDL
  161. try {
  162. final int positionx = uidl.getIntVariable("positionx");
  163. final int positiony = uidl.getIntVariable("positiony");
  164. if (positionx >= 0 && positiony >= 0) {
  165. setPopupPosition(positionx, positiony);
  166. }
  167. } catch (final IllegalArgumentException e) {
  168. // Silently ignored as positionx and positiony are not required
  169. // parameters
  170. }
  171. if (!isAttached()) {
  172. show();
  173. }
  174. // Initialize the size from UIDL
  175. /*
  176. * FIXME non-pixel size is set as "outer size", pixels are applied for
  177. * content area. This is due history as earlier only pixels where
  178. * allowed.
  179. */
  180. if (uidl.hasVariable("width")) {
  181. final String width = uidl.getStringVariable("width");
  182. if (width.indexOf("px") < 0) {
  183. /*
  184. * Only using non-pixel size for initial size measurement. Then
  185. * fix content area with pixels.
  186. */
  187. DOM.setStyleAttribute(getElement(), "width", width);
  188. int elementPropertyInt = DOM.getElementPropertyInt(
  189. getElement(), "offsetWidth");
  190. DOM.setStyleAttribute(getElement(), "width", "");
  191. elementPropertyInt -= (DOM.getElementPropertyInt(getElement(),
  192. "offsetWidth") - DOM.getElementPropertyInt(contents,
  193. "offsetWidth"));
  194. setWidth(elementPropertyInt + "px");
  195. } else {
  196. setWidth(width);
  197. }
  198. }
  199. // Height set after show so we can detect space used by decorations
  200. if (uidl.hasVariable("height")) {
  201. final String height = uidl.getStringVariable("height");
  202. if (height.indexOf("%") > 0) {
  203. int winHeight = Window.getClientHeight();
  204. float percent = Float.parseFloat(height.substring(0, height
  205. .indexOf("%"))) / 100.0f;
  206. int contentPixels = (int) (winHeight * percent);
  207. contentPixels -= (DOM.getElementPropertyInt(getElement(),
  208. "offsetHeight") - DOM.getElementPropertyInt(contents,
  209. "offsetHeight"));
  210. // FIXME hardcoded contents elements border size
  211. contentPixels -= 2;
  212. setHeight(contentPixels + "px");
  213. } else {
  214. setHeight(height);
  215. }
  216. }
  217. if (uidl.hasAttribute("caption")) {
  218. setCaption(uidl.getStringAttribute("caption"), uidl
  219. .getStringAttribute("icon"));
  220. }
  221. boolean showingUrl = false;
  222. int childIndex = 0;
  223. UIDL childUidl = uidl.getChildUIDL(childIndex++);
  224. while ("open".equals(childUidl.getTag())) {
  225. // TODO multiple opens with the same target will in practice just
  226. // open the last one - should we fix that somehow?
  227. final String parsedUri = client.translateToolkitUri(childUidl
  228. .getStringAttribute("src"));
  229. if (!childUidl.hasAttribute("name")) {
  230. final Frame frame = new Frame();
  231. DOM.setStyleAttribute(frame.getElement(), "width", "100%");
  232. DOM.setStyleAttribute(frame.getElement(), "height", "100%");
  233. DOM.setStyleAttribute(frame.getElement(), "border", "0px");
  234. frame.setUrl(parsedUri);
  235. contentPanel.setWidget(frame);
  236. showingUrl = true;
  237. } else {
  238. final String target = childUidl.getStringAttribute("name");
  239. Window.open(parsedUri, target, "");
  240. }
  241. childUidl = uidl.getChildUIDL(childIndex++);
  242. }
  243. final Paintable lo = client.getPaintable(childUidl);
  244. if (layout != null) {
  245. if (layout != lo) {
  246. // remove old
  247. client.unregisterPaintable(layout);
  248. contentPanel.remove((Widget) layout);
  249. // add new
  250. if (!showingUrl) {
  251. contentPanel.setWidget((Widget) lo);
  252. }
  253. layout = lo;
  254. }
  255. } else if (!showingUrl) {
  256. contentPanel.setWidget((Widget) lo);
  257. }
  258. lo.updateFromUIDL(childUidl, client);
  259. // we may have actions and notifications
  260. if (uidl.getChildCount() > 1) {
  261. final int cnt = uidl.getChildCount();
  262. for (int i = 1; i < cnt; i++) {
  263. childUidl = uidl.getChildUIDL(i);
  264. if (childUidl.getTag().equals("actions")) {
  265. if (shortcutHandler == null) {
  266. shortcutHandler = new ShortcutActionHandler(id, client);
  267. }
  268. shortcutHandler.updateActionMap(childUidl);
  269. } else if (childUidl.getTag().equals("notifications")) {
  270. // TODO needed? move ->
  271. for (final Iterator it = childUidl.getChildIterator(); it
  272. .hasNext();) {
  273. final UIDL notification = (UIDL) it.next();
  274. String html = "";
  275. if (notification.hasAttribute("icon")) {
  276. final String parsedUri = client
  277. .translateToolkitUri(notification
  278. .getStringAttribute("icon"));
  279. html += "<img src=\"" + parsedUri + "\" />";
  280. }
  281. if (notification.hasAttribute("caption")) {
  282. html += "<h1>"
  283. + notification
  284. .getStringAttribute("caption")
  285. + "</h1>";
  286. }
  287. if (notification.hasAttribute("message")) {
  288. html += "<p>"
  289. + notification
  290. .getStringAttribute("message")
  291. + "</p>";
  292. }
  293. final String style = notification.hasAttribute("style") ? notification
  294. .getStringAttribute("style")
  295. : null;
  296. final int position = notification
  297. .getIntAttribute("position");
  298. final int delay = notification.getIntAttribute("delay");
  299. new INotification(delay).show(html, position, style);
  300. }
  301. }
  302. }
  303. }
  304. // setting scrollposition must happen after children is rendered
  305. contentPanel.setScrollPosition(uidl.getIntVariable("scrollTop"));
  306. contentPanel.setHorizontalScrollPosition(uidl
  307. .getIntVariable("scrollLeft"));
  308. // Center this window on screen if requested
  309. // This has to be here because we might not know the content size before
  310. // everything is painted into the window
  311. if (uidl.getBooleanAttribute("center")) {
  312. center();
  313. }
  314. }
  315. public void show() {
  316. if (modal) {
  317. showModalityCurtain();
  318. }
  319. super.show();
  320. setFF2CaretFixEnabled(true);
  321. fixFF3OverflowBug();
  322. }
  323. /** Disable overflow auto with FF3 to fix #1837. */
  324. private void fixFF3OverflowBug() {
  325. if (BrowserInfo.get().isFF3()) {
  326. DeferredCommand.addCommand(new Command() {
  327. public void execute() {
  328. DOM.setStyleAttribute(getElement(), "overflow", "");
  329. }
  330. });
  331. }
  332. }
  333. /**
  334. * Fix "missing cursor" browser bug workaround for FF2 in Windows and Linux.
  335. *
  336. * Calling this method has no effect on other browsers than the ones based
  337. * on Gecko 1.8
  338. *
  339. * @param enable
  340. */
  341. private void setFF2CaretFixEnabled(boolean enable) {
  342. if (BrowserInfo.get().isFF2()) {
  343. if (enable) {
  344. DeferredCommand.addCommand(new Command() {
  345. public void execute() {
  346. DOM.setStyleAttribute(getElement(), "overflow", "auto");
  347. }
  348. });
  349. } else {
  350. DOM.setStyleAttribute(getElement(), "overflow", "");
  351. }
  352. }
  353. }
  354. public void hide() {
  355. if (modal) {
  356. hideModalityCurtain();
  357. }
  358. super.hide();
  359. }
  360. private void setModal(boolean modality) {
  361. modal = modality;
  362. if (modal) {
  363. modalityCurtain = DOM.createDiv();
  364. DOM.setElementProperty(modalityCurtain, "className", CLASSNAME
  365. + "-modalitycurtain");
  366. if (isAttached()) {
  367. showModalityCurtain();
  368. bringToFront();
  369. } else {
  370. DeferredCommand.addCommand(new Command() {
  371. public void execute() {
  372. // modal window must on top of others
  373. bringToFront();
  374. }
  375. });
  376. }
  377. } else {
  378. if (modalityCurtain != null) {
  379. if (isAttached()) {
  380. hideModalityCurtain();
  381. }
  382. modalityCurtain = null;
  383. }
  384. }
  385. }
  386. private void showModalityCurtain() {
  387. if (BrowserInfo.get().isFF2()) {
  388. DOM.setStyleAttribute(modalityCurtain, "height", DOM
  389. .getElementPropertyInt(RootPanel.getBodyElement(),
  390. "offsetHeight")
  391. + "px");
  392. DOM.setStyleAttribute(modalityCurtain, "position", "absolute");
  393. }
  394. DOM.appendChild(RootPanel.getBodyElement(), modalityCurtain);
  395. }
  396. private void hideModalityCurtain() {
  397. DOM.removeChild(RootPanel.getBodyElement(), modalityCurtain);
  398. }
  399. /*
  400. * Shows (or hides) an empty div on top of all other content; used when
  401. * resizing or moving, so that iframes (etc) do not steal event.
  402. */
  403. private void showDraggingCurtain(boolean show) {
  404. if (show && draggingCurtain == null) {
  405. setFF2CaretFixEnabled(false); // makes FF2 slow
  406. draggingCurtain = DOM.createDiv();
  407. DOM.setStyleAttribute(draggingCurtain, "position", "absolute");
  408. DOM.setStyleAttribute(draggingCurtain, "top", "0px");
  409. DOM.setStyleAttribute(draggingCurtain, "left", "0px");
  410. DOM.setStyleAttribute(draggingCurtain, "width", "100%");
  411. DOM.setStyleAttribute(draggingCurtain, "height", "100%");
  412. DOM.setStyleAttribute(draggingCurtain, "zIndex", ""
  413. + IToolkitOverlay.Z_INDEX);
  414. DOM.appendChild(RootPanel.getBodyElement(), draggingCurtain);
  415. } else if (!show && draggingCurtain != null) {
  416. setFF2CaretFixEnabled(true); // makes FF2 slow
  417. DOM.removeChild(RootPanel.getBodyElement(), draggingCurtain);
  418. draggingCurtain = null;
  419. }
  420. }
  421. private void setResizable(boolean resizability) {
  422. resizable = resizability;
  423. if (resizability) {
  424. DOM.setElementProperty(resizeBox, "className", CLASSNAME
  425. + "-resizebox");
  426. } else {
  427. DOM.setElementProperty(resizeBox, "className", CLASSNAME
  428. + "-resizebox " + CLASSNAME + "-resizebox-disabled");
  429. }
  430. }
  431. public void setPopupPosition(int left, int top) {
  432. super.setPopupPosition(left, top);
  433. if (left != uidlPositionX && client != null) {
  434. client.updateVariable(id, "positionx", left, false);
  435. uidlPositionX = left;
  436. }
  437. if (top != uidlPositionY && client != null) {
  438. client.updateVariable(id, "positiony", top, false);
  439. uidlPositionY = top;
  440. }
  441. }
  442. public void setCaption(String c) {
  443. setCaption(c, null);
  444. }
  445. public void setCaption(String c, String icon) {
  446. String html = Util.escapeHTML(c);
  447. if (icon != null) {
  448. icon = client.translateToolkitUri(icon);
  449. html = "<img src=\"" + icon + "\" class=\"i-icon\" />" + html;
  450. }
  451. DOM.setInnerHTML(headerText, html);
  452. }
  453. protected Element getContainerElement() {
  454. // in GWT 1.5 this method is used in PopupPanel constructor
  455. if (contents == null) {
  456. return super.getContainerElement();
  457. }
  458. return contents;
  459. }
  460. public void onBrowserEvent(final Event event) {
  461. final int type = DOM.eventGetType(event);
  462. if (type == Event.ONKEYDOWN && shortcutHandler != null) {
  463. shortcutHandler.handleKeyboardEvent(event);
  464. return;
  465. }
  466. final Element target = DOM.eventGetTarget(event);
  467. // Handle window caption tooltips
  468. if (client != null && DOM.isOrHasChild(header, target)) {
  469. client.handleTooltipEvent(event, this);
  470. }
  471. if (resizing || DOM.compare(resizeBox, target)) {
  472. onResizeEvent(event);
  473. DOM.eventCancelBubble(event, true);
  474. } else if (DOM.compare(target, closeBox)) {
  475. if (type == Event.ONCLICK) {
  476. onCloseClick();
  477. DOM.eventCancelBubble(event, true);
  478. }
  479. } else if (dragging || !DOM.isOrHasChild(contents, target)) {
  480. onDragEvent(event);
  481. DOM.eventCancelBubble(event, true);
  482. } else if (type == Event.ONCLICK) {
  483. // clicked inside window, ensure to be on top
  484. if (!isActive()) {
  485. bringToFront();
  486. }
  487. }
  488. }
  489. private void onCloseClick() {
  490. client.updateVariable(id, "close", true, true);
  491. }
  492. private void onResizeEvent(Event event) {
  493. if (resizable) {
  494. switch (DOM.eventGetType(event)) {
  495. case Event.ONMOUSEDOWN:
  496. if (!isActive()) {
  497. bringToFront();
  498. }
  499. showDraggingCurtain(true);
  500. resizing = true;
  501. startX = DOM.eventGetScreenX(event);
  502. startY = DOM.eventGetScreenY(event);
  503. origW = getWidget().getOffsetWidth();
  504. origH = getWidget().getOffsetHeight();
  505. DOM.setCapture(getElement());
  506. DOM.eventPreventDefault(event);
  507. break;
  508. case Event.ONMOUSEUP:
  509. showDraggingCurtain(false);
  510. resizing = false;
  511. DOM.releaseCapture(getElement());
  512. setSize(event, true);
  513. break;
  514. case Event.ONLOSECAPTURE:
  515. showDraggingCurtain(false);
  516. resizing = false;
  517. case Event.ONMOUSEMOVE:
  518. if (resizing) {
  519. setSize(event, false);
  520. DOM.eventPreventDefault(event);
  521. }
  522. break;
  523. default:
  524. DOM.eventPreventDefault(event);
  525. break;
  526. }
  527. }
  528. }
  529. public void setSize(Event event, boolean updateVariables) {
  530. int w = DOM.eventGetScreenX(event) - startX + origW;
  531. if (w < MIN_WIDTH) {
  532. w = MIN_WIDTH;
  533. }
  534. int h = DOM.eventGetScreenY(event) - startY + origH;
  535. if (h < MIN_HEIGHT) {
  536. h = MIN_HEIGHT;
  537. }
  538. setWidth(w + "px");
  539. setHeight(h + "px");
  540. if (updateVariables) {
  541. // sending width back always as pixels, no need for unit
  542. client.updateVariable(id, "width", w, false);
  543. client.updateVariable(id, "height", h, false);
  544. }
  545. // Update child widget dimensions
  546. Util.runDescendentsLayout(this);
  547. }
  548. public void setWidth(String width) {
  549. if (!"".equals(width)) {
  550. DOM
  551. .setStyleAttribute(
  552. getElement(),
  553. "width",
  554. (Integer.parseInt(width.substring(0,
  555. width.length() - 2)) + borderWidthHorizontal)
  556. + "px");
  557. }
  558. }
  559. private void onDragEvent(Event event) {
  560. switch (DOM.eventGetType(event)) {
  561. case Event.ONMOUSEDOWN:
  562. if (!isActive()) {
  563. bringToFront();
  564. }
  565. showDraggingCurtain(true);
  566. dragging = true;
  567. startX = DOM.eventGetScreenX(event);
  568. startY = DOM.eventGetScreenY(event);
  569. origX = DOM.getAbsoluteLeft(getElement());
  570. origY = DOM.getAbsoluteTop(getElement());
  571. DOM.setCapture(getElement());
  572. DOM.eventPreventDefault(event);
  573. break;
  574. case Event.ONMOUSEUP:
  575. dragging = false;
  576. showDraggingCurtain(false);
  577. DOM.releaseCapture(getElement());
  578. break;
  579. case Event.ONLOSECAPTURE:
  580. showDraggingCurtain(false);
  581. dragging = false;
  582. break;
  583. case Event.ONMOUSEMOVE:
  584. if (dragging) {
  585. final int x = DOM.eventGetScreenX(event) - startX + origX;
  586. final int y = DOM.eventGetScreenY(event) - startY + origY;
  587. setPopupPosition(x, y);
  588. DOM.eventPreventDefault(event);
  589. }
  590. break;
  591. default:
  592. break;
  593. }
  594. }
  595. public boolean onEventPreview(Event event) {
  596. if (dragging) {
  597. onDragEvent(event);
  598. return false;
  599. } else if (resizing) {
  600. onResizeEvent(event);
  601. return false;
  602. } else if (modal) {
  603. // return false when modal and outside window
  604. final Element target = DOM.eventGetTarget(event);
  605. if (!DOM.isOrHasChild(getElement(), target)) {
  606. return false;
  607. }
  608. }
  609. return true;
  610. }
  611. public void onScroll(Widget widget, int scrollLeft, int scrollTop) {
  612. client.updateVariable(id, "scrollTop", scrollTop, false);
  613. client.updateVariable(id, "scrollLeft", scrollLeft, false);
  614. }
  615. public void addStyleDependentName(String styleSuffix) {
  616. // IWindow's getStyleElement() does not return the same element as
  617. // getElement(), so we need to override this.
  618. setStyleName(getElement(), getStylePrimaryName() + "-" + styleSuffix,
  619. true);
  620. }
  621. protected void onAttach() {
  622. super.onAttach();
  623. // Calculate space required by window borders, so we can accurately
  624. // calculate space for content
  625. final int contentWidth = DOM.getElementPropertyInt(contentPanel
  626. .getElement(), "offsetWidth");
  627. final int windowWidth = DOM.getElementPropertyInt(getElement(),
  628. "offsetWidth");
  629. borderWidthHorizontal = windowWidth - contentWidth;
  630. }
  631. }