From 6356a1bfc5e2fa66a8850e08798fa4d4d0cd886b Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 3 Mar 2009 09:32:05 +0000 Subject: [PATCH] Merged fix for #2688 svn changeset:7013/svn branch:6.0 --- .../gwt/client/ApplicationConnection.java | 10 +++ .../terminal/gwt/client/ui/IScrollTable.java | 82 ++++++++++++++++--- .../LabelEmbeddedClickThroughForTable.java | 69 ++++++++++++++++ 3 files changed, 148 insertions(+), 13 deletions(-) create mode 100644 src/com/itmill/toolkit/tests/components/table/LabelEmbeddedClickThroughForTable.java diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java index b80eacfad9..4c06ad6aaa 100755 --- a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java @@ -1475,6 +1475,16 @@ public class ApplicationConnection { } } + /** + * Returns a Paintable element by its root element + * + * @param element + * Root element of the paintable + */ + public Paintable getPaintable(Element element) { + return getPaintable(getPid(element)); + } + public String getResource(String name) { return resourcesMap.get(name); } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java index 1f7bdcea2e..91623c29fb 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java @@ -2159,21 +2159,24 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { } } - private void handleClickEvent(Event event) { + private void handleClickEvent(Event event, Element targetTdOrTr) { if (emitClickEvents) { - boolean dbl = DOM.eventGetType(event) == Event.ONDBLCLICK; - final Element tdOrTr = DOM.getParent(DOM - .eventGetTarget(event)); + boolean doubleClick = (DOM.eventGetType(event) == Event.ONDBLCLICK); + + /* This row was clicked */ client.updateVariable(paintableId, "clickedKey", "" + rowKey, false); - if (getElement() == tdOrTr.getParentElement()) { - int childIndex = DOM - .getChildIndex(getElement(), tdOrTr); + + if (getElement() == targetTdOrTr.getParentElement()) { + /* A specific column was clicked */ + int childIndex = DOM.getChildIndex(getElement(), + targetTdOrTr); String colKey = null; colKey = tHead.getHeaderCell(childIndex).getColKey(); client.updateVariable(paintableId, "clickedColKey", colKey, false); } + MouseEventDetails details = new MouseEventDetails(event); // Note: the 'immediate' logic would need to be more // involved (see #2104), but iscrolltable always sends @@ -2185,7 +2188,7 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { paintableId, "clickEvent", details.toString(), - !(!dbl + !(!doubleClick && selectMode > Table.SELECT_MODE_NONE && immediate)); } } @@ -2195,12 +2198,11 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { */ @Override public void onBrowserEvent(Event event) { - final Element tdOrTr = DOM.getParent(DOM.eventGetTarget(event)); - if (getElement() == tdOrTr - || getElement() == tdOrTr.getParentElement()) { + Element targetTdOrTr = getEventTargetTdOrTr(event); + if (targetTdOrTr != null) { switch (DOM.eventGetType(event)) { case Event.ONCLICK: - handleClickEvent(event); + handleClickEvent(event, targetTdOrTr); if (selectMode > Table.SELECT_MODE_NONE) { toggleSelection(); // Note: changing the immediateness of this might @@ -2211,7 +2213,7 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { } break; case Event.ONDBLCLICK: - handleClickEvent(event); + handleClickEvent(event, targetTdOrTr); break; case Event.ONCONTEXTMENU: showContextMenu(event); @@ -2223,6 +2225,60 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { super.onBrowserEvent(event); } + /** + * Finds the TD that the event interacts with. Returns null if the + * target of the event should not be handled. If the event target is + * the row directly this method returns the TR element instead of + * the TD. + * + * @param event + * @return TD or TR element that the event targets (the actual event + * target is this element or a child of it) + */ + private Element getEventTargetTdOrTr(Event event) { + Element targetTdOrTr = null; + + final Element eventTarget = DOM.eventGetTarget(event); + final Element eventTargetParent = DOM.getParent(eventTarget); + final Element eventTargetGrandParent = DOM + .getParent(eventTargetParent); + + final Element thisTrElement = getElement(); + + if (eventTarget == thisTrElement) { + // This was a click on the TR element + targetTdOrTr = eventTarget; + // rowTarget = true; + } else if (thisTrElement == eventTargetParent) { + // Target parent is the TR, so the actual target is the TD + targetTdOrTr = eventTarget; + } else if (thisTrElement == eventTargetGrandParent) { + // Target grand parent is the TR, so the parent is the TD + targetTdOrTr = eventTargetParent; + } else { + /* + * This is a workaround to make Labels and Embedded in a + * Table clickable (see #2688). It is really not a fix as it + * does not work for a custom component (not extending + * ILabel/IEmbedded) or for read only textfields etc. + */ + Element tdElement = eventTargetParent; + while (DOM.getParent(tdElement) != thisTrElement) { + tdElement = DOM.getParent(tdElement); + } + + Element componentElement = tdElement.getFirstChildElement() + .getFirstChildElement().cast(); + Widget widget = (Widget) client + .getPaintable(componentElement); + if (widget instanceof ILabel || widget instanceof IEmbedded) { + targetTdOrTr = tdElement; + } + } + + return targetTdOrTr; + } + public void showContextMenu(Event event) { if (enabled && actionKeys != null) { int left = event.getClientX(); diff --git a/src/com/itmill/toolkit/tests/components/table/LabelEmbeddedClickThroughForTable.java b/src/com/itmill/toolkit/tests/components/table/LabelEmbeddedClickThroughForTable.java new file mode 100644 index 0000000000..0b9760e339 --- /dev/null +++ b/src/com/itmill/toolkit/tests/components/table/LabelEmbeddedClickThroughForTable.java @@ -0,0 +1,69 @@ +package com.itmill.toolkit.tests.components.table; + +import com.itmill.toolkit.data.Item; +import com.itmill.toolkit.event.ItemClickEvent; +import com.itmill.toolkit.event.ItemClickEvent.ItemClickListener; +import com.itmill.toolkit.terminal.ThemeResource; +import com.itmill.toolkit.tests.components.TestBase; +import com.itmill.toolkit.ui.Component; +import com.itmill.toolkit.ui.Embedded; +import com.itmill.toolkit.ui.Label; +import com.itmill.toolkit.ui.Table; + +public class LabelEmbeddedClickThroughForTable extends TestBase { + + @Override + protected String getDescription() { + return "Clicking on a Label or Embedded inside a Table should select the row in the same way that clicking on a text selects the row."; + } + + @Override + protected Integer getTicketNumber() { + return 2688; + } + + @Override + protected void setup() { + Table table = new Table(); + table.setSelectable(true); + table.addContainerProperty("Column 1", String.class, ""); + table.addContainerProperty("Column 2", Component.class, ""); + table.addContainerProperty("Column 3", Component.class, ""); + table.addContainerProperty("Column 4", Component.class, ""); + + Item item = table.addItem("Item 1 (row 1)"); + item.getItemProperty("Column 1").setValue("String A"); + item.getItemProperty("Column 2").setValue(new Label("Label A")); + item.getItemProperty("Column 3").setValue( + new Label("Label A", Label.CONTENT_XHTML)); + item.getItemProperty("Column 4").setValue( + new Embedded("An embedded image", new ThemeResource( + "icons/32/ok.png"))); + + item = table.addItem("Item 2 (row 2)"); + item.getItemProperty("Column 1").setValue("String B"); + item.getItemProperty("Column 2").setValue(new Label("Label B")); + item + .getItemProperty("Column 3") + .setValue( + new Label( + "Label A", + Label.CONTENT_XHTML)); + item.getItemProperty("Column 4").setValue( + new Embedded("", new ThemeResource("icons/32/cancel.png"))); + + table.addListener(new ItemClickListener() { + + @Override + public void itemClick(ItemClickEvent event) { + getMainWindow().showNotification( + "Clickevent on item " + event.getItemId() + + ", column: " + event.getPropertyId()); + + } + + }); + addComponent(table); + } + +} -- 2.39.5